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 不变,并将 lByteslpNumObjectTypes 设置为零。 不会尝试指示所需的缓冲区大小,因为此大小在下次调用之前可能会更改。
ERROR_SUCCESS 除ERROR_MORE_DATA 事例以外的所有情况下都返回此值,即使未返回任何数据或发生错误也是如此。 若要报告缓冲区大小不足以外的错误,请使用应用程序事件日志。

注解

如果在 lpValueName 参数中指定的请求对象与性能 DLL 支持的任何对象索引不对应,请将 pData 参数保持不变 (其中 pData 引用 lppData) 指向的指针,并将 lлTotalByteslpNumObjectTypes 参数设置为零。 这表示未返回任何数据。

如果支持一个或多个被查询的对象,请确定 l的身份汇总字节指定的 pData 缓冲区的大小是否足以存储数据。 如果没有,请保留 pData 不变,并将 ltotalByteslpNumObjectTypes 设置为零。 不会尝试指示所需的缓冲区大小,因为这可能会在下次调用之前更改。 返回 ERROR_MORE_DATA

如果数据收集非常耗时,则应仅响应特定对象的查询或成本高昂的查询。 还应降低收集数据的线程的优先级,以免对系统性能产生负面影响。 有关查询字符串格式,请参阅 使用注册表函数使用计数器数据

如果使用者在另一台计算机上运行 (远程) ,则在处理远程连接的服务器端的 Winlogon 进程的上下文中调用 OpenPerformanceDataClosePerformanceData 和 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

另请参阅