示例#1
0
        private void SendPacket(GarminUSBPacket aPacket)
        {
            var    bytesToWrite = 12 + (int)aPacket.Size;
            int    theBytesReturned;
            IntPtr pPacket = Marshal.AllocHGlobal(bytesToWrite);

            Marshal.StructureToPtr(aPacket, pPacket, false);

            bool r = APIs.WriteFile(handle, pPacket, bytesToWrite, out theBytesReturned, IntPtr.Zero);

            Marshal.FreeHGlobal(pPacket);
            if (!r)
            {
                throw new GarminUsbException(Strings.ErrorCommunicatingWithDevice);
            }

            // If the packet size was an exact multiple of the USB packet size, we must make a final write call with no data
            if (bytesToWrite % usbPacketSize == 0)
            {
                r = APIs.WriteFile(handle, IntPtr.Zero, 0, out theBytesReturned, IntPtr.Zero);
                if (!r)
                {
                    throw new GarminUsbException(Strings.ErrorCommunicatingWithDevice);
                }
            }
        }
示例#2
0
 private void StopUSBCommunication()
 {
     try
     {
         if (handle != IntPtr.Zero)
         {
             APIs.CloseHandle(handle);
             handle = IntPtr.Zero;
         }
     }
     finally
     {
         ReadingNow = false;
     }
 }
示例#3
0
        private static APIs.DeviceInterfaceDetailData GetDeviceInfo(IntPtr hDevInfoSet, Guid deviceGUID, out string deviceID, int devicePortIndex)
        {
            // Get a Device Interface Data structure.
            // --------------------------------------

            APIs.DeviceInterfaceData interfaceData = new APIs.DeviceInterfaceData();
            APIs.CRErrorCodes        crResult;
            IntPtr startingDevice;

            APIs.DevinfoData infoData = new APIs.DevinfoData();
            APIs.DeviceInterfaceDetailData detailData = new APIs.DeviceInterfaceDetailData();

            bool   result = true;
            IntPtr ptrInstanceBuf;
            uint   requiredSize = 0;

            interfaceData.Init();
            infoData.Size   = Marshal.SizeOf(typeof(APIs.DevinfoData));
            detailData.Size = Marshal.SizeOf(typeof(APIs.DeviceInterfaceDetailData));

            result = APIs.SetupDiEnumDeviceInterfaces(
                hDevInfoSet,
                0,
                ref deviceGUID,
                (uint)devicePortIndex,
                ref interfaceData);

            if (!result)
            {
                if (Marshal.GetLastWin32Error() == APIs.ERROR_NO_MORE_ITEMS)
                {
                    deviceID = string.Empty;
                    return(new APIs.DeviceInterfaceDetailData());
                }
                else
                {
                    throw new ApplicationException("[CCore::GetDeviceInfo] Error when retriving device info");
                }
            }


            //Get a DevInfoDetailData and DeviceInfoData
            // ------------------------------------------

            // First call to get the required size.
            result = APIs.SetupDiGetDeviceInterfaceDetail(
                hDevInfoSet,
                ref interfaceData,
                IntPtr.Zero,
                0,
                ref requiredSize,
                ref infoData);

            // Create the buffer.
            detailData.Size = 5;

            // Call with the correct buffer
            result = APIs.SetupDiGetDeviceInterfaceDetail(
                hDevInfoSet,
                ref interfaceData,
                ref detailData, // ref devDetailBuffer,
                requiredSize,
                ref requiredSize,
                ref infoData);

            if (!result)
            {
                System.Windows.Forms.MessageBox.Show(Marshal.GetLastWin32Error().ToString());
                throw new ApplicationException("[CCore::GetDeviceInfo] Can not get SetupDiGetDeviceInterfaceDetail");
            }

            startingDevice = infoData.DevInst;

            //Get current device data
            ptrInstanceBuf = Marshal.AllocHGlobal(1024);
            crResult       = (APIs.CRErrorCodes)APIs.CM_Get_Device_ID(startingDevice, ptrInstanceBuf, 1024, 0);

            if (crResult != APIs.CRErrorCodes.CR_SUCCESS)
            {
                throw new ApplicationException("[CCore::GetDeviceInfo] Error calling CM_Get_Device_ID: " + crResult);
            }

            // We have the pnp string of the parent device.
            deviceID = Marshal.PtrToStringAuto(ptrInstanceBuf);

            Marshal.FreeHGlobal(ptrInstanceBuf);
            return(detailData);
        }
示例#4
0
        private GarminUSBPacket GetPacket()
        {
            GarminUSBPacket packet;
            var             bufferSize = 0;
            var             buffer     = new byte[0];

            while (true)
            {
                // Read async data until the driver returns less than the
                // max async data size, which signifies the end of a packet
                var tempBuffer = new byte[APIs.ASYNC_DATA_SIZE];
                int bytesReturned;

                IntPtr pInBuffer  = Marshal.AllocHGlobal(0);
                IntPtr pOutBuffer = Marshal.AllocHGlobal(APIs.ASYNC_DATA_SIZE);

                bool r = APIs.DeviceIoControl(
                    handle.ToInt32(),
                    CTL_CODE(0x00000022, 0x850, 0, 0),
                    pInBuffer,
                    0,
                    pOutBuffer,
                    APIs.ASYNC_DATA_SIZE,
                    out bytesReturned,
                    0);

                Marshal.Copy(pOutBuffer, tempBuffer, 0, APIs.ASYNC_DATA_SIZE);
                Marshal.FreeHGlobal(pInBuffer);
                Marshal.FreeHGlobal(pOutBuffer);
                if (!r)
                {
                    throw new GarminUsbException(Strings.ErrorCommunicatingWithDevice);
                }

                bufferSize += APIs.ASYNC_DATA_SIZE;
                var newBuffer = new byte[bufferSize];

                if (buffer.Length > 0)
                {
                    Array.Copy(buffer, 0, newBuffer, 0, buffer.Length);
                }
                Array.Copy(tempBuffer, 0, newBuffer, bufferSize - APIs.ASYNC_DATA_SIZE, tempBuffer.Length);

                buffer = newBuffer;

                if (bytesReturned != APIs.ASYNC_DATA_SIZE)
                {
                    packet = new GarminUSBPacket(buffer);
                    break;
                }
            }

            // If this was a small "signal" packet, read a real
            // packet using ReadFile
            if (packet.Type == 0 && packet.Id == 2)
            {
                var newBuffer     = new byte[MAX_BUFFER_SIZE];
                var bytesReturned = 0;

                // A full implementation would keep reading (and queueing)
                // packets until the driver returns a 0 size buffer.
                bool r = APIs.ReadFile(handle,
                                       newBuffer,
                                       MAX_BUFFER_SIZE,
                                       ref bytesReturned,
                                       IntPtr.Zero);
                if (!r)
                {
                    throw new GarminUsbException(Strings.ErrorCommunicatingWithDevice);
                }
                return(new GarminUSBPacket(newBuffer));
            }

            return(packet);
        }
示例#5
0
        private void StartUSBCommunication()
        {
            ReadingNow = true;

            var       guid = new Guid("2C9C45C2-8E7D-4C08-A12D-816BBAE722C0");
            string    deviceId;
            const int portIndex = 0;

            IntPtr hDevInfoSet = APIs.SetupDiGetClassDevs(ref guid,
                                                          0,
                                                          IntPtr.Zero,
                                                          (int)(APIs.DeviceFlags.DigCDDeviceInterface | APIs.DeviceFlags.DigCFPresent));

            APIs.DeviceInterfaceDetailData mDetailedData = GetDeviceInfo(hDevInfoSet, guid, out deviceId, portIndex);

            handle = APIs.CreateFile(mDetailedData.DevicePath, FileAccess.Read | FileAccess.Write, FileShare.None, IntPtr.Zero, FileMode.Open, 0x00000080, IntPtr.Zero);

            // Did we get a handle?
            if ((int)handle < 0)
            {
                throw new GarminUsbException(Strings.ErrorFindingDevice);
            }

            IntPtr usbPacketSizePointer = Marshal.AllocHGlobal(sizeof(Int16));
            int    bytesReturned;

            bool r = APIs.DeviceIoControl(
                handle.ToInt32(),
                CTL_CODE(0x00000022, 0x851, 0, 0),
                IntPtr.Zero,
                0,
                usbPacketSizePointer,
                (uint)sizeof(int),
                out bytesReturned,
                0);

            if (!r)
            {
                throw new GarminUsbException(Strings.ErrorCommunicatingWithDevice);
            }
            usbPacketSize = (Int16)Marshal.PtrToStructure(usbPacketSizePointer, typeof(Int16));

            Marshal.FreeHGlobal(usbPacketSizePointer);

            // Tell the device that we are starting a session.
            var startSessionPacket = new GarminUSBPacket {
                Id = 5
            };

            SendPacket(startSessionPacket);

            GarminUSBPacket packet;

            while (true)
            {
                packet = GetPacket();
                if (packet.Type == 0 && packet.Id == 6)
                {
                    break;
                }
            }
        }