/**
 * Windows ABI constants for the ACL-sandbox backend.
 *
 * Every value was verified against the actual MinGW Windows headers on this
 * machine (C:\Strawberry\c\x86_64-w64-mingw32\include\) and cross-checked at
 * runtime by verify/abi-probe.cpp (same numbers; static_asserts passed).
 * Regenerate the probe with:
 *   g++ -std=c++20 -municode -O2 -o abi-probe.exe abi-probe.cpp -ladvapi32 && .\abi-probe.exe
 *
 * The port intentionally excludes two pieces of the original POC
 * (github.com/huoyaoyuan/windows-acl-restrict-poc @ 10e4dfb), both verified
 * empirically on Windows 11 build 26200:
 *  - S-1-2-1 (console logon SID) in the restricting list: the POC created it
 *    via CreateWellKnownSid(WinLocalLogonSid) which fails here with
 *    ERROR_INVALID_PARAMETER (87), leaving a garbage SID that makes
 *    CreateRestrictedToken fail with ERROR_INVALID_SID (1337); using the
 *    correct WinConsoleLogonSid does produce a valid S-1-2-1, but the child
 *    then still dies with STATUS_DLL_INIT_FAILED (0xC0000142) whenever
 *    CREATE_NO_WINDOW / CREATE_NEW_CONSOLE is used.
 *  - Console isolation: under this restriction scheme a hidden console is not
 *    attainable, so children share the host console (stdio redirection is
 *    pipe-based and unaffected).
 * @module @deepseek-ai/dsh-sandbox-windows-acl/win32-abi
 */

// ---- winnt.h ---------------------------------------------------------------

// TOKEN_* access rights (winnt.h lines ~3928)
/** TOKEN_ASSIGN_PRIMARY: required to create a process with the token (CreateProcessAsUser). */
export const TOKEN_ASSIGN_PRIMARY = 0x0001
/** TOKEN_DUPLICATE: required to duplicate a token (DuplicateTokenEx). */
export const TOKEN_DUPLICATE = 0x0002
/** TOKEN_QUERY: required to read token information (GetTokenInformation). */
export const TOKEN_QUERY = 0x0008
/** TOKEN_ADJUST_DEFAULT: required to change a token's default DACL. */
export const TOKEN_ADJUST_DEFAULT = 0x0080

// SID_AND_ATTRIBUTES.Attributes flags (winnt.h lines ~3446)
/**
 * SE_GROUP_LOGON_ID: marks a token group SID as the logon SID (compared with
 * `>>> 0` — the flag's high bit makes it negative as a signed 32-bit number).
 */
export const SE_GROUP_LOGON_ID = 0xC0000000

// Generic file access (winnt.h lines ~5893-5913):
// FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES
//                      | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE
/** STANDARD_RIGHTS_WRITE (== READ_CONTROL): the standard-rights component of generic write access. */
export const STANDARD_RIGHTS_WRITE = 0x00020000 // == READ_CONTROL
/** FILE_GENERIC_WRITE: every file-write permission bit plus SYNCHRONIZE. */
export const FILE_GENERIC_WRITE = 0x00120116
/** DELETE: remove or rename the object (winnt.h line ~3009). */
export const DELETE = 0x00010000
/** FILE_DELETE_CHILD: remove or rename a directory's children (winnt.h line ~5907). */
export const FILE_DELETE_CHILD = 0x0040
// The POC granted FILE_GENERIC_WRITE minus READ_CONTROL, which displays as
// "Write" in Explorer/icacls (windows-acl-restrict-poc.cpp line 16). The
// sandbox grant adds DELETE and FILE_DELETE_CHILD so confined
// delete/rename/git operations inside the granted trees pass the token's
// access check too; Write+DELETE displays as "Modify" in icacls.
// WRITE_DAC/WRITE_OWNER stay OUT deliberately — granting them would let the
// child take ownership or rewrite DACLs and escape the allowlist (the
// security boundary).
/**
 * GRANT_MASK: FILE_GENERIC_WRITE minus READ_CONTROL plus DELETE and
 * FILE_DELETE_CHILD — the write+delete access mask the capability-SID ACEs grant
 * (displays as "Modify" in Explorer/icacls). WRITE_DAC/WRITE_OWNER are
 * deliberately excluded: they would let the confined child take ownership or
 * rewrite DACLs.
 */
export const GRANT_MASK = (FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD) & ~STANDARD_RIGHTS_WRITE // 0x00110156

/**
 * FILE_ALL_ACCESS (winnt.h line ~2789: STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE
 * | 0x1FF): full file-object access. The mask of the ACE merged into the
 * restricted token's DEFAULT DACL — the token holder must keep full access to
 * every NEW object it creates (pipes included), and the ACE must name a
 * restricting SID so the write pass-2 check passes at creation.
 */
export const FILE_ALL_ACCESS = 0x1F01FF

// CreateRestrictedToken flags (winnt.h lines ~4284)
/** DISABLE_MAX_PRIVILEGE: strip the token's maximum-privilege elevation so the confined child cannot escalate. */
export const DISABLE_MAX_PRIVILEGE = 0x1
/** LUA_TOKEN: produce a limited-user (filtered admin) token. */
export const LUA_TOKEN = 0x4
/** WRITE_RESTRICTED: intersect write access with the restricting SIDs' ACL grants — the sandbox's core mechanism. */
export const WRITE_RESTRICTED = 0x8

// WELL_KNOWN_SID_TYPE (winnt.h lines ~3369-3407)
/** WinWorldSid: S-1-1-0 (Everyone) — the only well-known SID the restricted tokens use (keep-alive group; see token.ts). */
export const WinWorldSid = 1

// TOKEN_INFORMATION_CLASS (winnt.h line ~3963: TokenUser=1, TokenGroups=2)
/** TokenGroups: GetTokenInformation class returning the token's group SIDs. */
export const TokenGroups = 2
/** TokenDefaultDacl: the token's default DACL — the DACL every NEW object created without an explicit SD takes. */
export const TokenDefaultDacl = 6

// SECURITY_INFORMATION (winnt.h line ~4293)
/** DACL_SECURITY_INFORMATION: read/write only the DACL of a security descriptor. */
export const DACL_SECURITY_INFORMATION = 0x00000004

// PROCESS access rights (winnt.h lines ~4364)
/** PROCESS_QUERY_INFORMATION: read exit status and times of a process handle. */
export const PROCESS_QUERY_INFORMATION = 0x0400

// ---- accctrl.h -------------------------------------------------------------

// SE_OBJECT_TYPE (accctrl.h line ~22: SE_UNKNOWN_OBJECT_TYPE=0, SE_FILE_OBJECT=1)
/** SE_FILE_OBJECT: the trustee path names a filesystem object. */
export const SE_FILE_OBJECT = 1

// TRUSTEE_FORM / TRUSTEE_TYPE (accctrl.h lines ~38-55): both enums start at 0
/** TRUSTEE_IS_UNKNOWN: TRUSTEE_TYPE unknown (TrusteeForm carries the shape). */
export const TRUSTEE_IS_UNKNOWN = 0
/** TRUSTEE_IS_SID: TRUSTEE_FORM — Trustee.ptstrName is a SID pointer. */
export const TRUSTEE_IS_SID = 0
/** NO_MULTIPLE_TRUSTEE: Trustee.pMultipleTrustee is null. */
export const NO_MULTIPLE_TRUSTEE = 0

// ACCESS_MODE (accctrl.h line ~127: NOT_USED_ACCESS=0, GRANT_ACCESS=1, REVOKE_ACCESS=4)
/** GRANT_ACCESS: SetEntriesInAclW adds the entry as an allow ACE. */
export const GRANT_ACCESS = 1
/** REVOKE_ACCESS: SetEntriesInAclW removes the matching allow ACE. */
export const REVOKE_ACCESS = 4

// grfInheritance (accctrl.h lines ~137-142)
/**
 * SUB_CONTAINERS_AND_OBJECTS_INHERIT: the ACE applies to the directory, its
 * subdirectories, and files (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE).
 */
export const SUB_CONTAINERS_AND_OBJECTS_INHERIT = 0x3 // == OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE

// ---- winbase.h -------------------------------------------------------------

/**
 * STARTF_USESTDHANDLES: STARTUPINFOW dwFlags — the child uses the hStd*
 * handles, required because Node clears stdio inheritability at startup.
 */
export const STARTF_USESTDHANDLES = 0x00000100
/** HANDLE_FLAG_INHERIT: SetHandleInformation flag re-enabling handle inheritance for the spawned child's stdio handles. */
export const HANDLE_FLAG_INHERIT = 0x1
/** INFINITE: never-timeout wait value. */
export const INFINITE = 0xFFFFFFFF
/** MAX_PATH: legacy path length bound. */
export const MAX_PATH = 260
// winbase.h line ~410: the confined child starts suspended so the runner can
// assign it to the kill-on-close job before any of its code runs.
/** CREATE_SUSPENDED: create the child with its primary thread suspended until ResumeThread. */
export const CREATE_SUSPENDED = 0x4
// winbase.h lines ~497-499: GetStdHandle selectors.
/** STD_INPUT_HANDLE: GetStdHandle selector for the standard input. */
export const STD_INPUT_HANDLE = -10
/** STD_OUTPUT_HANDLE: GetStdHandle selector for the standard output. */
export const STD_OUTPUT_HANDLE = -11
/** STD_ERROR_HANDLE: GetStdHandle selector for the standard error. */
export const STD_ERROR_HANDLE = -12

// FormatMessageW flags (winbase.h lines ~1446-1469)
/** FORMAT_MESSAGE_FROM_SYSTEM: format the message from the system message table. */
export const FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
/** FORMAT_MESSAGE_IGNORE_INSERTS: skip insert-sequence substitution. */
export const FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200

// ---- error codes -----------------------------------------------------------

/** ERROR_SUCCESS: the operation succeeded. */
export const ERROR_SUCCESS = 0
/** ERROR_INSUFFICIENT_BUFFER: a size-probe call succeeded but needs a larger buffer. */
export const ERROR_INSUFFICIENT_BUFFER = 122
/** ERROR_BROKEN_PIPE: the pipe's other end has closed. */
export const ERROR_BROKEN_PIPE = 109
/** ERROR_NO_DATA: the pipe is being closed. */
export const ERROR_NO_DATA = 232
/** ERROR_LOCK_VIOLATION: a byte-range lock conflicts with an existing lock (winerror.h line ~78). */
export const ERROR_LOCK_VIOLATION = 33

// ---- lock files (fileapi.h / minwinbase.h / winnt.h) -----------------------

// CreateFileW dwDesiredAccess for the ACL lock files: plain read+write is
// enough to take byte-range locks.
/** GENERIC_READ: generic read access (winnt.h line ~3028). */
export const GENERIC_READ = 0x80000000
/** GENERIC_WRITE: generic write access (winnt.h line ~3029). */
export const GENERIC_WRITE = 0x40000000
// CreateFileW dwShareMode: the lock file is shared for read/write but NOT
// for delete — if a locked file could be deleted and recreated underneath the
// lock holder, two processes could hold "the same" lock on different files.
/** FILE_SHARE_READ: other opens may read (winnt.h line ~5949). */
export const FILE_SHARE_READ = 0x00000001
/** FILE_SHARE_WRITE: other opens may write (winnt.h line ~5950). */
export const FILE_SHARE_WRITE = 0x00000002
/** FILE_SHARE_DELETE: other opens may delete (winnt.h line ~5951) — deliberately NOT used for lock files. */
export const FILE_SHARE_DELETE = 0x00000004
/** OPEN_ALWAYS: create the lock file if absent, open it otherwise (fileapi.h line ~21). */
export const OPEN_ALWAYS = 4
// LockFileEx dwFlags (minwinbase.h lines ~180-181, included by winbase.h).
/** LOCKFILE_EXCLUSIVE_LOCK: request an exclusive byte-range lock. */
export const LOCKFILE_EXCLUSIVE_LOCK = 0x2
/** LOCKFILE_FAIL_IMMEDIATELY: fail with ERROR_LOCK_VIOLATION instead of waiting. */
export const LOCKFILE_FAIL_IMMEDIATELY = 0x1

// ACE_HEADER.AceType (winnt.h lines ~3449-3463)
/** ACCESS_ALLOWED_ACE_TYPE: an access-allowed ACE granting the mask to the trustee. */
export const ACCESS_ALLOWED_ACE_TYPE = 0

// SID structure (winnt.h line ~280 SID_IDENTIFIER_AUTHORITY; line ~286
// #define SID_MAX_SUB_AUTHORITIES 15).
/** SID_MAX_SUB_AUTHORITIES: the most subauthorities a SID may carry. */
export const SID_MAX_SUB_AUTHORITIES = 15

// ACE_HEADER.AceFlags (winnt.h lines ~3477-3524): inherited ACEs shown when
// reading a DACL are marked with this bit and are not part of the explicit
// DACL edits this module makes.
/** INHERITED_ACE: the ACE was inherited from the parent object, not stored explicitly. */
export const INHERITED_ACE = 0x10

// ---- job object (winnt.h lines ~4859-4866, ~5138, ~5190-5199) --------------

// JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: the child dies when the runner's last
// job handle closes — the orphan-child backstop for the runner design.
/** JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: the child dies when the runner's last job handle closes — the orphan-child backstop. */
export const JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000
// JOBOBJECTINFOCLASS: JobObjectBasicAccountingInformation=1, ..., ExtendedLimit=9.
/** JobObjectExtendedLimitInformation: JOBOBJECTINFOCLASS for the extended limit structure. */
export const JobObjectExtendedLimitInformation = 9
// sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION), verified by abi-probe.
/** sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION), verified by abi-probe. */
export const JOBOBJECT_EXTENDED_LIMIT_SIZE = 144
// LimitFlags offset inside JOBOBJECT_EXTENDED_LIMIT_INFORMATION
// (BasicLimitInformation@0 + PerProcessUserTimeLimit@0 + PerJobUserTimeLimit@8),
// verified by abi-probe.
/**
 * LimitFlags offset inside JOBOBJECT_EXTENDED_LIMIT_INFORMATION
 * (BasicLimitInformation@0 + PerProcessUserTimeLimit@0 +
 * PerJobUserTimeLimit@8), verified by abi-probe.
 */
export const JOBOBJECT_EXTENDED_LIMIT_FLAGS_OFFSET = 16

// ---- ABI layout, verified by verify/abi-probe.cpp (x64) --------------------

/** SECURITY_MAX_SID_SIZE: maximum SID byte size. */
export const SECURITY_MAX_SID_SIZE = 68
/** SID_AND_ATTRIBUTES stride: { PSID Sid @0 (8); DWORD Attributes @8 (4) } + pad. */
export const SID_AND_ATTRIBUTES_SIZE = 16
/** TOKEN_GROUPS.Groups[] starts at offset 8 (GroupCount @0 + alignment). */
export const TOKEN_GROUPS_OFFSET = 8
/** sizeof(EXPLICIT_ACCESS_W): perms@0 mode@4 inheritance@8 Trustee@16. */
export const EXPLICIT_ACCESS_W_SIZE = 48
/** Trustee offset inside EXPLICIT_ACCESS_W. */
export const TRUSTEE_W_OFFSET = 16
/** ptstrName offset inside TRUSTEE_W (=> 40 inside EXPLICIT_ACCESS_W). */
export const TRUSTEE_W_PTSTRNAME_OFFSET = 24
/** sizeof(STARTUPINFOW), verified by abi-probe. */
export const STARTUPINFOW_SIZE = 104
/** sizeof(PROCESS_INFORMATION), verified by abi-probe. */
export const PROCESS_INFORMATION_SIZE = 24
