sdmmd_return_t SDMMD_copy_image(SDMMD_AMDeviceRef device, CFStringRef path) { sdmmd_return_t result = kAMDUndefinedError; if (device) { result = kAMDSuccess; //SDMMD_AMDeviceConnect(device); CheckErrorAndReturn(result); result = SDMMD_AMDeviceStartSession(device); CheckErrorAndReturn(result); SDMMD_AMConnectionRef copyConn = NULL; result = SDMMD_AMDeviceSecureStartService(device, CFSTR(AMSVC_AFC), NULL, ©Conn); CheckErrorAndReturn(result); SDMMD_AFCConnectionRef copyAFCConn = SDMMD_AFCConnectionCreate(copyConn); SDMMD_AFCOperationRef makeStaging = SDMMD_AFCOperationCreateMakeDirectory(CFSTR("PublicStaging")); result = SDMMD_AFCProcessOperation(copyAFCConn, &makeStaging); CheckErrorAndReturn(result); // SDM copy file AFC char *pathString = SDMCFStringGetString(path); result = SDMMD_AMDeviceCopyFile(SDMMD_Default_AFC_CopyFile_Callback, NULL, NULL, copyAFCConn, pathString, "PublicStaging/staging.dimage"); Safe(free, pathString); CFSafeRelease(makeStaging); CFSafeRelease(copyAFCConn); CFSafeRelease(copyConn); } ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_AMDeviceInstallApp(SDMMD_AMDeviceRef device, CFStringRef path) { sdmmd_return_t result = kAMDNotConnectedError; SDMMD_AMConnectionRef connection = NULL; if (device) { result = SDMMD_AMDeviceConnect(device); CheckErrorAndReturn(result); result = SDMMD_AMDeviceStartSession(device); CheckErrorAndReturn(result); result = SDMMD_AMDeviceSecureStartService(device, CFSTR(AMSVC_AFC), NULL, &connection); CheckErrorAndReturn(result); CFStringRef keys[] = { CFSTR("PackageType") }; CFStringRef values[] = { CFSTR("Developer") }; CFDictionaryRef options = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); result = SDMMD_AMDeviceInstallApplication(device, path, options, SDMMD_Default_install_callback, NULL); CheckErrorAndReturn(result); result = SDMMD_AMDeviceStopSession(device); CheckErrorAndReturn(result); result = SDMMD_AMDeviceDisconnect(device); CheckErrorAndReturn(result); } ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_AMDeviceCopyApplication(SDMMD_AMDeviceRef device, CFStringRef path) { sdmmd_return_t result = kAMDNotConnectedError; SDMMD_AMConnectionRef connection = NULL; if (device) { result = SDMMD_AMDeviceConnect(device); CheckErrorAndReturn(result); result = SDMMD_AMDeviceStartSession(device); CheckErrorAndReturn(result); result = SDMMD_AMDeviceSecureStartService(device, CFSTR(AMSVC_AFC), NULL, &connection); CheckErrorAndReturn(result); result = SDMMD_AMDeviceTransferApplication(connection, path, NULL, SDMMD_Default_transfer_callback, NULL); CheckErrorAndReturn(result); result = SDMMD_AMDServiceConnectionInvalidate(connection); CheckErrorAndReturn(result); result = SDMMD_AMDeviceStopSession(device); CheckErrorAndReturn(result); result = SDMMD_AMDeviceDisconnect(device); CheckErrorAndReturn(result); } ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_MB2SendFile(SDMMD_AMConnectionRef conn, CFStringRef path, CFDataRef file) { sdmmd_return_t result = kAMDSuccess; result = SDMMD_MB2SendFileStream(conn, path, file); CheckErrorAndReturn(result); result = SDMMD_MB2SendEndStream(conn); CheckErrorAndReturn(result); ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_AMDebugConnectionStop(SDMMD_AMDebugConnectionRef dconn) { sdmmd_return_t result = kAMDSuccess; CFSafeRelease(dconn->connection); result = SDMMD_AMDeviceStopSession(dconn->device); CheckErrorAndReturn(result); result = SDMMD_AMDeviceDisconnect(dconn->device); CheckErrorAndReturn(result); ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_MB2SendEndStream(SDMMD_AMConnectionRef conn) { sdmmd_return_t result = kAMDSuccess; uint32_t zero_stream = 0x0; CFDataRef stream_end = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)&zero_stream, sizeof(uint32_t)); result = SDMMD_DirectServiceSend(SDMMD_TranslateConnectionToSocket(conn), stream_end); CFSafeRelease(stream_end); CheckErrorAndReturn(result); CFMutableArrayRef status_response = SDMMD_MB2StatusResponseMessage(); result = SDMMD_ServiceSendMessage(SDMMD_TranslateConnectionToSocket(conn), status_response, kCFPropertyListBinaryFormat_v1_0); ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_MB2SendFiles(SDMMD_AMConnectionRef conn, CFArrayRef paths, CFArrayRef files) { sdmmd_return_t result = kAMDSuccess; if (CFArrayGetCount(paths) == CFArrayGetCount(files)) { for (CFIndex index = 0; index < CFArrayGetCount(paths); index++) { CFStringRef path = CFArrayGetValueAtIndex(paths, index); CFDataRef file = CFArrayGetValueAtIndex(files, index); result = SDMMD_MB2SendFileStream(conn, path, file); CheckErrorAndReturn(result); } result = SDMMD_MB2SendEndStream(conn); } ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_mount_image(SDMMD_AMConnectionRef connection, CFStringRef image_type, CFDataRef signature, bool *mounted) { sdmmd_return_t result = kAMDSuccess; CFMutableDictionaryRef mountDict = SDMMD_create_dict(); if (mountDict) { CFDictionarySetValue(mountDict, CFSTR("Command"), CFSTR("MountImage")); CFDictionarySetValue(mountDict, CFSTR("ImageType"), image_type); CFDictionarySetValue(mountDict, CFSTR("ImagePath"), CFSTR("/var/mobile/Media/PublicStaging/staging.dimage")); if (signature) { CFDictionarySetValue(mountDict, CFSTR("ImageSignature"), signature); } result = SDMMD_ServiceSendMessage(SDMMD_TranslateConnectionToSocket(connection), mountDict, kCFPropertyListXMLFormat_v1_0); CFSafeRelease(mountDict); CheckErrorAndReturn(result); CFDictionaryRef response; result = SDMMD_ServiceReceiveMessage(SDMMD_TranslateConnectionToSocket(connection), (CFPropertyListRef *)&response); CheckErrorAndReturn(result); if (response) { result = SDMMD__ErrorHandler(SDMMD_ImageMounterErrorConvert, response); CheckErrorAndReturn(result); CFTypeRef status = CFDictionaryGetValue(response, CFSTR("Status")); if (status) { if (CFEqual(status, CFSTR("Complete"))) { *mounted = true; } else { result = kAMDMissingDigestError; } } } else { result = kAMDReadError; } } else { result = kAMDReadError; } ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_ServiceReceiveStream(SocketConnection handle, CFPropertyListRef *data) { CFDataRef dataBuffer = NULL; sdmmd_return_t result = SDMMD_ServiceReceive(handle, &dataBuffer); CheckErrorAndReturn(result); if (dataBuffer && CFDataGetLength(dataBuffer)) { CFReadStreamRef read = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, CFDataGetBytePtr(dataBuffer), CFDataGetLength(dataBuffer), kCFAllocatorNull); CFReadStreamOpen(read); *data = CFPropertyListCreateWithStream(kCFAllocatorDefault, read, CFDataGetLength(dataBuffer), kCFPropertyListMutableContainersAndLeaves, NULL, NULL); CFReadStreamClose(read); CFSafeRelease(read); } result = kAMDSuccess; CFSafeRelease(dataBuffer); ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_AMDebugConnectionStart(SDMMD_AMDebugConnectionRef dconn) { sdmmd_return_t result = SDMMD_AMDeviceConnect(dconn->device); CheckErrorAndReturn(result); result = SDMMD_AMDeviceStartSession(dconn->device); CheckErrorAndReturn(result); dconn->connection = SDMMD_AMDServiceConnectionCreate(0, NULL, NULL); result = SDMMD_AMDeviceStartService(dconn->device, CFSTR(AMSVC_DEBUG_SERVER), NULL, &(dconn->connection)); CheckErrorAndReturn(result); result = SDMMD_AMDeviceStopSession(dconn->device); CheckErrorAndReturn(result); result = SDMMD_AMDeviceDisconnect(dconn->device); CheckErrorAndReturn(result); ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_MB2SendFileStream(SDMMD_AMConnectionRef conn, CFStringRef path, CFDataRef file) { sdmmd_return_t result = kAMDSuccess; CFDataRef file_path = CFStringCreateExternalRepresentation(kCFAllocatorDefault, path, kCFStringEncodingUTF8, 0); result = SDMMD_ServiceSend(SDMMD_TranslateConnectionToSocket(conn), file_path); CFSafeRelease(file_path); CheckErrorAndReturn(result); char data_chunk[1] = { 0x0C }; CFMutableDataRef data_separator = CFDataCreateMutable(kCFAllocatorDefault, 0); CFDataAppendBytes(data_separator, (const UInt8 *)data_chunk, sizeof(uint8_t)); CFDataAppendBytes(data_separator, CFDataGetBytePtr(file), CFDataGetLength(file)); result = SDMMD_ServiceSend(SDMMD_TranslateConnectionToSocket(conn), data_separator); CFSafeRelease(data_separator); CheckErrorAndReturn(result); char zero_chunk[1] = { 0x0 }; CFDataRef data_end = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)zero_chunk, sizeof(uint8_t)); result = SDMMD_ServiceSend(SDMMD_TranslateConnectionToSocket(conn), data_end); CFSafeRelease(data_end); CheckErrorAndReturn(result); ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_stream_image(SDMMD_AMConnectionRef connection, CFStringRef path, CFStringRef image_type) { sdmmd_return_t result = kAMDSuccess; char fspath[0x400] = {0}; Boolean fsRep = CFStringGetFileSystemRepresentation(path, fspath, 0x400); if (fsRep) { struct stat fileStat; lstat(fspath, &fileStat); CFNumberRef size = CFNumberCreate(kCFAllocatorDefault, 0xb, &fileStat.st_size); CFMutableDictionaryRef streamDict = SDMMD_create_dict(); CFDictionarySetValue(streamDict, CFSTR("Command"), CFSTR("ReceiveBytes")); CFDictionarySetValue(streamDict, CFSTR("ImageType"), image_type); CFDictionarySetValue(streamDict, CFSTR("ImageSize"), size); result = SDMMD_ServiceSendMessage(SDMMD_TranslateConnectionToSocket(connection), streamDict, kCFPropertyListXMLFormat_v1_0); CFSafeRelease(streamDict); CFSafeRelease(size); CheckErrorAndReturn(result); CFDictionaryRef response; result = SDMMD_ServiceReceiveMessage(SDMMD_TranslateConnectionToSocket(connection), (CFPropertyListRef *)&response); CheckErrorAndReturn(result); if (response) { result = SDMMD__ErrorHandler(SDMMD_ImageMounterErrorConvert, response); CheckErrorAndReturn(result); CFTypeRef status = CFDictionaryGetValue(response, CFSTR("Status")); if (status) { if (CFStringCompare(status, CFSTR("ReceiveBytesAck"), 0) == 0) { // block code CFDataRef image_file = CFDataCreateFromPath(path); uint64_t offset = 0; uint64_t remainder = 0; while (offset < fileStat.st_size) { remainder = (fileStat.st_size - offset); remainder = (remainder > kDeveloperImageStreamSize ? kDeveloperImageStreamSize : remainder); CFRange current_read = CFRangeMake((CFIndex)offset, (CFIndex)remainder); CFDataRef image_stream = CFDataCreateFromSubrangeOfData(image_file, current_read); result = SDMMD_DirectServiceSend(SDMMD_TranslateConnectionToSocket(connection), image_stream); CheckErrorAndReturn(result); offset += remainder; CFSafeRelease(image_stream); } CFDictionaryRef getStatus; result = SDMMD_ServiceReceiveMessage(SDMMD_TranslateConnectionToSocket(connection), (CFPropertyListRef *)&getStatus); if (result == 0) { result = SDMMD__ErrorHandler(SDMMD_ImageMounterErrorConvert, response); CheckErrorAndReturn(result); CFTypeRef streamStatus = CFDictionaryGetValue(getStatus, CFSTR("Status")); if (streamStatus) { if (CFStringCompare(streamStatus, CFSTR("Complete"), 0x0) == 0) { result = kAMDSuccess; } } } CFSafeRelease(getStatus); CFSafeRelease(image_file); } } else { result = kAMDUndefinedError; } } else { result = kAMDReadError; } } else { result = kAMDNoResourcesError; } ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_AMDeviceTransferApplication(SDMMD_AMConnectionRef conn, CFStringRef path, CFDictionaryRef options, CallBack transferCallback, void* unknown) { sdmmd_return_t result = kAMDInvalidArgumentError; if (path) { if (conn) { char *cpath = calloc(1, sizeof(char[1024])); ATR_UNUSED struct stat pathStat, remoteStat; Boolean status = CFStringGetCString(path, cpath, 1024, kCFStringEncodingUTF8); if (status) { CFURLRef deviceURL = SDMMD__AMDCFURLCreateFromFileSystemPathWithSmarts(path); if (deviceURL) { CFStringRef lastComp = CFURLCopyLastPathComponent(deviceURL); if (lastComp) { CFURLRef base = SDMMD__AMDCFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault, CFSTR("PublicStaging"), 0, true); CFURLRef copy = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, base, lastComp, true); char *copyPath = calloc(1024, sizeof(char)); SDMMD__AMDCFURLGetCStringForFileSystemPath(copy, copyPath); SDMMD_fire_callback_767f4(transferCallback, unknown, 0, CFSTR("PreflightingTransfer")); //SDMMD_preflight_transfer(&cpath, &pathStat, &remoteStat); SDMMD_fire_callback_767f4(transferCallback, unknown, 0, CFSTR("TransferingPackage")); SDMMD_AFCConnectionRef afcConn = SDMMD_AFCConnectionCreate(conn);//(r12, conn, 0x0, 0x0, &var_72); if (afcConn) { result = kAMDSuccess; } CheckErrorAndReturn(result); result = SDMMD_AMDeviceCopy(afcConn, cpath, copyPath); /* CFDataRef touchResponse; result = SDMMD_check_can_touch(afcConn, &touchResponse); CheckErrorAndReturn(result); CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(r12, r13); result = SDMMD_make_path(afcConn, parent); CheckErrorAndReturn(result); result = SDMMD_nuke_path(afcConn, r13); if ((result | 0x8) == 0x8) { int statResult = lstat(cpath, &pathStat); if (statResult != 0xff) { if ((var_84 & 0xffff & 0xf000) != 0xa000) { if (rax == 0x8000) { rbx = SDMMD_copy_touch_file(&remoteStat, transferCallback, unknown, afcConn, &cpath, ©Path); } else { if (rax == 0x4000) { rbx = SDMMD_copy_directory(&remoteStat, transferCallback, unknown, afcConn, &cpath, ©Path); } else { printf("transfer_package: Don't know how to copy this type of file: %s\n", cpath); } } } else { rbx = SDMMD_copy_symlink(afcConn, &cpath, ©Path); } r14 = 0x0; if (rbx != 0x0) { r9 = SDMMD_AFCErrorString(rbx); printf("transfer_package: Could not copy %s to %s on the device.\n", cpath, copyPath); result = kAMDUndefinedError; } result = SDMMD_AFCConnectionClose(afcConn); if (result) { printf("transfer_package: Could not close AFC connection. error: %i\n", result); } CFSafeRelease(r12); } */ CFSafeRelease(base); CFSafeRelease(copy); } CFSafeRelease(lastComp); } CFSafeRelease(deviceURL); } else { result = kAMDUndefinedError; } Safe(free, cpath); } } ExitLabelAndReturn(result); }
sdmmd_return_t SDMMD_perform_command(SDMMD_AMConnectionRef conn, CFStringRef command, uint64_t code, CallBack handle, uint32_t argsCount, void* paramStart, ...) { sdmmd_return_t result = kAMDSuccess; CFMutableDictionaryRef message = SDMMD_create_dict(); if (message) { va_list args; CFDictionarySetValue(message, CFSTR("Command"), command); va_start(args, paramStart); CFTypeRef key, value; for (uint32_t i = 0; i < argsCount; i++) { key = va_arg(args, CFTypeRef); value = va_arg(args, CFTypeRef); CFDictionarySetValue(message, key, value); i++; } va_end(args); SocketConnection sock = SDMMD_TranslateConnectionToSocket(conn); result = SDMMD_ServiceSendStream(sock, message, kCFPropertyListXMLFormat_v1_0); CFSafeRelease(message); if (result == 0) { CFDictionaryRef response = NULL; result = SDMMD_ServiceReceiveStream(sock, (CFPropertyListRef*)&response); if (result == 0 && response) { while (result == 0) { result = SDMMD__ErrorHandler(SDMMD__ConvertServiceError, response); CheckErrorAndReturn(result); CFTypeRef status = CFDictionaryGetValue(response, CFSTR("Status")); if (status) { if (CFStringCompare(status, CFSTR("Complete"), 0) != 0) { CFArrayRef responses = CFDictionaryGetValue(response, CFSTR("CurrentList")); if (responses) { uint64_t count = CFArrayGetCount(responses); for (uint32_t i = 0; i < count; i++) { CFDictionaryRef value = CFArrayGetValueAtIndex(responses, i); handle(value, paramStart); } } else { handle(response, 0); } } else { break; } } SDMMD_ServiceReceiveStream(sock, (CFPropertyListRef*)&response); } } else { result = kAMDReceiveMessageError; printf("call_and_response: Could not receive response from proxy.\n"); } } else { result = kAMDSendMessageError; printf("call_and_response: Could not send request to proxy.\n"); } } else { result = kAMDUndefinedError; } ExitLabelAndReturn(result); }