- The basic rules are the same for both 64-bit and 32-bit processes.
- An n-byte parameter must start at an n-byte offset.
- The overall size of the struct must be divisible by the size of the biggest parameter.
- However, I came across around 9-11 structs where this is not the case, they are marked '[CHECK]', in this link:
list of structs with parameters (sizes and types) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=74&t=30497
- Here I came across #pragma as a possible explanation:
c - Structure padding and packing - Stack Overflow
https://stackoverflow.com/questions/4306186/structure-padding-and-packing
- Does MSDN indicate how structs are packed, can I retrieve this information programmatically via C++, by specifying a struct's name?
- Here is some test code:
Code: Select all
// ConsoleApplicationTestStructs.cpp : Defines the entry point for the console application.
//
//checking 11 structs marked '[CHECK]', listed here:
//list of structs with parameters (sizes and types) - AutoHotkey Community
//https://autohotkey.com/boards/viewtopic.php?f=74&t=30497
//would using '#pragma pack' give the expected item offsets/struct sizes
#include "stdafx.h"
#include <iostream>
#include "Windows.h"
#include "WinUser.h" //DLGTEMPLATE //(NMHDR)
#include "CommCtrl.h" //NMLVKEYDOWN
#include "Richedit.h" //GETTEXTEX
#include "commdlg.h" //(OPENFILENAMEA) //PRINTDLG
#include "shellapi.h" //SHFILEOPSTRUCT //SHQUERYRBINFO
#include "shtypes.h" //SHITEMID
#include "mmreg.h" //WAVEFORMAT //WAVEFORMATEX
//C:\Program Files (x86)\Windows Kits\8.1\Include\um\Richedit.h
//#pragma pack(4)
//#pragma pack()
//C:\Program Files (x86)\Windows Kits\8.1\Include\shared\mmreg.h
//#pragma pack(1)
//#pragma pack(1)
//#pragma pack(push, 1)
//#pragma pack(pop) /* Assume byte packing throughout */
int _tmain(int argc, _TCHAR* argv[])
{
//DLGTEMPLATE ;WinUser.h
//GETTEXTEX ;Richedit.h
//(NMHDR) ;WinUser.h
//NMLVKEYDOWN ;CommCtrl.h
//(OPENFILENAMEA) ;commdlg.h
//PRINTDLG ;commdlg.h
//SHFILEOPSTRUCT ;shellapi.h
//SHITEMID ;shtypes.h
//SHQUERYRBINFO ;shellapi.h
//WAVEFORMAT ;mmreg.h
//WAVEFORMATEX ;mmreg.h
//std::cout << "abc" << std::endl;
//std::cout << "MYSTRUCT=" << sizeof(MYSTRUCT) << std::endl;
//==================================================
//DLGTEMPLATE ;WinUser.h
typedef struct {
DWORD style;
DWORD dwExtendedStyle;
WORD cdit;
short x;
short y;
short cx;
short cy;
} MyDLGTEMPLATE;
#pragma pack(4)
//GETTEXTEX ;Richedit.h
typedef struct My_gettextex {
DWORD cb;
DWORD flags;
UINT codepage;
LPCSTR lpDefaultChar;
LPBOOL lpUsedDefChar;
} MyGETTEXTEX;
#pragma pack()
//(NMHDR) ;WinUser.h [MSDN: richedit.h (include Winuser.h)]
typedef struct My_nmhdr {
HWND hwndFrom;
UINT idFrom;
UINT code;
} MyNMHDR;
//(NMHDR) ;WinUser.h [MSDN: richedit.h (include Winuser.h)]
typedef struct My2_nmhdr {
HWND hwndFrom;
UINT_PTR idFrom;
UINT code;
} My2NMHDR;
//NMLVKEYDOWN ;CommCtrl.h
typedef struct MytagLVKEYDOWN {
NMHDR hdr;
WORD wVKey;
UINT flags;
} MyNMLVKEYDOWN, *MyLPNMLVKEYDOWN;
//(OPENFILENAMEA) ;commdlg.h
typedef struct MytagOFNA {
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCSTR lpstrFilter;
LPSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPSTR lpstrFile;
DWORD nMaxFile;
LPSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCSTR lpstrInitialDir;
LPCSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCSTR lpTemplateName;
//LPEDITMENU lpEditInfo; //not found, so using LPVOID instead (see line below)
LPVOID lpEditInfo;
LPCSTR lpstrPrompt;
void *pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
} MyOPENFILENAMEA, *MyLPOPENFILENAMEA;
//PRINTDLG ;commdlg.h
typedef struct MytagPDA {
DWORD lStructSize;
HWND hwndOwner;
HGLOBAL hDevMode;
HGLOBAL hDevNames;
HDC hDC;
DWORD Flags;
WORD nFromPage;
WORD nToPage;
WORD nMinPage;
WORD nMaxPage;
WORD nCopies;
HINSTANCE hInstance;
LPARAM lCustData;
LPPRINTHOOKPROC lpfnPrintHook;
LPSETUPHOOKPROC lpfnSetupHook;
LPCSTR lpPrintTemplateName;
LPCSTR lpSetupTemplateName;
HGLOBAL hPrintTemplate;
HGLOBAL hSetupTemplate;
} MyPRINTDLGA, *MyLPPRINTDLGA;
typedef MyPRINTDLGA MyPRINTDLG;
//SHFILEOPSTRUCT ;shellapi.h
typedef struct My_SHFILEOPSTRUCTA {
HWND hwnd;
UINT wFunc;
PCZZSTR pFrom;
PCZZSTR pTo;
FILEOP_FLAGS fFlags;
BOOL fAnyOperationsAborted;
LPVOID hNameMappings;
PCSTR lpszProgressTitle;
} MySHFILEOPSTRUCTA, *MyLPSHFILEOPSTRUCTA;
typedef MySHFILEOPSTRUCTA MySHFILEOPSTRUCT;
//typedef OLDNAME NEWNAME;
//SHITEMID ;shtypes.h
typedef struct My_SHITEMID {
USHORT cb;
BYTE abID[1];
} MySHITEMID;
//SHQUERYRBINFO ;shellapi.h
//source: shellapi.h
typedef struct My_SHQUERYRBINFO {
DWORD cbSize;
#if !defined(_MAC) || defined(_MAC_INT_64)
__int64 i64Size;
__int64 i64NumItems;
#else
DWORDLONG i64Size;
DWORDLONG i64NumItems;
#endif
} MySHQUERYRBINFO, *MyLPSHQUERYRBINFO;
#pragma pack(1)
//WAVEFORMAT ;mmreg.h
typedef struct Mywaveformat_tag {
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
} MyWAVEFORMAT;
//WAVEFORMATEX ;mmreg.h
typedef struct {
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
WORD cbSize;
} MyWAVEFORMATEX;
#pragma pack()
//==================================================
std::cout << "DLGTEMPLATE=" << sizeof(DLGTEMPLATE) << std::endl;
std::cout << "GETTEXTEX=" << sizeof(GETTEXTEX) << std::endl;
std::cout << "NMHDR=" << sizeof(NMHDR) << std::endl;
std::cout << "NMLVKEYDOWN=" << sizeof(NMLVKEYDOWN) << std::endl;
std::cout << "OPENFILENAMEA=" << sizeof(OPENFILENAMEA) << std::endl;
std::cout << "PRINTDLG=" << sizeof(PRINTDLG) << std::endl;
std::cout << "SHFILEOPSTRUCT=" << sizeof(SHFILEOPSTRUCT) << std::endl;
std::cout << "SHITEMID=" << sizeof(SHITEMID) << std::endl;
std::cout << "SHQUERYRBINFO=" << sizeof(SHQUERYRBINFO) << std::endl;
std::cout << "WAVEFORMAT=" << sizeof(WAVEFORMAT) << std::endl;
std::cout << "WAVEFORMATEX=" << sizeof(WAVEFORMATEX) << std::endl;
std::cout << "" << std::endl;
std::cout << "MyDLGTEMPLATE=" << sizeof(MyDLGTEMPLATE) << std::endl;
std::cout << "MyGETTEXTEX=" << sizeof(MyGETTEXTEX) << std::endl;
std::cout << "MyNMHDR=" << sizeof(MyNMHDR) << std::endl;
std::cout << "MyNMLVKEYDOWN=" << sizeof(MyNMLVKEYDOWN) << std::endl;
std::cout << "MyOPENFILENAMEA=" << sizeof(MyOPENFILENAMEA) << std::endl;
std::cout << "MyPRINTDLG=" << sizeof(MyPRINTDLG) << std::endl;
std::cout << "MySHFILEOPSTRUCT=" << sizeof(MySHFILEOPSTRUCT) << std::endl;
std::cout << "MySHITEMID=" << sizeof(MySHITEMID) << std::endl;
std::cout << "MySHQUERYRBINFO=" << sizeof(MySHQUERYRBINFO) << std::endl;
std::cout << "MyWAVEFORMAT=" << sizeof(MyWAVEFORMAT) << std::endl;
std::cout << "MyWAVEFORMATEX=" << sizeof(MyWAVEFORMATEX) << std::endl;
std::cout << "" << std::endl;
std::cout << "My2NMHDR=" << sizeof(My2NMHDR) << std::endl;
std::getchar();
return 0;
}