private static extern Boolean SetupDiEnumDeviceInterfaces( IntPtr hDevInfo, ref SP_DEVINFO_DATA devInfo, ref Guid interfaceClassGuid, UInt32 memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData );
private static extern Boolean SetupDiEnumDeviceInterfaces( IntPtr hDevInfo, [MarshalAs(UnmanagedType.AsAny)] Object devInfo, ref Guid interfaceClassGuid, UInt32 memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData );
internal static extern Boolean SetupDiEnumDeviceInterfaces( IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData );
static extern Boolean SetupDiGetDeviceInterfaceDetail( IntPtr hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, IntPtr deviceInterfaceDetailData, // Allow null UInt32 deviceInterfaceDetailDataSize, out UInt32 requiredSize, IntPtr deviceInfoData // Allow null );
static extern Boolean SetupDiGetDeviceInterfaceDetail( IntPtr hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, UInt32 deviceInterfaceDetailDataSize, out UInt32 requiredSize, ref SP_DEVINFO_DATA deviceInfoData );
public static unsafe string SetupDiGetDeviceInterfaceDetail( SafeDeviceInfoSetHandle deviceInfoSet, SP_DEVICE_INTERFACE_DATA interfaceData, SP_DEVINFO_DATA* deviceInfoData) { int requiredSize; // First call to get the size to allocate SetupDiGetDeviceInterfaceDetail( deviceInfoSet, ref interfaceData, null, 0, &requiredSize, deviceInfoData); // As we passed an empty buffer we know that the function will fail, not need to check the result. var lastError = GetLastError(); if (lastError != Win32ErrorCode.ERROR_INSUFFICIENT_BUFFER) { throw new Win32Exception(lastError); } fixed (byte* pBuffer = new byte[requiredSize]) { var pDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA*)pBuffer; pDetail->cbSize = SP_DEVICE_INTERFACE_DETAIL_DATA.ReportableStructSize; // Second call to get the value var success = SetupDiGetDeviceInterfaceDetail( deviceInfoSet, ref interfaceData, pDetail, requiredSize, null, null); if (!success) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); return null; } return SP_DEVICE_INTERFACE_DETAIL_DATA.GetDevicePath(pDetail); } }
public string GetDevicePath(Guid classGuid) { IntPtr hDevInfo = IntPtr.Zero; try { hDevInfo = SetupDiGetClassDevs(ref classGuid, null, IntPtr.Zero, DiGetClassFlags.DIGCF_DEVICEINTERFACE | DiGetClassFlags.DIGCF_PRESENT); if (hDevInfo.ToInt64() <= 0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA(); dia.cbSize = (uint)Marshal.SizeOf(dia); SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA(); devInfo.cbSize = (UInt32)Marshal.SizeOf(devInfo); UInt32 i = 0; // start the enumeration if (!SetupDiEnumDeviceInterfaces(hDevInfo, null, ref classGuid, i, dia)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA(); didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // trust me :) UInt32 requiredSize = 0; if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, dia, ref didd, 256, out requiredSize, devInfo)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return didd.DevicePath; } finally { SetupDiDestroyDeviceInfoList(hDevInfo); } }
protected static bool DevicePresent(Guid g) { // Used to capture how many bytes are returned by system calls UInt32 theBytesReturned = 0; // SetupAPI32.DLL Data Structures SP_DEVINFO_DATA theDevInfoData = new SP_DEVINFO_DATA(); theDevInfoData.cbSize = Marshal.SizeOf(theDevInfoData); IntPtr theDevInfo = SetupDiGetClassDevs(ref g, IntPtr.Zero, IntPtr.Zero, (int)(DiGetClassFlags.DIGCF_PRESENT | DiGetClassFlags.DIGCF_DEVICEINTERFACE)); SP_DEVICE_INTERFACE_DATA theInterfaceData = new SP_DEVICE_INTERFACE_DATA(); theInterfaceData.cbSize = Marshal.SizeOf(theInterfaceData); // Check for the device if (!SetupDiEnumDeviceInterfaces(theDevInfo, IntPtr.Zero, ref g, 0, ref theInterfaceData) && GetLastError() == ERROR_NO_MORE_ITEMS) return false; // Get the device's file path SetupDiGetDeviceInterfaceDetail(theDevInfo, ref theInterfaceData, IntPtr.Zero, 0, ref theBytesReturned, IntPtr.Zero); return !(theBytesReturned <= 0); }
protected static extern bool SetupDiSetClassInstallParams(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, ref SP_PROPCHANGE_PARAMS ClassInstallParams, int ClassInstallParamsSize);
// https://www.pinvoke.net/default.aspx/setupapi/SetupDiGetDeviceInterfaceDetail.html private static string GetDeviceNameFromGuid(Guid guid) { string instancePath = string.Empty; // We start at the "root" of the device tree and look for all // devices that match the interface GUID of a disk IntPtr h = SetupDiGetClassDevs(ref guid, null, IntPtr.Zero, (uint)DeviceConfig.DIGCF_PRESENT | (uint)DeviceConfig.DIGCF_DEVICEINTERFACE); if (h.ToInt32() != INVALID_HANDLE_VALUE) { bool Success = true; uint i = 0; while (Success) { // create a Device Interface Data structure SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA(); dia.cbSize = Marshal.SizeOf(dia); // start the enumeration Success = SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref guid, i, ref dia); if (Success) { // build a DevInfo Data structure SP_DEVINFO_DATA da = new SP_DEVINFO_DATA(); da.cbSize = (uint)Marshal.SizeOf(da); // build a Device Interface Detail Data structure SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA(); if (IntPtr.Size == 8) // for 64 bit operating systems { didd.cbSize = 8; } else { didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // for 32 bit systems } // now we can get some more detailed information uint nRequiredSize = 0; uint nBytes = BUFFER_SIZE; if (SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, ref nRequiredSize, ref da)) { instancePath = didd.DevicePath; // current InstanceID is at the "USBSTOR" level, so we // need up "move up" one level to get to the "USB" level // uint ptrPrevious; // CM_Get_Parent(out ptrPrevious, da.DevInst, 0); // // Now we get the InstanceID of the USB level device // IntPtr ptrInstanceBuf = Marshal.AllocHGlobal((int)nBytes); // CM_Get_Device_ID(ptrPrevious, ptrInstanceBuf, (int)nBytes, 0); // string InstanceID = Marshal.PtrToStringAuto(ptrInstanceBuf); // Marshal.FreeHGlobal(ptrInstanceBuf); } } i++; } } SetupDiDestroyDeviceInfoList(h); return(instancePath); }
public bool GetHidUSBDevices() { /* * Before we can "connect" our application to our USB embedded device, we must first find the device. * A USB bus can have many devices simultaneously connected, so somehow we have to find our device only. * This is done with the Vendor ID (VID) and Product ID (PID). Each USB product line should have * a unique combination of VID and PID. * * Microsoft has created a number of functions which are useful for finding plug and play devices. Documentation * for each function used can be found in the MSDN library. We will be using the following functions (unmanaged C functions): * * SetupDiGetClassDevs() //provided by setupapi.dll, which comes with Windows * SetupDiEnumDeviceInterfaces() //provided by setupapi.dll, which comes with Windows * GetLastError() //provided by kernel32.dll, which comes with Windows * SetupDiDestroyDeviceInfoList() //provided by setupapi.dll, which comes with Windows * SetupDiGetDeviceInterfaceDetail() //provided by setupapi.dll, which comes with Windows * SetupDiGetDeviceRegistryProperty() //provided by setupapi.dll, which comes with Windows * CreateFile() //provided by kernel32.dll, which comes with Windows * * In order to call these unmanaged functions, the Marshal class is very useful. * * We will also be using the following unusual data types and structures. Documentation can also be found in * the MSDN library: * * PSP_DEVICE_INTERFACE_DATA * PSP_DEVICE_INTERFACE_DETAIL_DATA * SP_DEVINFO_DATA * HDEVINFO * HANDLE * GUID * * The ultimate objective of the following code is to get the device path, which will be used elsewhere for getting * read and write handles to the USB device. Once the read/write handles are opened, only then can this * PC application begin reading/writing to the USB device using the WriteFile() and ReadFile() functions. * * Getting the device path is a multi-step round about process, which requires calling several of the * SetupDixxx() functions provided by setupapi.dll. */ if (HidDevices.Count > 0) { foreach (Hid_Devices Hd in HidDevices) { if (!Hd.WriteHandle.IsClosed) { Hd.WriteHandle.Close(); } if (!Hd.ReadHandle.IsClosed) { Hd.ReadHandle.Close(); } } } HidDevices.Clear(); string DevicePath = ""; try { IntPtr DeviceInfoTable = IntPtr.Zero; SP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new SP_DEVICE_INTERFACE_DATA(); SP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure = new SP_DEVICE_INTERFACE_DETAIL_DATA(); SP_DEVINFO_DATA DevInfoData = new SP_DEVINFO_DATA(); uint InterfaceIndex = 0; uint dwRegType = 0; uint dwRegSize = 0; uint StructureSize = 0; IntPtr PropertyValueBuffer = IntPtr.Zero; uint ErrorStatus; uint LoopCounter = 0; //First populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the specified class GUID. DeviceInfoTable = SetupDiGetClassDevs(ref InterfaceClassGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (DeviceInfoTable != IntPtr.Zero) { //Now look through the list we just populated. We are trying to see if any of them match our device. while (true) { InterfaceDataStructure.cbSize = (uint)Marshal.SizeOf(InterfaceDataStructure); if (SetupDiEnumDeviceInterfaces(DeviceInfoTable, IntPtr.Zero, ref InterfaceClassGuid, InterfaceIndex, ref InterfaceDataStructure)) { ErrorStatus = (uint)Marshal.GetLastWin32Error(); if (ErrorStatus == ERROR_NO_MORE_ITEMS) //Did we reach the end of the list of matching devices in the DeviceInfoTable? { //Cound not find the device. Must not have been attached. SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need. return(false); } } else //Else some other kind of unknown error ocurred... { ErrorStatus = (uint)Marshal.GetLastWin32Error(); SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need. return(HidDevices.Count > 0); } //Now retrieve the hardware ID from the registry. The hardware ID contains the VID and PID, which we will then //check to see if it is the correct device or not. //Initialize an appropriate SP_DEVINFO_DATA structure. We need this structure for SetupDiGetDeviceRegistryProperty(). DevInfoData.cbSize = (uint)Marshal.SizeOf(DevInfoData); SetupDiEnumDeviceInfo(DeviceInfoTable, InterfaceIndex, ref DevInfoData); //First query for the size of the hardware ID, so we can know how big a buffer to allocate for the data. SetupDiGetDeviceRegistryProperty(DeviceInfoTable, ref DevInfoData, SPDRP_HARDWAREID, ref dwRegType, IntPtr.Zero, 0, ref dwRegSize); //Device must have been found. In order to open I/O file handle(s), we will need the actual device path first. //We can get the path by calling SetupDiGetDeviceInterfaceDetail(), however, we have to call this function twice: The first //time to get the size of the required structure/buffer to hold the detailed interface data, then a second time to actually //get the structure (after we have allocated enough memory for the structure.) DetailedInterfaceDataStructure.cbSize = (uint)Marshal.SizeOf(DetailedInterfaceDataStructure); //First call populates "StructureSize" with the correct value SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, ref InterfaceDataStructure, IntPtr.Zero, 0, ref StructureSize, IntPtr.Zero); //Need to call SetupDiGetDeviceInterfaceDetail() again, this time specifying a pointer to a SP_DEVICE_INTERFACE_DETAIL_DATA buffer with the correct size of RAM allocated. //First need to allocate the unmanaged buffer and get a pointer to it. IntPtr pUnmanagedDetailedInterfaceDataStructure = IntPtr.Zero; //Declare a pointer. pUnmanagedDetailedInterfaceDataStructure = Marshal.AllocHGlobal((int)StructureSize); //Reserve some unmanaged memory for the structure. DetailedInterfaceDataStructure.cbSize = 6; //Initialize the cbSize parameter (4 bytes for DWORD + 2 bytes for unicode null terminator) Marshal.StructureToPtr(DetailedInterfaceDataStructure, pUnmanagedDetailedInterfaceDataStructure, false); //Copy managed structure contents into the unmanaged memory buffer. //Now call SetupDiGetDeviceInterfaceDetail() a second time to receive the device path in the structure at pUnmanagedDetailedInterfaceDataStructure. if (SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, ref InterfaceDataStructure, pUnmanagedDetailedInterfaceDataStructure, StructureSize, IntPtr.Zero, IntPtr.Zero)) { //Need to extract the path information from the unmanaged "structure". The path starts at (pUnmanagedDetailedInterfaceDataStructure + sizeof(DWORD)). IntPtr pToDevicePath = new IntPtr((uint)pUnmanagedDetailedInterfaceDataStructure.ToInt32() + 4); //Add 4 to the pointer (to get the pointer to point to the path, instead of the DWORD cbSize parameter) DevicePath = Marshal.PtrToStringUni(pToDevicePath); //Now copy the path information into the globally defined DevicePath String. //We now have the proper device path, and we can finally use the path to open I/O handle(s) to the device. //SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need. Marshal.FreeHGlobal(pUnmanagedDetailedInterfaceDataStructure); //No longer need this unmanaged SP_DEVICE_INTERFACE_DETAIL_DATA buffer. We already extracted the path information. uint ErrorStatusWrite; uint ErrorStatusRead; HidDev.DevicePath = DevicePath; HidDev.WriteHandle = CreateFile(DevicePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); ErrorStatusWrite = (uint)Marshal.GetLastWin32Error(); HidDev.ReadHandle = CreateFile(DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); ErrorStatusRead = (uint)Marshal.GetLastWin32Error(); if ((ErrorStatusWrite == ERROR_SUCCESS) && (ErrorStatusRead == ERROR_SUCCESS)) { HidDev.AttachedState = true; //Let the rest of the PC application know the USB device is connected, and it is safe to read/write to it HidDev.AttachedButBroken = false; HidDev.Caps = new HIDP_CAPS(); IntPtr preparsedData = new IntPtr(); HidD_GetPreparsedData(HidDev.WriteHandle, ref preparsedData); HidP_GetCaps(preparsedData, ref HidDev.Caps); HidD_FreePreparsedData(ref preparsedData); HidD_GetAttributes(HidDev.WriteHandle, ref HidDev.Attributes); StringBuilder Builder = new StringBuilder(253); bool success = HidD_GetSerialNumberString(HidDev.WriteHandle, Builder, (uint)Builder.Capacity); if (success) { HidDev.SerialNumber = Builder.ToString(); } success = HidD_GetProductString(HidDev.WriteHandle, Builder, (uint)Builder.Capacity); if (success) { HidDev.DeviceName = Builder.ToString(); } success = HidD_GetManufacturerString(HidDev.WriteHandle, Builder, (uint)Builder.Capacity); if (success) { HidDev.DeviceManufacturer = Builder.ToString(); } } else //for some reason the device was physically plugged in, but one or both of the read/write handles didn't open successfully... { HidDev.AttachedState = false; //Let the rest of this application known not to read/write to the device. HidDev.AttachedButBroken = true; //Flag so that next time a WM_DEVICECHANGE message occurs, can retry to re-open read/write pipes if (ErrorStatusWrite == ERROR_SUCCESS) { HidDev.WriteHandle.Close(); } if (ErrorStatusRead == ERROR_SUCCESS) { HidDev.ReadHandle.Close(); } } HidDev.ReadBuffer = new byte[HidDev.Caps.InputReport]; if (HidDev.DeviceName != null) { HidDevices.Add(HidDev); } } else //Some unknown failure occurred { uint ErrorCode = (uint)Marshal.GetLastWin32Error(); SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure. Marshal.FreeHGlobal(pUnmanagedDetailedInterfaceDataStructure); //No longer need this unmanaged SP_DEVICE_INTERFACE_DETAIL_DATA buffer. We already extracted the path information. return(false); } InterfaceIndex++; //Keep looping until we either find a device with matching VID and PID, or until we run out of devices to check. //However, just in case some unexpected error occurs, keep track of the number of loops executed. //If the number of loops exceeds a very large number, exit anyway, to prevent inadvertent infinite looping. LoopCounter++; if (LoopCounter == 10000000) //Surely there aren't more than 10 million devices attached to any forseeable PC... { return(false); } }//end of while(true) } return(false); }//end of try catch { //Something went wrong if PC gets here. Maybe a Marshal.AllocHGlobal() failed due to insufficient resources or something. return(false); } }
//-------------------------------------------------------------------------- // Discovery //-------------------------------------------------------------------------- public static List<KnownNXT> FindDeviceFromGuid(Guid guidDeviceInstance) // Find all connected instances of this kind of USB device { IntPtr hDeviceInfoSet = INVALID_HANDLE_VALUE; try { hDeviceInfoSet = SetupDiGetClassDevs(ref guidDeviceInstance, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (INVALID_HANDLE_VALUE==hDeviceInfoSet) ThrowWin32Error(); SP_DEVICE_INTERFACE_DATA did = new SP_DEVICE_INTERFACE_DATA(); did.Initialize(); List<KnownNXT> result = new List<KnownNXT>(); for (int iMember=0 ;; iMember++) { // Get did of the next interface bool fSuccess = SetupDiEnumDeviceInterfaces (hDeviceInfoSet, IntPtr.Zero, ref guidDeviceInstance, iMember, out did); if (!fSuccess) { break; // Done! no more } else { // A device is present. Get details SP_DEVICE_INTERFACE_DETAIL_DATA detail = new SP_DEVICE_INTERFACE_DETAIL_DATA(); detail.Initialize(); int cbRequired; ThrowIfFail(SetupDiGetDeviceInterfaceDetail (hDeviceInfoSet, ref did, ref detail, Marshal.SizeOf(detail), out cbRequired, IntPtr.Zero)); result.Add(new KnownNXT(KnownNXT.CONNECTIONTYPE.USB, detail.DevicePath)); } } return result; } finally { if (hDeviceInfoSet != IntPtr.Zero && hDeviceInfoSet != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(hDeviceInfoSet); } } }
public static extern bool SetupDiGetDeviceInterfaceDetail( IntPtr lpDeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA oInterfaceData, IntPtr lpDeviceInterfaceDetailData, uint nDeviceInterfaceDetailDataSize, ref uint nRequiredSize, IntPtr lpDeviceInfoData );
static public extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int RequiredSize, IntPtr DeviceInfoData);
private static extern bool SetupDiEnumDeviceInterfaces( IntPtr DeviceInfoSet, IntPtr DeviceInfoData, [MarshalAs(UnmanagedType.LPStruct), In] Guid InterfaceClassGuid, uint MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
// GetDevicesPath metodu USB aygýtlarý bulup, aygýt yollarýný (device path) // bir ArrayList içine dolduracak. public static ArrayList GetDevicesPath() { IntPtr hDevInfo = IntPtr.Zero; // Aygýtlar için handle Int32 iSize = 0; // Aygýt yolu (device path) uzunluðu Int32 iDevCount = 0; // Aygýt sayýsý String sDevicePath = ""; // Aygýt yolu (device path) // ArrayList içine bulunan aygýt yollarýný (device path) dolduracaðýz. ArrayList arrList = new ArrayList(); // USB aygýtlarý arayüz GUID numarasý Guid myGuid = new Guid(GUID_DEVINTERFACE_USB_DEVICE); // Bilgisayar baðlý durumda olan USB cihazlarýn aygýt bilgisini // almak için SetupDiGetClassDevs fonksiyonunu çaðýrýyoruz. // DIGCF_DEVICEINTERFACE: Verilen GUID'e göre arayüz sýnýfýný temsil eder. // DIGCF_PRESENT: Hazýr durumdaki USB aygýtlar. hDevInfo = SetupDiGetClassDevs(ref myGuid, 0, IntPtr.Zero, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); // Fonksiyondan dönen deðer geçerli mi? if (hDevInfo == INVALID_HANDLE_VALUE) { // Aygýt listesinin alýnmasý baþarýsýzlýða uðradý. // Ayrýntýlý hata bilgisi almak için GetLastWin32Error çaðrýlýr. throw new Win32Exception(Marshal.GetLastWin32Error()); } try { // SP_DEVICE_INTERFACE_DATA yapý nesnesi tanýmlýyoruz. SP_DEVICE_INTERFACE_DATA devInterfaceData = new SP_DEVICE_INTERFACE_DATA(); // SP_DEVICE_INTERFACE_DETAIL_DATA yapý nesnesi tanýmlýyoruz. SP_DEVICE_INTERFACE_DETAIL_DATA devInterfaceDetailData = new SP_DEVICE_INTERFACE_DETAIL_DATA(); // USB aygýtlarý while tekrarlý yapýsýyla arýyoruz. // SetupDiEnumDeviceInterfaces fonksiyonuyla aygýt arayüzünü // bulma þartý kontrol edilir. // // hDevInfo: SetupDiGetClassDevs fonksiyonundan gelen handle. // SP_DEVINFO_DATA yapýsý opsiyonel olduðu için sýfýr deðerine eþitlenmiþ. while (SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref myGuid, iDevCount, devInterfaceData)) { // Aygýt arayüzü hakkýndaki detaylarý alabilmek için iki aþamalý // bir yol izlenebilir. // #1. Adým: // SetupDiGetDeviceInterfaceDetail fonksiyonu, // SP_DEVICE_INTERFACE_DETAIL_DATA yapýsýna sýfýr veya null deðeri // verilerek çaðrýlýr. Gerekli tampon uzunluðu için sýfýr girilir. // RequiredSize parametresinden gerekli olan uzunluk elde edilir. // #2. Adým: // Bellekte tampon için yeterli miktarda yer ayýr. // Daha sonra SetupDiGetDeviceInterfaceDetail fonksiyonunu // tekrar çaðýr ve arayüz detayýný al. if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, devInterfaceData, IntPtr.Zero, 0, ref iSize, IntPtr.Zero)) { // Tampon için bellekte dönen uzunluk deðeri kadar yer ayýr. IntPtr buffer = Marshal.AllocHGlobal(iSize); // StructureToPtr ile yapýdaki deðerleri tampona kopyala. // Burada yönetimli kod kýsmýndan, yönetilmeyen hafýza // bloðuna veriler marshall ediliyor. Marshal.StructureToPtr(devInterfaceDetailData, buffer, false); try { // SetupDiGetDeviceInterfaceDetail fonksiyonunu tekrar çaðýr. // Tamponun gerçek uzunluðunu iSize parametresiyle geçir. if (SetupDiGetDeviceInterfaceDetail(hDevInfo, devInterfaceData, buffer, iSize, ref iSize, IntPtr.Zero)) { // Tampon içindeki aygýtýn yol bilgisini (device path) alabilmek için // tamponun adresini 4 byte ötele ve daha sonra // pDevicePath göstericisine aktar. // // Burada göstericinin adres bileþeni 4 arttýrýlýyor. IntPtr pDevicePath = (IntPtr)((Int32)buffer + Marshal.SizeOf(typeof(Int32))); // Yönetilmeyen bellekte bulunan bir string içeriði // yönetilen bir string içine kopyalanýyor. sDevicePath = Marshal.PtrToStringAuto(pDevicePath); // Bulunan aygýt yolu ArrayList deðiþkenine ekleniyor. arrList.Add(sDevicePath); } else { throw new Win32Exception(Marshal.GetLastWin32Error()); }//end if } finally { // AllocHGlobal ile bellekte ayrýlan yeri serbest býrak. Marshal.FreeHGlobal(buffer); } // Bir sonraki aygýta bakmak için sayacý arttýr. iDevCount++; } else { throw new Win32Exception(Marshal.GetLastWin32Error()); } //end if } //end while } finally { // Bellekteki aygýt bilgi setini serbest býrak. SetupDiDestroyDeviceInfoList(hDevInfo); } return(arrList); }
static public extern int SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, int DeviceInfoData, ref System.Guid InterfaceClassGuid, int MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
protected override void WndProc(ref System.Windows.Forms.Message m) { try { if (m.Msg == WM_DEVICECHANGE) { Thread.Sleep(500); DEV_BROADCAST_HDR pHdr = new DEV_BROADCAST_HDR(); pHdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR)); switch ((int)m.WParam) { case UsbNotification.DbtDeviceremovecomplete: Console.WriteLine("Usb_DeviceRemoved"); break; case UsbNotification.DbtDevicearrival: Console.WriteLine(" Usb_DeviceAdded"); // this is where you do your magic //Console.WriteLine("Hello: {0}", pHdr.dbch_DeviceType); if (pHdr.dbch_DeviceType == 5) { //Console.WriteLine("Human Interface Device"); DEV_BROADCAST_DEVICEINTERFACE pDevInf = (DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_DEVICEINTERFACE)); string name = GetDeviceName(pDevInf); //Console.WriteLine("Name: {0}", name); //GetDeviceNameNew(pDevInf); //Console.WriteLine("Size: {0}\nDevice Type: {1}\nreserved: {2}", pDevInf.dbcc_size, pDevInf.dbcc_devicetype, pDevInf.dbcc_reserved); //Console.WriteLine("Details: {0}", pDevInf.dbcc_name); //Console.WriteLine("Class GUID: {0}", pDevInf.dbcc_classguid); string pid = ""; string vid = ""; getDetails(pDevInf.dbcc_name.ToString(), ref pid, ref vid); Guid DiskGUID = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); IntPtr h = SetupDiGetClassDevs(ref DiskGUID, new IntPtr(0), IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); //Console.WriteLine("Class GUID: {0}", DiskGUID); if (h != (IntPtr)INVALID_HANDLE_VALUE) { bool Success = true; uint i = 0; while (Success) { // create a Device Interface Data structure SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA(); dia.cbSize = Marshal.SizeOf(dia); // start the enumeration Success = SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref DiskGUID, i, ref dia); if (Success) { // build a DevInfo Data structure //Console.WriteLine("DiskGUID Agian: " + DiskGUID.ToString()); SP_DEVINFO_DATA da = new SP_DEVINFO_DATA(); da.cbSize = 28; // this becomes 32 for 64 bit systems; // build a Device Interface Detail Data structure SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA(); didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // trust me :) int nRequiredSize = 0; int nBytes = 256; //Buffer Size = 256 uint n_required_size = (uint)(int)nRequiredSize; uint nbytes = (uint)(int)nBytes; if (SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nbytes, out n_required_size, ref da)) { // Now we get the InstanceID of the USB level device IntPtr ptrInstanceBuf = Marshal.AllocHGlobal(nBytes); CM_Get_Device_ID(da.devInst, ptrInstanceBuf, nBytes, 0); string InstanceID = Marshal.PtrToStringAuto(ptrInstanceBuf); //Console.WriteLine("Instance ID: " + da.devInst); //Console.WriteLine("PID: {0}\nVID: {1}", pid, vid); string pid_temp = "", vid_temp = ""; int storageFlag = 0; getDetails(InstanceID.ToString(), ref pid_temp, ref vid_temp); if (pid == pid_temp && vid == vid_temp) { additionalFunctions sa = new additionalFunctions(); tree.node root = new tree.node(da.devInst); //sa.buildTree(root); //Console.WriteLine("Device Added: {0} \nGetting Details................{1}....{2}....", InstanceID, pid, vid); var test = da.devInst; Thread th = new Thread(() => { string serialNo = sd.getSerial(InstanceID); //Console.WriteLine("Serial Number: {0}", serialNo); sd.search(pid, vid, ref storageFlag, serialNo, test); //Search details of the Given PID VID From WMI }); th.Start(); th.Join(); Marshal.FreeHGlobal(ptrInstanceBuf); SetupDiDestroyDeviceInfoList(h); break; /* * if (storageFlag == 1) * { * Console.WriteLine("TRYING TO EJECT!!-------------------" + da.devInst); * additionalFunctions.checkEject(da.devInst); //Ejects the USB by calling the CM_Request_Device_Eject function * Console.WriteLine("------------------------------------"); * } */ /*const int BUFFER_SIZE = 256; * UInt32 RequiredSize; * UInt32 RegType = 0; * byte[] ptrBuffer = new byte[BUFFER_SIZE]; * IntPtr test = new IntPtr(BUFFER_SIZE); * tree.node root1 = new tree.node(da.devInst); * //additionalFunctions.buildTree(root1); * * if (SetupDiGetDeviceRegistryProperty(h, ref da,(uint) SetupDiGetDeviceRegistryPropertyEnum.SPDRP_DEVICEDESC, out RegType, ptrBuffer, BUFFER_SIZE, out RequiredSize)) * { * //string ControllerDeviceDesc = Marshal.PtrToStringAuto(ptrBuf); * //Console.WriteLine("Controller Device Name: {0}", ControllerDeviceDesc); * SetupDiGetDeviceRegistryProperty(h, ref da, (uint)SetupDiGetDeviceRegistryPropertyEnum.SPDRP_DEVICEDESC, out RegType, ptrBuffer, BUFFER_SIZE, out RequiredSize); * byte[] data = ptrBuffer; * IntPtr ptr = Marshal.AllocHGlobal(data.Length); * try * { * * //Console.WriteLine("Sibling Status: " + CM_Get_Child(out parentDevInt, da.devInst, 0)); * UInt32 current = da.devInst; * Microsoft.Win32.RegistryValueKind kind; * uint length = 0; * * * Program.CM_Get_DevNode_Registry_Property(da.devInst, 0x0000001A, out kind, IntPtr.Zero, ref length, 0); * IntPtr buffer = Marshal.AllocHGlobal((int)length); * Program.CM_Get_DevNode_Registry_Property(da.devInst, 0x0000001A, out kind, buffer, ref length, 0); * byte[] test1 = new byte[BUFFER_SIZE]; * * Marshal.Copy(buffer,test1, 0, (int)length); * * //Console.WriteLine("dadas" + test1 + "DASdasd" + buffer); * //Console.WriteLine("\t\tDevice PATH: " + "\t" + System.Text.Encoding.UTF8.GetString(test1).ToString()); * * * //Console.WriteLine("The New Function------------------\t" + da.devInst); * * //tree.node root = new tree.node(da.devInst); * //additionalFunctions.buildTree(root); * * String ControllerDesc = System.Text.Encoding.UTF8.GetString(ptrBuffer); * //Console.WriteLine("Details: {0}", ControllerDesc); * //Console.WriteLine("Sec Details: {0}", ptrBuffer); * * * * * } * finally * { * Marshal.FreeHGlobal(ptr); * } * * //Console.WriteLine("Controller: " + RequiredSize); * } * else * { * if (GetLastError() == 13) * { * Console.WriteLine("The Property doesnot exist for the device"); * } * else * { * Console.WriteLine("SetupDiGetDeviceRegistryProperty Error: " + GetLastError().ToString()); * } * }*/ //Console.WriteLine("Pid: {0}\nVid:{1}", pid, vid); } Marshal.FreeHGlobal(ptrInstanceBuf); } } i++; } } SetupDiDestroyDeviceInfoList(h); } break; } } base.WndProc(ref m); } catch { } }
public static DeviceDetails[] FindDevicesFromGuid(Guid guid) { IntPtr deviceInfoSet = IntPtr.Zero; List <DeviceDetails> deviceList = new List <DeviceDetails>(); try { deviceInfoSet = SetupDiGetClassDevs(ref guid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (deviceInfoSet == FileIO.INVALID_HANDLE_VALUE) { throw APIException.Win32("Failed to enumerate devices."); } int memberIndex = 0; while (true) { // Begin with 0 and increment through the device information set until // no more devices are available. SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); // The cbSize element of the deviceInterfaceData structure must be set to // the structure's size in bytes. // The size is 28 bytes for 32-bit code and 32 bytes for 64-bit code. deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData); bool success; success = SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref guid, memberIndex, ref deviceInterfaceData); // Find out if a device information set was retrieved. if (!success) { int lastError = Marshal.GetLastWin32Error(); if (lastError == ERROR_NO_MORE_ITEMS) { break; } throw APIException.Win32("Failed to get device interface."); } // A device is present. int bufferSize = 0; success = SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref deviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero); if (!success) { if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) { throw APIException.Win32("Failed to get interface details buffer size."); } } IntPtr detailDataBuffer = IntPtr.Zero; try { // Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size. detailDataBuffer = Marshal.AllocHGlobal(bufferSize); // Store cbSize in the first bytes of the array. The number of bytes varies with 32- and 64-bit systems. Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); // Call SetupDiGetDeviceInterfaceDetail again. // This time, pass a pointer to DetailDataBuffer // and the returned required buffer size. // build a DevInfo Data structure SP_DEVINFO_DATA da = new SP_DEVINFO_DATA(); da.cbSize = Marshal.SizeOf(da); success = SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref deviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, ref da); if (!success) { throw APIException.Win32("Failed to get device interface details."); } // Skip over cbsize (4 bytes) to get the address of the devicePathName. IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4); string pathName = Marshal.PtrToStringUni(pDevicePathName); // Get the String containing the devicePathName. DeviceDetails details = GetDeviceDetails(pathName, deviceInfoSet, da); deviceList.Add(details); } finally { if (detailDataBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(detailDataBuffer); detailDataBuffer = IntPtr.Zero; } } memberIndex++; } } finally { if (deviceInfoSet != IntPtr.Zero && deviceInfoSet != FileIO.INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(deviceInfoSet); } } return(deviceList.ToArray()); }
internal static extern bool SetupDiEnumDeviceInterfaces(IntPtr hDevInfo, IntPtr devInfo, ref Guid interfaceClassGuid, uint memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
public static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr hDeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, out int cbRequired, IntPtr DeviceInfoData);
static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, UInt32 deviceInterfaceDetailDataSize, ref UInt32 requiredSize, ref SP_DEVINFO_DATA deviceInfoData);
/// <summary> /// Use SetupDi API functions to retrieve the device path name of an attached device that belongs to a device interface class. /// </summary> /// /// <param name="deviceGuid"> an interface class GUID. </param> /// <param name="devicePathNames"> a pointer to an array of device path names of attached deviced. </param> /// /// <returns> /// True if a devices are found, False if not. /// </returns> internal Boolean FindDevice(Guid deviceGuid, ref String[] devicePathNames) { IntPtr deviceInfoSet = IntPtr.Zero; Int32 memberIndex = 0; SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); Int32 bufferSize = 0; IntPtr detailDataBuffer = IntPtr.Zero; IntPtr pDevicePathName = IntPtr.Zero; Boolean devicesFound = false, moreDevices, success; try { // SetupDiGetClassDevs returns a pointer to an array of structures containing informations about all devices // in the device interface class specified by the Guid. deviceInfoSet = SetupDiGetClassDevs(ref deviceGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // Save the size of the structure. MyDeviceInterfaceData.cbSize = Marshal.SizeOf(MyDeviceInterfaceData); do { // SetupDiEnumDeviceInterfaces takes the previous return SP_DEVINFO_DATA and looks up their members. // We receive a SP_DEVICE_INTERFACE_DATA here. moreDevices = SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref deviceGuid, memberIndex, ref MyDeviceInterfaceData); if (moreDevices) { // SetupDiGetDeviceInterfaceDetail returns a structure with the device path name and its size as a SP_DEVICE_INTERFACE_DETAIL_DATA. // Calling this function we don't know the size of the structure and the function won't return the structure unless we call it with the correct size. // That's why we need to call the function twice. // The first call won't return the struture but an error. Still we can retrieve the size of the structure. success = SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref MyDeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero); // Allocate the memory for SP_DEVICE_INTERFACE_DETAIL_DATA of the size of bufferSize. detailDataBuffer = Marshal.AllocHGlobal(bufferSize); // Copy the bufferSize into the start of the structure, size depends on 32 or 64-Bit OS. Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); // The second call is now correct and a pointer to the structure is returned within detailDataBuffer. success = SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref MyDeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero); // The first four bytes are the buffersize. pDevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4); // Now make space for the next device and get the string with the device path. Array.Resize(ref devicePathNames, devicePathNames.Length + 1); devicePathNames[devicePathNames.Length - 1] = Marshal.PtrToStringAuto(pDevicePathName); devicesFound = true; } memberIndex++; } while (moreDevices == true); return devicesFound; } catch (Exception) { throw; } finally { if (detailDataBuffer != IntPtr.Zero) Marshal.FreeHGlobal(detailDataBuffer); if (deviceInfoSet != IntPtr.Zero) SetupDiDestroyDeviceInfoList(deviceInfoSet); } }
public static extern bool SetupDiEnumDeviceInterfaces(IntPtr deviceInfoList, SP_DEVICE_INFO_DATA deviceInfoData, Guid interfaceClassGuid, int memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
public static extern bool SetupDiEnumDeviceInterfaces( IntPtr hDevInfo, //Infoset de dispositivos uint devInfo,//ref SP_DEVINFO_DATA devInfo, ref Guid interfaceClassGuid, //GUID obtenido con HidD_GetHidGuid uint memberIndex, //Index que apunta a la lista 0-n ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData //Variable declarada anteriormente );
/// <summary> /// Use SetupDi API functions to retrieve the device path name of an /// attached device that belongs to a device interface class. /// </summary> /// /// <param name="myGuid"> an interface class GUID. </param> /// <param name="devicePathName"> a pointer to the device path name /// of an attached device. </param> /// /// <returns> /// True if a device is found, False if not. /// </returns> internal Boolean FindDeviceFromGuid(System.Guid myGuid, ref String[] devicePathName) { Int32 bufferSize = 0; IntPtr detailDataBuffer = IntPtr.Zero; Boolean deviceFound; IntPtr deviceInfoSet = new System.IntPtr(); Boolean lastDevice = false; Int32 memberIndex = 0; SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); Boolean success; try { // *** // API function // summary // Retrieves a device information set for a specified group of devices. // SetupDiEnumDeviceInterfaces uses the device information set. // parameters // Interface class GUID. // Null to retrieve information for all device instances. // 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 // Handle to a device information set for the devices. // *** deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); deviceFound = false; memberIndex = 0; // The cbSize element of the MyDeviceInterfaceData structure must be set to // the structure's size in bytes. // The size is 28 bytes for 32-bit code and 32 bits for 64-bit code. MyDeviceInterfaceData.cbSize = Marshal.SizeOf(MyDeviceInterfaceData); do { // Begin with 0 and increment through the device information set until // no more devices are available. // *** // API function // summary // 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. // parameters // DeviceInfoSet returned by SetupDiGetClassDevs. // Optional SP_DEVINFO_DATA structure that defines a device instance // that is a member of a device information set. // Device interface GUID. // Index to specify a device in a device information set. // Pointer to a handle to a SP_DEVICE_INTERFACE_DATA structure for a device. // Returns // True on success. // *** success = SetupDiEnumDeviceInterfaces (deviceInfoSet, IntPtr.Zero, ref myGuid, memberIndex, ref MyDeviceInterfaceData); // Find out if a device information set was retrieved. if (!success) { lastDevice = true; } else { // A device is present. // *** // API function: // summary: // 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. // parameters // DeviceInfoSet returned by SetupDiGetClassDevs // SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces // A returned 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. // Pointer to a variable that will receive the returned required size of the // SP_DEVICE_INTERFACE_DETAIL_DATA structure. // Returned pointer to an SP_DEVINFO_DATA structure to receive information about the device. // Returns // True on success. // *** success = SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref MyDeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero); // Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size. detailDataBuffer = Marshal.AllocHGlobal(bufferSize); // Store cbSize in the first bytes of the array. The number of bytes varies with 32- and 64-bit systems. Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); // 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); // 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); deviceFound = true; } memberIndex = memberIndex + 1; }while (!((lastDevice == true))); return(deviceFound); } catch (Exception ex) { throw; } finally { if (detailDataBuffer != IntPtr.Zero) { // Free the memory allocated previously by AllocHGlobal. Marshal.FreeHGlobal(detailDataBuffer); } // *** // API function // summary // Frees the memory reserved for the DeviceInfoSet returned by SetupDiGetClassDevs. // parameters // DeviceInfoSet returned by SetupDiGetClassDevs. // returns // True on success. // *** if (deviceInfoSet != IntPtr.Zero) { SetupDiDestroyDeviceInfoList(deviceInfoSet); } } }
//Metodo de ayuda para encontrar la ruta al dispositivo que se busca, esta funcion es llamada desde el metodo "EncuentraDevHID" private string GetDevicePath(IntPtr Infoset, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData) { uint nRequiredSize = 0; //Para obtener la ruta del dispositivo se hace un proceso de dos pasos, llamar a SetupDiGetDeviceInterfaceDetail la primer vez para obtener el espacio a guardar en cSize //Llamar por segunda vez a la misma funcion para obtener la ruta del dispositivo. if (!SetupDiGetDeviceInterfaceDetail(Infoset, ref DeviceInterfaceData, IntPtr.Zero, 0, ref nRequiredSize, IntPtr.Zero))//Primera llamada { SP_DEVICE_INTERFACE_DETAIL_DATA dDetail = new SP_DEVICE_INTERFACE_DETAIL_DATA(); if (IntPtr.Size == 8) // for 64 bit operating systems { dDetail.cbSize = 8; } else { dDetail.cbSize = 5; // for 32 bit systems } if (SetupDiGetDeviceInterfaceDetail(Infoset, ref DeviceInterfaceData, ref dDetail, nRequiredSize, ref nRequiredSize, IntPtr.Zero)) //Segunda llamada { return dDetail.DevicePath;//Listo se encontro la ruta de algun dispositivo, falta ahora ver si coinciden VIP y PID } string error = Marshal.GetLastWin32Error().ToString(); } return null; //No se encontro ningun otro dispositivo en la lista :( }
protected virtual Boolean Find(Guid Target, ref String Path, Int32 Instance = 0) { IntPtr detailDataBuffer = IntPtr.Zero; IntPtr deviceInfoSet = IntPtr.Zero; try { SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(), da = new SP_DEVICE_INTERFACE_DATA(); Int32 bufferSize = 0, memberIndex = 0; deviceInfoSet = SetupDiGetClassDevs(ref Target, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); DeviceInterfaceData.cbSize = da.cbSize = Marshal.SizeOf(DeviceInterfaceData); while (SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref Target, memberIndex, ref DeviceInterfaceData)) { SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, ref da); { detailDataBuffer = Marshal.AllocHGlobal(bufferSize); Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); if (SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, ref da)) { IntPtr pDevicePathName = new IntPtr(IntPtr.Size == 4 ? detailDataBuffer.ToInt32() + 4 : detailDataBuffer.ToInt64() + 4); Path = Marshal.PtrToStringAuto(pDevicePathName).ToUpper(); Marshal.FreeHGlobal(detailDataBuffer); if (memberIndex == Instance) { return(true); } } else { Marshal.FreeHGlobal(detailDataBuffer); } } memberIndex++; } } catch (Exception ex) { Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message); throw; } finally { if (deviceInfoSet != IntPtr.Zero) { SetupDiDestroyDeviceInfoList(deviceInfoSet); } } return(false); }
internal static extern bool SetupDiEnumDeviceInterfaces( IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, ref Guid interfaceClassGuid, int memberIndex, SP_DEVICE_INTERFACE_DATA deviceInterfaceData );
protected static extern Boolean SetupDiOpenDeviceInfo(IntPtr DeviceInfoSet, String DeviceInstanceId, IntPtr hwndParent, Int32 Flags, ref SP_DEVICE_INTERFACE_DATA DeviceInfoData);
static internal extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, int deviceInterfaceDetailDataSize, ref int requiredSize, IntPtr deviceInfoData);
protected static extern Boolean SetupDiChangeState(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
public static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref Guid InterfaceClassGuid, UInt32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
protected static extern Boolean SetupDiSetClassInstallParams(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, ref SP_PROPCHANGE_PARAMS ClassInstallParams, Int32 ClassInstallParamsSize);
protected static extern bool SetupDiChangeState(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
protected virtual Boolean GetDeviceInstance(ref String Instance) { IntPtr detailDataBuffer = IntPtr.Zero; IntPtr deviceInfoSet = IntPtr.Zero; try { SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(), da = new SP_DEVICE_INTERFACE_DATA(); Int32 bufferSize = 0, memberIndex = 0; deviceInfoSet = SetupDiGetClassDevs(ref m_Class, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); DeviceInterfaceData.cbSize = da.cbSize = Marshal.SizeOf(DeviceInterfaceData); while (SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref m_Class, memberIndex, ref DeviceInterfaceData)) { SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, ref da); { detailDataBuffer = Marshal.AllocHGlobal(bufferSize); Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); if (SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, ref da)) { IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4); String Current = Marshal.PtrToStringAuto(pDevicePathName).ToUpper(); Marshal.FreeHGlobal(detailDataBuffer); if (Current == Path) { Int32 nBytes = 256; IntPtr ptrInstanceBuf = Marshal.AllocHGlobal(nBytes); CM_Get_Device_ID(da.Flags, ptrInstanceBuf, nBytes, 0); Instance = Marshal.PtrToStringAuto(ptrInstanceBuf).ToUpper(); Marshal.FreeHGlobal(ptrInstanceBuf); return(true); } } else { Marshal.FreeHGlobal(detailDataBuffer); } } memberIndex++; } } catch (Exception ex) { Console.WriteLine("{0} {1}", ex.HelpLink, ex.Message); throw; } finally { if (deviceInfoSet != IntPtr.Zero) { SetupDiDestroyDeviceInfoList(deviceInfoSet); } } return(false); }
public static extern bool SetupDiEnumDeviceInterfaces(IntPtr hDeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, int MemberIndex, out SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
public static InterfaceDetails[] getConnectedDevices() { InterfaceDetails[] devices = new InterfaceDetails[0]; //Create structs to hold interface information SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA(); devInfo.cbSize = (uint)Marshal.SizeOf(devInfo); SP_DEVICE_INTERFACE_DATA devIface = new SP_DEVICE_INTERFACE_DATA(); devIface.cbSize = (uint)(Marshal.SizeOf(devIface)); Guid G = new Guid(); HID.HidD_GetHidGuid(ref G); //Get the guid of the HID device class IntPtr deviceInfo = SetupAPI.SetupDiGetClassDevs(ref G, IntPtr.Zero, IntPtr.Zero, SetupAPI.DIGCF_DEVICEINTERFACE | SetupAPI.DIGCF_PRESENT); //Loop through all available entries in the device list, until false int j = 0; while (true) { if (!SetupAPI.SetupDiEnumDeviceInterfaces(deviceInfo, IntPtr.Zero, ref G, (uint)j, ref devIface)) { break; } uint requiredSize = 0; IntPtr detailMemory = Marshal.AllocHGlobal((int)requiredSize); SP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = (SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(detailMemory, typeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); functionClassDeviceData.cbSize = Marshal.SizeOf(functionClassDeviceData); if (!SetupAPI.SetupDiGetDeviceInterfaceDetail(deviceInfo, ref devIface, ref functionClassDeviceData, requiredSize, out requiredSize, ref devInfo)) { Marshal.FreeHGlobal(detailMemory); break; } string devicePath = functionClassDeviceData.DevicePath; Marshal.FreeHGlobal(detailMemory); //create file handles using CT_CreateFile SafeFileHandle tempHandle = Kernel32.CreateFile(devicePath, Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero); //get capabilites - use getPreParsedData, and getCaps //store the reportlengths IntPtr ptrToPreParsedData = new IntPtr(); bool ppdSucsess = HID.HidD_GetPreparsedData(tempHandle, ref ptrToPreParsedData); if (!ppdSucsess) { continue; } HIDP_CAPS capabilities = new HIDP_CAPS(); HID.HidP_GetCaps(ptrToPreParsedData, ref capabilities); HIDD_ATTRIBUTES attributes = new HIDD_ATTRIBUTES(); HID.HidD_GetAttributes(tempHandle, ref attributes); string productName = ""; string SN = ""; string manfString = ""; const int bufferLen = 128; IntPtr buffer = Marshal.AllocHGlobal(bufferLen); if (HID.HidD_GetProductString(tempHandle, buffer, bufferLen)) { productName = Marshal.PtrToStringAuto(buffer); } if (HID.HidD_GetSerialNumberString(tempHandle, buffer, bufferLen)) { SN = Marshal.PtrToStringAuto(buffer); } if (HID.HidD_GetManufacturerString(tempHandle, buffer, bufferLen)) { manfString = Marshal.PtrToStringAuto(buffer); } Marshal.FreeHGlobal(buffer); //Call freePreParsedData to release some stuff HID.HidD_FreePreparsedData(ref ptrToPreParsedData); //If connection was sucsessful, record the values in a global struct InterfaceDetails productInfo = new InterfaceDetails(); productInfo.devicePath = devicePath; productInfo.manufacturer = manfString; productInfo.product = productName; productInfo.PID = (ushort)attributes.ProductID; productInfo.VID = (ushort)attributes.VendorID; productInfo.versionNumber = (ushort)attributes.VersionNumber; productInfo.IN_reportByteLength = (int)capabilities.InputReportByteLength; productInfo.OUT_reportByteLength = (int)capabilities.OutputReportByteLength; productInfo.serialNumber = SN; //Check that serial number is actually a number int newSize = devices.Length + 1; Array.Resize(ref devices, newSize); devices[newSize - 1] = productInfo; ++j; } SetupAPI.SetupDiDestroyDeviceInfoList(deviceInfo); return(devices); }
/// <summary> /// Find all devices with the HID GUID attached to the system /// </summary> /// <remarks>This method searches for all devices that have the correct HID GUID and /// returns an array of matching device paths</remarks> private bool findHidDevices(ref String[] listOfDevicePathNames, ref int numberOfDevicesFound) { Debug.WriteLine("usbGenericHidCommunication:findHidDevices() -> Method called"); // Detach the device if it's currently attached if (isDeviceAttached) detachUsbDevice(); // Initialise the internal variables required for performing the search Int32 bufferSize = 0; IntPtr detailDataBuffer = IntPtr.Zero; Boolean deviceFound; IntPtr deviceInfoSet = new System.IntPtr(); Boolean lastDevice = false; Int32 listIndex = 0; SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); Boolean success; // Get the required GUID System.Guid systemHidGuid = new Guid(); HidD_GetHidGuid(ref systemHidGuid); Debug.WriteLine(string.Format("usbGenericHidCommunication:findHidDevices() -> Fetched GUID for HID devices ({0})", systemHidGuid.ToString())); try { // Here we populate a list of plugged-in devices matching our class GUID (DIGCF_PRESENT specifies that the list // should only contain devices which are plugged in) Debug.WriteLine("usbGenericHidCommunication:findHidDevices() -> Using SetupDiGetClassDevs to get all devices with the correct GUID"); deviceInfoSet = SetupDiGetClassDevs(ref systemHidGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // Reset the deviceFound flag and the memberIndex counter deviceFound = false; listIndex = 0; deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData); // Look through the retrieved list of class GUIDs looking for a match on our interface GUID do { //Debug.WriteLine("usbGenericHidCommunication:findHidDevices() -> Enumerating devices"); success = SetupDiEnumDeviceInterfaces (deviceInfoSet, IntPtr.Zero, ref systemHidGuid, listIndex, ref deviceInterfaceData); if (!success) { //Debug.WriteLine("usbGenericHidCommunication:findHidDevices() -> No more devices left - giving up"); lastDevice = true; } else { // The target device has been found, now we need to retrieve the device path so we can open // the read and write handles required for USB communication // First call is just to get the required buffer size for the real request success = SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref deviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero); // Allocate some memory for the buffer detailDataBuffer = Marshal.AllocHGlobal(bufferSize); Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); // Second call gets the detailed data buffer //Debug.WriteLine("usbGenericHidCommunication:findHidDevices() -> Getting details of the device"); success = SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref deviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero); // 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. listOfDevicePathNames[listIndex] = Marshal.PtrToStringAuto(pDevicePathName); //Debug.WriteLine(string.Format("usbGenericHidCommunication:findHidDevices() -> Found matching device (memberIndex {0})", memberIndex)); deviceFound = true; } listIndex = listIndex + 1; } while (!((lastDevice == true))); } catch (Exception) { // Something went badly wrong... output some debug and return false to indicated device discovery failure Debug.WriteLine("usbGenericHidCommunication:findHidDevices() -> EXCEPTION: Something went south whilst trying to get devices with matching GUIDs - giving up!"); return false; } finally { // Clean up the unmanaged memory allocations if (detailDataBuffer != IntPtr.Zero) { // Free the memory allocated previously by AllocHGlobal. Marshal.FreeHGlobal(detailDataBuffer); } if (deviceInfoSet != IntPtr.Zero) { SetupDiDestroyDeviceInfoList(deviceInfoSet); } } if (deviceFound) { Debug.WriteLine(string.Format("usbGenericHidCommunication:findHidDevices() -> Found {0} devices with matching GUID", listIndex - 1)); numberOfDevicesFound = listIndex - 2; } else Debug.WriteLine("usbGenericHidCommunication:findHidDevices() -> No matching devices found"); return deviceFound; }
public static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr hDevInfo, IntPtr devInfo, ref Guid interfaceClassGuid, UInt32 memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
/* NKH /// <summary> /// 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. /// </summary> /// /// <param name="m"> a WM_DEVICECHANGE message. A call to RegisterDeviceNotification /// causes WM_DEVICECHANGE messages to be passed to an OnDeviceChange routine.. </param> /// <param name="mydevicePathName"> a device pathname returned by /// SetupDiGetDeviceInterfaceDetail in an SP_DEVICE_INTERFACE_DETAIL_DATA structure. </param> /// /// <returns> /// True if the names match, False if not. /// </returns> /// internal Boolean DeviceNameMatch(Message m, String mydevicePathName) { Int32 stringSize; try { DEV_BROADCAST_DEVICEINTERFACE_1 devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE_1(); DEV_BROADCAST_HDR devBroadcastHeader = new 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 == 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 32 bytes // in the strucutre that are not part of dbch_name and dividing by 2 because there are // 2 bytes per character. stringSize = System.Convert.ToInt32((devBroadcastHeader.dbch_size - 32) / 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); // 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)) { return true; } else { return false; } } } catch (Exception ex) { throw; } return false; } */ /// <summary> /// Use SetupDi API functions to retrieve the device path name of an /// attached device that belongs to a device interface class. /// </summary> /// /// <param name="myGuid"> an interface class GUID. </param> /// <param name="devicePathName"> a pointer to the device path name /// of an attached device. </param> /// /// <returns> /// True if a device is found, False if not. /// </returns> internal Boolean FindDeviceFromGuid(System.Guid myGuid, ref String devicePathName) { Int32 bufferSize = 0; IntPtr detailDataBuffer = IntPtr.Zero; Boolean deviceFound; IntPtr deviceInfoSet = new System.IntPtr(); Boolean lastDevice = false; Int32 memberIndex = 0; SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); Boolean success; try { // *** // API function // summary // Retrieves a device information set for a specified group of devices. // SetupDiEnumDeviceInterfaces uses the device information set. // parameters // Interface class GUID. // Null to retrieve information for all device instances. // 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 // Handle to a device information set for the devices. // *** deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); deviceFound = false; memberIndex = 0; // The cbSize element of the MyDeviceInterfaceData structure must be set to // the structure's size in bytes. // The size is 28 bytes for 32-bit code and 32 bits for 64-bit code. MyDeviceInterfaceData.cbSize = Marshal.SizeOf(MyDeviceInterfaceData); do { // Begin with 0 and increment through the device information set until // no more devices are available. // *** // API function // summary // 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. // parameters // DeviceInfoSet returned by SetupDiGetClassDevs. // Optional SP_DEVINFO_DATA structure that defines a device instance // that is a member of a device information set. // Device interface GUID. // Index to specify a device in a device information set. // Pointer to a handle to a SP_DEVICE_INTERFACE_DATA structure for a device. // Returns // True on success. // *** success = SetupDiEnumDeviceInterfaces (deviceInfoSet, IntPtr.Zero, ref myGuid, memberIndex, ref MyDeviceInterfaceData); // Find out if a device information set was retrieved. if (!success) { lastDevice = true; } else { // A device is present. // *** // API function: // summary: // 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. // parameters // DeviceInfoSet returned by SetupDiGetClassDevs // SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces // A returned 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. // Pointer to a variable that will receive the returned required size of the // SP_DEVICE_INTERFACE_DETAIL_DATA structure. // Returned pointer to an SP_DEVINFO_DATA structure to receive information about the device. // Returns // True on success. // *** success = SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref MyDeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero); // Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size. detailDataBuffer = Marshal.AllocHGlobal(bufferSize); // Store cbSize in the first bytes of the array. The number of bytes varies with 32- and 64-bit systems. Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); // 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); // 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 = Marshal.PtrToStringAuto(pDevicePathName); deviceFound = true; } memberIndex = memberIndex + 1; } while (!((lastDevice == true))); return deviceFound; } catch { throw; } finally { if (detailDataBuffer != IntPtr.Zero) { // Free the memory allocated previously by AllocHGlobal. Marshal.FreeHGlobal(detailDataBuffer); } if (deviceInfoSet != IntPtr.Zero) { // *** // API function // summary // Frees the memory reserved for the DeviceInfoSet returned by SetupDiGetClassDevs. // parameters // DeviceInfoSet returned by SetupDiGetClassDevs. // returns // True on success. // *** SetupDiDestroyDeviceInfoList(deviceInfoSet); } } }
static extern unsafe int SetupDiEnumDeviceInterfaces( int DeviceInfoSet, int DeviceInfoData, ref GUID lpHidGuid, int MemberIndex, ref SP_DEVICE_INTERFACE_DATA lpDeviceInterfaceData);
public static extern int SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, int DeviceInfoData, ref Guid InterfaceClassGuid, int MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
//---#+************************************************************************ //---NOTATION: //- int CT_SetupDiEnumDeviceInterfaces(int memberIndex) //- //--- DESCRIPTION: //-- // Autor: F.L. //-*************************************************************************+#* public unsafe int CT_SetupDiEnumDeviceInterfaces(int memberIndex) { mySP_DEVICE_INTERFACE_DATA = new SP_DEVICE_INTERFACE_DATA(); mySP_DEVICE_INTERFACE_DATA.cbSize = Marshal.SizeOf(mySP_DEVICE_INTERFACE_DATA); int result = SetupDiEnumDeviceInterfaces( hDevInfo, 0, ref MYguid, memberIndex, ref mySP_DEVICE_INTERFACE_DATA); return result; }
public static extern Boolean SetupDiGetDeviceInterfaceDetail( IntPtr hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, uint deviceInterfaceDetailDataSize, ref uint requiredSize,//out UInt32 requiredSize, IntPtr deviceInfoData//ref SP_DEVINFO_DATA deviceInfoData );
public static extern bool SetupDiGetDeviceInterfaceDetail(DeviceInfoHandle DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize, ref int RequiredSize, IntPtr DeviceInfoData);
//Este metodo de la clase USBboard18F encuentra la tarjeta y crea los handles de lectura y escritura de datos //Regresa true si encuentra la tarjeta y logro crear los handles, false si no encontró tarjeta o logró crear los handles public bool FindDevHID() { Guid ghid; IntPtr USBBoardinfoset; //VID y PID string strSearch = string.Format("vid_{0:x4}&pid_{1:x4}", VID, PID); HidD_GetHidGuid(out ghid); //Obtengo la lista de dispositivos y los guardo en un infoset USBBoardinfoset = SetupDiGetClassDevs(ref ghid, null, IntPtr.Zero, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); //Las siguientes dos lineas de codigo las aconsejan en pinvoke.net... SP_DEVICE_INTERFACE_DATA dInterface = new SP_DEVICE_INTERFACE_DATA(); //Lo siguiente es buscar nuestro dispositivo en la lista que se obtuvo con un ciclo loop, para sistemas de //64bits int index = 0; dInterface.cbSize = 32; while (SetupDiEnumDeviceInterfaces(USBBoardinfoset, 0, ref ghid, (uint)index, ref dInterface)) { USBDeviceInfo.DevicePath = GetDevicePath(USBBoardinfoset, ref dInterface); if (USBDeviceInfo.DevicePath.IndexOf(strSearch) >= 0) { //Lectura sincrona USBDeviceInfo.ReadHandle = CreateFile(USBDeviceInfo.DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); USBDeviceInfo.WriteHandle = CreateFile(USBDeviceInfo.DevicePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); return true; //Exito } index++; //Prueba con el siguiente de la lista } //En caso de que el sistema sea de 32 bits se vuelve a hacer la busqueda del dispositivo index = 0; dInterface.cbSize = 28; while (SetupDiEnumDeviceInterfaces(USBBoardinfoset, 0, ref ghid, (uint)index, ref dInterface)) { USBDeviceInfo.DevicePath = GetDevicePath(USBBoardinfoset, ref dInterface); if (USBDeviceInfo.DevicePath.IndexOf(strSearch) >= 0) { //Lectura sincrona USBDeviceInfo.ReadHandle = CreateFile(USBDeviceInfo.DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); USBDeviceInfo.WriteHandle = CreateFile(USBDeviceInfo.DevicePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); return true; //Exito } index++; //Prueba con el siguiente de la lista } string error = Marshal.GetLastWin32Error().ToString(); return false; //No se encontro dispositivo }
public static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, UInt32 DeviceInterfaceDetailDataSize, ref UInt32 RequiredSize, ref SP_DEVINFO_DATA DeviceInfoData);
private static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, IntPtr deviceInterfaceDetailData, int deviceInterfaceDetailDataSize, ref int requiredSize, SP_DEVINFO_DATA deviceInfoData);
/// <summary> /// Connects to the specified device in the list. /// </summary> /// <param name="listHandle"> /// The handle of the list created with listCreate. /// </param> /// <param name="index"> /// The zero-based index of the device in the list to connect to. /// </param> /// <param name="deviceInterfaceGuid">GUID from the INF file.</param> /// <returns>Handles needed to communicate with the device.</returns> internal static unsafe WinUsbDeviceHandles listConnect(IntPtr listHandle, Byte index, Guid deviceInterfaceGuid) { WinUsbDeviceHandles handles = new WinUsbDeviceHandles(); /* Get the device instance ****************************************/ handles.deviceInstance = listGetDeviceInstance(listHandle, index); /* Get the DeviceInterfaceData struct *****************************/ // DeviceInterfaceData is some info about the device in the list. SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); // Necessary according to http://msdn.microsoft.com/en-us/library/ms791242.aspx DeviceInterfaceData.cbSize = (UInt32)Marshal.SizeOf(DeviceInterfaceData); Boolean result = SetupDiEnumDeviceInterfaces(listHandle, IntPtr.Zero, ref deviceInterfaceGuid, index, ref DeviceInterfaceData); if (!result) { throw new Win32Exception("Unable to get the device interface data."); } /* Get the DeviceInterfaceDetailData struct ***********************/ // RequiredSize is the size in bytes of the // DeviceInterfaceDetailData struct we want to get for the device. UInt32 RequiredSize = 0; result = SetupDiGetDeviceInterfaceDetail(listHandle, ref DeviceInterfaceData, IntPtr.Zero, 0, ref RequiredSize, IntPtr.Zero); if (!result && Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) { throw new Win32Exception("Unable to get the size of the device interface detail."); } // Now that we know the size of the DeviceInterfaceDetailData struct, // we can allocate memory for it. IntPtr pDeviceInterfaceDetailData = Marshal.AllocHGlobal((Int32)RequiredSize); // Get the DeviceInterfaceDetailData. /* According to the MSDN, we must set cbSize (the first 4 bytes of * the array) to sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA). On 32-bit * machines, this is 6, and on 64-bit machines, this is 8. I'm not * sure why. */ bool sixtyFourBit = (sizeof(IntPtr) == 8); Marshal.WriteInt32(pDeviceInterfaceDetailData, sixtyFourBit ? 8 : 6); result = SetupDiGetDeviceInterfaceDetail(listHandle, ref DeviceInterfaceData, pDeviceInterfaceDetailData, RequiredSize, ref RequiredSize, IntPtr.Zero); if (!result) { Marshal.FreeHGlobal(pDeviceInterfaceDetailData); throw new Win32Exception("Unable to get the device interface detail."); } /* Get the device handle ******************************************/ // Get the address of the PDeviceInterfaceDetaildata->DevicePath. IntPtr pDevicePath = new IntPtr(pDeviceInterfaceDetailData.ToInt64() + 4); // Get a string object with the device path. // This is what a typical DevicePath looks like: // \\?\usb#vid_04d8&pid_da01#5&226425fa&0&2#{fe187157-e4cb-4c53-a1d6-e6040ff6896f} String devicePath = Marshal.PtrToStringAuto(pDevicePath); // Use the DevicePath to open a file handle. handles.deviceHandle = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, IntPtr.Zero); if (handles.deviceHandle.IsInvalid) { Int32 error = Marshal.GetLastWin32Error(); Marshal.FreeHGlobal(pDeviceInterfaceDetailData); if (error == 5) // ERROR_ACCESS_DENIED { throw new Win32Exception("Access denied when trying to open device. Try closing all other programs that are using the device."); } else { throw new Win32Exception(error, "Unable to create a handle for the device (" + devicePath + ")."); } } Marshal.FreeHGlobal(pDeviceInterfaceDetailData); // Use DeviceHandle to make a Winusb Interface Handle. result = WinUsb_Initialize(handles.deviceHandle, ref handles.winusbHandle); if (!result) { Int32 error = Marshal.GetLastWin32Error(); handles.deviceHandle.Close(); throw new Win32Exception(error, "Unable to initialize WinUSB."); } // Set the timeout for control transfers to 350 ms. // It needs to be that long to support the control transfer that erases the entire script // on the Mini Maestros. // TODO: test to make sure this timeout is actually being applied correctly UInt32 timeout = 350; result = WinUsb_SetPipePolicy(handles.winusbHandle, 0, PIPE_TRANSFER_TIMEOUT, 4, &timeout); if (!result) { Int32 error = Marshal.GetLastWin32Error(); Winusb.disconnect(handles); throw new Win32Exception(error, "Unable to set control transfer timeout."); } return(handles); }
static extern unsafe int SetupDiGetDeviceInterfaceDetail( int DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA lpDeviceInterfaceData, ref PSP_DEVICE_INTERFACE_DETAIL_DATA myPSP_DEVICE_INTERFACE_DETAIL_DATA, int detailSize, ref int requiredSize, int* bPtr);
internal static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
public static extern bool SetupDiEnumDeviceInterfaces(DeviceInfoHandle DeviceInfoSet, int DeviceInfoData, ref System.Guid InterfaceClassGuid, int MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
internal static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData);
private static extern Boolean SetupDiGetDeviceInterfaceDetail( IntPtr hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, Int32 deviceInterfaceDetailDataSize, IntPtr requiredSize, // null [MarshalAs(UnmanagedType.AsAny)] object deviceInfoData // null );
/// <summary> /// Creates an object to handle read/write functionality for a USB HID device /// asnychronous read /// </summary> public static interfaceDetails[] getConnectedDevices() { interfaceDetails[] devices = new interfaceDetails[0]; //Create structs to hold interface information SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA(); SP_DEVICE_INTERFACE_DATA devIface = new SP_DEVICE_INTERFACE_DATA(); devInfo.cbSize = (uint)Marshal.SizeOf(devInfo); devIface.cbSize = (uint)(Marshal.SizeOf(devIface)); Guid G = new Guid(); HidD_GetHidGuid(ref G); //Get the guid of the HID device class IntPtr i = SetupDiGetClassDevs(ref G, IntPtr.Zero, IntPtr.Zero, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); //Loop through all available entries in the device list, until false SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA(); if (IntPtr.Size == 8) // for 64 bit operating systems { didd.cbSize = 8; } else { didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // for 32 bit systems } int j = -1; bool b = true; int error; SafeFileHandle tempHandle; while (b) { j++; b = SetupDiEnumDeviceInterfaces(i, IntPtr.Zero, ref G, (uint)j, ref devIface); error = Marshal.GetLastWin32Error(); if (b == false) { break; } uint requiredSize = 0; bool b1 = SetupDiGetDeviceInterfaceDetail(i, ref devIface, ref didd, 256, out requiredSize, ref devInfo); string devicePath = didd.DevicePath; //create file handles using CT_CreateFile tempHandle = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); //get capabilites - use getPreParsedData, and getCaps //store the reportlengths IntPtr ptrToPreParsedData = new IntPtr(); bool ppdSucsess = HidD_GetPreparsedData(tempHandle, ref ptrToPreParsedData); if (ppdSucsess == false) { continue; } HIDP_CAPS capabilities = new HIDP_CAPS(); int hidCapsSucsess = HidP_GetCaps(ptrToPreParsedData, ref capabilities); HIDD_ATTRIBUTES attributes = new HIDD_ATTRIBUTES(); bool hidAttribSucsess = HidD_GetAttributes(tempHandle, ref attributes); string productName = ""; string manfString = ""; IntPtr buffer = Marshal.AllocHGlobal(126);//max alloc for string; if (HidD_GetProductString(tempHandle, buffer, 126)) { productName = Marshal.PtrToStringAuto(buffer); } if (HidD_GetManufacturerString(tempHandle, buffer, 126)) { manfString = Marshal.PtrToStringAuto(buffer); } Marshal.FreeHGlobal(buffer); //Call freePreParsedData to release some stuff HidD_FreePreparsedData(ref ptrToPreParsedData); //If connection was sucsessful, record the values in a global struct interfaceDetails productInfo = new interfaceDetails(); productInfo.devicePath = devicePath; productInfo.manufacturer = manfString; productInfo.product = productName; productInfo.PID = (ushort)attributes.ProductID; productInfo.VID = (ushort)attributes.VendorID; productInfo.versionNumber = (ushort)attributes.VersionNumber; productInfo.IN_reportByteLength = (int)capabilities.InputReportByteLength; productInfo.OUT_reportByteLength = (int)capabilities.OutputReportByteLength; productInfo.FEATURE_reportByteLength = (int)capabilities.FeatureReportByteLength; int newSize = devices.Length + 1; Array.Resize(ref devices, newSize); devices[newSize - 1] = productInfo; } SetupDiDestroyDeviceInfoList(i); return(devices); }
public static DeviceInfo[] GetInterfaces(string[] devicePaths = null) { var list = new List <DeviceInfo>(); Guid hidGuid = Guid.Empty; NativeMethods.HidD_GetHidGuid(ref hidGuid); int requiredSize3 = 0; List <string> devicePathNames3 = new List <string>(); var interfaceData = new SP_DEVICE_INTERFACE_DATA(); List <string> serials = new List <string>(); interfaceData.Initialize(); var deviceInfoSet = NativeMethods.SetupDiGetClassDevs(hidGuid, IntPtr.Zero, IntPtr.Zero, DIGCF.DIGCF_DEVICEINTERFACE); for (int i2 = 0; NativeMethods.SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref hidGuid, i2, ref interfaceData); i2++) { var deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.Initialize(); bool success = NativeMethods.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref interfaceData, IntPtr.Zero, 0, ref requiredSize3, IntPtr.Zero); IntPtr ptrDetails = Marshal.AllocHGlobal(requiredSize3); Marshal.WriteInt32(ptrDetails, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); success = NativeMethods.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref interfaceData, ptrDetails, requiredSize3, ref requiredSize3, ref deviceInfoData); var interfaceDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(ptrDetails, typeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); var devicePath = interfaceDetail.DevicePath; if (devicePaths != null && !devicePaths.Contains(devicePath)) { continue; } var deviceId = GetDeviceId(deviceInfoData.DevInst); devicePathNames3.Add(devicePath); Marshal.FreeHGlobal(ptrDetails); var accessRights = WinNT.GENERIC_READ | WinNT.GENERIC_WRITE; var shareModes = WinNT.FILE_SHARE_READ | WinNT.FILE_SHARE_WRITE; // Open the device as a file so that we can query it with HID and read/write to it. var devHandle = NativeMethods.CreateFile( interfaceDetail.DevicePath, accessRights, shareModes, IntPtr.Zero, WinNT.OPEN_EXISTING, WinNT.Overlapped, IntPtr.Zero ); if (devHandle.IsInvalid) { continue; } var ha = new HIDD_ATTRIBUTES(); ha.Size = Marshal.SizeOf(ha); var success2 = NativeMethods.HidD_GetAttributes(devHandle, ref ha); string serial = ""; string vendor = ""; string product = ""; string phdesc = ""; if (success2) { IntPtr preparsedDataPtr = new IntPtr(); HIDP_CAPS caps = new HIDP_CAPS(); // Read out the 'preparsed data'. NativeMethods.HidD_GetPreparsedData(devHandle, ref preparsedDataPtr); // feed that to GetCaps. NativeMethods.HidP_GetCaps(preparsedDataPtr, ref caps); // Free the 'preparsed data'. NativeMethods.HidD_FreePreparsedData(ref preparsedDataPtr); // This could fail if the device was recently attached. uint capacity = 126; IntPtr buffer = Marshal.AllocHGlobal((int)capacity); serial = NativeMethods.HidD_GetSerialNumberString(devHandle, buffer, capacity) ? Marshal.PtrToStringAuto(buffer) : ""; vendor = NativeMethods.HidD_GetManufacturerString(devHandle, buffer, capacity) ? Marshal.PtrToStringAuto(buffer) : ""; product = NativeMethods.HidD_GetProductString(devHandle, buffer, capacity) ? Marshal.PtrToStringAuto(buffer) : ""; phdesc = NativeMethods.HidD_GetPhysicalDescriptor(devHandle, buffer, capacity) ? Marshal.PtrToStringAuto(buffer) : ""; // Free resources. Marshal.FreeHGlobal(buffer); } uint parentDeviceInstance = 0; string parentDeviceId = null; var CRResult = NativeMethods.CM_Get_Parent(out parentDeviceInstance, deviceInfoData.DevInst, 0); if (CRResult == CR.CR_SUCCESS) { parentDeviceId = GetDeviceId(parentDeviceInstance); } var di = new DeviceInfo(deviceId, parentDeviceId, devicePath, vendor, product, hidGuid, "", DeviceNodeStatus.DN_MANUAL, ha.VendorID, ha.ProductID, ha.VersionNumber); list.Add(di); serials.Add(phdesc); devHandle.Close(); } NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet); deviceInfoSet = IntPtr.Zero; return(list.ToArray()); }
static internal extern bool SetupDiEnumDeviceInterfaces(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, ref Guid interfaceClassGuid, int memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
internal static extern bool SetupDiGetDeviceInterfaceDetail( IntPtr deviceInfoSet, SP_DEVICE_INTERFACE_DATA deviceInterfaceData, IntPtr deviceInterfaceDetailData, int deviceInterfaceDetailDataSize, ref int requiredSize, SP_DEVINFO_DATA deviceInfoData );
internal static extern bool SetupDiEnumDeviceInterfaces( IntPtr DeviceInfoSet, //Input: Give it the HDEVINFO we got from SetupDiGetClassDevs() IntPtr DeviceInfoData, //Input (optional) ref Guid InterfaceClassGuid, //Input uint MemberIndex, //Input: "Index" of the device you are interested in getting the path for. ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData); //Output: This function fills in an "SP_DEVICE_INTERFACE_DATA" structure.