So I've been trying to implement extracting files using RPC in Java. So far most of the code is working but it gets stuck on reading the file. It still opens the file successfully though.
As comparison, here is the C code Dimok uses in ddd which is working:
I'm passing the same parameters but it's not returning after the call:
See here for the full Java code.
Thanks!
@dimok
@QuarkTheAwesome
@Maschell
@gudenaurock
@timogus
@NWPlayer123
Code:
@Test
public void extractFile() throws IOException
{
String filePath = "/vol/content/some/file/that/really/exists";
FileSystemStatus status;
RemoteFileSystem fileSystem = new RemoteFileSystem();
try (FileSystemClient client = new FileSystemClient();
FileSystemCommandBlock commandBlock = new FileSystemCommandBlock();
FileSystemHandle fileDescriptor = new FileSystemHandle();
FileSystemPath path = new FileSystemPath(filePath);
FileSystemAccessMode accessMode = new FileSystemAccessMode(FileAccessMode.READ);
AllocatedMemory destinationBuffer = new AllocatedMemory(0x400 * 256, 0x40))
{
// Initialize the file system
status = fileSystem.initialize();
if (status != FileSystemStatus.OK)
{
Assert.fail("Failed initializing file system: " + status);
}
// Initialize the command block
fileSystem.initializeCommandBlock(commandBlock);
// Register the client
status = fileSystem.addClient(client);
if (status != FileSystemStatus.OK)
{
Assert.fail("Failed registering client: " + status);
}
// Open the file
status = fileSystem.openFile(client,
commandBlock,
path,
accessMode,
fileDescriptor,
FileSystemReturnFlag.ALL);
if (status != FileSystemStatus.OK)
{
Assert.fail("Failed opening file: " + status);
}
ByteArrayOutputStream fileBytesBuffer = new ByteArrayOutputStream();
int bytesRead;
// ########### Once it executes this, it gets stuck ############
while ((bytesRead = fileSystem.readFile(client,
commandBlock,
destinationBuffer,
fileDescriptor,
FileSystemReturnFlag.ALL)) > 0)
{
MemoryReader memoryReader = new MemoryReader();
byte[] readBytes = memoryReader.readBytes(destinationBuffer.getAddress(), bytesRead);
fileBytesBuffer.write(readBytes);
}
status = FileSystemStatus.getStatus(bytesRead);
System.out.println("File reading exit status: " + status);
// Close the file
status = fileSystem.closeFile(client, commandBlock, fileDescriptor, FileSystemReturnFlag.NONE);
if (status != FileSystemStatus.OK)
{
Assert.fail("Failed closing file: " + status);
}
// Delete the client registration
status = fileSystem.unRegisterClient(client, FileSystemReturnFlag.NONE);
if (status != FileSystemStatus.OK)
{
Assert.fail("Failed un-registering client: " + status);
}
storeFile(filePath, fileBytesBuffer);
}
}
private void storeFile(String filePath, ByteArrayOutputStream outputStream) throws IOException
{
Path targetFilePath = Paths.get(filePath);
// Create parent directory (if it doesn't exist yet)
Path parentDirectory = targetFilePath.getParent();
Files.createDirectories(parentDirectory);
// Write the bytes
byte[] bytes = outputStream.toByteArray();
Files.write(targetFilePath, bytes);
}
Code:
static void DumpFile(void *client,
void *commandBlock,
SendData *sendData,
char *path,
unsigned int fileSize) {
sendData->tag = 0x02;
memcpy(&sendData->data[0], &fileSize, 4);
sendData->length = snprintf((char *) sendData->data + 4, BUFFER_SIZE - 4, "%s", path) + 4 + 1;
sendwait(iClientSocket, sendData, sizeof(SendData) + sendData->length);
int ret = recvwait(iClientSocket, (char *) sendData, sizeof(SendData) + 1);
if (ret < (int) (sizeof(SendData) + 1) || (sendData->data[0] != 1)) {
return;
}
unsigned char *dataBuffer = (unsigned char *) memalign(0x40, BUFFER_SIZE);
if (!dataBuffer) {
return;
}
int fileDescriptor = 0;
if (FSOpenFile(client, commandBlock, path, "r", &fileDescriptor, -1) != FS_STATUS_OK) {
free(dataBuffer);
sendData->tag = 0x04;
sendData->length = 0;
sendwait(iClientSocket, sendData, sizeof(SendData) + sendData->length);
return;
}
unsigned int size = 0;
// Copy rpl in memory
while ((ret = FSReadFile(client, commandBlock, dataBuffer, 0x1, BUFFER_SIZE, fileDescriptor, 0, -1)) > 0) {
size += ret;
sendData->tag = 0x03;
sendData->length = ret;
memcpy(sendData->data, dataBuffer, sendData->length);
if (sendwait(iClientSocket, sendData, sizeof(SendData) + sendData->length) < 0) {
break;
}
}
sendData->tag = 0x04;
sendData->length = 0;
sendwait(iClientSocket, sendData, sizeof(SendData) + sendData->length);
FSCloseFile(client, commandBlock, fileDescriptor, -1);
free(dataBuffer);
}
Code:
public int readFile(FileSystemClient client,
FileSystemCommandBlock commandBlock,
AllocatedMemory dataBuffer,
FileSystemHandle fileDescriptor,
FileSystemReturnFlag returnFlag) throws IOException
{
ExportedSymbol readFile = remoteProcedureCall.getSymbol(RPL.CORE_INIT.toString(), "FSReadFile");
return remoteProcedureCall.callInt(readFile,
client.getAddress(),
commandBlock.getAddress(),
dataBuffer.getAddress(),
0x1,
0x1000,
// dataBuffer.getSize(),
fileDescriptor.dereference(),
0,
// returnFlag.getValue());
-1);
}
Thanks!
@dimok
@QuarkTheAwesome
@Maschell
@gudenaurock
@timogus
@NWPlayer123