?? 驅(qū)動(dòng)程序的安裝.txt
字號(hào):
加載一個(gè)驅(qū)動(dòng)程序,主要就是,在
SYSTEMCurrentControlSetServices 建一個(gè)鍵。
如:
SYSTEMCurrentControlSetServicesTwdm1
Type(1)
ErrorControl(0)
Start(3)
多數(shù)驅(qū)動(dòng)程序都是通過設(shè)置 Start 的值為 0, 1, 2 。
在系統(tǒng)啟動(dòng)的過程中加載驅(qū)動(dòng)程序。
在 win2k 下驅(qū)動(dòng)程序的加載處理上述方式外,
還可以在應(yīng)用程序里用 Service Api 實(shí)現(xiàn),驅(qū)動(dòng)程序的動(dòng)態(tài)加載。
這時(shí)候的 Start 為 3 。
所用到的 Api 為:
OpenSCManager, CreateService, OpenService, StartService
ControlService, DeleteService, CloseServiceHandle
其中需要說明的是:
CreateService :他通過參數(shù)在注冊(cè)表里自動(dòng)創(chuàng)建驅(qū)動(dòng)程序需要的鍵值。
DeleteService :他自動(dòng)刪除驅(qū)動(dòng)程序在注冊(cè)表里創(chuàng)的鍵值。
下面是一個(gè),簡(jiǎn)單的例子:
應(yīng)用程序:
#include "stdafx.h"
#include <windows.h>
#include <winsvc.h>
#include <conio.h>
void DelSvr( char * szSvrName ); //自動(dòng)卸載驅(qū)動(dòng)程序。
int main(int argc, char* argv[])//argc是由命令行傳入的參數(shù),至少大于1,argv[]存放 //程序名之類的
{
HANDLE hWdm;
printf("Hello World!n");
SC_HANDLE hServiceMgr, hServiceTwdm;
BOOL bRtn;
DWORD dwRtn, dwSize = 256;
char szDir[256];
if( argc > 1 ) //加任一個(gè)參數(shù)表示卸載驅(qū)動(dòng)程序。
{
DelSvr( "Twdm1" );
return 0;
}
GetCurrentDirectory( dwSize, szDir );//取當(dāng)前目錄,
strcat( szDir, "\Twdm.sys" ); //取驅(qū)動(dòng)程序的全路徑,
LPCTSTR lpszBinaryPathName = TEXT(szDir);//不管szDir是UNICODE還是ANSI都轉(zhuǎn)換成ANSI
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); //打開服務(wù)控制管理器
if( hServiceMgr == NULL )
{
printf( "OpenSCManager() Faild %d ! n", GetLastError() );
return 0;
}
else
{
printf( "OpenSCManager() ok ! n" );
}
//以下生成驅(qū)動(dòng)程序的服務(wù)并添加到控制面板數(shù)據(jù)庫(kù)
hServiceTwdm = CreateService( hServiceMgr, //控制面板的服務(wù)句柄
TEXT("Twdm1"), //SYSTEMCurrentControlSetServices 驅(qū)動(dòng)程序的在注冊(cè)表中的名字
TEXT("Twdm1"), // 注冊(cè)表驅(qū)動(dòng)程序的 DisplayName 值
SERVICE_ALL_ACCESS, // 加載驅(qū)動(dòng)程序的訪問權(quán)限
SERVICE_KERNEL_DRIVER,// 表示加載的服務(wù)是驅(qū)動(dòng)程序
SERVICE_DEMAND_START, // 注冊(cè)表驅(qū)動(dòng)程序的 Start 值
SERVICE_ERROR_IGNORE, // 注冊(cè)表驅(qū)動(dòng)程序的 ErrorControl 值
lpszBinaryPathName, // 注冊(cè)表驅(qū)動(dòng)程序的 ImagePath 值
NULL,
NULL,
NULL,
NULL,
NULL);
if( hServiceTwdm == NULL )
{
dwRtn = GetLastError();
if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )
{
CloseServiceHandle( hServiceMgr );
printf( "CrateService() Faild %d ! n", dwRtn );
return 0;
}
else
{
printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! n" );
}
//已經(jīng)生成了驅(qū)動(dòng)程序的服務(wù)作為打開驅(qū)動(dòng)服務(wù)的句柄
// 驅(qū)動(dòng)程序已經(jīng)加載,只需要打開
hServiceTwdm = OpenService( hServiceMgr, TEXT("Twdm1"), SERVICE_ALL_ACCESS );
if( hServiceTwdm == NULL )
{
dwRtn = GetLastError();
CloseServiceHandle( hServiceMgr );
printf( "OpenService() Faild %d ! n", dwRtn );
return 0;
}
else
{
printf( "OpenService() ok ! n" );
}
}
else
{
printf( "CrateService() ok ! n" );
}
// 啟動(dòng)驅(qū)動(dòng)程序,調(diào)用驅(qū)動(dòng)程序的 DriverEntry 函數(shù)
bRtn = StartService( hServiceTwdm, NULL, NULL );
if( !bRtn )
{
dwRtn = GetLastError();
if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )
{
printf( "StartService() Faild %d ! n", dwRtn );
CloseServiceHandle( hServiceTwdm );
CloseServiceHandle( hServiceMgr );
return 0;
}
else
{
if( dwRtn != ERROR_IO_PENDING )
{
printf( "StartService() Faild ERROR_IO_PENDING ! n");
}
else
{
printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! n");
}
}
}
//測(cè)試驅(qū)動(dòng)程序
hWdm = CreateFile("\\.\Twdm1",
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if( hWdm != INVALID_HANDLE_VALUE )
{
printf( "Open Driver Twdm ok ! n" );
}
else
{
printf( "Open Driver Twdm faild %d ! n", GetLastError() );
}
CloseHandle( hWdm );
CloseServiceHandle( hServiceTwdm );
CloseServiceHandle( hServiceMgr );
//這時(shí)候你可以通過注冊(cè)表,或其他查看符號(hào)連接的軟件驗(yàn)證。
printf( "按任意鍵 卸載驅(qū)動(dòng)程序 !n" );
getch();
//卸載驅(qū)動(dòng)程序。
DelSvr( "Twdm1" );
return 0;
}
//卸載驅(qū)動(dòng)程序。
void DelSvr( char * szSvrName )
{
SC_HANDLE hServiceMgr, hServiceTwdm;
SERVICE_STATUS SvrSta;
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if( hServiceMgr == NULL )
{
printf( "DelSvr::OpenSCManager() Faild %d ! n", GetLastError() );
return;
}
else
{
printf( "DelSvr::OpenSCManager() ok ! n" );
}
hServiceTwdm = OpenService( hServiceMgr, TEXT(szSvrName), SERVICE_ALL_ACCESS );
if( hServiceTwdm == NULL )
{
CloseServiceHandle( hServiceMgr );
printf( "DelSvr::OpenService() Faild %d ! n", GetLastError() );
return;
}
else
{
printf( "DelSvr::OpenService() ok ! n" );
}
//停止驅(qū)動(dòng)程序,如果停止失敗,只有重新啟動(dòng)才能,再動(dòng)態(tài)加載。
if( !ControlService( hServiceTwdm, SERVICE_CONTROL_STOP , &SvrSta ) )
{
printf( "DelSvr::ControlService() Faild %d !n", GetLastError() );
}
else
{
printf( "DelSvr::ControlService() ok !n" );
}
//動(dòng)態(tài)卸載驅(qū)動(dòng)程序。
if( !DeleteService( hServiceTwdm ) )
{
printf( "DelSvr:eleteSrevice() Faild %d !n", GetLastError() );
}
else
{
printf( "DelSvr:eleteSrevice() ok !n" );
}
CloseServiceHandle( hServiceTwdm );
CloseServiceHandle( hServiceMgr );
return;
}
驅(qū)動(dòng)程序:驅(qū)動(dòng)程序很簡(jiǎn)單,
只有一個(gè)文件,實(shí)現(xiàn)了DriverEntry,DispatchCreate,DispatchClose,GpdUnload 四個(gè)函數(shù)。
#include <ntddk.h>
#define NT_DEVICE_NAME L"\Device\Twdm1"
#define DOS_DEVICE_NAME L"\DosDevices\Twdm1"
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath );
NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp);
NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp);
VOID GpdUnload(PDRIVER_OBJECT DriverObject);
//////////////////////
PDEVICE_OBJECT fdo;
BOOLEAN fSymbolicLink;
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
//UNREFERENCED_PARAMETER (RegistryPath);
NTSTATUS status;
UNICODE_STRING ntDeviceName;
UNICODE_STRING win32DeviceName;
DbgPrint( "TWDM: DriverEntry for Twdm.sys ...... n" );
fSymbolicLink = FALSE;
//
// Create dispatch points for the IRPs.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
//DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = GpdDispatch;
DriverObject->DriverUnload = GpdUnload;
//DriverObject->MajorFunction[IRP_MJ_PNP] = GpdDispatchPnp;
//DriverObject->MajorFunction[IRP_MJ_POWER] = GpdDispatchPower;
//DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = GpdDispatchSystemControl;
//DriverObject->DriverExtension->AddDevice = GpdAddDevice;
RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
//創(chuàng)建設(shè)備
status = IoCreateDevice(DriverObject,
0,
&ntDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&fdo);
if (!NT_SUCCESS (status))
{
DbgPrint( "TWDM: IoCreateDevice() faild ! n" );
}
else
{
DbgPrint( "TWDM: IoCreateDevice() ok ! n" );
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
//創(chuàng)建符號(hào)連接
status = IoCreateSymbolicLink( &win32DeviceName, &ntDeviceName );
if (!NT_SUCCESS(status))
{
DbgPrint( "TWDM: IoCreateSymbolicLink() faild ! n" );
}
else
{
DbgPrint( "TWDM: IoCreateSymbolicLink() ok ! n" );
fSymbolicLink = TRUE;
}
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
}
if (!NT_SUCCESS(status))
{
if(fdo)
{
IoDeleteDevice(fdo);
}
if(fSymbolicLink)
{
IoDeleteSymbolicLink(&win32DeviceName);
}
}
return status;
}
NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp)
{
NTSTATUS status;
DbgPrint( "TWDM: IRP_MJ_CREATE for Twdm.sys ...... n" );
status = STATUS_SUCCESS;
return status;
} // DispatchCreate
NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp)
{ // DispatchClose
NTSTATUS status;
DbgPrint( "TWDM: IRP_MJ_CLOSE for Twdm.sys ...... n" );
status = STATUS_SUCCESS;
return status;
} // DispatchClose
VOID GpdUnload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING win32DeviceName;
DbgPrint( "TWDM: GpdUnload() for Twdm.sys ...... n" );
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
if(fdo)
{
IoDeleteDevice(fdo);
}
if(fSymbolicLink)
{
IoDeleteSymbolicLink(&win32DeviceName);
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -