Envoyer le pilote de périphérique IOCTL à Windows – CreateFile échoue

Je veux envoyer une commande IOCTL à un lecteur PC / SC connecté à mon ordinateur (win7 64 bit). Pour envoyer une commande IOCTL, j’ai besoin d’une poignée sur le périphérique, que je ne peux pas créer.

Le périphérique est répertorié comme “OMNIKEY 1021” dans le gestionnaire de périphériques, le nom de l’object de périphérique physique est “\ Device \ USBPDO-15”. En utilisant l’outil “WinObj”, je peux détecter 2 liens symboliques: USB # VID_076B & PID_1021 # 5 & 291f6990 & 0 & 1 # {50dd5230-ba8a-11d1-bf5d-0000f805f530} USB # VID_076B & PID_1021 # 5 & 291f6990

Mon problème: je ne peux pas créer un handle valide pour ce périphérique avec la fonction CreateFile:

J’ai trouvé plusieurs formats possibles sur MSDN / Google à utiliser comme paramètre lpFileName de la fonction CreateFile, mais aucun ne semble fonctionner:

\\?\Device\USBPDO-15 \\.\Device\USBPDO-15 \\GLOBAL??\Device\USBPDO-15 \GLOBAL??\Device\USBPDO-15 \\.\USBPDO-15 \\?\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530} \\.\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530} \\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530} \GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530} \\?\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed} \\.\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed} \\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed} \GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed} 

Échantillon de code :

 #include  #include  int main (int argc, char* argv[]) { HANDLE handle = CreateFile ( L"\\\\.\\Device\\USBPDO-15", 0, FILE_SHARE_READ, //FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, //FILE_FLAG_OVERLAPPED, NULL ); if (handle == INVALID_HANDLE_VALUE) std::cout << "INVALID HANDLE" << std::endl; else std::cout << "HANDLE: " << std::hex << handle << std::endl; } 

Remarques:

  • Le handle retourné est toujours invalide
  • Toujours en tant qu’administrateur, les privilèges ne devraient pas poser problème

modifier:

Solution:

  • Le service PC / SC prend la propriété exclusive des périphériques, de sorte que toute tentative d’appeler ‘CreateFile’ échouera toujours.
  • La solution est un pilote d’espace kernel, cela vous permet de transmettre les IRP au pilote. (J’ai pu implémenter un pilote de filtre KMDF pour modifier les données envoyées / reçues vers / depuis le périphérique)

Essayez-le à ma façon. J’utilise Setup API pour énumérer tous les périphériques USB actifs dans le système et obtenir des chemins. De cette façon, vous pouvez savoir s’il s’agit du chemin ou d’autres arguments que CreateFile n’aime pas.

J’appendai quelques commentaires un peu plus tard, si cela vous intéresse.

 HDEVINFO hDevInfo = SetupDiGetClassDevs( &_DEVINTERFACE_USB_DEVICE, 0, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if(hDevInfo == INVALID_HANDLE_VALUE) { return ERR_FAIL; } std::vector interfaces; for (DWORD i = 0; true; ++i) { SP_DEVINFO_DATA devInfo; devInfo.cbSize = sizeof(SP_DEVINFO_DATA); BOOL succ = SetupDiEnumDeviceInfo(hDevInfo, i, &devInfo); if (GetLastError() == ERROR_NO_MORE_ITEMS) break; if (!succ) continue; SP_INTERFACE_DEVICE_DATA ifInfo; ifInfo.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA); if (TRUE != SetupDiEnumDeviceInterfaces(hDevInfo, &devInfo, &(_DEVINTERFACE_USB_DEVICE), 0, &ifInfo)) { if (GetLastError() != ERROR_NO_MORE_ITEMS) break; } interfaces.push_back(ifInfo); } std::vector devicePaths; for (size_t i = 0; i < interfaces.size(); ++i) { DWORD requiredSize = 0; SetupDiGetDeviceInterfaceDetail(hDevInfo, &(interfaces.at(i)), NULL, NULL, &requiredSize, NULL); SP_INTERFACE_DEVICE_DETAIL_DATA* data = (SP_INTERFACE_DEVICE_DETAIL_DATA*) malloc(requiredSize); assert (data); data->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &(interfaces.at(i)), data, requiredSize, NULL, NULL)) { continue; } devicePaths.push_back(data); } 

Essayez simplement avec CreateFile(L"\\\\.\\{GUID}",etc..