Anyone has experience on using GetAppContainerNamedObjectPath?

  appcontainer, c++, winapi

Recently I came across a Windows API called GetAppContainerNamedObjectPath. But I have no idea on how I can use it.

I found a msdn page for this api (https://docs.microsoft.com/en-us/windows/win32/api/securityappcontainer/nf-securityappcontainer-getappcontainernamedobjectpath). But it does not have a right example and remarks, parameters are written poorly.

I am getting ERROR_INVALID_PARAMETER(87) error at the end, which tells me something’s wrong with the parameters that I put. Here’s what I’ve tried.

#define TokenIsAppContainer 29
#define TokenAppContainerSid 31
#define TokenAppContainerNumber 32

typedef struct _TOKEN_APPCONTAINER_INFORMATION {
    PSID TokenAppContainer;
} TOKEN_APPCONTAINER_INFORMATION, *PTOKEN_APPCONTAINER_INFORMATION;

void GetAppContainerProcessInfo(CString & procName)
{
    DWORD dwSize = 0;
    DWORD dwResult;
    HANDLE hToken;
    PTOKEN_APPCONTAINER_INFORMATION pAppCoInfo; 
    WCHAR wcsDebug[1024] = {0,};
    WCHAR * pwSID = NULL;

    typedef BOOL (WINAPI *_LPGETAPPCONTAINERNAMEOBJECTPATH)(HANDLE, PSID, ULONG, LPWSTR, PULONG);

    static _LPGETAPPCONTAINERNAMEOBJECTPATH lpGetAppContainerNamedObjectPath = NULL;

    if (0 == lpGetAppContainerNamedObjectPath)
    {
        HMODULE hKernel32 = LoadLibraryExW(L"kernel32.dll", NULL, 0);
        if (hKernel32)
        {
            lpGetAppContainerNamedObjectPath = reinterpret_cast<_LPGETAPPCONTAINERNAMEOBJECTPATH>(GetProcAddress(hKernel32, "GetAppContainerNamedObjectPath"));
        }
    }

    if (lpGetAppContainerNamedObjectPath)
    {
        DWORD processId = (DWORD)_ttoi((LPCTSTR)procName);
        //HANDLE hProcess = GetProcessHandleByProcessName(procName);
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);

        if(!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
        {
            dwResult = GetLastError();
            swprintf_s( wcsDebug, _countof(wcsDebug), L"OpenProcessToken Error(%u) PID(%d)n", dwResult, processId );
            AfxMessageBox(wcsDebug);
            return;
        }

        if (!GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) TokenAppContainerSid, NULL, dwSize, &dwSize))
        {
            dwResult = GetLastError();
            if( dwResult != ERROR_INSUFFICIENT_BUFFER ) 
            {
                swprintf_s( wcsDebug, _countof(wcsDebug), L"GetTokenInformation Error %un", dwResult );
                AfxMessageBox(wcsDebug);
                return;
            }
        }

        pAppCoInfo = (PTOKEN_APPCONTAINER_INFORMATION) GlobalAlloc( GPTR, dwSize );

        if (!GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) TokenAppContainerSid, pAppCoInfo, dwSize, &dwSize))
        {
            dwResult = GetLastError();
            swprintf_s( wcsDebug, _countof(wcsDebug), L"GetTokenInformation Error %un", dwResult );
            AfxMessageBox(wcsDebug);
            return;
        }

        WCHAR wcsNamedObjectPath[MAX_PATH];
        ULONG ulRetlen = 0;

        BOOL bRet = lpGetAppContainerNamedObjectPath(hToken, pAppCoInfo->TokenAppContainer, _countof(wcsNamedObjectPath), wcsNamedObjectPath, &ulRetlen );
        if (bRet)
        {
            swprintf_s( wcsDebug, _countof(wcsDebug), L"GetAppContainerNamedObjectPath Path(%s)n", wcsNamedObjectPath );
            AfxMessageBox(wcsDebug);
        }
        else
        {
            dwResult = GetLastError();
            swprintf_s( wcsDebug, _countof(wcsDebug), L"GetAppContainerNamedObjectPath Error %un", dwResult );
            AfxMessageBox(wcsDebug);
        }

        if (pwSID)
            LocalFree(pwSID);

        CloseHandle(hToken)
        CloseHandle(hProcess);
    }
}

As a side-note, I have tried using wchar_t * and dynamically allocate the memory buffer by calling GetAppContainerNamedObjectPath twice. But still had no chance. Return length does not return a meaningful value.

Source: Windows Questions C++

LEAVE A COMMENT