Problem z otwarciem uchwytu urządzenia

Wszystko dla programistów. C++, Delphi, Java, PHP, SQL
Witam!

Mam wielki problem z otwarciem uchwytu urządzenia.

Na samym początku Tworzę sterownik trybu jądra, któy rejesruje urządzenie za pomocą takiego kodu:


[code]
VOID OnUnload(IN PDRIVER_OBJECT driverObject)
{
DbgPrint("Wywolano funkcje OnUnload\n");
}


PDEVICE_OBJECT g_Device;
const WCHAR deviceNameBuffer[] = L"\\Device\\Kropki112";

NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath)
{
NTSTATUS ntStatus;
UNICODE_STRING deviceNameUnicodeString;

RtlInitUnicodeString(&deviceNameUnicodeString,deviceNameBuffer);

ntStatus = IoCreateDevice(driverObject,0,&deviceNameUnicodeString,0x00001234,0,TRUE,&g_Device);


if(NT_SUCCESS(ntStatus))
{
DbgPrint("Wszytsko oK");
}

driverObject->DriverUnload;

return ntStatus;

}
[/code]


Ładuje sterownik za pomocą menadżera SCM rejestruje Go i uruchamiam.
WinObj pokazuje zarejestrowane urządzenie, DebgView pokazuje komunikat "Wszytsko ok", jednak gdy próbuje utworzyć uchwyt urządzenia za pomocą następującego kodu:

[code]

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hDevice = CreateFile(L"\\\\Device\\Kropki112",GENERIC_READ,
0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);


if(hDevice == INVALID_HANDLE_VALUE)
{
printf("Error");
cout << GetLastError();
}

_getch();

return 0;
}
[/code]



hDevice zwraca -1, a GetLastError 53 - ERROR_BAD_NETPATH
gdy próbuje jakieś inne urządzenie otworzyć, komunikat ten sam - ktoś ma jakiś pomysł co robie źle?

System Windows7 x64 z SP1, wszytskie poprawki instalowane na bieżąco
Animalpak
user
 
Posty: 3
Dołączył(a): So gru 15, 2012 6:25
Podziękował: 1 razy
Podziękowano: 0 razy
Reputacja: 1

Spokojnie - to tylko reklama - zniknie po zalogowaniu :)

Kliknij 👇


serwery VPS
Pani Reklama
Automat
Posty:
Dołączył(a): ab aeterno
Lokalizacja: UW-Zaloga
Hey,

Musisz albo w DriverEntry stworzyć symbolic link do \DosDevices\Nazwa używając IoCreateSymbolicLink.
Albo korzystać z NtCreateFile zamiast z CreateFile.
Sam CreateFile nie umie się do \Device\Nazwa odwołać.

Prawdę mówiąc stworzenie symbilic linku jest prostsze i zajmuje mniej kodu.
[code]
UNICODE_STRING usDosDeviceName, usDriverName;
RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\Nazwa");
// usDriverName musi zawierac nazwe Device; to to co podajesz do IoCreateDevice
IoCreateSymbolicLink(&usDosDeviceName, &usDriverName);
[/code]
Po zrobieniu tego aliasu używasz ścieżki "\\\\.\\Nazwa" w CreateFile (czyli, bez escapeujących backslashów \\.\Nazwa).

EDIT Sposób z NtCreateFile możesz zobaczyć tutaj: http://gynvael.coldwind.pl/n/device_open_win32
[color=#0080FF]gynvael.coldwind[/color]//[color=#00FF00]vx[/color]
http://gynvael.coldwind.pl
Gynvael Coldwind
Przyjaciel
Avatar użytkownika
Posty: 1633
Dołączył(a): N lip 25, 2004 17:08
Podziękował: 53 razy
Podziękowano: 184 razy
Reputacja: 23041

Następujący użytkownik chciałby podziękować Gynvael Coldwind za jego post:
Animalpak

Dzięki wielkie za odzew :)

Powiem szczerze, że wcześniej próbowałem także z symbolic linkami, jednak także nie działało...

Dzięki Twojemu wyjaśnieniu mi sytuacji, udało mi się otworzyć uchwyty do urządzeń już zainstalowanych w systemie, więc zacząłem szukać błędu w kodzie sterownika który ładuje i udało się :)

Aby System czy to za pomocą CreateFile za pomocą linków symbolicznych czy to NtCreateFile, mógł otworzyć dany uchwyt urządzenia - to sterownik musi zawierać funkcje do obsługi konkretnych Pakietów IRP. Aby nakazać sterownikowi obsługe konkretnego pakietu IRP wystarczy mu przypisać odpowiedni wskaźnik funkcji w obiekcie sterownika.

Oto Poprawny kod sterownika który może się komunikować z user-mode za pomoca funkcji ReadFile, WirteFile

[code]
NTSTATUS MyOpen(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{
DbgPrint("MyOpen");
return STATUS_SUCCESS;
}


NTSTATUS MyClose(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{
DbgPrint("MyClose");
return STATUS_SUCCESS;
}

NTSTATUS MyRead(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{
DbgPrint("MyRead");
return STATUS_SUCCESS;
}


NTSTATUS MyWrite(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{
DbgPrint("MyWrite");
return STATUS_SUCCESS;
}


NTSTATUS MyIOControl(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION IrpSp;
ULONG FunctionCode;

DbgPrint("MyIOControl");
IrpSp = IoGetCurrentIrpStackLocation(Irp);
FunctionCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;

switch(FunctionCode)
{
//do wypelnienia
}

return STATUS_SUCCESS;
}





VOID OnUnload(IN PDRIVER_OBJECT driverObject)
{
DbgPrint("Wywolano funkcje OnUnload\n");
}


PDEVICE_OBJECT g_Device;
const WCHAR deviceNameBuffer[] = L"\\Device\\michal00";

NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath)
{
NTSTATUS ntStatus;
UNICODE_STRING deviceNameUnicodeString;

RtlInitUnicodeString(&deviceNameUnicodeString,deviceNameBuffer);

ntStatus = IoCreateDevice(driverObject,0,&deviceNameUnicodeString,0x00001234,0,TRUE,&g_Device);

driverObject->DriverUnload;

driverObject->MajorFunction[IRP_MJ_CREATE] = MyOpen;
driverObject->MajorFunction[IRP_MJ_CLOSE] = MyClose;
driverObject->MajorFunction[IRP_MJ_READ] = MyRead;
driverObject->MajorFunction[IRP_MJ_WRITE] = MyWrite;
driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyIOControl;

if(NT_SUCCESS(ntStatus))
{
DbgPrint("Wszytsko oK");
}
return ntStatus;

}
[/code]



Bez obsługi IRP_MJ_CREATE - funkcja NtCreateFile zwracała NtStatus < 0
Animalpak
user
 
Posty: 3
Dołączył(a): So gru 15, 2012 6:25
Podziękował: 1 razy
Podziękowano: 0 razy
Reputacja: 1

Ah, zgadza się. Przyznaję, że (bezpodstawnie ;p) założyłem, że wkleiłeś tylko fragment funkcji.

Anyways, rzuć też okiem na IOCTLe - trochę wygodniejsza (moim zdaniem) metoda komunikacji z driverem niż używając Read/Write.
(jako przykład użycia możesz rzucić okiem np. na kod http://gynvael.coldwind.pl/download.php ... .5-rc2.zip)

W skrócie, różnica polega na tym, że Read/Write są strumieniowe (czyli de facto operujesz na strumieniu danych), natomiast IOCTLe przypominają bardziej pakiety (czyli nie musisz się martwić że dostałeś tylko połowę danych w strumieniu, etc).
[color=#0080FF]gynvael.coldwind[/color]//[color=#00FF00]vx[/color]
http://gynvael.coldwind.pl
Gynvael Coldwind
Przyjaciel
Avatar użytkownika
Posty: 1633
Dołączył(a): N lip 25, 2004 17:08
Podziękował: 53 razy
Podziękowano: 184 razy
Reputacja: 23041

Powrót do Programowanie

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość

cron