#include <windows.h>
#include <stdio.h>
int main()
{
HANDLE hDevice =
CreateFile(L"\\\\.\\HelloDDKB",
GENERIC_READ | GENERIC_WRITE,
0, // share mode none
NULL, // no security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL ); // no template
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("Failed to obtain file handle to device "
"with Win32 error code: %d\n",
GetLastError() );
return 1;
}
DWORD dRet;
ReadFile(hDevice,NULL,0,&dRet,NULL);
system("pause");
CloseHandle(hDevice);
return 0;
}
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")
#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName; //裝置名稱
UNICODE_STRING ustrSymLinkName; //符号連結名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
// 函數聲明
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);
NTSTATUS HelloDDKCreate(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);
NTSTATUS HelloDDKClose(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) ;
#include "Driver.h"
/************************************************************************
* 函數名稱:DriverEntry
* 功能描述:初始化驅動程式,定位和申請硬體資源,建立核心對象
* 參數清單:
pDriverObject:從I/O管理器中傳進來的驅動對象
pRegistryPath:驅動程式在系統資料庫的中的路徑
* 傳回 值:傳回初始化驅動狀态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath )
{
NTSTATUS ntStatus;
KdPrint(("DriverB:Enter B DriverEntry\n"));
//注冊其他驅動調用函數入口
pDriverObject->DriverUnload = HelloDDKUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKCreate;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKClose;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;
//建立驅動裝置對象
ntStatus = CreateDevice(pDriverObject);
KdPrint(("DriverB:Leave B DriverEntry\n"));
return ntStatus;
}
/************************************************************************
* 函數名稱:CreateDevice
* 功能描述:初始化裝置對象
* 參數清單:
pDriverObject:從I/O管理器中傳進來的驅動對象
* 傳回 值:傳回初始化狀态
*************************************************************************/
#pragma INITCODE
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS ntStatus;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
//建立裝置名稱
UNICODE_STRING devName;
RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevicB");
//建立裝置
ntStatus = IoCreateDevice( pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0, TRUE,&pDevObj );
if (!NT_SUCCESS(ntStatus))
return ntStatus;
pDevObj->Flags |= DO_BUFFERED_IO;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->ustrDeviceName = devName;
//建立符号連結
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDKB");
pDevExt->ustrSymLinkName = symLinkName;
NTSTATUS status = IoCreateSymbolicLink( &symLinkName,&devName );
if (!NT_SUCCESS(status))
{
IoDeleteDevice( pDevObj );
return status;
}
return STATUS_SUCCESS;
}
/************************************************************************
* 函數名稱:HelloDDKUnload
* 功能描述:負責驅動程式的解除安裝操作
* 參數清單:
pDriverObject:驅動對象
* 傳回 值:傳回狀态
*************************************************************************/
#pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
KdPrint(("DriverB:Enter B DriverUnload\n"));
pNextObj = pDriverObject->DeviceObject;
//while (pNextObj != NULL)
//{
// PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
// pNextObj->DeviceExtension;
// //删除符号連結
// UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
// IoDeleteSymbolicLink(&pLinkName);
// pNextObj = pNextObj->NextDevice;
// IoDeleteDevice( pDevExt->pDevice );
//}
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDKB");
pNextObj = pDriverObject->DeviceObject;//我的第一個裝置
IoDeleteSymbolicLink(&symLinkName);//删除符号連接配接
IoDeleteDevice(pDriverObject->DeviceObject);//删除裝置
KdPrint(("DriverB:Enter B DriverUnload\n"));
}
#pragma PAGEDCODE
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
//KdPrint(("DriverB:Enter B HelloDDKRead\n"));
KdPrint(("進入了驅動B的讀曆程"));
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING DeviceName;
RtlInitUnicodeString( &DeviceName, L"\\Device\\MyDDKDeviceA" );
//初始化objectAttributes
OBJECT_ATTRIBUTES objectAttributes;
InitializeObjectAttributes(&objectAttributes, &DeviceName,OBJ_CASE_INSENSITIVE, NULL, NULL );
HANDLE hDevice;
IO_STATUS_BLOCK status_block;
//設定了FILE_SYNCHRONOUS_IO_NONALERT或者FILE_SYNCHRONOUS_IO_ALERT為同步打開裝置
ntStatus = ZwCreateFile(&hDevice, //同步打開裝置
FILE_READ_ATTRIBUTES|SYNCHRONIZE,&objectAttributes,&status_block,
NULL,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,
FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);
if (NT_SUCCESS(ntStatus))
{
ZwReadFile(hDevice,NULL,NULL,NULL,&status_block,NULL,0,NULL,NULL);//同步讀裝置
}
ZwClose(hDevice);
// 完成IRP
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
//KdPrint(("DriverB:Leave B HelloDDKRead\n"));
return ntStatus;
}
/************************************************************************
* 函數名稱:HelloDDKDispatchRoutine
* 功能描述:對讀IRP進行處理
* 參數清單:
pDevObj:功能裝置對象
pIrp:從IO請求包
* 傳回 值:傳回狀态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("DriverB:Enter B HelloDDKDispatchRoutine\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverB:Leave B HelloDDKDispatchRoutine\n"));
return ntStatus;
}
#pragma PAGEDCODE
NTSTATUS HelloDDKCreate(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("DriverB:Enter B HelloDDKCreate\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverB:Leave B HelloDDKCreate\n"));
return ntStatus;
}
#pragma PAGEDCODE
NTSTATUS HelloDDKClose(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("DriverB:Enter B HelloDDKClose\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
// 完成IRP
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverB:Leave B HelloDDKClose\n"));
return ntStatus;
}
/************************************************************************
* 檔案名稱:Driver.h
* 作 者:張帆
* 完成日期:2007-11-1
*************************************************************************/
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")
#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName; //裝置名稱
UNICODE_STRING ustrSymLinkName; //符号連結名
KDPC pollingDPC; // 存儲DPC對象
KTIMER pollingTimer;// 存儲計時器對象
PIRP currentPendingIRP;//記錄目前挂起的IRP
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
// 函數聲明
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp);
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp);
NTSTATUS HelloDDKCreate(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp);
NTSTATUS HelloDDKClose(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp) ;
#include "Driver.h"
/************************************************************************
* 函數名稱:DriverEntry
* 功能描述:初始化驅動程式,定位和申請硬體資源,建立核心對象
* 參數清單:
pDriverObject:從I/O管理器中傳進來的驅動對象
pRegistryPath:驅動程式在系統資料庫的中的路徑
* 傳回 值:傳回初始化驅動狀态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath)
{
NTSTATUS status;
KdPrint(("DriverA:Enter A DriverEntry\n"));
//注冊其他驅動調用函數入口
pDriverObject->DriverUnload = HelloDDKUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKCreate;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKClose;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;
//建立驅動裝置對象
status = CreateDevice(pDriverObject);
KdPrint(("DriverA:Leave A DriverEntry\n"));
return status;
}
#pragma LOCKEDCODE
VOID OnTimerDpc( IN PKDPC pDpc,IN PVOID pContext,IN PVOID SysArg1,IN PVOID SysArg2 )
{
PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)pContext;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
PIRP currentPendingIRP = pdx->currentPendingIRP;
//KdPrint(("DriverA:complete the Driver A IRP_MJ_READ irp!\n"));
KdPrint(("進入的DPC定時曆程"));
//設定完成狀态為STATUS_CANCELLED
currentPendingIRP->IoStatus.Status = STATUS_SUCCESS;
currentPendingIRP->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( currentPendingIRP, IO_NO_INCREMENT );
}
/************************************************************************
* 函數名稱:CreateDevice
* 功能描述:初始化裝置對象
* 參數清單:
pDriverObject:從I/O管理器中傳進來的驅動對象
* 傳回 值:傳回初始化狀态
*************************************************************************/
#pragma INITCODE
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
//建立裝置名稱
UNICODE_STRING devName;
RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDeviceA");
//建立裝置
status = IoCreateDevice( pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0, TRUE,&pDevObj );
if (!NT_SUCCESS(status))
return status;
pDevObj->Flags |= DO_BUFFERED_IO;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->ustrDeviceName = devName;
KeInitializeTimer( &pDevExt->pollingTimer );
KeInitializeDpc( &pDevExt->pollingDPC,OnTimerDpc,(PVOID) pDevObj );
//建立符号連結
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDKA");
pDevExt->ustrSymLinkName = symLinkName;
status = IoCreateSymbolicLink( &symLinkName,&devName );
if (!NT_SUCCESS(status))
{
IoDeleteDevice( pDevObj );
return status;
}
return STATUS_SUCCESS;
}
/************************************************************************
* 函數名稱:HelloDDKUnload
* 功能描述:負責驅動程式的解除安裝操作
* 參數清單:
pDriverObject:驅動對象
* 傳回 值:傳回狀态
*************************************************************************/
#pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
KdPrint(("DriverA:Enter A DriverUnload\n"));
pNextObj = pDriverObject->DeviceObject;
//while (pNextObj != NULL)
//{
// PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
// pNextObj->DeviceExtension;
// //删除符号連結
// UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
// IoDeleteSymbolicLink(&pLinkName);
// pNextObj = pNextObj->NextDevice;
// IoDeleteDevice( pDevExt->pDevice );
//}
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDKA");
pNextObj = pDriverObject->DeviceObject;//我的第一個裝置
IoDeleteSymbolicLink(&symLinkName);//删除符号連接配接
IoDeleteDevice(pDriverObject->DeviceObject);//删除裝置
KdPrint(("DriverA:Leave A DriverUnload\n"));
}
/************************************************************************
* 函數名稱:HelloDDKRead
* 功能描述:對讀IRP進行處理
* 參數清單:
pDevObj:功能裝置對象
pIrp:從IO請求包
* 傳回 值:傳回狀态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
//KdPrint(("DriverA:Enter A HelloDDKRead\n"));
KdPrint(("進入了驅動A的讀曆程"));
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
//将IRP設定為挂起
IoMarkIrpPending(pIrp);
//将挂起的IRP記錄下來
pDevExt->currentPendingIRP = pIrp;
//定義3秒後将IRP_MJ_READ的IRP完成
ULONG ulMicroSecond = 3000000;
//将32位整數轉化成64位整數
LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10*ulMicroSecond);
KeSetTimer(&pDevExt->pollingTimer,timeout,&pDevExt->pollingDPC );
//KdPrint(("DriverA:Leave A HelloDDKRead\n"));
//傳回pending狀态
KdPrint(("驅動A的API定時執行完畢 驅動A的讀曆程完畢"));
return STATUS_PENDING;
}
/************************************************************************
* 函數名稱:HelloDDKDispatchRoutine
* 功能描述:對讀IRP進行處理
* 參數清單:
pDevObj:功能裝置對象
pIrp:從IO請求包
* 傳回 值:傳回狀态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("DriverA:Enter A HelloDDKDispatchRoutine\n"));
NTSTATUS status = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverA:Leave A HelloDDKDispatchRoutine\n"));
return status;
}
#pragma PAGEDCODE
NTSTATUS HelloDDKCreate(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("DriverA:Enter A HelloDDKCreate\n"));
NTSTATUS status = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverA:Leave A HelloDDKCreate\n"));
return status;
}
#pragma PAGEDCODE
NTSTATUS HelloDDKClose(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("DriverA:Enter A HelloDDKClose\n"));
NTSTATUS status = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverA:Leave A HelloDDKClose\n"));
return status;
}