EnumerateTraceGuids返回“参数不正确”。 (87) [英] EnumerateTraceGuids returns "The parameter is incorrect" (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屋!