Hi,
Is this a macro or a function?
Best regards,
Astro.
The MASM manual could answer some of these questions.
sizeof is part of the MASM "language". It's a bit like STRUCT, db and others.
it's does not translate into code. the assembler reads it at runtime, finds out how big the item is defined in its inc files then translates it into an immediate value
Great! I did look in the MASM docs but couldn't see this one. The other point to remember is that documentation in general only ever explains something one way, and it is identical every time. :U
SP_DEVICE_INTERFACE_DETAIL_DATA struct
cbSize DWORD ?
DevicePath BYTE 4096 DUP (?)
SP_DEVICE_INTERFACE_DETAIL_DATA ends
Would sizeof of that struct be: 4096+4 = 4100?
...and cbSize = 4100 or 4096 (total of remaining elements)?
Best regards,
Astro.
#define ANYSIZE_ARRAY 1
typedef struct _SP_DEVICE_INTERFACE_DETAIL_DATA {
DWORD cbSize;
TCHAR DevicePath[ANYSIZE_ARRAY];
} SP_DEVICE_INTERFACE
From the PSDK documentation for the SetupDiGetDeviceInterfaceDetail function:
Quote
Pointer to a SP_DEVICE_INTERFACE_DETAIL_DATA structure to receive
information about the specified interface. You must set the cbSize
member to sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA) before calling
this function. The cbSize member always contains the size of the
fixed part of the data structure, not a size reflecting the
variable-length string at the end.
In my C test code compiled with Visual C++ Toolkit 2003 sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) returned 5.
SIZEOF DevicePath
Would be 4096.
sizeof cbSzie is 4
sizeof returns length in bytes
lengthof returns the number of data elements
they are assembler directives, similar to equate's
if you have
SomeArray dd 20 dup(?)
sizeof SomeArray = 80
lengthof SomeArray = 20
Quoteif you have
SomeArray dd 20 dup(?)
sizeof SomeArray = 80
lengthof SomeArray = 20
Thanks.
The reason I was asking was because if it was a macro, where is the code for it as I wanted to dissect it. :bg
Quote...and cbSize = 4100 or 4096 (total of remaining elements)?
I've since answered my own question. Needed a break.
http://msdn.microsoft.com/en-us/library/ms792901.aspx
Quote2. Allocate an appropriately sized buffer and call the function again to get the interface details.
Instead of putting DevicePath BYTE 4096 DUP (?) into the code, and eating 4 kB of memory for possibly no good reason, is there a way I can make the size of this element dynamic, or does it have to be hard-coded? As the function is expecting a pointer to a structure, I can't simply assign a block of memory of the required size for one element (correct me if I'm wrong), unless I replace the structure entirely with a block of memory assigned at run time and omit the structure. Seems this is all structures do anyway??? That way the memory is not assigned off the bat when the program starts, but rather during run-time as it is needed.
Please correct me if I'm talking rubbish - I'm still finding out just what I can/can't do, although I'm perfectly happy managing all this stuff as it gives total freedom. :)
Bottom line: I don't want to allocate 4 kB of memory until I need it.
Best regards,
Astro.
i suggest the HeapAlloc functions
you can allocate memory, more than you need, then resize the allocation
http://msdn.microsoft.com/en-us/library/aa366569(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa366597(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa366701(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa366704(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa366598(VS.85).aspx
Thanks! :8)
Best regards,
Astro.
Does this look correct?
;Create new private heap in process memory
push 0h ;heap can grow
push 0h ;allocates 1 page
push 0h
call HeapCreate ;use HeapDestroy to reverse
mov hHeap,eax
;hMemDevIntData DWORD ?
push 400h ;allocate 1024 bytes
push 8h ;zero memory
push hHeap
call HeapAlloc ;use HeapFree to reverse
mov hMemDevIntData,eax
mov dword ptr [hMemDevIntData],400h ;cbSize - 1024 bytes
;hMemDevIntDetailData DWORD ?
push 400h ;allocate 1024 bytes
push 8h ;zero memory
push hHeap
call HeapAlloc ;use HeapFree to reverse
mov hMemDevIntDetailData,eax
mov dword ptr [hMemDevIntDetailData],400h ;cbSize - 1024 bytes
Best regards,
Astro.
you don't need to use HeapCreate
here it is with INVOKE's
if you want to use push/call, just push the same parameters as the INVOKE, only push the last parameter first
.DATA?
hHeap dd ? ;process heap handle
HeapBlockAddress dd ?
.CODE
.
.
.
;get the handle to the process heap
INVOKE GetProcessHeap
mov hHeap,eax
.
.
.
;allocate 1 Kb memory
INVOKE HeapAlloc,
hHeap,
NULL,
1024
mov HeapBlockAddress,eax
.
.
.
;release the allocated block
INVOKE HeapFree,
hHeap,
NULL,
HeapBlockAddress
However you allocate the buffer, the first dword must be set to 5.
QuoteHowever you allocate the buffer, the first dword must be set to 5.
huh ? :eek
you mean the first dword in the allocated block ?
Sorry, I should have made my meaning clear. I mean that the pointer that is passed in the DeviceInterfaceDetailData parameter of the SetupDiGetDeviceInterfaceDetail function must point to a dword with the size of the fixed part of the structure (5), not 400h. Since you cannot reasonably allocate memory at the end of the structure, I'm assuming that the essential part of the structure will be duplicated at the start of the allocated memory.
Quote from: dedndave on July 28, 2009, 03:52:42 AM
QuoteHowever you allocate the buffer, the first dword must be set to 5.
huh ? :eek
+1
DWORD = 4 bytes. Why set the value to 5 bytes?
The length that wants setting before the call will be cloesr to 4 + 100 = 104. If I set it to 5, it will error every time (ERROR_INVALID_USER_BUFFER). Once I've ran it, I'll have a better idea of the size I want.
I know the fisrt DWORD of the memory block must be set to the size of the structure as this is where the function will be expecting to see cbSize.
@dedndave: By allocating a seperate heap, I can set the heap to be able to grow, not be executable, etc... If I don't do this, the default heap might not be expandable, and might be executable. It might also reduce my chance of breaking something. :cheekygreen:
The article talks of "system overhead" for the heap but fails to say what this is. ::)
Best regards,
Astro.
The attachment contains a minimal C test app compiled with Visual C++ Toolkit 2003 that shows what I am describing. API structures where the last member is the first character of a variable-length string are fairly common. Searching my 2003 version of the PSDK for "ANYSIZE_ARRAY" I find a total of 12. AFAIK the intention is that instead of allocating a structure you allocate a buffer of an appropriate length, cast the buffer pointer to a structure pointer, and then access the structure members by name through the pointer.
[attachment deleted by admin]
Hi Michael,
Not forgotton - just working on something else ATM. :U
Best regards,
Astro.