xuehaipiaoxiang
驱动牛犊
驱动牛犊
  • 注册日期2006-10-11
  • 最后登录2013-02-01
  • 粉丝0
  • 关注0
  • 积分250分
  • 威望273点
  • 贡献值0点
  • 好评度22点
  • 原创分4分
  • 专家分0分
阅读:2300回复:0

Regmon(2)

楼主#
更多 发布于:2007-05-18 05:46
if(NT_SUCCESS(ntStatus))
{
    创建符号连接,以便GUI能够指名,访问这个驱动/设备
    创建每个需要处理的方法的分发点
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =
    DriverObject->MajorFunction[IRP_MJ_CREATE] =
    DriverObject->MajorFunction[IRP_MJ_CLOSE] =
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RegmonDispatch;
#if DBG
    DriverObject->DriverUnload = RegmonUnload;
#end if
}

if(!NT_SUCCESS(ntStatus))
{
    DbgPrint((“Regmon: Failed  to create our device!\n”));
    发生错误,清理环境(资源等)
    if(GUIDevice) IoDeleteDevice(GUIDevice);
    IoDeleteSymbolicLink(&deviceLinkUnicodeString);
    return ntStatus;
}

初始化互斥量
MUTEX_INIT(StoreMutex);
MUTEX_INIT(HashMutex);
MUTEX_INIT(FilterMutex);

初始化根键长度
for(I = 0; I < NUMROOTKEYS; I ++)
{
    RootKey[I].RootNameLen = strlen(RootKey[I].RootName;
}
for(I = 0; I < 2; I ++)
{
    CurrentUser[I].RootNameLen = strlen(CurrentUser[I].RootName;
}

系统表数据结构指针,一个NTOSKRNL导出
ServiceTable = KeServiceDescriptorTable;    用户自定义的结构
DbgPrint((“HookRegistry:Servicetable:%x\n”, ServiceTable));
获取进程名称的偏移
ProcessNameOffset = GetProcessNameOffset(); 这个函数是牛人自己写的。

分配初始化的输出缓冲区
Store = ExAllocatePool(PagePool, sizeof(*Store));
if(!Store)
{
    IoDeleteDevice(GUIDevice);
    IoDeleteSymbolicLink(&deviceLinkUnicodeString);
    return STATUS_INSUFFICENT_RESOURCES;
}
Store->Len = 0;
Store->Next = NULL;
NumStore = 1;

如果我们是个启动设备则开始记日志
if(startType != SERVICE_DEMAND_START)
{
    初始化日志
    BoolLogging = TRUE;

    KeInitializeEvent(&LoggingEvent, SynchronizationEvent, FALSE);
    GUIActive = TRUE;
    Fileltet = BootFilter;
    RegmonUpdateFilters();
    HookRegisters();

    告诉用户,日志模式已经开启
    RtlInitUnicodeString(&bootMessageUnicodeString, bootMessage);
ZwDisplayString(&bootMessageUnicodeString);

注册关闭通知
IoRegisterShutdonwNotification注册一个驱动提供的系统关闭通知函数,在系统被完全关闭之前调用。
IoRegisterShutdown Notification(GUIDevice);

}
    return STATUS_SUCCESS;
}








RegmonDispatch
这个函数处理设备的请求。需要显示处理的请求来自GUI。当然,当GUI建立,关闭合驱动的通信时,也需要处理Create,Close。
NTSTAUTS RegmonDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PIO_STACK_LOCATION irpStack;    当前堆栈
    PVOID inputBuffer;
    PVOID outputBuffer;
    ULONG inputBufferLength;
    ULONG outputBufferLength;
    ULONG ioControlCode;
    PSTORE_BUF old;
    WORK_QUEUE_ITEM workItem;

    设置处理成功
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    
    获取Irp中当前位置的指针,这就是代码和参数定位的地方
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    inputBuffer = Irp->AssociatedIrp.SystemBuffer;
    inputBufferLength = iprStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBuffer = Irp->AssociatedIrp.SystemBuffer;
    outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

    switch(irpStack->MajorFunction)
{
    case IRP_MJ_CREATE:
        DbgPrint((“Regmon: IRP_MJ_CREATE\n”));
        关闭启动日志
        if(BootLogging)
        {
            BootLogging = FALSE;
            IoUnregisterShutdownNotification(DeviceObject);
            MUTEX_WAIT(StoreMutex);
            ExInitializeWorkItem(&workItem, RegmonCloseBootLog, 0);    
这个函数已经过期,应该使用IoAllocateWorkItem。返回一个指向私有结构IO_WORKITEM的指针。驱动不应该以任何形式访问这个结构!
            ExQueueWorkItem(&workItem, CriticalWorkQueue);
            这个函数也过期了,应该使用IoQueueWorkItem。插入一个指定的工作项到队列中,这个队列由系统工作线程访问,系统工作线程从队列中移出一个工作项,并调用其中的回调函数。
            KeWaitForSingleObject(&LoggingEvent, Executive, KernelMode, FALSE, NULL);
            MUTEX_RELEASE(StoreMutex);
        }
        Sequence = 0;
        GUIActive = TRUE;
        DbgPrint((“GUI Active: %d\n”, GUIActive));
        break;
    }
}
游客

返回顶部