Search code examples
c++comuacprivileges

Errors dereferencing variables passed to COM functions


I'm running code from a seperate project in my project, when I download and compile the original source, it runs smooth, but vomits errors in mine. I have tried to fix the errors by typecasting the variable to what they're expected to be by the compiler, but that results in CoCreateInstance and subsequent functions to fail, leading me to the conclusion that the issue is that I'm missing the code needed to make the calls work, so I scoured the original source and I can't find that code. Can somebody please explain what's going wrong? I've been at this for 4-5 hours.

The errors are: img

The code:

(https://pastebin.com/jffKKZAe full code just in case I missed something)

#include "stdafx.h"
#include <objbase.h>
#include <Windows.h>
#include <ntstatus.h>
#include <CommCtrl.h>
#include <shlobj.h>
#include <iostream>
#include <fci.h>
#include <fcntl.h>
#pragma comment(lib,"Ole32.lib")
#define T_CLSID_UninstallStringLauncher      L"{FCC74B77-EC3E-4DD8-A80B-008A702075A9}"
#define T_IID_IARPUninstallStringLauncher    L"{F885120E-3789-4FD9-865E-DC9B4A6412D2}"

BOOL ucmMasqueradedAPRLaunchFile(
    _In_ LPWSTR lpszFileGuid
)
{
    BOOL                         bCond = FALSE;
    HRESULT                      r = E_FAIL;
    IID                          xIID_IARPUninstallStringLauncher;
    CLSID                        xCLSID_IARPUninstallStringLauncher;
    IARPUninstallStringLauncher *USLauncher = NULL;

    do {

        if (lpszFileGuid == NULL)
            break;

        if (CLSIDFromString(T_CLSID_UninstallStringLauncher, &xCLSID_IARPUninstallStringLauncher) != NOERROR) {
            break;
        }
        if (IIDFromString(T_IID_IARPUninstallStringLauncher, &xIID_IARPUninstallStringLauncher) != S_OK) {
            break;
        }
        //Error in CoCreateInstance
        r = CoCreateInstance(&xCLSID_IARPUninstallStringLauncher, NULL,
            CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER,
            &xIID_IARPUninstallStringLauncher, &USLauncher);

        if (r != S_OK)
            break;
        //Error here too
        r = ucmMasqueradedCoGetObjectElevate(T_CLSID_UninstallStringLauncher,
            CLSCTX_LOCAL_SERVER, &xIID_IARPUninstallStringLauncher, &USLauncher);
        if (r != S_OK)
            break;

        r = USLauncher->lpVtbl->LaunchUninstallStringAndWait(USLauncher, 0, lpszFileGuid, FALSE, NULL);

    } while (bCond);

    if (USLauncher != NULL) {
        USLauncher->lpVtbl->Release(USLauncher);
    }

    return SUCCEEDED(r);
}
BOOL ucmUninstallLauncherMethod(
    _In_ LPWSTR lpszExecutable
)
{
    BOOL        bResult = FALSE, bCond = FALSE;
    HKEY        hKey = NULL;
    LRESULT     lResult;
    GUID        guid;
    WCHAR       szKeyName[MAX_PATH], szGuid[64];

    do {

        if (lpszExecutable == NULL)
            break;

        if (CoCreateGuid(&guid) != S_OK)
            break;

        _strcpy_w(szKeyName, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
        //the &guid returns an error, aswell.
        if (StringFromGUID2(&guid, szGuid, sizeof(szGuid) / sizeof(WCHAR))) {
            _strcat_w(szKeyName, szGuid);

            lResult = RegCreateKeyEx(HKEY_CURRENT_USER,
                szKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, &hKey, NULL);

            if (lResult != ERROR_SUCCESS)
                break;

            lResult = RegSetValueEx(hKey, L"UninstallString", 0, REG_SZ, (BYTE*)lpszExecutable,
                (DWORD)(_strlen_w(lpszExecutable) * sizeof(WCHAR)));

            if (lResult != ERROR_SUCCESS)
                break;

            bResult = ucmMasqueradedAPRLaunchFile(szGuid);
        }

    } while (bCond);

    if (hKey != NULL) {
        RegCloseKey(hKey);
        RegDeleteKey(HKEY_CURRENT_USER, szKeyName);
    }

    return bResult;
}
int main()
{
    bool h = ucmUninstallLauncherMethod(L"c:\\windows\\system32\\cmd.exe");
    if (h == TRUE)
        std::cout << "function returned true" << std::endl;
    else
        std::cout << "Function failed you imbicile" << std::endl;
    return 0;
}

Solution

  • Original source code is written in C where references don't exists so CoCreateInstance declared in C to accept pointer to CLSID as first parameter. While in C++ CoCreateInstance is declared to accept a reference to CLSID as first parameter but you still trying to pass a pointer. And so on. Therefore you get these errors. Recompile your code as C or remove unnecessary address takes.