EnumerateTraceGuids返回“参数不正确”。 (87) [英] EnumerateTraceGuids returns "The parameter is incorrect" (87)

查看:85
本文介绍了EnumerateTraceGuids返回“参数不正确”。 (87)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试调用Windows API函数 EnumerateTraceGuids

i am trying to call the Windows API function EnumerateTraceGuids:

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

从代码示例在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:

i convert the code to 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 ,参数不正确。)

i get the result code ERROR_INVALID_PARAMETER (87, The parameter is incorrect).

我在做什么错了?

MSDN描述了导致 ERROR_INVALID_PARAMETER 的原因:

MSDN describes what would cause ERROR_INVALID_PARAMETER:


ERROR_INVALID_PARAMETER

以下条件之一为真:


  • PropertyArrayCount为零

  • GuidPropertiesArray为NULL

第一种情况是是的,我的第二个参数 PropertyArrayCount 为零-就像示例中说的那样。

The first case is true, my 2nd parameter PropertyArrayCount is zero - just like the sample says it should be.

推荐答案

据我所知,您的代码应与MSDN示例相同。但是,正如Code所说,MSDN示例看上去确实有些时髦。确实,在我看来,MSDN示例只是偶然地工作。

So far as I can see, your code should be identical to the MSDN sample. However, as Code says, the MSDN sample does look a bit funky. Indeed, it seems to me that the MSDN sample is only working by chance.

请注意,该代码中的注释指出:

Note that comment in that code that states:

// 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代码将开始工作。

Then it allocates space in pProviders to store a single pointer. However, the value contained in pProviders actually matters. It cannot be NULL. In your Delphi code you zeroise that memory twice in fact. Once with AllocMem and once with ZeroMemory. If you just change your Delphi code to make the contents of providers non-zero then the Delphi code will start working.

这是一个非常简单的项目,确切地说明了正在发生的事情:

Here is a very simple project that illustrates exactly what is going on:

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

So I think that explains the problem, but I'd actually solve it more completely than that. I would move on to the next step of your work and declare EnumerateTraceGuids fully using a real Delphi equivalent to the TRACE_GUID_PROPERTIES struct.

我可能会这样写代码:

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 的指针。

Rather than trying to be too cute in GetRegisteredProviderCount, I have passed a pointer to a real TRACE_GUID_PROPERTIES.

这篇关于EnumerateTraceGuids返回“参数不正确”。 (87)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆