日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WinCE驱动的动态加载

發(fā)布時(shí)間:2023/12/10 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WinCE驱动的动态加载 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

//=====================================================================
//TITLE:
//??? WinCE驅(qū)動(dòng)的動(dòng)態(tài)加載
//AUTHOR:
//??? norains
//DATE:
//??? Monday 22- February-2010
//Environment:
//???? WINDOWS CE 5.0
//=====================================================================

????

???? WinCE驅(qū)動(dòng)的調(diào)試,很多人的第一感覺就是:編寫好DLL文件,接著在PB中添加相關(guān)注冊(cè)表信息,然后將DLL文件包含進(jìn)系統(tǒng),最后生成系統(tǒng),下載,調(diào)試。如果有誤,那么依次按步驟重來。
?
  其實(shí)這種繁瑣的操作完全可以不必要,因?yàn)樵赪inCE下驅(qū)動(dòng)是可以動(dòng)態(tài)加載和卸載的。
  
  驅(qū)動(dòng)的加載和卸載非常簡(jiǎn)單,我們只需要如下兩個(gè)函數(shù):
  

[cpp]?view plaincopy
  • HANDLE?ActivateDeviceEx(??
  • ??LPCWSTR?lpszDevKey,???
  • ??LPCVOID?lpRegEnts,???
  • ??DWORD?cRegEnts,???
  • ??LPVOID?lpvParam??
  • );??
  • ??
  • BOOL?DeactivateDevice(??
  • ??HANDLE?hDevice??
  • );??

  •   
      前者是加載,后者是卸載。
      
      我們首先來看一下加載函數(shù)。這函數(shù)很簡(jiǎn)單,lpszDevKey指向的是驅(qū)動(dòng)信息在注冊(cè)表的位置。比如,我之前文章所提到的虛擬串口的驅(qū)動(dòng)的注冊(cè)表信息如下:
      
      [HKEY_LOCAL_MACHINE/Drivers/Builtin/VirtualSerial]
      ??? "Prefix"="VSP"
      ??? "Dll"="VirtualSerial.dll"
      ??? "Order"=dword:0
      ??? "Index"=dword:1
      ??? "Map_Port"="COM1:"
      
      那么對(duì)于這個(gè)信息而言,lpszDevkey的取值為TEXT("Drivers//Builtin//VirtualSerial")。對(duì)于系統(tǒng)而言,驅(qū)動(dòng)的Root Key為HKEY_LOCAL_MACHINE,故這里并不需要特別指出。換而言之,驅(qū)動(dòng)的信息只能放置于HKEY_LOCAL_MACHINE,因?yàn)槲覀儫o法另外指定Root Key。
      
      接下來再看看別的參數(shù)。lpRegEnts和cRegEnts是和BUS有關(guān)的,但我們接下來的例子并沒有用上,所以這里直接可以忽略,直接賦值NULL即可。其實(shí),如果不使用這兩個(gè)形參的話,我們還可以選擇ActivateDevice。
      
      lpvParam指向的是傳給驅(qū)動(dòng)XXX_Init函數(shù)的形參,如果有特別需求,我們可以通過該指針進(jìn)行傳遞。
      
      函數(shù)功能很簡(jiǎn)單。我們寫一個(gè)功能簡(jiǎn)單的驅(qū)動(dòng),來測(cè)試該函數(shù)是否有效。


      驅(qū)動(dòng)代碼如下:  
      

    [cpp]?view plaincopy
  • DWORD?g_dwParam?=?0;??
  • std::wstring?g_strContext;??
  • ??
  • BOOL?WINAPI?DllEntry(HANDLE?hInstDll,?DWORD?dwReason,?LPVOID?lpvReserved)??
  • {??
  • ????switch?(?dwReason?)???
  • ????{??
  • ????????case?DLL_PROCESS_ATTACH:??
  • ????????break;??
  • ????}??
  • ????return?TRUE;??
  • }??
  • ??
  • ??
  • ??
  • DWORD?FKE_Init(??
  • ??LPCTSTR?pContext,??
  • ??LPCVOID?lpvBusContext??
  • )??
  • {??
  • ?printf("FKE_Init?!/r/n");??
  • ??
  • ?if(pContext?!=?NULL)??
  • ?{??
  • ??g_strContext?=?pContext;??
  • ?}??
  • ??
  • ?if(lpvBusContext?!=?NULL)??
  • ?{??
  • ??g_dwParam?=?*(reinterpret_cast<const?DWORD?*>(lpvBusContext));??
  • ?}??
  • ?return?TRUE;??
  • }??
  • ??
  • ??
  • BOOL?FKE_Deinit(??
  • ????DWORD?dwContext???????
  • ????)??
  • {??
  • ????
  • ?printf("FKE_Deinit?!/r/n");??
  • ?return?TRUE;??
  • }??
  • ??
  • DWORD?FKE_Open(??
  • ????DWORD?dwData,??
  • ????DWORD?dwAccess,??
  • ????DWORD?dwShareMode??
  • ????)??
  • {??
  • ?return?TRUE;??
  • }??
  • ??
  • BOOL?FKE_Close(DWORD?dwHandle)??
  • {??
  • ?return?TRUE;??
  • }??
  • ??
  • ??
  • BOOL?FKE_IOControl(??
  • ????DWORD?dwHandle,??
  • ????DWORD?dwIoControlCode,??
  • ????PBYTE?pBufIn,??
  • ????DWORD?dwBufInSize,??
  • ????PBYTE?pBufOut,??
  • ????DWORD?dwBufOutSize,??
  • ????PDWORD?pBytesReturned??
  • ????)??
  • {???
  • ?return?FALSE;??
  • }??
  • ??
  • DWORD?FKE_Read(DWORD?dwHandle,?LPVOID?pBuffer,?DWORD?dwNumBytes)??
  • {??
  • ?std::vector<TCHAR>?vtVal(MAX_PATH,0);??
  • ?_stprintf(&vtVal[0],TEXT("Context:%s/r/n?Parameter:%d/r/n"),g_strContext.c_str(),g_dwParam);??
  • ??
  • ?int?iLen?=?_tcslen(&vtVal[0]);??
  • ?memcpy(pBuffer,&vtVal[0],iLen?*?2);??
  • ???
  • ?return?iLen;??
  • }??
  • ??
  • DWORD?FKE_Write(DWORD?dwHandle,?LPCVOID?pBuffer,?DWORD?dwNumBytes)??
  • {??
  • ?return?0;??
  • }??
  • ??
  • ??
  • DWORD?FKE_Seek(DWORD?dwHandle,?long?lDistance,?DWORD?dwMoveMethod)??
  • {??
  • ?return?FALSE;??
  • }??
  • ??
  • void?FKE_PowerUp(void)??
  • {??
  • ?return;??
  • }??
  • ??
  • void?FKE_PowerDown(void)??
  • {??
  • ?return;??
  • }??
  • ??
  •   ??

  •   代碼意思很簡(jiǎn)單,就是在加載和卸載的時(shí)候,分別打印信息。然后還有兩個(gè)全局變量,一個(gè)是g_strContext,用來保存成功加載時(shí)的注冊(cè)表位置;另一個(gè)是g_dwParam,用來保存通過ActivateDeviceEx函數(shù)傳遞的第4個(gè)形參。而這兩個(gè)全局變量的數(shù)值,之后我們可以通過ReadFile函數(shù)獲得。只不過FKE_Read函數(shù)健壯性不高,沒有判斷緩沖區(qū)是否為空。但作為測(cè)試,還是夠了。
      
      驅(qū)動(dòng)方面大致如此,我們?cè)賮韺?shí)例看看如何加載驅(qū)動(dòng)。因?yàn)轵?qū)動(dòng)的加載涉及到注冊(cè)表的寫入,所以我這里直接采用了CReg類。關(guān)于該類的代碼,詳情可參見:(http://blog.csdn.net/norains/archive/2007/06/20/1659925.aspx)
      
      我們先寫注冊(cè)表信息:  

    [cpp]?view plaincopy
  • ????#define?DEV_KEY?TEXT("Drivers//Builtin//FakeDriver")??
  • ??
  • CReg?reg;??
  • reg.Create(HKEY_LOCAL_MACHINE,DEV_KEY);??
  • reg.SetDW(TEXT("Order"),0);??
  • reg.SetDW(TEXT("Index"),1);??
  • reg.SetSZ(TEXT("Prefix"),TEXT("FKE"));??
  • reg.SetSZ(TEXT("Dll"),TEXT("//Windows//Driver.dll"));??
  •   
      
      稍微說一下注冊(cè)表寫入數(shù)值的意思。Order是加載的順序,其實(shí)手工加載的話可以無視該字段。Index是打開時(shí)的序號(hào),與此相關(guān)的還有Prefix,為驅(qū)動(dòng)名。Dll則簡(jiǎn)單了,則是我們編譯好的驅(qū)動(dòng)的存放路徑。
      
      接下來就簡(jiǎn)單多了,我們加載驅(qū)動(dòng),然后傳遞一個(gè)DWORD的數(shù)值作為形參:  
    [cpp]?view plaincopy
  • DWORD?dwParam?=?89;??
  • HANDLE?hd?=?ActivateDeviceEx(DEV_KEY,NULL,0,&dwParam);??
  • ??
  • HANDLE?hDriver?=?CreateFile(TEXT("FKE1:"),??
  • ???GENERIC_READ?|?GENERIC_READ,??
  • ???0,??
  • ???NULL,??
  • ???OPEN_EXISTING,??
  • ???FILE_ATTRIBUTE_NORMAL,??
  • ???NULL);??
  • ??
  • std::vector<TCHAR>?vtBuf(MAX_PATH);??
  • DWORD?dwRead?=?0;??
  • ReadFile(hDriver,&vtBuf[0],vtBuf.size(),&dwRead,NULL);??
  • ??
  • ????CloseHandle(hDriver);??
  •  ??

  •   如果運(yùn)行這段代碼,你則會(huì)看到ReadFile之后,vtBuf則會(huì)存儲(chǔ)到相應(yīng)的數(shù)值。在我的平臺(tái)上,某次運(yùn)行時(shí)的數(shù)值如下:
      
      Context:Driver/Active/37 Parameter:89
      
      最后,就是卸載驅(qū)動(dòng)。這個(gè)最簡(jiǎn)單,直接傳遞ActivateDeviceEx執(zhí)行成功后返回的數(shù)值即可:

    總結(jié)

    以上是生活随笔為你收集整理的WinCE驱动的动态加载的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。