/*
		internal bool DeviceNameMatch(Message m, string mydevicePathName)
		{
			
			// Purpose    : Compares two device path names. Used to find out if the device name
			//            : of a recently attached or removed device matches the name of a
			//            : device the application is communicating with.
			
			// Accepts    : m - a WM_DEVICECHANGE message. A call to RegisterDeviceNotification
			//            : causes WM_DEVICECHANGE messages to be passed to an OnDeviceChange routine.
			//            : mydevicePathName - a device pathname returned by SetupDiGetDeviceInterfaceDetail
			//            : in an SP_DEVICE_INTERFACE_DETAIL_DATA structure.
			
			// Returns    : True if the names match, False if not.
			
			try {
				DeviceManagementApiDeclarations.DEV_BROADCAST_DEVICEINTERFACE_1 DevBroadcastDeviceInterface = new DeviceManagementApiDeclarations.DEV_BROADCAST_DEVICEINTERFACE_1();
				DeviceManagementApiDeclarations.DEV_BROADCAST_HDR DevBroadcastHeader = new DeviceManagementApiDeclarations.DEV_BROADCAST_HDR();
				
				// The LParam parameter of Message is a pointer to a DEV_BROADCAST_HDR structure.
				Marshal.PtrToStructure(m.LParam, DevBroadcastHeader);
				
				if (DevBroadcastHeader.dbch_devicetype == DeviceManagementApiDeclarations.DBT_DEVTYP_DEVICEINTERFACE) {
					
					// The dbch_devicetype parameter indicates that the event applies to a device interface.
					// So the structure in LParam is actually a DEV_BROADCAST_INTERFACE structure,
					// which begins with a DEV_BROADCAST_HDR.
					
					// Obtain the number of characters in dbch_name by subtracting the 28 bytes
					// in the other members of the structure and dividing by 2 because there are
					// 2 bytes per character.
					int StringSize = System.Convert.ToInt32((DevBroadcastHeader.dbch_size - 28) / 2);
					
					// The dbcc_name parameter of DevBroadcastDeviceInterface contains the device name.
					// Trim dbcc_name to match the size of the string.
					DevBroadcastDeviceInterface.dbcc_name = new char[StringSize + 1];
					
					// Marshal data from the unmanaged block pointed to by m.LParam
					// to the managed object DevBroadcastDeviceInterface.
					Marshal.PtrToStructure(m.LParam, DevBroadcastDeviceInterface);
					
					// Store the device name in a String.
					string DeviceNameString = new string(DevBroadcastDeviceInterface.dbcc_name, 0, StringSize);
					
					Debug.WriteLine("Device Name = " + DeviceNameString);
					Debug.WriteLine("");
					
					// Compare the name of the newly attached device with the name of the device
					// the application is accessing (mydevicePathName).
					// Set ignorecase True.
					if (string.Compare(DeviceNameString, mydevicePathName, true) == 0) {
						// The name matches.
						return true;
					}
				}
				
			} catch (Exception ex) {
				HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
			}

      // It's a different device.
      return false;
		}
		*/

    /// <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>
    internal static bool FindDeviceFromGuid(Guid myGuid, ref string[] devicePathName)
    {
      // int DetailData;
      bool DeviceFound = false;
      bool LastDevice = false;
      int BufferSize = 0;
      // DeviceManagementApiDeclarations.SP_DEVINFO_DATA MyDeviceInfoData;
      DeviceManagementApiDeclarations.SP_DEVICE_INTERFACE_DETAIL_DATA MyDeviceInterfaceDetailData =
        new DeviceManagementApiDeclarations.SP_DEVICE_INTERFACE_DETAIL_DATA();
      DeviceManagementApiDeclarations.SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData =
        new DeviceManagementApiDeclarations.SP_DEVICE_INTERFACE_DATA();

      try
      {
        // ***
        // 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.
        // ***
        IntPtr DeviceInfoSet = DeviceManagementApiDeclarations.SetupDiGetClassDevs(
          ref myGuid,
          null,
          0,
          DeviceManagementApiDeclarations.DIGCF_PRESENT | DeviceManagementApiDeclarations.DIGCF_DEVICEINTERFACE);

        Debug.WriteLine(Debugging.ResultOfAPICall("SetupDiClassDevs"));

        DeviceFound = false;
        int MemberIndex = 0;

        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.
          MyDeviceInterfaceData.cbSize = 28;
          //Marshal.SizeOf(MyDeviceInterfaceData);

          // ***
          // 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.
          // ***

          int Result = DeviceManagementApiDeclarations.SetupDiEnumDeviceInterfaces(
            DeviceInfoSet,
            0,
            ref myGuid,
            MemberIndex,
            ref MyDeviceInterfaceData);

          Debug.WriteLine(Debugging.ResultOfAPICall("SetupDiEnumDeviceInterfaces"));

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

          if (Result == 0)
          {
            LastDevice = true;
          }
          else
          {
            // A device is present.
            Debug.WriteLine("  DeviceInfoSet for device #" + MemberIndex + ": ");
            Debug.WriteLine("  cbSize = " + MyDeviceInterfaceData.cbSize);
            Debug.WriteLine("  InterfaceclassGuid = " + MyDeviceInterfaceData.InterfaceClassGuid);
            Debug.WriteLine("  Flags = " + MyDeviceInterfaceData.Flags.ToString("x"));

            // ***
            // 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.
            // ***


            DeviceManagementApiDeclarations.SetupDiGetDeviceInterfaceDetail(
              DeviceInfoSet,
              ref MyDeviceInterfaceData,
              IntPtr.Zero, 0, ref BufferSize, IntPtr.Zero);

            Debug.WriteLine(Debugging.ResultOfAPICall("SetupDiGetDeviceInterfaceDetail"));
            Debug.WriteLine("  (OK to say too small)");
            Debug.WriteLine("  Required buffer size for the data: " + BufferSize);

            // Store the structure's size.
            //MyDeviceInterfaceDetailData.cbSize = MyDeviceInterfaceDetailData.ToString().Length;
            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
            Marshal.WriteInt32(DetailDataBuffer, 4 + Marshal.SystemDefaultCharSize);
            Debug.WriteLine("cbsize = " + MyDeviceInterfaceDetailData.cbSize);

            // Call SetupDiGetDeviceInterfaceDetail again.
            // This time, pass a pointer to DetailDataBuffer
            // and the returned required buffer size.
            DeviceManagementApiDeclarations.SetupDiGetDeviceInterfaceDetail(
              DeviceInfoSet,
              ref MyDeviceInterfaceData,
              DetailDataBuffer,
              BufferSize,
              ref BufferSize,
              IntPtr.Zero);

            Debug.WriteLine(Debugging.ResultOfAPICall(" Result of second call: "));
            Debug.WriteLine("  MyDeviceInterfaceDetailData.cbSize: " + 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.
            string SingledevicePathName = Marshal.PtrToStringAuto(pdevicePathName);
            devicePathName[MemberIndex] = SingledevicePathName;

            Debug.WriteLine("Device Path = " + devicePathName[MemberIndex]);
            //Debug.WriteLine("Device Path Length= " + Marshal.SizeOf(devicePathName[MemberIndex]));
            Debug.WriteLine("Device Path Length = " + devicePathName[MemberIndex].Length);

            // Free the memory allocated previously by AllocHGlobal.
            Marshal.FreeHGlobal(DetailDataBuffer);
            DeviceFound = true;
          }
          MemberIndex++;
        } while (!LastDevice);

        // Trim the array to the number of devices found.
        Debug.WriteLine("Number of HIDs found = " + (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.
        // ***

        DeviceManagementApiDeclarations.SetupDiDestroyDeviceInfoList(DeviceInfoSet);

        Debug.WriteLine(Debugging.ResultOfAPICall("DestroyDeviceInfoList"));
      }
      catch (Exception ex)
      {
        HandleException(ModuleName + ":" + MethodBase.GetCurrentMethod(), ex);
      }

      return DeviceFound;
    }
Beispiel #2
0
        /*
         *          internal bool DeviceNameMatch(Message m, string mydevicePathName)
         *          {
         *
         *                  // Purpose    : Compares two device path names. Used to find out if the device name
         *                  //            : of a recently attached or removed device matches the name of a
         *                  //            : device the application is communicating with.
         *
         *                  // Accepts    : m - a WM_DEVICECHANGE message. A call to RegisterDeviceNotification
         *                  //            : causes WM_DEVICECHANGE messages to be passed to an OnDeviceChange routine.
         *                  //            : mydevicePathName - a device pathname returned by SetupDiGetDeviceInterfaceDetail
         *                  //            : in an SP_DEVICE_INTERFACE_DETAIL_DATA structure.
         *
         *                  // Returns    : True if the names match, False if not.
         *
         *                  try {
         *                          DeviceManagementApiDeclarations.DEV_BROADCAST_DEVICEINTERFACE_1 DevBroadcastDeviceInterface = new DeviceManagementApiDeclarations.DEV_BROADCAST_DEVICEINTERFACE_1();
         *                          DeviceManagementApiDeclarations.DEV_BROADCAST_HDR DevBroadcastHeader = new DeviceManagementApiDeclarations.DEV_BROADCAST_HDR();
         *
         *                          // The LParam parameter of Message is a pointer to a DEV_BROADCAST_HDR structure.
         *                          Marshal.PtrToStructure(m.LParam, DevBroadcastHeader);
         *
         *                          if (DevBroadcastHeader.dbch_devicetype == DeviceManagementApiDeclarations.DBT_DEVTYP_DEVICEINTERFACE) {
         *
         *                                  // The dbch_devicetype parameter indicates that the event applies to a device interface.
         *                                  // So the structure in LParam is actually a DEV_BROADCAST_INTERFACE structure,
         *                                  // which begins with a DEV_BROADCAST_HDR.
         *
         *                                  // Obtain the number of characters in dbch_name by subtracting the 28 bytes
         *                                  // in the other members of the structure and dividing by 2 because there are
         *                                  // 2 bytes per character.
         *                                  int StringSize = System.Convert.ToInt32((DevBroadcastHeader.dbch_size - 28) / 2);
         *
         *                                  // The dbcc_name parameter of DevBroadcastDeviceInterface contains the device name.
         *                                  // Trim dbcc_name to match the size of the string.
         *                                  DevBroadcastDeviceInterface.dbcc_name = new char[StringSize + 1];
         *
         *                                  // Marshal data from the unmanaged block pointed to by m.LParam
         *                                  // to the managed object DevBroadcastDeviceInterface.
         *                                  Marshal.PtrToStructure(m.LParam, DevBroadcastDeviceInterface);
         *
         *                                  // Store the device name in a String.
         *                                  string DeviceNameString = new string(DevBroadcastDeviceInterface.dbcc_name, 0, StringSize);
         *
         *                                  Debug.WriteLine("Device Name = " + DeviceNameString);
         *                                  Debug.WriteLine("");
         *
         *                                  // Compare the name of the newly attached device with the name of the device
         *                                  // the application is accessing (mydevicePathName).
         *                                  // Set ignorecase True.
         *                                  if (string.Compare(DeviceNameString, mydevicePathName, true) == 0) {
         *                                          // The name matches.
         *                                          return true;
         *                                  }
         *                          }
         *
         *                  } catch (Exception ex) {
         *                          HandleException(ModuleName + ":" + System.Reflection.MethodBase.GetCurrentMethod(), ex);
         *                  }
         *
         * // It's a different device.
         * return false;
         *          }
         */

        /// <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>
        internal static bool FindDeviceFromGuid(Guid myGuid, ref string[] devicePathName)
        {
            // int DetailData;
            bool DeviceFound = false;
            bool LastDevice  = false;
            int  BufferSize  = 0;

            // DeviceManagementApiDeclarations.SP_DEVINFO_DATA MyDeviceInfoData;
            DeviceManagementApiDeclarations.SP_DEVICE_INTERFACE_DETAIL_DATA MyDeviceInterfaceDetailData =
                new DeviceManagementApiDeclarations.SP_DEVICE_INTERFACE_DETAIL_DATA();
            DeviceManagementApiDeclarations.SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData =
                new DeviceManagementApiDeclarations.SP_DEVICE_INTERFACE_DATA();

            try
            {
                // ***
                // 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.
                // ***
                IntPtr DeviceInfoSet = DeviceManagementApiDeclarations.SetupDiGetClassDevs(
                    ref myGuid,
                    null,
                    0,
                    DeviceManagementApiDeclarations.DIGCF_PRESENT | DeviceManagementApiDeclarations.DIGCF_DEVICEINTERFACE);

                Debug.WriteLine(Debugging.ResultOfAPICall("SetupDiClassDevs"));

                DeviceFound = false;
                int MemberIndex = 0;

                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.
                    MyDeviceInterfaceData.cbSize = 28;
                    //Marshal.SizeOf(MyDeviceInterfaceData);

                    // ***
                    // 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.
                    // ***

                    int Result = DeviceManagementApiDeclarations.SetupDiEnumDeviceInterfaces(
                        DeviceInfoSet,
                        0,
                        ref myGuid,
                        MemberIndex,
                        ref MyDeviceInterfaceData);

                    Debug.WriteLine(Debugging.ResultOfAPICall("SetupDiEnumDeviceInterfaces"));

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

                    if (Result == 0)
                    {
                        LastDevice = true;
                    }
                    else
                    {
                        // A device is present.
                        Debug.WriteLine("  DeviceInfoSet for device #" + MemberIndex + ": ");
                        Debug.WriteLine("  cbSize = " + MyDeviceInterfaceData.cbSize);
                        Debug.WriteLine("  InterfaceclassGuid = " + MyDeviceInterfaceData.InterfaceClassGuid);
                        Debug.WriteLine("  Flags = " + MyDeviceInterfaceData.Flags.ToString("x"));

                        // ***
                        // 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.
                        // ***


                        DeviceManagementApiDeclarations.SetupDiGetDeviceInterfaceDetail(
                            DeviceInfoSet,
                            ref MyDeviceInterfaceData,
                            IntPtr.Zero, 0, ref BufferSize, IntPtr.Zero);

                        Debug.WriteLine(Debugging.ResultOfAPICall("SetupDiGetDeviceInterfaceDetail"));
                        Debug.WriteLine("  (OK to say too small)");
                        Debug.WriteLine("  Required buffer size for the data: " + BufferSize);

                        // Store the structure's size.
                        //MyDeviceInterfaceDetailData.cbSize = MyDeviceInterfaceDetailData.ToString().Length;
                        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
                        Marshal.WriteInt32(DetailDataBuffer, 4 + Marshal.SystemDefaultCharSize);
                        Debug.WriteLine("cbsize = " + MyDeviceInterfaceDetailData.cbSize);

                        // Call SetupDiGetDeviceInterfaceDetail again.
                        // This time, pass a pointer to DetailDataBuffer
                        // and the returned required buffer size.
                        DeviceManagementApiDeclarations.SetupDiGetDeviceInterfaceDetail(
                            DeviceInfoSet,
                            ref MyDeviceInterfaceData,
                            DetailDataBuffer,
                            BufferSize,
                            ref BufferSize,
                            IntPtr.Zero);

                        Debug.WriteLine(Debugging.ResultOfAPICall(" Result of second call: "));
                        Debug.WriteLine("  MyDeviceInterfaceDetailData.cbSize: " + 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.
                        string SingledevicePathName = Marshal.PtrToStringAuto(pdevicePathName);
                        devicePathName[MemberIndex] = SingledevicePathName;

                        Debug.WriteLine("Device Path = " + devicePathName[MemberIndex]);
                        //Debug.WriteLine("Device Path Length= " + Marshal.SizeOf(devicePathName[MemberIndex]));
                        Debug.WriteLine("Device Path Length = " + devicePathName[MemberIndex].Length);

                        // Free the memory allocated previously by AllocHGlobal.
                        Marshal.FreeHGlobal(DetailDataBuffer);
                        DeviceFound = true;
                    }
                    MemberIndex++;
                } while (!LastDevice);

                // Trim the array to the number of devices found.
                Debug.WriteLine("Number of HIDs found = " + (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.
                // ***

                DeviceManagementApiDeclarations.SetupDiDestroyDeviceInfoList(DeviceInfoSet);

                Debug.WriteLine(Debugging.ResultOfAPICall("DestroyDeviceInfoList"));
            }
            catch (Exception ex)
            {
                HandleException(ModuleName + ":" + MethodBase.GetCurrentMethod(), ex);
            }

            return(DeviceFound);
        }