標頭檔案
#pragma once #include <windows.h> #include <winsvc.h> #include <tchar.h> class CLoadNtDriver { public: CLoadNtDriver(); ~CLoadNtDriver(); BOOL pathIsFile(CString strPath); BOOL loadNTDriver(CString strDriverPath); BOOL unloadNTDriver(CString strSvrName); void showErrorInfo(UINT nErrCode, UINT nLine, LPCTSTR = _T(""), UINT = 0); CString m_strDvrName; wchar_t m_szServerName[40]; wchar_t m_szShowName[40]; };
原始檔
#include "stdafx.h" #include "LoadNtDriver.h" #include <strsafe.h> CLoadNtDriver::CLoadNtDriver() { } CLoadNtDriver::~CLoadNtDriver() { } BOOL CLoadNtDriver::pathIsFile(CString strPath) { // 過濾路徑是資料夾的情況 // Code by Lthis if (PathIsDirectory(strPath)) return FALSE; if (PathFileExists(strPath)) return TRUE; return FALSE; } void CLoadNtDriver::showErrorInfo(UINT nErrCode, UINT nLine, LPCTSTR lpFuncName, UINT nType){ LPTSTR lpMsgBuf = NULL; TCHAR szMessage[256] = { 0 }; TCHAR szCaption[32] = { 0 }; FormatMessage(0x1300, NULL, nErrCode, 0x400, (LPTSTR)&lpMsgBuf, 64, NULL); StringCchPrintf(szMessage, 256, _T("Error code:0x%X:%s\n"), nErrCode, lpMsgBuf); StringCchPrintf(szCaption, 32, _T("%s (Error Line:%d)"), lpFuncName, nLine); StringCchCat(szMessage, 256+32+1, szCaption); switch (nType) { case 0: OutputDebugString(szMessage); break; case 1: MessageBox(NULL, szMessage, szCaption, 0); break; default: break; } } //裝載NT驅動程式 BOOL CLoadNtDriver::loadNTDriver(CString strDriverPath) { wchar_t szDriverImagePath[256]; CString strDriverImagePath; //得到完整的驅動路徑 GetFullPathName(strDriverPath, 256, szDriverImagePath, NULL); strDriverImagePath = szDriverImagePath; if (strDriverImagePath.IsEmpty()){ MessageBoxW(0, L" CLoadDriver::installDriver: 請輸入路徑名", NULL, MB_OK | MB_ICONWARNING); return FALSE; } if (!pathIsFile(strDriverImagePath)){ strDriverImagePath += L"loadNTDriver:檔案不存在"; MessageBoxW(0, strDriverImagePath, NULL, MB_OK | MB_ICONWARNING); return FALSE; } // 提取驅動名 int nPos; nPos = strDriverImagePath.ReverseFind(_T('\\')); m_strDvrName = strDriverImagePath.Right(nPos - 1); nPos = m_strDvrName.ReverseFind(_T('.')); m_strDvrName = m_strDvrName.Left(nPos); swprintf_s(m_szServerName, m_strDvrName + L"_ServerName"); swprintf_s(m_szShowName, m_strDvrName + L"_ShowName"); BOOL bRet = FALSE; SC_HANDLE hServiceMgr = NULL; // SCM管理器的控制程式碼 SC_HANDLE hServiceDDK = NULL; // NT驅動程式的服務控制程式碼 //開啟服務控制管理器 hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hServiceMgr == NULL){ //OpenSCManager失敗 showErrorInfo(GetLastError(), __LINE__, L"loadNTDriver"); bRet = FALSE; goto BeforeLeave; } else{ //OpenSCManager成功 showErrorInfo(GetLastError(), __LINE__, L"loadNTDriver()"); } //建立驅動所對應的服務 hServiceDDK = CreateService(hServiceMgr, m_szServerName, //驅動程式的在登錄檔中的名字 m_szShowName, // 登錄檔驅動程式的 DisplayName 值 SERVICE_ALL_ACCESS, // 載入驅動程式的訪問許可權 SERVICE_KERNEL_DRIVER, // 表示載入的服務是驅動程式 SERVICE_DEMAND_START, // 登錄檔驅動程式的 Start 值 SERVICE_ERROR_IGNORE, // 登錄檔驅動程式的 ErrorControl 值 strDriverImagePath, // 登錄檔驅動程式的 ImagePath 值 NULL, NULL, NULL, NULL, NULL); DWORD dwRtn; //判斷服務是否失敗 if (hServiceDDK == NULL) { dwRtn = GetLastError(); if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS) { //由於其他原因建立服務失敗 //printf("CrateService() Faild %d ! \n", dwRtn); showErrorInfo(GetLastError(), __LINE__, L"loadNTDriver()"); bRet = FALSE; goto BeforeLeave; } else { //服務建立失敗,是由於服務已經創立過 //printf("CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n"); showErrorInfo(GetLastError(), __LINE__, L"loadNTDriver()"); } // 驅動程式已經載入,只需要開啟 hServiceDDK = OpenService(hServiceMgr, m_szServerName, SERVICE_ALL_ACCESS); if (hServiceDDK == NULL) { //如果開啟服務也失敗,則意味錯誤 dwRtn = GetLastError(); printf("OpenService() Faild %d ! \n", dwRtn); bRet = FALSE; goto BeforeLeave; } } //開啟此項服務 bRet = StartService(hServiceDDK, NULL, NULL); if (!bRet) { DWORD dwRtn = GetLastError(); if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING) { //printf("StartService() Faild %d ! \n", dwRtn); showErrorInfo(GetLastError(), __LINE__, L"loadNTDriver()"); bRet = FALSE; goto BeforeLeave; } else { if (dwRtn == ERROR_IO_PENDING) { //裝置被掛住 //printf("StartService() Faild ERROR_IO_PENDING ! \n"); showErrorInfo(GetLastError(), __LINE__, L"loadNTDriver()"); bRet = FALSE; goto BeforeLeave; } else { //服務已經開啟 //printf("StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n"); showErrorInfo(GetLastError(), __LINE__, L"loadNTDriver()"); bRet = TRUE; goto BeforeLeave; } } } bRet = TRUE; //離開前關閉控制程式碼 BeforeLeave: if (hServiceDDK){ CloseServiceHandle(hServiceDDK); } if (hServiceMgr){ CloseServiceHandle(hServiceMgr); } return bRet; } /**************************************************************** // FunctionName: unloadNTDriver // Function : 解除安裝NT驅動 // Parameter: strSvrName,驅動服務名,類中m_szServerName儲存, 傳遞該值即可 // Author: 張帆 // Create: 2015-3-23 20:57:50 // Checked: Lthis 2015-3-23 ****************************************************************/ BOOL CLoadNtDriver::unloadNTDriver(CString strSvrName) { BOOL bRet = FALSE; SC_HANDLE hServiceMgr = NULL;//SCM管理器的控制程式碼 SC_HANDLE hServiceDDK = NULL;//NT驅動程式的服務控制程式碼 SERVICE_STATUS SvrSta; CString strError; //開啟SCM管理器 hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hServiceMgr == NULL) { //開啟SCM管理器失敗 //"unloadNTDriver -> OpenSCManager() Faild ! \n"; showErrorInfo(GetLastError(), __LINE__, L"unloadNTDriver()"); bRet = FALSE; goto BeforeLeave; } //開啟驅動所對應的服務 hServiceDDK = OpenService(hServiceMgr, strSvrName, SERVICE_ALL_ACCESS); if (hServiceDDK == NULL){ //開啟驅動所對應的服務失敗 //strError = L"unloadNTDriver -> OpenService() Faild ! !"; showErrorInfo(GetLastError(), __LINE__, L"unloadNTDriver()"); goto BeforeLeave; } //停止驅動程式,如果停止失敗,只有重新啟動才能,再動態載入。 if (!ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrSta)) { //printf("ControlService() Faild %d !\n", GetLastError()); showErrorInfo(GetLastError(), __LINE__, L"unloadNTDriver()"); } //動態解除安裝驅動程式。 if (!DeleteService(hServiceDDK)) { //解除安裝失敗 //printf("DeleteSrevice() Faild %d !\n", GetLastError()); showErrorInfo(GetLastError(), __LINE__, L"unloadNTDriver()"); } bRet = TRUE; BeforeLeave: //離開前關閉開啟的控制程式碼 if (hServiceDDK){ CloseServiceHandle(hServiceDDK); } if (hServiceMgr){ CloseServiceHandle(hServiceMgr); } return bRet; }