Windows NT 與 Windows 9x 最大的差異在於 NT 提供強大的服務機制。服務可隨系統啟動自動執行,也可透過控制面板或 Win32 應用程式啟動/停止,甚至在無使用者登入時仍能運作。眾多 FTP、Web 伺服器及資料庫皆以服務形式運行,實現無人值守。著名的後門程式 Back Orifice 2000 也利用服務隱藏於 NT 系統中。但服務程式設計較複雜,許多開發者望而卻步。本文將從頭建構一個完整的服務框架,讀者只需在指定位置填入業務代碼,即可輕鬆擁有專屬服務。
SC_HANDLE OpenSCManager(
LPCTSTR lpMachineName, // 目標電腦名稱,NULL 為本機
LPCTSTR lpDatabaseName, // 資料庫名稱,通常為 NULL
DWORD dwDesiredAccess // 存取權限
);
常用權限常數:
SC_MANAGER_ALL_ACCESS - 所有權限SC_MANAGER_CREATE_SERVICE - 允許建立服務SC_MANAGER_ENUMERATE_SERVICE - 允許列舉服務成功返回 SCM 控制碼,失敗返回 NULL。所有服務操作皆需先開啟此資料庫。
SC_HANDLE CreateService(
SC_HANDLE hSCManager,
LPCTSTR lpServiceName, // 服務內部名稱
LPCTSTR lpDisplayName, // 顯示名稱
DWORD dwDesiredAccess, // 存取權限,如 SERVICE_ALL_ACCESS
DWORD dwServiceType, // 服務類型,如 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS
DWORD dwStartType, // 啟動類型,如 SERVICE_AUTO_START 自動啟動
DWORD dwErrorControl, // 錯誤控制,如 SERVICE_ERROR_IGNORE
LPCTSTR lpBinaryPathName, // 服務執行檔路徑
LPCTSTR lpLoadOrderGroup, // 載入順序群組,通常 NULL
LPDWORD lpdwTagId, // 標籤 ID,通常 NULL
LPCTSTR lpDependencies, // 相依服務,通常 NULL
LPCTSTR lpServiceStartName, // 啟動帳號,通常 NULL 表示 LocalSystem
LPCTSTR lpPassword // 帳號密碼,通常 NULL
);
對應刪除服務的函式為 DeleteService(hService)。
SC_HANDLE OpenService(
SC_HANDLE hSCManager,
LPCTSTR lpServiceName,
DWORD dwDesiredAccess
);
BOOL StartService(
SC_HANDLE hService,
DWORD dwNumServiceArgs,
LPCTSTR *lpServiceArgVectors
);
BOOL ControlService(
SC_HANDLE hService,
DWORD dwControl, // 控制碼:STOP, PAUSE, CONTINUE, INTERROGATE, SHUTDOWN
LPSERVICE_STATUS lpServiceStatus
);
SERVICE_STATUS 結構包含服務當前狀態、可接受的控制命令等資訊,是服務程式核心狀態結構。
ServiceMain 入口點,向 SCM 註冊控制處理函式。SERVICE_CONTROL_STOP、SERVICE_CONTROL_PAUSE 等命令,並回報狀態。SetServiceStatus 定期更新服務狀態,防止 SCM 判定服務無回應。MyService.exe)。sc create 命令或本文 API 註冊服務。掌握上述 API 與架構,即可開發穩健的 Windows NT 系統服務。