原代码如下
#include <ntddk.h>
#define DEVICE_NAME L"\\device\\NTModelDrv"
#define LINK_NAME L"\\dosDevices\\NTModelDrv"
#define IOCTL_BASE 0x8000
#define MY_CTL_CODE(i) \
CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HELLO MY_CTL_CODE(0)
typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName; //设备名称
UNICODE_STRING ustrSymLinkName; //符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
// function to dispatch the IRPs
NTSTATUS DispatchOK(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID DriverUnload (
IN PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink, LINK_NAME);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriverObject->DeviceObject);
DbgPrint("[NTModelDrv] Unloaded\n"); }
NTSTATUS DispatchIoctl(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInSize;
ULONG uOutSize;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode)
{
case IOCTL_HELLO:
{
DbgPrint("[NTModelDrv] Hello\n");
status = STATUS_SUCCESS;
}
break;
}
if(status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;
/
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
//处理应用层的write()函数
NTSTATUS DispatchWrite (
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID userBuffer;
PVOID drvBuffer;
ULONG xferSize;
//获得IRP堆栈的当前位置
PIO_STACK_LOCATION pIrpStack =
IoGetCurrentIrpStackLocation( pIrp );
//获得当前写的长度和缓冲
xferSize = pIrpStack->Parameters.Write.Length;
userBuffer = pIrp->AssociatedIrp.SystemBuffer;
drvBuffer = ExAllocatePoolWithTag(PagedPool, xferSize, 'tseT');
if (drvBuffer == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
xferSize = 0;
}
//将当前缓冲中的数据写入
RtlCopyMemory( drvBuffer, userBuffer, xferSize );
//完成IO,填写完成状态和传输的数据长度
ExFreePool(drvBuffer);
drvBuffer = NULL;
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = xferSize;
//完成IRP,不向下层传递
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
//处理应用层的read()函数
NTSTATUS DispatchRead (
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID userBuffer;
ULONG xferSize;
//获取IRP堆栈的当前位置
PIO_STACK_LOCATION pIrpStack =
IoGetCurrentIrpStackLocation( pIrp );
//获取传输的字节数和缓冲
xferSize = pIrpStack->Parameters.Read.Length;
userBuffer = pIrp->AssociatedIrp.SystemBuffer;
//从驱动中读数据
RtlCopyMemory( userBuffer, L"Hello, world",
xferSize );
//填写IRP中的完成状态,结束IRP操作,不向下层发送
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = xferSize;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{
UNICODE_STRING DeviceName;
UNICODE_STRING LinkName;
NTSTATUS status;
PDEVICE_OBJECT pDriverDeviceObject;
PDEVICE_EXTENSION pDevExt;
ULONG i;
//DbgPrint("Driver loaded.");
pDriverObject->DriverUnload = DriverUnload;
// init strings
RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
RtlInitUnicodeString(&LinkName, LINK_NAME);
// to communicate with usermode, we need a device
status = IoCreateDevice(
pDriverObject, // ptr to caller object
sizeof(DEVICE_EXTENSION), // extension device allocated byte number
&DeviceName, // device name
FILE_DEVICE_UNKNOWN,
0, // no special caracteristics
FALSE, // we can open many handles in same time
&pDriverDeviceObject); // [OUT] ptr to the created object
if ( !NT_SUCCESS(status) )
return STATUS_NO_SUCH_DEVICE;
pDriverDeviceObject-> Flags |= DO_BUFFERED_IO;
pDevExt = (PDEVICE_EXTENSION)pDriverDeviceObject->DeviceExtension;
pDevExt->pDevice = pDriverDeviceObject;
pDevExt->ustrDeviceName = DeviceName;
// we also need a symbolic link
status = IoCreateSymbolicLink(&LinkName,&DeviceName);
if( !NT_SUCCESS(status) )
{
IoDeleteDevice( pDriverDeviceObject );
return STATUS_NO_SUCH_DEVICE;
}
pDevExt->ustrSymLinkName = LinkName;
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
pDriverObject->MajorFunction[i] = DispatchOK;
// handle IRPs
pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
//Do other things...
return STATUS_SUCCESS;
}
上面是真正的框架
下面是测试使用的框架:
#include <ntddk.h>
#define DEVICE_NAME L"\\device\\ntmodeldrv"
#define LINK_NAME L"\\dosdevices\\ntmodeldrv"
#define IOCTRL_BASE 0x800
#define MYIOCTRL_CODE(i) \
CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTRL_BASE+i, METHOD_BUFFERED,FILE_ANY_ACCESS)
#define CTL_HELLO MYIOCTRL_CODE(0)
#define CTL_PRINT MYIOCTRL_CODE(1)
#define CTL_BYE MYIOCTRL_CODE(2)
NTSTATUS DispatchCommon(PDEVICE_OBJECT pObject, PIRP pIrp)
{
pIrp->IoStatus.Status=STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchCreate(PDEVICE_OBJECT pObject, PIRP pIrp)
{
pIrp->IoStatus.Status=STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchRead(PDEVICE_OBJECT pObject, PIRP pIrp)
{
PVOID pReadBuffer = NULL;
ULONG uReadLength = 0;
PIO_STACK_LOCATION pStack = NULL;
ULONG uMin = 0;
ULONG uHelloStr = 0;
uHelloStr = (wcslen(L"hello world")+1)*sizeof(WCHAR);
pReadBuffer = pIrp->AssociatedIrp.SystemBuffer;
pStack = IoGetCurrentIrpStackLocation(pIrp);
uReadLength = pStack->Parameters.Read.Length;
uMin = uReadLength>uHelloStr?uHelloStr:uReadLength;
RtlCopyMemory(pReadBuffer, L"hello world", uMin);
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = uMin;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchWrite(PDEVICE_OBJECT pObject, PIRP pIrp)
{
PVOID pWriteBuff = NULL;
ULONG uWriteLength = 0;
PIO_STACK_LOCATION pStack = NULL;
PVOID pBuffer = NULL;
pWriteBuff = pIrp->AssociatedIrp.SystemBuffer;
pStack = IoGetCurrentIrpStackLocation(pIrp);
uWriteLength = pStack->Parameters.Write.Length;
pBuffer = ExAllocatePoolWithTag(PagedPool, uWriteLength, 'TSET');
if(pBuffer == NULL)
{
pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
}
memset(pBuffer, 0, uWriteLength);
RtlCopyMemory(pBuffer, pWriteBuff, uWriteLength);
ExFreePool(pBuffer);
pBuffer=NULL;
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = uWriteLength;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchIoctrl(PDEVICE_OBJECT pObject, PIRP pIrp)
{
ULONG uIoctrlCode = 0;
PVOID pInputBuff = NULL;
PVOID pOutputBuff = NULL;
ULONG uInputLength = 0;
ULONG uOutputLength = 0;
PIO_STACK_LOCATION pStack = NULL;
pInputBuff = pOutputBuff = pIrp->AssociatedIrp.SystemBuffer;
pStack = IoGetCurrentIrpStackLocation(pIrp);
uInputLength = pStack->Parameters.DeviceIoControl.InputBufferLength;
uOutputLength = pStack->Parameters.DeviceIoControl.OutputBufferLength;
uIoctrlCode = pStack->Parameters.DeviceIoControl.IoControlCode;
switch(uIoctrlCode)
{
case CTL_HELLO:
DbgPrint("Hello iocontrol\n");
break;
case CTL_PRINT:
DbgPrint("%ws\n", pInputBuff);
break;
case CTL_BYE:
DbgPrint("Goodbye iocontrol\n");
break;
default:
DbgPrint("Unknown iocontrol\n");
}
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchClean(PDEVICE_OBJECT pObject, PIRP pIrp)
{
pIrp->IoStatus.Status=STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchClose(PDEVICE_OBJECT pObject, PIRP pIrp)
{
pIrp->IoStatus.Status=STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING uLinkName={0};
RtlInitUnicodeString(&uLinkName, LINK_NAME);
IoDeleteSymbolicLink(&uLinkName);
IoDeleteDevice(pDriverObject->DeviceObject);
DbgPrint("Driver unloaded\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,
PUNICODE_STRING pRegPath)
{
UNICODE_STRING uDeviceName = {0};
UNICODE_STRING uLinkName={0};
NTSTATUS ntStatus = 0;
PDEVICE_OBJECT pDeviceObject = NULL;
ULONG i=0;
DbgPrint("Driver load begin\n");
RtlInitUnicodeString(&uDeviceName, DEVICE_NAME);
RtlInitUnicodeString(&uLinkName,LINK_NAME);
ntStatus = IoCreateDevice(pDriverObject,
0,&uDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&pDeviceObject);
if(!NT_SUCCESS(ntStatus))
{
DbgPrint("IoCreateDevice failed:%x", ntStatus);
return ntStatus;
}
pDeviceObject->Flags |= DO_BUFFERED_IO;
ntStatus = IoCreateSymbolicLink(&uLinkName,&uDeviceName);
if(!NT_SUCCESS(ntStatus))
{
IoDeleteDevice(pDeviceObject);
DbgPrint("IoCreateSymbolicLink failed:%x\n", ntStatus);
return ntStatus;
}
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION+1;i++)
{
pDriverObject->MajorFunction[i] = DispatchCommon;
}
pDriverObject->MajorFunction[IRP_MJ_CREATE]=DispatchCreate;
pDriverObject->MajorFunction[IRP_MJ_READ]=DispatchRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE]=DispatchWrite;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DispatchIoctrl;
pDriverObject->MajorFunction[IRP_MJ_CLEANUP]=DispatchClean;
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=DispatchClose;
pDriverObject->DriverUnload=DriverUnload;
DbgPrint("Driver load ok!\n");
return STATUS_SUCCESS;
}
下面是R3加载驱动和通信代码:
#include <windows.h>
#include <winsvc.h>
#include <conio.h>
#include <stdio.h>
#include <winioctl.h>
#define DRIVER_NAME "ntmodeldrv"
#define DRIVER_PATH ".\\ntmodeldrv.sys"
#define IOCTRL_BASE 0x8000
#define MYIOCTRL_CODE(i) \
CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTRL_BASE+i, METHOD_BUFFERED,FILE_ANY_ACCESS)
#define CTL_HELLO MYIOCTRL_CODE(0)
#define CTL_PRINT MYIOCTRL_CODE(1)
#define CTL_BYE MYIOCTRL_CODE(2)
//装载NT驱动程序
BOOL LoadDriver(char* lpszDriverName,char* lpszDriverPath)
{
//char szDriverImagePath[256] = "D:\\DriverTest\\ntmodelDrv.sys";
char szDriverImagePath[256] = {0};
//得到完整的驱动路径
GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);
BOOL bRet = FALSE;
SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄
//打开服务控制管理器
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if( hServiceMgr == NULL )
{
//OpenSCManager失败
printf( "OpenSCManager() Failed %d ! \n", GetLastError() );
bRet = FALSE;
goto BeforeLeave;
}
else
{
OpenSCManager成功
printf( "OpenSCManager() ok ! \n" );
}
//创建驱动所对应的服务
hServiceDDK = CreateService( hServiceMgr,
lpszDriverName, //驱动程序的在注册表中的名字
lpszDriverName, // 注册表驱动程序的 DisplayName 值
SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限
SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序
SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值 自动启动 开机启动 手动启动 禁用
SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值
szDriverImagePath, // 注册表驱动程序的 ImagePath 值
NULL, //GroupOrder HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GroupOrderList
NULL,
NULL,
NULL,
NULL);
DWORD dwRtn;
//判断服务是否失败
if( hServiceDDK == NULL )
{
dwRtn = GetLastError();
if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )
{
//由于其他原因创建服务失败
printf( "CrateService() Failed %d ! \n", dwRtn );
bRet = FALSE;
goto BeforeLeave;
}
else
{
//服务创建失败,是由于服务已经创立过
printf( "CrateService() Failed Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" );
}
// 驱动程序已经加载,只需要打开
hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS );
if( hServiceDDK == NULL )
{
//如果打开服务也失败,则意味错误
dwRtn = GetLastError();
printf( "OpenService() Failed %d ! \n", dwRtn );
bRet = FALSE;
goto BeforeLeave;
}
else
{
printf( "OpenService() ok ! \n" );
}
}
else
{
printf( "CrateService() ok ! \n" );
}
//开启此项服务
bRet= StartService( hServiceDDK, NULL, NULL );
if( !bRet )
{
DWORD dwRtn = GetLastError();
if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )
{
printf( "StartService() Failed %d ! \n", dwRtn );
bRet = FALSE;
goto BeforeLeave;
}
else
{
if( dwRtn == ERROR_IO_PENDING )
{
//设备被挂住
printf( "StartService() Failed ERROR_IO_PENDING ! \n");
bRet = FALSE;
goto BeforeLeave;
}
else
{
//服务已经开启
printf( "StartService() Failed ERROR_SERVICE_ALREADY_RUNNING ! \n");
bRet = TRUE;
goto BeforeLeave;
}
}
}
bRet = TRUE;
//离开前关闭句柄
BeforeLeave:
if(hServiceDDK)
{
CloseServiceHandle(hServiceDDK);
}
if(hServiceMgr)
{
CloseServiceHandle(hServiceMgr);
}
return bRet;
}
//卸载驱动程序
BOOL UnloadDriver( char * szSvrName )
{
BOOL bRet = FALSE;
SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄
SERVICE_STATUS SvrSta;
//打开SCM管理器
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if( hServiceMgr == NULL )
{
//带开SCM管理器失败
printf( "OpenSCManager() Failed %d ! \n", GetLastError() );
bRet = FALSE;
goto BeforeLeave;
}
else
{
//带开SCM管理器失败成功
printf( "OpenSCManager() ok ! \n" );
}
//打开驱动所对应的服务
hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS );
if( hServiceDDK == NULL )
{
//打开驱动所对应的服务失败
printf( "OpenService() Failed %d ! \n", GetLastError() );
bRet = FALSE;
goto BeforeLeave;
}
else
{
printf( "OpenService() ok ! \n" );
}
//停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。
if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) )
{
printf( "ControlService() Failed %d !\n", GetLastError() );
}
else
{
//打开驱动所对应的失败
printf( "ControlService() ok !\n" );
}
//动态卸载驱动程序。
if( !DeleteService( hServiceDDK ) )
{
//卸载失败
printf( "DeleteSrevice() Failed %d !\n", GetLastError() );
}
else
{
//卸载成功
printf( "DelServer:deleteSrevice() ok !\n" );
}
bRet = TRUE;
BeforeLeave:
//离开前关闭打开的句柄
if(hServiceDDK)
{
CloseServiceHandle(hServiceDDK);
}
if(hServiceMgr)
{
CloseServiceHandle(hServiceMgr);
}
return bRet;
}
void TestDriver()
{
//测试驱动程序
HANDLE hDevice = CreateFile("\\\\.\\NTmodeldrv",
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if( hDevice != INVALID_HANDLE_VALUE )
{
printf( "Create Device ok ! \n" );
}
else
{
printf( "Create Device Failed %d ! \n", GetLastError() );
return;
}
CHAR bufRead[1024]={0};
WCHAR bufWrite[1024]=L"Hello, world";
DWORD dwRead = 0;
DWORD dwWrite = 0;
ReadFile(hDevice, bufRead, 1024, &dwRead, NULL);
printf("Read done!\n");
WriteFile(hDevice, bufWrite, (wcslen(bufWrite)+1)*sizeof(WCHAR), &dwWrite, NULL);
printf("Write done!\n");
CHAR bufInput[1024] ="Hello, world";
CHAR bufOutput[1024] = {0};
DWORD dwRet = 0;
WCHAR bufFileInput[1024] =L"c:\\docs\\hi.txt";
DeviceIoControl(hDevice,
CTL_PRINT,
bufFileInput,
sizeof(bufFileInput),
bufOutput,
sizeof(bufOutput),
&dwRet,
NULL);
DeviceIoControl(hDevice,
CTL_HELLO,
NULL,
0,
NULL,
0,
&dwRet,
NULL);
DeviceIoControl(hDevice,
CTL_BYE,
NULL,
0,
NULL,
0,
&dwRet,
NULL);
printf("DeviceIoControl done!\n");
CloseHandle( hDevice );
}
int main(int argc, char* argv[])
{
//加载驱动
BOOL bRet = LoadDriver(DRIVER_NAME,DRIVER_PATH);
if (!bRet)
{
printf("LoadNTDriver error\n");
return 0;
}
//加载成功
printf( "press any key to create device!\n" );
getch();
TestDriver();
//这时候你可以通过注册表,或其他查看符号连接的软件验证。
printf( "press any key to stop service!\n" );
getch();
//卸载驱动
bRet = UnloadDriver(DRIVER_NAME);
if (!bRet)
{
printf("UnloadNTDriver error\n");
return 0;
}
return 0;
}
下面是我自己的驱动模板
通信代码依旧是上面的 只是改了设备名和驱动名 和 testDriver中打开驱动的名称
#include <ntddk.h>
#define DEVICE_NAME L"\\device\\DjWow"
#define LINK_NAME L"\\dosdevices\\DjWow" //\\??\\xxxx
#define IOCTRL_BASE 0x800
#define IOCTL_CODE(i)\
CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTRL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define CTL_HELLO IOCTL_CODE(0)
#define CTL_ULONG IOCTL_CODE(1)
#define CTL_WCHAR IOCTL_CODE(2)
NTSTATUS DispatchCommon(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
UNREFERENCED_PARAMETER(pDeviceObject);
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
UNREFERENCED_PARAMETER(pDeviceObject);
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchClose(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
UNREFERENCED_PARAMETER(pDeviceObject);
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchClear(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
UNREFERENCED_PARAMETER(pDeviceObject);
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchRead(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
PVOID pBuff = 0;
ULONG pBuffLen = 0;
ULONG pStackLen = 0;
PIO_STACK_LOCATION pStack = 0;
ULONG uMin = 0;
UNREFERENCED_PARAMETER(pDeviceObject);
pBuff = pIrp->AssociatedIrp.SystemBuffer;
pStack = IoGetCurrentIrpStackLocation(pIrp);
pStackLen = pStack->Parameters.Read.Length;
pBuffLen = (wcslen(L"hello world") + 1) * sizeof(WCHAR);
uMin = pBuffLen < pStackLen ? pBuffLen:pStackLen;
RtlCopyMemory(pBuff, L"hello wolrd", uMin);
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = uMin;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DispatchWrite(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
PVOID pWriteBuff = 0;
PVOID pBuff = 0;
ULONG uWriteBuffLen = 0;
PIO_STACK_LOCATION pStack = 0;
UNREFERENCED_PARAMETER(pDeviceObject);
pWriteBuff = pIrp->AssociatedIrp.SystemBuffer;
pStack = IoGetCurrentIrpStackLocation(pIrp);
uWriteBuffLen = pStack->Parameters.Write.Length;
pBuff = ExAllocatePoolWithTag(PagedPool, uWriteBuffLen,'TSET');
if(pBuff == NULL)
{
pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
pIrp->IoStatus.Information = 0;
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(pBuff, uWriteBuffLen);
RtlCopyMemory(pBuff,pWriteBuff, uWriteBuffLen);
ExFreePool(pBuff);
pBuff = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = uWriteBuffLen;
return STATUS_SUCCESS;
}
NTSTATUS DispatchIoctrl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
PIO_STACK_LOCATION pStack = 0;
PVOID pBuff = 0;
ULONG uOutLen = 0;
ULONG uInLen = 0;
ULONG uCtlCode = 0;
UNREFERENCED_PARAMETER(pDeviceObject);
pStack = IoGetCurrentIrpStackLocation(pIrp);
uOutLen = pStack->Parameters.DeviceIoControl.OutputBufferLength;
uInLen = pStack->Parameters.DeviceIoControl.InputBufferLength;
pBuff = pIrp->AssociatedIrp.SystemBuffer;
uCtlCode = pStack->Parameters.DeviceIoControl.IoControlCode;
switch (uCtlCode)
{
case CTL_HELLO:
DbgPrint("hello!\n");
break;
case CTL_ULONG:
{
DbgPrint("pid:%d\n",*(ULONG*)pBuff);
RtlCopyMemory(pBuff,L"ok",uOutLen);
break;
}
case CTL_WCHAR:
DbgPrint("%ws",pBuff);
break;
default:
DbgPrint("UNKNUW CTLCODE!\n");
}
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = uOutLen;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING strLinkName ={0};
RtlInitUnicodeString(&strLinkName,LINK_NAME);
IoDeleteSymbolicLink(&strLinkName);
if(pDriverObject->DeviceObject)
{
IoDeleteDevice(pDriverObject->DeviceObject);
}
DbgPrint("DriverUnload");
return;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
UNICODE_STRING strDeviceName = {0};
UNICODE_STRING strLinkName = {0};
NTSTATUS status = 0;
PDEVICE_OBJECT pDeviceObject = 0;
ULONG i = 0;
DbgPrint("[DJWOW]DriverEntry!\n");
UNREFERENCED_PARAMETER(pRegPath);
RtlInitUnicodeString(&strDeviceName, DEVICE_NAME);
RtlInitUnicodeString(&strLinkName, LINK_NAME);
status = IoCreateDevice(pDriverObject, 0, &strDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
if(!NT_SUCCESS(status))
{
DbgPrint("CretaDevice Faild:0x%x\n",status);
return status;
}
pDeviceObject->Flags |= DO_BUFFERED_IO;
status = IoCreateSymbolicLink(&strLinkName,&strDeviceName);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(pDeviceObject);
DbgPrint("IoCreateSymbolicdLink Faild:0x%x\n",status);
return status;
}
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++)
{
pDriverObject->MajorFunction[i] = DispatchCommon;
}
pDriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctrl;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchClear;
pDriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}