NT式驅動的安裝

1.OpenSCManager

2.CreateService

3.OpenService

4.StartService

5.CloseServiceHandle

正確的加載步驟

打開SCM管理器->創建服務->開啟服務->關閉句炳

而這三個步驟所對應到的函數就是

OpenSCManager->CreateService->StartService->CloseServiceHandle

 

SC_HANDLE OpenSCManager(
LPCTSTR lpMachineName, // 計算機名稱 ,NULL代表本機
LPCTSTR lpDatabaseName, // SCM數據庫名稱
DWORD dwDesiredAccess // 權限, SC_MANAGER_ALL_ACCESS表示所有權限
);

//打開SCM管理器

ServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

//創建服務

 

ServiceDDK = CreateService( ServiceMgr,//SCM管理器的句柄 
DriverName, //驅動在註冊表中的名稱
DriverName, // 驅動在註冊表的DisplayName值
SERVICE_ALL_ACCESS, // 訪問權限
SERVICE_KERNEL_DRIVER,// 表示加載的服務為驅動
SERVICE_DEMAND_START, // 驅動在註冊表的Start值 
SERVICE_ERROR_IGNORE, // 驅動在註冊表的ErrorControl 值
DriverImagePath, // 驅動在註冊表的ImagePath 值 
NULL, //開啟服務的用戶組
NULL, //驗證簽名
NULL, //依賴的服務名稱
NULL, //帳戶名稱
NULL); //用戶指令

OpenService的功用,當創建服務失敗時,用這個函數打開服務


SC_HANDLE OpenService( SC_HANDLE hSCManager, // SCM管理器句柄
 LPCTSTR lpServiceName, // 服務名稱
 DWORD dwDesiredAccess  // 訪問權限
);


ServiceDDK = OpenService( ServiceMgr,DriverName, SERVICE_ALL_ACCESS );

//開啟服務

 

BOOL StartService( SC_HANDLE hService, // 創建服務或打開服務所返回的值
 DWORD dwNumServiceArgs, // 通常都是NULL
 LPCTSTR* lpServiceArgVectors   // 通常都是NULL
);

//關閉句柄

 

BOOL CloseServiceHandle( SC_HANDLE hSCObject   // 可以是服務也可以是對象);


BRet= StartService( ServiceDDK, NULL, NULL );

 

開始編寫代碼

BOOL LoadNTDriver(char* DriverName,char* DriverPathName)
{
BOOL BRet = FALSE;

SC_HANDLE ServiceMgr=NULL;//SCM管理器
SC_HANDLE ServiceDDK=NULL;//服務句柄

//打開SCM管理器
ServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

if( hServiceMgr == NULL )  //如果返回為空
{
//打開SCM管理器失敗
BRet = FALSE;
goto BExit;
}
else
{
////打開SCM管理器成功!
TRACE( "調用OpenSCManager成功! \n" );
}

//打開服務

ServiceDDK = CreateService( ServiceMgr,//SCM管理器的句柄 
DriverName, //驅動在註冊表中的名稱
DriverName, // 驅動在註冊表的DisplayName值
SERVICE_ALL_ACCESS, // 訪問權限
SERVICE_KERNEL_DRIVER,// 表示加載的服務為驅動
SERVICE_DEMAND_START, // 驅動在註冊表的Start值 
SERVICE_ERROR_IGNORE, // 驅動在註冊表的ErrorControl 值
DriverImagePath, // 驅動在註冊表的ImagePath 值 
NULL, //開啟服務的用戶組
NULL, //驗證簽名
NULL, //依賴的服務名稱
NULL, //帳戶名稱
NULL); //用戶指令

DWORD S_DDK_Error;
//判斷創建是否失敗
if( ServiceDDK == NULL )
{
S_DDK_Error = GetLastError(); //S_DDK_Error = GetLastError 獲取的返回值

//ERROR_IO_PENDING = 服務以創建過了,ERROR_SERVICE_EXISTS = 服務名稱以存在
if( S_DDK_Error != ERROR_IO_PENDING && S_DDK_Error != ERROR_SERVICE_EXISTS )
{
//創建失敗!!

TRACE( "CrateService() 服務不明原因創建失敗  \n" ); 
BRet = FALSE;
goto BExit;
}
else
{
TRACE( "CrateService() 服務以創建過,或者服務名以存在  \n" );
}

//打開服務
ServiceDDK = OpenService( ServiceMgr, DriverName, SERVICE_ALL_ACCESS );
if( ServiceDDK == NULL )  //如果打開失敗
{
S_DDK_Error = GetLastError();
TRACE( "打開服務失敗 %d ! \n", S_DDK_Error );
BRet = FALSE;
goto BExit;
}
else
{
TRACE( "打開服務成功! ! \n" );
}
}
else
{
TRACE( "創建服務成功! ! \n" );
}

//開啟服務
BRet= StartService( ServiceDDK, NULL, NULL );
if( !BRet ) //開啟失敗

S_DDK_Error = GetLastError(); 
TRACE( "服務可能已開啟%d ! \n", S_DDK_Error );  
}
BRet = TRUE;

//關閉句柄
BExit:
if(ServiceDDK)
{
CloseServiceHandle(ServiceDDK); //關閉創建時所返回的句柄
}
if(ServiceMgr)
{
CloseServiceHandle(ServiceMgr); //關閉打開SCM時所返回的句柄
}
return BRet;
}

這是一個加載驅動的例子,

但是這並非完整代碼,也無法編譯,

因為時間的關係,

之後會再講到利用CFileDialog打開驅動文件,

以及卸載驅動.


 



pua0156k 發表在 痞客邦 PIXNET 留言(0) 人氣()