// IOSApi.cpp : 定义 DLL 应用程序的导出函数。
//#include "stdafx.h"
#include "IOSApi.h"
#include "IOSConnect.h"
#include "io.h"
#include "common.h"#include "Plist.hpp"
// 这是导出变量的一个示例
IOSAPI int nIOSApi=0;// 这是导出函数的一个示例。
IOSAPI int fnIOSApi(void)
{
return 42;
}// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 IOSApi.h
CIOSApi::CIOSApi()
{
return ;
}#ifdef __cplusplus
extern "C"
{
#endif
//初始化
IOSAPI UINT IOS::Initialize(void){
UINT ret = iTunesApi::InitApi();
iTunesVersion = iTunesApi::GetiTunesVersion();
wchar_t wpsz_computer_name[512] = { 0 };
DWORD name_size = 0;
wstring wstr;
GetComputerName(NULL, &name_size);
GetComputerName(wpsz_computer_name, &name_size);
ComputerName = wpsz_computer_name;
return ret;
}
//释放
IOSAPI BOOL IOS::Dispose(void){
return iTunesApi::ReleaseApi();
}IOSAPI void IOS::SetApplicationDataFolder(const wchar_t* wpsz_path){
iTunesApi::SetApplicationDataFolder(wpsz_path);
}
IOSAPI void IOS::GetApplicationDataFolder(wchar_t* wpsz_path){
iTunesApi::GetApplicationDataFolder(wpsz_path);
}//注册连接回调函数
IOSAPI BOOL IOS::RegisterOnConnectListener(pConnecttion callback, void* pUserData){
IOSConnect::OnConnect = callback;
IOSConnect::OnConnectUserData = pUserData;
return TRUE;
}//注册断开回调函数
IOSAPI BOOL IOS::RegisterOnDisConnectListener(pConnecttion callback, void* pUserData){
IOSConnect::OnDisConnect = callback;
IOSConnect::OnDisconnectUserData = pUserData;
return TRUE;
}//开始监听
IOSAPI BOOL IOS::StartListen(){
HANDLE hDevice;
// 异步监听。
iTunesApi::AMDeviceNotificationSubscribe(IOSConnect::DeviceOnConnection,0,0,0,&hDevice);
return TRUE;
}//打开设备
IOSAPI BOOL IOS::DeviceOpen(HANDLE hDevice){
UINT ret = 0;
if((ret = iTunesApi::AMDeviceConnect(hDevice)) != 0)
return FALSE;
if((ret = iTunesApi::AMDeviceIsPaired(hDevice)) != 1)
return FALSE;
if((ret = iTunesApi::AMDeviceValidatePairing(hDevice)) != 0)
return FALSE;
if((ret = iTunesApi::AMDeviceStartSession(hDevice)) != 0)
return FALSE;
return TRUE;
}//保持设备打开状态
IOSAPI BOOL IOS::DeviceKeepConnect(HANDLE hDevice){
std::wstring str_SerialNumber;
UINT ret = 0;
IOSConnect::GetCharProperty(hDevice, str_SerialNumber, "SerialNumber");
if ((ret = iTunesApi::AMDeviceStartSession(hDevice))!=0)
{
if((ret = iTunesApi::AMDeviceDisconnect(hDevice)) != 0)
return FALSE;
if((ret = iTunesApi::AMDeviceConnect(hDevice)) != 0)
return FALSE;
if((ret = iTunesApi::AMDeviceIsPaired(hDevice)) != 1)
return FALSE;
if((ret = iTunesApi::AMDeviceValidatePairing(hDevice)) != 0)
return FALSE;
if((ret = iTunesApi::AMDeviceStartSession(hDevice)) != 0)
return FALSE;
}
return TRUE;
}//关闭设备
IOSAPI BOOL IOS::DeviceClose(HANDLE hDevice){
iTunesApi::AMDeviceStopSession(hDevice);
iTunesApi::AMDeviceDisconnect(hDevice);
return TRUE;
}//获取设备基本信息
IOSAPI BOOL IOS::GetDeviceInformation(HANDLE hDevice, ios_device_information* info){
IOSConnect::GetCharProperty(hDevice, info->SerialNumber, "SerialNumber"); // 序列号
IOSConnect::GetCharProperty(hDevice, info->DeviceName, "DeviceName"); // 设备名称
IOSConnect::GetCharProperty(hDevice, info->UniqueDeviceID, "UniqueDeviceID"); // 设备唯一ID
IOSConnect::GetCharProperty(hDevice, info->ProductType, "ProductType"); // 产品类型
IOSConnect::GetCharProperty(hDevice, info->DeviceClass, "DeviceClass"); // 设备类型
IOSConnect::GetCharProperty(hDevice, info->ProductVersion, "ProductVersion"); // 系统版本
IOSConnect::GetCharProperty(hDevice, info->ModelNumber, "ModelNumber"); // 设备型号
IOSConnect::GetCharProperty(hDevice, info->BuildVersion, "BuildVersion"); // 产品版本
IOSConnect::GetCharProperty(hDevice, info->HardwareModel, "HardwareModel"); // 硬件型号
IOSConnect::GetCharProperty(hDevice, info->DeviceColor, "DeviceColor"); // 设备颜色
IOSConnect::GetCharProperty(hDevice, info->RegionInfo, "RegionInfo"); // 地区信息
IOSConnect::GetCharProperty(hDevice, info->FirmwareVersion, "FirmwareVersion"); // 固件版本
IOSConnect::GetCharProperty(hDevice, info->ActivationState, "ActivationState"); // 激活状态
IOSConnect::GetBoolProperty(hDevice, info->ActivationStateAcknowledged, "ActivationStateAcknowledged"); // 激活确认 bool
IOSConnect::GetCharProperty(hDevice, info->BasebandVersion, "BasebandVersion"); // 调制解调器固件
IOSConnect::GetBoolProperty(hDevice, info->iTunesHasConnected, "iTunesHasConnected");// itunes 连接 bool
IOSConnect::GetCharProperty(hDevice, info->BluetoothAddress, "BluetoothAddress"); // 蓝牙
IOSConnect::GetCharProperty(hDevice, info->WiFiAddress, "WiFiAddress"); //WIFI
IOSConnect::GetCharProperty(hDevice, info->InternationalMobileEquipmentIdentity, "InternationalMobileEquipmentIdentity");//IMEI
IOSConnect::GetCharProperty(hDevice, info->IntegratedCircuitCardIdentity, "IntegratedCircuitCardIdentity");
IOSConnect::GetBoolProperty(hDevice, info->BatteryIsCharging, "BatteryIsCharging", "com.apple.mobile.battery");
IOSConnect::GetNumberProperty(hDevice, info->BatteryCurrentCapacity, "BatteryCurrentCapacity", "com.apple.mobile.battery");
IOSConnect::GetCharProperty(hDevice, info->CPUArchitecture, "CPUArchitecture");
IOSConnect::GetCharProperty(hDevice, info->Keyboard, "Keyboard", "com.apple.international");
IOSConnect::GetBoolProperty(hDevice, info->Uses24HourClock, "Uses24HourClock");
IOSConnect::GetCharProperty(hDevice, info->TimeZone, "TimeZone");
IOSConnect::GetCharProperty(hDevice, info->AppleID, "AppleID", "com.apple.itunesstored");
return TRUE;
}//获取设备容量信息
IOSAPI void IOS::GetDiskusage(HANDLE hDevice, char* pszLibraryID, ios_device_usage* usage){
HANDLE handleResult,cfName;
cfName = iTunesApi::CFStringMakeConstantString("com.apple.disk_usage");
handleResult = iTunesApi::AMDeviceCopyValue(hDevice, cfName, iTunesApi::CFStringMakeConstantString("TotalDiskCapacity"));
iTunesApi::GetCFInt64Number(handleResult, usage->TotalDiskCapacity);
handleResult = iTunesApi::AMDeviceCopyValue(hDevice, cfName, iTunesApi::CFStringMakeConstantString("TotalSystemAvailable"));
iTunesApi::GetCFInt64Number(handleResult, usage->TotalSystemAvailable);
handleResult = iTunesApi::AMDeviceCopyValue(hDevice, cfName, iTunesApi::CFStringMakeConstantString("TotalSystemCapacity"));
iTunesApi::GetCFInt64Number(handleResult, usage->TotalSystemCapacity);
handleResult = iTunesApi::AMDeviceCopyValue(hDevice, cfName, iTunesApi::CFStringMakeConstantString("TotalDataCapacity"));
iTunesApi::GetCFInt64Number(handleResult, usage->TotalDataCapacity);
handleResult = iTunesApi::AMDeviceCopyValue(hDevice, cfName, iTunesApi::CFStringMakeConstantString("TotalDataAvailable"));
iTunesApi::GetCFInt64Number(handleResult, usage->TotalDataAvailable);
}//服务发送数据
IOSAPI int IOS::ServiceConnectionSend(HANDLE h,const char* pszBuffer, int len){
char lenchar[4] = { 0 };
memcpy(lenchar, &len, 4);
int ret = iTunesApi::AMDServiceConnectionSend(h, lenchar, 4);
int pos = 0;
int relsend = 0;
if (ret == 4){
do
{
if ((pos + SERVICE_DATA_SECTION) < len) relsend = SERVICE_DATA_SECTION;
else relsend = len - pos;
ret = iTunesApi::AMDServiceConnectionSend(h, (char*)(pszBuffer + pos), relsend);
if (ret != relsend)
return -1;
pos += relsend;
} while (pos<len);
Sleep(50);
return len;
}
else
return -1;
}
//服务收取数据
IOSAPI int IOS::ServiceConnectionReceive(HANDLE h, char*& pszBuffer){
int ret = -1;
void* hBuffer = 0;
int len_buffer;
int pos = 0;
int left = 0;
ret = iTunesApi::AMDServiceConnectionReceive(h, &len_buffer, 4);
if (ret == 4){//buffer length
pszBuffer = (char*)malloc(len_buffer);
do
{
if (pos + SECTIONSIZE < len_buffer)
left = SECTIONSIZE;
else
left = len_buffer - pos;
ret = iTunesApi::AMDServiceConnectionReceive(h, pszBuffer + pos, left);
if (ret<=0)
return -1;
pos += ret;
} while (pos<len_buffer);
return len_buffer;
}
return -1;
}//开启服务
IOSAPI IOSServiceHandle* IOS::DeviceOpenService(HANDLE hDevice, char* pszServiceName){
int iRet = -1;
HANDLE hCFServiceName = iTunesApi::CFStringMakeConstantString(pszServiceName);
HANDLE hServiceHandle = 0;
iRet = iTunesApi::AMDeviceSecureStartService(hDevice,hCFServiceName,NULL,&hServiceHandle);
if(hServiceHandle == 0)return NULL;
UINT hServiceSocketHandle = iTunesApi::AMDServiceConnectionGetSocket(hServiceHandle);
iRet = iTunesApi::AMDServiceConnectionGetSecureIOContext(hServiceHandle);
IOSServiceHandle* pService = new IOSServiceHandle();
pService->pServiceHandle = hServiceHandle;
pService->pServiceSocketHandle = hServiceSocketHandle;
return pService;
}//打开文件服务
IOSAPI BOOL IOS::OpenAfc(UINT pServiceSocketHandle, unsigned int io_timeout, HANDLE* pAfcServiceHandle){
int iRet = iTunesApi::AFCConnectionOpen(pServiceSocketHandle,io_timeout,pAfcServiceHandle);
if (iRet == 0)
{
return TRUE;
}
return FALSE;
}//获取目录信息
IOSAPI AFCFileInfomation* IOS::GetPathInfo(HANDLE pAfcServiceHandle, const wchar_t* pszPath){
std::string str_path;
common::G2Utf8(common::WC2MB(pszPath).c_str(), str_path);
HANDLE pFileInfo = NULL;
int iRet = -1;
iRet = iTunesApi::AFCFileInfoOpen(pAfcServiceHandle, str_path.c_str(), &pFileInfo);
if (iRet!=0 || pFileInfo== NULL)
return NULL;
HANDLE pKey = NULL,pValue = NULL;
AFCPathDictPair* pInfoRoot,*pCurrent;
pInfoRoot = pCurrent = NULL;
iRet = iTunesApi::AFCKeyValueRead(pFileInfo,&pKey,&pValue);
while (iRet == 0 && pKey && pValue)
{
AFCPathDictPair* pInfo = (AFCPathDictPair*)malloc(sizeof(AFCPathDictPair));
memset(pInfo,0,sizeof(AFCPathDictPair));
strcpy(pInfo->pszKey,(char*)pKey);
strcpy(pInfo->pszValue,(char*)pValue);
if (pInfoRoot==NULL)
{
pInfoRoot = pCurrent = pInfo;
}else{
pCurrent->pNext = pInfo;
pCurrent = pInfo;
}
iRet = iTunesApi::AFCKeyValueRead(pFileInfo,&pKey,&pValue);
}
iTunesApi::AFCKeyValueClose(pFileInfo);
if (pInfoRoot)
{
AFCFileInfomation* infomation = (AFCFileInfomation*)malloc(sizeof(AFCFileInfomation));
memset(infomation,0,sizeof(AFCFileInfomation));
wcscpy(infomation->pszFilePath,pszPath);
char pszType[512] = {0};
pCurrent = pInfoRoot;
while (pCurrent)
{
if (strcmp(pCurrent->pszKey,"st_blocks") == 0)
infomation->st_blocks = atol(pCurrent->pszValue);
else if (strcmp(pCurrent->pszKey,"st_size") == 0)
infomation->st_size = atol(pCurrent->pszValue);
else if (strcmp(pCurrent->pszKey,"st_mtime") == 0)
infomation->st_mtime = atol(pCurrent->pszValue);
else if (strcmp(pCurrent->pszKey,"st_nlink") == 0)
infomation->st_nlink = atol(pCurrent->pszValue);
else if (strcmp(pCurrent->pszKey,"st_birthtime") == 0)
infomation->st_birthtime = atol(pCurrent->pszValue);
else if (strcmp(pCurrent->pszKey,"st_ifmt") == 0)
{
if (strcmp(pCurrent->pszValue,"S_IFDIR") == 0)
infomation->st_ifmt = DFS_Folder;
else if (strcmp(pCurrent->pszValue,"S_IFREG") == 0)
infomation->st_ifmt = DFS_File;
else if (strcmp(pCurrent->pszValue,"S_IFBLK") == 0)
infomation->st_ifmt = DFS_BlockDevice;
else if (strcmp(pCurrent->pszValue,"S_IFCHR") == 0)
infomation->st_ifmt = DFS_CharDevice;
else if (strcmp(pCurrent->pszValue,"S_IFIFO") == 0)
infomation->st_ifmt = DFS_FIFO;
else if (strcmp(pCurrent->pszValue,"S_IFLNK") == 0)
infomation->st_ifmt = DFS_Link;
else if (strcmp(pCurrent->pszValue,"S_IFMT") == 0)
infomation->st_ifmt = DFS_FileMask;
else if (strcmp(pCurrent->pszValue,"S_IFSOCK") == 0)
infomation->st_ifmt = DFS_Socket;
else
infomation->st_ifmt = DFS_Unknown;
}
pCurrent = pCurrent->pNext;
}
return infomation;
}
return NULL;
}//读取设备上文件内容
IOSAPI LONG64 IOS::ReadDeviceFile(HANDLE pAfcServiceHandle, const wchar_t* pszRemote, char* pszBuffer){
std::string str_remote;
common::G2Utf8(common::WC2MB(pszRemote).c_str(), str_remote);
LONG64 hRemoteFile;
int ret = -1;
LONG64 filelength = 0;
LONG64 pos = 0;
LONG64 left = 0;
AFCFileInfomation* fileinfo = GetPathInfo(pAfcServiceHandle, pszRemote);
if (!fileinfo || fileinfo->st_ifmt != DFS_File)
return FALSE;
filelength = fileinfo->st_size;
ret = iTunesApi::AFCFileRefOpen(pAfcServiceHandle, str_remote.c_str(), 1, 0, &hRemoteFile);
if (ret == 0){
char* buffer = NULL;
buffer = (char*)malloc((size_t)filelength);
memset(buffer, 0, (size_t)filelength);
do
{
if (pos + SECTIONSIZE < filelength)
left = SECTIONSIZE;
else
left = filelength - pos;
iTunesApi::AFCFileRefRead(pAfcServiceHandle, hRemoteFile, buffer + pos, &left);
pos += left;
} while (pos < filelength);
memcpy(pszBuffer, buffer, (size_t)filelength);
ret = iTunesApi::AFCFileRefClose(pAfcServiceHandle, hRemoteFile);
return filelength;
}
return 0;
}//写入数据到设备上
IOSAPI BOOL IOS::WriteDeviceFile(HANDLE pAfcServiceHandle, const wchar_t* pszRemote, const char* pszBuffer, long bufferSize){
std::string str_remote;
common::G2Utf8(common::WC2MB(pszRemote).c_str(), str_remote);
LONG64 hRemoteFile;
int ret = -1;
LONG64 pos = 0;
LONG64 left = 0;AFCFileInfomation* fileinfo = GetPathInfo(pAfcServiceHandle, pszRemote);
if (fileinfo && fileinfo->st_ifmt == DFS_File) DeletePath(pAfcServiceHandle, pszRemote);ret = iTunesApi::AFCFileRefOpen(pAfcServiceHandle, str_remote.c_str(), 3, 0, &hRemoteFile);
if (ret == 0){
char* buffer = (char*)pszBuffer;
do
{
if (pos + SECTIONSIZE < bufferSize)
left = SECTIONSIZE;
else
left = bufferSize - pos;
iTunesApi::AFCFileRefWrite(pAfcServiceHandle, hRemoteFile, buffer, left);
pos += left;
buffer = buffer + left;
} while (pos < bufferSize);
ret = iTunesApi::AFCFileRefClose(pAfcServiceHandle, hRemoteFile);
return TRUE;
}
return FALSE;
}//下载文件
IOSAPI BOOL IOS::DownloadDeviceFile(HANDLE pAfcServiceHandle, const wchar_t* pszRemote, const wchar_t* pszLocal){
std::string str_remote;
std::string str_local;
common::G2Utf8(common::WC2MB(pszRemote).c_str(), str_remote);
common::G2Utf8(common::WC2MB(pszLocal).c_str(), str_local);
LONG64 hRemoteFile;
int ret = -1;
LONG64 filelength = 0;
LONG64 pos = 0;
LONG64 left = 0;
AFCFileInfomation* fileinfo = GetPathInfo(pAfcServiceHandle, pszRemote);
if (!fileinfo || fileinfo->st_ifmt != DFS_File)
return FALSE;
filelength = fileinfo->st_size;
ret = iTunesApi::AFCFileRefOpen(pAfcServiceHandle, str_remote.c_str(), 1, 0, &hRemoteFile);
if (ret == 0){
FILE* file = _wfopen(pszLocal, L"rb");
if (file){ fclose(file); _wremove(pszLocal); }
file = _wfopen(pszLocal, L"wb");
fseek(file, 0, SEEK_SET);
char* buffer = NULL;
buffer = (char*)malloc(SECTIONSIZE);
memset(buffer, 0, SECTIONSIZE);
if (!file){
ret = iTunesApi::AFCFileRefClose(pAfcServiceHandle, hRemoteFile);
return FALSE;
}
do
{
if (pos + SECTIONSIZE < filelength)
left = SECTIONSIZE;
else
left = filelength - pos;
iTunesApi::AFCFileRefRead(pAfcServiceHandle, hRemoteFile, buffer, &left);
fwrite(buffer, 1, (size_t)left, file);
pos += left;
} while (pos < filelength);
free(buffer);
fclose(file);
ret = iTunesApi::AFCFileRefClose(pAfcServiceHandle, hRemoteFile);
return TRUE;
}
return FALSE;
}//上传文件
IOSAPI BOOL IOS::UploadDeviceFile(HANDLE pAfcServiceHandle, const wchar_t* pszRemote, const wchar_t* pszLocal){
std::string str_remote;
std::string str_local;
common::G2Utf8(common::WC2MB(pszRemote).c_str(), str_remote);
common::G2Utf8(common::WC2MB(pszLocal).c_str(), str_local);
LONG64 hRemoteFile;
int ret = -1;
LONG64 filelength = 0;
LONG64 pos = 0;
LONG64 left = 0;AFCFileInfomation* fileinfo = GetPathInfo(pAfcServiceHandle, pszRemote);
if (fileinfo && fileinfo->st_ifmt == DFS_File) DeletePath(pAfcServiceHandle, pszRemote);ret = iTunesApi::AFCFileRefOpen(pAfcServiceHandle, str_remote.c_str(), 3, 0, &hRemoteFile);
if (ret == 0){
FILE* file = _wfopen(pszLocal, L"rb");
if (!file){
ret = iTunesApi::AFCFileRefClose(pAfcServiceHandle, hRemoteFile);
return FALSE;
}
fseek(file, 0, SEEK_END);
filelength = ftell(file);
fseek(file, 0, SEEK_SET);
char* buffer = NULL;
buffer = (char*)malloc(SECTIONSIZE);
memset(buffer, 0, SECTIONSIZE);
do
{
if (pos + SECTIONSIZE < filelength)
left = SECTIONSIZE;
else
left = filelength - pos;
fread(buffer, 1, (size_t)left, file);
iTunesApi::AFCFileRefWrite(pAfcServiceHandle, hRemoteFile, buffer, left);
pos += left;
} while (pos < filelength);
free(buffer);
fclose(file);
ret = iTunesApi::AFCFileRefClose(pAfcServiceHandle, hRemoteFile);
return TRUE;
}
return FALSE;
}//获取二级目录信息
IOSAPI std::vector<AFCFileInfomation*>* IOS::DirPath(HANDLE pAfcServiceHandle,const wchar_t* pszPath){
std::string str_path;
common::G2Utf8(common::WC2MB(pszPath).c_str(), str_path);
std::vector<AFCFileInfomation*>* pPathVector = new std::vector<AFCFileInfomation*>();
HANDLE pDirInfo = NULL;
HANDLE pBuffer = NULL;
wchar_t pszTempPath[512] = {0};
wchar_t pszFolder[512] = {0};
wchar_t pszFullPath[512] = {0};
int iLength = -1;
wcscpy(pszFolder,pszPath);
iLength = wcslen(pszFolder);
if (pszFolder[iLength-1] != '/')
wcscat(pszFolder,L"/");
int iRet = -1;
iRet = iTunesApi::AFCDirectoryOpen(pAfcServiceHandle, str_path.c_str(), &pDirInfo);
if (iRet!=0)
return NULL; // iRet = 1; ??
iTunesApi::AFCDirectoryRead(pAfcServiceHandle,pDirInfo,&pBuffer);
while (pBuffer)
{
wcscpy(pszTempPath,(wchar_t*)pBuffer);
if (wcscmp(pszTempPath,L".") != 0 && wcscmp(pszTempPath,L"..") != 0){
wsprintf(pszFullPath,L"%s%s",pszFolder,pszTempPath);
AFCFileInfomation* info = GetPathInfo(pAfcServiceHandle,pszFullPath);
if (info)
pPathVector->push_back(info);
}
pBuffer = NULL;
iTunesApi::AFCDirectoryRead(pAfcServiceHandle,pDirInfo,&pBuffer);
}
return pPathVector;
}//删除路径
IOSAPI BOOL IOS::DeletePath(HANDLE pAfcServiceHandle,const wchar_t* pszPath)
{
std::string str_path;
common::G2Utf8(common::WC2MB(pszPath).c_str(), str_path);
if (GetPathInfo(pAfcServiceHandle, pszPath))
{
if (iTunesApi::AFCRemovePath(pAfcServiceHandle, str_path.c_str()) == 0)
return TRUE;
}
return FALSE;
}//创建文件夹
IOSAPI int IOS::DirectoryCreate(HANDLE pAfcServiceHandle, const wchar_t *path)
{
std::string str_path;
common::G2Utf8(common::WC2MB(path).c_str(), str_path);
return iTunesApi::AFCDirectoryCreate(pAfcServiceHandle, str_path.c_str());
}// 判断文件是否存在
IOSAPI bool IOS::FileExist(HANDLE pAfcServiceHandle, const wchar_t *path)
{
std::string str_path;
common::G2Utf8(common::WC2MB(path).c_str(), str_path);
LONG64 pFileHandle = 0;
int ret = iTunesApi::AFCFileRefOpen(pAfcServiceHandle, str_path.c_str(), 1, 0, &pFileHandle);
if (ret == 0)
ret = iTunesApi::AFCFileRefClose(pAfcServiceHandle, pFileHandle);
return ret == 0;
}//从XML转换成Plist
IOSAPI void IOS::GetPlistDataFromXmlData(std::vector<char> source_data, std::vector<char>& plist_data){
CFStringRef cferror;
bool ret;
CFDataRef cfdata = iTunesApi::CFDataCreate(nullptr, (const uint8_t*)source_data.data(), source_data.size());
CFPropertyListRef cfplist = iTunesApi::CFPropertyListCreateFromXMLData(nullptr, cfdata, 0, &cferror);
iTunesApi::CFRelease(cfdata);
CFWriteStreamRef cfstream = iTunesApi::CFWriteStreamCreateWithAllocatedBuffers(nullptr, nullptr);
ret = iTunesApi::CFWriteStreamOpen(cfstream);
if (ret){
CFIndex write_length = iTunesApi::CFPropertyListWriteToStream(cfplist, cfstream, kCFPropertyListBinaryFormat_v1_0, &cferror);
CFTypeRef cfproperty = iTunesApi::CFWriteStreamCopyProperty(cfstream, iTunesApi::kCFStreamPropertyDataWritten);
CFIndex property_length = iTunesApi::CFDataGetLength(cfproperty);
const uint8_t* property_buffer = iTunesApi::CFDataGetBytePtr(cfproperty);
for (int i = 0; i < property_length; i++)
{
plist_data.push_back(property_buffer[i]);
}
iTunesApi::CFRelease(cfproperty);
iTunesApi::CFWriteStreamClose(cfstream);
iTunesApi::CFRelease(cfplist);
}
}//获取CF数据的类型
IOSAPI CFDataType IOS::GetCFDataType(CFTypeRef data){
CFDataType type = CFTYPE_UnKnow;
CFIndex dataid = iTunesApi::CFGetTypeID(data);
if (dataid == iTunesApi::CFDictionaryGetTypeID()) type = CFTYPE_Dictionary;
if (dataid == iTunesApi::CFArrayGetTypeID()) type = CFTYPE_Array;
if (dataid == iTunesApi::CFStringGetTypeID()) type = CFTYPE_String;
if (dataid == iTunesApi::CFNumberGetTypeID()) type = CFTYPE_Number;
if (dataid == iTunesApi::CFBooleanGetTypeID()) type = CFTYPE_Boolean;
if (dataid == iTunesApi::CFDataGetTypeID()) type = CFTYPE_Data;
if (dataid == iTunesApi::CFDateGetTypeID()) type = CFTYPE_Date;
return type;
}//获取Plist的数据类型
IOSAPI CFDataType IOS::GetPlistDataType(void* plist){
using namespace std;
boost::any* bootanydata = (boost::any*)plist;
const std::type_info &objType = bootanydata->type();
if (objType == typeid(int32_t))
return CFTYPE_Number;
else if (objType == typeid(int64_t))
return CFTYPE_Number;
else if (objType == typeid(long))
return CFTYPE_Number;
else if (objType == typeid(short))
return CFTYPE_Number;
else if (objType == typeid(std::map<std::string, boost::any>))
return CFTYPE_Dictionary;
else if (objType == typeid(std::string))
return CFTYPE_String;
else if (objType == typeid(std::vector<boost::any>))
return CFTYPE_Array;
else if (objType == typeid(std::vector<char>))
return CFTYPE_Data;
else if (objType == typeid(double))
return CFTYPE_Real;
else if (objType == typeid(float))
return CFTYPE_Real;
else if (objType == typeid(Plist::Date))
return CFTYPE_Date;
else if (objType == typeid(bool))
return CFTYPE_Boolean;
return CFTYPE_UnKnow;
}//CFTypeRef to Plist
IOSAPI boost::any IOS::GetPlistDataFromCFData(CFTypeRef cfdata, CFDataType type){
switch (type)
{
case CFTYPE_Dictionary:
{
Plist::dictionary_type dict;
CFIndex dict_count = iTunesApi::CFDictionaryGetCount(cfdata);
if (dict_count > 0){
CFTypeRef *keys = new CFTypeRef[dict_count];
CFTypeRef *values = new CFTypeRef[dict_count];
iTunesApi::CFDictionaryGetKeysAndValues(cfdata, keys, values);
for (size_t i = 0; i < dict_count; i++)
{
CFDataType value_type = GetCFDataType(values[i]);
dict[boost::any_cast<const std::string&>(GetPlistDataFromCFData(keys[i], CFTYPE_String))] = GetPlistDataFromCFData(values[i], value_type);
}
}
return dict;
}
break;
case CFTYPE_Array:
{
Plist::array_type arr;
CFIndex arr_count = iTunesApi::CFArrayGetCount(cfdata);
if (arr_count > 0){
for (size_t i = 0; i < arr_count; i++)
{
CFTypeRef value = iTunesApi::CFArrayGetValueAtIndex(cfdata, i);
CFDataType value_type = GetCFDataType(value);
arr.push_back(GetPlistDataFromCFData(value,value_type));
}
}
return arr;
}
break;
case CFTYPE_Data:
{
Plist::data_type data;
CFIndex data_length = iTunesApi::CFDataGetLength(cfdata);
const uint8_t* databuffer = iTunesApi::CFDataGetBytePtr(cfdata);
for (size_t i = 0; i < data_length; i++)
data.push_back(databuffer[i]);
return data;
}
break;
case CFTYPE_String:
{
Plist::string_type str;
CFIndex len = iTunesApi::CFStringGetLength(cfdata);
char* pszbuffer = new char[len * 4 + 1];
iTunesApi::CFStringGetCString(cfdata, pszbuffer, len * 4 + 1, kCFStringEncodingUTF8);
str = pszbuffer;
return str;
}
break;
case CFTYPE_Number:
{
CFIndex len = iTunesApi::CFNumberGetByteSize(cfdata);
CFNumberType number_type = iTunesApi::CFNumberGetType(cfdata);
switch (number_type)
{
case kCFNumberSInt8Type:
case kCFNumberSInt16Type:
case kCFNumberSInt32Type:
case kCFNumberSInt64Type:
{
Plist::integer_type intret;
iTunesApi::CFNumberGetValue(cfdata, number_type, &intret);
return intret;
}
break;
case kCFNumberFloat32Type:
case kCFNumberFloat64Type:
{
Plist::real_type floatret;
iTunesApi::CFNumberGetValue(cfdata, number_type, &floatret);
return floatret;
}
break;
case kCFNumberCharType:
case kCFNumberShortType:
case kCFNumberIntType:
case kCFNumberLongType:
case kCFNumberLongLongType:
{
Plist::integer_type intret;
iTunesApi::CFNumberGetValue(cfdata, number_type, &intret);
return intret;
}
break;
case kCFNumberFloatType:
case kCFNumberDoubleType:
{
Plist::real_type floatret;
iTunesApi::CFNumberGetValue(cfdata, number_type, &floatret);
return floatret;
}
break;
case kCFNumberCFIndexType:
case kCFNumberNSIntegerType:
{
Plist::integer_type intret;
iTunesApi::CFNumberGetValue(cfdata, number_type, &intret);
return intret;
}
break;
case kCFNumberCGFloatType:
{
Plist::real_type floatret;
iTunesApi::CFNumberGetValue(cfdata, number_type, &floatret);
return floatret;
}
break;
default:
break;
}
Plist::integer_type intret = 0;
return intret;
}
break;
case CFTYPE_Date:
{
CFAbsoluteTime timestamp = iTunesApi::CFDateGetAbsoluteTime(cfdata);
Plist::date_type date;
date.setTimeFromAppleEpoch(timestamp);
return date;
}
break;
case CFTYPE_Boolean:
{
Plist::boolean_type boolret;
CFBooleanRef ref = iTunesApi::CFBooleanGetValue(cfdata);
if (ref == iTunesApi::kCFBooleanTrue) boolret = true;
else if (ref == iTunesApi::kCFBooleanFalse) boolret = false;
return boolret;
}
break;
case CFTYPE_Real:
{
CFIndex len = iTunesApi::CFNumberGetByteSize(cfdata);
CFNumberType number_type = iTunesApi::CFNumberGetType(cfdata);
Plist::real_type floatret;
iTunesApi::CFNumberGetValue(cfdata, number_type, &floatret);
return floatret;
}
break;
case CFTYPE_UnKnow:
break;
default:
break;
}
return NULL;
}//Plist to CFTypeRef
IOSAPI CFTypeRef IOS::GetCFDataFromPlistData(boost::any plist, CFDataType type){
switch (type)
{
case CFTYPE_Dictionary:
{
CFMutableDictionaryRef cf_dict = iTunesApi::CFDictionaryCreateMutable(NULL, 0, &iTunesApi::kCFTypeDictionaryKeyCallBacks, &iTunesApi::kCFTypeDictionaryValueCallBacks);
Plist::dictionary_type dict = boost::any_cast<const std::map<std::string, boost::any>&>(plist);
if (dict.size())
{
Plist::dictionary_type::iterator piar = dict.begin();
for (; piar != dict.end(); piar++)
{
CFDataType value_type = GetPlistDataType(&piar->second);
CFTypeRef value = GetCFDataFromPlistData(piar->second, value_type);
iTunesApi::CFDictionaryAddValue(cf_dict, iTunesApi::CFStringMakeConstantString(piar->first.c_str()), value);
}
}
return cf_dict;
}
break;
case CFTYPE_Array:
{
CFMutableArrayRef cf_array = iTunesApi::CFArrayCreateMutable(NULL, 0, &iTunesApi::kCFTypeArrayCallBacks);
Plist::array_type arr = boost::any_cast<const std::vector<boost::any>&>(plist);
if (arr.size())
{
Plist::array_type::iterator item = arr.begin();
for (; item != arr.end(); item++)
{
CFDataType value_type = GetPlistDataType(&*item);
CFTypeRef value = GetCFDataFromPlistData(*item, value_type);
iTunesApi::CFArrayAppendValue(cf_array, value);
}
}
return cf_array;
}
break;
case CFTYPE_Data:
{
Plist::data_type data = boost::any_cast<const std::vector<char>&>(plist);
CFDataRef cf_data = iTunesApi::CFDataCreate(NULL, (const uint8_t*)data.data(), data.size());
return cf_data;
}
break;
case CFTYPE_String:
{
Plist::string_type str = boost::any_cast<const std::string&>(plist);
CFStringRef cf_str = iTunesApi::CFStringMakeConstantString(str.c_str());
return cf_str;
}
break;
case CFTYPE_Number:
{
Plist::integer_type number = boost::any_cast<const int64_t&>(plist);
CFNumberRef cf_number = iTunesApi::CFNumberCreate(NULL, kCFNumberSInt64Type, &number);
return cf_number;
}
break;
case CFTYPE_Date:
{
Plist::date_type date = boost::any_cast<const Plist::Date&>(plist);
date.timeAsAppleEpoch();
CFDateRef cf_date = iTunesApi::CFDateCreate(NULL, date.timeAsAppleEpoch());
return cf_date;
}
break;
case CFTYPE_Boolean:
{
Plist::boolean_type flag = boost::any_cast<const bool&>(plist);
if (flag) return iTunesApi::kCFBooleanTrue;
else return iTunesApi::kCFBooleanFalse;
}
break;
case CFTYPE_Real:
{
Plist::real_type number = boost::any_cast<const double&>(plist);
CFNumberRef cf_number = iTunesApi::CFNumberCreate(NULL, kCFNumberDoubleType, &number);
return cf_number;
}
break;
case CFTYPE_UnKnow:
break;
default:
break;
}
return NULL;
}#ifdef __cplusplus
};#endif
#include "StdAfx.h"
#include "PhoneMgr.h"
#include <time.h>
#include <shlobj.h>
#include <stdio.h>
#include <io.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32")
#include "boost/thread/thread.hpp"
#include "boost/bind.hpp"
#include <string>
using namespace std;// 静态对象初始化
CPhoneMgr* CPhoneMgr::m_pSelf = NULL;
void* CPhoneMgr::m_pUserData = NULL;
HANDLE CPhoneMgr::_hMutex = CreateMutex(NULL, FALSE, NULL);
am_device_notification* CPhoneMgr::m_notif = NULL;
CPhoneMgr::CDodetele CPhoneMgr::m_Dodelete;CPhoneMgr::CPhoneMgr(void)
{
}CPhoneMgr::~CPhoneMgr(void)
{
}// iTunes支持检测
UINT CPhoneMgr::GetITunesApi()
{
return iTunesApi::InitApi();
}// 开始监听设备
UINT CPhoneMgr::StartListenDevice(void* pUserData)
{
boost::thread thread(boost::bind(&CPhoneMgr::StartListenDeviceThread,this,pUserData));
//StartListenDeviceThread(pUserData);
return 0;
}// 开始监听设备
UINT CPhoneMgr::StartListenDeviceThread(void* pUserData)
{
CPhoneMgr::m_pUserData = pUserData;
/*
* MDERR_OK if successful ------0
* MDERR_SYSCALL if CFRunLoopAddSource() failed
* MDERR_OUT_OF_MEMORY if we ran out of memory
*/
// 设置监听回调
return iTunesApi::AMDeviceNotificationSubscribe((am_device_notification_callback)CPhoneMgr::OnDeviceNotifyStaticFunc,0,0,0,&m_notif);
}
// 设备连接监听回调
void CPhoneMgr::OnDeviceNotifyStaticFunc( am_device_notification_callback_info* pNotify )
{
switch (pNotify->msg)
{
case ADNCI_MSG_CONNECTED:
{
// 检测到有IOS设备接入 尝试连接
CPhoneMgr* pMgr = CPhoneMgr::GetInstance();
unsigned int nConnect = pMgr->ConnectDevice(pNotify->dev);
if(MDERR_OK == nConnect)
{
pMgr->DisConnectDevice(pNotify->dev);
}
am_device_notification_callback_info* pParam = new am_device_notification_callback_info;
memcpy(pParam,pNotify,sizeof(am_device_notification_callback_info));
PostMessage((HWND)m_pUserData,MSG_DEVICENOFITY,nConnect,(LPARAM)pParam);
}
break;
case ADNCI_MSG_DISCONNECTED:
{
CPhoneMgr* pMgr = CPhoneMgr::GetInstance();
unsigned int nConnect = pMgr->DisConnectDevice(pNotify->dev);
am_device_notification_callback_info* pParam = new am_device_notification_callback_info;
memcpy(pParam,pNotify,sizeof(am_device_notification_callback_info));
PostMessage((HWND)m_pUserData,MSG_DEVICENOFITY,nConnect,(LPARAM)pParam);
}
break;
}
}void CPhoneMgr::GetDeviceInfo( am_device* pDev ,HWND hWnd/* = NULL*/)
{
// 启动线程获取基础信息
boost::thread thread(boost::bind(&CPhoneMgr::GetDeviceInfoThread,this,pDev,hWnd==NULL?(HWND)m_pUserData:hWnd));
//thread.detach();}
// 获取基础信息
void CPhoneMgr::GetDeviceInfoThread(am_device* pDevice,HWND hWnd /*= NULL*/)
{
//sleep(5000);
if(!pDevice)
return;mach_error_t nMach_error;
// 连接设备
if (MDERR_OK != (nMach_error = ConnectDevice(pDevice)))
{
PostMessage(hWnd,MSG_DEVICEINFO,nMach_error,0);
return;
}// 通过domain、key获取对应信息
auto f_Dev_Info = [this](am_device* pDev, /*const*/ char* domain, /*const*/ char* key, void* pResult, int nResultLen)->bool
{
CFStringRef cfDomain = NULL, cfKey=NULL;
if(domain)
cfDomain = iTunesApi::__CFStringMakeConstantString(domain);
if(key)
cfKey = iTunesApi::__CFStringMakeConstantString(key);
CFStringRef cfValue = iTunesApi::AMDeviceCopyValue( pDev, cfDomain, cfKey );
if( !cfValue)
{
string sMsg = "f_Dev_Info";
if(domain)
{
sMsg+=" domain[";
sMsg+=domain;
sMsg+="]";
}
if(key)
{
sMsg+=" key[";
sMsg+=key;
sMsg+="]";
}
LOG4CPLUS_ERROR(Logger::getRoot(),sMsg<<" faild");
return false;
}// 获取值类型
unsigned int tid = iTunesApi::CFGetTypeID( cfValue );
if( tid == iTunesApi::CFStringGetTypeID())
{
CFString2CString(cfValue,(char*)pResult,nResultLen);
if(strcmp(key,"ProductType") == 0)
{
auto it = mapProductType.find(string((char*)pResult));
if(it != mapProductType.end())
{
string sProType = it->second;
memset(pResult,0,nResultLen);
strncpy( (char*)pResult, sProType.c_str(), sProType.length());
}
}
}
else if( tid == iTunesApi::CFNumberGetTypeID() )
{
Boolean b = iTunesApi::CFNumberGetValue( (CFNumberRef)cfValue, nResultLen?kCFNumberSInt64Type:kCFNumberSInt32Type, pResult );
}
else if( tid == iTunesApi::CFBooleanGetTypeID())
{
Boolean b = iTunesApi::CFBooleanGetValue( (CFBooleanRef)cfValue);
*((bool*)pResult) = b?true:false;
}
iTunesApi::CFRelease(cfValue);
return true;
};// 将作为消息传递出去 由外部释放
DeviceInfo* pInfo = new DeviceInfo;
memset(pInfo,0,sizeof(DeviceInfo));
bool bRet = false;
#define CC(A,B) f_Dev_Info( pDevice, 0, A, B, sizeof(B));
#define CN64(A,B,C ) f_Dev_Info( pDevice, A,B, &C, 1 );
#define CN32(A,B,C ) f_Dev_Info( pDevice, A,B, &C, 0 );
CC("DeviceName", pInfo->sDeviceName);
CC("DeviceClass", pInfo->sDeviceType);
CC("ProductType", pInfo->sProductType);
CC("ProductVersion", pInfo->sOsVersion);
CC("SerialNumber", pInfo->sSerialNum);
CC("UniqueDeviceID", pInfo->sDeviceId);
CC("ModelNumber", pInfo->sDeviceModel);
CC("BuildVersion",pInfo->sDeviceVersion);
CC("HardwareModel",pInfo->sHardwareModel);
CC("DeviceColor", pInfo->sDeviceColor);
CC("DeviceEnclosureColor", pInfo->sDeviceColor);
CC("RegionInfo", pInfo->sRegionInfo);//购买地区(中国、美国、香港等)
CC("CPUArchitecture", pInfo->sCpuInfo);
CC("WiFiAddress", pInfo->sWifiAddress);
CC("BluetoothAddress", pInfo->sBthAddress);
CC("FirmwareVersion",pInfo->sFirmwareVersion);
CC("ActivationState", pInfo->sActiveState);
CN32(NULL,"ActivationStateAcknowledged", pInfo->bActiveAck);
CC("BasebandVersion", pInfo->sBootVersion);
CC("BasebandBootloaderVersion", pInfo->sBootloaderVersion);
CN32(NULL, "BasebandChipId",pInfo->nBootChipId);
CN32(NULL, "BasebandGoldCertId", pInfo->nBootCertId);
CC("IntegratedCircuitCardIdentity", pInfo->sICCID);
CC("InternationalMobileEquipmentIdentity",pInfo->sIMEI);
CC("InternationalMobileSubscriberIdentity",pInfo->sIMSI);
CC("MLBSerialNumber",pInfo->sMLBSerialNum);
CC("MobileSubscriberCountryCode", pInfo->sSubscriberCountryCode);
CC("MobileSubscriberNetworkCode", pInfo->sSubscriberNetworkCode);
CN32( NULL, "PasswordProtected", pInfo->bPasswordProtected);
CC("PhoneNumber", pInfo->sPhoneNum);
CN32(NULL,"ProductionSOC", pInfo->bProductSOC);
//CC("SDIOProductInfo", pInfo->sSDIOInfo);
CC("SIMStatus", pInfo->sSimStatus);
CC("TimeZone", pInfo->sTimeZone);
CN64(NULL,"UniqueChipID", pInfo->nChipId);
f_Dev_Info( pDevice, "com.apple.international","Keyboard", pInfo->sKeyBoard, sizeof(pInfo->sKeyBoard));CN64( "com.apple.disk_usage", "TotalDiskCapacity", pInfo->disk_info.nDiskAll); //总内存容量
CN64( "com.apple.disk_usage", "TotalDataCapacity", pInfo->disk_info.nDataAll); //占用内存容量
CN64( "com.apple.disk_usage", "TotalDataAvailable", pInfo->disk_info.nDataFree); //剩余内存容量
CN64( "com.apple.disk_usage", "TotalSystemCapacity", pInfo->disk_info.nSysAll); //系统总容量
CN64( "com.apple.disk_usage", "TotalSystemAvailable", pInfo->disk_info.nSysFree); //系统容量(可用)
CN64( "com.apple.disk_usage", "MobileApplicationUsage", pInfo->disk_info.nAppUsed); //应用程序占内存大小
CN32( "com.apple.mobile.battery","BatteryCurrentCapacity", pInfo->battery_info.current);//电池容量
CN32( "com.apple.mobile.battery","BatteryIsCharging", pInfo->battery_info.is_charging);// 越狱标志
afc_connection* pSocket = NULL;
pInfo->bBreakedStatus = true;
// 打开AFC服务
nMach_error = iTunesApi::AMDeviceStartService( pDevice, iTunesApi::__CFStringMakeConstantString("com.apple.afc2"), &pSocket, NULL);
if(nMach_error)
{
closesocket((SOCKET)pSocket);
pInfo->bBreakedStatus = false;
}
// 断开连接
DisConnectDevice( pDevice );
GetDeviceInfoEx(pDevice,pInfo);
PostMessage(hWnd,MSG_DEVICEINFO,MDERR_OK,(LPARAM)pInfo);
GetAppDetail(pDevice,hWnd);
}// 获取磁盘占用信息
bool CPhoneMgr::GetDeviceInfoEx( am_device* pDevice, DeviceInfo* pInfo )
{
HAFC_ENV pAfc = Afc_Open(pDevice);
if( !pAfc)
return false;
Afc_Dirinfo_t di;GetDirInfo( pAfc, "/DCIM", &di );
pInfo->disk_info.nPicUsed = di.di_total_size;GetDirInfo( pAfc, "/Books", &di );
pInfo->disk_info.nEbookUsed = di.di_total_size;GetDirInfo( pAfc, "/iTunes_Control/Music", &di );
pInfo->disk_info.nMusicUsed = di.di_total_size;GetDirInfo( pAfc, "/iTunes_Control/Sync/Media", &di );
pInfo->disk_info.nVideoUsed = di.di_total_size;GetDirInfo( pAfc, "/general_storage", &di );
pInfo->disk_info.nMobileUsed = di.di_total_size;Afc_Close( pAfc );
return true;
}// 连接设备
mach_error_t CPhoneMgr::ConnectDevice( am_device* pDev )
{
mach_error_t ret = MDERR_OK;
int nTryTimes = 3;
do
{
ret = iTunesApi::AMDeviceConnect(pDev);
if (ret)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"Could not connect Device [AMDeviceConnect:"<<ret<<"]");
--nTryTimes;
continue;
}ret = iTunesApi::AMDeviceIsPaired(pDev);
if (!ret)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"Could not pair Device [AMDeviceIsPaired:"<<ret<<"]");
--nTryTimes;
continue;
}ret = iTunesApi::AMDeviceValidatePairing(pDev);
if (ret)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"Could not validate device pairing [AMDeviceValidatePairing:"<<ret<<"]");
--nTryTimes;
continue;
}ret = iTunesApi::AMDeviceStartSession(pDev);
if (ret)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"Could not start session [AMDeviceStartSession:"<<ret<<"]");
--nTryTimes;
continue;
}
break;
} while (nTryTimes>0);
return ret;
}// 断开连接
mach_error_t CPhoneMgr::DisConnectDevice( am_device* device )
{
mach_error_t ret = MDERR_OK;
do
{
ret = iTunesApi::AMDeviceStopSession(device);
if (ret)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"Could not Stop session [AMDeviceStopSession:"<<ret<<"]");
break;
}
ret = iTunesApi::AMDeviceDisconnect(device);
if (ret)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"Could not Disconnect device [AMDeviceDisconnect:"<<ret<<"]");
break;
}
} while (0);return ret;
}// 打开并连接到AFC服务
HAFC_ENV CPhoneMgr::Afc_Open( am_device* device )
{
if( MDERR_OK !=ConnectDevice( device ) )
return NULL;afc_connection* pSocket = NULL;
// 打开AFC服务
mach_error_t ret = iTunesApi::AMDeviceStartService( (am_device*)device, iTunesApi::__CFStringMakeConstantString("com.apple.afc"), &pSocket, NULL);
DisConnectDevice( device );
if( ret )
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AMDeviceStartService faild:"<<ret);
return NULL;
}afc_connection* pAfc;
// 连接到AFC
ret = iTunesApi::AFCConnectionOpen( pSocket, 0, &pAfc);
if(ret)
{
closesocket((SOCKET)pSocket);
LOG4CPLUS_ERROR(Logger::getRoot(),"AFCConnectionOpen faild:"<<ret);
return NULL;
}
///////
Afc_Env_t* pAfc_Env = new Afc_Env_t;
memset(pAfc_Env,0,sizeof(Afc_Env_t));
pAfc_Env->pSocket = pSocket;
pAfc_Env->pAfc = pAfc;
/////
return pAfc_Env;
}// 关闭AFC连接
void CPhoneMgr::Afc_Close( HAFC_ENV pAfcEnv )
{
if(!pAfcEnv)
return;iTunesApi::AFCConnectionClose( pAfcEnv->pAfc);
closesocket((SOCKET)pAfcEnv->pSocket);delete pAfcEnv;
pAfcEnv = NULL;
}// 获取目录信息
bool CPhoneMgr::GetDirInfo( HAFC_ENV pAfc,const char* sRemotePath, Afc_Dirinfo_t* di )
{
if(!pAfc || !di || !sRemotePath )
return false;memset( di, 0, sizeof(*di));
////
Afc_Stat_t st;
if( !GetStatInfo( pAfc, sRemotePath, &st))
return false;
// 是否目录
if( st.st_mode != S_IFDIR )
return false;di->di_ctime = st.st_ctime;
di->di_mtime = st.st_mtime;// 获取详细信息
return GetDirInfoDetail( pAfc, sRemotePath, di );
}// 获取文件属性
bool CPhoneMgr::GetStatInfo( HAFC_ENV pAfc, const char* path, Afc_Stat_t* st )
{
if( !pAfc || !st )
return false;memset( st, 0, sizeof(*st) );
mach_error_t ret;
struct afc_dictionary *pInfo;
char *pKey, *pVal;
unsigned int size = 0;
ret = iTunesApi::AFCFileInfoOpen( pAfc->pAfc, (char*)path, &pInfo);
if (ret)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AFCFileInfoOpen path["<<path<<"] faild:"<<ret);
return false;
}
ret = iTunesApi::AFCKeyValueRead(pInfo, &pKey, &pVal);
while( pKey || pVal )
{
if (pKey == NULL || pVal == NULL)
break;
if (!_stricmp(pKey, "st_size"))
{
st->st_size = _atoi64(pVal);
}
else if( !_stricmp( pKey, "st_ifmt"))
{
if( _stricmp(pVal,"S_IFDIR")==0)
st->st_mode = S_IFDIR;
else
st->st_mode = S_IFREG;
}
else if( !_stricmp( pKey,"st_mtime"))
{
st->st_mtime = (time_t)(_atoi64(pVal)/1000000000);
}
else if( !_stricmp( pKey,"st_birthtime"))
{
st->st_ctime = (time_t)(_atoi64(pVal)/1000000000);
}
iTunesApi::AFCKeyValueRead(pInfo, &pKey, &pVal);
}
iTunesApi::AFCKeyValueClose(pInfo);return true;
}// 获取目录详细信息
bool CPhoneMgr::GetDirInfoDetail( HAFC_ENV pAfc,const char* sRemotePath, Afc_Dirinfo_t* di )
{
HAFC_HANDLE pDirHandle = Afc_Open_Dir( pAfc, sRemotePath );
if( !pDirHandle )
{
++di->di_error_count;
return false;
}
const char* name;
while( name = Afc_Read_Dir( pDirHandle))
{
if( _stricmp(name,".")==0 || _stricmp( name,"..")==0)
continue;
char path[512];
sprintf_s( path,"%s/%s", sRemotePath, name );
Afc_Stat_t st;
if( !GetStatInfo( pAfc, path, &st))
{
++di->di_error_count;
continue;
}
if( st.st_mode == S_IFDIR)
{ // dir
di->di_dir_count++;
GetDirInfoDetail( pAfc, path, di );
}
else
{
di->di_file_count++;
di->di_total_size += st.st_size ;
}
}
Afc_Close_Handle( pDirHandle );return true;
}// 打开AFC目录
HAFC_HANDLE CPhoneMgr::Afc_Open_Dir( HAFC_ENV pAfc, const char* path )
{
if(!pAfc || !path)
return NULL;struct afc_directory *pDir;
mach_error_t ret;ret = iTunesApi::AFCDirectoryOpen( pAfc->pAfc, (char*)path, &pDir );
if (ret)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AFCDirectoryOpen["<<path<<"] faild:"<<ret);
return NULL;
}Afc_Handle_t* h = new Afc_Handle_t;
memset( h, 0, sizeof(Afc_Handle_t));
h->pEnv = pAfc;
h->bIsDir = true;
h->pDir = pDir;return h;
}// 读取目录信息
const char* CPhoneMgr::Afc_Read_Dir( HAFC_HANDLE pDir )
{
if(!pDir ||!pDir->pDir)
return NULL;char *pEntry = NULL ;
mach_error_t ret;
ret = iTunesApi::AFCDirectoryRead(pDir->pEnv->pAfc,pDir->pDir, &pEntry);
if (ret)
{
//printf("AFCDirectoryRead() = %d\n", ret );
LOG4CPLUS_ERROR(Logger::getRoot(),"AFCDirectoryRead faild:"<<ret);
}
return pEntry;
}// 关闭AFC句柄
void CPhoneMgr::Afc_Close_Handle( HAFC_HANDLE handle )
{
if(!handle)
return;if( handle->pFile)
iTunesApi::AFCFileRefClose( handle->pEnv->pAfc, handle->pFile);
if( handle->pDir)
iTunesApi::AFCDirectoryClose( handle->pEnv->pAfc, handle->pDir);delete handle;
handle = NULL;
}// 获取APP信息线程
void CPhoneMgr::GetDeviceAppThread(am_device* pDevice,HWND hWnd)
{
LOG4CPLUS_DEBUG(Logger::getRoot(),"GetDeviceAppThread begin device_id:"<<pDevice->device_id);
// 连接手机
if( MDERR_OK!=ConnectDevice(pDevice))
{
PostMessage(hWnd,MSG_DEVICEAPP,1,(LPARAM)NULL);
return;
}afc_connection* fd;
// 开启com.apple.mobile.installation_proxy 服务
mach_error_t ret = iTunesApi::AMDeviceStartService(pDevice, iTunesApi::__CFStringMakeConstantString("com.apple.mobile.installation_proxy"), &fd, NULL);
DisConnectDevice(pDevice); // 及时断开手机连接
if( ret )
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AMDeviceStartService[com.apple.mobile.installation_proxy] faild:"<<ret);
PostMessage(hWnd,MSG_DEVICEAPP,ret,(LPARAM)NULL);
return;
}//
CFDictionaryRef cfDicRef_Req = iTunesApi::CFDictionaryCreateMutable( NULL,0,NULL,NULL);
if( !cfDicRef_Req )
{
closesocket((SOCKET)fd);
LOG4CPLUS_ERROR(Logger::getRoot(),"CFDictionaryCreateMutable( NULL,0,NULL,NULL) faild");
PostMessage(hWnd,MSG_DEVICEAPP,1,(LPARAM)NULL);
return ;
}
CFDictionaryRef cfDicRef_Opt = iTunesApi::CFDictionaryCreateMutable( NULL,0,NULL,NULL);
if( !cfDicRef_Opt )
{
iTunesApi::CFRelease(cfDicRef_Req);
closesocket((SOCKET)fd);
LOG4CPLUS_ERROR(Logger::getRoot(),"CFDictionaryCreateMutable( NULL,0,NULL,NULL) faild");
PostMessage(hWnd,MSG_DEVICEAPP,1,(LPARAM)NULL);
return ;
}
CFMutableArrayRef cfMutArrRef = iTunesApi::CFArrayCreateMutable( NULL, 0, NULL );
if( !cfMutArrRef )
{
iTunesApi::CFRelease(cfDicRef_Req);
iTunesApi::CFRelease(cfDicRef_Opt);
closesocket((SOCKET)fd);
LOG4CPLUS_ERROR(Logger::getRoot(),"CFArrayCreateMutable( NULL,0,NULL,NULL) faild");
PostMessage(hWnd,MSG_DEVICEAPP,1,(LPARAM)NULL);
return ;
}iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("CFBundleIdentifier"));
//iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("StaticDiskUsage"));
//iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("DynamicDiskUsage"));
iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("iTunesMetadata"));
iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("CFBundleName"));
iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("CFBundleExecutable"));
iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("CFBundleDisplayName"));
iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("CFBundleVersion"));iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)cfDicRef_Opt, (void*)iTunesApi::__CFStringMakeConstantString("ReturnAttributes"), (void*)cfMutArrRef );
iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)cfDicRef_Opt, (void*)iTunesApi::__CFStringMakeConstantString("ApplicationType"),(void*)iTunesApi::__CFStringMakeConstantString("User") );
iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)cfDicRef_Req, (void*)iTunesApi::__CFStringMakeConstantString("Command"), (void*)iTunesApi::__CFStringMakeConstantString("Browse") );
iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)cfDicRef_Req, (void*)iTunesApi::__CFStringMakeConstantString("ClientOptions"), (void*)cfDicRef_Opt );bool bHadTotal = false;
int nAppIndex = 0;
int nAppTotal = 0;
//boost::shared_ptr<AppArray> pAppArray;// = NULL;
AppArray* pAppArray = NULL;
//pAppArray.
LOG4CPLUS_DEBUG(Logger::getRoot(),"Send_Xml_Request for get applist");
bool bSend = Send_Xml_Request( fd, cfDicRef_Req);
while(bSend)
{
CFPropertyListRef cfPlRef_Res = Recv_Xml_Response(fd );
if( !cfPlRef_Res )
break;
CFStringRef cfRef_Status = (CFStringRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)cfPlRef_Res, iTunesApi::__CFStringMakeConstantString("Status"));
if(!cfRef_Status)
{
iTunesApi::CFRelease(cfPlRef_Res);
LOG4CPLUS_ERROR(Logger::getRoot(),"CFDictionaryGetValue[Status] error");
break;
}
char sStatus[64];
memset(sStatus,0,64);
iTunesApi::CFStringGetCString( cfRef_Status, sStatus,64, kCFStringEncodingUTF8 );
if( !bHadTotal )
{
CFNumberRef cfRefTotal = (CFNumberRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)cfPlRef_Res, iTunesApi::__CFStringMakeConstantString("Total"));
if( !cfRefTotal )
{
iTunesApi::CFRelease(cfPlRef_Res);
LOG4CPLUS_ERROR(Logger::getRoot(),"AppTotal is 0");
break;
}
iTunesApi::CFNumberGetValue(cfRefTotal, kCFNumberSInt32Type, &nAppTotal);
if( nAppTotal <=0 )
{
iTunesApi::CFRelease(cfPlRef_Res);
LOG4CPLUS_ERROR(Logger::getRoot(),"AppTotal is 0");
break;
}
//boost::shared_ptr<AppArray> pTemp((AppArray*)new char[sizeof(AppArray) + nAppTotal* sizeof( AppInfo)]);
//pAppArray = pTemp;
pAppArray = (AppArray*)new char[sizeof(AppArray) + nAppTotal* sizeof( AppInfo)];
if(!pAppArray)
{
iTunesApi::CFRelease(cfPlRef_Res);
break;
}
pAppArray->pAppDetail = (AppInfo*)( ((char*)pAppArray) + sizeof( AppArray) );
pAppArray->nAppCount = nAppTotal;
memset( pAppArray->pAppDetail,0, nAppTotal*sizeof(AppInfo) );bHadTotal = true ;
}
CFArrayRef cfRefList = (CFArrayRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)cfPlRef_Res, iTunesApi::__CFStringMakeConstantString("CurrentList"));
if( !cfRefList )
{
iTunesApi::CFRelease(cfPlRef_Res);
LOG4CPLUS_ERROR(Logger::getRoot(),"CFDictionaryGetValue[CurrentList] error");
break;
}
int nListCount = iTunesApi::CFArrayGetCount( cfRefList );
for (int i=0; i<nListCount;++i)
{
CFDictionaryRef cfDicRef_App=(CFDictionaryRef)iTunesApi::CFArrayGetValueAtIndex(cfRefList, i);
AppInfo* pAppInfo = &pAppArray->pAppDetail[nAppIndex++];
pAppInfo->bDel = false;
CFString2CString((CFStringRef)iTunesApi::CFDictionaryGetValue(cfDicRef_App,iTunesApi::__CFStringMakeConstantString("CFBundleIdentifier"))
,pAppInfo->sAppleID
,sizeof(pAppInfo->sAppleID));
CFString2CString((CFStringRef)iTunesApi::CFDictionaryGetValue(cfDicRef_App,iTunesApi::__CFStringMakeConstantString("CFBundleName"))
,pAppInfo->sName
,sizeof(pAppInfo->sName));
CFString2CString((CFStringRef)iTunesApi::CFDictionaryGetValue(cfDicRef_App,iTunesApi::__CFStringMakeConstantString("CFBundleDisplayName"))
,pAppInfo->sDisplayName
,sizeof(pAppInfo->sDisplayName));
CFString2CString((CFStringRef)iTunesApi::CFDictionaryGetValue(cfDicRef_App,iTunesApi::__CFStringMakeConstantString("CFBundleVersion"))
,pAppInfo->sVersion
,sizeof(pAppInfo->sVersion));
if( strlen(pAppInfo->sDisplayName)<=0 )
{
strcpy( pAppInfo->sDisplayName,pAppInfo->sName);
if( strlen(pAppInfo->sDisplayName)<=0)
CFString2CString((CFStringRef)iTunesApi::CFDictionaryGetValue(cfDicRef_App,iTunesApi::__CFStringMakeConstantString("CFBundleExecutable"))
,pAppInfo->sDisplayName
,sizeof(pAppInfo->sDisplayName));
}
}
iTunesApi::CFRelease( cfPlRef_Res );
if( _stricmp( sStatus,"BrowsingApplications") !=0 )
break;
if( nAppIndex>= nAppTotal)
break;
}
closesocket((SOCKET)fd);
iTunesApi::CFRelease( cfDicRef_Req);
iTunesApi::CFRelease( cfDicRef_Opt);
iTunesApi::CFRelease( cfMutArrRef);
// 获取APP图标
if(bHadTotal)
{
AppGetIconFile(pDevice, pAppArray->pAppDetail, pAppArray->nAppCount);
LOG4CPLUS_DEBUG(Logger::getRoot(),"GetDeviceAppThread Suc AppCount:"<<nAppTotal);
}
PostMessage(hWnd,MSG_DEVICEAPP,MDERR_OK,(LPARAM)pAppArray);// 获取APP大小
// 连接手机
if( MDERR_OK!=ConnectDevice(pDevice))
{
PostMessage(hWnd,MSG_DEVICEAPP,1,(LPARAM)NULL);
return;
}// 开启com.apple.mobile.installation_proxy 服务
ret = iTunesApi::AMDeviceStartService(pDevice, iTunesApi::__CFStringMakeConstantString("com.apple.mobile.installation_proxy"), &fd, NULL);
DisConnectDevice(pDevice); // 及时断开手机连接cfDicRef_Req = iTunesApi::CFDictionaryCreateMutable( NULL,0,NULL,NULL);
if( !cfDicRef_Req )
{
closesocket((SOCKET)fd);
LOG4CPLUS_ERROR(Logger::getRoot(),"CFDictionaryCreateMutable( NULL,0,NULL,NULL) faild");
PostMessage(hWnd,MSG_DEVICEAPP,1,(LPARAM)NULL);
return ;
}
cfDicRef_Opt = iTunesApi::CFDictionaryCreateMutable( NULL,0,NULL,NULL);
if( !cfDicRef_Opt )
{
iTunesApi::CFRelease(cfDicRef_Req);
closesocket((SOCKET)fd);
LOG4CPLUS_ERROR(Logger::getRoot(),"CFDictionaryCreateMutable( NULL,0,NULL,NULL) faild");
PostMessage(hWnd,MSG_DEVICEAPP,1,(LPARAM)NULL);
return ;
}
cfMutArrRef = iTunesApi::CFArrayCreateMutable( NULL, 0, NULL );
if( !cfMutArrRef )
{
iTunesApi::CFRelease(cfDicRef_Req);
iTunesApi::CFRelease(cfDicRef_Opt);
closesocket((SOCKET)fd);
LOG4CPLUS_ERROR(Logger::getRoot(),"CFArrayCreateMutable( NULL,0,NULL,NULL) faild");
PostMessage(hWnd,MSG_DEVICEAPP,1,(LPARAM)NULL);
return ;
}iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("CFBundleIdentifier"));
iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("StaticDiskUsage"));
iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("DynamicDiskUsage"));
iTunesApi::CFArrayAppendValue(cfMutArrRef,iTunesApi::__CFStringMakeConstantString("iTunesMetadata"));iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)cfDicRef_Opt, (void*)iTunesApi::__CFStringMakeConstantString("ReturnAttributes"), (void*)cfMutArrRef );
iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)cfDicRef_Opt, (void*)iTunesApi::__CFStringMakeConstantString("ApplicationType"),(void*)iTunesApi::__CFStringMakeConstantString("User") );
iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)cfDicRef_Req, (void*)iTunesApi::__CFStringMakeConstantString("Command"), (void*)iTunesApi::__CFStringMakeConstantString("Browse") );
iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)cfDicRef_Req, (void*)iTunesApi::__CFStringMakeConstantString("ClientOptions"), (void*)cfDicRef_Opt );bHadTotal = false;
nAppIndex = 0;
nAppTotal = 0;
bSend = Send_Xml_Request( fd, cfDicRef_Req);
while(bSend)
{
CFPropertyListRef cfPlRef_Res = Recv_Xml_Response(fd );
if( !cfPlRef_Res )
break;
CFStringRef cfRef_Status = (CFStringRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)cfPlRef_Res, iTunesApi::__CFStringMakeConstantString("Status"));
if(!cfRef_Status)
{
iTunesApi::CFRelease(cfPlRef_Res);
LOG4CPLUS_ERROR(Logger::getRoot(),"CFDictionaryGetValue[Status] error");
break;
}
char sStatus[64];
memset(sStatus,0,64);
iTunesApi::CFStringGetCString( cfRef_Status, sStatus,64, kCFStringEncodingUTF8 );
if( !bHadTotal )
{
CFNumberRef cfRefTotal = (CFNumberRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)cfPlRef_Res, iTunesApi::__CFStringMakeConstantString("Total"));
if( !cfRefTotal )
{
iTunesApi::CFRelease(cfPlRef_Res);
LOG4CPLUS_ERROR(Logger::getRoot(),"AppTotal is 0");
break;
}
iTunesApi::CFNumberGetValue(cfRefTotal, kCFNumberSInt32Type, &nAppTotal);
if( nAppTotal <=0 )
{
iTunesApi::CFRelease(cfPlRef_Res);
LOG4CPLUS_ERROR(Logger::getRoot(),"AppTotal is 0");
break;
}bHadTotal = true ;
}
CFArrayRef cfRefList = (CFArrayRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)cfPlRef_Res, iTunesApi::__CFStringMakeConstantString("CurrentList"));
if( !cfRefList )
{
iTunesApi::CFRelease(cfPlRef_Res);
LOG4CPLUS_ERROR(Logger::getRoot(),"CFDictionaryGetValue[CurrentList] error");
break;
}
int nListCount = iTunesApi::CFArrayGetCount( cfRefList );
for (int i=0; i<nListCount;++i)
{
++nAppIndex;
CFDictionaryRef cfDicRef_App=(CFDictionaryRef)iTunesApi::CFArrayGetValueAtIndex(cfRefList, i);
AppInfo* pAppInfo = NULL;
char sAppleID[256];
CFString2CString((CFStringRef)iTunesApi::CFDictionaryGetValue(cfDicRef_App,iTunesApi::__CFStringMakeConstantString("CFBundleIdentifier"))
,sAppleID,sizeof(sAppleID));for (int j = 0;j<pAppArray->nAppCount;++j)
{
AppInfo* pAppFind = &pAppArray->pAppDetail[j];
if(strcmp(pAppFind->sAppleID,sAppleID) == 0)
{
pAppInfo = pAppFind;
break;
}
}
if(pAppInfo == NULL)
continue;CFNumberRef d1 = (CFNumberRef)iTunesApi::CFDictionaryGetValue(cfDicRef_App, iTunesApi::__CFStringMakeConstantString("StaticDiskUsage"));
CFNumberRef d2 = (CFNumberRef)iTunesApi::CFDictionaryGetValue(cfDicRef_App, iTunesApi::__CFStringMakeConstantString("DynamicDiskUsage"));
if(d1) iTunesApi::CFNumberGetValue( (CFNumberRef)d1, kCFNumberSInt64Type, &pAppInfo->nStaticSize);
if(d1) iTunesApi::CFNumberGetValue( (CFNumberRef)d2, kCFNumberSInt64Type, &pAppInfo->nDynamicSize);CFDictionaryRef cfDicRef_iIMD = NULL;
CFDataRef cfIData = (CFDataRef)iTunesApi::CFDictionaryGetValue(cfDicRef_App, iTunesApi::__CFStringMakeConstantString("iTunesMetadata"));
if(cfIData)
{
cfDicRef_iIMD = (CFDictionaryRef)iTunesApi::CFPropertyListCreateFromXMLData( 0, cfIData,0,0);
}
else//尝试读取 iTunesMetadata.plist
{
cfDicRef_iIMD = Get_iTunesMetadata( pDevice, pAppInfo->sAppleID );
}if(cfDicRef_iIMD)
{
CFString2CString( (CFStringRef)iTunesApi::CFDictionaryGetValue(cfDicRef_iIMD, iTunesApi::__CFStringMakeConstantString("genre")), pAppInfo->sAppClass, sizeof(pAppInfo->sAppClass));
CFString2CString( (CFStringRef)iTunesApi::CFDictionaryGetValue(cfDicRef_iIMD, iTunesApi::__CFStringMakeConstantString("appleId")), pAppInfo->sAccount ,sizeof(pAppInfo->sAccount));
CFNumberRef cfNumDef_Tmp = (CFNumberRef)iTunesApi::CFDictionaryGetValue(cfDicRef_iIMD, iTunesApi::__CFStringMakeConstantString("genreId"));
if(cfNumDef_Tmp)
iTunesApi::CFNumberGetValue(cfNumDef_Tmp, kCFNumberSInt32Type, &pAppInfo->nAppClassId);
cfNumDef_Tmp = (CFNumberRef)iTunesApi::CFDictionaryGetValue( cfDicRef_iIMD, iTunesApi::__CFStringMakeConstantString("softwareVersionExternalIdentifier"));
if(cfNumDef_Tmp)
iTunesApi::CFNumberGetValue(cfNumDef_Tmp, kCFNumberSInt32Type, &pAppInfo->nExternalVer);
CFDictionaryRef dd = (CFDictionaryRef)iTunesApi::CFDictionaryGetValue( cfDicRef_iIMD, iTunesApi::__CFStringMakeConstantString("com.apple.iTunesStore.downloadInfo"));
if( dd )
{
CFDictionaryRef kk = (CFDictionaryRef)iTunesApi::CFDictionaryGetValue(dd, iTunesApi::__CFStringMakeConstantString("accountInfo"));
if(kk)
{
CFString2CString( (CFStringRef)iTunesApi::CFDictionaryGetValue(kk, iTunesApi::__CFStringMakeConstantString("AppleID")), pAppInfo->sAccount ,sizeof(pAppInfo->sAccount));
}
}
iTunesApi::CFRelease(cfDicRef_iIMD);
}
}
iTunesApi::CFRelease( cfPlRef_Res );
if( _stricmp( sStatus,"BrowsingApplications") !=0 )
break;
if( nAppIndex>= nAppTotal)
break;
}
closesocket((SOCKET)fd);
iTunesApi::CFRelease( cfDicRef_Req);
iTunesApi::CFRelease( cfDicRef_Opt);
iTunesApi::CFRelease( cfMutArrRef);PostMessage(hWnd,MSG_DEVICEAPPEX,MDERR_OK,(LPARAM)pAppArray);
}// 获取APP信息接口
void CPhoneMgr::GetAppDetail( am_device* pDevice,HWND hWnd/* = NULL*/)
{
if(hWnd == NULL)
hWnd = (HWND)m_pUserData;
if(!pDevice)
{
LOG4CPLUS_DEBUG(Logger::getRoot(),"Call GetAppDetail failed:pDevice is null");
PostMessage(hWnd,MSG_DEVICEAPP,1,0);
return;
}// 启动线程获取基础信息
boost::thread thread(boost::bind(&CPhoneMgr::GetDeviceAppThread,this,pDevice,hWnd));
}// 获取APP图标信息
void CPhoneMgr::AppGetIconFile(am_device* pDevice,AppInfo* pAppDetail, int nAppCount)
{
///
char path[512];
memset(path,0,512);
Common_Data_Path( path );
strcat( path, "\\app_icons" );
CreateDirectoryA(path, NULL);bool bPar = false;
afc_connection* fd;
for(int i=0; i< nAppCount ; ++i )
{
CFDictionaryRef req = iTunesApi::CFDictionaryCreateMutable( NULL,0,NULL,NULL);
if(!req)
continue;AppInfo* a = &pAppDetail[i];
// 判断图标是否存在
char png_path[260];
sprintf( png_path, "%s\\%s_icon.png", path, a->sAppleID);
if(_access(png_path,0) == 0)
{
strcpy( a->sLogoPath, png_path );
continue;
}if (bPar == false)
{
//LOG4CPLUS_DEBUG(Logger::getRoot(),"AppGetIconFile Begin");
if( MDERR_OK != ConnectDevice(pDevice))
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AppGetIconFile faild when ConnectDevice(),try again");
if( MDERR_OK != ConnectDevice(pDevice))
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AppGetIconFile faild when ConnectDevice()");
return ;
}
}
////mach_error_t ret = iTunesApi::AMDeviceStartService(pDevice, iTunesApi::__CFStringMakeConstantString("com.apple.springboardservices"), &fd, NULL);
DisConnectDevice(pDevice);
if( ret )
{
//sprintf( apple_errmsg, "start installation_proxy error <%u>" , ret );
LOG4CPLUS_ERROR(Logger::getRoot(),"AMDeviceStartService[com.apple.springboardservices] error");
return ;
}
bPar = true;
}CFStringRef sapp_id = iTunesApi::CFStringCreateWithCString( NULL, a->sAppleID, kCFStringEncodingUTF8 );
if( !sapp_id)
{
iTunesApi::CFRelease( req);
continue;
}
iTunesApi::CFDictionaryAddValue((CFMutableDictionaryRef)(req), (void*)iTunesApi::__CFStringMakeConstantString("command"), (void*)iTunesApi::__CFStringMakeConstantString("getIconPNGData") );
iTunesApi::CFDictionaryAddValue((CFMutableDictionaryRef)(req), (void*)iTunesApi::__CFStringMakeConstantString("bundleId"), (void*)sapp_id );
////
bool bSend = Send_Xml_Request( fd, req );
CFPropertyListRef res = 0;
if( bSend )
res = Recv_Xml_Response( fd );
if( res )
{
//
CFDataRef data = (CFDataRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)res, iTunesApi::__CFStringMakeConstantString("pngData"));
if(data )
{
int len = iTunesApi::CFDataGetLength( data );
const void* ptr = iTunesApi::CFDataGetBytePtr( data );
//char png_path[260];
//sprintf( png_path, "%s\\%s_icon.png", path, a->sAppleID);
FILE* fp = fopen( png_path , "wb" );
if(fp)
{
fwrite( ptr,1,len, fp);
fclose(fp);
///
strcpy( a->sLogoPath, png_path );
}
else
{
//printf("fopen %s error \n", png_path );
}
}
///
iTunesApi::CFRelease( res );
}
/////
iTunesApi::CFRelease( req);
iTunesApi::CFRelease( sapp_id);
}
/////////closesocket((SOCKET)fd);
////
//LOG4CPLUS_DEBUG(Logger::getRoot(),"AppGetIconFile End");
}// 发送请求包到设备
bool CPhoneMgr::Send_Xml_Request( void* pSocket,CFDictionaryRef cfDicRef )
{
int sock = (int)pSocket;
CFPropertyListRef cfXml_Data = iTunesApi::CFPropertyListCreateXMLData( NULL, cfDicRef );
if( !cfXml_Data )
{
LOG4CPLUS_ERROR(Logger::getRoot(),"CFPropertyListCreateXMLData Error");
return false;
}
CFIndex cfLen = iTunesApi::CFDataGetLength( (CFDataRef)cfXml_Data );
uint32_t nSendSize = htonl( cfLen );
const void* pSendBuf = iTunesApi::CFDataGetBytePtr( (CFDataRef)cfXml_Data );
// 发送长度字段和具体buf数据
if( send( sock, (char*)&nSendSize, sizeof(nSendSize),0) != sizeof(nSendSize) ||
send( sock, (char*)pSendBuf, cfLen,0) != cfLen )
{
iTunesApi::CFRelease( cfXml_Data );
LOG4CPLUS_ERROR(Logger::getRoot(),"Send_Xml_Request send Error");
return false;
}
iTunesApi::CFRelease( cfXml_Data );return true;
}// 从设备接收请求数据
CFPropertyListRef CPhoneMgr::Recv_Xml_Response( void* pSocket )
{
CFPropertyListRef cfPlRef_Res = NULL;
int sock = (int)pSocket;
uint32_t nBufSize;
// 先接收Response数据长度
if( sizeof(nBufSize) != recv( sock, (char*)&nBufSize, sizeof(nBufSize),0) )
{
LOG4CPLUS_ERROR(Logger::getRoot(),"Recv_Xml_Response recv ResponseLen error");
return cfPlRef_Res; // NULL
}
nBufSize = ntohl(nBufSize);
if( nBufSize==0)
return cfPlRef_Res; // NULLchar* pBuf = new char[nBufSize];
int pos = 0;
// 开始接收数据
while( pos<nBufSize )
{
int nRecv = recv( sock, pBuf+pos, nBufSize-pos, 0);
if( nRecv <=0)
{
delete[] pBuf;
LOG4CPLUS_ERROR(Logger::getRoot(),"Recv_Xml_Response recv data error");
return NULL;
}
pos += nRecv;
}
CFDataRef dd = iTunesApi::CFDataCreateWithBytesNoCopy( 0, (UInt8*)pBuf, nBufSize, iTunesApi::s_kCFAllocatorNull );
cfPlRef_Res = iTunesApi::CFPropertyListCreateFromXMLData(0,dd,0,0);
iTunesApi::CFRelease( dd );
delete[] pBuf;
return cfPlRef_Res;
}// 尝试读取iTunesMetadata数据
CFDictionaryRef CPhoneMgr::Get_iTunesMetadata(am_device* pDevice, const char* apple_id )
{
CFDictionaryRef cfDicRef_Res = NULL;
HAFC_ENV pEvn = App_Open_Dir(pDevice, apple_id);
if( !pEvn)
return NULL ;
Afc_Stat_t st;
const char* itunes = "/iTunesMetadata.plist";
if( !GetStatInfo( pEvn, itunes, &st ))
{
Afc_Close( pEvn );
return NULL;
}
HAFC_HANDLE h = Afc_Open_File( pEvn, itunes , "r");
if( !h )
{
Afc_Close( pEvn);
return NULL;
}
char* buf = new char[st.st_size];
if( !buf)
{
Afc_Close_Handle( h );
Afc_Close( pEvn );
return NULL;
}
int pos = 0;
while( pos < st.st_size )
{
int len = Afc_Read_File( h, buf + pos, st.st_size - pos );
if( len <=0 )
break;
pos += len ;
}
Afc_Close_Handle( h );
Afc_Close( pEvn );
///
CFDataRef dd = iTunesApi::CFDataCreateWithBytesNoCopy( 0, (UInt8*)buf, st.st_size, iTunesApi::s_kCFAllocatorNull );
cfDicRef_Res = (CFDictionaryRef)iTunesApi::CFPropertyListCreateFromXMLData(0,dd,0,0);
iTunesApi::CFRelease(dd);
delete[] buf;
/////
return cfDicRef_Res;
}// 打开APP程序包路径
HAFC_ENV CPhoneMgr::App_Open_Dir( am_device* pDevice, const char* apple_id)
{
///
if(MDERR_OK != ConnectDevice(pDevice))
return NULL;afc_connection* fd = NULL;
mach_error_t ret = iTunesApi::AMDeviceStartService( pDevice, iTunesApi::__CFStringMakeConstantString("com.apple.mobile.house_arrest"), &fd, NULL);
DisConnectDevice(pDevice);
if( ret )
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AMDeviceStartService[com.apple.mobile.house_arrest] error");
return NULL;
}
////
CFDictionaryRef res = NULL;
CFStringRef cfRef_AppID = iTunesApi::CFStringCreateWithCString( NULL, apple_id, kCFStringEncodingUTF8 );
if( !cfRef_AppID)
{
closesocket((SOCKET)fd);
return NULL;
}
CFDictionaryRef cfDicRef_Req = iTunesApi::CFDictionaryCreateMutable( NULL,0,NULL,NULL);
if(!cfDicRef_Req)
{
iTunesApi::CFRelease(cfRef_AppID);
closesocket((SOCKET)fd);
return NULL;
}
// iTunesApi::CFDictionaryAddValue((CFMutableDictionaryRef)(mp), (void*)(k), (void*)(v) )
iTunesApi::CFDictionaryAddValue((CFMutableDictionaryRef)cfDicRef_Req,(void*)iTunesApi::__CFStringMakeConstantString("Command"), (void*)iTunesApi::__CFStringMakeConstantString("VendContainer"));
iTunesApi::CFDictionaryAddValue((CFMutableDictionaryRef)cfDicRef_Req,(void*)iTunesApi::__CFStringMakeConstantString("Identifier"), (void*)cfRef_AppID );
bool bSend = Send_Xml_Request( fd, cfDicRef_Req );
if( !bSend )
{
iTunesApi::CFRelease(cfDicRef_Req);
iTunesApi::CFRelease(cfRef_AppID);
closesocket((SOCKET)fd);
return NULL;
}
CFPropertyListRef cfPlRef_Res = Recv_Xml_Response( fd );
if( !cfPlRef_Res )
{
iTunesApi::CFRelease(cfDicRef_Req);
iTunesApi::CFRelease(cfRef_AppID);
closesocket((SOCKET)fd);
return NULL;
}
if( iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)cfPlRef_Res, iTunesApi::__CFStringMakeConstantString("Error") ) )
{
iTunesApi::CFRelease(cfDicRef_Req);
iTunesApi::CFRelease(cfRef_AppID);
iTunesApi::CFRelease(cfPlRef_Res);
closesocket((SOCKET)fd);
return NULL;
}
iTunesApi::CFRelease(cfPlRef_Res);afc_connection* afc;
ret = iTunesApi::AFCConnectionOpen( fd, 0, &afc);
if(ret)
{
iTunesApi::CFRelease(cfDicRef_Req);
iTunesApi::CFRelease(cfRef_AppID);
closesocket((SOCKET)fd);
return NULL;
}
///////Afc_Env_t* pEnv = new Afc_Env_t;
memset(pEnv,0,sizeof(Afc_Env_t));
pEnv->pAfc = afc;
pEnv->pSocket = fd;
return pEnv;
}// AFC打开文件
HAFC_HANDLE CPhoneMgr::Afc_Open_File( HAFC_ENV pEnv, const char* path, const char* str_mode )
{
if( !str_mode || !path || !pEnv )
return NULL;
/////
unsigned int mode = 0;
if( _stricmp( str_mode,"r") ==0 )
{
mode = 1;
}
else if( _stricmp( str_mode,"w")==0)
{
mode = 2;
}
else
{
return NULL;
}
/////
afc_file_ref handle=0;
mach_error_t ret = iTunesApi::AFCFileRefOpen( pEnv->pAfc, (char*)path , mode , 0, &handle );
if ( ret != MDERR_OK )
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AFCFileRefOpen["<<path<<"] error["<<ret<<"]");
return NULL;
}
///////
Afc_Handle_t* h = new Afc_Handle_t;
memset(h, 0,sizeof(Afc_Handle_t));
h->pEnv = pEnv;
h->bIsDir = false;
h->pFile = handle;return h;
}// AFC读取文件
int CPhoneMgr::Afc_Read_File( HAFC_HANDLE pFile, char* buf, int len )
{
if(!buf || len<=0 || !pFile )return -1;
unsigned int ret_len = (unsigned int)len;
mach_error_t ret = iTunesApi::AFCFileRefRead(pFile->pEnv->pAfc, pFile->pFile, buf, &ret_len);
if(ret)
{
//printf("AFCFileRefRead() = %d\n", ret);
LOG4CPLUS_ERROR(Logger::getRoot(),"AFCFileRefRead error["<<ret<<"]");
return -1;
}
return ret_len;
}// AFC写文件
int CPhoneMgr::Afc_Write_File( HAFC_HANDLE pFile, char* buf, int len )
{
if(!buf || len<=0 || !pFile )
return -1;
mach_error_t ret;
unsigned int ret_len = (unsigned int)len;
ret = iTunesApi::AFCFileRefWrite(pFile->pEnv->pAfc, pFile->pFile, buf, ret_len);
if(ret)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AFCFileRefWrite error["<<ret<<"]");
return -1;
}
return ret_len;
}// 获取操作系统Common_Data路径
void CPhoneMgr::Common_Data_Path( char* path )
{
if( !::SHGetSpecialFolderPathA( NULL, path, CSIDL_COMMON_APPDATA, FALSE))
{
strcpy( path,"c:\\xApp_tools");
}
else
{
strcat(path, "\\xApp_tools");
}
CreateDirectoryA(path, NULL);
}// APP安装线程
bool CPhoneMgr::AppInstallThread(am_device* pDevice,const char* packetPath, DWORD dwUserdata,HWND hWnd)
{
char install_path[260];
sprintf( install_path, "/PublicStaging/%ld.ipa", time(0) );// 打开AFC服务
HAFC_ENV afc = Afc_Open( pDevice);
if( !afc )
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_ERROR,MAKELPARAM(dwUserdata,0));
return false;
}// 上传文件
if( Afc_UpFile( afc, install_path, packetPath, hWnd, dwUserdata))
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_ERROR,MAKELPARAM(dwUserdata,0));
Afc_Close( afc );
return false;
}
// 文件上传成功
//PostMessage(hWnd,MSG_AFC_UPFILE,0,100);
Afc_Close( afc );// 连接设备
if( MDERR_OK != ConnectDevice(pDevice) )
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_ERROR,MAKELPARAM(dwUserdata,0));
return false;
}afc_connection* fd;
afc_connection* house_arrest_fd = NULL;
mach_error_t ret;
// 打开安装服务
ret = iTunesApi::AMDeviceStartService( pDevice, iTunesApi::__CFStringMakeConstantString("com.apple.mobile.installation_proxy"), &fd, NULL);
DisConnectDevice(pDevice);
if( ret )
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AMDeviceStartService[com.apple.mobile.installation_proxy] Error:"<<ret);
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_ERROR,MAKELPARAM(dwUserdata,0));
return false;
}
CFDictionaryRef req = iTunesApi::CFDictionaryCreateMutable( NULL,0,NULL,NULL);
CFStringRef pkt_path = iTunesApi::CFStringCreateWithCString( NULL, install_path, kCFStringEncodingUTF8 );
if( !req || !pkt_path)
{
if( req)
iTunesApi::CFRelease( req);
if( pkt_path)
iTunesApi::CFRelease( pkt_path);
closesocket((SOCKET)fd);
LOG4CPLUS_ERROR(Logger::getRoot(),"Something Error");
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_ERROR,MAKELPARAM(dwUserdata,0));
return false;
}// 构造安装命令
iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)req, (void*)iTunesApi::__CFStringMakeConstantString("Command"), (void*)iTunesApi::__CFStringMakeConstantString("Install"));
iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)req, (void*)iTunesApi::__CFStringMakeConstantString("PackagePath"), (void*)pkt_path);// 发送安装请求
bool bSend = Send_Xml_Request(fd,req);
ret = INSTALL_STATUS_OK;
if(!bSend)
ret = INSTALL_STATUS_ERROR;
while( bSend )
{
CFPropertyListRef res = Recv_Xml_Response( fd );
if( !res )
{
ret = INSTALL_STATUS_ERROR;
break;
}CFStringRef aerr= (CFStringRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)res, iTunesApi::__CFStringMakeConstantString("Error") );
CFStringRef astatus= (CFStringRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)res, iTunesApi::__CFStringMakeConstantString("Status") );
if( aerr )
{
char err[256]="";
CFString2CString( aerr, err, 256 );
//sprintf( apple_errmsg, "ab_app_install error: %s", err );
LOG4CPLUS_ERROR(Logger::getRoot(),"AppInstall Error:"<<err);
iTunesApi::CFRelease(res);
ret = INSTALL_STATUS_ERROR;
break;
}
if( !astatus )
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AppInstall Error:unknown err");
ret = INSTALL_STATUS_ERROR;
iTunesApi::CFRelease( res );
break;
}
char status[256]="";
CFString2CString( astatus, status, 256 );
LOG4CPLUS_DEBUG(Logger::getRoot(),"AppInstall Status : "<<status);
if( _stricmp( status, "Complete") == 0 )
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,100));
iTunesApi::CFRelease( res );
break;
}
///
if( _stricmp( status, "CreatingStagingDirectory" )==0)
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,5));
}
else if( stricmp( status, "ExtractingPackage") == 0)
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,15));
}
else if( stricmp( status, "InspectingPackage") == 0)
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,20));
}
else if( stricmp( status, "PreflightingApplication") == 0)
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,30));
}
else if( stricmp( status, "VerifyingApplication") == 0)
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,40));
}
else if( stricmp( status, "CreatingContainer") == 0)
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,50));
}
else if( stricmp( status, "InstallingApplication") == 0)
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,60));
}
else if( stricmp( status, "PostflightingApplication") == 0)
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,70));
}
else if( stricmp( status, "SandboxingApplication") == 0)
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,80));
}
else if( stricmp( status, "GeneratingApplicationMap") == 0)
{
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_INSTALL,MAKELPARAM(dwUserdata,90));
}
///
iTunesApi::CFRelease( res );
}
iTunesApi::CFRelease( req );
iTunesApi::CFRelease( pkt_path );
//////
closesocket( (SOCKET)fd );
////////
PostMessage(hWnd,MSG_DEVICEINSTALL,ret,MAKELPARAM(dwUserdata,0));
return ret == INSTALL_STATUS_OK;
}// 安装APP接口
void CPhoneMgr::App_Install(am_device* pDevice, const char* packetPath, DWORD dwUserdata,HWND hWnd)
{
if(hWnd == NULL)
hWnd = (HWND)m_pUserData;
if(!pDevice)
{
LOG4CPLUS_DEBUG(Logger::getRoot(),"Call App_Install failed:pDevice is null");
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_ERROR,MAKELPARAM(dwUserdata,0));
return;
}
if(!packetPath)
{
LOG4CPLUS_DEBUG(Logger::getRoot(),"Call App_Install failed: Ipa Packet Path Is Null");
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_ERROR,MAKELPARAM(dwUserdata,0));
return;
}// 启动线程获取基础信息
boost::thread thread(boost::bind(&CPhoneMgr::AppInstallThread,this,pDevice,packetPath,dwUserdata,hWnd));
}// 上传文件
int CPhoneMgr::Afc_UpFile( HAFC_ENV env, const char* remote_path,const char* local_path,HWND hWnd,DWORD dwUserdata)
{
if( !env || !remote_path || !local_path )
return -1;
struct _stat64 st;
if( _stati64( local_path, &st) < 0)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"_stati64["<<local_path<<"] Error");
return -1;
}
FILE* fp = fopen( local_path, "rb");
if( !fp)
{
LOG4CPLUS_ERROR(Logger::getRoot(),"fopen["<<local_path<<" , rb] Error");
return -1;
}
HAFC_HANDLE h = Afc_Open_File( env, remote_path,"w");
if( !h )
{
fclose(fp);
return -1;
}char buf[BUF_SIZE];
__int64 size = st.st_size;
__int64 idx = 0;
COleDateTime dtTimer(COleDateTime::GetCurrentTime());
while( idx < size )
{
int len = fread( buf, 1, BUF_SIZE, fp );
if( len<=0) break;int r = Afc_Write_File( h, buf, len );
if( r != len )
break;
///
idx += len;
double pos = (double)idx/(double)size*100;
//(*pFunSetProgressPos)(pos,0);
LOG4CPLUS_DEBUG(Logger::getRoot(),"Afc_UpFile["<<remote_path<<"] Cul:"<<idx<<" total:"<<size);
if((COleDateTime::GetCurrentTime() - dtTimer).GetTotalSeconds()>=1)
{
dtTimer = COleDateTime::GetCurrentTime();
PostMessage(hWnd,MSG_DEVICEINSTALL,INSTALL_STATUS_UPFILE,MAKELPARAM(dwUserdata,pos));
}
}
////
Afc_Close_Handle( h );
fclose(fp);
if( idx != size )
{ // fail
remove(remote_path );
LOG4CPLUS_ERROR(Logger::getRoot(),"UpFile["<<remote_path<<"] Error");
return -1;
}
///
return 0;
}void CPhoneMgr::AppUnInstallThread(am_device* pDevice, const AppInfo* pAppInfo,HWND hWnd)
{
if( MDERR_OK != ConnectDevice( pDevice))
{
PostMessage(hWnd,MSG_UNINSTALL,1,(LPARAM)pAppInfo);
return ;
}afc_connection* fd;
afc_connection* house_arrest_fd = NULL;
mach_error_t ret = iTunesApi::AMDeviceStartService(pDevice, iTunesApi::__CFStringMakeConstantString("com.apple.mobile.installation_proxy"), &fd, NULL);
DisConnectDevice( pDevice);
if( ret )
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AMDeviceStartService[com.apple.mobile.installation_proxy] Error:"<<ret);
PostMessage(hWnd,MSG_UNINSTALL,1,(LPARAM)pAppInfo);
return;
}
/////
//int nRet = RemoveApp(fd,apple_id,"Uninstall");
//////
CFDictionaryRef req = iTunesApi::CFDictionaryCreateMutable( NULL,0,NULL,NULL);
CFStringRef sappid = iTunesApi::CFStringCreateWithCString( NULL, pAppInfo->sAppleID, kCFStringEncodingUTF8 );
if( !req || !sappid )
{
if( req)
iTunesApi::CFRelease(req);
if(sappid)
iTunesApi::CFRelease(sappid);LOG4CPLUS_ERROR(Logger::getRoot(),"SomeThing Error");
PostMessage(hWnd,MSG_UNINSTALL,1,(LPARAM)pAppInfo);
return;
}
////
iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)req,(void*)iTunesApi::__CFStringMakeConstantString("Command"),(void*)iTunesApi::__CFStringMakeConstantString("Uninstall") );
iTunesApi::CFDictionaryAddValue( (CFMutableDictionaryRef)req,(void*)iTunesApi::__CFStringMakeConstantString("ApplicationIdentifier"),(void*)sappid);bool bSend = Send_Xml_Request( fd, req );
ret = MDERR_OK;
while( bSend )
{
CFPropertyListRef res = Recv_Xml_Response( fd );
if( !res )
{
ret = 1;
break;
}CFStringRef aerr= (CFStringRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)res, iTunesApi::__CFStringMakeConstantString("Error") );
CFStringRef astatus= (CFStringRef)iTunesApi::CFDictionaryGetValue( (CFDictionaryRef)res, iTunesApi::__CFStringMakeConstantString("Status") );
if( aerr )
{
char err[256]="";
CFString2CString( aerr, err, 256 );
//sprintf( apple_errmsg, "ab_app_install error: %s", err );
LOG4CPLUS_ERROR(Logger::getRoot(),"AppUnInstallThread Error:"<<err);
iTunesApi::CFRelease(res);
iTunesApi::CFRelease(sappid);
ret = 1;
break;
}
if( !astatus )
{
LOG4CPLUS_ERROR(Logger::getRoot(),"AppUnInstallThread Error:unknown err");
iTunesApi::CFRelease( res );
iTunesApi::CFRelease(sappid);
ret = 1;
break;
}
char status[256]="";
CFString2CString( astatus, status, 256 );
if( _stricmp( status, "Complete")==0)
{
iTunesApi::CFRelease(res);
ret = MDERR_OK;
break;
}
///
iTunesApi::CFRelease( res );
}iTunesApi::CFRelease(sappid);
closesocket((SOCKET)fd);LOG4CPLUS_DEBUG(Logger::getRoot(),"AppUnInstall AppleID["<<pAppInfo->sAppleID<<"]");
PostMessage(hWnd,MSG_UNINSTALL,ret,(LPARAM)pAppInfo);
}// 卸载APP接口
void CPhoneMgr::App_UnInstall( am_device* pDevice, const AppInfo* pAppInfo,bool bThread /*= true*/,HWND hWnd)
{
if(hWnd==NULL)
hWnd = (HWND)m_pUserData;
if(!pDevice)
{
LOG4CPLUS_DEBUG(Logger::getRoot(),"Call App_UnInstall failed:pDevice is null");
PostMessage(hWnd,MSG_UNINSTALL,1,0);
return;
}/*char* sAppleID = new char[256];
memset(sAppleID,0,256);
memcpy(sAppleID,apple_id,256);*/
// 启动线程获取基础信息
if(bThread)
boost::thread thread(boost::bind(&CPhoneMgr::AppUnInstallThread,this,pDevice,pAppInfo,hWnd));
else
AppUnInstallThread(pDevice,pAppInfo,hWnd);
}// IOS字符串转换
void CPhoneMgr::CFString2CString( CFStringRef cfValue, char* pResult,int nResultLen)
{
if(!cfValue)
return;char cUtf8[MAX_PATH]; memset(cUtf8,0,MAX_PATH);
wchar_t wcTmp[MAX_PATH]; memset(wcTmp,0,MAX_PATH);
iTunesApi::CFStringGetCString(cfValue, cUtf8, MAX_PATH-1, kCFStringEncodingUTF8 );
::MultiByteToWideChar( CP_UTF8,0,cUtf8,-1, wcTmp, 256);
memset(cUtf8,0,sizeof(cUtf8));
::WideCharToMultiByte(CP_ACP,0,wcTmp,-1,cUtf8, MAX_PATH,NULL,NULL);
if( nResultLen>0)
strncpy( pResult, cUtf8, nResultLen>(MAX_PATH-1)?(MAX_PATH-1):nResultLen);
}// 修改手机名称
bool CPhoneMgr::RenameIphone(am_device* pDevice, const char* sNewName )
{
if(!pDevice)
return false;mach_error_t nMach_error;
// 连接设备
if (MDERR_OK != (nMach_error = ConnectDevice(pDevice)))
return false;CFStringRef cfKey = iTunesApi::__CFStringMakeConstantString("DeviceName");
//CFStringRef cfValue = iTunesApi::__CFStringMakeConstantString(sNewName);
CFStringRef cfValue = iTunesApi::CFStringCreateWithCString(NULL,sNewName,kCFStringEncodingUTF8);
iTunesApi::AMDeviceSetValue( pDevice, NULL, cfKey, cfValue);
// 断开连接
DisConnectDevice( pDevice );
return true;
}
_kCFTypeDictionaryKeyCallBacks = (CFDictionaryKeyCallBacks*) GetProcAddress(corefoundation, "kCFTypeDictionaryKeyCallBacks");
_kCFTypeDictionaryValueCallBacks= (CFDictionaryValueCallBacks*) GetProcAddress(corefoundation, "kCFTypeDictionaryValueCallBacks");void RebootDevice(void *pDeviceSession)
{
CFMutableDictionaryRef request = cfDictionaryCreateMutable(NULL, 0, _kCFTypeDictionaryKeyCallBacks, _kCFTypeDictionaryValueCallBacks);
cfDictionarySetValue(request, getConstCFString("Request"), getConstCFString("Restart"));
cfDictionarySetValue(request, getConstCFString("DisplayPass"), *boolRefTrue);
cfDictionarySetValue(request, getConstCFString("WaitForDisconnect"), *boolRefFalse);
SendDeviceCommand(pDeviceSession, request);
}void ShutdownDevice(void *pDeviceSession)
{
CFMutableDictionaryRef request = cfDictionaryCreateMutable(NULL, 0, _kCFTypeDictionaryKeyCallBacks, _kCFTypeDictionaryValueCallBacks);
cfDictionarySetValue(request, getConstCFString("Request"), getConstCFString("Shutdown"));
cfDictionarySetValue(request, getConstCFString("DisplayPass"), *boolRefTrue);
cfDictionarySetValue(request, getConstCFString("WaitForDisconnect"), *boolRefFalse);
SendDeviceCommand(pDeviceSession, request);
}
void SendDeviceCommand(void *pDeviceSession, CFMutableDictionaryRef& ref)
{
int socket = AttachToDeviceAndService(pDeviceSession, "com.apple.mobile.diagnostics_relay");
if (socket == -1)
{
return;
}CFDataRef xmlData = CFPropertyListCreateData(NULL, ref, kCFPropertyListBinaryFormat_v1_0, 0, NULL);
const char *buf = (const char *)cfDataGetBytePtr(xmlData);
size_t Size = cfDataGetLength(xmlData);CSocketOperation sockOperation;
char *buff = (char *)Bplist2Xml((const char*)buf, Size);
if (!sockOperation.write(socket, buf, Size))
{
cfRelease(xmlData);
}unsigned char *msg = NULL;
int len = 0;if (!sockOperation.read(socket, &msg, &len))
{
return;
}closesocket(socket);
}
int AttachToDeviceAndService(void* pDeviceSession, char *service) {
AMDeviceRef device = (AMDeviceRef)pDeviceSession;SDMMD_AMConnectionRef serviceCon = NULL;
if (device) {
mach_error_t result = am_device_connect(device);
if (0 == result) {
result = am_device_start_session(device);
if (0 == result) {
CFStringRef serviceString = cfStringCreateWithCString(NULL, service, kCFStringEncodingMacRoman);int afc_conn = -1;
CFStringRef afc_refVal;
afc_refVal = getConstCFString(service);
result = amdeviceStartService(device, afc_refVal, &afc_conn, NULL);
//result = amdeviceStartService(device, serviceString, NULL, (unsigned int**)&serviceCon);
if (0 == result) {CFStringRef deviceName = (CFStringRef)am_copy_value(device, NULL, getConstCFString("DeviceName"));
char *name = (char*)cfStringGetCStringPtr(deviceName, kCFStringEncodingMacRoman);
if (!name) {
name = "unnamed device";
}
printf("Connected to %s on \"%s\" ...\n", name, service);
//stopSession(device);
serviceCon = NULL;
}
else
{
afc_conn = -1;
}
cfRelease(serviceString);amdeviceStopSession(device);
amdeviceDisconnect(device);return afc_conn;
}
}
}
else {
printf("Could not find device with that UDID\n");
}return -1;
}