Example #1
0
kern_return_t test_sdm_AFCConnectionCreate(SDMMD_AMDeviceRef sdm) {
	kern_return_t sdm_return = kAMDUndefinedError;
	kern_return_t result = SDMMD_AMDeviceConnect(sdm);
	if (SDM_MD_CallSuccessful(result)) {
		result = SDMMD_AMDeviceStartSession(sdm);
		if (SDM_MD_CallSuccessful(result)) {
			SDMMD_AMConnectionRef test_sdm_afc_conn;
			if (SDMMD_AMDeviceGetInterfaceType(sdm) == kAMDInterfaceConnectionTypeIndirect) {
				result = SDMMD_AMDeviceSecureStartService(sdm, CFSTR(AMSVC_AFC), NULL, &test_sdm_afc_conn);
			}
			else {
				result = SDMMD_AMDeviceStartService(sdm, CFSTR(AMSVC_AFC), NULL, &test_sdm_afc_conn);
			}
			if (SDM_MD_CallSuccessful(result)) {
				SDMMD_AFCConnectionRef afc = SDMMD_AFCConnectionCreate(test_sdm_afc_conn);
				if (afc) {
					sdm_return = kAMDSuccess;
					CFSafeRelease(test_sdm_afc_conn);
					CFSafeRelease(afc);
				}
			}
			SDMMD_AMDeviceStopSession(sdm);
		}
		SDMMD_AMDeviceDisconnect(sdm);
	}
	return sdm_return;
}
Example #2
0
void EnableExtendedLogging(SDMMD_AMDeviceRef device)
{
	sdmmd_return_t result = SDMMD_AMDeviceConnect(device);
	if (SDM_MD_CallSuccessful(result)) {
		result = SDMMD_AMDeviceStartSession(device);
		if (SDM_MD_CallSuccessful(result)) {
			CFTypeRef value = SDMMD_AMDeviceCopyValue(device, CFSTR(AMSVC_MOBILE_DEBUG), CFSTR(kEnableLockdownExtendedLogging));
			if (CFGetTypeID(value) == CFBooleanGetTypeID()) {
				if (!CFBooleanGetValue(value)) {
					result = SDMMD_AMDeviceSetValue(device, CFSTR(AMSVC_MOBILE_DEBUG), CFSTR(kEnableLockdownExtendedLogging), kCFBooleanTrue);
					if (SDM_MD_CallSuccessful(result)) {
						printf("Enabling extended logging...\n");
					}
				}
				else {
					printf("Extended logging already enabled.\n");
				}
			}
			else {
				PrintCFType(value);
			}
			CFSafeRelease(value);
		}
		SDMMD_AMDeviceStopSession(device);
		SDMMD_AMDeviceDisconnect(device);
	}
}
void InstallProfileToDevice(char *udid, char *path)
{
	SDMMD_AMDeviceRef device = FindDeviceFromUDID(udid);
	if (device) {
		SDMMD_AMDeviceConnect(device);
		SDMMD_AMDeviceStartSession(device);
		SDMMD_AMConnectionRef conn = NULL;
		SDMMD_AMDeviceStartService(device, CFSTR(AMSVC_MCINSTALL), NULL, &conn);
		CFDataRef config_data = CFDataCreateFromFilePath(path);

		CFMutableDictionaryRef request = SDMMD_create_dict();
		CFDictionaryAddValue(request, CFSTR("RequestType"), CFSTR("InstallProfile"));
		CFDictionaryAddValue(request, CFSTR("Payload"), config_data);

		SDMMD_ServiceSendMessage(SDMMD_TranslateConnectionToSocket(conn), request, kCFPropertyListXMLFormat_v1_0);
		CFSafeRelease(request);
		CFSafeRelease(config_data);

		CFPropertyListRef response = NULL;
		SDMMD_ServiceReceiveMessage(SDMMD_TranslateConnectionToSocket(conn), &response);
		CFSafeRelease(response);

		CFSafeRelease(conn);
		SDMMD_AMDeviceStopSession(device);
		SDMMD_AMDeviceDisconnect(device);
	}
}
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);
}
Example #5
0
void LookupAppsOnDevice(char *udid)
{
	SDMMD_AMDeviceRef device = FindDeviceFromUDID(udid);
	if (device) {
		sdmmd_return_t result = SDMMD_AMDeviceConnect(device);
		if (SDM_MD_CallSuccessful(result)) {
			result = SDMMD_AMDeviceStartSession(device);
			if (SDM_MD_CallSuccessful(result)) {
				CFDictionaryRef response;

				//CFMutableArrayRef lookupValues = CFArrayCreateMutable(kCFAllocatorDefault, 0x0, &kCFTypeArrayCallBacks);
				//CFArrayAppendValue(lookupValues, CFSTR(kAppLookupKeyCFBundleIdentifier));
				//CFArrayAppendValue(lookupValues, CFSTR("SequenceNumber"));
				CFArrayRef lookupValues = SDMMD_ApplicationLookupDictionary();
				CFMutableDictionaryRef optionsDict = SDMMD_create_dict();
				CFDictionarySetValue(optionsDict, CFSTR("ReturnAttributes"), lookupValues);

				//CFDictionarySetValue(optionsDict, CFSTR("com.apple.mobile_installation.metadata"), kCFBooleanTrue);
				//CFDictionarySetValue(optionsDict, CFSTR("BundleIDs"), kCFBooleanTrue);

				result = SDMMD_AMDeviceLookupApplications(device, optionsDict, &response);
				if (SDM_MD_CallSuccessful(result)) {
					PrintCFDictionary(response);
				}
				SDMMD_AMDeviceStopSession(device);
			}
			SDMMD_AMDeviceDisconnect(device);
		}
	}
}
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);
}
Example #7
0
SDMMD_AMConnectionRef AttachToDeviceAndService(SDMMD_AMDeviceRef device, char *service) {
	SDMMD_AMConnectionRef serviceCon = NULL;
	if (device) {
		sdmmd_return_t result = SDMMD_AMDeviceConnect(device);
		if (SDM_MD_CallSuccessful(result)) {
			result = SDMMD_AMDeviceStartSession(device);
			if (SDM_MD_CallSuccessful(result)) {
				CFStringRef serviceString = CFStringCreateWithCString(kCFAllocatorDefault, service, kCFStringEncodingMacRoman);
				result = SDMMD_AMDeviceStartService(device, serviceString, NULL, &serviceCon);
				if (SDM_MD_CallSuccessful(result)) {
					CFTypeRef deviceName = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kDeviceName));
					char *name = (char*)CFStringGetCStringPtr(deviceName,kCFStringEncodingMacRoman);
					if (!name) {
						name = "unnamed device";
					}
					printf("Connected to %s on \"%s\" ...\n",name,service);
					CFSafeRelease(deviceName);
				}
				else {
					SDMMD_AMDeviceStopSession(device);
					SDMMD_AMDeviceDisconnect(device);
					serviceCon = NULL;
				}
				CFSafeRelease(serviceString);
			}
		}
	} else {
		printf("Could not find device with that UDID\n");
	}
	return serviceCon;
}
kern_return_t test_sdm_AMDeviceLookupApplications(SDMMD_AMDeviceRef sdm, CFTypeRef *value) {
	CFDictionaryRef sdm_response = NULL;
	kern_return_t sdm_return = kAMDUndefinedError;
	kern_return_t result = SDMMD_AMDeviceConnect(sdm);
	if (SDM_MD_CallSuccessful(result)) {
		result = SDMMD_AMDeviceStartSession(sdm);
		if (SDM_MD_CallSuccessful(result)) {
			CFArrayRef lookupValues = SDMMD_ApplicationLookupDictionary();
			CFMutableDictionaryRef optionsDict = SDMMD_create_dict();
			CFDictionarySetValue(optionsDict, CFSTR("ReturnAttributes"), lookupValues);
			sdm_return = SDMMD_AMDeviceLookupApplications(sdm, optionsDict, &sdm_response);
			if (sdm_return != kAMDSuccess) {
				printf("\t\tSDMMD_AMDeviceLookupApplications: %08x %s\n",sdm_return,SDMMD_AMDErrorString(sdm_return));
			}
			else {
				*value = sdm_response;
			}
			CFSafeRelease(optionsDict);
			CFSafeRelease(lookupValues);
			SDMMD_AMDeviceStopSession(sdm);
		}
		SDMMD_AMDeviceDisconnect(sdm);
	}
	return sdm_return;
}
Example #9
0
kern_return_t test_sdm_AFCOperationCreateGetConnectionInfo(SDMMD_AMDeviceRef sdm, CFTypeRef *response) {
	kern_return_t sdm_return = kAMDUndefinedError;
	kern_return_t result = SDMMD_AMDeviceConnect(sdm);
	if (SDM_MD_CallSuccessful(result)) {
		result = SDMMD_AMDeviceStartSession(sdm);
		if (SDM_MD_CallSuccessful(result)) {
			SDMMD_AMConnectionRef test_sdm_afc_conn;
			if (SDMMD_AMDeviceGetInterfaceType(sdm) == kAMDInterfaceConnectionTypeIndirect) {
				result = SDMMD_AMDeviceSecureStartService(sdm, CFSTR(AMSVC_AFC), NULL, &test_sdm_afc_conn);
			}
			else {
				result = SDMMD_AMDeviceStartService(sdm, CFSTR(AMSVC_AFC), NULL, &test_sdm_afc_conn);
			}
			if (SDM_MD_CallSuccessful(result)) {
				SDMMD_AFCConnectionRef afc = SDMMD_AFCConnectionCreate(test_sdm_afc_conn);
				if (afc) {
					SDMMD_AFCOperationRef conn_info = SDMMD_AFCOperationCreateGetConnectionInfo();
					result = SDMMD_AFCProcessOperation(afc, &conn_info);
					if (SDM_MD_CallSuccessful(result)) {
						CFTypeRef test = SDMMD_AFCOperationGetPacketResponse(conn_info);
						if (test) {
							*response = test;
							sdm_return = kAMDSuccess;
						}
					}
					CFSafeRelease(afc);
				}
			}
			SDMMD_AMDeviceStopSession(sdm);
		}
		SDMMD_AMDeviceDisconnect(sdm);
	}
	return sdm_return;
}
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);
}
Example #11
0
kern_return_t test_sdm_AFCFileDescriptorCreateReadOperation(SDMMD_AMDeviceRef sdm, CFTypeRef *response) {
	kern_return_t sdm_return = kAMDUndefinedError;
	kern_return_t result = SDMMD_AMDeviceConnect(sdm);
	if (SDM_MD_CallSuccessful(result)) {
		result = SDMMD_AMDeviceStartSession(sdm);
		if (SDM_MD_CallSuccessful(result)) {
			SDMMD_AMConnectionRef test_sdm_afc_conn;
			if (SDMMD_AMDeviceGetInterfaceType(sdm) == kAMDInterfaceConnectionTypeIndirect) {
				result = SDMMD_AMDeviceSecureStartService(sdm, CFSTR(AMSVC_AFC), NULL, &test_sdm_afc_conn);
			}
			else {
				result = SDMMD_AMDeviceStartService(sdm, CFSTR(AMSVC_AFC), NULL, &test_sdm_afc_conn);
			}
			if (SDM_MD_CallSuccessful(result)) {
				SDMMD_AFCConnectionRef afc = SDMMD_AFCConnectionCreate(test_sdm_afc_conn);
				if (afc) {
					SDMMD_AFCOperationRef file_info = SDMMD_AFCOperationCreateGetFileInfo(CFSTR(kTestCreateFileForAFC));
					result = SDMMD_AFCProcessOperation(afc, &file_info);
					if (SDM_MD_CallSuccessful(result)) {
						CFTypeRef file_info_response = SDMMD_AFCOperationGetPacketResponse(file_info);
						int32_t size = CFStringGetIntValue(CFDictionaryGetValue(file_info_response, AFC_File_Info_Keys[AFC_File_Info_Key_size]));
						SDMMD_AFCOperationRef file_ref = SDMMD_AFCOperationCreateFileRefOpen(CFSTR(kTestCreateFileForAFC), 2);
						result = SDMMD_AFCProcessOperation(afc, &file_ref);
						if (SDM_MD_CallSuccessful(result)) {
							uint64_t fd = 0;
							CFTypeRef file_ref_response = SDMMD_AFCOperationGetPacketResponse(file_ref);
							memcpy(&fd, CFDataGetBytePtr(file_ref_response), sizeof(uint64_t));
							SDMMD_AFCOperationRef file_ref_read = SDMMD_AFCFileDescriptorCreateReadOperation(fd, size);
							result = SDMMD_AFCProcessOperation(afc, &file_ref_read);
							if (SDM_MD_CallSuccessful(result)) {
								CFTypeRef file_ref_read_response = SDMMD_AFCOperationGetPacketResponse(file_ref_read);
								if (file_ref_read_response) {
									*response = file_ref_read_response;
									sdm_return = kAMDSuccess;
								}
							}
						}
					}
					CFSafeRelease(afc);
				}
			}
			SDMMD_AMDeviceStopSession(sdm);
		}
		SDMMD_AMDeviceDisconnect(sdm);
	}
	return sdm_return;
}
kern_return_t test_sdm_AMDeviceSecureStartService(SDMMD_AMDeviceRef sdm) {
	kern_return_t sdm_return = kAMDUndefinedError;
	kern_return_t result = SDMMD_AMDeviceConnect(sdm);
	if (SDM_MD_CallSuccessful(result)) {
		result = SDMMD_AMDeviceStartSession(sdm);
		if (SDM_MD_CallSuccessful(result)) {
			SDMMD_AMConnectionRef test_sdm_conn;
			sdm_return = SDMMD_AMDeviceSecureStartService(sdm, CFSTR(AMSVC_MOBILE_IMAGE_MOUNT), NULL, &test_sdm_conn);
			if (sdm_return != kAMDSuccess) {
				printf("\t\tSDMMD_AMDeviceSecureStartService: %08x %s\n",sdm_return,SDMMD_AMDErrorString(sdm_return));
			}
			SDMMD_AMDeviceStopSession(sdm);
		}
		SDMMD_AMDeviceDisconnect(sdm);
	}
	return sdm_return;
}
Example #13
0
kern_return_t test_sdm_AFCFileDescriptorCreateWriteOperation(SDMMD_AMDeviceRef sdm, CFTypeRef *response) {
	kern_return_t sdm_return = kAMDUndefinedError;
	kern_return_t result = SDMMD_AMDeviceConnect(sdm);
	if (SDM_MD_CallSuccessful(result)) {
		result = SDMMD_AMDeviceStartSession(sdm);
		if (SDM_MD_CallSuccessful(result)) {
			SDMMD_AMConnectionRef test_sdm_afc_conn;
			if (SDMMD_AMDeviceGetInterfaceType(sdm) == kAMDInterfaceConnectionTypeIndirect) {
				result = SDMMD_AMDeviceSecureStartService(sdm, CFSTR(AMSVC_AFC), NULL, &test_sdm_afc_conn);
			}
			else {
				result = SDMMD_AMDeviceStartService(sdm, CFSTR(AMSVC_AFC), NULL, &test_sdm_afc_conn);
			}
			if (SDM_MD_CallSuccessful(result)) {
				SDMMD_AFCConnectionRef afc = SDMMD_AFCConnectionCreate(test_sdm_afc_conn);
				if (afc) {
					SDMMD_AFCOperationRef file_ref = SDMMD_AFCOperationCreateFileRefOpen(CFSTR(kTestCreateFileForAFC), 2);
					result = SDMMD_AFCProcessOperation(afc, &file_ref);
					if (SDM_MD_CallSuccessful(result)) {
						uint64_t fd = 0;
						CFTypeRef file_ref_response = SDMMD_AFCOperationGetPacketResponse(file_ref);
						memcpy(&fd, CFDataGetBytePtr(file_ref_response), sizeof(uint64_t));
						CFDataRef write_data = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)test_write_bytes, strlen(test_write_bytes));
						SDMMD_AFCOperationRef file_ref_read = SDMMD_AFCFileDescriptorCreateWriteOperation(fd, write_data);
						result = SDMMD_AFCProcessOperation(afc, &file_ref_read);
						if (SDM_MD_CallSuccessful(result)) {
							CFTypeRef file_ref_read_response = SDMMD_AFCOperationGetPacketResponse(file_ref_read);
							if (file_ref_read_response) {
								*response = file_ref_read_response;
								sdm_return = kAMDSuccess;
							}
						}
					}
					CFSafeRelease(afc);
				}
			}
			SDMMD_AMDeviceStopSession(sdm);
		}
		SDMMD_AMDeviceDisconnect(sdm);
	}
	return sdm_return;
}
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);
}
CFStringRef SDMMD_PathToDeviceSupport(SDMMD_AMDeviceRef device)
{
	CFStringRef dev_support_path = NULL;
	if (device) {
		SDMMD_AMDeviceConnect(device);
		SDMMD_AMDeviceStartSession(device);
		CFStringRef full_os_version = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kProductVersion));
		CFStringRef os_version = CFStringCreateWithSubstring(kCFAllocatorDefault, full_os_version, CFRangeMake(0, 3));
		CFSafeRelease(full_os_version);
		CFStringRef build_version = SDMMD_AMDeviceCopyValue(device, NULL, CFSTR(kBuildVersion));
		SDMMD_AMDeviceStopSession(device);
		SDMMD_AMDeviceDisconnect(device);
		if (os_version && build_version) {
			CFStringRef sdk_path = SDMMD_CopyDeviceSupportPathFromXCRUN();
			CFStringRef device_support = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@/DeviceSupport/%@"), sdk_path, os_version);
			char *device_support_cstr = SDMCFStringGetString(device_support);
			bool isDir = false;
			bool file_exists = FileExistsAtPathIsDir(device_support_cstr, &isDir);
			if (file_exists && isDir) {
				dev_support_path = CFStringCreateCopy(kCFAllocatorDefault, device_support);
			}
			else {
				CFStringRef device_support_build = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ (%@)"), device_support, build_version);
				char *device_support_build_cstr = SDMCFStringGetString(device_support_build);
				file_exists = FileExistsAtPathIsDir(device_support_build_cstr, &isDir);
				if (file_exists && isDir) {
					dev_support_path = CFStringCreateCopy(kCFAllocatorDefault, device_support_build);
				}
				Safe(free, device_support_build_cstr);
				CFSafeRelease(device_support_build);
			}
			Safe(free, device_support_cstr);
			CFSafeRelease(sdk_path);
			CFSafeRelease(device_support);
		}
		CFSafeRelease(os_version);
		CFSafeRelease(build_version);
	}
	return dev_support_path;
}
kern_return_t test_sdm_AMDeviceStartService(SDMMD_AMDeviceRef sdm) {
	kern_return_t sdm_return = kAMDUndefinedError;
	kern_return_t result = SDMMD_AMDeviceConnect(sdm);
	if (SDM_MD_CallSuccessful(result)) {
		result = SDMMD_AMDeviceStartSession(sdm);
		if (SDM_MD_CallSuccessful(result)) {
			SDMMD_AMConnectionRef test_sdm_conn;
			if (SDMMD_AMDeviceGetInterfaceType(sdm) == kAMDInterfaceConnectionTypeIndirect) {
				sdm_return = SDMMD_AMDeviceSecureStartService(sdm, CFSTR(AMSVC_AFC), NULL, &test_sdm_conn);
			}
			else {
				sdm_return = SDMMD_AMDeviceStartService(sdm, CFSTR(AMSVC_AFC), NULL, &test_sdm_conn);
			}
			if (sdm_return != kAMDSuccess) {
				printf("\t\tSDMMD_AMDeviceStartService: %08x %s\n",sdm_return,SDMMD_AMDErrorString(sdm_return));
			}
			SDMMD_AMDeviceStopSession(sdm);
		}
		SDMMD_AMDeviceDisconnect(sdm);
	}
	return sdm_return;
}
Example #17
0
void RunAppOnDeviceWithIdentifier(char *udid, char *identifier, bool waitForDebugger)
{
	SDMMD_AMDeviceRef device = FindDeviceFromUDID(udid);
	if (device) {
		sdmmd_return_t result = SDMMD_AMDeviceConnect(device);
		if (SDM_MD_CallSuccessful(result)) {
			result = SDMMD_AMDeviceStartSession(device);
			if (SDM_MD_CallSuccessful(result)) {
				CFDictionaryRef response;
				CFArrayRef lookupValues = SDMMD_ApplicationLookupDictionary();
				CFMutableDictionaryRef optionsDict = SDMMD_create_dict();
				CFDictionarySetValue(optionsDict, CFSTR("ReturnAttributes"), lookupValues);

				result = SDMMD_AMDeviceLookupApplications(device, optionsDict, &response);
				if (SDM_MD_CallSuccessful(result)) {
					CFStringRef bundleIdentifier = CFStringCreateWithCString(kCFAllocatorDefault, identifier, kCFStringEncodingUTF8);
					CFDictionaryRef details = NULL;
					if (CFDictionaryContainsKey(response, bundleIdentifier)) {
						details = CFDictionaryGetValue(response, bundleIdentifier);
					}
					CFSafeRelease(bundleIdentifier);
					if (details) {
						SDMMD_AMDeviceStopSession(device);
						SDMMD_AMDeviceDisconnect(device);
						SDMMD_AMDebugConnectionRef dconn = SDMMD_AMDebugConnectionCreateForDevice(device);
						sdmmd_return_t result = SDMMD_AMDebugConnectionStart(dconn);
						bool launchSuccess = false;
						if (SDM_MD_CallSuccessful(result)) {

							// setting max packet size
							CFMutableArrayRef maxPacketArgs = CFArrayCreateMutable(kCFAllocatorDefault, 0x0, &kCFTypeArrayCallBacks);
							CFArrayAppendValue(maxPacketArgs, CFSTR("1024"));
							DebuggerCommandRef maxPacket = SDMMD_CreateDebuggingCommand(kDebugQSetMaxPacketSize, NULL, maxPacketArgs);
							CFSafeRelease(maxPacketArgs);

							CFDataRef maxPacketResponse = NULL;
							result = SDMMD_DebuggingSend(dconn, maxPacket, &maxPacketResponse);
							CFSafeRelease(maxPacketResponse);
							SDMMD_DebuggingCommandRelease(maxPacket);

							// setting the working directory
							CFStringRef path = CFDictionaryGetValue(details, CFSTR("Path"));
							CFStringRef container = CFDictionaryGetValue(details, CFSTR("Container"));
							if (!container) {
								CFURLRef pathURL = CFURLCreateWithString(kCFAllocatorDefault, path, NULL);
								CFURLRef containerURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, pathURL);
								container = CFURLGetString(containerURL);
								CFSafeRelease(pathURL);
							}
							CFMutableArrayRef containerPathArgs = CFArrayCreateMutable(kCFAllocatorDefault, 0x0, &kCFTypeArrayCallBacks);
							CFArrayAppendValue(containerPathArgs, container);
							DebuggerCommandRef containerPath = SDMMD_CreateDebuggingCommand(kDebugQSetWorkingDir, NULL, containerPathArgs);
							CFSafeRelease(containerPathArgs);

							CFDataRef containerPathResponse = NULL;
							result = SDMMD_DebuggingSend(dconn, containerPath, &containerPathResponse);
							CFSafeRelease(containerPathResponse);
							SDMMD_DebuggingCommandRelease(containerPath);

							// setting launch args
							CFStringRef commandFormat = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("A%d,0,"), (uint32_t)CFStringGetLength(path) * 0x2);

							CFMutableArrayRef setLaunchArgsArgs = CFArrayCreateMutable(kCFAllocatorDefault, 0x0, &kCFTypeArrayCallBacks);
							CFArrayAppendValue(setLaunchArgsArgs, path);
							DebuggerCommandRef setLaunchArgs = SDMMD_CreateDebuggingCommand(kDebugCUSTOMCOMMAND, commandFormat, setLaunchArgsArgs);
							CFSafeRelease(setLaunchArgsArgs);
							CFSafeRelease(commandFormat);

							CFDataRef setLaunchArgsResponse = NULL;
							result = SDMMD_DebuggingSend(dconn, setLaunchArgs, &setLaunchArgsResponse);
							CFSafeRelease(setLaunchArgsResponse);
							SDMMD_DebuggingCommandRelease(setLaunchArgs);

							// Check for launch success
							CFMutableArrayRef launchSuccessArgs = CFArrayCreateMutable(kCFAllocatorDefault, 0x0, &kCFTypeArrayCallBacks);
							DebuggerCommandRef launchSuccessCommand = SDMMD_CreateDebuggingCommand(kDebugqLaunchSuccess, NULL, launchSuccessArgs);
							CFSafeRelease(launchSuccessArgs);

							CFDataRef launchSuccessResponse = NULL;
							result = SDMMD_DebuggingSend(dconn, launchSuccessCommand, &launchSuccessResponse);

							if (launchSuccessResponse) {
								char *launchSuccessResponseAsString = (char *)CFDataGetBytePtr(launchSuccessResponse);
								launchSuccess = !strncmp(launchSuccessResponseAsString, "OK", 2);

								if (!launchSuccess) {
									printf("Launch failure: %s\n", launchSuccessResponseAsString);
								}
							}

							CFSafeRelease(launchSuccessResponse);
							SDMMD_DebuggingCommandRelease(launchSuccessCommand);

							if (launchSuccess) {
								printf("Launch success\n");

								if (!waitForDebugger) {
									printf("Continuing with execution...\n");

									// setting thread to attach
									CFMutableArrayRef setThreadArgs = CFArrayCreateMutable(kCFAllocatorDefault, 0x0, &kCFTypeArrayCallBacks);
									CFArrayAppendValue(setThreadArgs, CFSTR(""));
									DebuggerCommandRef setThread = SDMMD_CreateDebuggingCommand(kDebugCUSTOMCOMMAND, CFSTR("Hc0"), setThreadArgs);
									CFSafeRelease(setThreadArgs);

									CFDataRef setThreadResponse = NULL;
									result = SDMMD_DebuggingSend(dconn, setThread, &setThreadResponse);
									CFSafeRelease(setThreadResponse);
									SDMMD_DebuggingCommandRelease(setThread);

									// setting continue with execution
									CFMutableArrayRef contArgs = CFArrayCreateMutable(kCFAllocatorDefault, 0x0, &kCFTypeArrayCallBacks);
									CFArrayAppendValue(contArgs, CFSTR(""));
									DebuggerCommandRef cont = SDMMD_CreateDebuggingCommand(kDebugc, NULL, contArgs);
									CFSafeRelease(contArgs);

									CFDataRef contResponse = NULL;
									result = SDMMD_DebuggingSend(dconn, cont, &contResponse);
									CFSafeRelease(contResponse);
									SDMMD_DebuggingCommandRelease(cont);
								}
								else {
									printf("Waiting for debugger to attach...\n");

									CFRunLoopRun();
								}
							}
						}
						/*
						sdmmd_return_t result = SDMMD_StartDebuggingSessionOnDevice(device, &connection);
						if (SDM_MD_CallSuccessful(result)) {
							bool launchSuccess = false;
							CFStringRef path = CFDictionaryGetValue(details, CFSTR("Path"));
							CFStringRef encodedPath = SDMMD_EncodeDebuggingString(path);
							CFStringRef container = CFDictionaryGetValue(details, CFSTR("Container"));
							if (!container) {
								CFURLRef pathURL = CFURLCreateWithString(kCFAllocatorDefault, path, NULL);
								CFURLRef containerURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, pathURL);
								container = CFURLGetString(containerURL);
								CFSafeRelease(pathURL);
								//CFSafeRelease(containerURL);
							}
							if (container) {
								CFStringRef containerPath = SDMMD_EncodeDebuggingString(container);
								sdmmd_debug_return_t dresult;
								CFStringRef maxPacket = SDMMD_EncodeDebuggingString(CFSTR("1024"));
								dresult = SDMMD_DebuggingSend(connection, KnownDebugCommands[kDebugQSetMaxPacketSize], maxPacket);
								CFSafeRelease(maxPacket);
								dresult = SDMMD_DebuggingSend(connection, KnownDebugCommands[kDebugQSetWorkingDir], containerPath);
								CFSafeRelease(containerPath);
								CFStringRef commandFormat = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d,0,%s"), (uint32_t)CFStringGetLength(encodedPath), CFStringGetCStringPtr(encodedPath, kCFStringEncodingUTF8));
								dresult = SDMMD_DebuggingSend(connection, KnownDebugCommands[kDebugA], commandFormat);
								CFSafeRelease(commandFormat);
								dresult = SDMMD_DebuggingSend(connection, KnownDebugCommands[kDebugH], CFSTR("c0"));
								dresult = SDMMD_DebuggingSend(connection, KnownDebugCommands[kDebugc], CFSTR(""));
								launchSuccess = true;
							}
							CFSafeRelease(encodedPath);
							if (launchSuccess) {
								CFRunLoopRun();
							}
						}
						*/
					}
				}
			}
		}
	}
}