Help with declare

I have the following code working on 32 bit targets but failing on 64 bit and can’t understand the reason.
Maybe someone else familiar with declares on Windows can spot the problem.

The error I get is 24, that is ERROR_BAD_LENGTH. This seems to indicate wrong length of… something. The struct seems correct to me but still…

' typedef struct tagPROCESSENTRY32 {
' DWORD     dwSize;                  // 4 bytes
' DWORD     cntUsage;                // 4 bytes
' DWORD     th32ProcessID;           // 4 bytes
' ULONG_PTR th32DefaultHeapID;       // 4 bytes on 32 bit, 8 bytes on 64 bit
' DWORD     th32ModuleID;            // 4 bytes
' DWORD     cntThreads;              // 4 bytes
' DWORD     th32ParentProcessID;     // 4 bytes
' LONG      pcPriClassBase;          // 4 bytes
' DWORD     dwFlags;                 // 4 bytes
' TCHAR     szExeFile[MAX_PATH];     // 260 bytes * 2 (due to Unicode)
' } PROCESSENTRY32, *PPROCESSENTRY32;


' HANDLE WINAPI CreateToolhelp32Snapshot(
' _In_ DWORD dwFlags,
' _In_ DWORD th32ProcessID
' );

' BOOL WINAPI Process32First(
' _In_    HANDLE           hSnapshot,
' _Inout_ LPPROCESSENTRY32 lppe
' );

Declare Function CreateToolhelp32Snapshot Lib "Kernel32" (dwFlags as UInt32, th32ProcessID as UInt32 ) as Integer
Declare Function Process32FirstW Lib "Kernel32" ( hSnapshot as Integer, lppe as Ptr ) as Boolean
Declare Function GetLastError Lib "Kernel32" () as UInt32

const TH32CS_SNAPPROCESS = &h2
const MAX_PATH = 260*2 // WCHAR = 16 bit

// get handle
dim snapHandle as Integer = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 )

// create memory block to hold the PROCESSENTRY32 struct
#if target32Bit
  dim mb as new memoryBlock( MAX_PATH + 36 )
#else
  dim mb as new memoryBlock( MAX_PATH + 40 )
#endif

// set the struct size on first DWORD
mb.UInt32Value(0) = mb.Size

// get first process
dim b as boolean = Process32FirstW( snapHandle, mb )

// get error number if needed
dim err as UInt32
if not b then
  err = GetLastError()
end if

You’re only taking the last tchar and the long_ptr into account in your Memoryblock. What about all the other parts?

The other parts are either DWORD or LONG which, as from Microsoft docs, don’t change in size either in 32 or 64 bit.

Solved.
It’s a struct alignment problem. On the memoryBlock have to allocate 8 bytes more due to the alignment and then it works.

The problem is due to alignment and padding, the sizes are slightly bigger because things are moved along after th32DefaultHeapID:

32b size 556

offsets
0
4
8
12
16
20
24
28
32
36

64b size 568
0
4
8
16
24
28
32
36
40
44