Delphi的EnumerateTraceGuids返回参数错误(87),这是为什么?

2026-04-10 17:072阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计698个文字,预计阅读时间需要3分钟。

Delphi的EnumerateTraceGuids返回参数错误(87),这是为什么?

我尝试对这段文本进行简化

使用Windows API调用`EnumerateTraceGuids`函数,获取GUID列表。函数原型:`ULONG EnumerateTraceGuids(__inout PTRACE_GUID_PROPERTIES *GuidPropertiesArray, __in ULONG PropertyArrayCount, __out PULONG GuidCount);` 从MSDN文档开始。

我试图调用 Windows API函数 EnumerateTraceGuids:

ULONG EnumerateTraceGuids( __inout PTRACE_GUID_PROPERTIES *GuidPropertiesArray, __in ULONG PropertyArrayCount, __out PULONG GuidCount );

从代码示例on MSDN开始:

ULONG status = ERROR_SUCCESS; PTRACE_GUID_PROPERTIES *pProviders = NULL; ULONG RegisteredProviderCount = 0; ULONG ProviderCount = 0; pProviders = (PTRACE_GUID_PROPERTIES *) malloc(sizeof(PTRACE_GUID_PROPERTIES)); status = EnumerateTraceGuids(pProviders, ProviderCount, &RegisteredProviderCount);

我将代码转换为Delphi:

var providers: PPointerList; providerCount: LongWord; registeredProviderCount: LongWord; res: LongWord; begin providerCount := 0; registeredProviderCount := 0; providers := AllocMem(SizeOf(Pointer)); ZeroMemory(providers, SizeOf(Pointer)); res := EnumerateTraceGuids(providers, providerCount, {out}registeredProviderCount); end;

随着api电话:

function EnumerateTraceGuids( GuidPropertiesArray: Pointer; PropertyArrayCount: Cardinal; var GuidCount: Cardinal): Cardinal; stdcall; external 'advapi32.dll';

我得到结果代码ERROR_INVALID_PARAMETER(87,参数不正确).

我究竟做错了什么?

Delphi的EnumerateTraceGuids返回参数错误(87),这是为什么?

MSDN描述了导致ERROR_INVALID_PARAMETER的原因:

ERROR_INVALID_PARAMETER

One of the following is true:

  • PropertyArrayCount is zero
  • GuidPropertiesArray is NULL

第一种情况是正确的,我的第二个参数PropertyArrayCount为零 – 就像样本所说的那样.

据我所知,您的代码应该与MSDN示例相同.但是,正如Code所说,MSDN示例确实看起来有点时髦.实际上,在我看来,MSDN样本只是偶然的.

请注意,该代码中的注释表明:

// EnumerateTraceGuids requires a valid pointer. Create a dummy // allocation, so that you can get the actual allocation size.

然后它在pProviders中分配空间来存储单个指针.但是,pProviders中包含的值实际上很重要.它不能为NULL.在你的Delphi代码中,你实际上将内存归零了两次.一次使用AllocMem,一次使用ZeroMemory.如果您只是更改Delphi代码以使提供程序的内容非零,那么Delphi代码将开始工作.

这是一个非常简单的项目,它准确地说明了发生了什么:

program _EnumerateTraceGuidsFaultDemo; {$APPTYPE CONSOLE} function EnumerateTraceGuids( GuidPropertiesArray: Pointer; PropertyArrayCount: Cardinal; var GuidCount: Cardinal): Cardinal; stdcall; external 'advapi32.dll'; var providers: Pointer; providerCount: LongWord; registeredProviderCount: LongWord; res: LongWord; begin providerCount := 0; registeredProviderCount := 0; providers := AllocMem(SizeOf(Pointer));//zeroises memory res := EnumerateTraceGuids(providers, providerCount, registeredProviderCount); Writeln(res);//outputs 87 PInteger(providers)^ := 1; res := EnumerateTraceGuids(providers, providerCount, registeredProviderCount); Writeln(res);//outputs 234 Readln; end.

所以我认为这解释了这个问题,但我实际上解决的问题还不止于此.我将继续进行下一步的工作,并使用与TRACE_GUID_PROPERTIES结构等效的真实Delphi完全声明EnumerateTraceGuids.

我可能会写这样的代码:

program _EnumerateTraceGuids; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Windows; type PTraceGuidProperties = ^TTraceGuidProperties; TTraceGuidProperties = record Guid: TGUID; GuidType: ULONG; LoggerId: ULONG; EnableLevel: ULONG; EnableFlags: ULONG; IsEnable: Boolean; end; function EnumerateTraceGuids( var GuidPropertiesArray: PTraceGuidProperties; PropertyArrayCount: ULONG; var GuidCount: ULONG ): ULONG; stdcall; external 'advapi32.dll'; function GetRegisteredProviderCount: ULONG; var provider: TTraceGuidProperties; pprovider: PTraceGuidProperties; providerCount: LongWord; registeredProviderCount: ULONG; res: ULONG; begin providerCount := 0; pprovider := @provider; res := EnumerateTraceGuids(pprovider, providerCount, registeredProviderCount); if (res<>ERROR_MORE_DATA) and (res<>ERROR_SUCCESS) then RaiseLastOSError; Result := registeredProviderCount; end; var i: Integer; provider: TTraceGuidProperties; pprovider: PTraceGuidProperties; providers: array of TTraceGuidProperties; pproviders: array of PTraceGuidProperties; providerCount: ULONG; registeredProviderCount: ULONG; res: ULONG; begin providerCount := GetRegisteredProviderCount; SetLength(providers, providerCount); SetLength(pproviders, providerCount); for i := 0 to providerCount-1 do pproviders[i] := @providers[i]; res := EnumerateTraceGuids(pproviders[0], providerCount, registeredProviderCount); if res<>ERROR_SUCCESS then RaiseLastOSError; //do stuff with providers end.

我没有尝试在GetRegisteredProviderCount中过于可爱,而是传递了指向真实TRACE_GUID_PROPERTIES的指针.

本文共计698个文字,预计阅读时间需要3分钟。

Delphi的EnumerateTraceGuids返回参数错误(87),这是为什么?

我尝试对这段文本进行简化

使用Windows API调用`EnumerateTraceGuids`函数,获取GUID列表。函数原型:`ULONG EnumerateTraceGuids(__inout PTRACE_GUID_PROPERTIES *GuidPropertiesArray, __in ULONG PropertyArrayCount, __out PULONG GuidCount);` 从MSDN文档开始。

我试图调用 Windows API函数 EnumerateTraceGuids:

ULONG EnumerateTraceGuids( __inout PTRACE_GUID_PROPERTIES *GuidPropertiesArray, __in ULONG PropertyArrayCount, __out PULONG GuidCount );

从代码示例on MSDN开始:

ULONG status = ERROR_SUCCESS; PTRACE_GUID_PROPERTIES *pProviders = NULL; ULONG RegisteredProviderCount = 0; ULONG ProviderCount = 0; pProviders = (PTRACE_GUID_PROPERTIES *) malloc(sizeof(PTRACE_GUID_PROPERTIES)); status = EnumerateTraceGuids(pProviders, ProviderCount, &RegisteredProviderCount);

我将代码转换为Delphi:

var providers: PPointerList; providerCount: LongWord; registeredProviderCount: LongWord; res: LongWord; begin providerCount := 0; registeredProviderCount := 0; providers := AllocMem(SizeOf(Pointer)); ZeroMemory(providers, SizeOf(Pointer)); res := EnumerateTraceGuids(providers, providerCount, {out}registeredProviderCount); end;

随着api电话:

function EnumerateTraceGuids( GuidPropertiesArray: Pointer; PropertyArrayCount: Cardinal; var GuidCount: Cardinal): Cardinal; stdcall; external 'advapi32.dll';

我得到结果代码ERROR_INVALID_PARAMETER(87,参数不正确).

我究竟做错了什么?

Delphi的EnumerateTraceGuids返回参数错误(87),这是为什么?

MSDN描述了导致ERROR_INVALID_PARAMETER的原因:

ERROR_INVALID_PARAMETER

One of the following is true:

  • PropertyArrayCount is zero
  • GuidPropertiesArray is NULL

第一种情况是正确的,我的第二个参数PropertyArrayCount为零 – 就像样本所说的那样.

据我所知,您的代码应该与MSDN示例相同.但是,正如Code所说,MSDN示例确实看起来有点时髦.实际上,在我看来,MSDN样本只是偶然的.

请注意,该代码中的注释表明:

// EnumerateTraceGuids requires a valid pointer. Create a dummy // allocation, so that you can get the actual allocation size.

然后它在pProviders中分配空间来存储单个指针.但是,pProviders中包含的值实际上很重要.它不能为NULL.在你的Delphi代码中,你实际上将内存归零了两次.一次使用AllocMem,一次使用ZeroMemory.如果您只是更改Delphi代码以使提供程序的内容非零,那么Delphi代码将开始工作.

这是一个非常简单的项目,它准确地说明了发生了什么:

program _EnumerateTraceGuidsFaultDemo; {$APPTYPE CONSOLE} function EnumerateTraceGuids( GuidPropertiesArray: Pointer; PropertyArrayCount: Cardinal; var GuidCount: Cardinal): Cardinal; stdcall; external 'advapi32.dll'; var providers: Pointer; providerCount: LongWord; registeredProviderCount: LongWord; res: LongWord; begin providerCount := 0; registeredProviderCount := 0; providers := AllocMem(SizeOf(Pointer));//zeroises memory res := EnumerateTraceGuids(providers, providerCount, registeredProviderCount); Writeln(res);//outputs 87 PInteger(providers)^ := 1; res := EnumerateTraceGuids(providers, providerCount, registeredProviderCount); Writeln(res);//outputs 234 Readln; end.

所以我认为这解释了这个问题,但我实际上解决的问题还不止于此.我将继续进行下一步的工作,并使用与TRACE_GUID_PROPERTIES结构等效的真实Delphi完全声明EnumerateTraceGuids.

我可能会写这样的代码:

program _EnumerateTraceGuids; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Windows; type PTraceGuidProperties = ^TTraceGuidProperties; TTraceGuidProperties = record Guid: TGUID; GuidType: ULONG; LoggerId: ULONG; EnableLevel: ULONG; EnableFlags: ULONG; IsEnable: Boolean; end; function EnumerateTraceGuids( var GuidPropertiesArray: PTraceGuidProperties; PropertyArrayCount: ULONG; var GuidCount: ULONG ): ULONG; stdcall; external 'advapi32.dll'; function GetRegisteredProviderCount: ULONG; var provider: TTraceGuidProperties; pprovider: PTraceGuidProperties; providerCount: LongWord; registeredProviderCount: ULONG; res: ULONG; begin providerCount := 0; pprovider := @provider; res := EnumerateTraceGuids(pprovider, providerCount, registeredProviderCount); if (res<>ERROR_MORE_DATA) and (res<>ERROR_SUCCESS) then RaiseLastOSError; Result := registeredProviderCount; end; var i: Integer; provider: TTraceGuidProperties; pprovider: PTraceGuidProperties; providers: array of TTraceGuidProperties; pproviders: array of PTraceGuidProperties; providerCount: ULONG; registeredProviderCount: ULONG; res: ULONG; begin providerCount := GetRegisteredProviderCount; SetLength(providers, providerCount); SetLength(pproviders, providerCount); for i := 0 to providerCount-1 do pproviders[i] := @providers[i]; res := EnumerateTraceGuids(pproviders[0], providerCount, registeredProviderCount); if res<>ERROR_SUCCESS then RaiseLastOSError; //do stuff with providers end.

我没有尝试在GetRegisteredProviderCount中过于可爱,而是传递了指向真实TRACE_GUID_PROPERTIES的指针.