設備驅動程序的動態加載主要是由服務控制管理程序(Service Control Manager,SCM)系統組件完成的,讓系統加載驅動程序,主要是操作SCM組件.
步驟如下:
首先打開SCM管理器,得到SCM管理器句柄,openSCManager
其次打開了SCM管理器以后,就可以創建一個服務,CreateService
然后打開創建的服務,OpenServicer
最后打開創建的服務后,啟動服務,StartService
簡單的4個步驟,就可以把驅動加載到系統中.我們來解釋下加載的理解,其中最重要的是這個函數CreateService.來看看這個函數的調用,我帖代碼

除開0參數和一些常量權限參數外,還有4個需要自己填寫的參數,1.局_SCM管理器句柄(用openSCManager打開返回的句柄),2和3.都是pszDriverName(這里是一個服務的名稱,一般把驅動文件名作為服務的名稱),4. pszDriverPath(驅動文件的全路徑).看到這4個參數,我們就應該想到了,這個函數就是為驅動文件創建一個服務.然后打開創建的服務,啟動服務,驅動就自動加載到系統中去了(如果把SYS驅動想象成一個DLL的話,SCM管理器就相當於一個LoadDLLexe,我們要做的工作就是先為SYS驅動創建一個服務,然后讓服務控制管理器SCM來啟動服務,這樣就把驅動裝載到系統中了)
既然知道了用服務控制管理程序SCM是以啟動服務來讓系統裝載驅動,那么停止驅動和卸載驅動就很好理解了,只要停止服務,和刪除服務,那么自然就可以停止驅動和卸載驅動了.
下面,我直接貼代碼




我把加載驅動,和卸載驅動封裝成4個子程序,分別是注冊驅動,運行驅動,停止驅動,和卸載驅動.
注冊驅動就是為驅動文件創建一個服務,而運行驅動就是把這個為驅動文件創建的服務進行啟動,啟動服務后,SCM服務管理器就會為系統加載這個服務的驅動文件.經歷注冊驅動和運行驅動后,驅動文件就會被加載進系統(驅動加載后會自動執行DriverEntry這個入口函數,好比DLL被加載后DLL會自動執行DLLMAIN一樣,把SYS想象成系統的一個DLL,一切都很簡單了)
上面的加載驅動和卸載驅動,我們來說下和驅動怎么通訊,這里講一個最簡單的,用DeviceloControl與驅動交流,正常的nt驅動,會在入口函數也就是DriverEntry函數里創建一個設備對象,這個設置對象有個內核名和一個應用層名(應用層名也叫符號鏈接),我們用CreateFile函數打開這個設備,然后就可以用DeviceloControl給這個設備對象發送自定義的IO控制碼,這個IO控制碼就可以被驅動接收到,在驅動的派遣函數中進行處理(這個控制碼簡單說就象是消息,而驅動派遣函數函數就象處理消息的回調函數) 下面是貼代碼

總結下,驅動的加載和卸載就是利用服務控制管理程序(SCM)系統組件,為驅動文件創建一個服務,然后啟動這個服務,讓服務控制管理器把驅動裝載到系統中
加載后就沒SCM什么事了
和驅動的通訊主要是通過設備對象的操作.由於驅動自己在入口函數處虛擬了一個設備,並創造了一個設備名稱(供給應用層程序識別的設備名叫符號鏈接),打開這個設備,然后用DeviceloControl發送Io控制碼.所以與驅動進行交互,一定要知道驅動設備所創造的符號鏈接.
也就是我們可以加載驅動的時候指定任意服務名加載驅動,而與驅動進行交互的時候,一定要知道驅動所創造的符號鏈接(也就是驅動在入口函數所創造的設備對象的名字)*筆者就親測過,在驅動入口函數創造的設備對象是MyDriver的名字,而加載驅動的時候就用自己隨便填的服務名"2"就加載成功了,而與驅動交互是用CreateFile打開名字為MyDriver的設備對象,再調用DeviceloControl發送Io控制碼進行交互的*
源碼下載 http://files.cnblogs.com/qq32175822/SYSControl.rar
參考資料
<<windows驅動開發技術詳解>> 張帆 史采成
看雪論壇http://bbs.pediy.com ID:非安全 地址:http://bbs.pediy.com/showthread.php?t=176945&highlight=%E9%9D%9E%E5%AE%89+%E5%AE%89%E5%85%A8+%E5%85%A8
