5 ms·
> This is why so many Win32 methods take structs that have a size parameter that must be filled in. That acts as a version parameter That said, I couldn't name
by orra 5y ago
> This is why so many Win32 methods take structs that have a size parameter that must be filled in. That acts as a version parameter
That said, I couldn't name you a Win32 that actually has more than one valid value for said cbSize member. Are there any?
- coldpie 5y agoSure, you can find a fair number with a grep of the Wine source. Try "git grep if.*cbSize", there's a few obvious ones and some less obvious, too. One example: https://source.winehq.org/git/wine.git/blob/62df608d3ed84aac7ce517fd07ea13e48b49b08c:/dlls/shell32/systray.c#l64 https://source.winehq.org/git/wine.git/blob/62df608d3ed84aac...
- pitterpatter 5y agoIt's hard to notice sometimes because the a struct FOO is often a typedef to whatever the latest version is in the SDK you're using (FOO1, FOO2, etc).
- alternatetwo 5y agoThis happens a lot in the Media SDKs, dsound, ddraw, dplay etc. Not that they're really used nowadays.
- MaulingMonkey 5y agoum/winuser.h has some, although they haven't changed in awhile. WNDCLASSEX gained hIconSm after Windows 3.x. MENUITEMINFO gained hbmpItem in Windows 2000. NONCLIENTMETRICS gained iPaddedBorderWidth in Windows Vista. https://devblogs.microsoft.com/oldnewthing/20031212-00/?p=41523 https://devblogs.microsoft.com/oldnewthing/20031212-00/?p=41... um/webauthn.h has a bunch of structures that explicitly document fields added in various dwVersion s. However, no individual structure has changed since being published in the Windows SDK last I checked. e.g.: // // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_2 // // Cancellation Id - Optional - See WebAuthNGetCancellationId GUID *pCancellationId; um/wincrypt.h also has a few structures chopped up with #ifdef ..._HAS_EXTRA_FIELDS s that are presumably differentaited between via cbSize. um/ShlObj_core.h has COMPONENT, which extends and is differentiated from IE4COMPONENT - presumably by dwSize. It also wouldn't suprise me if cbSize is also used to differentiate between 32-bit and 64-bit versions of the same structure as well, with WoW64 blindly forwarding said structures.
- orra 5y agoThanks to you, and everybody else, for the examples. I find it interesting upgrading the SDK could make your code invalid, due to uninitialized struct members. Compiler warnings can catch that sort of thing, thankfully—at least these days.
- MaulingMonkey 5y agoThere's a reason examples tend to use ZeroMemory or other mechanism for zero-initializing the entire struct ;) There are other subtle edge cases as well - like needing to make sure all code (including third party libs) is built with the same defines and settings if they might share said structs without painstaking checking cbSize & never passing by value. (Even that might not be enough when statically linking, as it's an ODR violation - and thus undefined behavior - to mix and match different definitions of the same struct...)
- jborean93 5y agoA good example of a really important one is CreateProcess for lpStartupInfo. The value is either a STARTINFO or STARTUPINFOEX and the first member of both structs is cb which is set to the size of the struct that is being used. This allows the code to understand what struct is actually used in the call.