diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/afc.c | 284 | ||||
| -rw-r--r-- | src/afc.h | 1 |
2 files changed, 188 insertions, 97 deletions
| @@ -78,12 +78,12 @@ LIBIMOBILEDEVICE_API afc_error_t afc_client_new_with_service_client(service_clie | |||
| 78 | client_loc->free_parent = 0; | 78 | client_loc->free_parent = 0; |
| 79 | 79 | ||
| 80 | /* allocate a packet */ | 80 | /* allocate a packet */ |
| 81 | client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); | 81 | client_loc->packet_extra = 1024; |
| 82 | client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket) + client_loc->packet_extra); | ||
| 82 | if (!client_loc->afc_packet) { | 83 | if (!client_loc->afc_packet) { |
| 83 | free(client_loc); | 84 | free(client_loc); |
| 84 | return AFC_E_NO_MEM; | 85 | return AFC_E_NO_MEM; |
| 85 | } | 86 | } |
| 86 | |||
| 87 | client_loc->afc_packet->packet_num = 0; | 87 | client_loc->afc_packet->packet_num = 0; |
| 88 | client_loc->afc_packet->entire_length = 0; | 88 | client_loc->afc_packet->entire_length = 0; |
| 89 | client_loc->afc_packet->this_length = 0; | 89 | client_loc->afc_packet->this_length = 0; |
| @@ -148,7 +148,7 @@ LIBIMOBILEDEVICE_API afc_error_t afc_client_free(afc_client_t client) | |||
| 148 | * | 148 | * |
| 149 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. | 149 | * @return AFC_E_SUCCESS on success or an AFC_E_* error value. |
| 150 | */ | 150 | */ |
| 151 | static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation, const char *data, uint32_t data_length, const char* payload, uint32_t payload_length, uint32_t *bytes_sent) | 151 | static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation, uint32_t data_length, const char* payload, uint32_t payload_length, uint32_t *bytes_sent) |
| 152 | { | 152 | { |
| 153 | uint32_t sent = 0; | 153 | uint32_t sent = 0; |
| 154 | 154 | ||
| @@ -157,8 +157,6 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation, | |||
| 157 | 157 | ||
| 158 | *bytes_sent = 0; | 158 | *bytes_sent = 0; |
| 159 | 159 | ||
| 160 | if (!data || !data_length) | ||
| 161 | data_length = 0; | ||
| 162 | if (!payload || !payload_length) | 160 | if (!payload || !payload_length) |
| 163 | payload_length = 0; | 161 | payload_length = 0; |
| 164 | 162 | ||
| @@ -169,34 +167,26 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, uint64_t operation, | |||
| 169 | 167 | ||
| 170 | debug_info("packet length = %i", client->afc_packet->this_length); | 168 | debug_info("packet length = %i", client->afc_packet->this_length); |
| 171 | 169 | ||
| 172 | debug_buffer((char*)client->afc_packet, sizeof(AFCPacket)); | 170 | /* send AFC packet header and data */ |
| 173 | |||
| 174 | /* send AFC packet header */ | ||
| 175 | AFCPacket_to_LE(client->afc_packet); | 171 | AFCPacket_to_LE(client->afc_packet); |
| 172 | debug_buffer((char*)client->afc_packet, sizeof(AFCPacket) + data_length); | ||
| 176 | sent = 0; | 173 | sent = 0; |
| 177 | service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket), &sent); | 174 | service_send(client->parent, (void*)client->afc_packet, sizeof(AFCPacket) + data_length, &sent); |
| 178 | AFCPacket_from_LE(client->afc_packet); | 175 | AFCPacket_from_LE(client->afc_packet); |
| 179 | *bytes_sent += sent; | 176 | *bytes_sent += sent; |
| 180 | if (sent < sizeof(AFCPacket)) { | 177 | if (sent < sizeof(AFCPacket) + data_length) { |
| 181 | return AFC_E_SUCCESS; | ||
| 182 | } | ||
| 183 | |||
| 184 | /* send AFC packet data (if there's data to send) */ | ||
| 185 | sent = 0; | ||
| 186 | if (data_length > 0) { | ||
| 187 | debug_info("packet data follows"); | ||
| 188 | debug_buffer(data, data_length); | ||
| 189 | service_send(client->parent, data, data_length, &sent); | ||
| 190 | } | ||
| 191 | *bytes_sent += sent; | ||
| 192 | if (sent < data_length) { | ||
| 193 | return AFC_E_SUCCESS; | 178 | return AFC_E_SUCCESS; |
| 194 | } | 179 | } |
| 195 | 180 | ||
| 196 | sent = 0; | 181 | sent = 0; |
| 197 | if (payload_length > 0) { | 182 | if (payload_length > 0) { |
| 198 | debug_info("packet payload follows"); | 183 | if (payload_length > 256) { |
| 199 | debug_buffer(payload, payload_length); | 184 | debug_info("packet payload follows (256/%u)", payload_length); |
| 185 | debug_buffer(payload, 256); | ||
| 186 | } else { | ||
| 187 | debug_info("packet payload follows"); | ||
| 188 | debug_buffer(payload, payload_length); | ||
| 189 | } | ||
| 200 | service_send(client->parent, payload, payload_length, &sent); | 190 | service_send(client->parent, payload, payload_length, &sent); |
| 201 | } | 191 | } |
| 202 | *bytes_sent += sent; | 192 | *bytes_sent += sent; |
| @@ -310,8 +300,13 @@ static afc_error_t afc_receive_data(afc_client_t client, char **bytes, uint32_t | |||
| 310 | } | 300 | } |
| 311 | 301 | ||
| 312 | debug_info("packet data size = %i", current_count); | 302 | debug_info("packet data size = %i", current_count); |
| 313 | debug_info("packet data follows"); | 303 | if (current_count > 256) { |
| 314 | debug_buffer(dump_here, current_count); | 304 | debug_info("packet data follows (256/%u)", current_count); |
| 305 | debug_buffer(dump_here, 256); | ||
| 306 | } else { | ||
| 307 | debug_info("packet data follows"); | ||
| 308 | debug_buffer(dump_here, current_count); | ||
| 309 | } | ||
| 315 | 310 | ||
| 316 | /* check operation types */ | 311 | /* check operation types */ |
| 317 | if (header.operation == AFC_OP_STATUS) { | 312 | if (header.operation == AFC_OP_STATUS) { |
| @@ -400,6 +395,21 @@ static char **make_strings_list(char *tokens, uint32_t length) | |||
| 400 | return list; | 395 | return list; |
| 401 | } | 396 | } |
| 402 | 397 | ||
| 398 | static int _afc_check_packet_buffer(afc_client_t client, uint32_t data_len) | ||
| 399 | { | ||
| 400 | if (data_len > client->packet_extra) { | ||
| 401 | client->packet_extra = (data_len & ~8) + 8; | ||
| 402 | AFCPacket* newpkt = (AFCPacket*)realloc(client->afc_packet, sizeof(AFCPacket) + client->packet_extra); | ||
| 403 | if (!newpkt) { | ||
| 404 | return -1; | ||
| 405 | } | ||
| 406 | client->afc_packet = newpkt; | ||
| 407 | } | ||
| 408 | return 0; | ||
| 409 | } | ||
| 410 | |||
| 411 | #define AFC_PACKET_DATA_PTR ((char*)client->afc_packet + sizeof(AFCPacket)) | ||
| 412 | |||
| 403 | LIBIMOBILEDEVICE_API afc_error_t afc_read_directory(afc_client_t client, const char *path, char ***directory_information) | 413 | LIBIMOBILEDEVICE_API afc_error_t afc_read_directory(afc_client_t client, const char *path, char ***directory_information) |
| 404 | { | 414 | { |
| 405 | uint32_t bytes = 0; | 415 | uint32_t bytes = 0; |
| @@ -411,8 +421,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_read_directory(afc_client_t client, const c | |||
| 411 | 421 | ||
| 412 | afc_lock(client); | 422 | afc_lock(client); |
| 413 | 423 | ||
| 424 | uint32_t data_len = (uint32_t)strlen(path)+1; | ||
| 425 | if (_afc_check_packet_buffer(client, data_len) < 0) { | ||
| 426 | afc_unlock(client); | ||
| 427 | debug_info("Failed to realloc packet buffer"); | ||
| 428 | return AFC_E_NO_MEM; | ||
| 429 | } | ||
| 430 | |||
| 414 | /* Send the command */ | 431 | /* Send the command */ |
| 415 | ret = afc_dispatch_packet(client, AFC_OP_READ_DIR, path, strlen(path)+1, NULL, 0, &bytes); | 432 | memcpy(AFC_PACKET_DATA_PTR, path, data_len); |
| 433 | ret = afc_dispatch_packet(client, AFC_OP_READ_DIR, data_len, NULL, 0, &bytes); | ||
| 416 | if (ret != AFC_E_SUCCESS) { | 434 | if (ret != AFC_E_SUCCESS) { |
| 417 | afc_unlock(client); | 435 | afc_unlock(client); |
| 418 | return AFC_E_NOT_ENOUGH_DATA; | 436 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -448,7 +466,7 @@ LIBIMOBILEDEVICE_API afc_error_t afc_get_device_info(afc_client_t client, char * | |||
| 448 | afc_lock(client); | 466 | afc_lock(client); |
| 449 | 467 | ||
| 450 | /* Send the command */ | 468 | /* Send the command */ |
| 451 | ret = afc_dispatch_packet(client, AFC_OP_GET_DEVINFO, NULL, 0, NULL, 0, &bytes); | 469 | ret = afc_dispatch_packet(client, AFC_OP_GET_DEVINFO, 0, NULL, 0, &bytes); |
| 452 | if (ret != AFC_E_SUCCESS) { | 470 | if (ret != AFC_E_SUCCESS) { |
| 453 | afc_unlock(client); | 471 | afc_unlock(client); |
| 454 | return AFC_E_NOT_ENOUGH_DATA; | 472 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -510,8 +528,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_remove_path(afc_client_t client, const char | |||
| 510 | 528 | ||
| 511 | afc_lock(client); | 529 | afc_lock(client); |
| 512 | 530 | ||
| 531 | uint32_t data_len = (uint32_t)strlen(path)+1; | ||
| 532 | if (_afc_check_packet_buffer(client, data_len) < 0) { | ||
| 533 | afc_unlock(client); | ||
| 534 | debug_info("Failed to realloc packet buffer"); | ||
| 535 | return AFC_E_NO_MEM; | ||
| 536 | } | ||
| 537 | |||
| 513 | /* Send command */ | 538 | /* Send command */ |
| 514 | ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH, path, strlen(path)+1, NULL, 0, &bytes); | 539 | memcpy(AFC_PACKET_DATA_PTR, path, data_len); |
| 540 | ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH, data_len, NULL, 0, &bytes); | ||
| 515 | if (ret != AFC_E_SUCCESS) { | 541 | if (ret != AFC_E_SUCCESS) { |
| 516 | afc_unlock(client); | 542 | afc_unlock(client); |
| 517 | return AFC_E_NOT_ENOUGH_DATA; | 543 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -533,18 +559,25 @@ LIBIMOBILEDEVICE_API afc_error_t afc_rename_path(afc_client_t client, const char | |||
| 533 | if (!client || !from || !to || !client->afc_packet || !client->parent) | 559 | if (!client || !from || !to || !client->afc_packet || !client->parent) |
| 534 | return AFC_E_INVALID_ARG; | 560 | return AFC_E_INVALID_ARG; |
| 535 | 561 | ||
| 536 | char *buffer = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t))); | ||
| 537 | uint32_t bytes = 0; | 562 | uint32_t bytes = 0; |
| 538 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 563 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 539 | 564 | ||
| 565 | size_t from_len = strlen(from); | ||
| 566 | size_t to_len = strlen(to); | ||
| 567 | |||
| 540 | afc_lock(client); | 568 | afc_lock(client); |
| 541 | 569 | ||
| 542 | /* Send command */ | 570 | uint32_t data_len = (uint32_t)(from_len+1 + to_len+1); |
| 543 | memcpy(buffer, from, strlen(from) + 1); | 571 | if (_afc_check_packet_buffer(client, data_len) < 0) { |
| 544 | memcpy(buffer + strlen(from) + 1, to, strlen(to) + 1); | 572 | afc_unlock(client); |
| 545 | ret = afc_dispatch_packet(client, AFC_OP_RENAME_PATH, buffer, strlen(to)+1 + strlen(from)+1, NULL, 0, &bytes); | 573 | debug_info("Failed to realloc packet buffer"); |
| 546 | free(buffer); | 574 | return AFC_E_NO_MEM; |
| 575 | } | ||
| 547 | 576 | ||
| 577 | /* Send command */ | ||
| 578 | memcpy(AFC_PACKET_DATA_PTR, from, from_len+1); | ||
| 579 | memcpy(AFC_PACKET_DATA_PTR + from_len+1, to, to_len+1); | ||
| 580 | ret = afc_dispatch_packet(client, AFC_OP_RENAME_PATH, data_len, NULL, 0, &bytes); | ||
| 548 | if (ret != AFC_E_SUCCESS) { | 581 | if (ret != AFC_E_SUCCESS) { |
| 549 | afc_unlock(client); | 582 | afc_unlock(client); |
| 550 | return AFC_E_NOT_ENOUGH_DATA; | 583 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -567,8 +600,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_make_directory(afc_client_t client, const c | |||
| 567 | 600 | ||
| 568 | afc_lock(client); | 601 | afc_lock(client); |
| 569 | 602 | ||
| 603 | uint32_t data_len = (uint32_t)strlen(path)+1; | ||
| 604 | if (_afc_check_packet_buffer(client, data_len) < 0) { | ||
| 605 | afc_unlock(client); | ||
| 606 | debug_info("Failed to realloc packet buffer"); | ||
| 607 | return AFC_E_NO_MEM; | ||
| 608 | } | ||
| 609 | |||
| 570 | /* Send command */ | 610 | /* Send command */ |
| 571 | ret = afc_dispatch_packet(client, AFC_OP_MAKE_DIR, path, strlen(path)+1, NULL, 0, &bytes); | 611 | memcpy(AFC_PACKET_DATA_PTR, path, data_len); |
| 612 | ret = afc_dispatch_packet(client, AFC_OP_MAKE_DIR, data_len, NULL, 0, &bytes); | ||
| 572 | if (ret != AFC_E_SUCCESS) { | 613 | if (ret != AFC_E_SUCCESS) { |
| 573 | afc_unlock(client); | 614 | afc_unlock(client); |
| 574 | return AFC_E_NOT_ENOUGH_DATA; | 615 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -592,8 +633,18 @@ LIBIMOBILEDEVICE_API afc_error_t afc_get_file_info(afc_client_t client, const ch | |||
| 592 | 633 | ||
| 593 | afc_lock(client); | 634 | afc_lock(client); |
| 594 | 635 | ||
| 636 | uint32_t data_len = (uint32_t)strlen(path)+1; | ||
| 637 | if (_afc_check_packet_buffer(client, data_len) < 0) { | ||
| 638 | afc_unlock(client); | ||
| 639 | debug_info("Failed to realloc packet buffer"); | ||
| 640 | return AFC_E_NO_MEM; | ||
| 641 | } | ||
| 642 | |||
| 643 | debug_info("We got %p and %p", client->afc_packet, AFC_PACKET_DATA_PTR); | ||
| 644 | |||
| 595 | /* Send command */ | 645 | /* Send command */ |
| 596 | ret = afc_dispatch_packet(client, AFC_OP_GET_FILE_INFO, path, strlen(path)+1, NULL, 0, &bytes); | 646 | memcpy(AFC_PACKET_DATA_PTR, path, data_len); |
| 647 | ret = afc_dispatch_packet(client, AFC_OP_GET_FILE_INFO, data_len, NULL, 0, &bytes); | ||
| 597 | if (ret != AFC_E_SUCCESS) { | 648 | if (ret != AFC_E_SUCCESS) { |
| 598 | afc_unlock(client); | 649 | afc_unlock(client); |
| 599 | return AFC_E_NOT_ENOUGH_DATA; | 650 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -616,9 +667,8 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_open(afc_client_t client, const char * | |||
| 616 | if (!client || !client->parent || !client->afc_packet) | 667 | if (!client || !client->parent || !client->afc_packet) |
| 617 | return AFC_E_INVALID_ARG; | 668 | return AFC_E_INVALID_ARG; |
| 618 | 669 | ||
| 619 | uint64_t file_mode_loc = htole64(file_mode); | 670 | //uint64_t file_mode_loc = htole64(file_mode); |
| 620 | uint32_t bytes = 0; | 671 | uint32_t bytes = 0; |
| 621 | char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); | ||
| 622 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 672 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 623 | 673 | ||
| 624 | /* set handle to 0 so in case an error occurs, the handle is invalid */ | 674 | /* set handle to 0 so in case an error occurs, the handle is invalid */ |
| @@ -626,20 +676,25 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_open(afc_client_t client, const char * | |||
| 626 | 676 | ||
| 627 | afc_lock(client); | 677 | afc_lock(client); |
| 628 | 678 | ||
| 629 | /* Send command */ | 679 | uint32_t data_len = (uint32_t)(strlen(filename)+1 + 8); |
| 630 | memcpy(data, &file_mode_loc, 8); | 680 | if (_afc_check_packet_buffer(client, data_len) < 0) { |
| 631 | memcpy(data + 8, filename, strlen(filename)); | 681 | afc_unlock(client); |
| 632 | data[8 + strlen(filename)] = '\0'; | 682 | debug_info("Failed to realloc packet buffer"); |
| 633 | ret = afc_dispatch_packet(client, AFC_OP_FILE_OPEN, data, 8 + strlen(filename) + 1, NULL, 0, &bytes); | 683 | return AFC_E_NO_MEM; |
| 634 | free(data); | 684 | } |
| 635 | 685 | ||
| 686 | /* Send command */ | ||
| 687 | //memcpy(AFC_PACKET_DATA_PTR, &file_mode_loc, 8); | ||
| 688 | *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(file_mode); | ||
| 689 | memcpy(AFC_PACKET_DATA_PTR + 8, filename, data_len-8); | ||
| 690 | ret = afc_dispatch_packet(client, AFC_OP_FILE_OPEN, data_len, NULL, 0, &bytes); | ||
| 636 | if (ret != AFC_E_SUCCESS) { | 691 | if (ret != AFC_E_SUCCESS) { |
| 637 | debug_info("Didn't receive a response to the command"); | 692 | debug_info("Didn't receive a response to the command"); |
| 638 | afc_unlock(client); | 693 | afc_unlock(client); |
| 639 | return AFC_E_NOT_ENOUGH_DATA; | 694 | return AFC_E_NOT_ENOUGH_DATA; |
| 640 | } | 695 | } |
| 641 | /* Receive the data */ | 696 | /* Receive the data */ |
| 642 | data = NULL; | 697 | char* data = NULL; |
| 643 | ret = afc_receive_data(client, &data, &bytes); | 698 | ret = afc_receive_data(client, &data, &bytes); |
| 644 | if ((ret == AFC_E_SUCCESS) && (bytes > 0) && data) { | 699 | if ((ret == AFC_E_SUCCESS) && (bytes > 0) && data) { |
| 645 | afc_unlock(client); | 700 | afc_unlock(client); |
| @@ -663,23 +718,25 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_read(afc_client_t client, uint64_t han | |||
| 663 | { | 718 | { |
| 664 | char *input = NULL; | 719 | char *input = NULL; |
| 665 | uint32_t current_count = 0, bytes_loc = 0; | 720 | uint32_t current_count = 0, bytes_loc = 0; |
| 721 | struct readinfo { | ||
| 722 | uint64_t handle; | ||
| 723 | uint64_t size; | ||
| 724 | }; | ||
| 666 | afc_error_t ret = AFC_E_SUCCESS; | 725 | afc_error_t ret = AFC_E_SUCCESS; |
| 667 | 726 | ||
| 668 | if (!client || !client->afc_packet || !client->parent || handle == 0) | 727 | if (!client || !client->afc_packet || !client->parent || handle == 0) |
| 669 | return AFC_E_INVALID_ARG; | 728 | return AFC_E_INVALID_ARG; |
| 670 | debug_info("called for length %i", length); | 729 | debug_info("called for length %i", length); |
| 671 | 730 | ||
| 731 | //uint32_t data_len = 8 + 8; | ||
| 732 | |||
| 672 | afc_lock(client); | 733 | afc_lock(client); |
| 673 | 734 | ||
| 674 | /* Send the read command */ | 735 | /* Send the read command */ |
| 675 | struct { | 736 | struct readinfo* readinfo = (struct readinfo*)(AFC_PACKET_DATA_PTR); |
| 676 | uint64_t handle; | 737 | readinfo->handle = handle; |
| 677 | uint64_t size; | 738 | readinfo->size = htole64(length); |
| 678 | } readinfo; | 739 | ret = afc_dispatch_packet(client, AFC_OP_FILE_READ, sizeof(struct readinfo), NULL, 0, &bytes_loc); |
| 679 | readinfo.handle = handle; | ||
| 680 | readinfo.size = htole64(length); | ||
| 681 | ret = afc_dispatch_packet(client, AFC_OP_FILE_READ, (const char*)&readinfo, sizeof(readinfo), NULL, 0, &bytes_loc); | ||
| 682 | |||
| 683 | if (ret != AFC_E_SUCCESS) { | 740 | if (ret != AFC_E_SUCCESS) { |
| 684 | afc_unlock(client); | 741 | afc_unlock(client); |
| 685 | return AFC_E_NOT_ENOUGH_DATA; | 742 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -721,11 +778,14 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_write(afc_client_t client, uint64_t ha | |||
| 721 | if (!client || !client->afc_packet || !client->parent || !bytes_written || (handle == 0)) | 778 | if (!client || !client->afc_packet || !client->parent || !bytes_written || (handle == 0)) |
| 722 | return AFC_E_INVALID_ARG; | 779 | return AFC_E_INVALID_ARG; |
| 723 | 780 | ||
| 781 | uint32_t data_len = 8; | ||
| 782 | |||
| 724 | afc_lock(client); | 783 | afc_lock(client); |
| 725 | 784 | ||
| 726 | debug_info("Write length: %i", length); | 785 | debug_info("Write length: %i", length); |
| 727 | 786 | ||
| 728 | ret = afc_dispatch_packet(client, AFC_OP_FILE_WRITE, (const char*)&handle, 8, data, length, &bytes_loc); | 787 | *(uint64_t*)(AFC_PACKET_DATA_PTR) = handle; |
| 788 | ret = afc_dispatch_packet(client, AFC_OP_FILE_WRITE, data_len, data, length, &bytes_loc); | ||
| 729 | 789 | ||
| 730 | current_count += bytes_loc - (sizeof(AFCPacket) + 8); | 790 | current_count += bytes_loc - (sizeof(AFCPacket) + 8); |
| 731 | 791 | ||
| @@ -752,12 +812,15 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_close(afc_client_t client, uint64_t ha | |||
| 752 | if (!client || (handle == 0)) | 812 | if (!client || (handle == 0)) |
| 753 | return AFC_E_INVALID_ARG; | 813 | return AFC_E_INVALID_ARG; |
| 754 | 814 | ||
| 815 | uint32_t data_len = 8; | ||
| 816 | |||
| 755 | afc_lock(client); | 817 | afc_lock(client); |
| 756 | 818 | ||
| 757 | debug_info("File handle %i", handle); | 819 | debug_info("File handle %i", handle); |
| 758 | 820 | ||
| 759 | /* Send command */ | 821 | /* Send command */ |
| 760 | ret = afc_dispatch_packet(client, AFC_OP_FILE_CLOSE, (const char*)&handle, 8, NULL, 0, &bytes); | 822 | *(uint64_t*)(AFC_PACKET_DATA_PTR) = handle; |
| 823 | ret = afc_dispatch_packet(client, AFC_OP_FILE_CLOSE, data_len, NULL, 0, &bytes); | ||
| 761 | 824 | ||
| 762 | if (ret != AFC_E_SUCCESS) { | 825 | if (ret != AFC_E_SUCCESS) { |
| 763 | afc_unlock(client); | 826 | afc_unlock(client); |
| @@ -775,10 +838,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_close(afc_client_t client, uint64_t ha | |||
| 775 | LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation) | 838 | LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation) |
| 776 | { | 839 | { |
| 777 | uint32_t bytes = 0; | 840 | uint32_t bytes = 0; |
| 778 | struct { | 841 | struct lockinfo { |
| 779 | uint64_t handle; | 842 | uint64_t handle; |
| 780 | uint64_t op; | 843 | uint64_t op; |
| 781 | } lockinfo; | 844 | }; |
| 782 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 845 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 783 | 846 | ||
| 784 | if (!client || (handle == 0)) | 847 | if (!client || (handle == 0)) |
| @@ -789,10 +852,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t han | |||
| 789 | debug_info("file handle %i", handle); | 852 | debug_info("file handle %i", handle); |
| 790 | 853 | ||
| 791 | /* Send command */ | 854 | /* Send command */ |
| 792 | lockinfo.handle = handle; | 855 | struct lockinfo* lockinfo = (struct lockinfo*)(AFC_PACKET_DATA_PTR); |
| 793 | lockinfo.op = htole64(operation); | 856 | lockinfo->handle = handle; |
| 794 | ret = afc_dispatch_packet(client, AFC_OP_FILE_LOCK, (const char*)&lockinfo, sizeof(lockinfo), NULL, 0, &bytes); | 857 | lockinfo->op = htole64(operation); |
| 795 | 858 | ret = afc_dispatch_packet(client, AFC_OP_FILE_LOCK, sizeof(struct lockinfo), NULL, 0, &bytes); | |
| 796 | if (ret != AFC_E_SUCCESS) { | 859 | if (ret != AFC_E_SUCCESS) { |
| 797 | afc_unlock(client); | 860 | afc_unlock(client); |
| 798 | debug_info("could not send lock command"); | 861 | debug_info("could not send lock command"); |
| @@ -809,11 +872,11 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t han | |||
| 809 | LIBIMOBILEDEVICE_API afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence) | 872 | LIBIMOBILEDEVICE_API afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence) |
| 810 | { | 873 | { |
| 811 | uint32_t bytes = 0; | 874 | uint32_t bytes = 0; |
| 812 | struct { | 875 | struct seekinfo { |
| 813 | uint64_t handle; | 876 | uint64_t handle; |
| 814 | uint64_t whence; | 877 | uint64_t whence; |
| 815 | int64_t offset; | 878 | int64_t offset; |
| 816 | } seekinfo; | 879 | }; |
| 817 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 880 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 818 | 881 | ||
| 819 | if (!client || (handle == 0)) | 882 | if (!client || (handle == 0)) |
| @@ -822,10 +885,11 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_seek(afc_client_t client, uint64_t han | |||
| 822 | afc_lock(client); | 885 | afc_lock(client); |
| 823 | 886 | ||
| 824 | /* Send the command */ | 887 | /* Send the command */ |
| 825 | seekinfo.handle = handle; | 888 | struct seekinfo* seekinfo = (struct seekinfo*)(AFC_PACKET_DATA_PTR); |
| 826 | seekinfo.whence = htole64(whence); | 889 | seekinfo->handle = handle; |
| 827 | seekinfo.offset = (int64_t)htole64(offset); | 890 | seekinfo->whence = htole64(whence); |
| 828 | ret = afc_dispatch_packet(client, AFC_OP_FILE_SEEK, (const char*)&seekinfo, sizeof(seekinfo), NULL, 0, &bytes); | 891 | seekinfo->offset = (int64_t)htole64(offset); |
| 892 | ret = afc_dispatch_packet(client, AFC_OP_FILE_SEEK, sizeof(struct seekinfo), NULL, 0, &bytes); | ||
| 829 | 893 | ||
| 830 | if (ret != AFC_E_SUCCESS) { | 894 | if (ret != AFC_E_SUCCESS) { |
| 831 | afc_unlock(client); | 895 | afc_unlock(client); |
| @@ -848,11 +912,13 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_tell(afc_client_t client, uint64_t han | |||
| 848 | if (!client || (handle == 0)) | 912 | if (!client || (handle == 0)) |
| 849 | return AFC_E_INVALID_ARG; | 913 | return AFC_E_INVALID_ARG; |
| 850 | 914 | ||
| 915 | uint32_t data_len = 8; | ||
| 916 | |||
| 851 | afc_lock(client); | 917 | afc_lock(client); |
| 852 | 918 | ||
| 853 | /* Send the command */ | 919 | /* Send the command */ |
| 854 | ret = afc_dispatch_packet(client, AFC_OP_FILE_TELL, (const char*)&handle, 8, NULL, 0, &bytes); | 920 | *(uint64_t*)(AFC_PACKET_DATA_PTR) = handle; |
| 855 | 921 | ret = afc_dispatch_packet(client, AFC_OP_FILE_TELL, data_len, NULL, 0, &bytes); | |
| 856 | if (ret != AFC_E_SUCCESS) { | 922 | if (ret != AFC_E_SUCCESS) { |
| 857 | afc_unlock(client); | 923 | afc_unlock(client); |
| 858 | return AFC_E_NOT_ENOUGH_DATA; | 924 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -875,10 +941,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_tell(afc_client_t client, uint64_t han | |||
| 875 | LIBIMOBILEDEVICE_API afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize) | 941 | LIBIMOBILEDEVICE_API afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize) |
| 876 | { | 942 | { |
| 877 | uint32_t bytes = 0; | 943 | uint32_t bytes = 0; |
| 878 | struct { | 944 | struct truncinfo { |
| 879 | uint64_t handle; | 945 | uint64_t handle; |
| 880 | uint64_t newsize; | 946 | uint64_t newsize; |
| 881 | } truncinfo; | 947 | }; |
| 882 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 948 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 883 | 949 | ||
| 884 | if (!client || (handle == 0)) | 950 | if (!client || (handle == 0)) |
| @@ -887,9 +953,10 @@ LIBIMOBILEDEVICE_API afc_error_t afc_file_truncate(afc_client_t client, uint64_t | |||
| 887 | afc_lock(client); | 953 | afc_lock(client); |
| 888 | 954 | ||
| 889 | /* Send command */ | 955 | /* Send command */ |
| 890 | truncinfo.handle = handle; | 956 | struct truncinfo* truncinfo = (struct truncinfo*)(AFC_PACKET_DATA_PTR); |
| 891 | truncinfo.newsize = htole64(newsize); | 957 | truncinfo->handle = handle; |
| 892 | ret = afc_dispatch_packet(client, AFC_OP_FILE_SET_SIZE, (const char*)&truncinfo, sizeof(truncinfo), NULL, 0, &bytes); | 958 | truncinfo->newsize = htole64(newsize); |
| 959 | ret = afc_dispatch_packet(client, AFC_OP_FILE_SET_SIZE, sizeof(struct truncinfo), NULL, 0, &bytes); | ||
| 893 | 960 | ||
| 894 | if (ret != AFC_E_SUCCESS) { | 961 | if (ret != AFC_E_SUCCESS) { |
| 895 | afc_unlock(client); | 962 | afc_unlock(client); |
| @@ -908,19 +975,22 @@ LIBIMOBILEDEVICE_API afc_error_t afc_truncate(afc_client_t client, const char *p | |||
| 908 | if (!client || !path || !client->afc_packet || !client->parent) | 975 | if (!client || !path || !client->afc_packet || !client->parent) |
| 909 | return AFC_E_INVALID_ARG; | 976 | return AFC_E_INVALID_ARG; |
| 910 | 977 | ||
| 911 | char *buffer = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); | ||
| 912 | uint32_t bytes = 0; | 978 | uint32_t bytes = 0; |
| 913 | uint64_t size_requested = htole64(newsize); | ||
| 914 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 979 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 915 | 980 | ||
| 916 | afc_lock(client); | 981 | afc_lock(client); |
| 917 | 982 | ||
| 918 | /* Send command */ | 983 | uint32_t data_len = 8 + (uint32_t)(strlen(path)+1); |
| 919 | memcpy(buffer, &size_requested, 8); | 984 | if (_afc_check_packet_buffer(client, data_len) < 0) { |
| 920 | memcpy(buffer + 8, path, strlen(path) + 1); | 985 | afc_unlock(client); |
| 921 | ret = afc_dispatch_packet(client, AFC_OP_TRUNCATE, buffer, 8 + strlen(path) + 1, NULL, 0, &bytes); | 986 | debug_info("Failed to realloc packet buffer"); |
| 922 | free(buffer); | 987 | return AFC_E_NO_MEM; |
| 988 | } | ||
| 923 | 989 | ||
| 990 | /* Send command */ | ||
| 991 | *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(newsize); | ||
| 992 | memcpy(AFC_PACKET_DATA_PTR + 8, path, data_len-8); | ||
| 993 | ret = afc_dispatch_packet(client, AFC_OP_TRUNCATE, data_len, NULL, 0, &bytes); | ||
| 924 | if (ret != AFC_E_SUCCESS) { | 994 | if (ret != AFC_E_SUCCESS) { |
| 925 | afc_unlock(client); | 995 | afc_unlock(client); |
| 926 | return AFC_E_NOT_ENOUGH_DATA; | 996 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -938,23 +1008,31 @@ LIBIMOBILEDEVICE_API afc_error_t afc_make_link(afc_client_t client, afc_link_typ | |||
| 938 | if (!client || !target || !linkname || !client->afc_packet || !client->parent) | 1008 | if (!client || !target || !linkname || !client->afc_packet || !client->parent) |
| 939 | return AFC_E_INVALID_ARG; | 1009 | return AFC_E_INVALID_ARG; |
| 940 | 1010 | ||
| 941 | char *buffer = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8)); | ||
| 942 | uint32_t bytes = 0; | 1011 | uint32_t bytes = 0; |
| 943 | uint64_t type = htole64(linktype); | 1012 | uint64_t type = htole64(linktype); |
| 944 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 1013 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 945 | 1014 | ||
| 1015 | size_t target_len = strlen(target); | ||
| 1016 | size_t link_len = strlen(linkname); | ||
| 1017 | |||
| 946 | afc_lock(client); | 1018 | afc_lock(client); |
| 947 | 1019 | ||
| 1020 | uint32_t data_len = 8 + target_len + 1 + link_len + 1; | ||
| 1021 | if (_afc_check_packet_buffer(client, data_len) < 0) { | ||
| 1022 | afc_unlock(client); | ||
| 1023 | debug_info("Failed to realloc packet buffer"); | ||
| 1024 | return AFC_E_NO_MEM; | ||
| 1025 | } | ||
| 1026 | |||
| 948 | debug_info("link type: %lld", type); | 1027 | debug_info("link type: %lld", type); |
| 949 | debug_info("target: %s, length:%d", target, strlen(target)); | 1028 | debug_info("target: %s, length:%d", target, target_len); |
| 950 | debug_info("linkname: %s, length:%d", linkname, strlen(linkname)); | 1029 | debug_info("linkname: %s, length:%d", linkname, link_len); |
| 951 | 1030 | ||
| 952 | /* Send command */ | 1031 | /* Send command */ |
| 953 | memcpy(buffer, &type, 8); | 1032 | *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(linktype); |
| 954 | memcpy(buffer + 8, target, strlen(target) + 1); | 1033 | memcpy(AFC_PACKET_DATA_PTR + 8, target, target_len + 1); |
| 955 | memcpy(buffer + 8 + strlen(target) + 1, linkname, strlen(linkname) + 1); | 1034 | memcpy(AFC_PACKET_DATA_PTR + 8 + target_len + 1, linkname, link_len + 1); |
| 956 | ret = afc_dispatch_packet(client, AFC_OP_MAKE_LINK, buffer, 8 + strlen(linkname) + 1 + strlen(target) + 1, NULL, 0, &bytes); | 1035 | ret = afc_dispatch_packet(client, AFC_OP_MAKE_LINK, data_len, NULL, 0, &bytes); |
| 957 | free(buffer); | ||
| 958 | if (ret != AFC_E_SUCCESS) { | 1036 | if (ret != AFC_E_SUCCESS) { |
| 959 | afc_unlock(client); | 1037 | afc_unlock(client); |
| 960 | return AFC_E_NOT_ENOUGH_DATA; | 1038 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -972,18 +1050,22 @@ LIBIMOBILEDEVICE_API afc_error_t afc_set_file_time(afc_client_t client, const ch | |||
| 972 | if (!client || !path || !client->afc_packet || !client->parent) | 1050 | if (!client || !path || !client->afc_packet || !client->parent) |
| 973 | return AFC_E_INVALID_ARG; | 1051 | return AFC_E_INVALID_ARG; |
| 974 | 1052 | ||
| 975 | char *buffer = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); | ||
| 976 | uint32_t bytes = 0; | 1053 | uint32_t bytes = 0; |
| 977 | uint64_t mtime_loc = htole64(mtime); | ||
| 978 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; | 1054 | afc_error_t ret = AFC_E_UNKNOWN_ERROR; |
| 979 | 1055 | ||
| 980 | afc_lock(client); | 1056 | afc_lock(client); |
| 981 | 1057 | ||
| 1058 | uint32_t data_len = 8 + strlen(path) + 1; | ||
| 1059 | if (_afc_check_packet_buffer(client, data_len) < 0) { | ||
| 1060 | afc_unlock(client); | ||
| 1061 | debug_info("Failed to realloc packet buffer"); | ||
| 1062 | return AFC_E_NO_MEM; | ||
| 1063 | } | ||
| 1064 | |||
| 982 | /* Send command */ | 1065 | /* Send command */ |
| 983 | memcpy(buffer, &mtime_loc, 8); | 1066 | *(uint64_t*)(AFC_PACKET_DATA_PTR) = htole64(mtime); |
| 984 | memcpy(buffer + 8, path, strlen(path) + 1); | 1067 | memcpy(AFC_PACKET_DATA_PTR + 8, path, data_len-8); |
| 985 | ret = afc_dispatch_packet(client, AFC_OP_SET_FILE_MOD_TIME, buffer, 8 + strlen(path) + 1, NULL, 0, &bytes); | 1068 | ret = afc_dispatch_packet(client, AFC_OP_SET_FILE_MOD_TIME, data_len, NULL, 0, &bytes); |
| 986 | free(buffer); | ||
| 987 | if (ret != AFC_E_SUCCESS) { | 1069 | if (ret != AFC_E_SUCCESS) { |
| 988 | afc_unlock(client); | 1070 | afc_unlock(client); |
| 989 | return AFC_E_NOT_ENOUGH_DATA; | 1071 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -1006,8 +1088,16 @@ LIBIMOBILEDEVICE_API afc_error_t afc_remove_path_and_contents(afc_client_t clien | |||
| 1006 | 1088 | ||
| 1007 | afc_lock(client); | 1089 | afc_lock(client); |
| 1008 | 1090 | ||
| 1091 | uint32_t data_len = strlen(path) + 1; | ||
| 1092 | if (_afc_check_packet_buffer(client, data_len) < 0) { | ||
| 1093 | afc_unlock(client); | ||
| 1094 | debug_info("Failed to realloc packet buffer"); | ||
| 1095 | return AFC_E_NO_MEM; | ||
| 1096 | } | ||
| 1097 | |||
| 1009 | /* Send command */ | 1098 | /* Send command */ |
| 1010 | ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH_AND_CONTENTS, path, strlen(path)+1, NULL, 0, &bytes); | 1099 | memcpy(AFC_PACKET_DATA_PTR, path, data_len); |
| 1100 | ret = afc_dispatch_packet(client, AFC_OP_REMOVE_PATH_AND_CONTENTS, data_len, NULL, 0, &bytes); | ||
| 1011 | if (ret != AFC_E_SUCCESS) { | 1101 | if (ret != AFC_E_SUCCESS) { |
| 1012 | afc_unlock(client); | 1102 | afc_unlock(client); |
| 1013 | return AFC_E_NOT_ENOUGH_DATA; | 1103 | return AFC_E_NOT_ENOUGH_DATA; |
| @@ -53,6 +53,7 @@ typedef struct { | |||
| 53 | struct afc_client_private { | 53 | struct afc_client_private { |
| 54 | service_client_t parent; | 54 | service_client_t parent; |
| 55 | AFCPacket *afc_packet; | 55 | AFCPacket *afc_packet; |
| 56 | uint32_t packet_extra; | ||
| 56 | mutex_t mutex; | 57 | mutex_t mutex; |
| 57 | int free_parent; | 58 | int free_parent; |
| 58 | }; | 59 | }; |
