討論區快速選單
知識庫快速選單
程式設計俱樂部Facebook粉絲團 掌握Salesforce雲端管理秘訣 軟體開發過程中有哪些資安漏洞?
[ 回上頁 ] [ 討論區發言規則 ]
建立產生IRP
更改我的閱讀文章字型大小
作者 : hansdisckkklll(hansdisckkklllkkklll)
[ 貼文 20 | 人氣 3050 | 評價 0 | 評價/貼文 0 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/25 下午 09:45:08
Dear All
我想在驅動程式裡寫一個定時程式跟裝置要report
希望不經由AP發要求(I/O Messager 不產生IRP)
所以我想我應該是要在驅動裡產生IRP往下層傳(IoCallDriver(PDEVICE_OBJECT,PIRP))
製作主要IRP的流程是參照http://pollos-blog.blogspot.com/2007/09/windows-driver-programming8.html介紹
唯一不同的是IRP的DeviceObject參數不是從NdisMGetDeviceProperty() 的 NextDeviceObject 參數來的
是physical_device_object來的
但是如果我對新產生出的IRP進行調用電腦會REBOOT-EX : IoGetNextIrpStackLocation(Irp)-
想請問一下為什麼會這樣?
對於IRP的DeviceObject參數我還是用過另一個方法
主要是參考filter hook driver作法
利用RtlInitUnicodeString和IoGetDeviceObjectPointer取得PDeviceObject
然後調用IoBuildDeviceIoControlRequest產生IRP
但是在執行到IoBuildDeviceIoControlRequest這行就重開機
想請問一下為什麼會這樣?
PS.IRP在建立的時候有用KeGetCurrentIrql( )判斷是否小於 APC_LEVEL
     -結果判斷式成立-


感謝您的參予...


作者 : tdtsai(新兵衛) 驅動程式優秀好手貼文超過200則
[ 貼文 362 | 人氣 779 | 評價 1290 | 評價/貼文 3.56 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人hansdisckkklll註記此篇回應為很有道理 2008/6/26 下午 11:14:57
Dear Hans:
You should not use PhysicalDeviceObject to do this you should use NextDeviceObject. And you should not build IRP in Adddevice. In this time the driver stack is not ready. If you list your code maybe more people can help. Otherwise no one can help you. Because no one can guess what do you do in your code. In kernel mode programming it too easy let system BSOD.

BR,
Tzung-Dar Tsai

>Dear A
>我想在驅動程式裡寫一個定時程式跟裝置要report
>希望不經由AP發要求(I/O Messager 不產生IRP)
>所以我想我應該是要在驅動裡產生IRP往下層傳(IoCallDriver(PDEVICE_OBJECT,PIRP))
>製作主要IRP的流程是參照http://pollos-blog.blogspot.com/2007/09/windows-driver-programming8.html介紹
>唯一不同的是IRP的DeviceObject參數不是從NdisMGetDeviceProperty() 的 NextDeviceObject 參數來的
>是physical_device_object來的
>但是如果我對新產生出的IRP進行調用電腦會REBOOT-EX : IoGetNextIrpStackLocation(Irp)-
>想請問一下為什麼會這樣?
>對於IRP的DeviceObject參數我還是用過另一個方法
>主要是參考filter hook driver作法
>利用RtlInitUnicodeString和IoGetDeviceObjectPointer取得PDeviceObject
>然後調用IoBuildDeviceIoControlRequest產生IRP
>但是在執行到IoBuildDeviceIoControlRequest這行就重開機
>想請問一下為什麼會這樣?
>PS.IRP在建立的時候有用KeGetCurrentIrql( )判斷是否小於 APC_LEVEL
> -結果判斷式成立-
>
>
>感謝您的參予...
>
>
>
作者 : hansdisckkklll(hansdisckkklllkkklll)
[ 貼文 20 | 人氣 3050 | 評價 0 | 評價/貼文 0 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/27 上午 11:22:51
首先感謝新兵衛的回應
接下來是我建立IRP相關程式碼
我想要讓驅動做的事是定時和HID裝置要report
關於TIMER部分就先PASS
我直接PO出DCP裡的工作
UNICODE_STRING hans_device_name;
NTSTATUS status;
PIRP hans_irp;
KEVENT hans_event;
IO_STATUS_BLOCK hans_iosb;
KeInitializeEvent(&hans_event, SynchronizationEvent, FALSE);
RtlInitUnicodeString(&hans_device_name,L"\\DEVICE\\hans_HID_01");
IoGetDeviceObjectPointer(&hans_device_name,
     STANDARD_RIGHT_ALL,
     &hans_FO,
     &hans_DO);
hans_irp = IoBuildDeviceIoControlRequest(IO_INTERRUPT_OR_BULK_READ,
     hans_DO,
     NULL,
     0,
     NULL,
     0,
     false,
     &hans_event,
     &hans_iosb);
基本上以上的code就足以重開機,應該是hans_DO的問題,但不知道問題出在哪
有了IRP,我會繼續建立urb
int urb_size;
URB *urb = NULL;
//-還不知道怎麼取得相對應的pipe_handle
USBD_PIPE_HANDLE pipe_handle;
//-
urb_size = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
*urb = ExAllocatePool(NonPagedPool, urb_size);
memset(*urb, 0, urb_size);
(*urb)->UrbHeader.Length = (USHORT)urb_size;
(*urb)->UrbHeader.Function
     = (USHORT)URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
(*urb)->UrbBulkOrInterruptTransfer.PipeHandle = pipe_handle;
(*urb)->UrbBulkOrInterruptTransfer.TransferFlags
     = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
(*urb)->UrbBulkOrInterruptTransfer.TransferBufferLength = 0;
(*urb)->UrbBulkOrInterruptTransfer.TransferBufferMDL = NULL;




作者 : hansdisckkklll(hansdisckkklllkkklll)
[ 貼文 20 | 人氣 3050 | 評價 0 | 評價/貼文 0 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/27 上午 11:23:03
首先感謝新兵衛的回應
接下來是我建立IRP相關程式碼
我想要讓驅動做的事是定時和HID裝置要report
關於TIMER部分就先PASS
我直接PO出DCP裡的工作
UNICODE_STRING hans_device_name;
NTSTATUS status;
PIRP hans_irp;
KEVENT hans_event;
IO_STATUS_BLOCK hans_iosb;
KeInitializeEvent(&hans_event, SynchronizationEvent, FALSE);
RtlInitUnicodeString(&hans_device_name,L"\\DEVICE\\hans_HID_01");
IoGetDeviceObjectPointer(&hans_device_name,
     STANDARD_RIGHT_ALL,
     &hans_FO,
     &hans_DO);
hans_irp = IoBuildDeviceIoControlRequest(IO_INTERRUPT_OR_BULK_READ,
     hans_DO,
     NULL,
     0,
     NULL,
     0,
     false,
     &hans_event,
     &hans_iosb);
基本上以上的code就足以重開機,應該是hans_DO的問題,但不知道問題出在哪
有了IRP,我會繼續建立urb
int urb_size;
URB *urb = NULL;
//-還不知道怎麼取得相對應的pipe_handle
USBD_PIPE_HANDLE pipe_handle;
//-
urb_size = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
*urb = ExAllocatePool(NonPagedPool, urb_size);
memset(*urb, 0, urb_size);
(*urb)->UrbHeader.Length = (USHORT)urb_size;
(*urb)->UrbHeader.Function
     = (USHORT)URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
(*urb)->UrbBulkOrInterruptTransfer.PipeHandle = pipe_handle;
(*urb)->UrbBulkOrInterruptTransfer.TransferFlags
     = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
(*urb)->UrbBulkOrInterruptTransfer.TransferBufferLength = 0;
(*urb)->UrbBulkOrInterruptTransfer.TransferBufferMDL = NULL;




作者 : hansdisckkklll(hansdisckkklllkkklll)
[ 貼文 20 | 人氣 3050 | 評價 0 | 評價/貼文 0 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/27 上午 11:24:32
然後設定IRP參數
IO_STACK_LOCATION *stack_location = NULL;
stack_location = IoGetNextIrpStackLocation(hans_irp);
stack_location->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
stack_location->Parameters.Others.Argument1 = urb;
stack_location->Parameters.DeviceIoControl.IoControlCode
    = IOCTL_INTERNAL_USB_SUBMIT_URB;
和I/O溝通
status = IoCallDriver(hans_DO, irp);
if (status == STATUS_PENDING)
 (void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);

然後預期結果
僅可以在tracker上看到HID裝置傳出report


(真尷尬 上面那篇PO兩次 真是大新手....)
作者 : hansdisckkklll(hansdisckkklllkkklll)
[ 貼文 20 | 人氣 3050 | 評價 0 | 評價/貼文 0 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/27 下午 12:08:04
補上USBD_PIPE_HANDLE的作法


PIO_STACK_LOCATION hans_irpstack;
hans_irpstack = IoGetCurrentIrpStackLocation (hans_irp);
hans_FO1= hans_irpstack->FileObject;
//問題又來了: hans_FO1和hans_FO是一樣的東西嗎?
pipe_handle = hans_FO1>FsContext;
作者 : tdtsai(新兵衛) 驅動程式優秀好手貼文超過200則
[ 貼文 362 | 人氣 779 | 評價 1290 | 評價/貼文 3.56 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人hansdisckkklll註記此篇回應為很有道理 2008/6/28 上午 12:23:13
If your hand_DO is NULL, you will get BSOD when you call IoBuildDeviceIoControlRequest. You can check it.

>首先感謝新兵衛的回應
>接下來是我建立IRP相關程式碼
>我想要讓驅動做的事是定時和HID裝置要report
>關於TIMER部分就先PASS
>我直接PO出DCP裡的工作
>UNICODE_STRING hans_device_name;
>NTSTATUS status;
>PIRP hans_irp;
>KEVENT hans_event;
>IO_STATUS_BLOCK hans_iosb;
>KeInitializeEvent(&hans_event, SynchronizationEvent, FALSE);
>RtlInitUnicodeString(&hans_device_name,L\\DEVICE\\hans_HID_01);
>IoGetDeviceObjectPointer(&hans_device_name,
> STANDARD_RIGHT_ALL,
> &hans_FO,
> &hans_DO);
>hans_irp = IoBuildDeviceIoControlRequest(IO_INTERRUPT_OR_BULK_READ,
> hans_DO,
> NULL,
> 0,
> NULL,
> 0,
> false,
> &hans_event,
> &hans_iosb);
>基本上以上的code就足以重開機,應該是hans_DO的問題,但不知道問題出在哪
作者 : hansdisckkklll(hansdisckkklllkkklll)
[ 貼文 20 | 人氣 3050 | 評價 0 | 評價/貼文 0 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/30 上午 09:37:14
hans_DO的確等於NULL
我又往上檢查IoGetDeviceObjectPointer

當我將DPC裡的程式碼縮減到只剩生產DeviceObject和FileObject
PDEVICE_OBJECT hans_DO=NULL;
PFILE_OBJECT hans_FO=NULL;
UNICODE_STRING hans_device_name;
NTSTATUS status;
RtlInitUnicodeString(&hans_device_name,L"\\DEVICE\\hans_HID_01");
status = IoGetDeviceObjectPointer(&hans_device_name,
     STANDARD_RIGHTS_ALL,
     &hans_FO,
     &hans_DO);
if(NT_SUCCESS(status))
 DbgPrint("hans success");
hans_FO = NULL;
hans_DO = NULL;

尷尬的結果,還是重開機

我猜的可能發生問題的地方有3個
1.裝置名字給錯
2.access mask用錯
3.TimerSet時機錯

1和2比較不太有可能會錯
因為我用的是別人OPEN SOUCE, device name=libusb00001;

3的話,我是在一般中斷傳輸的時候啟動Timer,所以應該不會有the driver stack is not ready的問題

那如果上述三個都沒有問題
問題到底會是什麼呢?
不會是這樣做根就是不對的吧?
作者 : tdtsai(新兵衛) 驅動程式優秀好手貼文超過200則
[ 貼文 362 | 人氣 779 | 評價 1290 | 評價/貼文 3.56 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人hansdisckkklll註記此篇回應為很有道理 2008/6/30 下午 12:04:40
mmm ... where you get the BSOD ?? I can sure this code will not make system BSOD if you are in PASSIVE_LEVEL.

>hans_DO的確等於NULL
>我又往上檢查IoGetDeviceObjectPointer
>
>當我將DPC裡的程式碼縮減到只剩生產DeviceObject和FileObject
>PDEVICE_OBJECT hans_DO=NULL;
>PFILE_OBJECT hans_FO=NULL;
>UNICODE_STRING hans_device_name;
>NTSTATUS status;
>RtlInitUnicodeString(&hans_device_name,L\\DEVICE\\hans_HID_01);
>status = IoGetDeviceObjectPointer(&hans_device_name,
> STANDARD_RIGHTS_ALL,
> &hans_FO,
> &hans_DO);
>if(NT_SUCCESS(status))
> DbgPrint(hans success);
>hans_FO = NULL;
>hans_DO = NULL;
>
>尷尬的結果,還是重開機
>
>我猜的可能發生問題的地方有3個
>1.裝置名字給錯
>2.access mask用錯
>3.TimerSet時機錯
>
>1和2比較不太有可能會錯
>因為我用的是別人OPEN SOUCE, device name=libusb00001;
>
>3的話,我是在一般中斷傳輸的時候啟動Timer,所以應該不會有the driver stack is not ready的問題
>
>那如果上述三個都沒有問題
>問題到底會是什麼呢?
>不會是這樣做根就是不對的吧?
作者 : hansdisckkklll(hansdisckkklllkkklll)
[ 貼文 20 | 人氣 3050 | 評價 0 | 評價/貼文 0 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/30 下午 01:50:14
關於我撰寫這支程式所遇過的重開機狀況
都是一更新完驅動程式,還來不及按完成就重開機
我還沒遇過藍屏的狀況 @.@

驗證PASSIVE_LEVEL部份
我在TIMER要執行的DPC裡加上
if(KeGetCurrentIrql()==PASSIVE_LEVEL)
 DbgPrint("OK");
結果有秀OK
故應該可說是在PASSIVE_LEVEL執行的

請問還有其他可能錯誤的地方嗎? Thanks!
作者 : hansdisckkklll(hansdisckkklllkkklll)
[ 貼文 20 | 人氣 3050 | 評價 0 | 評價/貼文 0 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/30 下午 03:26:50
不好意思
上面一篇打錯了
我的DPC不是在"PASSIVE_LEVEL" , 是在"APC_LEVEL"

如果我上面用的一些函式一定要在PASSIVE_LEVEL執行的話
請問這樣的話是否就間接說明了我無法利用TIMER+IRP讀REPORT
如果是這樣的話
那還有其他辦法可以實現定時向裝置索取REPORT嗎?

作者 : tdtsai(新兵衛) 驅動程式優秀好手貼文超過200則
[ 貼文 362 | 人氣 779 | 評價 1290 | 評價/貼文 3.56 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人hansdisckkklll註記此篇回應為最佳解答 2008/6/30 下午 11:50:46
mmm You cant use timer callback function to call those function. You should queue a workitem. And do it in workitem.
And as I know the Timer callback function will be called in DPC_LEVEL not in APC_LEVEL.

>不好意思
>上面一篇打錯了
>我的DPC不是在PASSIVE_LEVEL , 是在APC_LEVEL
>
>如果我上面用的一些函式一定要在PASSIVE_LEVEL執行的話
>請問這樣的話是否就間接說明了我無法利用TIMER+IRP讀REPORT
>如果是這樣的話
>那還有其他辦法可以實現定時向裝置索取REPORT嗎?
>
>
作者 : hansdisckkklll(hansdisckkklllkkklll)
[ 貼文 20 | 人氣 3050 | 評價 0 | 評價/貼文 0 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/7/1 下午 06:38:33
感謝新兵衛
經由新兵衛的提點
我將上述創建IRP和URB的流程加入workitem的ROUTINE
就可以使用上面流程的函式
然後利用TIMER呼叫WORKITEM(IoQueueWorkItem)
以達定時工作的目的

我還有些問題想請教一下
其實也就是前幾篇問的hans_FO等於hans_FO1嗎?
//hans_FO
//RtlInitUnicodeString(&hans_device_name,L"\\DEVICE\\hans_HID_01");
//IoGetDeviceObjectPointer(&hans_device_name,
// STANDARD_RIGHT_ALL,
// &hans_FO,
// &hans_DO);
//hans_FO1
// PIO_STACK_LOCATION hans_irpstack;
// hans_irpstack = IoGetCurrentIrpStackLocation (hans_irp);
// hans_FO1= hans_irpstack->FileObject;
//
結果是否定的.....因為hans_FO1==NULL
不好意思想請問一下為什麼呢?
(是不是IoBuildDeviceIoControlRequest創出的irp不完整,資料不全?)




 板主 : 徵求中
 > 驅動程式 - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - 驅動程式 - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
驅動程式
1 新兵衛 1240 
2 eBoy 980 
3 牧童哥 780 
4 北極熊 580 
5 天行者 580 
6 燒酒仙 440 
7 weber 380 
8 KEN 350 
9 jonay 180 
10 掌握文武半邊天 180 
驅動程式
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.078125