我有一个在32位上运行良好的驱动程序代码。在64位我编译它并进行数字签名。驱动程序加载但无法正常工作。驱动程序的主要功能是在回调中将进程创建和终止注册到我的程序。所以我有两个IOCTL工作。代码如下..
NTSTATUS DispatchIoctl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;
PPROCESS_CALLBACK_INFO pProcCallbackInfo;
//
// These IOCTL handlers are the set and get interfaces between
// the driver and the user mode app
//
switch(irpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_PROCOBSRV_ACTIVATE_MONITORING:
{
ntStatus = ActivateMonitoringHanlder( Irp );
break;
}
case IOCTL_PROCOBSRV_GET_PROCINFO:
{
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PROCESS_CALLBACK_INFO))
{
pProcCallbackInfo = Irp->AssociatedIrp.SystemBuffer;
pProcCallbackInfo->hParentId = extension->hParentId;
pProcCallbackInfo->hProcessId = extension->hProcessId;
pProcCallbackInfo->bCreate = extension->bCreate;
ntStatus = STATUS_SUCCESS;
}
break;
}
default:
break;
}
Irp->IoStatus.Status = ntStatus;
//
// Set number of bytes to copy back to user-mode
//
if(ntStatus == STATUS_SUCCESS)
Irp->IoStatus.Information = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
else
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;
}
当我打电话
bReturnCode = ::DeviceIoControl(
hDriverFile,
IOCTL_PROCOBSRV_ACTIVATE_MONITORING,
&activateInfo,
sizeof(activateInfo),
NULL,
0,
&dwBytesReturned,
NULL
);
代码成功但我打电话
bReturnCode = ::DeviceIoControl(
m_hDriverFile,
IOCTL_PROCOBSRV_GET_PROCINFO,
0,
0,
&callbackInfo, sizeof(callbackInfo),
&dwBytesReturned,
&ov
);
getLastError返回31.任何人都可以帮助我。这是64位IOCTL结构的问题吗?请帮我找到解决方案。感谢..
答案 0 :(得分:2)
如果您没有驱动程序调试经验,请尝试使用跟踪来诊断此问题。在必要的所有位置将KdPrint行添加到代码中,例如:
case IOCTL_PROCOBSRV_GET_PROCINFO: { KdPrint(("IOCTL_PROCOBSRV_GET_PROCINFO. OutputBufferLength = %d\n", irpStack->Parameters.DeviceIoControl.OutputBufferLength)); KdPrint(("sizeof(PROCESS_CALLBACK_INFO) = %d\n", sizeof(PROCESS_CALLBACK_INFO))); if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PROCESS_CALLBACK_INFO)) { pProcCallbackInfo = Irp->AssociatedIrp.SystemBuffer; pProcCallbackInfo->hParentId = extension->hParentId; pProcCallbackInfo->hProcessId = extension->hProcessId; pProcCallbackInfo->bCreate = extension->bCreate; KdPrint(("IOCTL_PROCOBSRV_GET_PROCINFO. STATUS_SUCCESS\n")); ntStatus = STATUS_SUCCESS; } break; }
这只是一个示例,将KdPrint行添加到所有地方以了解会发生什么。在已检查的配置中构建驱动程序,安装它并运行程序。请参阅DbgView程序中的KdPrint输出,并启用Caprure Kernel选项。
您可以使用DbgPrint而不是KdPrint,在这种情况下,它也可以在免费驱动程序配置中使用。
编辑:
如何定义PROCESS_CALLBACK_INFO?什么是调用驱动程序的客户端代码?客户端编译为32位还是64位?在客户端和驱动程序之间传递结构,确保它不包含与位数相关的字段(在32位和64位编译时具有相同的大小),并且结构填充是相同的。
答案 1 :(得分:1)
此处没有太多信息,但您可以随时检查编译的用户模式客户端和驱动程序在运行64位时自定义结构的大小是否相同。可能存在打包/对齐问题,可以通过使用#pragma pack
(或编译器支持的任何内容)来修复结构。
作为一般规则,还尝试将状态代码设置为检测到的问题的更具体的值,例如如果检测到传递的缓冲区太小,则STATUS_BUFFER_TOO_SMALL
。我怀疑在使用IOCTL_PROCOBSRV_GET_PROCINFO
IOCTL时这不是实际问题,因为您回到Win32错误31,但它可以帮助客户解决他们的问题。
更新:由于差异实际上似乎与您的评论不匹配,请尝试用包装来包围结构定义,然后确保重新编译客户端和驱动程序。如果您使用的是Visual C ++编译器,请执行以下示例:
#pragma pack(push, 8) // Save current packing and set to 8-byte
typedef struct _PROCESS_CALLBACK_INFO
{
// Whatever ...
} PROCESS_CALLBACK_INFO;
#pragma pack(pop) // Restore previous packing
答案 2 :(得分:1)
我找到了答案。感谢调试。如前所述,outputBufferLength小于驱动程序失败的结构长度。
outputBufferLength会调用您在调用以下函数时传递的结构的大小。
bReturnCode = :: DeviceIoControl( m_hDriverFile, IOCTL_PROCOBSRV_GET_PROCINFO, 0, 0, & callbackInfo,sizeof(callbackInfo), &安培; dwBytesReturned, &安培; OV );
所以callbackInfo的大小是12,所以outputBufferLength = 12.结构callbackInfo有DWORD datamember,64位必须是DWORD64。当我更改结构中成员的数据类型然后调用DeviceIOControl函数时,驱动程序工作得很好,outputBufferLength是= 24,如预期的那样。谢谢你的帮助。