首页 > win7x64简单测试驱动程序报“...访问冲突”错误

win7x64简单测试驱动程序报“...访问冲突”错误

在win7 x64 平台上编写驱动程序:

我有如下几个文件:
dbsmsg.h:

#ifdef LOG_OFF
#define DBG_TRACE(src,msg)
#define DBG_PRINT1(arg1)
#define DBG_PRINT2(fmt,arg1)
#define DBG_PRINT3(fmt,arg1,arg2)
#define DBG_PRINT4(fmt,arg1,arg2,arg3)
#else
#define DBG_TRACE(src,msg)    DbgPrint("[%s]:%s\n",src,msg)
#define DBG_PRINT1(arg1)    DbgPrint("%s",arg1)
#define DBG_PRINT2(fmt,arg1)    DbgPrint(fmt,arg1)
#define DBG_PRINT3(fmt,arg1,arg2)    DbgPrint(fmt,arg1,arg2)
#define DBG_PRINT4(fmt,arg1,arg2,arg3)    DbgPrint(fmt,arg1,arg2,arg3)
#endif

ctrlcode.h:

#define FILE_DEVICE_RK 0x00008001
#define IOCTL_TEST_CMD \
    CTL_CODE(FILE_DEVICE_RK, 0x801, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)

device.h:

#include "ntddk.h"
const WCHAR DeviceNameBuffer[] = L"\\Device\\msnetdiag";
const WCHAR DeviceLinkBuffer[] = L"\\DosDevices\\msnetdiag";
const char UserlandPath[]      = "\\\\.\\msnetdiag";

kmd.c:

#include "ntddk.h"

#include "dbgmsg.h"
#include "ctrlcode.h"
#include "device.h"


/* MSNetDigaDeviceObject代表我们创建的设备 */
PDEVICE_OBJECT MSNetDiagDeviceObject;
/* DriverObjectRef代表我们注册的驱动 */
PDRIVER_OBJECT DriverObjectRef;


void TestCommand(PVOID inputBuffer, PVOID outputBuffer, ULONG inputBufferLength, ULONG outputBufferLength);
NTSTATUS defaultDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS dispatchIOControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);


NTSTATUS RegisterDriverDeviceName(IN PDRIVER_OBJECT DriverObject);
NTSTATUS RegisterDriverDeviceLink();

VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
    PDEVICE_OBJECT pdeviceObj;
    UNICODE_STRING unicodeString;
    DBG_TRACE("OnUnload","Received signal to unload the driver");
    pdeviceObj = (*DriverObject).DeviceObject;
    if(pdeviceObj != NULL)
    {
        DBG_TRACE("OnUnload","Unregistering driver's symbolic link");
        RtlInitUnicodeString(&unicodeString, DeviceLinkBuffer);
        IoDeleteSymbolicLink(&unicodeString);
        DBG_TRACE("OnUnload","Unregistering driver's device name");
        IoDeleteDevice((*DriverObject).DeviceObject);
    }
    return ;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    int i;
    NTSTATUS ntStatus;
    DBG_TRACE("Driver Entry","Driver has benn loaded");
    for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
    {
        (*DriverObject).MajorFunction[i] = defaultDispatch;
    }
    (*DriverObject).MajorFunction[IRP_MJ_DEVICE_CONTROL] = dispatchIOControl;
    (*DriverObject).DriverUnload = Unload;

    DBG_TRACE("Driver Entry","Registering driver's device name");
    ntStatus = RegisterDriverDeviceName(DriverObject);
    if(!NT_SUCCESS(ntStatus))
    {
        DBG_TRACE("Driver Entry","Failed to create device");
        return ntStatus;
    }

    DBG_TRACE("Driver Entry","Registering driver's symbolic link");
    if(!NT_SUCCESS(ntStatus))
    {
        DBG_TRACE("Driver Entry","Failed to create symbolic link");
        return ntStatus;
    }
    DriverObjectRef = DriverObject;
    return STATUS_SUCCESS;
}

NTSTATUS defaultDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRP)
{
    ((*IRP).IoStatus).Status = STATUS_SUCCESS;
    ((*IRP).IoStatus).Information = 0;
    /*
     The IoCompleteRequest routine indicates that the caller has 
     completed all processing for a given I/O request and is 
     returning the given IRP to the I/O manager.
    */
    IoCompleteRequest(IRP, IO_NO_INCREMENT);
    return (STATUS_SUCCESS);
}

//
// NtDeviceIoControlFile 参数
//
struct
{
    ULONG OutputBufferLength;
    ULONG POINTER_ALIGNMENT InputBufferLength;
    ULONG POINTER_ALIGNMENT IoControlCode;
    PVOID Type3InputBuffer;
} DeviceIoControl;

NTSTATUS dispatchIOControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP IRP)
{
    PIO_STACK_LOCATION irpStack;
    PVOID inputBuffer;
    PVOID outputBuffer;
    ULONG inBufferLength;
    ULONG outBufferLength;
    ULONG ioctrlcode;
    NTSTATUS ntStatus;
    ntStatus = STATUS_SUCCESS;
    ((*IRP).IoStatus).Status = STATUS_SUCCESS;
    ((*IRP).IoStatus).Information = 0;
    inputBuffer = (*IRP).AssociatedIrp.SystemBuffer;
    outputBuffer = (*IRP).AssociatedIrp.SystemBuffer;
    irpStack = IoGetCurrentIrpStackLocation(IRP);
    inBufferLength = (*irpStack).Parameters.DeviceIoControl.InputBufferLength;
    outBufferLength = (*irpStack).Parameters.DeviceIoControl.OutputBufferLength;
    ioctrlcode = (*irpStack).Parameters.DeviceIoControl.IoControlCode;

    DBG_TRACE("dispatchIOControl","Received a command");
    switch(ioctrlcode)
    {
        case IOCTL_TEST_CMD:
        {
            TestCommand(inputBuffer, outputBuffer, inBufferLength, outBufferLength);
            ((*IRP).IoStatus).Information = outBufferLength;
        }
        break;
        default:
        {
            DBG_TRACE("dispatchIOControl","control code not recognized");
        }
        break;
    }
    /* 在处理完请求后,调用IoCompleteRequest */
    IoCompleteRequest(IRP, IO_NO_INCREMENT);
    return(ntStatus);
}

void TestCommand(PVOID inputBuffer, PVOID outputBuffer, ULONG inputBufferLength, ULONG outputBufferLength)
{
    char *ptrBuffer;
    DBG_TRACE("dispathIOControl","Displaying inputBuffer");
    ptrBuffer = (char*)inputBuffer;
    DBG_PRINT2("[dispatchIOControl]: inputBuffer=%s\n", ptrBuffer);
    DBG_TRACE("dispatchIOControl","Populating outputBuffer");
    ptrBuffer = (char*)outputBuffer;
    ptrBuffer[0] = '!';
    ptrBuffer[1] = '1';
    ptrBuffer[2] = '2';
    ptrBuffer[3] = '3';
    ptrBuffer[4] = '!';
    ptrBuffer[5] = '\0';
    DBG_PRINT2("[dispatchIOControl]:outputBuffer=%s\n", ptrBuffer);
    return;
}

NTSTATUS RegisterDriverDeviceName(IN PDRIVER_OBJECT DriverObject)
{
    NTSTATUS ntStatus;
    UNICODE_STRING unicodeString;
    /* 利用DeviceNameBuffer来初始化unicodeString */
    RtlInitUnicodeString(&unicodeString, DeviceNameBuffer);

    ntStatus = IoCreateDevice
    (
        DriverObject,
        0,
        &unicodeString,
        FILE_DEVICE_RK,
        0,
        TRUE,&MSNetDiagDeviceObject
    );
    return (ntStatus);
}

NTSTATUS RegisterDriverDeviceLink()
{
    NTSTATUS ntStatus;
    UNICODE_STRING unicodeString;
    UNICODE_STRING unicodeLinkString;
    RtlInitUnicodeString(&unicodeString, DeviceNameBuffer);
    RtlInitUnicodeString(&unicodeString, DeviceLinkBuffer);

    ntStatus = IoCreateSymbolicLink(&unicodeLinkString, &unicodeString);
    return (ntStatus);
}

但是每次运行到DriverEntry->RegisterDriverDeviceName->IoCreateDevice就会报:

kmd.sys 中的 0x00000001403aa527 (ntoskrnl.exe) 处有未经处理的异常: 0xC0000005: 读取位置 0x0000000000000001 时发生访问冲突

的错误。请问应该怎么解决啊?

【热门文章】
【热门文章】