예제 #1
0
        /// <summary>
        /// 开启Session。Session需要在调用服务前先行打开,然后完成服务操作后自行关闭(函数会自动关闭),否则可能会遇到无法打开服务的错误
        /// </summary>
        /// <returns></returns>
        public kAMDError StartSession(bool isRretry = false)
        {
            var kAMDSuccess = kAMDError.kAMDSuccess;

            try
            {
                if (!isSessionOpen)
                {
                    kAMDSuccess = (kAMDError)MobileDevice.AMDeviceStartSession(DevicePtr);
                    if (kAMDSuccess != kAMDError.kAMDInvalidHostIDError)
                    {
                        if (kAMDSuccess != (int)kAMDError.kAMDSuccess)
                        {
                            //修复:Session关闭后一段时间无法再次打开的问题
                            if (!isRretry)
                            {
                                Disconnect();
                                Connect();
                                return(StartSession(true));
                            }

                            return(kAMDSuccess);
                        }

                        isSessionOpen = true;
                        return(kAMDSuccess);
                    }

                    if (MobileDevice.AMDeviceUnpair(DevicePtr) == (int)kAMDError.kAMDSuccess &&
                        MobileDevice.AMDevicePair(DevicePtr) == (int)kAMDError.kAMDSuccess)
                    {
                        kAMDSuccess = (kAMDError)MobileDevice.AMDeviceStartSession(DevicePtr);
                        if (kAMDSuccess != kAMDError.kAMDSuccess)
                        {
                            return(kAMDSuccess);
                        }

                        isSessionOpen = true;
                        return(kAMDSuccess);
                    }
                }

                return(kAMDSuccess);
            }
            catch
            {
                kAMDSuccess = kAMDError.kAMDUndefinedError;
            }

            return(kAMDSuccess);
        }
예제 #2
0
        /// <summary>
        /// 获取设备信息
        /// </summary>
        /// <param name="domain">The domain.</param>
        /// <param name="key">The key.</param>
        /// <returns>System.Object.</returns>
        public object GetDeviceValue(string domain, string key)
        {
            object resultValue = null;

            try
            {
                var isReconnect     = false;
                var isReOpenSession = false;
                if (!isConnected)
                {
                    if (Connect() != (int)kAMDError.kAMDSuccess)
                    {
                        return(null);
                    }

                    isReconnect = true;
                }

                if (!isSessionOpen)
                {
                    if (StartSession(false) == (int)kAMDError.kAMDSuccess)
                    {
                        isReOpenSession = true;
                    }
                    else
                    {
                        if (isReconnect)
                        {
                            Disconnect();
                        }
                    }
                }

                resultValue = MobileDevice.AMDeviceCopyValue(DevicePtr, domain, key);
                if (isReOpenSession)
                {
                    StopSession();
                }

                if (isReconnect)
                {
                    Disconnect();
                }
            }
            catch
            {
            }

            return(resultValue);
        }
예제 #3
0
        /// <summary>
        /// 开启AFC服务
        /// </summary>
        /// <param name="inSocket">socket句柄</param>
        /// <returns></returns>
        public bool OpenConnection(int inSocket, out IntPtr connPtr)
        {
            connPtr = IntPtr.Zero;
            try
            {
                if (MobileDevice.AFCConnectionOpen(new IntPtr(inSocket), 0, ref connPtr) == (int)kAMDError.kAMDSuccess)
                {
                    return(true);
                }
            }
            catch
            {
            }

            return(false);
        }
예제 #4
0
        /// <summary>
        /// 断开设备链接,但不会断开USB树链接,因而可以通过调用Connect来重新链接到设备
        /// </summary>
        /// <returns></returns>
        public kAMDError Disconnect()
        {
            var kAMDSuccess = kAMDError.kAMDSuccess;

            isConnected = false;
            try
            {
                kAMDSuccess = (kAMDError)MobileDevice.AMDeviceDisconnect(DevicePtr);
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception.ToString());
            }

            return(kAMDSuccess);
        }
예제 #5
0
        /// <summary>
        /// 停止Socket服务
        /// </summary>
        /// <param name="inSocket"></param>
        /// <returns></returns>
        private bool StopSocketService(ref int socket)
        {
            kAMDError kAMDSuccess = kAMDError.kAMDSuccess;

            if (socket > 0)
            {
                try
                {
                    kAMDSuccess = (kAMDError)MobileDevice.closesocket(socket);
                }
                catch (Exception ex)
                {
                    return(false);
                }
            }

            socket = 0;
            return(kAMDSuccess != kAMDError.kAMDSuccess);
        }
예제 #6
0
        /// <summary>
        /// 链接到设备,用于设备链接失效或者手动推出后重链接操作,此函数只要设备还在USB树上,是无需用户插拔的
        /// </summary>
        /// <returns></returns>
        public kAMDError Connect()
        {
            kAMDError kAMDSuccess = kAMDError.kAMDSuccess;

            try
            {
                if (!isConnected)
                {
                    kAMDSuccess = (kAMDError)MobileDevice.AMDeviceConnect(DevicePtr);
                    if (kAMDSuccess == kAMDError.kAMDSuccess)
                    {
                        isConnected = true;
                    }
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception.ToString());
            }

            return(kAMDSuccess);
        }
예제 #7
0
        /// <summary>
        /// 开始监听链接
        /// 需要使用线程方式调用
        /// </summary>
        public void StartListen()
        {
            if (!iSStartListen)
            {
                iSStartListen = true;
                try
                {
                    deviceNotificationCallback                     = NotificationCallback;
                    deviceDFUConnectedNotificationCallback         = DfuConnectCallback;
                    deviceRecoveryConnectedNotificationCallback    = RecoveryConnectCallback;
                    deviceDFUDisConnectedNotificationCallback      = DfuDisconnectCallback;
                    deviceRecoveryDisConnectedNotificationCallback = RecoveryDisconnectCallback;
                    IntPtr    zero  = IntPtr.Zero;
                    kAMDError error = (kAMDError)MobileDevice.AMDeviceNotificationSubscribe(deviceNotificationCallback, 0, 1, 0, ref zero);
                    if (error != kAMDError.kAMDSuccess)
                    {
                        //Check "Apple Mobile Device Service" status
                        ListenErrorEvent?.Invoke(this, new ListenErrorEventHandlerEventArgs("AMDeviceNotificationSubscribe failed with error : " + error, ListenErrorEventType.StartListen));
                    }

                    IntPtr userInfo = IntPtr.Zero;
                    error = (kAMDError)MobileDevice.AMRestoreRegisterForDeviceNotifications(deviceDFUConnectedNotificationCallback, deviceRecoveryConnectedNotificationCallback, deviceDFUDisConnectedNotificationCallback, deviceRecoveryDisConnectedNotificationCallback, 0,
                                                                                            ref userInfo);
                    if (error != kAMDError.kAMDSuccess)
                    {
                        ListenErrorEvent?.Invoke(this, new ListenErrorEventHandlerEventArgs("AMRestoreRegisterForDeviceNotifications failed with error : " + error, ListenErrorEventType.StartListen));
                    }
                    //LoopRun
                    CoreFoundation.CFRunLoopRun();
                }
                catch (Exception ex)
                {
                    if (ListenErrorEvent != null)
                    {
                        ListenErrorEvent(this, new ListenErrorEventHandlerEventArgs(ex.Message, ListenErrorEventType.StartListen));
                    }
                }
            }
        }
예제 #8
0
        /// <summary>
        /// 连接设备并初始化基础服务
        /// </summary>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        private bool ConnectAndInitService()
        {
            bool      result             = false;
            kAMDError kAMDUndefinedError = kAMDError.kAMDUndefinedError;

            try
            {
                if (Connect() != (int)kAMDError.kAMDSuccess)
                {
                    return(false);
                }

                //TODO:初始化设备信息
                if (MobileDevice.AMDeviceValidatePairing(DevicePtr) != (int)kAMDError.kAMDSuccess)
                {
                    kAMDUndefinedError = (kAMDError)MobileDevice.AMDevicePair(DevicePtr);
                    if (kAMDUndefinedError != kAMDError.kAMDSuccess)
                    {
                        Disconnect();
                        return(false);
                    }
                }

                isSessionOpen = false; //确保Session已打开
                if (StartSession(false) == (int)kAMDError.kAMDSuccess)
                {
                    //TODO:初始化服务,填充基础数据
                    isConnected = true;
                    StopSession();
                    result = true;
                }
            }
            catch
            {
            }

            return(result);
        }
예제 #9
0
        /// <summary>
        /// 接收Socket消息,主要为接收设备返回的指令结果,大部分为Plist,所以函数内将会自行作转换
        /// </summary>
        /// <param name="sock"></param>
        /// <returns></returns>
        public object ReceiveMessageFromSocket(int sock)
        {
            if (sock < 0)
            {
                return(null);
            }

            int    recvCount;
            uint   buffer     = 0;
            uint   reviceSize = 0;
            uint   dataSize   = 0;
            IntPtr zero       = IntPtr.Zero;

            if (DeviceSecureIOContext != IntPtr.Zero && SocketContext != IntPtr.Zero)
            {
                if (MobileDevice.AMDServiceConnectionReceive(SocketContext, ref buffer, 4) == 4)
                {
                    dataSize = MobileDevice.ntohl(buffer); //获取数据总长度
                    if (dataSize <= 0)
                    {
                        Console.WriteLine("receive size error, dataSize:" + dataSize);
                        return(null);
                    }

                    zero = Marshal.AllocCoTaskMem((int)dataSize);
                    if (zero == IntPtr.Zero)
                    {
                        Console.WriteLine("Could not allocate message buffer.");
                        return(null);
                    }

                    var tempPtr = zero;
                    while (reviceSize < dataSize)
                    {
                        recvCount = MobileDevice.AMDServiceConnectionReceive_1(SocketContext, tempPtr, (int)(dataSize - reviceSize));
                        if (recvCount <= -1)
                        {
                            Console.WriteLine("Could not receive secure message: " + recvCount);
                            reviceSize = dataSize + 1;
                        }
                        else if (recvCount == 0)
                        {
                            Console.WriteLine("receive size is zero. ");
                            break;
                        }

                        tempPtr     = new IntPtr(tempPtr.ToInt64() + recvCount);
                        reviceSize += (uint)recvCount;
                    }
                }
            }
            else if (MobileDevice.recv_UInt(sock, ref buffer, 4, 0) == 4)
            {
                dataSize = MobileDevice.ntohl(buffer); //获取数据总长度
                if (dataSize <= 0)
                {
                    Console.WriteLine("receive size error, dataSize:" + dataSize);
                    return(null);
                }

                zero = Marshal.AllocCoTaskMem((int)dataSize);
                if (zero == IntPtr.Zero)
                {
                    Console.WriteLine("Could not allocate message buffer.");
                    return(null);
                }

                var tempPtr = zero;
                while (reviceSize < dataSize)
                {
                    recvCount = MobileDevice.recv(sock, tempPtr, (int)(dataSize - reviceSize), 0);
                    if (recvCount <= -1)
                    {
                        Console.WriteLine("Could not receive secure message: " + recvCount);
                        reviceSize = dataSize + 1;
                    }
                    else if (recvCount == 0)
                    {
                        Console.WriteLine("receive size is zero. ");
                        break;
                    }

                    tempPtr     = new IntPtr(tempPtr.ToInt64() + recvCount);
                    reviceSize += (uint)recvCount;
                }
            }

            var datas  = IntPtr.Zero;
            var srcRef = IntPtr.Zero;

            if (reviceSize == dataSize)
            {
                datas = CoreFoundation.CFDataCreate(CoreFoundation.kCFAllocatorDefault, zero, (int)dataSize);
                if (datas == IntPtr.Zero)
                {
                    Console.WriteLine("Could not create CFData for message");
                }
                else
                {
                    var errorString = IntPtr.Zero;
                    srcRef = CoreFoundation.CFPropertyListCreateFromXMLData(CoreFoundation.kCFAllocatorDefault, datas,
                                                                            CFPropertyListMutabilityOptions.kCFPropertyListImmutable, ref errorString);
                    if (srcRef == IntPtr.Zero)
                    {
                        Console.WriteLine("Could not convert raw xml into a dictionary: " + Convert.ToString(CoreFoundation.ManagedTypeFromCFType(ref errorString)));
                        return(null);
                    }
                }
            }

            if (datas != IntPtr.Zero)
            {
                try
                {
                    CoreFoundation.CFRelease(datas);
                }
                catch
                {
                }
            }

            if (zero != IntPtr.Zero)
            {
                Marshal.FreeCoTaskMem(zero);
            }

            var result = CoreFoundation.ManagedTypeFromCFType(ref srcRef);

            if (srcRef != IntPtr.Zero)
            {
                CoreFoundation.CFRelease(srcRef);
            }

            return(result);
        }
예제 #10
0
        /// <summary>
        /// 发送消息通过Socket,大部分用途为发送plist文件(指令)给设备
        /// </summary>
        /// <param name="sock"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool SendMessageToSocket(int sock, IntPtr message)
        {
            if (sock < 1 || message == IntPtr.Zero)
            {
                return(false);
            }

            var flag   = false;
            var stream = CoreFoundation.CFWriteStreamCreateWithAllocatedBuffers(IntPtr.Zero, IntPtr.Zero);

            if (stream != IntPtr.Zero)
            {
                if (!CoreFoundation.CFWriteStreamOpen(stream))
                {
                    return(false);
                }

                var zero = IntPtr.Zero;
                if (CoreFoundation.CFPropertyListWriteToStream(message, stream, CFPropertyListFormat.kCFPropertyListBinaryFormat_v1_0, ref zero) > 0)
                {
                    IntPtr srcRef        = CoreFoundation.CFWriteStreamCopyProperty(stream, CoreFoundation.kCFStreamPropertyDataWritten);
                    IntPtr buffer        = CoreFoundation.CFDataGetBytePtr(srcRef);
                    var    bufferlen     = CoreFoundation.CFDataGetLength(srcRef);
                    var    structure     = MobileDevice.htonl((uint)bufferlen);
                    var    structureSize = Marshal.SizeOf(structure);
                    if (DeviceSecureIOContext == IntPtr.Zero || SocketContext == IntPtr.Zero)
                    {
                        if (MobileDevice.send_UInt32(sock, ref structure, structureSize, 0) != structureSize)
                        {
                            Console.WriteLine("could not send message size");
                        }
                        else if (MobileDevice.send(sock, buffer, bufferlen, 0) != bufferlen)
                        {
                            Console.WriteLine("Could not send message.");
                        }
                        else
                        {
                            flag = true;
                        }
                    }
                    else if (MobileDevice.AMDServiceConnectionSend_UInt32(SocketContext, ref structure, structureSize) != structureSize)
                    {
                        Console.WriteLine("could not send message size with socket");
                    }
                    else if (MobileDevice.AMDServiceConnectionSend(SocketContext, buffer, bufferlen) != bufferlen)
                    {
                        Console.WriteLine("could not send message size");
                    }
                    else
                    {
                        flag = true;
                    }

                    CoreFoundation.CFRelease(srcRef);
                }

                CoreFoundation.CFWriteStreamClose(stream);
            }

            return(flag);
        }