{"record":{"id":"0c8c98472b9dbf66","repo":"babalae/better-genshin-impact","slug":"bitblt-not-supported","errorCode":null,"errorMessage":"BitBlt not supported","messagePattern":"BitBlt not supported","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"Fischless.GameCapture/BitBlt/BitBltSession.cs","lineNumber":72,"sourceCode":"        _hWnd = hWnd;\n\n        if (w <= 0 || h <= 0) throw new Exception(\"Invalid width or height\");\n\n        // 这俩仅做标记\n        Width = w;\n        Height = h;\n\n        lock (_lockObject)\n        {\n            try\n            {\n                _hdcSrc = User32.GetDC(_hWnd);\n                if (_hdcSrc.IsInvalid) throw new Exception($\"Failed to get DC for {_hWnd}\");\n\n                var hdcRasterCaps = Gdi32.GetDeviceCaps(_hdcSrc, Gdi32.DeviceCap.RASTERCAPS);\n                if ((hdcRasterCaps | 1) == 0) // RC_BITBLT\n                    // 设备不支持 BitBlt\n                    throw new Exception(\"BitBlt not supported\");\n\n                var hdcSrcPixel = Gdi32.GetDeviceCaps(_hdcSrc, Gdi32.DeviceCap.BITSPIXEL);\n                // 颜色位数\n                if (hdcSrcPixel != 32 && hdcSrcPixel != 24)\n                    // 目前只考虑支持24/32位像素格式\n                    throw new Exception(\"BitBlt only support 24 or 32 bit pixel color\");\n\n                var hdcSrcPlanes = Gdi32.GetDeviceCaps(_hdcSrc, Gdi32.DeviceCap.PLANES);\n                // 颜色平面数\n                if (hdcSrcPlanes > 1)\n                    // 意味着色深不是标准色深\n                    throw new Exception(\"BitBlt only support 1 plane\");\n\n                var hdcClip = Gdi32.GetDeviceCaps(_hdcSrc, Gdi32.DeviceCap.CLIPCAPS);\n                if (hdcClip == 0)\n                    // 设备不支持剪切出单一窗口\n                    throw new Exception(\"Device does not support clipping\");\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/Fischless.GameCapture/BitBlt/BitBltSession.cs#L54-L90","documentation":"Intended to throw when the window device context lacks the RC_BITBLT raster capability, meaning the device cannot perform BitBlt operations. CRITICAL BUG: the guard uses bitwise OR `(hdcRasterCaps | 1) == 0` — since `x | 1` always sets bit 0, it can never equal 0, so this condition is unreachable and the exception will never actually fire. The operator should be bitwise AND (`&`).","triggerScenarios":"Only theoretically: a device context reporting no RC_BITBLT capability (some virtual/remote display drivers). In practice unreachable due to the `|` vs `&` bug.","commonSituations":"Headless or virtual display adapters, certain RDP modes, or software renderers with limited raster caps — but the bug prevents the guard from ever triggering.","solutions":["Fix the operator: change `(hdcRasterCaps | 1) == 0` to `(hdcRasterCaps & 1) == 0` so RC_BITBLT is actually tested.","If a device genuinely lacks BitBlt after the fix, fall back to GraphicsCapture or DXGI capture mode.","Validate device caps during capture-mode selection and pick a backend the hardware supports."],"exampleFix":"// before\nif ((hdcRasterCaps | 1) == 0) // RC_BITBLT\n    throw new Exception(\"BitBlt not supported\");\n\n// after\nif ((hdcRasterCaps & 1) == 0) // RC_BITBLT\n    throw new Exception(\"BitBlt not supported\");","handlingStrategy":"validation","validationCode":"// After fixing the operator to '&':\nvar caps = Gdi32.GetDeviceCaps(hdc, Gdi32.DeviceCap.RASTERCAPS);\nif ((caps & 1) == 0) // RC_BITBLT not supported\n    return CaptureMode.BitBltUnsupported; // pick another backend","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use bitwise AND (&) when testing a capability bit, never OR (|).","Add a unit test asserting the RC_BITBLT check actually fires for caps lacking bit 0.","Select the capture backend from a capability probe rather than throwing at construction time."],"tags":["capture","bitblt","gdi","bug"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}