DeviceIoControl出现错误,错误码为87,请高人帮我看看
驱动程序:
/*采用缓冲区内存模式IOCTL, MY_DVC_BUFFERED_CODE是自定义的控制码*/
#define MY_DVC_BUFFERED_CODE (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)
NTSTATUS COMMUNICATE_DispatchCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS COMMUNICATE_DispatchDeviceControl(
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 = "select * from where int = 3"; //要向应用层输出的信息
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 = (PCHAR)Irp->AssociatedIrp.SystemBuffer; //输入缓冲区
outBuf = (PCHAR)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;
}
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;
}
VOID COMMUNICATE_DriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;
IoDeleteSymbolicLink(&usSymlinkName);
// Delete all the device objects
while(pdoNextDeviceObj)
{
PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
IoDeleteDevice(pdoThisDeviceObj);
}
}
#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
PDEVICE_OBJECT pdoDeviceObj = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;
pdoGlobalDrvObj = DriverObject;
// Create the device object.
if(!NT_SUCCESS(status = IoCreateDevice(
DriverObject,
0,
&usDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pdoDeviceObj
)))
{
// Bail out (implicitly forces the driver to unload).
return status;
};
// Now create the respective symbolic link object
if(!NT_SUCCESS(status = IoCreateSymbolicLink(
&usSymlinkName,
&usDeviceName
)))
{
IoDeleteDevice(pdoDeviceObj);
return status;
}
// NOTE: You need not provide your own implementation for any major function that
// you do not want to handle. I have seen code using DDKWizard that left the
// *empty* dispatch routines intact. This is not necessary at all!
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] = COMMUNICATE_DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = COMMUNICATE_DispatchDeviceControl;
DriverObject->DriverUnload = COMMUNICATE_DriverUnload;
return STATUS_SUCCESS;
}
#ifdef __cplusplus
}; // extern "C"
#endif
应用程序:
#define MY_DVC_BUFFERED_CODE (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)
int _tmain(int argc, _TCHAR* argv[])
{
ULONG bytesReturned;
char inBuf[50] = "This String is from User !!!"; //传入驱动的内容
char outBuf[50]; //用于接收驱动传出内容的缓冲区
/*打开设备,用我们自定的符号链接,响应驱动IRP_MJ_CREATE*/
HANDLE hDevice = CreateFile((LPCWSTR)".//COMMUNICATE_DeviceName",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("设备打开失败 %d %.8x/n", GetLastError(), hDevice);
return 0;
}
// BOOL bRead = ReadFile(hDevice, )
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);
return 0;
}