1. 程式人生 > >發幾個iphone助手相關程式碼,供大家參考

發幾個iphone助手相關程式碼,供大家參考

// 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)