热re99久久精品国99热,精品多毛少妇人妻AV免费久久,99精品伊人久久久大香线蕉http://www.shnenglu.com/oosky/category/711.html一天一個腳印...... <br>每日一句: <script language="javascript" charset="utf-8" src="http://sl.iciba.com/spdshow.php"></script>zh-cnMon, 19 May 2008 21:16:02 GMTMon, 19 May 2008 21:16:02 GMT60驅(qū)動開程序發(fā)—安裝 http://www.shnenglu.com/oosky/archive/2006/01/03/2370.html任我行任我行Tue, 03 Jan 2006 02:11:00 GMThttp://www.shnenglu.com/oosky/archive/2006/01/03/2370.htmlhttp://www.shnenglu.com/oosky/comments/2370.htmlhttp://www.shnenglu.com/oosky/archive/2006/01/03/2370.html#Feedback4http://www.shnenglu.com/oosky/comments/commentRss/2370.htmlhttp://www.shnenglu.com/oosky/services/trackbacks/2370.html作為一個完整的例子,你開發(fā)出來驅(qū)動還必須要能安裝。所以下面我講一下安裝。

如果前面的編譯過程沒有錯誤的話,現(xiàn)在我們應(yīng)該已經(jīng)得到了一個HelloWDM.sys文件,假設(shè)它是放在D:\HelloWDM\objfre\i386中。

安裝WDM驅(qū)動程序可以用兩種方法,一種是利用注冊表,還有一種是利用INF文件。我們一般是采用INF文件(這是微軟推薦的)。INF文件可以在 WINNT\INF 目錄中找到很多。為了順利安裝,我在這里先給出 HelloWDM 所需要的 HelloWDM.INF 文件:

;; The Win2K DDK documentation contains an excellent INF reference.

;--------- Version Section ---------------------------------------------------

[Version]
Signature="$CHICAGO$"
Provider=LC_Device
DriverVer=8/21/2002,3.0.0.3

; If device fits one of the standard classes, use the name and GUID here,
; otherwise create your own device class and GUID as this example shows.

Class=Unknown
ClassGUID={ff646f80-8def-11d2-9449-00105a075f6b}

;--------- SourceDiskNames and SourceDiskFiles Section -----------------------

; These sections identify source disks and files for installation. They are
; shown here as an example, but commented out.

[SourceDisksNames]
1 = "HelloWDM",Disk1,,

[SourceDisksFiles]
HelloWDM.sys = 1,objfre\i386,

;--------- ClassInstall/ClassInstall32 Section -------------------------------

; Not necessary if using a standard class

; 9X Style
[ClassInstall]
Addreg=Class_AddReg

; NT Style
[ClassInstall32]
Addreg=Class_AddReg

[Class_AddReg]
HKR,,,,%DeviceClassName%
HKR,,Icon,,"-5"

;--------- DestinationDirs Section -------------------------------------------

[DestinationDirs]
YouMark_Files_Driver = 10,System32\Drivers

;--------- Manufacturer and Models Sections ----------------------------------

[Manufacturer]
%MfgName%=Mfg0

[Mfg0]

; PCI hardware Ids use the form
; PCI\VEN_aaaa&DEV_bbbb&SUBSYS_cccccccc&REV_dd
;改成你自己的ID
%DeviceDesc%=YouMark_DDI, PCI\VEN_9999&DEV_9999

;---------- DDInstall Sections -----------------------------------------------
; --------- Windows 9X -----------------

; Experimentation has shown that DDInstall root names greater than 19 characters
; cause problems in Windows 98

[YouMark_DDI]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_9X_AddReg

[YouMark_9X_AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,HelloWDM.sys
HKR, "Parameters", "BreakOnEntry", 0x00010001, 0

; --------- Windows NT -----------------

[YouMark_DDI.NT]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_NT_AddReg

[YouMark_DDI.NT.Services]
Addservice = HelloWDM, 0x00000002, YouMark_AddService

[YouMark_AddService]
DisplayName = %SvcDesc%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %10%\System32\Drivers\HelloWDM.sys

[YouMark_NT_AddReg]
HKLM, "System\CurrentControlSet\Services\HelloWDM\Parameters",\
"BreakOnEntry", 0x00010001, 0


; --------- Files (common) -------------

[YouMark_Files_Driver]
HelloWDM.sys

;--------- Strings Section ---------------------------------------------------

[Strings]
ProviderName="Flying L Co.,Ltd."
MfgName="LC Soft"
DeviceDesc="Hello World WDM!"
DeviceClassName="LC_Device"
SvcDesc="???"



注意它可以同時在Win98或者Win2000中使用(系統(tǒng)會通過這個INF文件里面的字段名稱,自動選擇適合當前系統(tǒng)的安裝方法的)。關(guān)于INF文件的各個字段含義現(xiàn)在我也不知道,所以也沒有辦法說清楚,如果誰看到這篇文章,而又知道的話,不妨為我一份。

準備好這個 HelloWDM.INF 文件后,讓我們打開控制面板,雙擊“添加/刪除硬件”,選擇“添加/排除設(shè)備故障”->“添加新設(shè)備”->“否,我想從列表選擇硬件”->“其它設(shè)備”->“從磁盤安裝”,選擇 HelloWDM.INF 所在的路徑,然后安裝。

當安裝完成后,系統(tǒng)就會添加上你寫好的驅(qū)動程序了。(可以在“設(shè)備管理器”中查看到)。然后重啟電腦,這個驅(qū)動程序就投入使用啦。

關(guān)于安裝,我也只知道這么多,到底安裝驅(qū)動程序時,操作系統(tǒng)都作了些什么,我也不是很清楚,等我弄明白了我再貼上。



任我行 2006-01-03 10:11 發(fā)表評論
]]>
驅(qū)動程序開發(fā)—編譯正傳 http://www.shnenglu.com/oosky/archive/2006/01/03/2369.html任我行任我行Tue, 03 Jan 2006 02:10:00 GMThttp://www.shnenglu.com/oosky/archive/2006/01/03/2369.htmlhttp://www.shnenglu.com/oosky/comments/2369.htmlhttp://www.shnenglu.com/oosky/archive/2006/01/03/2369.html#Feedback0http://www.shnenglu.com/oosky/comments/commentRss/2369.htmlhttp://www.shnenglu.com/oosky/services/trackbacks/2369.html我在前面也講過了一些關(guān)于編譯環(huán)境及工具的。在這里結(jié)合本例子我再說一下:

DDK分為98 DDK和2000 DDK兩種,它們工作起來是大同小異的,不過有些驅(qū)動程序只能在2000 DDK中使用。由于Win98注定是一種即將被淘汰的操作系統(tǒng)了,所以我學(xué)習的時候也沒有過多的關(guān)注,我用的是2000的DDK,所以以下的所有內(nèi)容都是針對2000 DDK的。

·準備工作
1、確定你已經(jīng)安裝了Visual C++
2、安裝2000 DDK
3、安裝2000 DDK成功后,在“開始”->“程序”里應(yīng)該有“Development Kits”->“Windows 2000 DDK”的項目。
注意一定要先安裝好VC,然后才安裝DDK,這個順序決不能顛倒!!
4、保證DDKROOT環(huán)境變量設(shè)置為Windows 2000 DDK的基目錄,如果不是的話,請在控制面板“系統(tǒng)”屬性的“高級”標簽環(huán)境變量編輯器中設(shè)置好這個環(huán)境變量。


·編寫必需的文件
編譯WDM程序的時候,有兩個文件是必須要有的,它們是:
1、makefile
(這個是什么啊?你可能會問。)對于比較年輕的程序員來說,有可能沒有見過這個文件吧。其實在VC這些IDE出現(xiàn)之前,我們都必須使用makefile來確定項目中哪些文件需要重新編譯,現(xiàn)在的IDE都把這個工作自動做好了
我們要做的工作很簡單,就是提供這樣一個文件,它的內(nèi)容是:

#
# DO NOT EDIT THIS FILE!!!  Edit .\sources. If you want to add a new source
# file to this component.  This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#

!INCLUDE $(NTMAKEENV)\makefile.def


正如它所述,不要編輯這個文件。事實上每個WDM程序所需要的makefile的內(nèi)容都是一樣的,也就是說,我們只需要簡單地copy一個makefile到新的項目中就可以了
2、Sources

TARGETNAME=HelloWDM //編譯出來的驅(qū)動程序的名稱
TARGETTYPE=DRIVER      //編譯的類型是驅(qū)動程序編譯
DRIVERTYPE=WDM           //驅(qū)動程序的類型是WDM驅(qū)動程序
TARGETPATH=OBJ             //生成的文件存放在OBJ目錄中

INCLUDES=$(BASEDIR)\inc;\   //這是需要引入的頭文件
         $(BASEDIR)\inc\ddk;\

TARGETLIBS=$(BASEDIR)\lib\*\free\usbd.lib\  //這是需要引入的庫文件

SOURCES=HelloWDM.cpp\    //這是源碼文件


這個文件指定了驅(qū)動程序目標名是HelloWDM.sys,是一個WDM驅(qū)動程序,生成的文件存放在OBJ目錄中。值得注意的是,“=”前后不能有空格,否則編譯的時候會出錯。


·開始編譯
娃哈哈,前面羅羅嗦嗦講了一大堆,現(xiàn)在終于到重點了。WDM程序的編譯過程比較特殊,它不是在VC里面按F7來編譯的(盡管你可以通過設(shè)置來達到這一目的),而是通過一個DDK實用工具build來完成。下面我們來講講具體步驟:
1、“Debug”版的生成
首先,我們假設(shè)你的源代碼放在D:\HelloWDM里面。請跟著以下步驟:

“開始”->“程序”->“Development Kits”->“Windows 2000 DDK”->“Checked Build Environment”

屏幕將顯示:(有“回車”的那行是需要讀者你親自打進去的)

New or updated MSVC detected.  Updating DDK environment….

Setting environment for using Microsoft Visual C++ tools.
Starting dirs creation…Completed.

D:\NTDDK>cd\HelloWDM    (回車)

D:\HelloWDM>build    (回車)


如果源代碼沒有錯誤的話,生成的HelloWDM.sys將存放在objchk\i386目錄中。

2、“Release”版的生成
請跟著以下步驟:

“開始”->“程序”->“Development Kits”->“Windows 2000 DDK”->“Free Build Environment”

隨后的步驟跟“Debug”版相同,不同的是生成的HelloWDM.sys將存放在objfre\i386目錄中。

任我行 2006-01-03 10:10 發(fā)表評論
]]>
驅(qū)動程序開發(fā)—編譯前傳http://www.shnenglu.com/oosky/archive/2006/01/03/2368.html任我行任我行Tue, 03 Jan 2006 02:08:00 GMThttp://www.shnenglu.com/oosky/archive/2006/01/03/2368.htmlhttp://www.shnenglu.com/oosky/comments/2368.htmlhttp://www.shnenglu.com/oosky/archive/2006/01/03/2368.html#Feedback0http://www.shnenglu.com/oosky/comments/commentRss/2368.htmlhttp://www.shnenglu.com/oosky/services/trackbacks/2368.html好啦,辛辛苦苦終于寫完了程序,讓我們編譯運行吧!按下Ctrl+F5(嘿嘿,讓我們先假設(shè)你習慣用VC來寫程序),我等啊等……疑?怎么毫無動靜的?再看看Output窗口,哇!有幾百個錯誤啊!!不禁頭大——這是怎么回事呢?

原來,WDM程序編譯出來的并不是我們常見的.exe,而是.sys文件,在未經(jīng)設(shè)置編譯環(huán)境之前,是不能直接用VC來編譯的(這就是為什么會有幾百個錯誤了)。這種類型的文件你可以在WINNT\System32\Drivers里面找到很多。其實驅(qū)動程序也是一種PE文件,它同樣由DOS MZ header開頭,也有完整的DOS stub和PE header,同樣擁有Import table和Export table——……那跟普通的PE文件有什么不一樣呢?那么就讓我們先來做個小剖析,加深對.sys文件的認識吧


首先祭出Delphi里附帶的tdump.exe程序。讓我們鍵入:
C:\WINNT\System32\Drivers>tdump ccport.sys -em -ee
參數(shù)-em是列出Import table,-ee是列出Export table。回車之后,屏幕列出一大堆東西:

C:\WINNT\SYSTEM32\DRIVERS>tdump ccport.sys -em -ee
Turbo Dump  Version 5.0.16.12 Copyright ? 1988, 2000 Inprise Corporation
                    Display of File CCPORT.SYS

IMPORT:     NTOSKRNL.EXE={hint:011Fh}.’memcpy’
IMPORT:     NTOSKRNL.EXE={hint:003Dh}.’IoDeleteDevice’
IMPORT:     NTOSKRNL.EXE={hint:0030h}.’IoAttachDeviceToDeviceStack’
IMPORT:     NTOSKRNL.EXE={hint:008Eh}.’KeSetEvent’
IMPORT:     NTOSKRNL.EXE={hint:0068h}.’IofCallDriver’
IMPORT:     NTOSKRNL.EXE={hint:0095h}.’KeWaitForSingleObject’
IMPORT:     NTOSKRNL.EXE={hint:0074h}.’KeInitializeEvent’
IMPORT:     NTOSKRNL.EXE={hint:003Fh}.’IoDetachDevice’
IMPORT:     NTOSKRNL.EXE={hint:00D3h}.’RtlFreeUnicodeString’
IMPORT:     NTOSKRNL.EXE={hint:0077h}.’KeInitializeSpinLock’
IMPORT:     NTOSKRNL.EXE={hint:0129h}.’strcpy’
IMPORT:     NTOSKRNL.EXE={hint:0121h}.’memset’
IMPORT:     NTOSKRNL.EXE={hint:003Ch}.’IoCreateUnprotectedSymbolicLink’
IMPORT:     NTOSKRNL.EXE={hint:0038h}.’IoCreateDevice’
IMPORT:     NTOSKRNL.EXE={hint:00C2h}.’RtlAnsiStringToUnicodeString’
IMPORT:     NTOSKRNL.EXE={hint:0069h}.’IofCompleteRequest’
IMPORT:     NTOSKRNL.EXE={hint:0124h}.’sprintf’
IMPORT:     NTOSKRNL.EXE={hint:003Eh}.’IoDeleteSymbolicLink’
IMPORT:     NTOSKRNL.EXE={hint:0042h}.’IoFreeIrp’
IMPORT:     NTOSKRNL.EXE={hint:004Dh}.’IoInitializeIrp’
IMPORT:     NTOSKRNL.EXE={hint:002Dh}.’IoAllocateIrp’
IMPORT:     NTOSKRNL.EXE={hint:0027h}.’InterlockedExchange’
IMPORT:     NTOSKRNL.EXE={hint:0025h}.’InterlockedCompareExchange’
IMPORT:     NTOSKRNL.EXE={hint:0035h}.’IoCancelIrp’
IMPORT:     NTOSKRNL.EXE={hint:012Ah}.’strlen’
IMPORT:     NTOSKRNL.EXE={hint:0126h}.’strcat’
IMPORT:     NTOSKRNL.EXE={hint:0114h}.’atoi’
IMPORT:     NTOSKRNL.EXE={hint:0128h}.’strcmp’
IMPORT:     NTOSKRNL.EXE={hint:0034h}.’IoBuildSynchronousFsdRequest’
IMPORT:     NTOSKRNL.EXE={hint:00D5h}.’RtlInitAnsiString’
IMPORT:          HAL.DLL={hint:0006h}.’KfAcquireSpinLock’
IMPORT:          HAL.DLL={hint:0009h}.’KfReleaseSpinLock’

EXPORT ord:0001=’Vcomm_DriverControl’



看到了嗎?它主要調(diào)用了NTOSKRNL.EXE和HAL.DLL文件(實際上你會發(fā)現(xiàn),幾乎所有的WDM驅(qū)動程序都會調(diào)用NTOSKRNL.EXE文件,從它的名字你可以看出為什么了吧?),并且輸出了一個函數(shù)“Vcomm_DriverControl”。這表明,其實.sys跟.exe文件一樣,都是一種PE文件來的。不同的是,.sys文件Import的通常是NTOSKRNL.EXE,而.exe文件Import的通常是KERNEL32.DLL和USER32.DLL。

知道了這些有什么用呢?實際上,由于.sys通常不調(diào)用KERNEL32.DLL和USER32.DLL,所以你是不能在設(shè)備驅(qū)動程序里面調(diào)用任何C、C++和Win32函數(shù)的,而且也不能用C++關(guān)鍵字new和delete等(可以用malloc和free來代替),而必須使用大量的內(nèi)核函數(shù)。另外,你應(yīng)該也能看到她調(diào)用了像IoDeleteDevice、IoAttachDeviceToDeviceStack等等函數(shù),這些你以前可能沒有見過的函數(shù)都是些內(nèi)核函數(shù)。為了讀者的方便,下面我列出一些常見的驅(qū)動程序可用的內(nèi)核函數(shù):

Ex…        執(zhí)行支持
Hal…        硬件抽象層(僅NT/Windows 2000)
Io…        I/O管理器(包括即插即用函數(shù))
Ke…        內(nèi)核
Ks…        內(nèi)核流IRP管理函數(shù)
Mm…        內(nèi)存管理器
Ob…        對象管理器
Po…        電源管理
Ps…        進程結(jié)構(gòu)
Rtl…        運行時庫
Se…        安全引用監(jiān)視
Zw…        其他函數(shù)


最后讓我們再來看看,寫設(shè)備驅(qū)動程序時必須注意的一些問題:

1、內(nèi)核宏
如果查看DDK頭文件,會發(fā)現(xiàn)有幾個內(nèi)核函數(shù)是以宏的方式實現(xiàn)的。這種宏中有幾個宏的定義是相當糟糕的。例如,我們看到RemoveHeadList的定義如下:

#define RemoveHeadList(ListHead)
        (ListHead)->Flink;
        {RemoveEntryList((ListHead)->Flink)}


如果以以下方式調(diào)用RemoveHeadList,則將編譯錯誤的代碼:

if(SomethingInList)
        Entry = RemoveHeadList(list);


使這個調(diào)用安全的唯一方法是使用花括號:

if(SomethingInList)
    {
        Entry = RemoveHeadList(list);
    }


所以我們切勿為了貪圖一時的方便,而使用不太規(guī)范的寫法,最好是在所有的if、for和while等語句中使用花括號。

2、驅(qū)動程序函數(shù)名稱
跟C/C++的main()函數(shù)一樣,設(shè)備驅(qū)動程序也有一個必須存在,而且只能以DriverEntry()為名稱的入口函數(shù)。然而,除此之外,我們可以使用任何名字來給其他函數(shù)命名——只要你自己記得就行了,當然,最好符合某些特定的規(guī)范啦,例如匈牙利命名法……

3、安裝時的問題
·在Windows98中驅(qū)動程序可執(zhí)行文件必須是8.3文件名。(別問我為什么,我也不知道,我只能建議你去問比爾該死)
·如果INF文件中含有非法節(jié)的詳細資料,Windows將不使用這個INF文件。

本節(jié)羅羅嗦嗦講了一大堆,跟實際的編程卻并沒有太大的關(guān)系,前傳嘛!就是這樣的啦!



任我行 2006-01-03 10:08 發(fā)表評論
]]>
驅(qū)動程序開發(fā)—Hello Wordhttp://www.shnenglu.com/oosky/archive/2006/01/03/2367.html任我行任我行Tue, 03 Jan 2006 02:07:00 GMThttp://www.shnenglu.com/oosky/archive/2006/01/03/2367.htmlhttp://www.shnenglu.com/oosky/comments/2367.htmlhttp://www.shnenglu.com/oosky/archive/2006/01/03/2367.html#Feedback6http://www.shnenglu.com/oosky/comments/commentRss/2367.htmlhttp://www.shnenglu.com/oosky/services/trackbacks/2367.html 

看了好多天的書!特別到書店買了《Windows 200/xp wdm 設(shè)備驅(qū)動開發(fā)》這本書,在這里我不想怎么評論它!對于高手來說,我覺得她一定不能滿足,但是對于像我這樣想入門的人來說,仿佛看了半天,還是不知道從何下手。什么原理、模型、分層等等講不講,講!絕對應(yīng)該講!但是你得快點告訴我怎么先弄一個像“Hello Word!”的什么簡單來不能再簡單的完整的例子給我呀!到網(wǎng)上找阿找啊!那些高手啊!也不為我們新手寫點圖文并茂的上手資料。沒辦法!結(jié)合自己的需要再參考一些別人的東東,算是自己的一點不成熟的想法吧!

我覺得下面這個介紹非常不錯!我能看懂,所以貼了出來。

我道為什么找不到“Hello Word!”呢?原來在驅(qū)動開發(fā)的例子里是沒有所謂的“Hello World”程序的。這主要還是因為網(wǎng)絡(luò)上的WDM資料太少造成的。但是程序的入口點呢?c語言有Main(),用Vc的常看見的是WinMain(),Delphi開發(fā)的是Program里的Begin,但是驅(qū)動開發(fā)呢?那也是應(yīng)該有程序的入口點啊。后來我才明白了,那就是DriverEntry()函數(shù)。還有一個問題讓我懷疑了老半天,那就是驅(qū)動開發(fā)的源程序中需不需要include頭文件呀?為什么會懷疑呢?那是因為我看了半天的書都沒有看到一個完整的驅(qū)動程序結(jié)構(gòu)。真的是郁悶。下面是我看到的一個完整的結(jié)構(gòu),我先放上來,讓大家看看驅(qū)動開發(fā)的結(jié)構(gòu)吧。

/***************************************************************
程序名稱:Hello World for WDM
文件名稱:HelloWDM.cpp
日期:2002-8-16
***************************************************************/

//一定要的頭文件,聲明了函數(shù)模塊和變量:

#include "HelloWDM.h"

/***************************************************************
函數(shù)名稱:DriverEntry()
功能描述:WDM程序入口(原來的WinMain被換成了DriverEntry,也是驅(qū)動程序的大門)
***************************************************************/

//extern "C"是必須的,表示“用C鏈接”。如果你的文件名是HelloWDM.c的話,這句可以省略。
extern "C"
NTSTATUS DriverEntry(    IN PDRIVER_OBJECT DriverObject, //IN 是一個關(guān)鍵字表示這是一個輸 入?yún)?shù),PDRIVER_OBJECT是一個數(shù)據(jù)結(jié)構(gòu)的指針,就像PCHAR一樣,這個數(shù)據(jù)結(jié)構(gòu)是什么樣子的,后面我會列出來。她描述了一個驅(qū)動設(shè)備對象。
                        IN PUNICODE_STRING RegistryPath)//參數(shù)RegistryPath指定了驅(qū)動程序注冊表健的路徑,因為驅(qū)動程序安裝后總會在系統(tǒng)注冊表里留下一點東西的。
{
    //指定“添加設(shè)備”消息由函數(shù)“HelloWDMAddDevice()”來處理:
    DriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;
    //指定“即插即用”消息由函數(shù)“HelloWDMPnp()”來處理:
    DriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;

    //返回一個NTSTATUS值STATUS_SUCCESS。幾乎所有的驅(qū)動程序例程都必須返回一個NTSTATUS值,這些值在NTSTATUS.H DDK頭文件中有詳細的定義。
    return STATUS_SUCCESS;
}

//NTSTATUS也是一個數(shù)據(jù)類型,上面我所說的消息有點不準確的,準確地說是“I/O請求包”,不過如果像我們以前理解消息那樣來理解也無不可,我覺得兩者太想了。無非就是上層的應(yīng)用程序通過它來告訴驅(qū)動程序,你要給我什么服務(wù)吧!IRP_MJ_PNP就是即插即用處理的請求。你發(fā)沒發(fā)覺上面其實是在制造進入各個房間的“小門”


/***************************************************************
函數(shù)名稱:HelloWDMAddDevice()
功能描述:處理“添加設(shè)備”消息
***************************************************************/

NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
                           IN PDEVICE_OBJECT PhysicalDeviceObject)
{
    //定義一個NTSTATUS類型的返回值:
    NTSTATUS status;
    //定義一個功能設(shè)備對象(Functional Device Object):
    PDEVICE_OBJECT fdo;

    //創(chuàng)建我們的功能設(shè)備對象,并儲存到fdo中:
    status = IoCreateDevice(
        DriverObject,                //驅(qū)動程序?qū)ο?/FONT>
        sizeof(DEVICE_EXTENSION),    //要求的設(shè)備擴展的大小
        NULL,                        //設(shè)備名稱,這里為NULL
        FILE_DEVICE_UNKNOWN,        //設(shè)備的類型,在標準頭文件WDM.H或NTDDK.H中列出的FILE_DEVICE_xxx值之一
        0,                            //各種常量用OR組合在一起,指示可刪除介質(zhì)、只讀等。
        FALSE,                        //如果一次只有一個線程可以訪問該設(shè)備,為TRUE,否則為FALSE
        &fdo);                        //返回的設(shè)備對象

    //NT_SUCCESS宏用于測試IoCreateDevice內(nèi)核是否成功完成。不要忘記檢查對內(nèi)核的所有調(diào)用是否成功。NT_ERROR宏不等同于!NT_SUCCESS,最好使用!NT_SUCCESS,因為除了錯誤外,它還截獲警告信息。
    if( !NT_SUCCESS(status))
        return status;

    //創(chuàng)建一個設(shè)備擴展對象dx,用于存儲指向fdo的指針:
    PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
    dx->fdo = fdo;

    //用IoAttachDeviceToDeviceStack函數(shù)把HelloWDM設(shè)備掛接到設(shè)備棧:
    dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);

    //設(shè)置fdo的flags。有兩個“位”是必須改變的,一個是必須清除DO_DEVICE_INITIALIZING標志,如果在DriverEntry例程中調(diào)用IoCreateDevice(),就不需要清除這個標志位。還有一個是必須設(shè)置DO_BUFFER_IO標志位:
    fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
    fdo->Flags &= ~DO_DEVICE_INITIALIZING;

    //返回值:
    return STATUS_SUCCESS;
}


/***************************************************************
函數(shù)名稱:HelloWDMPnp()
功能描述:處理“即插即用”消息
***************************************************************/

NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
                        IN PIRP Irp)
{
    //創(chuàng)建一個設(shè)備擴展對象dx,用于存儲指向fdo的指針:
    PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

    //首先要通過函數(shù)IoGetCurrentIrpStackLocation()得到當前的IRP,并由此得到Minor Function:
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    ULONG MinorFunction = IrpStack->MinorFunction;

    //然后把這個Minor Function傳遞給下一個設(shè)備棧:
    IoSkipCurrentIrpStackLocation(Irp);
    NTSTATUS status = IoCallDriver( dx->NextStackDevice, Irp);

    //處理“即插即用”次功能代碼:
    //當Minor Function等于IRP_MN_REMOVE_DEVICE時,說明有設(shè)備被拔出或卸下,這時要取消資源分配并刪除設(shè)備:
    if( MinorFunction==IRP_MN_REMOVE_DEVICE)
    {
        //取消設(shè)備接口:
        IoSetDeviceInterfaceState(&dx->ifSymLinkName, FALSE);
        RtlFreeUnicodeString(&dx->ifSymLinkName);
        
        //調(diào)用IoDetachDevice()把fdo從設(shè)備棧中脫開:
        if (dx->NextStackDevice)
            IoDetachDevice(dx->NextStackDevice);
        //刪除fdo:
        IoDeleteDevice(fdo);
    }

    //返回值:
    return status;
}



/***************************************************************
程序名稱:Hello World for WDM
文件名稱:HelloWDM.h
作者:羅聰
日期:2002-8-16
***************************************************************/


//頭文件,只是聲明一些函數(shù)和變量,比較簡單就不多說了,請讀者自行研究:

#ifdef __cplusplus

extern "C"
{
#endif

#include "ntddk.h"

#ifdef __cplusplus
}
#endif

typedef struct _DEVICE_EXTENSION
{
    PDEVICE_OBJECT    fdo;
    PDEVICE_OBJECT    NextStackDevice;
    UNICODE_STRING    ifSymLinkName;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
                           IN PDEVICE_OBJECT PhysicalDeviceObject);

NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
                        IN PIRP Irp);



好了,第一個WDM版的“Hello World”就介紹到這里,雖然實際上它什么都沒有做,但是由于它包含了完整的框架,所以對于向我這樣的新手來說還是很有參考價值的。至于怎么編譯及安裝只有下次再說了



任我行 2006-01-03 10:07 發(fā)表評論
]]>
驅(qū)動程序開發(fā)—工具篇 http://www.shnenglu.com/oosky/archive/2006/01/03/2366.html任我行任我行Tue, 03 Jan 2006 02:05:00 GMThttp://www.shnenglu.com/oosky/archive/2006/01/03/2366.htmlhttp://www.shnenglu.com/oosky/comments/2366.htmlhttp://www.shnenglu.com/oosky/archive/2006/01/03/2366.html#Feedback1http://www.shnenglu.com/oosky/comments/commentRss/2366.htmlhttp://www.shnenglu.com/oosky/services/trackbacks/2366.html因為我學(xué)習的時候是在win2000下進行的,所以一切以我學(xué)習時的配置為準。

第一:安裝win2000操作系統(tǒng),我安裝是win2000高級服務(wù)器版本。

第二:安裝Vc++6.0,我裝的是英文版。

第三:安裝win2000DDK;

通常驅(qū)動程序的調(diào)試都是用ddk在cmd中完成的。這部分我暫時略過。下面先介紹如何設(shè)置vc++6.0在Visual Studio 6.0集成環(huán)境中開發(fā)設(shè)備驅(qū)動程序的方法。

在Windows上,Windows DDK提供的開發(fā)環(huán)境是基于命令行的,操作起來極為不便,而Visual Studio 6.0給我們提供了非常友好易用的集成環(huán)境,讓我們有如虎添翼之感。 
  那么,能否利用Visual Studio的集成環(huán)境來開發(fā)驅(qū)動程序呢?答案是可以的。通過對Visual Studio集成環(huán)境的簡單設(shè)置,創(chuàng)建好自己的驅(qū)動開發(fā)集成環(huán)境就可以了。

首先要求系統(tǒng)已安裝DDK和Visual C++6.0(安裝時選上所有工具),

1、接下來需要改造ddk\bin\setenv.bat 把要求mstools的有關(guān)語句注釋掉(若想在命令行環(huán)境開發(fā)驅(qū)動則還需加入call VC_DIR\VC98\Bin\Vcvars32. bat),以便能在命令行使用vc的相關(guān)工具;若只想在IDE環(huán)境開發(fā)就不必調(diào)用Vcvars32.bat,因為相關(guān)工具的路徑信息可以在vc環(huán)境中設(shè)置.) 

2、創(chuàng)建一個目錄DriverEnv(目錄名隨意),作為你開發(fā)驅(qū)動的大本營 

3、在該目錄下創(chuàng)建一個批處理文件MakeDrvr.bat,內(nèi)容如下:

@echo off 
if "%1"=="" goto usage 
if "%3"=="" goto usage 
if not exist %1\bin\setenv.bat goto usage 
call %1\bin\setenv %1 %4 
%2 

cd %3 
build -b -w %5 %6 %7 %8 %9 

goto exit 

:usage 
echo usage MakeDrvr DDK_dir Driver_Drive Driver_Dir free/checked [build_options]echo eg MakeDrvr %%DDKROOT%% C: %%WDMBOOK%% free -cef 
:exit 


該批處理首先對傳遞的參數(shù)作一些檢查,然后調(diào)用ddk的setenv命令設(shè)置環(huán)境變量,然后改變目錄為源程序所在驅(qū)動器和目錄,并最后調(diào)用build,-b保證顯示完全的錯誤信息,-w保證在屏幕上輸出警告,在vc ide里的output窗口中可以看到這些錯誤和警告。

4.建立一個空白工程 
選File的new菜單項,然后選project欄的makefile,然后輸入路徑,一路next下去即可,visual studio提供兩種配置win32 debug和win32 release. 

5.修改這兩種配置 
  選project的settings菜單項win32 debug: 
  在Build Command Line一欄填入MakeDrvr DDK_DIR SOURCE_DRIVE SOURCE_DIR checked [build options] 
  在Rebuild all options一欄填入 -nmake /a 
  在output file一欄填入與sources文件中的TARGETNAME相同的文件名 
  在Browse info file name一欄填入obj\i386\checked\(與TARGETNAME相同的文件名,見下述).bsc 

  win32 release: 
  在Build Command Line一欄填入MakeDrvr DDK_DIR SOURCE_DRIVE SOURCE_DIR free [build options] 
  在Rebuild all options一欄填入 -nmake /a 
  在output file一欄填入與sources文件中的TARGETNAME相同的文件名 
  在Browse info file name一欄填入obj\i386\free\(與TARGETNAME相同的文件名).bsc 
  注:DDK_DIR一般可以寫成%BASEDIR%,build options一般為-cef即已足夠 

6.添加源文件到工程 
  可以新建,也可以添加,這和普通的win32開發(fā)一樣。 

7.添加資源文件 
  選INSERT的RESOURCE菜單項即可 

8.把文件makefile放入源程序目錄,其內(nèi)容總是 

# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source 
# file to this component. This file merely indirects to the real make file 
# that is shared by all the driver components of the Windows NT DDK 


!INCLUDE $(NTMAKEENV)\makefile.def 

9.把文件Sources放入源程序目錄,內(nèi)容為 
  TARGETNAME=RamDrive//這是要生成的驅(qū)動程序.sys文件的名字 
  TARGETPATH=obj //.sys文件所在目錄的上層目錄,(由于ddk的bug)應(yīng)手工在obj目錄下創(chuàng)建checked和free目錄,以作為.sys的最終存放目錄 
  TARGETTYPE=DRIVER //驅(qū)動程序的類型,一般不變 
  INCLUDES=$(BASEDIR)\inc //ddk包含文件路徑,一般不變 
  SOURCES=RamDrive.cpp RamDrive.rc //源文件(不要頭文件),資源文件 
  BROWSER_INFO = 1 //若想要瀏覽信息,則要有本行;否則可無 

10.因為MakeDrvr.bat在DriverEnv目錄,所以應(yīng)把該目錄添加到vc的Executable files里面 
  選tools的options菜單項,然后選directories頁,在show directories for一欄選擇Executable files,然后添加即可. 

  至此,環(huán)境設(shè)置完畢,你可以按F7, build你的驅(qū)動程序了。



任我行 2006-01-03 10:05 發(fā)表評論
]]>
驅(qū)動程序開發(fā)-概述http://www.shnenglu.com/oosky/archive/2006/01/03/2365.html任我行任我行Tue, 03 Jan 2006 02:03:00 GMThttp://www.shnenglu.com/oosky/archive/2006/01/03/2365.htmlhttp://www.shnenglu.com/oosky/comments/2365.htmlhttp://www.shnenglu.com/oosky/archive/2006/01/03/2365.html#Feedback4http://www.shnenglu.com/oosky/comments/commentRss/2365.htmlhttp://www.shnenglu.com/oosky/services/trackbacks/2365.html很久沒有網(wǎng)了,出了一段時間的差,近來,莫名的就有點郁悶!前不久在大富翁上發(fā)了一份帖子是關(guān)于delphi程序員的發(fā)展,大家的反應(yīng)并不都是很好。于是開始覺得可以考慮換個方向。以前我是做MIS開發(fā)的。換哪個方向呢?人越多的方向,好像越是沒有前途。想想當初上大學(xué),那可是越多人考的學(xué)校,學(xué)費越貴啊!可現(xiàn)在的職業(yè)呢?越多人干的事,越是沒有前途了。考慮來考慮去,決定學(xué)習一下驅(qū)動程序的開發(fā)吧!于是從網(wǎng)上查找了一些資料,看的懂的覺得蠻不錯適合我這種小學(xué)生的就貼了出來,算是學(xué)習筆記吧!

用戶模式與內(nèi)核模式

從Intel80386開始,出于安全性和穩(wěn)定性的考慮,該系列的CPU可以運行于ring0~ring3從高到低四個不同的權(quán)限級,對數(shù)據(jù)也提供相應(yīng)的四個保護級別。運行于較低級別的代碼不能隨意調(diào)用高級別的代碼和訪問較高級別的數(shù)據(jù),而且也只有運行在ring0層的代碼可以直接對物理硬件進行訪問。由于WindowsNT是一個支持多平臺的操作系統(tǒng),為了與其他平臺兼容,它只利用了CPU的兩個運行級別。一個被稱為內(nèi)核模式,對應(yīng)80x86的ring0層,是操作系統(tǒng)的核心部分,設(shè)備驅(qū)動程序就是運行在該模式下;另一個被稱為用戶模式,對應(yīng)80x86的ring3層,操作系統(tǒng)的用戶接口部分(就是我們通常所說的win32 API)以及所有的用戶應(yīng)用程序都運行在該級別。操作系統(tǒng)對運行在內(nèi)核模式下的代碼是不設(shè)防的,所以不管是建設(shè)還是破壞內(nèi)核模式下的編程都是值得去研究的。

圖1-WIN2000系統(tǒng)的分層結(jié)構(gòu)

在物理硬件與系統(tǒng)核心之間有一個硬件抽象層(HardwareAbstractionLayer),它屏蔽了不同平臺硬件的差異,向操作系統(tǒng)的上層提供了一套統(tǒng)一的接口。從圖中我們還可以看到,設(shè)備驅(qū)動程序(DeviceDriver)是被I/O管理器(I/OManager)包圍起來的,即驅(qū)動程序與操作系統(tǒng)上層的通信全部都要通過I/O管理器。這給驅(qū)動程序的編寫帶來了很大的便利,因為很多諸如接收用戶的請求、與用戶程序交換數(shù)據(jù)、內(nèi)存映射、掛接中斷、同步等等麻煩的工作都由I/O管理器代勞了。

驅(qū)動程序的分類

驅(qū)動程序并不像所有人想的那樣一定要和硬件打交道,我粗略的把他分為兩類:硬驅(qū)動和軟驅(qū)動。硬驅(qū)動就是對硬件直接編程進行控制,這類驅(qū)動通常必須遵守硬件的通信協(xié)議,直接對硬件進行端口訪問、中斷響應(yīng)、DMA傳輸。它包括:串、并行口,鍵盤,文件系統(tǒng),SCSI,網(wǎng)絡(luò)等驅(qū)動程序;另外一種軟驅(qū)動呢?不需要直接對硬件就行操作。我認為他可以理解為它是在硬驅(qū)動之上的一層更為高級的驅(qū)動。我想學(xué)習的主要是軟驅(qū)動。

一般來說,設(shè)備驅(qū)動程序的任務(wù)主要有兩個:第一,接受來自用戶程序的讀寫請求,把用戶的數(shù)據(jù)傳送給設(shè)備,或把從設(shè)備接收到的數(shù)據(jù)傳送給用戶;第二,輪詢設(shè)備或處理來自設(shè)備的中斷請求,完成數(shù)據(jù)傳輸。

驅(qū)動程序的結(jié)構(gòu)

在這里,我主要介紹WDM的結(jié)構(gòu)。WDM(Windows driver module)是什么東西呢?在Windows98\95下面,也許你聽得最多的是VXD,我只知道VXD是一種驅(qū)動程序,和WDM差不多的東西。只是因為Windows2000是WindowsNT那條線過來的東西,要加上兩個主要的新功能:即插即用(Plug and Play)和電源管理(Power Menage),又不能用Windows98\95那一套,所以就搞出一個叫WDM這么個東西,來支持PNP和PM.。其實想想,現(xiàn)在的技術(shù)名詞還不是一般的多啊!總之wdm大家都叫它windows驅(qū)動程序模型

Windows2000里有叫即插即用管理器和I\O(此I\O非彼I\O端口)管理器的兩個東西。比如說我在機器上插了一張符合PCI規(guī)范的PCI卡。即插即用管理器會發(fā)現(xiàn)這張卡插在第N個插槽上,然后即插即用管理器會說它找到了這樣一張卡,它就去找有沒有現(xiàn)成的驅(qū)動程序,如果沒有找到,它會告訴我們,我找到了這樣一張卡,請你插入這張卡的驅(qū)動程序盤。好,我們就把驅(qū)動程序盤給它,即插即用管理器會去找驅(qū)動程序盤上的INF文件,找到后它會比較PCI卡上的標志和INF文件里的標志是否相同,如果相同,它就會依照INF文件里提供的路徑去找驅(qū)動程序,找到之后就可以交給I\O管理器,I\O管理器會裝載這個驅(qū)動程序。I\O管理器在做了一些接口的工作后,即插即用管理器會先分配好相關(guān)的資源給PCI卡,比如說I\O端口空間、內(nèi)存空間和中斷向量,然后告訴這張卡的驅(qū)動程序,我給你分配了這些資源,你看怎么的。如果你沒有怎么的或不敢怎么的,那就趕快記下這些資源,以備后用。
    下面說I\O管理器這個東西。上面我們講到I\O管理器裝載這個驅(qū)動程序,驅(qū)動程序有一個大門,還有N多的小門。I\O管理器先從大門進去(因為I\O管理器只找得到大門,I\O管理器是不是很傻,NO,當然有它的道理,你別問我:I\O管理器怎么找到大門的?驅(qū)動程序無非就是一些文件,I\O管理器把這么些文件加載到系統(tǒng)中去),去找一樣?xùn)|西:進小門的地圖。我們要在大門進去的房間里放這張地圖(驅(qū)動程序都是我們造的,我們當然有驅(qū)動程序的地圖啦)。I\O管理器找到了地圖,就可以自由進出大小門了。———這些大小門說白了就是函數(shù)(不要問我函數(shù)是什么東東),小門的地圖就是函數(shù)的地址。I\O管理器知道了這些函數(shù)的地址,當然就可以調(diào)用這些函數(shù)啦。還有一個叫IRP的東西,中文名叫I\O請求包。我們這樣來理解它:在用戶的應(yīng)用程序這一端,要和驅(qū)動程序?qū)υ挘鼈冎g不是簡單的調(diào)用函數(shù)(至于為什么,我現(xiàn)在也不知道),應(yīng)用程序和驅(qū)動程序之間有I\O管理器隔著,應(yīng)用程序?qū)︱?qū)動程序的操作,首先由I\O管理器處理成一個包,這個包里面有應(yīng)用程序請求的操作內(nèi)容、傳送的數(shù)據(jù)等等一些東西,然后I\O管理器把這個包扔給驅(qū)動程序,驅(qū)動程序依照包里的請求,完成操作,把該回傳的數(shù)據(jù)放進包里,再把包扔還給I\O管理器,I\O管理器再把數(shù)據(jù)返回給應(yīng)用程序。——這里所說的包,就是IRP。
    這里說的只是WDM結(jié)構(gòu)的一部分,但是有了這一部分知識,其它部分就不難懂了。通過上面的介紹你看見了什么。你可以想象得出驅(qū)動程序是什么樣子的嗎?我是這樣想的。驅(qū)動程序好像就是一個函數(shù)庫,只不過在大門的地方放了一張地圖。而這個大門與地圖我們見到過嗎?好像有點像dll文件呢。在早些時候我學(xué)dll的時候,我就只會用dll來存放函數(shù)。



任我行 2006-01-03 10:03 發(fā)表評論
]]>
欧美精品福利视频一区二区三区久久久精品 | 女人香蕉久久**毛片精品| 久久香综合精品久久伊人| 国产精品一久久香蕉国产线看观看 | 亚洲国产一成人久久精品| 久久亚洲中文字幕精品有坂深雪| 精品免费tv久久久久久久| 久久精品18| 欧美喷潮久久久XXXXx| 国产精品亚洲综合专区片高清久久久| 久久综合九色综合久99| 久久精品国产亚洲av麻豆色欲| 国内精品伊人久久久久影院对白| 中文精品99久久国产 | 久久亚洲精品成人av无码网站| 日韩亚洲欧美久久久www综合网 | 91精品国产91久久综合| 久久久久人妻一区精品| 亚洲成色WWW久久网站| 久久亚洲国产精品123区| 精品久久久久久成人AV| 久久久精品人妻一区二区三区蜜桃 | 久久精品视频免费| 男女久久久国产一区二区三区| 久久黄视频| 久久久久久久尹人综合网亚洲 | 久久天天躁狠狠躁夜夜96流白浆 | 国产成人久久精品一区二区三区| 色欲综合久久躁天天躁| 国产香蕉97碰碰久久人人| 久久精品一本到99热免费| 精品综合久久久久久97| 色婷婷久久综合中文久久一本| 国产成人精品久久一区二区三区av | 久久综合给合综合久久| 精品99久久aaa一级毛片| 99久久www免费人成精品| 国产精品国色综合久久| 久久精品人人做人人妻人人玩| 亚洲国产另类久久久精品| 婷婷久久久亚洲欧洲日产国码AV|