i am trying to call the Windows API function EnumerateTraceGuids:
ULONG EnumerateTraceGuids(
__inout PTRACE_GUID_PROPERTIES *GuidPropertiesArray,
__in ULONG PropertyArrayCount,
__out PULONG GuidCount
);
Starting from the code sample 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);
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;
with the api call:
function EnumerateTraceGuids(
GuidPropertiesArray: Pointer;
PropertyArrayCount: Cardinal;
var GuidCount: Cardinal): Cardinal; stdcall; external 'advapi32.dll';
i get the result code ERROR_INVALID_PARAMETER
(87, The parameter is incorrect).
What am i doing wrong?
MSDN describes what would cause ERROR_INVALID_PARAMETER
:
ERROR_INVALID_PARAMETER
One of the following is true:
- PropertyArrayCount is zero
- GuidPropertiesArray is NULL
The first case is true, my 2nd parameter PropertyArrayCount
is zero - just like the sample says it should be.
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:
Then it allocates space in
pProviders
to store a single pointer. However, the value contained inpProviders
actually matters. It cannot beNULL
. In your Delphi code you zeroise that memory twice in fact. Once withAllocMem
and once withZeroMemory
. If you just change your Delphi code to make the contents ofproviders
non-zero then the Delphi code will start working.Here is a very simple project that illustrates exactly what is going on:
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 theTRACE_GUID_PROPERTIES
struct.I'd probably write the code something like this:
Rather than trying to be too cute in
GetRegisteredProviderCount
, I have passed a pointer to a realTRACE_GUID_PROPERTIES
.