PM_COLLECT_PROC回调函数 (winperf.h)
收集性能数据并将其返回给使用者。 如果要编写性能 DLL 以提供性能数据,请实现并导出此函数。 每当使用者在注册表中查询性能数据时,系统都调用此函数。
CollectPerformanceData 函数是应用程序定义的函数名称的占位符。
语法
PM_COLLECT_PROC PmCollectProc;
DWORD PmCollectProc(
LPWSTR pValueName,
void **ppData,
DWORD *pcbTotalBytes,
DWORD *pNumObjectTypes
)
{...}
参数
pValueName
ppData
pcbTotalBytes
pNumObjectTypes
返回值
以下值之一:
返回代码 | 说明 |
---|---|
ERROR_MORE_DATA | pData 缓冲区的大小 (其中 pData 引用 lppData) 所指定的指针,其大小不足以存储数据。 保留 pData 不变,并将 lBytes 和 lpNumObjectTypes 设置为零。 不会尝试指示所需的缓冲区大小,因为此大小在下次调用之前可能会更改。 |
ERROR_SUCCESS | 在 除ERROR_MORE_DATA 事例以外的所有情况下都返回此值,即使未返回任何数据或发生错误也是如此。 若要报告缓冲区大小不足以外的错误,请使用应用程序事件日志。 |
注解
如果在 lpValueName 参数中指定的请求对象与性能 DLL 支持的任何对象索引不对应,请将 pData 参数保持不变 (其中 pData 引用 lppData) 指向的指针,并将 lлTotalBytes 和 lpNumObjectTypes 参数设置为零。 这表示未返回任何数据。
如果支持一个或多个被查询的对象,请确定 l的身份汇总字节指定的 pData 缓冲区的大小是否足以存储数据。 如果没有,请保留 pData 不变,并将 ltotalBytes 和 lpNumObjectTypes 设置为零。 不会尝试指示所需的缓冲区大小,因为这可能会在下次调用之前更改。 返回 ERROR_MORE_DATA。
如果数据收集非常耗时,则应仅响应特定对象的查询或成本高昂的查询。 还应降低收集数据的线程的优先级,以免对系统性能产生负面影响。 有关查询字符串格式,请参阅 使用注册表函数使用计数器数据。
如果使用者在另一台计算机上运行 (远程) ,则在处理远程连接的服务器端的 Winlogon 进程的上下文中调用 OpenPerformanceData、ClosePerformanceData 和 CollectPerformanceData 函数。 当对仅远程发生的问题进行故障排除时,这种区别非常重要。
函数成功返回后,系统可以执行一些基本测试,以确保数据的完整性。 默认情况下,不执行任何测试。 如果测试失败,系统将生成事件日志消息,并丢弃数据,以防止由于指针无效而导致的任何进一步问题。 以下注册表值控制测试级别: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Perflib\ExtCounterTestLevel
。
以下是 ExtCounterTestLevel 的可能测试级别。
级别 | 含义 |
---|---|
1 | 测试受信任计数器 DLL 的指针和缓冲区。 发送用户缓冲区的副本。 |
2 | 测试指针和缓冲区长度,但不测试指针引用或缓冲区内容。 发送用户缓冲区的副本。 |
3 | 不要测试指针或缓冲区。 发送用户缓冲区的副本。 |
4 | 不要测试指针或缓冲区。 发送用户的缓冲区,而不是副本。 这是默认值。 |
以下测试在级别 1 和级别 2 中执行:
- 验证 lTotalTotalBytes 的值是否与返回的缓冲区指针 pData 一致。 如果将 lTotalBytes 值添加到传递给此函数的原始缓冲区指针,则最终应得到此函数返回的相同缓冲区指针。 如果它们不相同,则会记录错误消息并忽略数据。
- 验证缓冲区溢出是否未发生。 系统在使用者分配的缓冲区之前和之后添加一个 1 KB 的防护页。 如果返回的缓冲区指针 pData 指向追加的防护页的第一个字节,则假定缓冲区无效且数据被忽略。 如果缓冲区指针超过缓冲区的末尾,但未超过保护页的末尾,则记录缓冲区溢出错误。 如果缓冲区指针超过保护页的末尾,则会记录堆错误,因为从中分配缓冲区的堆可能已损坏,从而导致其他内存错误。
- 验证防护页是否未损坏。 在缓冲区之前和之后添加的 1 KB 防护页在调用此函数之前使用数据模式进行初始化。 收集过程返回后,将检查此数据模式。 如果检测到任何差异,则假定出现缓冲区溢出或其他内存错误,并忽略数据。
仅当使用测试级别 1 时,才执行以下测试:
- 验证每个对象的 TotalByteLength 成员的总和是否与 lTotalTotalBytes 的值相同。 否则,将忽略数据。
- 验证每个实例的 ByteLength 成员是否一致。 如果下一个对象或缓冲区末尾位于最后一个实例之后,则长度是一致的。 否则,将忽略数据。
示例
请参阅 实现 CollectPerformanceData。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows XP [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | Windows |
标头 | winperf.h |