/* 驅動SYS irp1.h */
#include <ntddk.h>
/*采用緩沖區內存模式IOCTL,
MY_DVC_BUFFERED_CODE是自定義的控制碼*/
#define MY_DVC_BUFFERED_CODE /
(ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, /
0x900, /
METHOD_BUFFERED, /
FILE_ANY_ACCESS)
//---------函數聲明---------
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING registryPath);
NTSTATUS
MyDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
MyCreateClose(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
VOID
MyDriverOnUnload(IN PDRIVER_OBJECT DriverObject);
//-------------------------
/* 驅動SYS irp1.c */
#include "irp1.h"
//------------驅動入口----------
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING registryPath )
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT Device;
UNICODE_STRING DeviceName, DeviceLink; //設備名,符號鏈接名
DbgPrint("[Aliwy] DriverEntry/n");
RtlInitUnicodeString(&DeviceName, L"//Device//Aliwy"); //初始化設備名
RtlInitUnicodeString(&DeviceLink, L"//DosDevices//IamAliwy"); //初始化符號鏈接名
/* IoCreateDevice 生成設備對象 */
ntStatus = IoCreateDevice(DriverObject, //生成設備的驅動對象
0, //設備擴展區內存大小
&DeviceName, //設備名,/Device/Aliwy
FILE_DEVICE_UNKNOWN, //設備類型
0, //填寫0即可
FALSE, //必須為FALSE
&Device); //設備對象指針返回到DeviceObject中
if (!NT_SUCCESS(ntStatus))
{
DbgPrint("[Aliwy] IoCreateDevice FALSE: %.8X/n", ntStatus);
return ntStatus; //生成失敗就返回
}
else
DbgPrint("[Aliwy] IoCreateDevice SUCCESS/n");
/* IoCreateSymbolicLink 生成符號鏈接 */
ntStatus = IoCreateSymbolicLink(&DeviceLink, &DeviceName);
if (!NT_SUCCESS(ntStatus))
{
DbgPrint("[Aliwy] IoCreateSymbolicLink FALSE: %.8X/n", ntStatus);
IoDeleteDevice(Device); //刪除設備
return ntStatus;
}
else
DbgPrint("[Aliwy] IoCreateSymbolicLink SUCCESS/n");
Device->Flags &= ~DO_DEVICE_INITIALIZING; //設備初始化完成標記
DriverObject->DriverUnload = MyDriverOnUnload;
/*設備控制請求,對應Ring3 DeviceIoControl*/
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDeviceIoControl;
/*設備打開請求,對應Ring3 CreateFile*/ //
DriverObject->MajorFunction[IRP_MJ_CREATE] = MyCreateClose; // 要與應用層通信,
/*設備關閉請求,對應Ring3 CloseHandle*/ // 必須有打開、關閉請求!
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyCreateClose; //
return ntStatus;
}
//------------------------------
//---------設備請求處理---------
NTSTATUS MyDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
PIO_STACK_LOCATION irpSp; //當前IRP調用棧空間
ULONG code; //功能號
NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG inBufLength; //輸入緩沖區長度
ULONG outBufLength; //輸出緩沖區長度
PCHAR inBuf; //輸入緩沖區
PCHAR outBuf; //輸出緩沖區
PCHAR outData = "[Aliwy] outBuf: This String is from Driver !!!"; //要向應用層輸出的信息
ULONG outDataLen = strlen(outData) + 1; //信息長度含結尾一個NULL
DbgPrint("[Aliwy] MyDeviceIoControl/n");
irpSp = IoGetCurrentIrpStackLocation(Irp); //獲得當前IRP調用棧空間
code = irpSp->Parameters.DeviceIoControl.IoControlCode; //得到功能號,即控制碼
inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; //得到輸入緩沖區長度
outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; //得到輸出緩沖區長度
inBuf = Irp->AssociatedIrp.SystemBuffer; //輸入緩沖區
outBuf = Irp->AssociatedIrp.SystemBuffer; //輸出緩沖區
if (code == MY_DVC_BUFFERED_CODE) //我們自定義的控制碼
{
DbgPrint("[Aliwy] inBuf: %s/n", inBuf); //打印出應用層傳入的內容
RtlCopyBytes(outBuf, outData, outBufLength); //復制我們要傳入的內容到輸出緩沖區
Irp->IoStatus.Information = (outBufLength < outDataLen ? outBufLength : outDataLen);
Irp->IoStatus.Status = STATUS_SUCCESS;
}
else
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
IoCompleteRequest(Irp, IO_NO_INCREMENT); //結束IRP請求
DbgPrint("[Aliwy] MyDeviceIoControl Over/n");
return Irp->IoStatus.Status;
}
//------------------------------
//----------打開關閉------------
NTSTATUS MyCreateClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
DbgPrint("[Aliwy] MyCreateClose/n");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
//------------------------------
//----------驅動卸載------------
VOID MyDriverOnUnload( IN PDRIVER_OBJECT DriverObject )
{
UNICODE_STRING DeviceLink; //符號鏈接名
DbgPrint("[Aliwy] MyDriverOnUnload/n");
RtlInitUnicodeString(&DeviceLink, L"//DosDevices//IamAliwy");
IoDeleteSymbolicLink(&DeviceLink); //刪除符號鏈接
if (DriverObject->DeviceObject != NULL)
{
IoDeleteDevice(DriverObject->DeviceObject); //刪除設備
}
}
//------------------------------
/* 應用層EXE irp1.cpp */
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
/*采用緩沖區內存模式IOCTL,MY_DVC_IN_CODE是自定義的控制碼*/
#define MY_DVC_BUFFERED_CODE /
(ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, /
0x900, /
METHOD_BUFFERED, /
FILE_ANY_ACCESS)
void main()
{
ULONG bytesReturned;
char inBuf[50] = "This String is from User !!!"; //傳入驅動的內容
char outBuf[50]; //用於接收驅動傳出內容的緩沖區
/*打開設備,用我們自定的符號鏈接,響應驅動IRP_MJ_CREATE*/
HANDLE hDevice = CreateFile("////.//IamAliwy",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("設備打開失敗 %d %.8x/n", GetLastError(), hDevice);
return;
}
memset(outBuf, 0, sizeof(outBuf));
/*控制設備,響應驅動IRP_MJ_DEVICE_CONTROL*/
BOOL ret = DeviceIoControl(hDevice,
MY_DVC_BUFFERED_CODE, //我們自定義的功能號
&inBuf, //傳入驅動的內容
strlen(inBuf) + 1, //傳入內容長度
&outBuf, //驅動輸出的緩沖區
sizeof(outBuf), //驅動輸出緩沖區大小
&bytesReturned, //返回的長度
NULL);
if (!ret)
{
printf("Error in DeviceIoControl: %d", GetLastError());
}
else
printf("%s(%d)/n", outBuf, bytesReturned); //打印驅動傳給我們的內容
/*關閉設備,對應驅動IRP_MJ_CLOSE*/
CloseHandle(hDevice);
}
