Geoff Chappell - Software Analyst
The public symbol file NTKRPAMP.PDB for the original release of Windows 10 tells that the kernel is built with the NTPSAPI_X.H header at
d:\th.public.fre\internal\sdk\inc
and draws from it the type definitions that are tabulated below. The header NTPSAPI_X.H is not known in any Device Driver Kit (DDK) or Windows Driver Kit (WDK).
Line Number | Type |
---|---|
42 | struct _PEB_LDR_DATA |
83 | struct _GDI_TEB_BATCH |
114 | struct _CLIENT_ID64 |
230 | struct _CLIENT_ID |
259 | struct _EXCEPTION_REGISTRATION_RECORD |
266 | struct _NT_TIB |
287 | struct _NT_TIB32 |
306 | struct _NT_TIB64 |
855 | enum _HARDWARE_COUNTER_TYPE |
1382 | enum JOB_OBJECT_NET_RATE_CONTROL_FLAGS |
1419 | enum JOB_OBJECT_IO_RATE_CONTROL_FLAGS |
1605 | enum _JOBOBJECTINFOCLASS |
Though only these dozen types that are defined in NTPSAPI_X.H show in the public symbols for the kernel, many more show in symbol files for other modules. Among these are user-mode modules that are very far removed from system-level programming, e.g., URLMON.DLL from Internet Explorer. Though the symbol files in question have private symbols, Microsoft has published them freely in downloadable packages of all the public symbols for all of Windows, starting with Windows 8, and continues to make them available on demand to debugging tools via the public symbol server. If distribution of these unusually detailed symbol files was at first an oversight, it is a disclosure that has been left to stand for a decade, though not for all modules. For instance, it ceased for URLMON.DLL after the 1709 release of Windows 10.
Most, though certainly not all, of the types that multiple symbol files attribute to the unpublished NTPSAPI_X.H are defined in other headers that Microsoft does publish: WDM.H and NTDDK.H from the WDK and WINNT.H from the Software Development Kit (SDK). These are in some sense the standard headers for their level of Windows programming, one or another (or more) being included by the source code for almost all kernel-mode or user-mode software.
It may be that content is extracted from NTPSAPI_X.H to these standard headers or that all are extracted from yet some other input. However it’s done, the effect looks to be that successive lines of NTPSAPI_X.H are appended to zero or more of the published headers, and each of the latter then has one contiguous region of lines that are each in NTPSAPI_X.H. Matching line numbers for type definitions as seen in the standard headers and deduced from type information for NTPSAPI_X.H then supports a reasonable attempt at reconstructing much of what the unseen NTPSAPI_X.H must have between its type definitions. The table below is then a skeleton for reconstructing NTPSAPI_X.H for the original Windows 10.
Types and line numbers in this table are collected from all known type information not just in symbol files but also in the statically linked library CLFSMGMT.LIB from the SDK for Windows 10. That this library has type information for NTPSAPI_X.H means, of course, that one of the object files it archives has a #include of this header, if not directly then as a nested inclusion. That this library has no much type information for NTPSAPI_X.H is because this object file is a by-product of creating a pre-compiled header. It thus records not what types were regarded as used for any compilation of a source file but all the types that might get used. Its list of types defined in NTPSAPI_X.H is plausibly complete.
Line Number | Type | WDM.H | NTDDK.H | WINNT.H |
---|---|---|---|---|
42 | struct _PEB_LDR_DATA | |||
83 | struct _GDI_TEB_BATCH | |||
94 | struct _Wx86ThreadState | |||
114 | struct _CLIENT_ID64 | |||
217 | struct _JOB_SET_ARRAY | 10929 | ||
230 | struct _CLIENT_ID | 7360 | ||
259 | struct _EXCEPTION_REGISTRATION_RECORD | 4274 | 10938 | |
266 | struct _NT_TIB | 4281 | 10945 | |
272 | anonymous union in struct _NT_TIB |
4287 | 10951 | |
287 | struct _NT_TIB32 | 4302 | 10966 | |
294 | anonymous union in struct _NT_TIB32 |
4309 | 10973 | |
306 | struct _NT_TIB64 | 4321 | 10985 | |
313 | anonymous union in struct _NT_TIB64 |
4328 | 10992 | |
336 | enum _PROCESSINFOCLASS | 4345 | ||
422 | enum _THREADINFOCLASS | 4424 | ||
491 | enum _THREAD_UMS_INFORMATION_COMMAND | |||
498 | struct _THREAD_UMS_INFORMATION | |||
505 | anonymous union in struct _THREAD_UMS_INFORMATION |
|||
507 | anonymous struct in anonymous union in struct _THREAD_UMS_INFORMATION |
|||
526 | anonymous union in anonymous union in struct _THREAD_UMS_INFORMATION |
|||
528 | anonymous struct in anonymous union in anonymous union in struct _THREAD_UMS_INFORMATION |
|||
541 | struct _UMS_CREATE_THREAD_ATTRIBUTES | 11012 | ||
552 | anonymous union in struct _UMS_CREATE_THREAD_ATTRIBUTES |
|||
561 | anonymous union in struct _UMS_CREATE_THREAD_ATTRIBUTES |
|||
578 | enum _MEMORY_EXHAUSTION_TYPE | |||
586 | struct _MEMORY_EXHAUSTION_INFORMATION | |||
593 | struct _PROCESS_JOB_MEMORY_INFO | |||
612 | struct _PAGE_PRIORITY_INFORMATION | 4478 | ||
620 | struct _PROCESS_WS_WATCH_INFORMATION | 4486 | ||
630 | struct _PROCESS_BASIC_INFORMATION | 4496 | ||
639 | struct _PROCESS_EXTENDED_BASIC_INFORMATION | 4505 | ||
642 | anonymous union in struct _PROCESS_EXTENDED_BASIC_INFORMATION |
4508 | ||
644 | anonymous struct in anonymous union in struct _PROCESS_EXTENDED_BASIC_INFORMATION |
4510 | ||
673 | struct _PROCESS_DEVICEMAP_INFORMATION | 4531 | ||
674 | anonymous union in struct _PROCESS_DEVICEMAP_INFORMATION |
4532 | ||
675 | unnamed struct Set in anonymous union in struct _PROCESS_DEVICEMAP_INFORMATION |
4533 | ||
678 | unnamed struct Query in anonymous union in struct _PROCESS_DEVICEMAP_INFORMATION |
4536 | ||
685 | struct _PROCESS_DEVICEMAP_INFORMATION_EX | 4543 | ||
686 | anonymous union in struct _PROCESS_DEVICEMAP_INFORMATION_EX |
4544 | ||
687 | unnamed struct Set in anonymous union in struct _PROCESS_DEVICEMAP_INFORMATION_EX |
4545 | ||
690 | unnamed struct for Query in anonymous union in struct _PROCESS_DEVICEMAP_INFORMATION_EX |
4548 | ||
708 | struct _PROCESS_SESSION_INFORMATION | 4566 | ||
712 | struct _PROCESS_HANDLE_TRACING_ENABLE | 4570 | ||
716 | struct _PROCESS_HANDLE_TRACING_ENABLE_EX | 4574 | ||
728 | struct _PROCESS_HANDLE_TRACING_ENTRY | 4586 | ||
735 | struct _PROCESS_HANDLE_TRACING_QUERY | 4593 | ||
750 | struct _QUOTA_LIMITS | 4608 | 11018 | |
765 | union _RATE_QUOTA_LIMIT | 4623 | 11033 | |
767 | anonymous struct in union _RATE_QUOTA_LIMIT |
4625 | 11035 | |
773 | struct _QUOTA_LIMITS_EX | 4631 | 11041 | |
796 | struct _IO_COUNTERS | 4654 | 11056 | |
813 | struct _VM_COUNTERS | 4671 | ||
828 | struct _VM_COUNTERS_EX | 4686 | ||
845 | struct _VM_COUNTERS_EX2 | 4703 | ||
855 | enum _HARDWARE_COUNTER_TYPE | 4713 | 11069 | |
865 | struct _HARDWARE_COUNTER | 4720 | ||
877 | enum _PROCESS_MITIGATION_POLICY | 4732 | 11073 | |
896 | struct _PROCESS_MITIGATION_ASLR_POLICY | 4751 | 11092 | |
897 | anonymous union in struct _PROCESS_MITIGATION_ASLR_POLICY |
4752 | 11093 | |
899 | anonymous struct in anonymous union in struct _PROCESS_MITIGATION_ASLR_POLICY |
4754 | 11095 | |
909 | struct _PROCESS_MITIGATION_DEP_POLICY | 4764 | 11105 | |
910 | anonymous union in struct _PROCESS_MITIGATION_DEP_POLICY |
4765 | 11106 | |
912 | anonymous struct in anonymous union in struct _PROCESS_MITIGATION_DEP_POLICY |
4767 | 11108 | |
921 | struct _PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY | 4776 | 11117 | |
922 | anonymous union in struct _PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY |
4777 | 11118 | |
924 | anonymous struct in anonymous union in struct _PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY |
4779 | 11120 | |
932 | struct _PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY | 4787 | 11128 | |
933 | anonymous union in struct _PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY |
4788 | 11129 | |
935 | anonymous struct in anonymous union in struct _PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY |
4790 | 11131 | |
942 | struct _PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY | 4797 | 11138 | |
943 | anonymous union in struct _PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY |
4798 | 11139 | |
945 | anonymous struct in anonymous union in struct _PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY |
4800 | 11141 | |
952 | struct _PROCESS_MITIGATION_DYNAMIC_CODE_POLICY | 4807 | 11148 | |
953 | anonymous union in struct _PROCESS_MITIGATION_DYNAMIC_CODE_POLICY |
4808 | 11149 | |
955 | anonymous struct in anonymous union in struct _PROCESS_MITIGATION_DYNAMIC_CODE_POLICY |
4810 | 11151 | |
964 | struct _PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY | |||
965 | anonymous union in struct _PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY |
|||
967 | anonymous struct in anonymous union in struct _PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY |
|||
976 | struct _PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY | 4818 | 11159 | |
977 | anonymous union in struct _PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY |
4819 | 11160 | |
979 | anonymous struct in anonymous union in struct _PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY |
4821 | 11162 | |
986 | struct _PROCESS_MITIGATION_FONT_DISABLE_POLICY | 4828 | 11169 | |
987 | anonymous union in struct _PROCESS_MITIGATION_FONT_DISABLE_POLICY |
4829 | 11170 | |
989 | anonymous struct in anonymous union in struct _PROCESS_MITIGATION_FONT_DISABLE_POLICY |
4831 | 11172 | |
1003 | struct _PROCESS_KEEPALIVE_COUNT_INFORMATION | 4845 | ||
1012 | struct _PROCESS_REVOKE_FILE_HANDLES_INFORMATION | 4854 | ||
1021 | struct _POOLED_USAGE_AND_LIMITS | 4863 | ||
1041 | struct _PROCESS_ACCESS_TOKEN | 4883 | ||
1072 | struct _PROCESS_EXCEPTION_PORT | 4914 | ||
1095 | struct _KERNEL_USER_TIMES | 4937 | ||
1159 | struct _JOBOBJECT_BASIC_ACCOUNTING_INFORMATION | 11181 | ||
1170 | struct _JOBOBJECT_BASIC_LIMIT_INFORMATION | 11192 | ||
1182 | struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION | 11204 | ||
1197 | struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION_V2 | |||
1216 | struct _JOBOBJECT_BASIC_PROCESS_ID_LIST | 11214 | ||
1222 | struct _JOBOBJECT_BASIC_UI_RESTRICTIONS | 11220 | ||
1230 | struct _JOBOBJECT_SECURITY_LIMIT_INFORMATION | 11228 | ||
1238 | struct _JOBOBJECT_END_OF_JOB_TIME_INFORMATION | 11236 | ||
1242 | struct _JOBOBJECT_ASSOCIATE_COMPLETION_PORT | 11240 | ||
1247 | struct _JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION | 11245 | ||
1252 | struct _JOBOBJECT_JOBSET_INFORMATION | 11250 | ||
1256 | enum _JOBOBJECT_RATE_CONTROL_TOLERANCE | 11254 | ||
1262 | enum _JOBOBJECT_RATE_CONTROL_TOLERANCE_INTERVAL | 11260 | ||
1269 | struct _JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION | 11267 | ||
1279 | struct JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION_2 | 11277 | ||
1283 | anonymous union in struct JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION_2 |
11281 | ||
1288 | anonymous union in struct JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION_2 |
11286 | ||
1293 | anonymous union in struct JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION_2 |
11291 | ||
1313 | struct _JOBOBJECT_LIMIT_VIOLATION_INFORMATION | 11306 | ||
1328 | struct JOBOBJECT_LIMIT_VIOLATION_INFORMATION_2 | 11321 | ||
1338 | anonymous union in struct JOBOBJECT_LIMIT_VIOLATION_INFORMATION_2 |
11331 | ||
1343 | anonymous union in struct JOBOBJECT_LIMIT_VIOLATION_INFORMATION_2 |
11336 | ||
1348 | anonymous union in struct JOBOBJECT_LIMIT_VIOLATION_INFORMATION_2 |
11341 | ||
1366 | struct _JOBOBJECT_CPU_RATE_CONTROL_INFORMATION | 11354 | ||
1368 | anonymous union in struct _JOBOBJECT_CPU_RATE_CONTROL_INFORMATION |
11356 | ||
1371 | anonymous struct in anonymous union in struct _JOBOBJECT_CPU_RATE_CONTROL_INFORMATION |
11359 | ||
1382 | enum JOB_OBJECT_NET_RATE_CONTROL_FLAGS | 11370 | ||
1401 | struct JOBOBJECT_NET_RATE_CONTROL_INFORMATION | 11389 | ||
1419 | enum JOB_OBJECT_IO_RATE_CONTROL_FLAGS | 11402 | ||
1432 | struct JOBOBJECT_IO_RATE_CONTROL_INFORMATION_NATIVE | 11415 | ||
1605 | enum _JOBOBJECTINFOCLASS | 11552 | ||
1695 | struct _SILOOBJECT_BASIC_INFORMATION | 11604 | ||
1703 | struct _SILOOBJECT_ROOT_DIRECTORY | 11612 | ||
1709 | enum _SERVERSILO_STATE | 11618 | ||
1716 | struct _SERVERSILO_BASIC_INFORMATION | 11625 | ||
1724 | enum _SILOOBJECTINFOCLASS | 11633 |
To include line numbers for anonymous structures and unions nested in other structures and unions is undeniably tedious and yet it can be instructive. Look, for instance, at _UMS_CREATE_THREAD_ATTRIBUTES. The definition in WINNT.H does not have the anonymous unions, but their existence is known from type information in CLFSMGMT.LIB. The explanation is that the definition in WINNT.H is not whole:
typedef struct _UMS_CREATE_THREAD_ATTRIBUTES { DWORD UmsVersion; PVOID UmsContext; PVOID UmsCompletionList; } UMS_CREATE_THREAD_ATTRIBUTES, *PUMS_CREATE_THREAD_ATTRIBUTES;
Practised readers of Microsoft’s published headers will recognise that the unusual alignment of the text—and especially the trailing white space that does not show readily in a web browser—is a tip-off. The full definition has two anonymous unions, each wrapping one of the pointers that seem overly-indented in the WINNT.H definition. Programmers who have access to the full definition have additional members whose types show what’s pointed to. The full definition must look very much like:
typedef struct _UMS_CREATE_THREAD_ATTRIBUTES { // winnt DWORD UmsVersion; // winnt union { PRTL_UMS_CONTEXT RtlUmsContext; PVOID UmsContext; // winnt }; union { PRTL_UMS_COMPLETION_LIST RtlUmsCompletionList; PVOID UmsCompletionList; // winnt }; } UMS_CREATE_THREAD_ATTRIBUTES, *PUMS_CREATE_THREAD_ATTRIBUTES; // winnt
There are a few editorical choices here. I omit whatever it is (empty lines and commenting, most likely) that spreads the definition so that the successive opening braces are 11 and 9 lines apart instead of the 2 and 4 that I show. Though the single-line comments that mark their lines for passing into WINNT.H have no neat alignment, they reproduce the trailing white space that survives in WINNT.H. With one exception, each is simply at the next tab stop. The PRTL_UMS_CONTEXT and PRTL_UMS_COMPLETION_LIST are known from the type information to be Microsoft’s typedef names for pointers to the relevant structures (defined in ntrtl_x.h) and it would be unusual of Microsoft not to use them here.
Which definition shows in symbol files varies with the module and how it was built. For instance, URLMON.DLL picks up the reduced definition from WINNT.H but OLE32.DLL has the full definition from NTPSAPI_X.H—well, as full as we yet know.
The wonder is that WINNT.H has any definition at all of UMS_CREATE_THREAD_ATTRIBUTES. Someone at Microsoft evidently took trouble to get it there, and yet it’s an orphan: neither WINNT.H nor any other header in either the SDK or WDK has any reference to it.
Of all the types that are known to be defined in NTPSAPI_X.H for the original Windows 10 (see the preceding table), here for the record are those that are not defined in any of the standard headers for either kernel-mode or user-mode programming and were not accessible to the source code for URLMON.DLL from including NTPSAPI_X.H when building for the original release of 32-bit Windows 10: none.
Many of the other types that are defined in NTPSAPI_X.H will have been accessible too, of course, but the symbol file shows that URLMON.DLL got these unremarkably: from WINNT.H, as might any other user-mode DLL. For those that are not defined in the standard headers, the programmers of URLMON had complete access.