w2kServiceLoadEx() 是一个十分强大的函数 。它会构建自动加载一个服务时所需的全部参数,但你要提供可执行文件的路径 。SC 管理器的 CreateService() 函数所需要的服务名称将从可执行文件名(会去掉文件的扩展名)中派生出来 。为了给新创建的服务构建一个适当的用于显示名称,w2kServiceLoadEx() 会尝试从文件的版本信息中读取 FileDescription 字符串 。如果可执行文件中不包含版本信息,或者 FileDescription 字符串不可用,则将使用缺省的服务名称 。
和 w2kServiceLoad() 不同,w2kServiceLoadEx() 支持路径中的环境变量 。换句话说,如果路径字符串中包含如 %SystemRoot% 或 %TEMP% 这样的子串,它们会被相应系统变量的当前值替换掉 。w2kServiceUnloadEx() 是 w2kServiceLoadEx() 的很好的搭档,它会从提供的路径中提取服务的名称,与前面提及的展开过程类似,并将提取出来的服务名称传递给 w2kServiceUnload()。这两个函数是需要加载 / 卸载第三方设备驱动的应用程序的理想搭档,只需提供这些驱动的全路径即可 。本书的光盘中包含一个这样的示例程序 。
控制台模式的工具 -----w2k_load.exe 是一个通用的内核驱动程序加载 / 卸载器,它为 w2kServiceLoadEx() 和 w2kServiceUnloadEx() 提供了简单的命令行接口 。其源代码可以在随书 CD 的 srcw2k_load 目录下找到 。列表 3-9 给出了相关的代码,该工具仅是一种示意性的实现 。因为大量的工作都是由 w2k_lib.dll 中的 w2kServiceLoadEx() 和 w2kServiceUnloadEx() 完成的 。
// =================================================================
// GLOBAL STRINGS
// =================================================================
Word awUsage [] =
L"rn"
L"Usage: " SW(MAIN_MODULE) L"
L" " SW(MAIN_MODULE) L"
L" " SW(MAIN_MODULE) L"
WORD awUnload [] = L"/unload";
WORD awOk [] = L"OKrn";
WORD awError [] = L"ERRORrn";
// =================================================================
// COMMAND HANDLERS
// =================================================================
BOOL WINAPI DriverLoad (PWORD pwPath)
{
SC_HANDLE hManager;
BOOL fOk = FALSE;
_printf (L"rnLoading "%s" ... ", pwPath);
if ((hManager = w2kServiceLoadEx (pwPath, TRUE)) != NULL)
{
w2kServiceDisconnect (hManager);
fOk = TRUE;
}
_printf (fOk ? awOk : awError);
return fOk;
}
// -----------------------------------------------------------------
BOOL WINAPI DriverUnload (PWORD pwPath)
{
BOOL fOk = FALSE;
_printf (L"rnUnloading "%s" ... ", pwPath);
fOk = w2kServiceUnloadEx (pwPath, NULL);
_printf (fOk ? awOk : awError);
return fOk;
}
// =================================================================
// MAIN PROGRAM
// =================================================================
DWORD Main (DWORD argc, PTBYTE *argv, PTBYTE *argp)
{
_printf (atAbout);
if (argc == 2)
{
DriverLoad (argv [1]);
}
else
{
if ((argc == 3) && (!lstrcmpi (argv [2], awUnload)))
{
DriverUnload (argv [1]);
}
else
{
_printf (awUsage, awUnload, awUnload);
}
}
return 0;
}
// =================================================================
// END OF PROGRAM
// =================================================================
列表 3-9. 加载 / 卸载设备驱动
表 3-4 中剩余的库函数在更低一级的层面上工作,它们都在 w2k_lib.dll 内部使用 。当然,如果你喜欢的话,你也可以从你的程序里调用它们 。从 列表 3-8 给出的它们的源代码中,可以很容易得出它们的使用方式 。
推荐阅读
- 1 《Undocumented Windows 2000 Secrets》翻译 --- 第二章
- 浅谈非系统管理员用户本地登录Windows 2000 server
- 同床异梦秋瓷炫多少期
- Windows 2000进程细述
- 《Undocumented Windows 2000 Secrets》翻译 --- 3
- Windows2000的日志文件详述及删除方法
- 命令篇 Windows 2000/XP的CMD命令教程 (3)
- 2 《Undocumented Windows 2000 Secrets》翻译 --- 第三章
- 如何安装/卸载 Windows 2000 的公钥证书颁发机构
- 使用 Windows 2000 备份程序备份和还原系统状态
