Открыть устройство с помощью ZwCreateFile

Как открыть устройство через функции Native API




Для получения хэндла устройства используется функция ZwCreateFile (её аналогом в пользовательском режиме является NtCreateFile).

В качестве имени устройства этой функции нельзя указывать пользовательские символические ссылки (то есть «C:\», как для функции CreateFile, указать нельзя). Нужно указывать имя устройства в native-формате. Однако, «родное» наименование даже одних и тех же устройств в разных системах может быть различным (например, в Windows NT 4 устройство «\Device\Harddisk0\Partition1» соответствует «\Device\HarddiskVolume1» в Windows 2000). Для получения имени устройства в native-формате по его «пользовательскому» имени (в этом конкретном случае имелся в виду обычный первый раздел на первом жестом диске, чаще всего имеющий имя «C:») и для работы с такими именами вообще имеются функции RtlDosPathNameToNtPathName_U, RtlDetermineDosPathNameType_U и еще несколько функций.

Если процесс получения правильного имени рассмотреть шире, немаловажное значение имеет параметр Attributes структуры OBJECT_ATTRIBUTES (значение остальных параметров вроде бы очевидно). Советую обратить внимание на возможные значения этого параметра, задаваемые флагами, хотя, непосредственное влияние на обработку передаваемого имени оказывает только флаг OBJ_CASE_INSENSITIVE. Назначение флагов более или менее очевидно из их названий, кроме того, не все объекты поддерживают весь набор этих флагов (чаще наоборот).

Приведу пример открытия устройства «\Device\Tcp» (для самых разных операций). В этом коде следует обратить внимание на константу FILE_OPEN.

WCHAR szDeviceName[] = L"\\Device\\Tcp";
UNICODE_STRING us;
OBJECT_ATTRIBUTES oa = {sizeof(OBJECT_ATTRIBUTES), NULL, &us};
HANDLE hDevice;
IO_STATUS_BLOCK iosb;

us.Buffer = szDeviceName;
us.Length = wcslen(szDeviceName) * sizeof(WCHAR);
us.MaximumLength = us.Length + sizeof(WCHAR);

NTSTATUS ns = ZwCreateFile (&hDevice, MAXIMUM_ALLOWED, &oa, &iosb,
  NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0);

После окончания работы с устройством, когда HANDLE на него уже больше не нужен, его необходимо закрыть с помощью функции ZwClose. Её использование представляется тривиальным, и нет необходимости его описывать. Следует отметить, что с учетом природы хэндлов, после выполнения этой функции описатель, переданный в неё, может быть как не валидным вовсе, так и соответствовать уже совсем другому устройству.



Автор: Сергей Васкецов (ntprog.by.ru)
Дата: 29.10.2002


При копировании материалов хорошим тоном будет указание авторства и ссылка на сайт.