static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS status;
PIO_STACK_LOCATION irpSp;
//得到当前IRP (I/O请求包)
irpSp = IoGetCurrentIrpStackLocation( Irp );
switch (irpSp->MajorFunction)
{
case IRP_MJ_CREATE:
DbgPrint("IRP_MJ_CREATE\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;
break;
case IRP_MJ_CLOSE:
DbgPrint("IRP_MJ_CLOSE\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;
break;
}
IoCompleteRequest(Irp, 0);
return STATUS_SUCCESS;
}
大部分的I/O管理器的操作支持一个标准的读写提取,IRP_MJ_DEVICE_CONTROL允许扩展的I/O请求,使用用户模式的DeviceIoControl函数来调用,I/O管理器创建一个IRP,这个IRP的MajorFunction和IoControlCode是被DeviceIoControl函数指定其内容。传递给驱动程序的IOCTL遵循一个特殊的结构,它有32-bit大小,DDK包含一个方便的产生IOCTL值的机制的宏,CTL_CODE。可以使用CTL_CODE宏来定义我们自己的IOCTL。
例如:
#define IOCTL_MISSLEDEVICE_AIM CTL_CODE \
( FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ACCESS_ANY )
NTSTATUS DispatchIoControl( IN PDEVICE_OBJECT pDO, IN PIRP pIrp )
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pDE;
PVOID userBuffer;
ULONG inSize;
ULONG outSize;
ULONG controlCode; // IOCTL请求代码
PIO_STACK_LOCATION pIrpStack; //堆栈区域存储了用户缓冲区信息
pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
// 取出IOCTL请求代码
controlCode = pIrpStack-> Parameters.DeviceIoControl.IoControlCode;
// 得到请求缓冲区大小
inSize = pIrpStack-> Parameters.DeviceIoControl.InputBufferLength;
OutSize = pIrpStack-> Parameters.DeivceIoControl.OutputBufferLength;
//现在执行二次派遣
switch (controlCode)
{
case IOCTL_MISSLEDEVICEAIM:
......
case IOCTL_DEVICE_LAUNCH:
......
default: // 驱动程序收到了未被承认的控制代码
status = STATUS_INVALID_DEVICE_REQUEST;
}
pIrp->IoStatus.Information = 0; // 数据没有传输
IoCompleteRequest( pIrp, IO_NO_INCREMENT ) ;
return status;
}
5.驱动程序的安装
SC管理器(即服务控制管理器)可以控制服务和驱动程序。
加载和运行一个服务需要执行的典型操作步骤:
1.调用OpenSCManager()以获取一个管理器句柄
2.调用CreateService()来向系统中添加一个服务
3.调用StartService()来运行一个服务
4.调用CloseServiceHandle()来释放管理器或服务句柄
BOOL InstallDriver()
{
SC_HANDLE hSCManager = NULL;
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(hSCManager == NULL)
{
fprintf(stderr, "OpenSCManager() failed. --err: %d\n", GetLastError());
return FALSE;
}
SC_HANDLE schService;
schService = CreateService( hSCManager, //SCManager database
"MyDriver", // name of service
"MyDriver", // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_KERNEL_DRIVER, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
DriverPath, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL // no password
);
if (schService == NULL)
{
if(GetLastError() == ERROR_SERVICE_EXISTS)
{
printf("Service has already installed!\n");
}
printf("Install driver false!");
return FALSE;
}
BOOL nRet = StartService(schService, 0, NULL);
if(!nRet)
{
if(GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
{
printf("Service is already running!\n");
return FALSE;