Example #1
0
        ///  <summary>
        ///  Uses SetupDi API functions to retrieve the device path name of an
        ///  attached device that belongs to an interface class.
        ///  </summary>
        ///  
        ///  <param name="myGuid"> an interface class GUID. </param>
        ///  <param name="devicePathName"> a pointer to an array of strings that 
        ///  will contain the device path names of attached devices. </param>
        ///  
        ///  <returns>
        ///  True if at least one device is found, False if not. 
        ///  </returns>

        public Boolean FindDeviceFromGuid(System.Guid myGuid, ref String[] devicePathName) 
        {
            String apiFunction = "";
            Boolean deviceFound = false; 
            IntPtr deviceInfoSet = new System.IntPtr();
            bool is64Bit = false;
            Boolean lastDevice = false; 
            Int32 bufferSize = 0; 
            Int32 memberIndex = 0;
            SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData = new DeviceManagement.SP_DEVICE_INTERFACE_DATA(); 
            SP_DEVICE_INTERFACE_DETAIL_DATA MyDeviceInterfaceDetailData = new DeviceManagement.SP_DEVICE_INTERFACE_DETAIL_DATA();             
            Boolean result = false; 
            Boolean success = false;

            try
            {             
                if (System.IntPtr.Size == 8)
                    is64Bit = true;

                //  ***
                //  API function: SetupDiGetClassDevs

                //  Purpose: 
                //  Retrieves a device information set for a specified group of devices.
                //  SetupDiEnumDeviceInterfaces uses the device information set.

                //  Accepts: 
                //  An interface class GUID
                //  Null to retrieve information for all device instances
                //  An optional handle to a top-level window (unused here)
                //  Flags to limit the returned information to currently present devices 
                //  and devices that expose interfaces in the class specified by the GUID.

                //  Returns:
                //  A handle to a device information set for the devices.
                //  ***

                deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

                apiFunction = "SetupDiClassDevs";
                Debug.WriteLine(MyDebugging.ResultOfAPICall(apiFunction));

                deviceFound = false;             

                do
                {
                    //  Begin with 0 and increment through the device information set until
                    //  no more devices are available.

                    //  The cbSize element of the MyDeviceInterfaceData structure must be set to
                    //  the structure's size in bytes. The size is 28 bytes.

                    // Alternative for 32-bit code:
                    // MyDeviceInterfaceData.cbSize = Marshal.SizeOf(MyDeviceInterfaceData);

                    if (!is64Bit)
                     {
                         MyDeviceInterfaceData.cbSize = 28;
                     }
                     else 
                     {
                         MyDeviceInterfaceData.cbSize = 32;
                     }
                    
                    //  ***
                    //  API function: 
                    //  SetupDiEnumDeviceInterfaces()

                    //  Purpose: Retrieves a handle to a SP_DEVICE_INTERFACE_DATA 
                    //  structure for a device.
                    //  On return, MyDeviceInterfaceData contains the handle to a
                    //  SP_DEVICE_INTERFACE_DATA structure for a detected device.

                    //  Accepts:
                    //  A DeviceInfoSet returned by SetupDiGetClassDevs.
                    //  An interface class GUID.
                    //  An index to specify a device in a device information set.
                    //  A pointer to a handle to a SP_DEVICE_INTERFACE_DATA structure for a device.

                    //  Returns:
                    //  Non-zero on success, zero on True.
                    //  ***

                    result = SetupDiEnumDeviceInterfaces(deviceInfoSet, 0, ref myGuid, memberIndex, ref MyDeviceInterfaceData);

                    apiFunction = "SetupDiEnumDeviceInterfaces";
                    Debug.WriteLine(MyDebugging.ResultOfAPICall(apiFunction));

                    //  Find out if a device information set was retrieved.

                    if ((result == false))
                    {
                        lastDevice = true;
                    }
                    else
                    {
                        //  A device is present.

                        Debug.WriteLine("  DeviceInfoSet for device #" + Convert.ToString(memberIndex) + ": ");
                        Debug.WriteLine("  cbSize = " + Convert.ToString(MyDeviceInterfaceData.cbSize));
                        Debug.WriteLine("  InterfaceclassGuid = " + MyDeviceInterfaceData.InterfaceClassGuid.ToString());                                               
                        Debug.WriteLine("  Flags = " + Convert.ToString(MyDeviceInterfaceData.Flags, 16));
                        
                        //  ***
                        //  API function: 
                        //  SetupDiGetDeviceInterfaceDetail()

                        //  Purpose:
                        //  Retrieves an SP_DEVICE_INTERFACE_DETAIL_DATA structure
                        //  containing information about a device.
                        //  To retrieve the information, call this function twice.
                        //  The first time returns the size of the structure.
                        //  The second time returns a pointer to the data.

                        //  Accepts:
                        //  A DeviceInfoSet returned by SetupDiGetClassDevs
                        //  An SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces
                        //  A pointer to an SP_DEVICE_INTERFACE_DETAIL_DATA structure to receive information 
                        //  about the specified interface.
                        //  The size of the SP_DEVICE_INTERFACE_DETAIL_DATA structure.
                        //  A pointer to a variable that will receive the returned required size of the 
                        //  SP_DEVICE_INTERFACE_DETAIL_DATA structure.
                        //  A pointer to an SP_DEVINFO_DATA structure to receive information about the device.

                        //  Returns:
                        //  Non-zero on success, zero on failure.
                        //  ***

                        //MyDeviceInterfaceDetailData = ( ( DeviceManagement.SP_DEVICE_INTERFACE_DETAIL_DATA )( null ) ); 

                        success = SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref MyDeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero);

                        apiFunction = "SetupDiGetDeviceInterfaceDetail";
                        Debug.WriteLine(MyDebugging.ResultOfAPICall(apiFunction));
                        Debug.WriteLine("  (OK to say too small)");
                        Debug.WriteLine("  Required buffer size for the data: " + bufferSize);

                        //  Store the structure's size.

                        MyDeviceInterfaceDetailData.cbSize = Marshal.SizeOf(MyDeviceInterfaceDetailData);

                        //  Allocate memory for the MyDeviceInterfaceDetailData Structure using the returned buffer size.

                        IntPtr detailDataBuffer = Marshal.AllocHGlobal(bufferSize);

                        //  Store cbSize in the first 4 bytes of the array                   
                        
                        if (!is64Bit)
                        {
                            Marshal.WriteInt32(detailDataBuffer, 4 + Marshal.SystemDefaultCharSize);
                        }
                        else
                        {
                            Marshal.WriteInt32(detailDataBuffer, 8);
                        }

                        Debug.WriteLine("cbsize = " + MyDeviceInterfaceDetailData.cbSize);

                        //  Call SetupDiGetDeviceInterfaceDetail again.
                        //  This time, pass a pointer to DetailDataBuffer
                        //  and the returned required buffer size.

                        success = SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref MyDeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero);

                        apiFunction = " Result of second call: ";
                        Debug.WriteLine(MyDebugging.ResultOfAPICall(apiFunction));
                        Debug.WriteLine("  MyDeviceInterfaceDetailData.cbSize: " + Convert.ToString(MyDeviceInterfaceDetailData.cbSize));

                        //  Skip over cbsize (4 bytes) to get the address of the devicePathName.

                        IntPtr pdevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4);

                        //  Get the String containing the devicePathName.

                        devicePathName[memberIndex] = Marshal.PtrToStringAuto(pdevicePathName);

                        Debug.WriteLine("Device Path = " + devicePathName[memberIndex]);
                        Debug.WriteLine("Device Path Length= " + devicePathName[memberIndex].Length);

                        //  Free the memory allocated previously by AllocHGlobal.

                        Marshal.FreeHGlobal(detailDataBuffer);
                        deviceFound = true;
                    }

                    memberIndex = memberIndex + 1;
                }
                while (!lastDevice == true);

                //  Trim the array to the number of devices found.
               
                String[] tempArray = new String[memberIndex - 1];
                System.Array.Copy(devicePathName, tempArray, Math.Min(devicePathName.Length, tempArray.Length));
                devicePathName = tempArray;

                Debug.WriteLine("Number of HIDs found = " + Convert.ToString(memberIndex - 1));

                //  ***
                //  API function:
                //  SetupDiDestroyDeviceInfoList

                //  Purpose:
                //  Frees the memory reserved for the DeviceInfoSet returned by SetupDiGetClassDevs.

                //  Accepts:
                //  A DeviceInfoSet returned by SetupDiGetClassDevs.

                //  Returns:
                //  True on success, False on failure.
                //  ***

                SetupDiDestroyDeviceInfoList(deviceInfoSet);

                apiFunction = "DestroyDeviceInfoList";
                Debug.WriteLine(MyDebugging.ResultOfAPICall(apiFunction));

                return deviceFound;
            }
            catch (Exception ex)
            {
                DisplayException( MODULE_NAME, ex ); 
                throw ; 
            }                          }         
Example #2
0
        ///  <summary>
        ///  Uses SetupDi API functions to retrieve the device path name of an
        ///  attached device that belongs to an interface class.
        ///  </summary>
        ///
        ///  <param name="myGuid"> an interface class GUID. </param>
        ///  <param name="devicePathName"> a pointer to an array of strings that
        ///  will contain the device path names of attached devices. </param>
        ///
        ///  <returns>
        ///  True if at least one device is found, False if not.
        ///  </returns>

        public Boolean FindDeviceFromGuid(System.Guid myGuid, ref String[] devicePathName)
        {
            String  apiFunction   = "";
            Boolean deviceFound   = false;
            IntPtr  deviceInfoSet = new System.IntPtr();
            bool    is64Bit       = false;
            Boolean lastDevice    = false;
            Int32   bufferSize    = 0;
            Int32   memberIndex   = 0;
            SP_DEVICE_INTERFACE_DATA        MyDeviceInterfaceData       = new DeviceManagement.SP_DEVICE_INTERFACE_DATA();
            SP_DEVICE_INTERFACE_DETAIL_DATA MyDeviceInterfaceDetailData = new DeviceManagement.SP_DEVICE_INTERFACE_DETAIL_DATA();
            Boolean result  = false;
            Boolean success = false;

            try
            {
                if (System.IntPtr.Size == 8)
                {
                    is64Bit = true;
                }

                //  ***
                //  API function: SetupDiGetClassDevs

                //  Purpose:
                //  Retrieves a device information set for a specified group of devices.
                //  SetupDiEnumDeviceInterfaces uses the device information set.

                //  Accepts:
                //  An interface class GUID
                //  Null to retrieve information for all device instances
                //  An optional handle to a top-level window (unused here)
                //  Flags to limit the returned information to currently present devices
                //  and devices that expose interfaces in the class specified by the GUID.

                //  Returns:
                //  A handle to a device information set for the devices.
                //  ***

                deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

                apiFunction = "SetupDiClassDevs";
                Debug.WriteLine(MyDebugging.ResultOfAPICall(apiFunction));

                deviceFound = false;

                do
                {
                    //  Begin with 0 and increment through the device information set until
                    //  no more devices are available.

                    //  The cbSize element of the MyDeviceInterfaceData structure must be set to
                    //  the structure's size in bytes. The size is 28 bytes.

                    // Alternative for 32-bit code:
                    // MyDeviceInterfaceData.cbSize = Marshal.SizeOf(MyDeviceInterfaceData);

                    if (!is64Bit)
                    {
                        MyDeviceInterfaceData.cbSize = 28;
                    }
                    else
                    {
                        MyDeviceInterfaceData.cbSize = 32;
                    }

                    //  ***
                    //  API function:
                    //  SetupDiEnumDeviceInterfaces()

                    //  Purpose: Retrieves a handle to a SP_DEVICE_INTERFACE_DATA
                    //  structure for a device.
                    //  On return, MyDeviceInterfaceData contains the handle to a
                    //  SP_DEVICE_INTERFACE_DATA structure for a detected device.

                    //  Accepts:
                    //  A DeviceInfoSet returned by SetupDiGetClassDevs.
                    //  An interface class GUID.
                    //  An index to specify a device in a device information set.
                    //  A pointer to a handle to a SP_DEVICE_INTERFACE_DATA structure for a device.

                    //  Returns:
                    //  Non-zero on success, zero on True.
                    //  ***

                    result = SetupDiEnumDeviceInterfaces(deviceInfoSet, 0, ref myGuid, memberIndex, ref MyDeviceInterfaceData);

                    apiFunction = "SetupDiEnumDeviceInterfaces";
                    Debug.WriteLine(MyDebugging.ResultOfAPICall(apiFunction));

                    //  Find out if a device information set was retrieved.

                    if ((result == false))
                    {
                        lastDevice = true;
                    }
                    else
                    {
                        //  A device is present.

                        Debug.WriteLine("  DeviceInfoSet for device #" + Convert.ToString(memberIndex) + ": ");
                        Debug.WriteLine("  cbSize = " + Convert.ToString(MyDeviceInterfaceData.cbSize));
                        Debug.WriteLine("  InterfaceclassGuid = " + MyDeviceInterfaceData.InterfaceClassGuid.ToString());
                        Debug.WriteLine("  Flags = " + Convert.ToString(MyDeviceInterfaceData.Flags, 16));

                        //  ***
                        //  API function:
                        //  SetupDiGetDeviceInterfaceDetail()

                        //  Purpose:
                        //  Retrieves an SP_DEVICE_INTERFACE_DETAIL_DATA structure
                        //  containing information about a device.
                        //  To retrieve the information, call this function twice.
                        //  The first time returns the size of the structure.
                        //  The second time returns a pointer to the data.

                        //  Accepts:
                        //  A DeviceInfoSet returned by SetupDiGetClassDevs
                        //  An SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces
                        //  A pointer to an SP_DEVICE_INTERFACE_DETAIL_DATA structure to receive information
                        //  about the specified interface.
                        //  The size of the SP_DEVICE_INTERFACE_DETAIL_DATA structure.
                        //  A pointer to a variable that will receive the returned required size of the
                        //  SP_DEVICE_INTERFACE_DETAIL_DATA structure.
                        //  A pointer to an SP_DEVINFO_DATA structure to receive information about the device.

                        //  Returns:
                        //  Non-zero on success, zero on failure.
                        //  ***

                        //MyDeviceInterfaceDetailData = ( ( DeviceManagement.SP_DEVICE_INTERFACE_DETAIL_DATA )( null ) );

                        success = SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref MyDeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero);

                        apiFunction = "SetupDiGetDeviceInterfaceDetail";
                        Debug.WriteLine(MyDebugging.ResultOfAPICall(apiFunction));
                        Debug.WriteLine("  (OK to say too small)");
                        Debug.WriteLine("  Required buffer size for the data: " + bufferSize);

                        //  Store the structure's size.

                        MyDeviceInterfaceDetailData.cbSize = Marshal.SizeOf(MyDeviceInterfaceDetailData);

                        //  Allocate memory for the MyDeviceInterfaceDetailData Structure using the returned buffer size.

                        IntPtr detailDataBuffer = Marshal.AllocHGlobal(bufferSize);

                        //  Store cbSize in the first 4 bytes of the array

                        if (!is64Bit)
                        {
                            Marshal.WriteInt32(detailDataBuffer, 4 + Marshal.SystemDefaultCharSize);
                        }
                        else
                        {
                            Marshal.WriteInt32(detailDataBuffer, 8);
                        }

                        Debug.WriteLine("cbsize = " + MyDeviceInterfaceDetailData.cbSize);

                        //  Call SetupDiGetDeviceInterfaceDetail again.
                        //  This time, pass a pointer to DetailDataBuffer
                        //  and the returned required buffer size.

                        success = SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref MyDeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero);

                        apiFunction = " Result of second call: ";
                        Debug.WriteLine(MyDebugging.ResultOfAPICall(apiFunction));
                        Debug.WriteLine("  MyDeviceInterfaceDetailData.cbSize: " + Convert.ToString(MyDeviceInterfaceDetailData.cbSize));

                        //  Skip over cbsize (4 bytes) to get the address of the devicePathName.

                        IntPtr pdevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4);

                        //  Get the String containing the devicePathName.

                        devicePathName[memberIndex] = Marshal.PtrToStringAuto(pdevicePathName);

                        Debug.WriteLine("Device Path = " + devicePathName[memberIndex]);
                        Debug.WriteLine("Device Path Length= " + devicePathName[memberIndex].Length);

                        //  Free the memory allocated previously by AllocHGlobal.

                        Marshal.FreeHGlobal(detailDataBuffer);
                        deviceFound = true;
                    }

                    memberIndex = memberIndex + 1;
                }while (!lastDevice == true);

                //  Trim the array to the number of devices found.

                String[] tempArray = new String[memberIndex - 1];
                System.Array.Copy(devicePathName, tempArray, Math.Min(devicePathName.Length, tempArray.Length));
                devicePathName = tempArray;

                Debug.WriteLine("Number of HIDs found = " + Convert.ToString(memberIndex - 1));

                //  ***
                //  API function:
                //  SetupDiDestroyDeviceInfoList

                //  Purpose:
                //  Frees the memory reserved for the DeviceInfoSet returned by SetupDiGetClassDevs.

                //  Accepts:
                //  A DeviceInfoSet returned by SetupDiGetClassDevs.

                //  Returns:
                //  True on success, False on failure.
                //  ***

                SetupDiDestroyDeviceInfoList(deviceInfoSet);

                apiFunction = "DestroyDeviceInfoList";
                Debug.WriteLine(MyDebugging.ResultOfAPICall(apiFunction));

                return(deviceFound);
            }
            catch (Exception ex)
            {
                DisplayException(MODULE_NAME, ex);
                return(false);
            }
        }