* Copyright 2005-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <debugger.h>
#include "MemoryReader.h"
MemoryReader::MemoryReader()
:
fNubPort(-1),
fReplyPort(-1)
{
}
MemoryReader::~MemoryReader()
{
if (fReplyPort >= 0)
delete_port(fReplyPort);
}
status_t
MemoryReader::Init(port_id nubPort)
{
if (fReplyPort >= 0)
delete_port(fReplyPort);
fNubPort = nubPort;
fReplyPort = create_port(1, "memory reader reply");
if (fReplyPort < 0) {
fprintf(stderr, "Failed to create memory reader reply port: %s\n",
strerror(fReplyPort));
return fReplyPort;
}
return B_OK;
}
status_t
MemoryReader::Read(void *_address, void *_buffer, int32 size, int32 &bytesRead)
{
char *address = (char*)_address;
char *buffer = (char*)_buffer;
bytesRead = 0;
while (size > 0) {
int32 toRead = size;
if (toRead > B_MAX_READ_WRITE_MEMORY_SIZE)
toRead = B_MAX_READ_WRITE_MEMORY_SIZE;
int32 actuallyRead = 0;
status_t error = _Read(address, buffer, toRead, actuallyRead);
if (error != B_OK) {
if (bytesRead > 0)
return B_OK;
return error;
}
bytesRead += actuallyRead;
address += actuallyRead;
buffer += actuallyRead;
size -= actuallyRead;
}
return B_OK;
}
status_t
MemoryReader::_Read(void *address, void *buffer, int32 size, int32 &bytesRead)
{
debug_nub_read_memory message;
message.reply_port = fReplyPort;
message.address = address;
message.size = size;
while (true) {
status_t error = write_port(fNubPort, B_DEBUG_MESSAGE_READ_MEMORY,
&message, sizeof(message));
if (error == B_OK)
break;
if (error != B_INTERRUPTED)
return error;
}
int32 code;
debug_nub_read_memory_reply reply;
while (true) {
ssize_t bytesRead = read_port(fReplyPort, &code, &reply, sizeof(reply));
if (bytesRead > 0)
break;
if (bytesRead != B_INTERRUPTED)
return bytesRead;
}
if (reply.error != B_OK)
return reply.error;
bytesRead = reply.size;
memcpy(buffer, reply.data, bytesRead);
return B_OK;
}