private static string GetUSBInterfacePath(string systemDeviceInstanceID) { if (string.IsNullOrEmpty(systemDeviceInstanceID)) throw new ArgumentNullException("systemDeviceInstanceID"); IntPtr hdi = SetupApi.SetupDiGetClassDevs(GUID_DEVINTERFACE_USBPRINT, systemDeviceInstanceID, IntPtr.Zero, SetupApi.DIGCF_PRESENT | SetupApi.DIGCF_DEVICEINTERFACE); if (hdi.Equals(INVALID_HANDLE_VALUE)) throw new Win32Exception(); try { var device_data = new SetupApi.SP_DEVINFO_DATA(); device_data.cbSize = (uint) Marshal.SizeOf(typeof (SetupApi.SP_DEVINFO_DATA)); if (SetupApi.SetupDiEnumDeviceInfo(hdi, 0, ref device_data) == 0) throw new Win32Exception(); // Only one device in the set var interface_data = new SetupApi.SP_DEVICE_INTERFACE_DATA(); interface_data.cbSize = (uint) Marshal.SizeOf(typeof (SetupApi.SP_DEVICE_INTERFACE_DATA)); if ( SetupApi.SetupDiEnumDeviceInterfaces(hdi, ref device_data, GUID_DEVINTERFACE_USBPRINT, 0, ref interface_data) == 0) throw new Win32Exception(); // Only one interface in the set // Get required buffer size uint required_size = 0; SetupApi.SetupDiGetDeviceInterfaceDetail(hdi, ref interface_data, IntPtr.Zero, 0, out required_size, IntPtr.Zero); int last_error_code = Marshal.GetLastWin32Error(); if (last_error_code != SetupApi.ERROR_INSUFFICIENT_BUFFER) throw new Win32Exception(last_error_code); IntPtr interface_detail_data = Marshal.AllocCoTaskMem((int) required_size); try { switch (IntPtr.Size) { case 4: Marshal.WriteInt32(interface_detail_data, 4 + Marshal.SystemDefaultCharSize); break; case 8: Marshal.WriteInt32(interface_detail_data, 8); break; default: throw new NotSupportedException("Architecture not supported."); } if ( SetupApi.SetupDiGetDeviceInterfaceDetail(hdi, ref interface_data, interface_detail_data, required_size, out required_size, IntPtr.Zero) == 0) throw new Win32Exception(); return Marshal.PtrToStringAuto( new IntPtr(interface_detail_data.ToInt64() + Marshal.OffsetOf(typeof (SetupApi.SP_DEVICE_INTERFACE_DETAIL_DATA), "DevicePath") .ToInt64())); } finally { Marshal.FreeCoTaskMem(interface_detail_data); } } finally { SetupApi.SetupDiDestroyDeviceInfoList(hdi); } }
private static string GetPrinterParentDeviceId(string RegistryInstanceID) { if (string.IsNullOrEmpty(RegistryInstanceID)) throw new ArgumentNullException("RegistryInstanceID"); IntPtr hdi = SetupApi.SetupDiGetClassDevs(GUID_PRINTER_INSTALL_CLASS, RegistryInstanceID, IntPtr.Zero, SetupApi.DIGCF_PRESENT); if (hdi.Equals(INVALID_HANDLE_VALUE)) throw new Win32Exception(); try { var printer_data = new SetupApi.SP_DEVINFO_DATA(); printer_data.cbSize = (uint) Marshal.SizeOf(typeof (SetupApi.SP_DEVINFO_DATA)); if (SetupApi.SetupDiEnumDeviceInfo(hdi, 0, ref printer_data) == 0) throw new Win32Exception(); // Only one device in the set uint cmret = 0; uint parent_devinst = 0; cmret = Cfgmgr32.CM_Get_Parent(out parent_devinst, printer_data.DevInst, 0); if (cmret != SetupApi.CR_SUCCESS) throw new Exception(string.Format("Failed to get parent of the device '{0}'. Error code: 0x{1:X8}", RegistryInstanceID, cmret)); uint parent_device_id_size = 0; cmret = Cfgmgr32.CM_Get_Device_ID_Size(out parent_device_id_size, parent_devinst, 0); if (cmret != SetupApi.CR_SUCCESS) throw new Exception( string.Format( "Failed to get size of the device ID of the parent of the device '{0}'. Error code: 0x{1:X8}", RegistryInstanceID, cmret)); parent_device_id_size++; // To include the null character var parent_device_id = new string('\0', (int) parent_device_id_size); cmret = Cfgmgr32.CM_Get_Device_ID(parent_devinst, parent_device_id, parent_device_id_size, 0); if (cmret != SetupApi.CR_SUCCESS) throw new Exception( string.Format( "Failed to get device ID of the parent of the device '{0}'. Error code: 0x{1:X8}", RegistryInstanceID, cmret)); return parent_device_id; } catch (Exception e) { Global.Logger.Fatal(e.Message); return ""; } finally { SetupApi.SetupDiDestroyDeviceInfoList(hdi); } }