Je suis très nouveau pour la communication avec les pilotes de périphériques Windows. A12) J'ai besoin de communiquer avec un pilote tiers. Je vois que CreateFile()
accepte à la fois le nom du périphérique (tel que \\\\.\\DeviceName
) et aussi je peux appeler le nom de fichier complet (tel que \\\\.\\C:\\MyPath\\DriverName.sys
). Quelle est la meilleure option? Pourquoi? Les deux fonctionnent de la même manière?DeviceIOControl() donne une erreur 50
B) Je vois que beaucoup de pilotes de périphériques a deux noms, par exemple:
SymbolicLink "\GLOBAL??\VirtualSerial"
Destination "\Device\VrSerialrs232"
Si je tente ouvert par exemple ouvert VrSerialrs232
avec CreateFile()
il échoue. Alors, pourquoi utiliser le VrSerialrs232
si je dois toujours appeler le SymbolicLink(VirtualSerial)
? C) J'ai installé un moniteur DeviceIOControl
pour vérifier pourquoi mon code échoue avec Error 50
(la demande n'est pas supportée) et je ne peux pas comprendre pourquoi.
La sortie du DeviceIOControl
moniteur est here
Ceux de test.exe
sont mon code, l'autre (protégé) est l'application d'origine appelant le même appareil.
Mon code est comme ceci:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
void ErrorExit(LPTSTR lpszFunction){
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL);
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf)/sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}
BOOL OpenDevice(PWSTR DriverName, HANDLE *lphDevice){
WCHAR DeviceName[MAX_PATH]; HANDLE hDevice;
if ((GetVersion() & 0xFF) >= 5) {
wcscpy(DeviceName, L"\\\\.\\Global\\");
} else {
wcscpy(DeviceName, L"\\\\.\\"); }
wcscat(DeviceName, DriverName); printf("Opening.. %S\n", DeviceName);
hDevice = CreateFileW(DeviceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDevice == INVALID_HANDLE_VALUE) {
printf("CreateFile() ERROR %d\n", GetLastError()); return FALSE;
}
*lphDevice = hDevice; return TRUE;
}
int _tmain(int argc, _TCHAR* argv[]){
HANDLE hDevice = NULL;
DWORD cb = 0;
int ret = 0;
char tcode[] = "\x8a\xb3\x39\x9d"; /* Copied from original request seen on Monitor) */
if(!OpenDevice(L"MyDeviceName",&hDevice)) {
printf("Error: Error opening device\n");
return(0);
} else {
printf("Device succesfully opened!\n");
}
char *Buff = (char *)VirtualAlloc(NULL, 0x330, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (Buff){
ret = DeviceIoControl(hDevice, 0xa028442f, tcode, 0x04, 0, NULL, &cb, (LPOVERLAPPED)NULL);
if (ret == 0) {
printf("Error: Bytes returned %#x\n",cb);
ErrorExit(TEXT("DeviceIoControl: "));
}
}
CloseHandle(hDevice);
return(0);
}
Je reçois toujours cette erreur:
C:>Test.exe
Opening.. \\.\Global\MyDeviceName
Device succesfully opened!
Error: Bytes returned 0
DeviceIOControl: Error 50 - The request is not supported
Pourquoi? Je ne connais pas le nom des commandes IOCTL, mais je connais les numéros. Il existe un moyen de traduire un numéro IOCTL à un nom?
Ceci est une demande valide et réelle que j'ai capturé avec un moniteur IOCTL.
Log started...
'C:\PathToApplication\OriginalAppName.exe' (PID: 2896)
'\Device\VSFilterbpd' (0x86b83c40) [\??\C:\LocalPath\DeviceDriverName.sys]
SymbolicLink "\GLOBAL??\VSFFilter"
IOCTL Code: 0xa028442f, Method: METHOD_NEITHER
InBuff: 0x004883a4, InSize: 0x00000004
--------------------------------------------------------------------
9c 84 e2 86 | ....
OutBuff: 0x004b4f68, OutSize: 0x00001b20
--------------------------------------------------------------------
03 00 00 00 1c 03 00 00 00 00 00 00 00 00 00 00 | ................
00 00 00 00 e4 0c 00 00 00 00 00 00 00 00 00 00 | ................
A lot of data.
Ce que je manque à reproduire/clone/reproduire exactement le même message au même pilote par de ma propre application?
Merci
Eh bien, le code de contrôle est faux, le conducteur ne le reconnaît pas. Cela semble étrange, le code de la méthode de passage de tampon est 3, METHOD_NEITHER. –