{"record":{"id":"fea237d307f0e5c7","repo":"andrewmd5/Borderless-Gaming","slug":"win32exception","errorCode":null,"errorMessage":"Win32Exception","messagePattern":"Win32Exception","errorType":"exception","errorClass":"Win32Exception","httpStatus":null,"severity":"warning","filePath":"BorderlessGaming.Logic/Windows/Uac.cs","lineNumber":110,"sourceCode":"        /// in that, when UAC is turned off, elevation type always returns \n        /// TokenElevationTypeDefault even though the process is elevated (Integrity \n        /// Level == High). In other words, it is not safe to say if the process is \n        /// elevated based on elevation type. Instead, we should use TokenElevation. \n        /// </remarks>\n        public static bool IsProcessElevated()\n        {\n            bool fIsElevated = false;\n            SafeTokenHandle hToken = null;\n            int cbTokenElevation = 0;\n            IntPtr pTokenElevation = IntPtr.Zero;\n\n            try\n            {\n                // Open the access token of the current process with TOKEN_QUERY.\n                if (!NativeMethods.OpenProcessToken(Process.GetCurrentProcess().Handle,\n                    NativeMethods.TOKEN_QUERY, out hToken))\n                {\n                    throw new Win32Exception();\n                }\n\n                // Allocate a buffer for the elevation information.\n                cbTokenElevation = Marshal.SizeOf(typeof(TOKEN_ELEVATION));\n                pTokenElevation = Marshal.AllocHGlobal(cbTokenElevation);\n                if (pTokenElevation == IntPtr.Zero)\n                {\n                    throw new Win32Exception();\n                }\n\n                // Retrieve token elevation information.\n                if (!NativeMethods.GetTokenInformation(hToken,\n                    TOKEN_INFORMATION_CLASS.TokenElevation, pTokenElevation,\n                    cbTokenElevation, out cbTokenElevation))\n                {\n                    // When the process is run on operating systems prior to Windows \n                    // Vista, GetTokenInformation returns false with the error code \n                    // ERROR_INVALID_PARAMETER because TokenElevation is not supported ","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/andrewmd5/Borderless-Gaming/blob/d6a541a64a2a9baf0f4aae55434a21fd9c93b8aa/BorderlessGaming.Logic/Windows/Uac.cs#L92-L128","documentation":"IsProcessElevated throws a Win32Exception when the native OpenProcessToken call fails to open the current process's access token with TOKEN_QUERY access. Win32Exception wraps the last Win32 error code (Marshal.GetLastWin32Error). OpenProcessToken can fail for the current process only in rare conditions such as a corrupted/security-hardened environment, an invalid process handle, or security software blocking token access.","triggerScenarios":"Calling Uac.IsElevated()/Uac.IsProcessElevated() when OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_QUERY, out hToken) returns false — e.g. the process handle is invalid (racing process exit), or the security context/AV policy denies opening the own process token.","commonSituations":"Running under aggressive security/EDR software that hooks advapi32 token APIs; calling the API from an unusual host (service, sandboxed/containersized process) where the pseudo process handle is invalid; a process already terminating when the check runs.","solutions":["Check the Win32Exception.NativeErrorCode for the real failure cause and fix accordingly (e.g. ERROR_ACCESS_DENIED).","Prefer Uac.Elevated (or wrap IsElevated in try/catch) which already swallows this exception and returns false.","Retry once if the call races with process startup/shutdown, since GetCurrentProcess().Handle should always be openable.","If security software blocks token inspection, fall back to Uac.IsRunAsAdmin() (WindowsPrincipal/WindowsBuiltInRole.Administrator) as a heuristic elevation check."],"exampleFix":"// before\nreturn Uac.IsProcessElevated();\n// after\nbool elevated;\ntry { elevated = Uac.IsProcessElevated(); }\ncatch (Win32Exception ex) {\n    Trace.WriteLine($\"OpenProcessToken failed: {ex.NativeErrorCode}\");\n    elevated = Uac.IsRunAsAdmin(); // fallback heuristic\n}","handlingStrategy":"try-catch","validationCode":"// No reliable pre-check: token open for the own process normally always succeeds.\n// Guard by checking OS support first:\nif (Environment.OSVersion.Version.Major < 6) return; // path never reached\nif (!Environment.IsPrivilegedProcess.HasValue) { /* .NET: Environment just probe */ }","typeGuard":"static bool CanQueryToken()\n{\n    try\n    {\n        using var p = System.Diagnostics.Process.GetCurrentProcess();\n        return p.Handle != IntPtr.Zero;\n    }\n    catch { return false; }\n}","tryCatchPattern":"try\n{\n    bool elevated = Uac.IsElevated();\n}\ncatch (System.ComponentModel.Win32Exception ex)\n{\n    Log.Warn($\"Token query failed (code {ex.NativeErrorCode}); assuming non-elevated.\");\n    bool elevated = false;\n}","preventionTips":["Use the Uac.Elevated property instead of IsProcessElevated — it already swallows Win32Exception.","Log Win32Exception.NativeErrorCode to identify the true native failure cause.","Fall back to Uac.IsRunAsAdmin() when native token queries fail.","Do not call elevation checks during process shutdown races."],"tags":["windows","win32","pinvoke","elevation","token"],"backgroundTag":"permission-denied","analyzedSha":"d6a541a64a2a9baf0f4aae55434a21fd9c93b8aa","analyzedAt":"2026-09-15T22:40:35.721Z","contentChangedAt":"2026-09-15T22:40:35.721Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}