Chinaunix首页 | 论坛 | 博客
  • 博客访问: 309050
  • 博文数量: 48
  • 博客积分: 2635
  • 博客等级: 少校
  • 技术积分: 495
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-16 18:07
个人简介

软件开发领域都关心。

文章分类

全部博文(48)

文章存档

2013年(1)

2012年(1)

2011年(4)

2010年(3)

2009年(4)

2008年(7)

2007年(13)

2006年(3)

2005年(12)

分类: WINDOWS

2007-10-05 23:19:47

 

操作系统在初始化驱动程序的时候会调用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) |
给主人留下些什么吧!~~