电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

《Undocumented Windows 2000 Secrets》翻譯 --- 第三章(1)

瀏覽:111日期:2023-08-27 17:46:38

第三章 編寫(xiě)內(nèi)核模式驅(qū)動(dòng)程序

翻譯: Kendiv

更新: Monday, February 07, 2005

在下一章中,我們會(huì)經(jīng)常訪問(wèn)那些僅在內(nèi)核模式下才有效的系統(tǒng)資源。大量的示例代碼都被設(shè)計(jì)為內(nèi)核驅(qū)動(dòng)例程( Kernel-mode driver routine )。因此,需要有關(guān)開(kāi)發(fā)此種軟件的基本知識(shí)。因?yàn)槲也荒芗俣ㄋ凶x者都有這方面的經(jīng)驗(yàn),我會(huì)在此簡(jiǎn)要地介紹一下內(nèi)核模式驅(qū)動(dòng)程序編程,不過(guò)這僅集中在如何使用驅(qū)動(dòng)開(kāi)發(fā)向?qū)Вㄔ诒緯?shū)光盤(pán)上)。

本章還將討論 Windows 2000 服務(wù)控制管理器( Service Control Manager , SCM )的基本知識(shí),這包括 SCM 如何允許在運(yùn)行時(shí)加載、控制和卸載驅(qū)動(dòng)程序, resulting in wonderfully short change-build-test turnaround cycles 。本章的題目或許會(huì)讓人有些誤解,驅(qū)動(dòng)一詞通常與控制硬件的底層軟件相關(guān)。事實(shí)上,很多內(nèi)核程序員每天都在做這些事情。不過(guò), Windows 2000 的驅(qū)動(dòng)程序分層模式允許做比這更多的事情。內(nèi)核驅(qū)動(dòng)程序可以完成任意復(fù)雜的任務(wù),若不考慮它們運(yùn)行于更高的 CPU 特權(quán)級(jí)別上而且使用不同的開(kāi)發(fā)接口,那它們很像用戶模式下的 DLL 。在此,我們將使用這種強(qiáng)大的開(kāi)發(fā)技術(shù)來(lái)偵測(cè) Windows 2000 的內(nèi)部秘密,使用內(nèi)核驅(qū)動(dòng)程序就像駕駛從狹小的用戶模式飛往 Windows 2000 內(nèi)核的太空飛船。

創(chuàng)建一個(gè)驅(qū)動(dòng)程序的骨架

即使長(zhǎng)時(shí)間開(kāi)發(fā) Win32 應(yīng)用程序和庫(kù)的開(kāi)發(fā)人員,在首次編寫(xiě)內(nèi)核驅(qū)動(dòng)程序時(shí),也會(huì)感覺(jué)像是一個(gè)絕對(duì)的初學(xué)者。這是因?yàn)?,?nèi)核模式下的代碼運(yùn)行在一個(gè)完全不同的操作系統(tǒng)環(huán)境中。 Win32 開(kāi)發(fā)人員的工作僅局限在屬于 Windows 2000 Win32 子系統(tǒng)的幾個(gè)系統(tǒng)組件上。其他開(kāi)發(fā)人員可能編寫(xiě) POSI 或 OS/2 應(yīng)用程序, Windows 2000 的附加子系統(tǒng)為它們提供支持。感謝子系統(tǒng)這個(gè)概念, Windows 2000 就像一個(gè)變色龍 --- 它可通過(guò)這些子系統(tǒng)(前面提及的)導(dǎo)出不同的應(yīng)用程序開(kāi)發(fā)接口來(lái)模擬不同的操作系統(tǒng)。與此相反,內(nèi)核模式的代碼可以看到“真實(shí)”的 Windows 2000 操作系統(tǒng)。它們使用的接口可以稱之為“最終邊界”。當(dāng)然,這并不是說(shuō),內(nèi)核模式完全擺脫了子系統(tǒng)。在第二章中,我們看到 win32k.sys 就是 Win32 GUI 和窗口管理器在內(nèi)核模式下的分支,將它們放在內(nèi)核是出于性能考慮。然而, win32k.sys 導(dǎo)出的 API 函數(shù)集合中只有一小部分出現(xiàn)在了 gdi32.dll 和 user32.dll 中,這也意味著只有這一小部分函數(shù)可以作為 Win32 API 函數(shù)來(lái)使用,因此, Win32K 決不只是 Win32 踏入內(nèi)核世界的一腳,實(shí)際上,應(yīng)把它看作是一個(gè)高性能的內(nèi)核模式的圖形引擎。

Windows 2000 DDK Device Driver Kit

由于內(nèi)核模式下的編程使用了不同的系統(tǒng)接口,在 Win32 編程中經(jīng)常使用的頭文件和庫(kù)都將無(wú)法在內(nèi)核模式下使用。針對(duì) Win32 開(kāi)發(fā),微軟提供了 Platform Software Development Kit ( SDK )。而與內(nèi)核模式的驅(qū)動(dòng)開(kāi)發(fā)相關(guān)的是, Windows 2000 Device Driver Kit ( DDK )。隨文檔一起, DDK 還提供了特殊的頭文件和導(dǎo)入庫(kù),這些都是 Windows 2000 內(nèi)核模塊必須的接口。安裝完 DDK 之后,接下來(lái)你應(yīng)該打開(kāi) Visual C/C++ ,把 DDK 的路徑加入到編譯器和鏈接器的目錄列表中。在主菜單中選擇 Tools à Options ,然后單擊 DirectorIEs 。在目錄選擇下拉列表中選擇 Include files ,然后將 DDK 的適當(dāng)路徑加入,如 3-1 所示。默認(rèn)情況下, DDK 將安裝到 NTDDK 目錄下, included 文件位于 NTDDKinc 子目錄中。需要注意的是,請(qǐng)將新添加的路徑置于原有路徑的上方,這樣就會(huì)使用新的頭文件或者庫(kù)。

圖 3-1 添加 DDK 頭文件路徑

圖 3-2 添加 DDK 導(dǎo)入庫(kù)路徑

在添加完 DDK 頭文件路徑后,用同樣的方法添加導(dǎo)入庫(kù)的路徑。 DDK 包含兩組導(dǎo)入庫(kù),一組叫做 free ( release ) builds ,另一組叫做 checked ( debug ) builds 。其對(duì)應(yīng)的目錄為: NTDDKlibfrei386 和 NTDDKlibchki386 ,參見(jiàn) 3-2 。

DDK 開(kāi)發(fā)環(huán)境與 Win32 模式有所不同,下面給出二者之間的一些明顯區(qū)別:

l 對(duì)于 Win32 程序員來(lái)說(shuō),主要的頭文件是 windows.h ,對(duì)于內(nèi)核模式代碼來(lái)說(shuō),應(yīng)使用 ntddk.h 替代之。

l 主進(jìn)入點(diǎn)函數(shù)叫做 DirverEntry() ,而不再是 WinMain() 或 main() 。 列表 3-1 給出了它們的原型。

l 不能再使用一些常見(jiàn)的 Win32 數(shù)據(jù)類型,如 BYTE 、 Word 和 DWORD 。 DDK 使用 UCHAR 、 USHORT 、 ULONG 等。不過(guò),很容易就能定義你自己喜歡的類型, 列表 3-2 給出了這樣的一個(gè)示例。

NTSTATUS DriverEntry ( PDRIVER_OBJECT pDriverObject,

PUNICODE_STRING pusRegistryPath);

列表 3-1 DriverEntry 函數(shù)的原型

typedef UCHAR BYTE, *PBYTE;

typedef USHORT WORD, *PWORD;

typedef ULONG DWORD, *PDWORD;

列表 3-2 定義常見(jiàn)的 Win32 數(shù)據(jù)類型

此外,還需要注意 Windows NT 4.0 和 Windows 2000 所使用的 DDK 之間的差別,有三點(diǎn)不同需要注意,如下:

l 默認(rèn)情況下, Windows NT 4.0 DDK 的主目錄叫做 DDK ,而 Windows 2000 DDK 叫做 NTDDK

l 在 Windows NT 4.0 DDK 中,主要的頭文件 ntddk.h 位于主目錄之下。而在 Windows 2000 DDK 中,該文件被移到了 NTDDKDDK 子目錄下。

l 導(dǎo)入庫(kù)的路徑也發(fā)生了變化: libi386free 變成了 libfrei386 , libi386checked 變成了 libchki386 。

我不知道微軟的這種改變有什么實(shí)際意義,不過(guò)為了生活,我們還是需要了解其變化 J 。

可定制的驅(qū)動(dòng)程序向?qū)?

開(kāi)發(fā)內(nèi)核驅(qū)動(dòng)程序的主要困難在于 Visual C/C++ 沒(méi)有提供此種類型的工程向?qū)?。幸運(yùn)的是, MSDN 里有一系列不錯(cuò)的關(guān)于 Windows NT 內(nèi)核驅(qū)動(dòng)開(kāi)發(fā)的文章,是 Ruediger R.Asche. 在 1994 至 1995 年編寫(xiě)的。其中的兩篇文章( Asche 1995a , 1995b )詳細(xì)說(shuō)明了如何在 Visual C/C++ 中加入自定義的驅(qū)動(dòng)程序向?qū)?,這些文章給了我很大的幫助,盡管原始向?qū)У妮敵鑫募荒軡M足我的所有需求,但這是一個(gè)很好的開(kāi)始。我提供的內(nèi)核驅(qū)動(dòng)向?qū)⒒?Ruediger Asche 的原始向?qū)Мa(chǎn)生的輸出文件。

我提供的驅(qū)動(dòng)向?qū)У乃性创a位于本書(shū)光盤(pán)的 srcw2k_wiz 目錄。通過(guò)閱讀這些代碼,你會(huì)發(fā)現(xiàn)它實(shí)際的標(biāo)題“ SBS Windows 2000 Code Wizard ”。事實(shí)上,這是一個(gè)一般性的 Windows 2000 程序骨架生成器,該生成器可以產(chǎn)生多種類型的程序,包括 Win32 DLL 和應(yīng)用程序。不過(guò),光盤(pán)中的配置文件針對(duì)內(nèi)核驅(qū)動(dòng)開(kāi)發(fā)做了一定的修改?;旧蟻?lái)說(shuō),我提供的向?qū)且粋€(gè)文件轉(zhuǎn)換器,它讀取一組文件,然后按照一些簡(jiǎn)單的規(guī)則將它們進(jìn)行轉(zhuǎn)換,最后將結(jié)果寫(xiě)入另一組文件中。輸入文件是模板,輸出文件是 C 工程文件。通過(guò)修改模板文件,該向?qū)Э梢宰兂梢粋€(gè) DLL 向?qū)У鹊?。必須提?7 個(gè)模板文件(如果丟失了某一個(gè),會(huì)產(chǎn)生錯(cuò)誤):

l 擴(kuò)展名為 .tw 的文件是 workspace 模板,此種文件將會(huì)被保存為 Visual Studio 的工程文件 .dsw 。

l 擴(kuò)展名為 .tp 的文件是工程模板,此種文件將被保存為 .dsp 文件。工程文件由于之關(guān)聯(lián)的 workspace 文件引用,工程文件還包含生成工程的所有配置選項(xiàng)。

l 擴(kuò)展名為 .tc 、 .th 、 .tr 和 .td 的文件都是 C 代碼文件,這些文件最后會(huì)變成相應(yīng)的 .c 、 .h 、 .rc 和 .def 文件。

l 擴(kuò)展名為 .ti 的是 icon 文件,該文件會(huì)被直接保存為 .ico 文件。

這七個(gè)文件是一個(gè)新工程所必需的。 .def 文件以一種較老風(fēng)格的方法從 DLL 中導(dǎo)出 API 函數(shù),不過(guò)我更喜歡 __declspec(dllexport) 方式。因?yàn)轵?qū)動(dòng)程序通常不導(dǎo)出函數(shù),所以我省略了 .td 模板,導(dǎo)致的結(jié)果是,在開(kāi)始時(shí),向?qū)?huì)報(bào)告一個(gè)錯(cuò)誤。我還省略了資源腳本和 icon 文件,不過(guò)經(jīng)驗(yàn)告訴我,最好提供它們。采用的轉(zhuǎn)換規(guī)則也非常簡(jiǎn)單,僅包含一個(gè)很短的字符串替換列表。在掃描模板文件時(shí),轉(zhuǎn)換器查找以 % 號(hào)開(kāi)始的轉(zhuǎn)義符。當(dāng)它找到后,會(huì)根據(jù) % 后的字符來(lái)決定執(zhí)行什么樣的動(dòng)作。 3-1 列出了驗(yàn)證過(guò)的轉(zhuǎn)義符。

表 3-1 中有幾處需參考配置文件 ---w2k_wiz.ini 。 示例 3-1 給出了其默認(rèn)設(shè)置。在使用向?qū)е?,你?yīng)該將光盤(pán) srcw2k_wizrelease 目錄下的 w2k_wiz.exe 、 w2k_wiz.ini 和所有的 w2k_wiz.t* 模板文件復(fù)制到你的硬盤(pán)上,然后編輯配置文件,將對(duì)應(yīng)內(nèi)容改為你自己的設(shè)置。你還需要修改 Include 、 Free 和 Checked ,使其和你的 DDK 安裝相匹配。如果你使用 Visual C/C++ 6.0 ,可以不改變 Root 的值。如果不,則將其設(shè)為你存放工程文件的根目錄。如果以一個(gè)反斜線結(jié)尾,它將作為默認(rèn)值。在 示例 3-1 中,其鍵值為: HKEY_CURRENT_USERSoftWareMicrosoftoDevStudio6.0Directories ,而 WorkspaceDir 用來(lái)存放基本的工作目錄。

鍵入 w2k_wiz MyDriver 來(lái)執(zhí)行該向?qū)?,它?huì)當(dāng)前目錄下創(chuàng)建名為 MyDriver 的工程目錄,該目錄將存放向?qū)傻?MyDriver.dsw 、 MyDriver.dsp 、 MyDriver.c 、 MyDriver.h 、 MyDriver.rc 和 MyDriver.ico 文件。如果你指定了具體的路徑,則會(huì)在你指定的路徑下創(chuàng)建該目錄。另一個(gè)合法的命令選項(xiàng)是星號(hào),如: w2k_wiz *MyDriver 。在此種情況下,向?qū)Р粫?huì)在當(dāng)前目錄下創(chuàng)建工程目錄,而是去查找 Visual C/C++ 維護(hù)的默認(rèn)的工程根目錄,即 w2k_wiz.ini 中的 Root 所指向的位置。

w2k_wiz.ini

08-27-2000 Sven B. Schreiber

sbs@orgon.com

[Settings]

Text = <SBS Windows 2000 Code Wizard Project>

Company = <MyCompany>

Author = <MyName>

Email = <my@email>

Prefix = <MyPrefix>

Include = E:NTDDKinc

Free = E:NTDDKlibfrei386

Checked = E:NTDDKlibchki386

Root = HKEY_CURRENT_USERSoftwareMicrosoftDevStudio6.0DirectoriesWorkspaceDir

示例 3-1. 向?qū)еС值淖远x選項(xiàng)

運(yùn)行驅(qū)動(dòng)向?qū)?

現(xiàn)在,來(lái)試試這個(gè)驅(qū)動(dòng)向?qū)А?示例 3-2 給出了在 Windows 2000 控制臺(tái)下執(zhí)行 w2k_wiz *TestDrv 后的輸出。這將在 Visual C/C++ 默認(rèn)的工程根目錄下創(chuàng)建一個(gè)名為 TestDrv 的工程目錄。

顯然,除了將 .td 模板轉(zhuǎn)換為 .def 時(shí)出了錯(cuò),其余轉(zhuǎn)換都成功的完成了。因?yàn)樵撓驅(qū)傻尿?qū)動(dòng)程序骨架不需要 .def 文件,所以不需要提供 .td 模板文件?,F(xiàn)在,用 Visual C/C++ 打開(kāi)一個(gè)新的 WorkSpace ,然后你會(huì)發(fā)現(xiàn)一個(gè)名為 TestDrv 的新目錄,該目錄中包含一個(gè)名為 TestDrv.dsw 的 WorkSpace 文件。該文件可以被正確的打開(kāi)。接下來(lái),你因該為生成項(xiàng)目選擇活動(dòng)的配置信息。驅(qū)動(dòng)向?qū)傻?.dsp 文件提供了如下兩個(gè)可用配置:

1. Win2k Kernel-mode Driver(debug)

2. Win2k Kernel-mode Driver(release)

默認(rèn)情況下,將使用 debug 配置來(lái)生成項(xiàng)目,但是你可在任何時(shí)候從 Visual C/C++ 菜單 Build/Set Active Configuration 來(lái)選擇不同的項(xiàng)目配置。最后,你要將光盤(pán)中的 srccommonincludeDrvInfo.h 復(fù)制到你自己的頭文件目錄中。在打開(kāi) TestDrv.rc 時(shí),應(yīng)使用文本模式來(lái)打開(kāi)(如 3-3 所示),這是因?yàn)樵撐募褂昧藖?lái)自 DrvInfo.h 中的復(fù)雜的宏定義,這些宏會(huì)導(dǎo)致資源編輯器異常退出。這個(gè)錯(cuò)誤從 Visual C/C++ 5.0 開(kāi)始,在我印象中,一直沒(méi)有被改正過(guò)。和編輯器不同,資源編譯器( Resource Compiler )可以正常的處理這些宏。

圖 3-3. 以文本模式打開(kāi) TestDrv.c 、 TestDrv.h 和 TestDrv.rc

現(xiàn)在,已經(jīng)為第一次編譯做好了所有準(zhǔn)備。在示例 3-3 中,我通過(guò)選擇 Build/Rebuild 菜單來(lái)建立 Driver 的 Release 版,看起來(lái)一切都正常。順便說(shuō)一下,頭兩行末尾的省略號(hào)表示我截?cái)嗔?Build 命令的輸出。

鏈接器會(huì)在 Debug 或 Release 目錄下創(chuàng)建了一個(gè)名為 TestDrv.sys 的可執(zhí)行文件,這依賴于你的生成配置。 Test Driver 的 Release 版大小為 5.5KB ,其 Debug 版為 8KB 。你可以使用本書(shū)光盤(pán)中的 MFVDasm 或 PEView 來(lái)驗(yàn)證 TestDrv.sys 是否包含有效的代碼和數(shù)據(jù)。

深入驅(qū)動(dòng)程序的骨架

列表 3-3 展示了向?qū)傻?TestDrv.c 。與之相關(guān)的頭文件 TestDrv.h 在 列表 3-4 中。在 列表 3-3 中,請(qǐng)注意標(biāo)題處的 <MyName> 和 <MyCompany> 標(biāo)志。如果 w2k_wiz.ini 中的作者和公司名稱正確,那你自己的名字和相應(yīng)的公司名稱將會(huì)替代它們。

// TestDrv.c

// 08-07-2000 <MyName>

// Copyright @2005 <MyCompany>

#define _TESTDRV_SYS_

#include <ntddk.h>

#include 'TestDrv.h'

// =================================================================

// DISCLAIMER

// =================================================================

/*

This software is provided 'as is' and any express or implied

warranties, including, but not limited to, the implied warranties of

merchantability and fitness for a particular purpose are disclaimed.

In no event shall the author <MyName> be liable for any

direct, indirect, incidental, special, exemplary, or consequential

damages (including, but not limited to, procurement of substitute

goods or services; loss of use, data, or profits; or business

interruption) however caused and on any theory of liability,

whether in contract, strict liability, or tort (including negligence

or otherwise) arising in any way out of the use of this software,

even if advised of the possibility of such damage.

*/

// =================================================================

// REVISION HISTORY

// =================================================================

/*

08-07-2000 V1.00 Original version.

*/

// =================================================================

// GLOBAL DATA

// =================================================================

PRESET_UNICODE_STRING (usDeviceName, CSTRING (DRV_DEVICE));

PRESET_UNICODE_STRING (usSymbolicLinkName, CSTRING (DRV_LINK ));

PDEVICE_OBJECT gpDeviceObject = NULL;

PDEVICE_CONTEXT gpDeviceContext = NULL;

// =================================================================

// DISCARDABLE FUNCTIONS

// =================================================================

NTSTATUS DriverInitialize (PDRIVER_OBJECT pDriverObject,

PUNICODE_STRING pusRegistryPath);

NTSTATUS DriverEntry (PDRIVER_OBJECT pDriverObject,

PUNICODE_STRING pusRegistryPath);

// -----------------------------------------------------------------

#ifdef ALLOC_PRAGMA

#pragma alloc_text (INIT, DriverInitialize)

#pragma alloc_text (INIT, DriverEntry)

#endif

// =================================================================

// DEVICE REQUEST HANDLER

// =================================================================

NTSTATUS DeviceDispatcher (PDEVICE_CONTEXT pDeviceContext,

PIRP pIrp)

{

PIO_STACK_LOCATION pisl;

DWORD dInfo = 0;

NTSTATUS ns = STATUS_NOT_IMPLEMENTED;

pisl = IoGetCurrentIrpStackLocation (pIrp);

switch (pisl->MajorFunction)

{

case IRP_MJ_CREATE:

case IRP_MJ_CLEANUP:

case IRP_MJ_CLOSE:

{

ns = STATUS_SUCCESS;

break;

}

}

pIrp->IoStatus.Status = ns;

pIrp->IoStatus.Information = dInfo;

IoCompleteRequest (pIrp, IO_NO_INCREMENT);

return ns;

}

// =================================================================

// DRIVER REQUEST HANDLER

// =================================================================

NTSTATUS DriverDispatcher (PDEVICE_OBJECT pDeviceObject,

PIRP pIrp)

{

return (pDeviceObject == gpDeviceObject

? DeviceDispatcher (gpDeviceContext, pIrp)

: STATUS_INVALID_PARAMETER_1);

}

// -----------------------------------------------------------------

void DriverUnload (PDRIVER_OBJECT pDriverObject)

{

IoDeleteSymbolicLink (&usSymbolicLinkName);

IoDeleteDevice (gpDeviceObject);

return;

}

// =================================================================

// DRIVER INITIALIZATION

// =================================================================

NTSTATUS DriverInitialize (PDRIVER_OBJECT pDriverObject,

PUNICODE_STRING pusRegistryPath)

{

PDEVICE_OBJECT pDeviceObject = NULL;

NTSTATUS ns = STATUS_DEVICE_CONFIGURATION_ERROR;

if ((ns = IoCreateDevice (pDriverObject, DEVICE_CONTEXT_,

&usDeviceName, FILE_DEVICE_CUSTOM,

0, FALSE, &pDeviceObject))

== STATUS_SUCCESS)

{

if ((ns = IoCreateSymbolicLink (&usSymbolicLinkName,

&usDeviceName))

== STATUS_SUCCESS)

{

gpDeviceObject = pDeviceObject;

gpDeviceContext = pDeviceObject->DeviceExtension;

gpDeviceContext->pDriverObject = pDriverObject;

gpDeviceContext->pDeviceObject = pDeviceObject;

}

else

{

IoDeleteDevice (pDeviceObject);

}

}

return ns;

}

// -----------------------------------------------------------------

NTSTATUS DriverEntry (PDRIVER_OBJECT pDriverObject,

PUNICODE_STRING pusRegistryPath)

{

PDRIVER_DISPATCH *ppdd;

NTSTATUS ns = STATUS_DEVICE_CONFIGURATION_ERROR;

if ((ns = DriverInitialize (pDriverObject, pusRegistryPath))

== STATUS_SUCCESS)

{

ppdd = pDriverObject->MajorFunction;

ppdd [IRP_MJ_CREATE ] =

ppdd [IRP_MJ_CREATE_NAMED_PIPE ] =

ppdd [IRP_MJ_CLOSE ] =

ppdd [IRP_MJ_READ ] =

ppdd [IRP_MJ_WRITE ] =

ppdd [IRP_MJ_QUERY_INFORMATION ] =

ppdd [IRP_MJ_SET_INFORMATION ] =

ppdd [IRP_MJ_QUERY_EA ] =

ppdd [IRP_MJ_SET_EA ] =

ppdd [IRP_MJ_FLUSH_BUFFERS ] =

ppdd [IRP_MJ_QUERY_VOLUME_INFORMATION] =

ppdd [IRP_MJ_SET_VOLUME_INFORMATION ] =

ppdd [IRP_MJ_DIRECTORY_CONTROL ] =

ppdd [IRP_MJ_FILE_SYSTEM_CONTROL ] =

ppdd [IRP_MJ_DEVICE_CONTROL ] =

ppdd [IRP_MJ_INTERNAL_DEVICE_CONTROL ] =

ppdd [IRP_MJ_SHUTDOWN ] =

ppdd [IRP_MJ_LOCK_CONTROL ] =

ppdd [IRP_MJ_CLEANUP ] =

ppdd [IRP_MJ_CREATE_MAILSLOT ] =

ppdd [IRP_MJ_QUERY_SECURITY ] =

ppdd [IRP_MJ_SET_SECURITY ] =

ppdd [IRP_MJ_POWER ] =

ppdd [IRP_MJ_SYSTEM_CONTROL ] =

ppdd [IRP_MJ_DEVICE_CHANGE ] =

ppdd [IRP_MJ_QUERY_QUOTA ] =

ppdd [IRP_MJ_SET_QUOTA ] =

ppdd [IRP_MJ_PNP ] = DriverDispatcher;

pDriverObject->DriverUnload = DriverUnload;

}

return ns;

}

// =================================================================

// END OF PROGRAM

// =================================================================

列表 3-3. 驅(qū)動(dòng)程序骨架的源代碼

// TestDrv.h

// 08-07-2000 <MyName>

// Copyright @2005 <MyCompany>

// =================================================================

// PROGRAM IDENTIFICATION

// =================================================================

#define DRV_BUILD 1

#define DRV_VERSION_HIGH 1

#define DRV_VERSION_LOW 0

// -----------------------------------------------------------------

#define DRV_DAY 07

#define DRV_MONTH 02

#define DRV_YEAR 2005

// -----------------------------------------------------------------

// Customize these settings by editing the configuration file

// D:etc32w2k_wiz.ini

#define DRV_MODULE TestDrv

#define DRV_NAME <SBS Windows 2000 Code Wizard Project>

#define DRV_COMPANY <MyCompany>

#define DRV_AUTHOR <MyName>

#define DRV_EMAIL <my@email>

#define DRV_PREFIX <MyPrefix>

// =================================================================

// HEADER FILES

// =================================================================

#include 'drvinfo.h' // defines more DRV_* items

////////////////////////////////////////////////////////////////////

#ifndef _RC_PASS_

////////////////////////////////////////////////////////////////////

// =================================================================

// CONSTANTS

// =================================================================

#define FILE_DEVICE_CUSTOM 0x8000

// =================================================================

// STRUCTURES

// =================================================================

typedef struct _DEVICE_CONTEXT

{

PDRIVER_OBJECT pDriverObject;

PDEVICE_OBJECT pDeviceObject;

}

DEVICE_CONTEXT, *PDEVICE_CONTEXT, **PPDEVICE_CONTEXT;

#define DEVICE_CONTEXT_ sizeof (DEVICE_CONTEXT)

////////////////////////////////////////////////////////////////////

#endif // #ifndef _RC_PASS_

////////////////////////////////////////////////////////////////////

// =================================================================

// END OF FILE

// =================================================================

列表 3-4. 驅(qū)動(dòng)程序骨架的頭文件

標(biāo)簽: Windows系統(tǒng)
主站蜘蛛池模板: 语料库-提供经典范文,文案句子,常用文书,您的写作得力助手 | 北京京云律师事务所| 高通量组织研磨仪-多样品组织研磨仪-全自动组织研磨仪-研磨者科技(广州)有限公司 | 智能型高压核相仪-自动开口闪点测试仪-QJ41A电雷管测试仪|上海妙定 | 首页|专注深圳注册公司,代理记账报税,注册商标代理,工商变更,企业400电话等企业一站式服务-慧用心 | 风信子发稿-专注为企业提供全球新闻稿发布服务 | 红立方品牌应急包/急救包加盟,小成本好项目代理_应急/消防/户外用品加盟_应急好项目加盟_新奇特项目招商 - 中红方宁(北京) 供应链有限公司 | 北京包装设计_标志设计公司_包装设计公司-北京思逸品牌设计 | 河南空气能热水器-洛阳空气能采暖-洛阳太阳能热水工程-洛阳润达高科空气能商行 | 陕西华春网络科技股份有限公司 | 空调风机,低噪声离心式通风机,不锈钢防爆风机,前倾皮带传动风机,后倾空调风机-山东捷风风机有限公司 | 超细|超微气流粉碎机|气流磨|气流分级机|粉体改性机|磨粉机|粉碎设备-山东埃尔派粉体科技 | 【星耀裂变】_企微SCRM_任务宝_视频号分销裂变_企业微信裂变增长_私域流量_裂变营销 | 精密交叉滚子轴承厂家,转盘轴承,YRT转台轴承-洛阳千协轴承 | Eiafans.com_环评爱好者 环评网|环评论坛|环评报告公示网|竣工环保验收公示网|环保验收报告公示网|环保自主验收公示|环评公示网|环保公示网|注册环评工程师|环境影响评价|环评师|规划环评|环评报告|环评考试网|环评论坛 - Powered by Discuz! | 篷房|仓储篷房|铝合金篷房|体育篷房|篷房厂家-华烨建筑科技官网 知名电动蝶阀,电动球阀,气动蝶阀,气动球阀生产厂家|价格透明-【固菲阀门官网】 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 | 电动卫生级调节阀,电动防爆球阀,电动软密封蝶阀,气动高压球阀,气动对夹蝶阀,气动V型调节球阀-上海川沪阀门有限公司 | 衬塑设备,衬四氟设备,衬氟设备-淄博鲲鹏防腐设备有限公司 | 膜结构_ETFE膜结构_膜结构厂家_膜结构设计-深圳市烨兴智能空间技术有限公司 | 电销卡 防封电销卡 不封号电销卡 电话销售卡 白名单电销卡 电销系统 外呼系统 | TPE_TPE热塑性弹性体_TPE原料价格_TPE材料厂家-惠州市中塑王塑胶制品公司- 中塑王塑胶制品有限公司 | 刹车盘机床-刹车盘生产线-龙口亨嘉智能装备 | 热风机_工业热风机生产厂家上海冠顶公司提供专业热风机图片价格实惠 | 世界箱包品牌十大排名,女包小众轻奢品牌推荐200元左右,男包十大奢侈品牌排行榜双肩,学生拉杆箱什么品牌好质量好 - Gouwu3.com | 厌氧工作站-通用型厌氧工作站-上海胜秋科学仪器有限公司 | 集装箱标准养护室-集装箱移动式养护室-广州璟业试验仪器有限公司 | 铝镁锰板_铝镁锰合金板_铝镁锰板厂家_铝镁锰金属屋面板_安徽建科 | 智能汉显全自动量热仪_微机全自动胶质层指数测定仪-鹤壁市科达仪器仪表有限公司 | 微型驱动系统解决方案-深圳市兆威机电股份有限公司 | 海外整合营销-独立站营销-社交媒体运营_广州甲壳虫跨境网络服务 焊管生产线_焊管机组_轧辊模具_焊管设备_焊管设备厂家_石家庄翔昱机械 | 葡萄酒灌装机-食用油灌装机-液体肥灌装设备厂家_青州惠联灌装机械 | 北京发电车出租-发电机租赁公司-柴油发电机厂家 - 北京明旺盛安机电设备有限公司 | 车辆定位管理系统_汽车GPS系统_车载北斗系统 - 朗致物联 | 安徽合肥格力空调专卖店_格力中央空调_格力空调总经销公司代理-皖格制冷设备 | 纸箱抗压机,拉力机,脂肪测定仪,定氮仪-山东德瑞克仪器有限公司 | 飞扬动力官网-广告公司管理软件,广告公司管理系统,喷绘写真条幅制作管理软件,广告公司ERP系统 | 石膏基自流平砂浆厂家-高强石膏基保温隔声自流平-轻质抹灰石膏粉砂浆批发-永康市汇利建设有限公司 | 保镖公司-私人保镖-深圳保镖公司【环宇兄弟保镖】 | CNC机加工-数控加工-精密零件加工-ISO认证厂家-鑫创盟 | 奥因-光触媒除甲醛公司-除甲醛加盟公司十大品牌 |