2011-08-23 106 views
3

我有一個驅動程序代碼,在32位上效果很好。在64位我編譯它,並且數字簽名它。驅動程序加載但無法正常工作。驅動程序的主要功能是在回撥過程中將程序創建和終止註冊到我的程序中。所以我有兩個IOCTL工作。該代碼如下..驅動程序64位

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結構的問題嗎?請幫我找到解決辦法。謝謝..

+2

您的帖子中沒有包含足夠的信息來解決這個問題。調試驅動程序,看看裏面發生了什麼。或者將KdPrint語句添加到驅動程序,執行它並在DbgView程序中查看調試輸出。 –

+0

好吧..我是新來的司機...你能幫我告訴我如何調試驅動程序? – Neha

+0

看看這個MSDN部分,它可能會幫助:[驅動程序開發工具](http://msdn.microsoft.com/en-us/library/ff545440(v = VS.85).aspx),特別是 - 「調試驅動程序的工具「和」驗證驅動程序的工具「。 – Eugene

回答

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 
+0

緩衝區較小是因爲我得到OutputBufferLength = 12和sizeof(PROCESS_CALLBACK_INFO)= 24的問題。結構如下typedef struct _ProcessCallbackInfo { HANDLE hParentId; HANDLE hProcessId; BOOLEAN bCreate; } PROCESS_CALLBACK_INFO – Neha

+0

如何解決此問題。爲什麼outputBufferLenght在64位上更小? – Neha

+0

@neha:問題可能是因爲編譯驅動程序和客戶端時,或者因爲您使用的是32位客戶端而有不同的默認值。至於OutputBufferLength,我猜想一個在32位系統上是一樣的。 – rjnilsson

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位編譯時具有相同的大小),並且結構填充相同。

+0

非常感謝..我會試試這個... – Neha

+0

我嘗試了你建議的方式...並發現OutputBufferLength = 12和sizeof(PROCESS_CALLBACK_INFO)= 24。這就是爲什麼if循環無法執行。我如何解決這個問題?是因爲我在64位? – Neha

1

我找到了答案。感謝調試。如前所述,outputBufferLength小於驅動程序失效的結構長度。

outputBufferLength取決於您在調用以下函數時傳遞的結構體的大小。

bReturnCode = ::的DeviceIoControl( m_hDriverFile, IOCTL_PROCOBSRV_GET_PROCINFO, 0, 0, & callbackInfo,的sizeof(callbackInfo) & dwBytesReturned, & OV );

因此,callbackInfo大小爲12,因此outputBufferLength = 12。結構callbackInfo具有DWORD數據塊,對於64位,該數據塊必須是DWORD64。當我改變結構中成員的數據類型,然後調用DeviceIOControl函數時,驅動程序工作得很好,outputBufferLength = 24,如預期的那樣。感謝你的幫助。

相關問題