TokenHasRestrictions should be decoded as a one-byte BOOLEAN at a DWORD-aligned address when a successful call returns ReturnLength == 1; allocate four zero-initialized bytes defensively, but do not treat four-byte capacity as an established minimum requirement.
Supported interpretation
Microsoft-maintainer guidance, following internal discussion, states that the current documentation is incorrect: the payload is a BOOLEAN, its pointer must be DWORD-aligned, and the observed ReturnLength == 1 behavior should be documented rather than treated as an implementation defect.^1^
For the reported successful call:
- Representation: one-byte
BOOLEAN.
- Meaning: zero means false; nonzero means the token has been filtered.
-
ReturnLength: 1 describes the complete class-specific BOOLEAN result.
- Defined output: consume only byte 0.
- Bytes 1–3: they are not part of the returned value and must not be decoded as a
DWORD.
- Alignment: the output pointer must be DWORD-aligned.
- Minimum capacity: the clarification does not explicitly establish whether the formal minimum is one accessible byte at a DWORD-aligned address or four accessible bytes.
- Recommended capacity: use an aligned four-byte object while the published header documentation still describes a
DWORD. This is a conservative compatibility measure, not a confirmed minimum-capacity rule.
- Initialization: zero-initialization is not stated as an API prerequisite. It is advisable defensively so that accidental DWORD decoding cannot incorporate indeterminate trailing bytes.
The current Win32 and WDK pages still say that the buffer receives a DWORD whose nonzero value means the token has ever been filtered.^2^^3^ Those pages therefore remain inconsistent with the public maintainer clarification.
A defensive C++ implementation can accept the corrected result without relying on trailing bytes:
alignas(DWORD) std::byte storage[sizeof(DWORD)]{}; // defensive capacity
DWORD returned = 0;
if (!GetTokenInformation(token, TokenHasRestrictions,
storage, sizeof(storage), &returned)) {
DWORD error = GetLastError();
// Report error; do not consume storage.
}
if (returned != sizeof(BOOLEAN)) {
// Unexpected contract result; record diagnostics and reject.
}
const BOOLEAN value = std::to_integer<BOOLEAN>(storage[0]);
const bool hasEverBeenFiltered = (value != FALSE);
The four-byte array preserves DWORD alignment and compatibility with the still-uncorrected DWORD documentation; it is not evidence that four-byte capacity is mandatory.
Version, architecture, and WOW64 scope
The WDK enumeration lists TokenHasRestrictions as valid starting with Windows Vista.^3^ The maintainer expected the one-byte behavior to be consistent across versions, but no published build, architecture, ARM64, or WOW64 test matrix was provided.^1^
Consequently:
- Do not claim a formally documented per-build guarantee beyond the stated Windows Vista applicability.
- Keep the scalar-size validator class-specific rather than globally accepting one-byte results for other token information classes.
- Treat any successful length other than
sizeof(BOOLEAN) as unexpected and collect diagnostics rather than guessing its representation.
GetTokenInformation generally defines ReturnLength as the bytes needed for the requested information and requires TOKEN_QUERY for this class.^4^
Alternative API is not semantically equivalent
IsTokenRestricted is documented, but it answers a narrower question: whether the token currently contains a list of restricting SIDs. It returns FALSE when no such list exists—even if CreateRestrictedToken filtered the token by disabling SIDs or deleting privileges.^5^
Therefore, it cannot replace the “has ever been filtered” predicate unless the application only needs to detect restricting SIDs.
Diagnostics for unexpected results
For a successful result other than length 1, retain:
- Exact Windows edition, build, revision, architecture, and WOW64 status.
- Process bitness and compiler/SDK versions.
-
advapi32.dll and KernelBase.dll file versions.
- Token type and whether it is primary or impersonation.
- Requested capacity, pointer address modulo
alignof(DWORD), returned length, success value, and changed-byte mask.
- A minimal native C/C++ reproduction using
TOKEN_QUERY.
- For failure only, the immediate
GetLastError() value; last-error after success is not meaningful under this API contract.
The win32metadata maintainer recommended filing a documentation issue to track correction of the published contract.^1^
References
- TokenHasRestrictions: documented DWORD vs observed one-byte output - GitHub
- TOKEN_INFORMATION_CLASS enumeration (winnt.h)
- TOKEN_INFORMATION_CLASS enumeration (ntifs.h)
- GetTokenInformation function (securitybaseapi.h)
- IsTokenRestricted function (securitybaseapi.h)