diff --git a/source/win32/advapi32/lib.ts b/source/win32/advapi32/lib.ts index 5583e97..1482330 100644 --- a/source/win32/advapi32/lib.ts +++ b/source/win32/advapi32/lib.ts @@ -1,15 +1,6 @@ import koffi from 'koffi-cream' -import { Internals, binaryBuffer, type OUT } from '../private.js' -import { cBOOL, cBYTE, cINT, cDWORD, cHANDLE, cPVOID, cPDWORD, type HTOKEN } from '../ctypes.js' -import { - cLUID_AND_ATTRIBUTES, - cSID, type SID, - cSID_AND_ATTRIBUTES, cSID_AND_ATTRIBUTES_HASH, type SID_AND_ATTRIBUTES_HASH, - cTOKEN_PRIVILEGES, type TOKEN_PRIVILEGES, - cTOKEN_GROUPS, type TOKEN_GROUPS, - cCLAIM_SECURITY_ATTRIBUTES_INFORMATION, type CLAIM_SECURITY_ATTRIBUTES_INFORMATION, - cCLAIM_SECURITY_ATTRIBUTE_V1, -} from '../structs.js' +import { binaryBuffer, type OUT } from '../private.js' +import { cBOOL, cINT, cDWORD, cHANDLE, cPVOID, cPDWORD, type HTOKEN } from '../ctypes.js' export const advapi32 = koffi.load('advapi32.dll') @@ -66,62 +57,6 @@ export const enum INTERNAL_TOKEN_INFORMATION_CLASS { MaxTokenInfoClass } -export function decodeSid(ptr: unknown): SID { - const [ Revision, SubAuthorityCount, ...IdentifierAuthority ] = koffi.decode(ptr, 0, cBYTE, 8) as [ number, number, number, number, number, number, number, number ] - const SubAuthority: number[] = Array.from(koffi.decode(ptr, koffi.offsetof(cSID, 'SubAuthority'), cDWORD, SubAuthorityCount)) - SubAuthority.length = Internals.SID_MAX_SUB_AUTHORITIES - SubAuthority.fill(0, SubAuthorityCount) - return { - Revision, - SubAuthorityCount, - IdentifierAuthority, - SubAuthority - } -} - -export function decodeSidAndAttributesHash(ptr: unknown): SID_AND_ATTRIBUTES_HASH { - const ret: SID_AND_ATTRIBUTES_HASH = koffi.decode(ptr, cSID_AND_ATTRIBUTES_HASH) - if (ret.SidAttr) { - ret.SidAttr = koffi.decode(ret.SidAttr, cSID_AND_ATTRIBUTES, ret.SidCount) - ret.SidAttr.forEach(sid => sid.Sid = decodeSid(sid.Sid)) - } - else ret.SidAttr = [], ret.SidCount = 0 - return ret -} - -export function decodeTokenPrivileges(ptr: unknown): TOKEN_PRIVILEGES { - const ret: TOKEN_PRIVILEGES = koffi.decode(ptr, cTOKEN_PRIVILEGES) - if (ret.Privileges) { - ret.Privileges = koffi.decode(ptr, koffi.offsetof(cTOKEN_PRIVILEGES, 'Privileges'), cLUID_AND_ATTRIBUTES, ret.PrivilegeCount) - } - else ret.Privileges = [], ret.PrivilegeCount = 0 - return ret -} - -export function decodeTokenGroups(ptr: unknown): TOKEN_GROUPS { - const ret: TOKEN_GROUPS = koffi.decode(ptr, cTOKEN_GROUPS) - if (ret.GroupCount > 0) { - ret.Groups = koffi.decode(ptr, koffi.offsetof(cTOKEN_GROUPS, 'Groups'), cSID_AND_ATTRIBUTES, ret.GroupCount) - ret.Groups.forEach(group => group.Sid = decodeSid(group.Sid)) - } - else ret.Groups = [] - return ret -} - -export function decodeClaimSecurityAttributesInformation(ptr: unknown): CLAIM_SECURITY_ATTRIBUTES_INFORMATION { - const ret: CLAIM_SECURITY_ATTRIBUTES_INFORMATION = koffi.decode(ptr, cCLAIM_SECURITY_ATTRIBUTES_INFORMATION) - if (ret.Attribute?.pAttributeV1) { - ret.Attribute = { - pAttributeV1: koffi.decode(ret.Attribute, cCLAIM_SECURITY_ATTRIBUTE_V1, ret.AttributeCount) - } - } - else { - ret.AttributeCount = 0 - ret.Attribute = { pAttributeV1: [] } - } - return ret -} - export function getTokenInfo(hToken: HTOKEN, infoClass: INTERNAL_TOKEN_INFORMATION_CLASS, tokenInformationLength = binaryBuffer.byteLength): boolean { getTokenInfo.native ??= advapi32.func('GetTokenInformation', cBOOL, [ cHANDLE, cINT, cPVOID, cDWORD, koffi.out(cPDWORD) ]) diff --git a/source/win32/advapi32/sid.ts b/source/win32/advapi32/sid.ts index e4cc62a..423c07d 100644 --- a/source/win32/advapi32/sid.ts +++ b/source/win32/advapi32/sid.ts @@ -2,12 +2,13 @@ import koffi from 'koffi-cream' import { StringOutputBuffer, Internals, type OUT, binaryBuffer } from '../private.js' import { cBOOL, cINT, cBYTE, cDWORD, cPVOID, cPDWORD, cSTR } from '../ctypes.js' import { + cSID, cPSID, type SID, - cSID_IDENTIFIER_AUTHORITY, type SID_IDENTIFIER_AUTHORITY + cSID_IDENTIFIER_AUTHORITY, type SID_IDENTIFIER_AUTHORITY, } from '../structs.js' import { ERROR_, type SID_NAME_USE} from '../consts.js' import { LocalFree, SetLastError, cLocalAllocatedString } from '../kernel32.js' -import { advapi32, decodeSid } from './lib.js' +import { advapi32 } from './lib.js' export interface LookupAccountSidResult { name: string @@ -43,7 +44,7 @@ export function AllocateAndInitializeSid(identifierAuthority: SID_IDENTIFIER_AUT subAuthorities[4], subAuthorities[5], subAuthorities[6], subAuthorities[7], ppSID ) !== 0) { - const sid = decodeSid(ppSID[0]) + const sid = koffi.decode(ppSID[0], cSID) freeSid(ppSID[0]) return sid } @@ -83,7 +84,7 @@ export function ConvertStringSidToSid(stringSid: string): SID | null { const ppSID: OUT = [null] if (ConvertStringSidToSid.native(stringSid, ppSID) !== 0) { - const sid = decodeSid(ppSID[0]) + const sid = koffi.decode(ppSID[0], cSID) LocalFree(ppSID[0]) return sid } @@ -99,7 +100,7 @@ export function CopySid(sourceSid: SID): SID | null { CopySid.native ??= advapi32.func('CopySid', cBOOL, [ cDWORD, koffi.out(cPVOID), cPSID ]) return CopySid.native(binaryBuffer.length, binaryBuffer, sourceSid) !== 0 - ? decodeSid(binaryBuffer) + ? koffi.decode(binaryBuffer, cSID) : null } @@ -116,7 +117,7 @@ export function CreateWellKnownSid(wellKnownSidType: number, domainSid?: SID): S const pCbSid: OUT = [binaryBuffer.length] return CreateWellKnownSid.native(wellKnownSidType, domainSid, binaryBuffer, pCbSid) !== 0 - ? decodeSid(binaryBuffer) + ? koffi.decode(binaryBuffer, cSID) : null } diff --git a/source/win32/advapi32/token.ts b/source/win32/advapi32/token.ts index 7791b44..da99083 100644 --- a/source/win32/advapi32/token.ts +++ b/source/win32/advapi32/token.ts @@ -1,17 +1,21 @@ import koffi from 'koffi-cream' +import { SetLastError } from '../kernel32.js' import { binaryBuffer, Internals, type OUT } from '../private.js' import { cBOOL, cDWORD, cPVOID, cPDWORD, cHANDLE, type HANDLE, type HTOKEN } from '../ctypes.js' import { - cACL, cPSID, type SID, - cLUID_AND_ATTRIBUTES, cSID_AND_ATTRIBUTES, type CLAIM_SECURITY_ATTRIBUTES_INFORMATION, + cACL, cSID, cPSID, type SID, + cSID_AND_ATTRIBUTES_HASH, type SID_AND_ATTRIBUTES_HASH, + cCLAIM_SECURITY_ATTRIBUTE_V1, cCLAIM_SECURITY_ATTRIBUTES_INFORMATION, type CLAIM_SECURITY_ATTRIBUTES_INFORMATION, + cTOKEN_USER, type TOKEN_USER, + cTOKEN_GROUPS, type TOKEN_GROUPS, cTOKEN_ACCESS_INFORMATION, type TOKEN_ACCESS_INFORMATION, cTOKEN_APPCONTAINER_INFORMATION, type TOKEN_APPCONTAINER_INFORMATION, cTOKEN_DEFAULT_DACL, type TOKEN_DEFAULT_DACL, cTOKEN_ELEVATION, type TOKEN_ELEVATION, - cTOKEN_GROUPS_AND_PRIVILEGES, type TOKEN_GROUPS_AND_PRIVILEGES, type TOKEN_GROUPS, + cTOKEN_GROUPS_AND_PRIVILEGES, type TOKEN_GROUPS_AND_PRIVILEGES, cTOKEN_LINKED_TOKEN, type TOKEN_LINKED_TOKEN, cTOKEN_MANDATORY_LABEL, type TOKEN_MANDATORY_LABEL, cTOKEN_MANDATORY_POLICY, type TOKEN_MANDATORY_POLICY, @@ -20,17 +24,36 @@ import { cTOKEN_PRIMARY_GROUP, type TOKEN_PRIMARY_GROUP, cTOKEN_PRIVILEGES, type TOKEN_PRIVILEGES, cTOKEN_SOURCE, type TOKEN_SOURCE, - cTOKEN_STATISTICS, type TOKEN_STATISTICS, - cTOKEN_USER, type TOKEN_USER, + cTOKEN_STATISTICS, type TOKEN_STATISTICS } from '../structs.js' import { TOKEN_INFORMATION_CLASS, ERROR_, type SECURITY_IMPERSONATION_LEVEL, type TOKEN_TYPE, type TOKEN_ } from '../consts.js' -import { SetLastError } from '../kernel32.js' -import { - advapi32, - getTokenInfo, INTERNAL_TOKEN_INFORMATION_CLASS, - decodeSid, decodeSidAndAttributesHash, decodeTokenPrivileges, decodeTokenGroups, - decodeClaimSecurityAttributesInformation -} from './lib.js' +import { advapi32, getTokenInfo, INTERNAL_TOKEN_INFORMATION_CLASS } from './lib.js' + +function decodeSidAndAttributesHash(ptr: unknown): SID_AND_ATTRIBUTES_HASH { + const ret: SID_AND_ATTRIBUTES_HASH = koffi.decode(ptr, cSID_AND_ATTRIBUTES_HASH) + ret.SidAttr.forEach(sid => sid.Sid = koffi.decode(sid.Sid, cSID)) + return ret +} + +function decodeTokenGroups(ptr: unknown): TOKEN_GROUPS { + const ret: TOKEN_GROUPS = koffi.decode(ptr, cTOKEN_GROUPS) + ret.Groups.forEach(group => group.Sid = koffi.decode(group.Sid, cSID)) + return ret +} + +function decodeClaimSecurityAttributesInformation(ptr: unknown): CLAIM_SECURITY_ATTRIBUTES_INFORMATION { + const ret: CLAIM_SECURITY_ATTRIBUTES_INFORMATION = koffi.decode(ptr, cCLAIM_SECURITY_ATTRIBUTES_INFORMATION) + if (ret.Attribute?.pAttributeV1) { + ret.Attribute = { + pAttributeV1: koffi.decode(ret.Attribute, cCLAIM_SECURITY_ATTRIBUTE_V1, ret.AttributeCount) + } + } + else { + ret.AttributeCount = 0 + ret.Attribute = { pAttributeV1: [] } + } + return ret +} /** * The AdjustTokenPrivileges function enables or disables privileges in the specified access token. @@ -39,7 +62,7 @@ import { * * https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-adjusttokenprivileges */ -export function AdjustTokenPrivileges(tokenHandle: HTOKEN, disableAllPrivileges: boolean, newState?: TOKEN_PRIVILEGES | null): TOKEN_PRIVILEGES | null { +export function AdjustTokenPrivileges(tokenHandle: HTOKEN, disableAllPrivileges: boolean, newState: TOKEN_PRIVILEGES | null = null): TOKEN_PRIVILEGES | null { AdjustTokenPrivileges.native ??= advapi32.func('AdjustTokenPrivileges', cBOOL, [ cHANDLE, cBOOL, koffi.pointer(cTOKEN_PRIVILEGES), cDWORD, cPVOID, koffi.out(cPDWORD) ]) @@ -48,7 +71,7 @@ export function AdjustTokenPrivileges(tokenHandle: HTOKEN, disableAllPrivileges: return AdjustTokenPrivileges.native( tokenHandle, Number(disableAllPrivileges), newState, binaryBuffer.byteLength, binaryBuffer, pLength ) !== 0 - ? decodeTokenPrivileges(binaryBuffer) + ? koffi.decode(binaryBuffer, cTOKEN_PRIVILEGES) : null } @@ -79,13 +102,14 @@ export function GetTokenAccessInformation(tokenHandle: HTOKEN): TOKEN_ACCESS_INF if (ret.RestrictedSidHash) ret.RestrictedSidHash = decodeSidAndAttributesHash(ret.RestrictedSidHash) if (ret.Privileges) - ret.Privileges = decodeTokenPrivileges(ret.Privileges) + ret.Privileges = koffi.decode(ret.Privileges, cTOKEN_PRIVILEGES) if (ret.PackageSid) - ret.PackageSid = decodeSid(ret.PackageSid) + ret.PackageSid = koffi.decode(ret.PackageSid, cSID) if (ret.CapabilitiesHash) ret.CapabilitiesHash = decodeSidAndAttributesHash(ret.CapabilitiesHash) if (ret.TrustLevelSid) - ret.TrustLevelSid = decodeSid(ret.TrustLevelSid) + ret.TrustLevelSid = koffi.decode(ret.TrustLevelSid, cSID) + ret.SecurityAttributes = null // Reserved. Must be set to NULL. return ret } return null @@ -111,7 +135,7 @@ export function GetTokenAppContainerSidInformation(tokenHandle: HTOKEN): TOKEN_A if (getTokenInfo(tokenHandle, INTERNAL_TOKEN_INFORMATION_CLASS.TokenAppContainerSid)) { const ret: TOKEN_APPCONTAINER_INFORMATION = koffi.decode(binaryBuffer, cTOKEN_APPCONTAINER_INFORMATION) if (ret.TokenAppContainer) - ret.TokenAppContainer = decodeSid(ret.TokenAppContainer) + ret.TokenAppContainer = koffi.decode(ret.TokenAppContainer, cSID) return ret } return null @@ -197,24 +221,8 @@ export function GetTokenElevationTypeInformation(tokenHandle: HTOKEN): number | export function GetTokenGroupsAndPrivilegesInformation(tokenHandle: HTOKEN): TOKEN_GROUPS_AND_PRIVILEGES | null { if (getTokenInfo(tokenHandle, INTERNAL_TOKEN_INFORMATION_CLASS.TokenGroupsAndPrivileges)) { const ret: TOKEN_GROUPS_AND_PRIVILEGES = koffi.decode(binaryBuffer, cTOKEN_GROUPS_AND_PRIVILEGES) - - if (ret.Sids && ret.SidCount > 0) { - ret.Sids = koffi.decode(ret.Sids, cSID_AND_ATTRIBUTES, ret.SidCount) - ret.Sids.forEach(sid => sid.Sid = decodeSid(sid.Sid)) - } - else ret.Sids = [] - - if (ret.RestrictedSids && ret.RestrictedSidCount > 0) { - ret.RestrictedSids = koffi.decode(ret.RestrictedSids, cSID_AND_ATTRIBUTES, ret.RestrictedSidCount) - ret.RestrictedSids.forEach(sid => sid.Sid = decodeSid(sid.Sid)) - } - else ret.RestrictedSids = [] - - if (ret.Privileges && ret.PrivilegeCount > 0) { - ret.Privileges = koffi.decode(ret.Privileges, cLUID_AND_ATTRIBUTES, ret.PrivilegeCount) - } - else ret.Privileges = [] - + ret.Sids.forEach(sid => sid.Sid = koffi.decode(sid.Sid, cSID)) + ret.RestrictedSids.forEach(sid => sid.Sid = koffi.decode(sid.Sid, cSID)) return ret } return null @@ -261,7 +269,7 @@ export function GetTokenImpersonationLevelInformation(tokenHandle: HTOKEN): SECU export function GetTokenIntegrityLevelInformation(tokenHandle: HTOKEN): TOKEN_MANDATORY_LABEL | null { if (getTokenInfo(tokenHandle, INTERNAL_TOKEN_INFORMATION_CLASS.TokenIntegrityLevel)) { const ret: TOKEN_MANDATORY_LABEL = koffi.decode(binaryBuffer, cTOKEN_MANDATORY_LABEL) - ret.Label.Sid = decodeSid(ret.Label.Sid) + ret.Label.Sid = koffi.decode(ret.Label.Sid, cSID) return ret } return null @@ -330,7 +338,7 @@ export function GetTokenOriginInformation(tokenHandle: HTOKEN): TOKEN_ORIGIN | n export function GetTokenOwnerInformation(tokenHandle: HTOKEN): TOKEN_OWNER | null { if (getTokenInfo(tokenHandle, INTERNAL_TOKEN_INFORMATION_CLASS.TokenOwner)) { const ret: TOKEN_OWNER = koffi.decode(binaryBuffer, cTOKEN_OWNER) - ret.Owner = decodeSid(ret.Owner) + ret.Owner = koffi.decode(ret.Owner, cSID) return ret } return null @@ -344,7 +352,7 @@ export function GetTokenOwnerInformation(tokenHandle: HTOKEN): TOKEN_OWNER | nul export function GetTokenPrimaryGroupInformation(tokenHandle: HTOKEN): TOKEN_PRIMARY_GROUP | null { if (getTokenInfo(tokenHandle, INTERNAL_TOKEN_INFORMATION_CLASS.TokenPrimaryGroup)) { const ret: TOKEN_PRIMARY_GROUP = koffi.decode(binaryBuffer, cTOKEN_PRIMARY_GROUP) - ret.PrimaryGroup = decodeSid(ret.PrimaryGroup) + ret.PrimaryGroup = koffi.decode(ret.PrimaryGroup, cSID) return ret } return null @@ -358,7 +366,7 @@ export function GetTokenPrimaryGroupInformation(tokenHandle: HTOKEN): TOKEN_PRIM export function GetTokenPrivilegesInformation(tokenHandle: HTOKEN): TOKEN_PRIVILEGES | null { if (getTokenInfo(tokenHandle, INTERNAL_TOKEN_INFORMATION_CLASS.TokenPrivileges)) { const ret: TOKEN_PRIVILEGES = koffi.decode(binaryBuffer, cTOKEN_PRIVILEGES) - ret.Privileges = koffi.decode(binaryBuffer, koffi.offsetof(cTOKEN_PRIVILEGES, 'Privileges'), cLUID_AND_ATTRIBUTES, ret.PrivilegeCount) + // ret.Privileges = koffi.decode(binaryBuffer, koffi.offsetof(cTOKEN_PRIVILEGES, 'Privileges'), cLUID_AND_ATTRIBUTES, ret.PrivilegeCount) return ret } return null @@ -471,7 +479,7 @@ export function GetTokenUserClaimAttributesInformation(tokenHandle: HTOKEN): CLA export function GetTokenUserInformation(tokenHandle: HTOKEN): TOKEN_USER | null { if (getTokenInfo(tokenHandle, INTERNAL_TOKEN_INFORMATION_CLASS.TokenUser)) { const ret: TOKEN_USER = koffi.decode(binaryBuffer, cTOKEN_USER) - ret.User.Sid = decodeSid(ret.User.Sid) + ret.User.Sid = koffi.decode(ret.User.Sid, cSID) return ret } return null diff --git a/source/win32/private.ts b/source/win32/private.ts index 612a236..8b27f46 100644 --- a/source/win32/private.ts +++ b/source/win32/private.ts @@ -19,6 +19,9 @@ export class StringOutputBuffer { /** Various Win32 constants. */ export const enum Internals { + ANYSIZE_ARRAY = 1, + DWORD_LENGTH = 4, // == koffi.sizeof(cDWORD) + UNLEN = 256, GNLEN = UNLEN, PWLEN = 256, @@ -32,8 +35,10 @@ export const enum Internals { SID_RECOMMENDED_SUB_AUTHORITIES = 1, SID_REVISION = 1, TOKEN_SOURCE_LENGTH = 8, + TOKEN_GROUPS_MAX_GROUPS = 32, // No idea if this is enough, but Koffi needs an upper limit + TOKEN_PRIVILEGES_MAX_PRIVILEGES = 32, // No idea if this is enough, but Koffi needs an upper limit + TOKEN_PRIVILEGES_SET_MAX_PRIVILEGES = 32, // No idea if this is enough, but Koffi needs an upper limit - ANYSIZE_ARRAY = 1, NOERROR = 0, ERROR_SUCCESS = 0, // LSTATUS STATUS_SUCCESS = 0, // NTSTATUS @@ -42,8 +47,6 @@ export const enum Internals { MAX_NAME = 256, INVALID_HANDLE_VALUE = -1, INFINITE = 0xffffffff, // Infinite timeout - - DWORD_LENGTH = 4, } /** koffi.out() and koffi.inout() expect a table with a single entry. */ diff --git a/source/win32/structs.ts b/source/win32/structs.ts index 6121a34..66f91a7 100644 --- a/source/win32/structs.ts +++ b/source/win32/structs.ts @@ -1,7 +1,7 @@ import koffi from 'koffi-cream' import { Internals } from './private.js' import { - cBOOL, cINT, cUINT, cCHAR, cBYTE, cWCHAR, cSHORT, cUSHORT, cWORD, + cBOOL, cINT, cUINT, cCHAR, cBYTE, cSHORT, cUSHORT, cWORD, cLONG, cULONG, cDWORD, cLONGLONG, cULONG_PTR, cLONG64, cULONG64, cDWORD64, cPVOID, cSTR, cSIZE_T, cHANDLE, type HANDLE, type HINSTANCE, type HICON, type HCURSOR, type HBRUSH, type HDESK, type HWND, type HTOKEN, type HKEY, type HMONITOR, cWPARAM, type WPARAM, cLPARAM, type LPARAM, @@ -388,7 +388,7 @@ export const cSID = koffi.struct({ Revision: cBYTE, SubAuthorityCount: cBYTE, IdentifierAuthority: cSID_IDENTIFIER_AUTHORITY, - SubAuthority: koffi.array(cDWORD, Internals.SID_MAX_SUB_AUTHORITIES, 'Array') // DWORD SubAuthority[] + SubAuthority: koffi.array(cDWORD, 'SubAuthorityCount', Internals.SID_MAX_SUB_AUTHORITIES, 'Array') }), cPSID = koffi.pointer(cSID) export const SID_REVISION = Internals.SID_REVISION @@ -423,7 +423,7 @@ export interface SID_AND_ATTRIBUTES_HASH { /** @internal */ export const cSID_AND_ATTRIBUTES_HASH = koffi.struct({ SidCount: cDWORD, - SidAttr: koffi.pointer(cSID_AND_ATTRIBUTES, Internals.ANYSIZE_ARRAY), + SidAttr: koffi.pointer(null, cSID_AND_ATTRIBUTES, 'SidCount'), Hash: koffi.array(cULONG_PTR, Internals.SID_HASH_SIZE) }) @@ -786,7 +786,7 @@ export interface TOKEN_GROUPS { /** @internal */ export const cTOKEN_GROUPS = koffi.struct({ GroupCount: cDWORD, - Groups: koffi.array(cSID_AND_ATTRIBUTES, Internals.ANYSIZE_ARRAY) + Groups: koffi.array(cSID_AND_ATTRIBUTES, 'GroupCount', Internals.TOKEN_GROUPS_MAX_GROUPS) }) /** @@ -811,13 +811,13 @@ export interface TOKEN_GROUPS_AND_PRIVILEGES { export const cTOKEN_GROUPS_AND_PRIVILEGES = koffi.struct({ SidCount: cDWORD, SidLength: cDWORD, - Sids: koffi.pointer(cSID_AND_ATTRIBUTES, Internals.ANYSIZE_ARRAY), + Sids: koffi.pointer(null, cSID_AND_ATTRIBUTES, 'SidCount'), RestrictedSidCount: cDWORD, RestrictedSidLength: cDWORD, - RestrictedSids: koffi.pointer(cSID_AND_ATTRIBUTES, Internals.ANYSIZE_ARRAY), + RestrictedSids: koffi.pointer(null, cSID_AND_ATTRIBUTES, 'RestrictedSidCount'), PrivilegeCount: cDWORD, PrivilegeLength: cDWORD, - Privileges: koffi.pointer(cLUID_AND_ATTRIBUTES, Internals.ANYSIZE_ARRAY), + Privileges: koffi.pointer(null, cLUID_AND_ATTRIBUTES, 'PrivilegeCount'), AuthenticationId: cLUID, }) @@ -918,7 +918,7 @@ export interface TOKEN_PRIVILEGES { /** @internal */ export const cTOKEN_PRIVILEGES = koffi.struct({ PrivilegeCount: cDWORD, - Privileges: koffi.array(cLUID_AND_ATTRIBUTES, Internals.ANYSIZE_ARRAY) + Privileges: koffi.array(cLUID_AND_ATTRIBUTES, 'PrivilegeCount', Internals.TOKEN_PRIVILEGES_MAX_PRIVILEGES) }) /** @@ -1038,7 +1038,7 @@ export interface PRIVILEGE_SET { export const cPRIVILEGE_SET = koffi.struct({ PrivilegeCount: cDWORD, Control: cDWORD, - Privilege: koffi.array(cLUID_AND_ATTRIBUTES, Internals.ANYSIZE_ARRAY) + Privilege: koffi.array(cLUID_AND_ATTRIBUTES, 'PrivilegeCount', Internals.TOKEN_PRIVILEGES_SET_MAX_PRIVILEGES) }) /**