Commit 1c6aa3dd authored by Matt Colyer's avatar Matt Colyer

Fixed the data corruption, it turns out that there is a maximum length

that you can request in an AFC packet 2^16.
parent bef65596
...@@ -141,7 +141,7 @@ int receive_AFC_data(AFClient *client, char **dump_here) { ...@@ -141,7 +141,7 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
char *buffer = (char*)malloc(sizeof(AFCPacket) * 4); char *buffer = (char*)malloc(sizeof(AFCPacket) * 4);
char *final_buffer = NULL; char *final_buffer = NULL;
int bytes = 0, recv_len = 0, current_count=0; int bytes = 0, recv_len = 0, current_count=0;
int retval = 0; int retval = 0;
bytes = mux_recv(client->connection, buffer, sizeof(AFCPacket) * 4); bytes = mux_recv(client->connection, buffer, sizeof(AFCPacket) * 4);
if (bytes <= 0) { if (bytes <= 0) {
...@@ -386,41 +386,63 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode) ...@@ -386,41 +386,63 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)
return NULL; return NULL;
} }
/** Attempts to the read the given number of bytes from the given file.
*
* @param client The relevant AFC client
* @param file The AFCFile to read from
* @param data The pointer to the memory region to store the read data
* @param length The number of bytes to read
*
* @return The number of bytes read if successful. If there was an error
*/
int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) { int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
if (!client || !client->afc_packet || !client->connection || !file) return -1; if (!client || !client->afc_packet || !client->connection || !file) return -1;
AFCFilePacket *packet = (AFCFilePacket*)malloc(sizeof(AFCFilePacket)); if (debug) printf("afc_read_file called for length %i\n", length);
if (debug) printf("afc_read_file called for length %i\n");
afc_lock(client);
char *input = NULL; char *input = NULL;
packet->unknown1 = packet->unknown2 = 0; int current_count = 0, bytes = 0;
packet->filehandle = file->filehandle; const int MAXIMUM_READ_SIZE = 1 << 16;
packet->size = length;
int bytes = 0; afc_lock(client);
client->afc_packet->operation = AFC_READ;
client->afc_packet->entire_length = client->afc_packet->this_length = 0; // Looping here to get around the maximum amount of data that recieve_AFC_data can handle
bytes = dispatch_AFC_packet(client, (char*)packet, sizeof(AFCFilePacket)); while (current_count < length){
if (bytes > 0) { // Send the read command
bytes = receive_AFC_data(client, &input); AFCFilePacket *packet = (AFCFilePacket*)malloc(sizeof(AFCFilePacket));
afc_unlock(client); packet->unknown1 = packet->unknown2 = 0;
if (bytes < 0) { packet->filehandle = file->filehandle;
if (input) free(input); packet->size = ((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE;
return -1; client->afc_packet->operation = AFC_READ;
} else if (bytes == 0) { client->afc_packet->entire_length = client->afc_packet->this_length = 0;
if (input) free(input); bytes = dispatch_AFC_packet(client, (char*)packet, sizeof(AFCFilePacket));
return 0;
// If we get a positive reponse to the command gather the data
if (bytes > 0) {
bytes = receive_AFC_data(client, &input);
if (bytes < 0) {
if (input) free(input);
return -1;
} else if (bytes == 0) {
if (input) free(input);
return current_count;
} else {
if (input) {
printf("afc_read_file: %d\n", bytes);
memcpy(data+current_count, input, (bytes > length) ? length : bytes);
free(input);
input = NULL;
current_count += (bytes > length) ? length : bytes;
}
}
} else { } else {
if (input) afc_unlock(client);
memcpy(data, input, (bytes > length) ? length : bytes); return -1;
free(input);
return (bytes > length) ? length : bytes;
} }
} else {
afc_unlock(client);
return -1;
} }
return 0; afc_unlock(client);
return current_count;
} }
int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length) { int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length) {
......
...@@ -103,6 +103,9 @@ static int ifuse_read(const char *path, char *buf, size_t size, off_t offset, ...@@ -103,6 +103,9 @@ static int ifuse_read(const char *path, char *buf, size_t size, off_t offset,
AFCFile *file; AFCFile *file;
AFClient *afc = fuse_get_context()->private_data; AFClient *afc = fuse_get_context()->private_data;
if (size == 0)
return 0;
file = g_hash_table_lookup(file_handles, &(fi->fh)); file = g_hash_table_lookup(file_handles, &(fi->fh));
if (!file){ if (!file){
return -ENOENT; return -ENOENT;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment