操作系统在初始化驱动程序的时候会调用DriverEntry,通常会用这个函数来填充dispatch例程的指针,这就象注册回调函数一样。有的设备要创建设备的对象,或者还要创建一个设备名字,以及其他的初始化操作。它的原型:
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ){ }
|
IN,OUT,INOUT是一个空的宏,只是用来说明这个参数是用于输入参数,还是输出的参数。NTSTATUS实际是个长整型可以在DDK头文件NTSTATUS.H中找到NTSTATUS的代码列表。函数的第一个参数DriverObject是刚被初始化的驱动对象,就是操作系统为这个驱动分配的空间的指针。函数的第二个参数RegistryPath是驱动在注册表中的键值。如果驱动程序需要访问设备的服务键需要保存这个键值以备后用。
本章使用的例子驱动是DDK自带的ioctrl代码。代码位于src\general\ioctl\sys。
NTSTATUS DriverEntry( IN OUT PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) /*++
Routine Description: This routine is called by the Operating System to initialize the driver.
It creates the device object, fills in the dispatch entry points and completes the initialization.
Arguments: DriverObject - a pointer to the object that represents this device driver.
RegistryPath - a pointer to our Services key in the registry.
Return Value: STATUS_SUCCESS if initialized; an error otherwise.
--*/
{ NTSTATUS ntStatus; UNICODE_STRING ntUnicodeString; // NT Device Name "\Device\SIOCTL"
UNICODE_STRING ntWin32NameString; // Win32 Name "\DosDevices\IoctlTest"
PDEVICE_OBJECT deviceObject = NULL; // ptr to device object
RtlInitUnicodeString( &ntUnicodeString, NT_DEVICE_NAME ); ntStatus = IoCreateDevice( DriverObject, // Our Driver Object
0, // We don't use a device extension
&ntUnicodeString, // Device name "\Device\SIOCTL"
FILE_DEVICE_UNKNOWN, // Device type
FILE_DEVICE_SECURE_OPEN, // Device characteristics
FALSE, // Not an exclusive device
&deviceObject ); // Returned ptr to Device Object
if ( !NT_SUCCESS( ntStatus ) ) { SIOCTL_KDPRINT(("Couldn't create the device object\n")); return ntStatus; } //
// Initialize the driver object with this driver's entry points.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = SioctlCreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = SioctlCreateClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SioctlDeviceControl; DriverObject->DriverUnload = SioctlUnloadDriver; //
// Initialize a Unicode String containing the Win32 name
// for our device.
//
RtlInitUnicodeString( &ntWin32NameString, DOS_DEVICE_NAME );
//
// Create a symbolic link between our device name and the Win32 name
//
ntStatus = IoCreateSymbolicLink( &ntWin32NameString, &ntUnicodeString );
if ( !NT_SUCCESS( ntStatus ) ) { //
// Delete everything that this routine has allocated.
//
SIOCTL_KDPRINT(("Couldn't create symbolic link\n")); IoDeleteDevice( deviceObject ); }
return ntStatus; }
|
这是一个非常规范的例子,函数首先构造了设备对象,这里并没有把设备对象扩展来存储驱动特需的东西。NT设备名字是"\Device\SIOCTL"。然后填充了派发函数的指针。然后创建了一个设备名字的符号链接。这样这个设备就是命名了的设备,上层应用可以通过打开这个符号链接,从而获得设备handle来访问这个驱动。这里的符号链接是"\DosDevice\IoctlTest",上层应用要想访问这个设备只需要调用CreateFile就可得到这个设备的句柄。如下代码所示:
//
// open the device
//
if((hDevice = CreateFile( "\\\\.\\IoctlTest", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { //error to open device
}else{ //good get it,:)
}
|
阅读(8020) | 评论(0) | 转发(0) |