microsoft / Windows.UI.Composition-Win32-Samples

Windows.UI.Composition Win32 Samples
MIT License
459 stars 186 forks source link

Cannot use IGraphicsCaptureItemInterop::CreateForWindow with electron apps #111

Closed YueLu0116 closed 2 years ago

YueLu0116 commented 2 years ago

My Windows screen-capture sdk is built on winrt(c++) and work with electron through c++ addons. However, every time I call CreateForMonitor, it will throw an access-deined exception. How can I solve this issue?

Windows version: Windows 10 20H2 (19042.1706) What I have tried:

  1. run the electron application as Administrator
  2. start the electron app with command line arguements: --no-sandbox
  3. I check the result of GetSidSubAuthority: SECURITY_MANDATORY_HIGH_RID

Some similar but unsolved issues:

  1. https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/issues/49
  2. https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/issues/55
robmikh commented 2 years ago

IGraphicsCaptureItemInterop is not available to LowIL callers, which would include the JavaScript process in Chromium. You'll need to either construct the item from at least a MediumIL process and marshal it to the LowIL process or use the newer TryCreateFromWindowId method added in Windows 11.

YueLu0116 commented 2 years ago

IGraphicsCaptureItemInterop is not available to LowIL callers, which would include the JavaScript process in Chromium. You'll need to either construct the item from at least a MediumIL process and marshal it to the LowIL process or use the newer TryCreateFromWindowId method added in Windows 11.

I call GetSidSubAuthority before calling CreateForMonitor and I always get SECURITY_MANDATORY_HIGH_RID. Does it mean the process is HighIL?

robmikh commented 2 years ago

How are you calling GetSidSubAuthority? What does it say when you query for TokenIsAppContainer from the process token? Unfortunately, I'm not very familiar with Electron, so I'm not sure how your steps are affecting the environment when we go to inspect the process token on the system side.

YueLu0116 commented 2 years ago

@robmikh Today I query TokenIsAppContainer following your advice. After this query, I call CreateForMonitor and everything works fine. Don't know what happened...

void IsAppContainer() {
    HANDLE hToken = nullptr;
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
        DWORD dwSize = 0;
        BOOL fIsAppContainerProcess;
        if (!GetTokenInformation(hToken, TokenIsAppContainer, &fIsAppContainerProcess, sizeof(BOOL), &dwSize) ||
            dwSize != sizeof BOOL) {
            fIsAppContainerProcess = false;
        }
        if (fIsAppContainerProcess) {
            LOG("It is an app container. [fIsAppContainerProcess={}]", fIsAppContainerProcess);
        }
        else {
            LOG("It is NOT an app container. [fIsAppContainerProcess={}]", fIsAppContainerProcess);
        }
    }
    else {
        LOG("OpenProcessToken() error {}\n", (unsigned long)(GetLastError()));
    }
}

Codes for calling GetSidSubAuthority:

DWORD GetProcessIL(TOKEN_INFORMATION_CLASS tokenInfoCls)
{
    DWORD dwRet = 0; {
        HANDLE hToken = NULL;
        if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
            DWORD dwSize = 0;
            // determine information length
            if (!GetTokenInformation(hToken, tokenInfoCls, NULL, 0, &dwSize) &&
                GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                PTOKEN_MANDATORY_LABEL TokenInfo = (PTOKEN_MANDATORY_LABEL)malloc(dwSize);
                if (TokenInfo) {
                    // get an actual information
                    if (GetTokenInformation(hToken, tokenInfoCls, TokenInfo, dwSize, &dwSize)) {
                        // get the integrity level
                        dwRet = *GetSidSubAuthority(
                            TokenInfo->Label.Sid,
                            (DWORD)(*GetSidSubAuthorityCount(TokenInfo->Label.Sid) - 1)
                        );
                    }
                    else {
                        LOG("GetSidSubAuthorityCount() error {}\n", (unsigned long)GetLastError());
                    }
                    free(TokenInfo);
                }
                else {
                    LOG("Token allocation error {}\n", (unsigned long)(GetLastError()));
                }
            }
            else {
                LOG("GetTokenInformation() error {}\n", (unsigned long)(GetLastError()));
            }
            CloseHandle(hToken);
        }
        else {
            LOG("OpenProcessToken() error {}\n", (unsigned long)(GetLastError()));
        }
    }
    return dwRet;
}
w0nche0l commented 2 years ago

Hi @YueLu0116, so this worked after you called both of those functions? Is it that you stopped calling it as an admin?

Lijian1122 commented 9 months ago

Hi @YueLu0116, so this worked after you called both of those functions? Is it that you stopped calling it as an admin?

Do you resolve this problem when as admin