编写资源DLL
开始
可以使用MS Visual C++开发系统或其它C/C++开发工具编写自定义资源DLL。本文中例子使用的是:
Microsoft Visual C++ version 4.2b, 包含Unicode MFC库.
MIDL编译器,版本3.00.44。(该MIDL编译器可在SDK中找到)
活动模板库(ATL)版本2.0(扩展例子代码和资源类型生成向导产生的代码需要它)
建立编译环境时,请参考平台SDK,特别是“Preparing a Build Environment”和“Developer Notes”章节。
在平台SDK的例子中也可找到完整的资源DLL参考实现(参见SMBsmp)。
创建新资源类型
要创建新的资源类型,必须写一个资源DLL和一个群集管理器扩展DLL。简单的方法是运行资源类型生成向导来创建资源DLL。该向导将箭竹一个资源DLL框架和/或包含入口点定义,申明,导出的群集管理器扩展DLL。
创建资源DLL的完整步骤,请参考SDK文档的“Creating a Custom Resource Type”,“Using the Resource Type AppWizard”和“Customizing a Resource DLL”等章节。
生成的资源DLL框架仅包含最基本的故障转移和故障恢复功能。要使用群集环境的全部功能和允许DLL提供资源的特定信息,需要编写自己的代码。注意由向导生成的框架代码中包含TODO:和ADDPARAM:注释以指明哪里需要添加资源的特定信息。像下面所描述的那样,你需要使用资源API完成大部分的自定义功能。
自定义资源DLL
如前所述,资源API包含几个入口点函数,这些函数在资源DLL内实现。资源监视器使用这些入口点函数管理DLL提供的资源。另外,资源监视器实现少数几个回调函数,资源DLL使用这些回调函数向群集服务报告状态或为系统管理员记录事件日志。
大部分入口点函数是所有资源必需的。两个特别的API入口点函数-Arbitrate和Release-仅在编写仲裁资源时需要。本文不讨论这两个函数。其余的入口点函数在下面列出,本文将讨论它们的细节。
Startup
Open
Online
LooksAlive
IsAlive
Offline
Close
Terminate
ResourceControl
ResourceTypeControl
每个由群集软件支持的资源DLL应该遵从下面的指引:
在某个例外情况下,对于给定的资源实例,资源DLL是不可重入的。该情况是Terminate入口点函数。Terminate应该在任何时候都能被调用,即使资源DLL中线程处于等待Online或Offline调用完成的阻塞状态。
资源DLL对于其它资源ID是可重入的。如果资源DLL拥有超过1个资源ID,就必须为DLL内所有共享的全局数据进行同步。
在资源DLL内,一个入口点函数完成操作所花费的时间不应该超过300毫秒。如果一个入口点函数-特别是Online, Offline, LooksAlive或isAlive-超出了这个限制,就应该派生线程来处理耗时的操作。(注意当前向导会为Online生成线程,未来版本也应该为Offline生成一个线程。)
在资源DLL初始化期间,DLL的入口点函数(系统加载DLL后的标准的DLL入口)以DLL_PROCESS_ATTACH标志被调用。接着资源监视器开始调用资源API入口点函数。
Startup例程
当资源DLL被加载后,资源监视器就调用Startup例程。注意仅有Startup入口点函数被导出。所有在资源DLL内实现的其它入口点函数通过Startup返回的函数表来访问。
下面是Startup例程的定义:
DWORD WINAPI Startup
(
LPCWSTR ResourceType,
DWORD MinVersionSupported,
DWORD MaxVersionSupported,
PSET_RESOURCE_STATUS_ROUTINE SetResourceStatus,
PLOG_EVENT_ROUTINE LogEvent,
PCLRES_FUNCTION_TABLE * FunctionTable
);
ResourceType参数标识被启动的资源的类型。
SetResourceStatus和LogEvent是由资源监视器实现的回调函数。(本文后面章节将讨论这些回调函数。)在Online或Offline入口点函数被调用后,如果它们要花费超过300毫秒,资源DLL应该调用SetResourceStatus向群集告知资源状态;资源DLL也应该使用LogEvent报告事件和错误。(SetResourceStatus应该仅由Online或Offline调用,并且仅在Online或Offline返回ERROR_IO_PENDING的情况。更多的信息,请参考Online和Offline的讨论。)
FunctionTable结构包含了资源DLL其余入口点的函数地址。
注意 Startup入口点函数资源DLL保存回调函数LogEvent和SetResourceStatus的仅有的地方。
Startup返回以下值:
如果请求成功,返回ERROR_SUCCESS。
如果资源不支持在MinVersionSupported和MaxVersionSupported之间的版本,返回ERROR_REVISION_MISMATCH
如果操作不成功,返回Win32?编程接口的错误值。
出于对资源操作的优化,要确保实现的Startup能够在300毫秒内完成。