static int ConnectionOpen(void* ServiceHandle, AFCCommConnection** OutConn) { void* Conn = NULL; int result = AFCConnectionOpen(ServiceHandle, 0, &Conn); *OutConn = (AFCCommConnection*)Conn; return result; }
// Opens a session on the iPod. This should be called before starting any // operation to ensure the iPod hasn't been disconnected since the last time, // or simply to initialize the first connection if it hasn't been done before. // // Returns: // IPOD_ERR_OK when successful // IPOD_IPOD_NOT_FOUND if no iPod is connected to any USB port // IPOD_COULD_NOT_CONNECT if the connection could not be established // t_iPodError CiPoTApi::OpenSession() { t_MachError ret; int timeout; CheckConnection(); if (m_ApiState == API_STATE_AVAILABLE) // Session is already open return IPOD_ERR_OK; // Checks if iPod connected for (timeout = 0; (timeout < 200) && (m_iPodState != IPOD_STATE_CONNECTED); timeout++) Sleep(10); if (m_iPodState != IPOD_STATE_CONNECTED) return IPOD_IPOD_NOT_FOUND; // Opens a session for this instance m_pDev = (t_AMDevice *)m_iPodDev; if (AMDeviceStartService(m_pDev, m_iPodAFCName, &m_iPodAFC, NULL)) { // Not jailbroken, tries to connect to the standard name m_iPodAFCName = AMSVC_AFC; ret = AMDeviceStartService(m_pDev, m_iPodAFCName, &m_iPodAFC, NULL); if (ret) return IPOD_COULD_NOT_CONNECT; } lstrcpyn(m_Serial, m_pDev->serial, sizeof(m_Serial)); if (AFCConnectionOpen(m_iPodAFC, 0, &m_iPodConnection)) return IPOD_COULD_NOT_CONNECT; m_ApiState = API_STATE_AVAILABLE; m_ConnectionID = m_GlobalConnectionID; return IPOD_ERR_OK; }
kern_return_t test_apple_AFCOperationCreateGetConnectionInfo(struct am_device *apple, CFTypeRef *response) { kern_return_t apple_return = kAMDUndefinedError; kern_return_t result = AMDeviceConnect(apple); if (SDM_MD_CallSuccessful(result)) { result = AMDeviceStartSession(apple); if (SDM_MD_CallSuccessful(result)) { service_conn_t test_apple_afc_conn; result = AMDeviceStartService(apple, CFSTR(AMSVC_AFC), &test_apple_afc_conn, NULL); if (SDM_MD_CallSuccessful(result)) { struct afc_connection *afc = NULL; result = AFCConnectionOpen(test_apple_afc_conn, 0, &afc); if (afc) { afc_operation conn_info = AFCOperationCreateGetConnectionInfo(kCFAllocatorDefault, NULL); result = AFCConnectionProcessOperation(afc, conn_info, 0); if (SDM_MD_CallSuccessful(result)) { CFTypeRef test = AFCOperationGetResultObject(conn_info); if (test) { *response = test; apple_return = kAMDSuccess; } } AFCConnectionClose(afc); } } AMDeviceStopSession(apple); } AMDeviceDisconnect(apple); } return apple_return; }
void list_files(AMDeviceRef device) { service_conn_t houseFd = start_house_arrest_service(device); afc_connection afc_conn; afc_connection* afc_conn_p = &afc_conn; AFCConnectionOpen(houseFd, 0, &afc_conn_p); read_dir(houseFd, afc_conn_p, "/"); }
void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir) { char *dir_ent; afc_connection afc_conn; if (!afc_conn_p) { afc_conn_p = &afc_conn; AFCConnectionOpen(afcFd, 0, &afc_conn_p); } printf("%s\n", dir); afc_dictionary afc_dict; afc_dictionary* afc_dict_p = &afc_dict; AFCFileInfoOpen(afc_conn_p, dir, &afc_dict_p); afc_directory afc_dir; afc_directory* afc_dir_p = &afc_dir; afc_error_t err = AFCDirectoryOpen(afc_conn_p, dir, &afc_dir_p); if (err != 0) { // Couldn't open dir - was probably a file return; } while(true) { err = AFCDirectoryRead(afc_conn_p, afc_dir_p, &dir_ent); if (!dir_ent) break; if (strcmp(dir_ent, ".") == 0 || strcmp(dir_ent, "..") == 0) continue; char* dir_joined = malloc(strlen(dir) + strlen(dir_ent) + 2); strcpy(dir_joined, dir); if (dir_joined[strlen(dir)-1] != '/') strcat(dir_joined, "/"); strcat(dir_joined, dir_ent); read_dir(afcFd, afc_conn_p, dir_joined); free(dir_joined); } AFCDirectoryClose(afc_conn_p, afc_dir_p); }
/** Connect to an iPhone device, and register callbacks. * Members of the iPhone struct that must be valid: dnc * for device notifications */ BOOL iPhone_Connect(iPhone *iphone) { if(AMDeviceConnect(iphone->handle) == 1) { iPhone_SetLastError("Device is in recovery mode. Must be activated with iTunes."); return FALSE ; } if(AMDeviceIsPaired(iphone->handle) == 0) { iPhone_SetLastError("AMDeviceIsPaired failed."); return FALSE; } if(AMDeviceValidatePairing(iphone->handle) != 0) { iPhone_SetLastError("AMDeviceValidatePairing failed."); return FALSE; } if(AMDeviceStartSession(iphone->handle) == 1) { iPhone_SetLastError("AMDeviceStartSession failed."); return FALSE; } if(AMDeviceStartService(iphone->handle, __CFStringMakeConstantString("com.apple.afc2"), &iphone->hService, NULL) != 0) { if(AMDeviceStartService(iphone->handle, __CFStringMakeConstantString("com.apple.afc"), &iphone->hService, NULL) != 0) return FALSE; } if(AFCConnectionOpen(iphone->hService, 0, &iphone->hAFC) != 0) { iPhone_SetLastError("AFCConnectionOpen failed."); return FALSE; } iphone->connected = TRUE; return TRUE; }
kern_return_t test_apple_AFCConnectionCreate(struct am_device *apple) { kern_return_t apple_return = kAMDUndefinedError; kern_return_t result = AMDeviceConnect(apple); if (SDM_MD_CallSuccessful(result)) { result = AMDeviceStartSession(apple); if (SDM_MD_CallSuccessful(result)) { service_conn_t test_apple_afc_conn; result = AMDeviceStartService(apple, CFSTR(AMSVC_AFC), &test_apple_afc_conn, NULL); if (SDM_MD_CallSuccessful(result)) { struct afc_connection *afc = NULL; result = AFCConnectionOpen(test_apple_afc_conn, 0, &afc); if (afc) { apple_return = kAMDSuccess; AFCConnectionClose(afc); } } AMDeviceStopSession(apple); } AMDeviceDisconnect(apple); } return apple_return; }
void upload_file(AMDeviceRef device) { service_conn_t houseFd = start_house_arrest_service(device); afc_file_ref file_ref; afc_connection afc_conn; afc_connection* afc_conn_p = &afc_conn; AFCConnectionOpen(houseFd, 0, &afc_conn_p); // read_dir(houseFd, NULL, "/"); if (!target_filename) { target_filename = get_filename_from_path(doc_file_path); } char *target_path = malloc(sizeof("/Documents/") + strlen(target_filename) + 1); strcat(target_path, "/Documents/"); strcat(target_path, target_filename); size_t file_size; void* file_content = read_file_to_memory(doc_file_path, &file_size); if (!file_content) { PRINT("Could not open file: %s\n", doc_file_path); exit(-1); } assert(AFCFileRefOpen(afc_conn_p, target_path, 3, &file_ref) == 0); assert(AFCFileRefWrite(afc_conn_p, file_ref, file_content, file_size) == 0); assert(AFCFileRefClose(afc_conn_p, file_ref) == 0); assert(AFCConnectionClose(afc_conn_p) == 0); free(target_path); free(file_content); }
static void cb(am_device_notification_callback_info * info, void *foo) { struct am_device *dev; if (info->msg == ADNCI_MSG_CONNECTED) { dev = info->dev; AMDeviceConnect(dev); assert(AMDeviceIsPaired(dev)); assert(!AMDeviceValidatePairing(dev)); assert(!AMDeviceStartSession(dev)); CFStringRef product = AMDeviceCopyValue(dev, 0, CFSTR("ProductVersion")); assert(product); UniChar first = CFStringGetCharacterAtIndex(product, 0); int epoch = first - '0'; Retry: {} printf("Attempting to mount image...\n"); service_conn_t afc_socket = 0; struct afc_connection *afc = NULL; assert(!AMDeviceStartService(dev, CFSTR("com.apple.afc"), &afc_socket, NULL)); assert(!AFCConnectionOpen(afc_socket, 0, &afc)); assert(!AFCDirectoryCreate(afc, "PublicStaging")); AFCRemovePath(afc, "PublicStaging/staging.dimage"); qwrite(afc, real_dmg, "PublicStaging/staging.dimage"); qwrite(afc, ddi_dmg, "PublicStaging/ddi.dimage"); service_conn_t mim_socket1 = 0; service_conn_t mim_socket2 = 0; assert(!AMDeviceStartService(dev, CFSTR("com.apple.mobile.mobile_image_mounter"), &mim_socket1, NULL)); assert(mim_socket1); CFPropertyListRef result = NULL; CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(dict, CFSTR("Command"), CFSTR("MountImage")); CFDictionarySetValue(dict, CFSTR("ImageType"), CFSTR("Developer")); CFDictionarySetValue(dict, CFSTR("ImagePath"), CFSTR("/var/mobile/Media/PublicStaging/staging.dimage")); int fd = open(real_dmg_signature, O_RDONLY); assert(fd != -1); uint8_t sig[128]; assert(read(fd, sig, sizeof(sig)) == sizeof(sig)); close(fd); CFDictionarySetValue(dict, CFSTR("ImageSignature"), CFDataCreateWithBytesNoCopy(NULL, sig, sizeof(sig), kCFAllocatorNull)); send_message(mim_socket1, dict); usleep(timesl); assert(!AFCRenamePath(afc, "PublicStaging/ddi.dimage", "PublicStaging/staging.dimage")); result = receive_message(mim_socket1); int len = CFDataGetLength(CFPropertyListCreateXMLData(NULL, result)); char* bytes = CFDataGetBytePtr(CFPropertyListCreateXMLData(NULL, result)); if(strstr(bytes, "Complete")) { char* the_service = "CopyIt"; service_conn_t socket = 0; sleep(2); printf("Image mounted, running helper...\n"); assert(!AMDeviceStartService(dev, CFStringCreateWithCStringNoCopy(NULL, the_service, kCFStringEncodingUTF8, kCFAllocatorNull), &socket, NULL)); assert(!fcntl(socket, F_SETFL, O_NONBLOCK)); assert(!fcntl(0, F_SETFL, O_NONBLOCK)); } else { printf("Failed to inject image, trying again... (if it fails, try a different time), delay ... %dus\n", timesl); timesl += 1000; goto Retry; } exit(0); } }
static void device_notification_callback(am_device_notification_callback_info *info, void *thing) { if (info->msg != ADNCI_MSG_CONNECTED) return; puts("Opened device connection."); am_device *dev = info->dev; AMDeviceConnect(dev); assert(AMDeviceIsPaired(dev)); assert(AMDeviceValidatePairing(dev) == 0); assert(AMDeviceStartSession(dev) == 0); struct afc_connection *afc; service_conn_t afc_conn; assert(AMDeviceStartService(dev, CFSTR("com.apple.afc2"), &afc_conn, NULL) == 0); assert(AFCConnectionOpen(afc_conn, 0, &afc) == 0); char cachepath[63]; const char *caches[3] = {"dyld_shared_cache_armv7s", "dyld_shared_cache_armv7", "dyld_shared_cache_armv6"}; struct afc_dictionary *dict; unsigned int cache_index; char *fullpath; size_t cachesize; for (cache_index=0; cache_index<3; cache_index++) { strcpy(cachepath, "/System/Library/Caches/com.apple.dyld/"); fullpath = strcat(cachepath, caches[cache_index]); if (AFCFileInfoOpen(afc, fullpath, &dict) == 0) { char *key, *value; while (1) { assert(AFCKeyValueRead(dict, &key, &value) == 0); if (key == NULL) break; if (strcmp(key, "st_size") == 0) { cachesize = strtol(value, NULL, 0); break; } } printf("Found cache %s with size %lu\n", fullpath, cachesize); assert(AFCKeyValueClose(dict) == 0); goto _label_hasfile; } } fprintf(stderr, "Could not find cache file.\n"); exit(2); _label_hasfile:; afc_file_ref cache; assert(AFCFileRefOpen(afc, fullpath, 1, &cache) == 0); if (is_cwd) { strcat(outputfile, "/"); strcat(outputfile, caches[cache_index]); gen_path = 1; } puts(outputfile); FILE *output = fopen(outputfile, "w"); assert(output != NULL); printf("Writing cache to %s\n", outputfile); size_t total_bytes = 0; char buffer[65536]; while (1) { unsigned int length = 65536; assert(AFCFileRefRead(afc, cache, buffer, &length) == 0); fwrite(buffer, sizeof(char), length, output); total_bytes += length; float progress = (float)total_bytes/cachesize*100; printf("Progress: %f%%\n\033[F\033[J", progress); if (length < sizeof(buffer)) break; } printf("Successfully wrote cache to %s\n", outputfile); assert(AFCFileRefClose(afc, cache) == 0); CFRunLoopStop(CFRunLoopGetCurrent()); }