請問這一段取得USB Device Handle的程式碼有何問題? |
尚未結案
|
LouisLu
一般會員 發表:7 回覆:8 積分:3 註冊:2005-01-31 發送簡訊給我 |
請問各位大大:
可否請各位大大指點不知道我的這一段取得USB Device Handle的程式碼有什麼問題?
我已有定義好GUID_CLASS_ISO為正確的GUID,我想再取得Device Hamdle之後對Device做
DeviceIoControl的動作,但是一直無法成功,似乎是沒有成功取得Device Handle的關係。
煩請各位大大指點迷津...感謝感謝...
HANDLE GetDeviceHandle(BOOL Async) { HANDLE hIsoDev = INVALID_HANDLE_VALUE; HDEVINFO HardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA DeviceInfoData; PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceDetailData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0; ULONG i; BOOLEAN done; HardwareDeviceInfo = SetupDiGetClassDevs( &GUID_CLASS_ISO, NULL, // Define no enumerator (global) NULL, // Define no (DIGCF_PRESENT | // Only Devices present DIGCF_DEVICEINTERFACE) ); // Function class devices. done = FALSE; DeviceInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for (i=0;!done;i ) { if ( SetupDiEnumDeviceInterfaces(HardwareDeviceInfo, 0, &GUID_CLASS_ISO, i, &DeviceInfoData) ) { SetupDiGetDeviceInterfaceDetail ( HardwareDeviceInfo, &DeviceInfoData, NULL, 0, /*其實是有的,不知道之前為什麼會看不見*/&requiredLength, NULL); predictedLength = requiredLength; DeviceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(predictedLength); DeviceDetailData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); if( SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo, &DeviceInfoData, DeviceDetailData, predictedLength, &requiredLength, NULL) ) { DWORD FileAttr; if (Async) FileAttr = FILE_FLAG_OVERLAPPED; else FileAttr = 0; hIsoDev = CreateFile(DeviceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FileAttr, NULL); } else { hIsoDev = INVALID_HANDLE_VALUE; } free( DeviceDetailData); if ( hIsoDev != INVALID_HANDLE_VALUE ) { done = TRUE; break; } } else { if (ERROR_NO_MORE_ITEMS == GetLastError()) { done = TRUE; break; } } SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); return hIsoDev; }. 發表人 - LouisLu 於 2005/02/16 19:59:18 |
derrenbol1
中階會員 發表:5 回覆:113 積分:93 註冊:2004-12-09 發送簡訊給我 |
|
LouisLu
一般會員 發表:7 回覆:8 積分:3 註冊:2005-01-31 發送簡訊給我 |
|
derrenbol1
中階會員 發表:5 回覆:113 積分:93 註冊:2004-12-09 發送簡訊給我 |
LouisLu: SetupDiGetDeviceInterfaceDetail這個API主要在取得該裝置的路徑, 而路
徑會放到你所給的參數DeviceDetailData裏面, 然而因為每一個裝置的路徑名稱不一樣, 所以該結構的大小不一定, 故OS希望程式設計者"呼叫兩次", 第一
次你必須給一個DWORD變數的位置於參數5: DWORD RequiredSize = 0; SetupDiGetDeviceInterfaceDetail(
DeviceInfoSet,
&DeviceInfoData,
DeviceDetailData,
0,
&RequiredSize,
NULL); 於第一次呼叫時DeviceDetailData為NULL, 而OS會將該結構所須的大小放到
RequiredSize裏面, 這樣你才可以用來呼叫malloc去分配空間給DeviceDetailData; 再一次的呼叫, OS就會將"裝置路徑"放到DeviceDetailData裏面了. 你說你predictedLength 及requiredLength的除錯值皆為83, 我想你的除錯
點放錯位罝了, 你是否將斷點放到第二次呼叫之後了呢? 不然你的程式到下
面這一行時: predictedLength = requiredLength;
怎麼看都是0, 因為在上面的程式除了宣告外, 根本沒用到.
|
LouisLu
一般會員 發表:7 回覆:8 積分:3 註冊:2005-01-31 發送簡訊給我 |
|
derrenbol1
中階會員 發表:5 回覆:113 積分:93 註冊:2004-12-09 發送簡訊給我 |
LouisLu : 那你Port的文章確實怪怪的, 害我以為你的錯誤就是那個, 你有發現
SetupDiEnumDeviceInterfaces也少了個參數嗎?
如果是這樣的話, 那你的程式應該沒有問題才對. 你檢查一下你的GUID
是否"真的"正確. 還有你可以用Regedit.exe來看你所定義的GUID底下真的有
裝置.
\\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{Your GUID}如果該GUID底下沒裝置的話, 你的程式在列舉裝置時, 會得到NO_MORE_ITEM
這個系統錯誤訊息.
|
blk5743
高階會員 發表:34 回覆:371 積分:236 註冊:2003-11-17 發送簡訊給我 |
LouisLu你好 你可以參考下面這一個範例
【分享】偵測USB裝置插入哪一個USB Port插槽
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=59211 其中有個問題
但是程式碼中的sizeof(NodeInformation)的長度會算錯
(正確為76,但是我的兩台電腦均為73)
修正方法為
Project->Option->Advanced Compiler->Data Alignment->Byte DeviceDetailData->DevicePath所得到的東西會是下面的形式(舉例)
\\?\usb#vid_0123&pid_abcd#6&14e622e5&0&2#{a5dcbf10-6530-11d2-901f-00c04fb951ed} 這樣你就得到Vendor ID, Product ID及OS給的編號(這個是我猜的)
因此你就可以針對特定裝置做控制了
|
LouisLu
一般會員 發表:7 回覆:8 積分:3 註冊:2005-01-31 發送簡訊給我 |
感謝derrenbol1大大和blk5743大大: 我在VC中用這一段程式是沒有問題的,而且我的GUID是從VC程式中copy過來的,所以應該是不會有問題。
會不會是在BCB中使用這些DDK的function要有哪些設定或是include檔需要修改呢?
以下是小弟的一些include和define,不知道是不是有問題,請各位大大指點迷津。 還有一個問題,小弟不懂為何各位大大都會 #include "stdafx.h"。
那是什麼作用呢?內容為何呢?
#include發表人 - LouisLu 於 2005/02/17 10:51:53 |
blk5743
高階會員 發表:34 回覆:371 積分:236 註冊:2003-11-17 發送簡訊給我 |
引言: 還有一個問題,小弟不懂為何各位大大都會 #include "stdafx.h"。以下是我之前在別的站看到的 ================================================================ 簡單來說,stdafx.h 和 precompile header 有關。如果你在編譯器環境設定不使用 procompile header 的話,就可以不要理會 stdafx.h/.cpp 這東西。不過對編譯大型的程式來說,使用 precompile header 編譯會比較省時間(precompile header 把常用到的又不常變動的 library source 先預先編譯,就像先預先做成 .lib 一樣,不過 source 有變,precompile header 可以更新) quote: --------------------------------------------------------------------- 原發表者是 Tom 簡單來講,它就是將一些原本我們應該要一個一個 include 的標頭檔, 全部寫在 stdafx.h 內,這樣一來,寫大型的程式就會比較方便! 是不是這樣呢? 還有,這應該只有在用 VC 來寫視窗程式時才會用到吧! 在寫 console 程式時,有沒有可能使用到! 謝謝! --------------------------------------------------------------------- precompile header 和你把所有的標頭檔集中在一個 header 再分別 include 到其他 .cpp 檔是不一樣的。 有些編譯環境讓你指定 precompile header 是哪一個後,你不需要把 precompile header 一一 include 到 .cpp 檔案裡,而編譯環境也只有在 precompile header 裡的內容有變動時才會再編譯出 precompile header output 檔,這和把一個集大成的巨大 header 拿來到處掛上 .cpp 檔是不一樣的。 寫 console mode 時有沒有可能用到 precompile header 是看你,你也可以把常用到的 Standard C Library 的一部份(如 STL)先弄到 precompile header 裡來增加編譯的效率。你不想使用也可以,在 project 設定下可以取消 precompile header 的使用。 |
LouisLu
一般會員 發表:7 回覆:8 積分:3 註冊:2005-01-31 發送簡訊給我 |
|
LouisLu
一般會員 發表:7 回覆:8 積分:3 註冊:2005-01-31 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |