setup_native: use more Unicode in MSI custom actions

Change-Id: Id47ea566c9cf508116216625fe00013e8326b165
Reviewed-on: https://gerrit.libreoffice.org/42839
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
diff --git a/setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx b/setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx
index 1e94223..4ea57b8 100644
--- a/setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx
+++ b/setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx
@@ -42,10 +42,10 @@
*/
typedef BOOL (__stdcall * CloseServiceHandle_t)(SC_HANDLE);
typedef BOOL (__stdcall * ControlService_t)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
typedef SC_HANDLE (__stdcall * OpenSCManager_t)(LPCSTR, LPCSTR, DWORD);
typedef SC_HANDLE (__stdcall * OpenService_t)(SC_HANDLE, LPCSTR, DWORD);
typedef SC_HANDLE (__stdcall * OpenSCManager_t)(LPCWSTR, LPCWSTR, DWORD);
typedef SC_HANDLE (__stdcall * OpenService_t)(SC_HANDLE, LPCWSTR, DWORD);
typedef BOOL (__stdcall * QueryServiceStatus_t)(SC_HANDLE, LPSERVICE_STATUS);
typedef BOOL (__stdcall * StartService_t)(SC_HANDLE, DWORD, LPCSTR*);
typedef BOOL (__stdcall * StartService_t)(SC_HANDLE, DWORD, LPCWSTR*);

static CloseServiceHandle_t CloseServiceHandle_ = nullptr;
static ControlService_t ControlService_ = nullptr;
@@ -54,7 +54,7 @@ static OpenService_t OpenService_ = nullptr;
static QueryServiceStatus_t QueryServiceStatus_ = nullptr;
static StartService_t StartService_ = nullptr;

const char * const INDEXING_SERVICE_NAME = "cisvc";
const wchar_t * const INDEXING_SERVICE_NAME = L"cisvc";

bool StopIndexingService(SC_HANDLE hService)
{
@@ -150,18 +150,16 @@ void StartIndexingService(SC_HANDLE hService)

extern "C" UINT __stdcall RestartIndexingService(MSIHANDLE)
{
    // MessageBoxW(NULL, L"Restarting Indexing Service", L"Message", MB_OK | MB_ICONINFORMATION);

    HMODULE hAdvapi32 = LoadLibrary("advapi32.dll");
    HMODULE hAdvapi32 = LoadLibraryW(L"advapi32.dll");

    if (hAdvapi32)
    {
        CloseServiceHandle_ = reinterpret_cast<CloseServiceHandle_t>(GetProcAddress(hAdvapi32, "CloseServiceHandle"));
        ControlService_ = reinterpret_cast<ControlService_t>(GetProcAddress(hAdvapi32, "ControlService"));
        OpenSCManager_ = reinterpret_cast<OpenSCManager_t>(GetProcAddress(hAdvapi32, "OpenSCManagerA"));
        OpenService_ = reinterpret_cast<OpenService_t>(GetProcAddress(hAdvapi32, "OpenServiceA"));
        OpenSCManager_ = reinterpret_cast<OpenSCManager_t>(GetProcAddress(hAdvapi32, "OpenSCManagerW"));
        OpenService_ = reinterpret_cast<OpenService_t>(GetProcAddress(hAdvapi32, "OpenServiceW"));
        QueryServiceStatus_ = reinterpret_cast<QueryServiceStatus_t>(GetProcAddress(hAdvapi32, "QueryServiceStatus"));
        StartService_ = reinterpret_cast<StartService_t>(GetProcAddress(hAdvapi32, "StartServiceA"));
        StartService_ = reinterpret_cast<StartService_t>(GetProcAddress(hAdvapi32, "StartServiceW"));
    }

    /* On systems other than Windows 2000/XP the service API
diff --git a/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx b/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx
index c6434e3..efcfb0d 100644
--- a/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx
+++ b/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx
@@ -31,40 +31,40 @@
#include <string>
#include <strsafe.h>

static const CHAR* g_Extensions[] =
static const WCHAR* g_Extensions[] =
{
    ".doc",     // Microsoft Word Text [0]
    ".dot",     // Microsoft Word Template
    ".wps",     // Kingsoft Writer Document
    ".wpt",     // Kingsoft Writer Template
    ".rtf",     // rtf text
    ".docx",    // Office Word 2007 XML document
    ".docm",    // Office Word 2007 XML macro-enabled document
    ".dotx",    // Office Word 2007 XML template
    ".dotm",    // Office Word 2007 XML macro-enabled template
    ".xlw",     // Microsoft Excel
    ".xls",     // Microsoft Excel
    ".xlt",     // Microsoft Excel Template
    ".xlsx",    // Office Excel 2007 XML workbook
    ".xlsm",    // Office Excel 2007 XML macro-enabled workbook
    ".xltx",    // Office Excel 2007 XML template
    ".xltm",    // Office Excel 2007 XML macro-enabled template
    ".xlsb",    // Office Excel 2007 binary workbook (BIFF12)
    ".iqy",     // Microsoft Excel Web Query File
    ".et",      // Kingsoft Spreadsheet
    ".ett",     // Kingsoft SpreadSheet Template
    ".ppt",     // Microsoft Powerpoint
    ".pps",     // Microsoft Powerpoint
    ".pot",     // Microsoft Powerpoint Template
    ".pptx",    // Office PowerPoint 2007 XML presentation
    ".pptm",    // Office PowerPoint 2007 macro-enabled XML presentation
    ".potx",    // Office PowerPoint 2007 XML template
    ".potm",    // Office PowerPoint 2007 macro-enabled XML template
    ".ppsx",    // Office PowerPoint 2007 XML show
    ".dps",     // Kingsoft Presentation 
    ".dpt",     // Kingsoft Presentation Template
    ".vsd",     // Visio 2000/XP/2003 document
    ".vst",     // Visio 2000/XP/2003 template
    L".doc",     // Microsoft Word Text [0]
    L".dot",     // Microsoft Word Template
    L".wps",     // Kingsoft Writer Document
    L".wpt",     // Kingsoft Writer Template
    L".rtf",     // rtf text
    L".docx",    // Office Word 2007 XML document
    L".docm",    // Office Word 2007 XML macro-enabled document
    L".dotx",    // Office Word 2007 XML template
    L".dotm",    // Office Word 2007 XML macro-enabled template
    L".xlw",     // Microsoft Excel
    L".xls",     // Microsoft Excel
    L".xlt",     // Microsoft Excel Template
    L".xlsx",    // Office Excel 2007 XML workbook
    L".xlsm",    // Office Excel 2007 XML macro-enabled workbook
    L".xltx",    // Office Excel 2007 XML template
    L".xltm",    // Office Excel 2007 XML macro-enabled template
    L".xlsb",    // Office Excel 2007 binary workbook (BIFF12)
    L".iqy",     // Microsoft Excel Web Query File
    L".et",      // Kingsoft Spreadsheet
    L".ett",     // Kingsoft SpreadSheet Template
    L".ppt",     // Microsoft Powerpoint
    L".pps",     // Microsoft Powerpoint
    L".pot",     // Microsoft Powerpoint Template
    L".pptx",    // Office PowerPoint 2007 XML presentation
    L".pptm",    // Office PowerPoint 2007 macro-enabled XML presentation
    L".potx",    // Office PowerPoint 2007 XML template
    L".potm",    // Office PowerPoint 2007 macro-enabled XML template
    L".ppsx",    // Office PowerPoint 2007 XML show
    L".dps",     // Kingsoft Presentation
    L".dpt",     // Kingsoft Presentation Template
    L".vsd",     // Visio 2000/XP/2003 document
    L".vst",     // Visio 2000/XP/2003 template
    nullptr
};

@@ -79,48 +79,48 @@ static const int VISIO_END = 32;
//    ".ppsm",    // Office PowerPoint 2007 macro-enabled XML show

#ifdef DEBUG
inline void OutputDebugStringFormatA( LPCSTR pFormat, ... )
inline void OutputDebugStringFormatW( LPCWSTR pFormat, ... )
{
    CHAR    buffer[1024];
    WCHAR    buffer[1024];
    va_list args;

    va_start( args, pFormat );
    StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
    OutputDebugStringA( buffer );
    StringCchVPrintfW( buffer, sizeof(buffer)/sizeof(*buffer), pFormat, args );
    OutputDebugStringW( buffer );
    va_end(args);
}
#else
static inline void OutputDebugStringFormatA( LPCSTR, ... )
static inline void OutputDebugStringFormatW( LPCWSTR, ... )
{
}
#endif

static BOOL CheckExtensionInRegistry( LPCSTR lpSubKey )
static BOOL CheckExtensionInRegistry( LPCWSTR lpSubKey )
{
    BOOL    bRet = false;
    HKEY    hKey = nullptr;
    LONG    lResult = RegOpenKeyExA( HKEY_CLASSES_ROOT, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );
    LONG    lResult = RegOpenKeyExW( HKEY_CLASSES_ROOT, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );

    if ( ERROR_SUCCESS == lResult )
    {
        CHAR    szBuffer[1024];
        DWORD   nSize = sizeof( szBuffer );
        WCHAR szBuffer[1024];
        DWORD nSize = sizeof( szBuffer );

        lResult = RegQueryValueExA( hKey, "", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &nSize );
        lResult = RegQueryValueExW( hKey, L"", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &nSize );
        if ( ERROR_SUCCESS == lResult && nSize > 0 )
        {
            szBuffer[nSize] = '\0';
            OutputDebugStringFormatA( "Found value [%s] for key [%s].\n", szBuffer, lpSubKey );
            szBuffer[nSize/sizeof(*szBuffer)] = L'\0';
            OutputDebugStringFormatW( L"Found value [%s] for key [%s].\n", szBuffer, lpSubKey );

            if ( strncmp( szBuffer, "WordPad.Document.1", 18 ) == 0 )
            if ( wcsncmp( szBuffer, L"WordPad.Document.1", 18 ) == 0 )
            {   // We will replace registration for WordPad (alas, on XP only) FIXME
                bRet = true;
            }
            else if ( strncmp( szBuffer, "LibreOffice.", 12 ) == 0 )
            else if ( wcsncmp( szBuffer, L"LibreOffice.", 12 ) == 0 )
            {   // We will replace registration for our own types, too
                bRet = true;
            }
            else if ( strncmp( szBuffer, "lostub.", 7 ) == 0 )
            else if ( wcsncmp( szBuffer, L"lostub.", 7 ) == 0 )
            {   // We will replace registration for lostub, too
                bRet = true;
            }
@@ -138,80 +138,80 @@ static BOOL CheckExtensionInRegistry( LPCSTR lpSubKey )
    return bRet;
}

bool GetMsiPropA( MSIHANDLE handle, LPCSTR name, /*out*/std::string& value )
bool GetMsiPropW( MSIHANDLE handle, LPCWSTR name, /*out*/std::wstring& value )
{
    DWORD sz = 0;
    LPSTR dummy = const_cast<LPSTR>("");
    if (MsiGetPropertyA(handle, name, dummy, &sz) == ERROR_MORE_DATA)
    LPWSTR dummy = const_cast<LPWSTR>(L"");
    if (MsiGetPropertyW(handle, name, dummy, &sz) == ERROR_MORE_DATA)
    {
        sz++;
        DWORD nbytes = sz * sizeof(CHAR);
        LPSTR buff = static_cast<LPSTR>(_alloca(nbytes));
        DWORD nbytes = sz * sizeof(WCHAR);
        LPWSTR buff = static_cast<LPWSTR>(_alloca(nbytes));
        ZeroMemory(buff, nbytes);
        MsiGetPropertyA(handle, name, buff, &sz);
        MsiGetPropertyW(handle, name, buff, &sz);
        value = buff;
        return true;
    }
    return false;
}

bool IsSetMsiPropA( MSIHANDLE handle, LPCSTR name )
bool IsSetMsiPropW( MSIHANDLE handle, LPCWSTR name )
{
    std::string val;
    GetMsiPropA( handle, name, val );
    return (val == "1");
    std::wstring val;
    GetMsiPropW( handle, name, val );
    return (val == L"1");
}

static void registerForExtension( MSIHANDLE handle, const int nIndex, bool bRegister )
{
    CHAR sPropName[256];
    StringCchCopyA( sPropName, 256, "REGISTER_" );
    StringCchCatA( sPropName, 256, (g_Extensions[nIndex])+1 );
    CharUpperBuffA( sPropName+9, 4 );
    WCHAR sPropName[256];
    StringCchCopyW( sPropName, 256, L"REGISTER_" );
    StringCchCatW( sPropName, 256, (g_Extensions[nIndex])+1 );
    CharUpperBuffW( sPropName+9, 4 );

    if ( bRegister ) {
        MsiSetPropertyA( handle, sPropName, "1" );
        OutputDebugStringFormatA( "Set MSI property %s.\n", sPropName );
        MsiSetPropertyW( handle, sPropName, L"1" );
        OutputDebugStringFormatW( L"Set MSI property %s.\n", sPropName );
    } else {
        MsiSetPropertyA( handle, sPropName, "0" );
        OutputDebugStringFormatA( "Unset MSI property %s.\n", sPropName );
        MsiSetPropertyW( handle, sPropName, L"0" );
        OutputDebugStringFormatW( L"Unset MSI property %s.\n", sPropName );
    }
}

static void saveOldRegistration( LPCSTR lpSubKey )
static void saveOldRegistration( LPCWSTR lpSubKey )
{
    HKEY    hKey = nullptr;
    LONG    lResult = RegOpenKeyExA( HKEY_CLASSES_ROOT, lpSubKey, 0,
    LONG    lResult = RegOpenKeyExW( HKEY_CLASSES_ROOT, lpSubKey, 0,
                                     KEY_QUERY_VALUE|KEY_SET_VALUE, &hKey );

    if ( ERROR_SUCCESS == lResult )
    {
        CHAR    szBuffer[1024];
        WCHAR   szBuffer[1024];
        DWORD   nSize = sizeof( szBuffer );

        lResult = RegQueryValueExA( hKey, "", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &nSize );
        lResult = RegQueryValueExW( hKey, L"", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &nSize );
        if ( ERROR_SUCCESS == lResult )
        {
            szBuffer[nSize] = '\0';
            szBuffer[nSize/sizeof(*szBuffer)] = L'\0';

            // No need to save associations for our own types
            if ( strncmp( szBuffer, "LibreOffice.", 12 ) != 0 )
            if ( wcsncmp( szBuffer, L"LibreOffice.", 12 ) != 0 )
            {
                // Save the old association
                RegSetValueExA( hKey, "LOBackupAssociation", 0,
                RegSetValueExW( hKey, L"LOBackupAssociation", 0,
                                REG_SZ, reinterpret_cast<LPBYTE>(szBuffer), nSize );
                // Also save what the old association means, just so we can try to verify
                // if/when restoring it that the old application still exists
                HKEY hKey2 = nullptr;
                lResult = RegOpenKeyExA( HKEY_CLASSES_ROOT, szBuffer, 0,
                lResult = RegOpenKeyExW( HKEY_CLASSES_ROOT, szBuffer, 0,
                                         KEY_QUERY_VALUE, &hKey2 );
                if ( ERROR_SUCCESS == lResult )
                {
                    nSize = sizeof( szBuffer );
                    lResult = RegQueryValueExA( hKey2, "", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &nSize );
                    lResult = RegQueryValueExW( hKey2, L"", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &nSize );
                    if ( ERROR_SUCCESS == lResult )
                    {
                        RegSetValueExA( hKey, "LOBackupAssociationDeref", 0,
                        RegSetValueExW( hKey, L"LOBackupAssociationDeref", 0,
                                        REG_SZ, reinterpret_cast<LPBYTE>(szBuffer), nSize );
                    }
                    RegCloseKey( hKey2 );
@@ -246,7 +246,7 @@ static bool checkSomeExtensionInRegistry( const int nStart, const int nEnd )
        bFound = ! CheckExtensionInRegistry( g_Extensions[nIndex] );

        if ( bFound )
            OutputDebugStringFormatA( "Found registration for [%s].\n", g_Extensions[nIndex] );
            OutputDebugStringFormatW( L"Found registration for [%s].\n", g_Extensions[nIndex] );

        ++nIndex;
    }
@@ -265,7 +265,7 @@ static void registerSomeExtensions( MSIHANDLE handle, const int nStart, const in

extern "C" UINT __stdcall LookForRegisteredExtensions( MSIHANDLE handle )
{
    OutputDebugStringFormatA( "LookForRegisteredExtensions: " );
    OutputDebugStringFormatW( L"LookForRegisteredExtensions: " );

    INSTALLSTATE current_state;
    INSTALLSTATE future_state;
@@ -274,181 +274,181 @@ extern "C" UINT __stdcall LookForRegisteredExtensions( MSIHANDLE handle )
    bool bCalcEnabled = false;
    bool bImpressEnabled = false;
    bool bDrawEnabled = false;
    bool bRegisterNone = IsSetMsiPropA( handle, "REGISTER_NO_MSO_TYPES" );
    bool bRegisterNone = IsSetMsiPropW( handle, L"REGISTER_NO_MSO_TYPES" );

    if ( ( ERROR_SUCCESS == MsiGetFeatureStateW( handle, L"gm_p_Wrt", &current_state, &future_state ) ) &&
         ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
        bWriterEnabled = true;

    OutputDebugStringFormatA( "LookForRegisteredExtensions: Install state Writer is [%d], will be [%d]", current_state, future_state );
    OutputDebugStringFormatW( L"LookForRegisteredExtensions: Install state Writer is [%d], will be [%d]", current_state, future_state );
    if ( bWriterEnabled )
        OutputDebugStringFormatA( "LookForRegisteredExtensions: Writer is enabled" );
        OutputDebugStringFormatW( L"LookForRegisteredExtensions: Writer is enabled" );
    else
        OutputDebugStringFormatA( "LookForRegisteredExtensions: Writer is NOT enabled" );
        OutputDebugStringFormatW( L"LookForRegisteredExtensions: Writer is NOT enabled" );

    if ( ( ERROR_SUCCESS == MsiGetFeatureStateW( handle, L"gm_p_Calc", &current_state, &future_state ) ) &&
         ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
        bCalcEnabled = true;

    OutputDebugStringFormatA( "LookForRegisteredExtensions: Install state Calc is [%d], will be [%d]", current_state, future_state );
    OutputDebugStringFormatW( L"LookForRegisteredExtensions: Install state Calc is [%d], will be [%d]", current_state, future_state );
    if ( bCalcEnabled )
        OutputDebugStringFormatA( "LookForRegisteredExtensions: Calc is enabled" );
        OutputDebugStringFormatW( L"LookForRegisteredExtensions: Calc is enabled" );
    else
        OutputDebugStringFormatA( "LookForRegisteredExtensions: Calc is NOT enabled" );
        OutputDebugStringFormatW( L"LookForRegisteredExtensions: Calc is NOT enabled" );

    if ( ( ERROR_SUCCESS == MsiGetFeatureStateW( handle, L"gm_p_Impress", &current_state, &future_state ) ) &&
         ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
        bImpressEnabled = true;

    OutputDebugStringFormatA( "LookForRegisteredExtensions: Install state Impress is [%d], will be [%d]", current_state, future_state );
    OutputDebugStringFormatW( L"LookForRegisteredExtensions: Install state Impress is [%d], will be [%d]", current_state, future_state );
    if ( bImpressEnabled )
        OutputDebugStringFormatA( "LookForRegisteredExtensions: Impress is enabled" );
        OutputDebugStringFormatW( L"LookForRegisteredExtensions: Impress is enabled" );
    else
        OutputDebugStringFormatA( "LookForRegisteredExtensions: Impress is NOT enabled" );
        OutputDebugStringFormatW( L"LookForRegisteredExtensions: Impress is NOT enabled" );

    if ( ( ERROR_SUCCESS == MsiGetFeatureStateW( handle, L"gm_p_Draw", &current_state, &future_state ) ) &&
         ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
        bDrawEnabled = true;

    OutputDebugStringFormatA( "LookForRegisteredExtensions: Install state Draw is [%d], will be [%d]", current_state, future_state );
    OutputDebugStringFormatW( L"LookForRegisteredExtensions: Install state Draw is [%d], will be [%d]", current_state, future_state );
    if ( bImpressEnabled )
        OutputDebugStringFormatA( "LookForRegisteredExtensions: Draw is enabled" );
        OutputDebugStringFormatW( L"LookForRegisteredExtensions: Draw is enabled" );
    else
        OutputDebugStringFormatA( "LookForRegisteredExtensions: Draw is NOT enabled" );
        OutputDebugStringFormatW( L"LookForRegisteredExtensions: Draw is NOT enabled" );

    MsiSetPropertyA( handle, "SELECT_WORD", "" );
    MsiSetPropertyA( handle, "SELECT_EXCEL", "" );
    MsiSetPropertyA( handle, "SELECT_POWERPOINT", "" );
    MsiSetPropertyA( handle, "SELECT_VISIO", "" );
    MsiSetPropertyW( handle, L"SELECT_WORD", L"" );
    MsiSetPropertyW( handle, L"SELECT_EXCEL", L"" );
    MsiSetPropertyW( handle, L"SELECT_POWERPOINT", L"" );
    MsiSetPropertyW( handle, L"SELECT_VISIO", L"" );

    if ( ! bRegisterNone )
    {
        if ( IsSetMsiPropA( handle, "REGISTER_ALL_MSO_TYPES" ) )
        if ( IsSetMsiPropW( handle, L"REGISTER_ALL_MSO_TYPES" ) )
        {
            if ( bWriterEnabled )
                MsiSetPropertyA( handle, "SELECT_WORD", "1" );
                MsiSetPropertyW( handle, L"SELECT_WORD", L"1" );
            if ( bCalcEnabled )
                MsiSetPropertyA( handle, "SELECT_EXCEL", "1" );
                MsiSetPropertyW( handle, L"SELECT_EXCEL", L"1" );
            if ( bImpressEnabled )
                MsiSetPropertyA( handle, "SELECT_POWERPOINT", "1" );
                MsiSetPropertyW( handle, L"SELECT_POWERPOINT", L"1" );
            if ( bDrawEnabled )
                MsiSetPropertyA( handle, "SELECT_VISIO", "1" );
                MsiSetPropertyW( handle, L"SELECT_VISIO", L"1" );
        }
        else
        {
            if ( bWriterEnabled && ! checkSomeExtensionInRegistry( WORD_START, EXCEL_START ) )
            {
                MsiSetPropertyA( handle, "SELECT_WORD", "1" );
                OutputDebugStringFormatA( "LookForRegisteredExtensions: Register for Microsoft Word" );
                MsiSetPropertyW( handle, L"SELECT_WORD", L"1" );
                OutputDebugStringFormatW( L"LookForRegisteredExtensions: Register for Microsoft Word" );
            }
            if ( bCalcEnabled && ! checkSomeExtensionInRegistry( EXCEL_START, POWERPOINT_START ) )
            {
                MsiSetPropertyA( handle, "SELECT_EXCEL", "1" );
                OutputDebugStringFormatA( "LookForRegisteredExtensions: Register for Microsoft Excel" );
                MsiSetPropertyW( handle, L"SELECT_EXCEL", L"1" );
                OutputDebugStringFormatW( L"LookForRegisteredExtensions: Register for Microsoft Excel" );
            }
            if ( bImpressEnabled && ! checkSomeExtensionInRegistry( POWERPOINT_START, VISIO_START ) )
            {
                MsiSetPropertyA( handle, "SELECT_POWERPOINT", "1" );
                OutputDebugStringFormatA( "LookForRegisteredExtensions: Register for Microsoft PowerPoint" );
                MsiSetPropertyW( handle, L"SELECT_POWERPOINT", L"1" );
                OutputDebugStringFormatW( L"LookForRegisteredExtensions: Register for Microsoft PowerPoint" );
            }
            if ( bImpressEnabled && ! checkSomeExtensionInRegistry( VISIO_START, VISIO_END ) )
            {
                MsiSetPropertyA( handle, "SELECT_VISIO", "1" );
                OutputDebugStringFormatA( "LookForRegisteredExtensions: Register for Microsoft Visio" );
                MsiSetPropertyW( handle, L"SELECT_VISIO", L"1" );
                OutputDebugStringFormatW( L"LookForRegisteredExtensions: Register for Microsoft Visio" );
            }
        }
    }

    MsiSetPropertyA( handle, "FILETYPEDIALOGUSED", "1" );
    MsiSetPropertyW( handle, L"FILETYPEDIALOGUSED", L"1" );

    return ERROR_SUCCESS;
}

extern "C" UINT __stdcall RegisterSomeExtensions( MSIHANDLE handle )
{
    OutputDebugStringFormatA( "RegisterSomeExtensions: " );
    OutputDebugStringFormatW( L"RegisterSomeExtensions: " );

    if ( IsSetMsiPropA( handle, "SELECT_WORD" ) )
    if ( IsSetMsiPropW( handle, L"SELECT_WORD" ) )
    {
        registerSomeExtensions( handle, WORD_START, EXCEL_START, true );
        MsiSetFeatureState( handle, L"gm_p_Wrt_MSO_Reg", INSTALLSTATE_LOCAL );
        OutputDebugStringFormatA( "RegisterSomeExtensions: Register for Microsoft Word" );
        MsiSetFeatureStateW( handle, L"gm_p_Wrt_MSO_Reg", INSTALLSTATE_LOCAL );
        OutputDebugStringFormatW( L"RegisterSomeExtensions: Register for Microsoft Word" );
    }
    else
    {
        registerSomeExtensions( handle, WORD_START, EXCEL_START, false );
        MsiSetFeatureState( handle, L"gm_p_Wrt_MSO_Reg", INSTALLSTATE_ABSENT );
        MsiSetFeatureStateW( handle, L"gm_p_Wrt_MSO_Reg", INSTALLSTATE_ABSENT );
    }

    if ( IsSetMsiPropA( handle, "SELECT_EXCEL" ) )
    if ( IsSetMsiPropW( handle, L"SELECT_EXCEL" ) )
    {
        registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, true );
        MsiSetFeatureState( handle, L"gm_p_Calc_MSO_Reg", INSTALLSTATE_LOCAL );
        OutputDebugStringFormatA( "RegisterSomeExtensions: Register for Microsoft Excel" );
        MsiSetFeatureStateW( handle, L"gm_p_Calc_MSO_Reg", INSTALLSTATE_LOCAL );
        OutputDebugStringFormatW( L"RegisterSomeExtensions: Register for Microsoft Excel" );
    }
    else
    {
        registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, false );
        MsiSetFeatureState( handle, L"gm_p_Calc_MSO_Reg", INSTALLSTATE_ABSENT );
        MsiSetFeatureStateW( handle, L"gm_p_Calc_MSO_Reg", INSTALLSTATE_ABSENT );
    }

    if ( IsSetMsiPropA( handle, "SELECT_POWERPOINT" ) )
    if ( IsSetMsiPropW( handle, L"SELECT_POWERPOINT" ) )
    {
        registerSomeExtensions( handle, POWERPOINT_START, VISIO_START, true );
        MsiSetFeatureState( handle, L"gm_p_Impress_MSO_Reg", INSTALLSTATE_LOCAL );
        OutputDebugStringFormatA( "RegisterSomeExtensions: Register for Microsoft PowerPoint" );
        MsiSetFeatureStateW( handle, L"gm_p_Impress_MSO_Reg", INSTALLSTATE_LOCAL );
        OutputDebugStringFormatW( L"RegisterSomeExtensions: Register for Microsoft PowerPoint" );
    }
    else
    {
        registerSomeExtensions( handle, POWERPOINT_START, VISIO_START, false );
        MsiSetFeatureState( handle, L"gm_p_Impress_MSO_Reg", INSTALLSTATE_ABSENT );
        MsiSetFeatureStateW( handle, L"gm_p_Impress_MSO_Reg", INSTALLSTATE_ABSENT );
    }

    if ( IsSetMsiPropA( handle, "SELECT_VISIO" ) )
    if ( IsSetMsiPropW( handle, L"SELECT_VISIO" ) )
    {
        registerSomeExtensions( handle, VISIO_START, VISIO_END, true );
        MsiSetFeatureState( handle, L"gm_p_Draw_MSO_Reg", INSTALLSTATE_LOCAL );
        OutputDebugStringFormatA( "RegisterSomeExtensions: Register for Microsoft Visio" );
        MsiSetFeatureStateW( handle, L"gm_p_Draw_MSO_Reg", INSTALLSTATE_LOCAL );
        OutputDebugStringFormatW( L"RegisterSomeExtensions: Register for Microsoft Visio" );
    }
    else
    {
        registerSomeExtensions( handle, VISIO_START, VISIO_END, false );
        MsiSetFeatureState( handle, L"gm_p_Draw_MSO_Reg", INSTALLSTATE_ABSENT );
        MsiSetFeatureStateW( handle, L"gm_p_Draw_MSO_Reg", INSTALLSTATE_ABSENT );
    }
    return ERROR_SUCCESS;
}

extern "C" UINT __stdcall FindRegisteredExtensions( MSIHANDLE handle )
{
    if ( IsSetMsiPropA( handle, "FILETYPEDIALOGUSED" ) )
    if ( IsSetMsiPropW( handle, L"FILETYPEDIALOGUSED" ) )
    {
        OutputDebugStringFormatA( "FindRegisteredExtensions: FILETYPEDIALOGUSED!" );
        OutputDebugStringFormatW( L"FindRegisteredExtensions: FILETYPEDIALOGUSED!" );
        return ERROR_SUCCESS;
    }

    OutputDebugStringFormatA( "FindRegisteredExtensions:" );
    OutputDebugStringFormatW( L"FindRegisteredExtensions:" );

    bool bRegisterAll = IsSetMsiPropA( handle, "REGISTER_ALL_MSO_TYPES" );
    bool bRegisterAll = IsSetMsiPropW( handle, L"REGISTER_ALL_MSO_TYPES" );

    if ( IsSetMsiPropA( handle, "REGISTER_NO_MSO_TYPES" ) )
    if ( IsSetMsiPropW( handle, L"REGISTER_NO_MSO_TYPES" ) )
    {
        OutputDebugStringFormatA( "FindRegisteredExtensions: Register none!" );
        OutputDebugStringFormatW( L"FindRegisteredExtensions: Register none!" );
        return ERROR_SUCCESS;
    }
    else if ( bRegisterAll )
        OutputDebugStringFormatA( "FindRegisteredExtensions: Force all on" );
        OutputDebugStringFormatW( L"FindRegisteredExtensions: Force all on" );
    else
        OutputDebugStringFormatA( "FindRegisteredExtensions: " );
        OutputDebugStringFormatW( L"FindRegisteredExtensions: " );

    // setting the msi properties SELECT_* will force registering for all corresponding
    // file types
    if ( IsSetMsiPropA( handle, "SELECT_WORD" ) )
    if ( IsSetMsiPropW( handle, L"SELECT_WORD" ) )
        registerSomeExtensions( handle, WORD_START, EXCEL_START, true );
    if ( IsSetMsiPropA( handle, "SELECT_EXCEL" ) )
    if ( IsSetMsiPropW( handle, L"SELECT_EXCEL" ) )
        registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, true );
    if ( IsSetMsiPropA( handle, "SELECT_POWERPOINT" ) )
    if ( IsSetMsiPropW( handle, L"SELECT_POWERPOINT" ) )
        registerSomeExtensions( handle, POWERPOINT_START, VISIO_START, true );
    if ( IsSetMsiPropA( handle, "SELECT_VISIO" ) )
    if ( IsSetMsiPropW( handle, L"SELECT_VISIO" ) )
        registerSomeExtensions( handle, VISIO_START, VISIO_END, true );

    registerForExtensions( handle, bRegisterAll );
@@ -456,59 +456,60 @@ extern "C" UINT __stdcall FindRegisteredExtensions( MSIHANDLE handle )
    return ERROR_SUCCESS;
}

static void restoreOldRegistration( LPCSTR lpSubKey )
static void restoreOldRegistration( LPCWSTR lpSubKey )
{
    HKEY    hKey = nullptr;
    LONG    lResult = RegOpenKeyExA( HKEY_CLASSES_ROOT, lpSubKey, 0,
    LONG    lResult = RegOpenKeyExW( HKEY_CLASSES_ROOT, lpSubKey, 0,
                                     KEY_QUERY_VALUE|KEY_SET_VALUE, &hKey );

    if ( ERROR_SUCCESS == lResult )
    {
        CHAR    szBuffer[1024];
        WCHAR   szBuffer[1024];
        DWORD   nSize = sizeof( szBuffer );

        lResult = RegQueryValueExA( hKey, "LOBackupAssociation", nullptr, nullptr,
        lResult = RegQueryValueExW( hKey, L"LOBackupAssociation", nullptr, nullptr,
                                    reinterpret_cast<LPBYTE>(szBuffer), &nSize );
        if ( ERROR_SUCCESS == lResult )
        {
            szBuffer[nSize/sizeof(*szBuffer)] = L'\0';
            HKEY hKey2 = nullptr;
            lResult = RegOpenKeyExA( HKEY_CLASSES_ROOT, szBuffer, 0,
            lResult = RegOpenKeyExW( HKEY_CLASSES_ROOT, szBuffer, 0,
                                     KEY_QUERY_VALUE, &hKey2 );
            if ( ERROR_SUCCESS == lResult )
            {
                CHAR   szBuffer2[1024];
                WCHAR  szBuffer2[1024];
                DWORD  nSize2 = sizeof( szBuffer2 );

                lResult = RegQueryValueExA( hKey2, "", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer2), &nSize2 );
                lResult = RegQueryValueExW( hKey2, L"", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer2), &nSize2 );
                if ( ERROR_SUCCESS == lResult )
                {
                    CHAR   szBuffer3[1024];
                    WCHAR  szBuffer3[1024];
                    DWORD  nSize3 = sizeof( szBuffer3 );

                    // Try to verify that the old association is OK to restore
                    lResult = RegQueryValueExA( hKey, "LOBackupAssociationDeref", nullptr, nullptr,
                    lResult = RegQueryValueExW( hKey, L"LOBackupAssociationDeref", nullptr, nullptr,
                                                reinterpret_cast<LPBYTE>(szBuffer3), &nSize3 );
                    if ( ERROR_SUCCESS == lResult )
                    {
                        if ( nSize2 == nSize3 && strcmp (szBuffer2, szBuffer3) == 0)
                        if ( nSize2 == nSize3 && wcsncmp (szBuffer2, szBuffer3, nSize2/sizeof(*szBuffer2)) == 0)
                        {
                            // Yep. So restore it
                            RegSetValueExA( hKey, "", 0, REG_SZ, reinterpret_cast<LPBYTE>(szBuffer), nSize );
                            RegSetValueExW( hKey, L"", 0, REG_SZ, reinterpret_cast<LPBYTE>(szBuffer), nSize );
                        }
                    }
                }
                RegCloseKey( hKey2 );
            }
            RegDeleteValueA( hKey, "LOBackupAssociation" );
            RegDeleteValueW( hKey, L"LOBackupAssociation" );
        }
        RegDeleteValueA( hKey, "LOBackupAssociationDeref" );
        RegDeleteValueW( hKey, L"LOBackupAssociationDeref" );
        RegCloseKey( hKey );
    }
}

extern "C" UINT __stdcall RestoreRegAllMSDoc( MSIHANDLE /*handle*/ )
{
    OutputDebugStringFormatA( "RestoreRegAllMSDoc\n" );
    OutputDebugStringFormatW( L"RestoreRegAllMSDoc\n" );

    int nIndex = 0;
    while ( g_Extensions[nIndex] != nullptr )
diff --git a/setup_native/source/win32/customactions/regactivex/regactivex.cxx b/setup_native/source/win32/customactions/regactivex/regactivex.cxx
index 00739ac..947fbfb 100644
--- a/setup_native/source/win32/customactions/regactivex/regactivex.cxx
+++ b/setup_native/source/win32/customactions/regactivex/regactivex.cxx
@@ -147,7 +147,7 @@ BOOL GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDe
    nDeinstallMode = 0;

    INSTALLSTATE current_state;
       INSTALLSTATE future_state;
    INSTALLSTATE future_state;

    if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Wrt_Bin", &current_state, &future_state ) )
    {
@@ -158,7 +158,7 @@ BOOL GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDe
        if ( future_state == INSTALLSTATE_LOCAL
          || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
            nInstallMode |= WRITER_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
        else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= WRITER_COMPONENT;
    }
    else
@@ -175,7 +175,7 @@ BOOL GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDe
        if ( future_state == INSTALLSTATE_LOCAL
          || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
            nInstallMode |= CALC_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
        else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= CALC_COMPONENT;
    }
    else
@@ -192,7 +192,7 @@ BOOL GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDe
        if ( future_state == INSTALLSTATE_LOCAL
          || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
            nInstallMode |= DRAW_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
        else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= DRAW_COMPONENT;
    }
    else
@@ -209,7 +209,7 @@ BOOL GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDe
        if ( future_state == INSTALLSTATE_LOCAL
          || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
            nInstallMode |= IMPRESS_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
        else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= IMPRESS_COMPONENT;
    }
    else
@@ -226,7 +226,7 @@ BOOL GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDe
        if ( future_state == INSTALLSTATE_LOCAL
          || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
            nInstallMode |= MATH_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
        else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= MATH_COMPONENT;
    }
    else
diff --git a/setup_native/source/win32/customactions/sellang/sorttree.cxx b/setup_native/source/win32/customactions/sellang/sorttree.cxx
index ed0c0c1..b34832e 100644
--- a/setup_native/source/win32/customactions/sellang/sorttree.cxx
+++ b/setup_native/source/win32/customactions/sellang/sorttree.cxx
@@ -12,7 +12,7 @@
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <msiquery.h>
#include <msi.h>
#include <commctrl.h>
#ifdef _MSC_VER
#pragma warning(pop)
@@ -25,32 +25,32 @@ extern "C" UINT __stdcall SortTree(MSIHANDLE)
    HWND hwndMSI = FindWindowW(L"MsiDialogCloseClass", nullptr);
    if (hwndMSI == nullptr)
    {
        OutputDebugStringA("SortTree: MsiDialogCloseClass not found\n");
        OutputDebugStringW(L"SortTree: MsiDialogCloseClass not found\n");
        return ERROR_SUCCESS;
    }
    HWND hwndTV = FindWindowExW(hwndMSI, nullptr, L"SysTreeView32", nullptr);
    if (hwndTV == nullptr)
    {
        OutputDebugStringA("SortTree: SysTreeView32 not found\n");
        OutputDebugStringW(L"SortTree: SysTreeView32 not found\n");
        return ERROR_SUCCESS;
    }
    HTREEITEM optional = TreeView_GetRoot(hwndTV);
    if (optional == nullptr)
    {
        OutputDebugStringA("SortTree: Optional Components branch not found\n");
        OutputDebugStringW(L"SortTree: Optional Components branch not found\n");
        return ERROR_SUCCESS;
    }
    HTREEITEM dicts = TreeView_GetChild(hwndTV, optional);
    if (dicts == nullptr)
    {
        OutputDebugStringA("SortTree: Dictionaries branch not found\n");
        OutputDebugStringW(L"SortTree: Dictionaries branch not found\n");
        return ERROR_SUCCESS;
    }
    TreeView_SortChildren(hwndTV, dicts, TRUE);
    HTREEITEM langs = TreeView_GetNextSibling(hwndTV, optional);
    if (langs == nullptr)
    {
        OutputDebugStringA("SortTree: Additional UI Languages branch not found\n");
        OutputDebugStringW(L"SortTree: Additional UI Languages branch not found\n");
        return ERROR_SUCCESS;
    }
    TreeView_SortChildren(hwndTV, langs, TRUE);
diff --git a/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx b/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx
index ca6b0c5..02bd693 100644
--- a/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx
+++ b/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx
@@ -43,7 +43,7 @@ extern "C" UINT __stdcall CheckInstallDirectory(MSIHANDLE handle)

    std::wstring sSetupIniPath = sInstallPath + sOfficeHostnamePath + L"\\program\\setup.ini";

    WIN32_FIND_DATA data;
    WIN32_FIND_DATAW data;
    HANDLE hdl = FindFirstFileW(sSetupIniPath.c_str(), &data);

    // std::wstring mystr = L"Searching for " + sSetupIniPath;
diff --git a/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx b/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx
index f8a28f7..729bce0b 100644
--- a/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx
+++ b/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx
@@ -18,14 +18,7 @@
 */

#include "shlxtmsi.hxx"

#include <malloc.h>
#include <assert.h>

#include <queue>
#include <stdio.h>
#include <strsafe.h>

#include <systools/win32/uwinapi.h>

#ifdef DEBUG
@@ -35,7 +28,7 @@ inline void OutputDebugStringFormatW( PCWSTR pFormat, ... )
    va_list args;

    va_start( args, pFormat );
    StringCchVPrintfW( buffer, sizeof(buffer)/sizeof(buffer[0]), pFormat, args );
    StringCchVPrintfW( buffer, SAL_N_ELEMENTS(buffer), pFormat, args );
    OutputDebugStringW( buffer );
    va_end(args);
}
diff --git a/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
index 4f2fb4e..4d78d7d 100644
--- a/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
+++ b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
@@ -18,8 +18,8 @@
 */

#include "shlxtmsi.hxx"

#include <malloc.h>
#include <algorithm>
#include <systools/win32/uwinapi.h>

extern "C" UINT __stdcall MigrateInstallPath( MSIHANDLE handle )
{
@@ -40,6 +40,7 @@ extern "C" UINT __stdcall MigrateInstallPath( MSIHANDLE handle )
    {
        if ( ERROR_SUCCESS == RegQueryValueExW( hKey, L"INSTALLLOCATION", nullptr, nullptr, reinterpret_cast<LPBYTE>(szValue), &nValueSize ) )
        {
            szValue[std::min(unsigned int(SAL_N_ELEMENTS(szValue) - 1), unsigned int(nValueSize / sizeof(*szValue)))] = 0;
            sInstDir = szValue;
            MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
            // MessageBoxW( NULL, sInstDir.c_str(), L"Found in HKEY_CURRENT_USER", MB_OK );
@@ -51,6 +52,7 @@ extern "C" UINT __stdcall MigrateInstallPath( MSIHANDLE handle )
    {
        if ( ERROR_SUCCESS == RegQueryValueExW( hKey, L"INSTALLLOCATION", nullptr, nullptr, reinterpret_cast<LPBYTE>(szValue), &nValueSize ) )
        {
            szValue[std::min(unsigned int(SAL_N_ELEMENTS(szValue) - 1), unsigned int(nValueSize / sizeof(*szValue)))] = 0;
            sInstDir = szValue;
            MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
            // MessageBoxW( NULL, sInstDir.c_str(), L"Found in HKEY_LOCAL_MACHINE", MB_OK );
diff --git a/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx b/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx
index 22309d5..ad73627 100644
--- a/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx
+++ b/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx
@@ -35,9 +35,9 @@ extern "C" UINT __stdcall InstallStartmenuFolderIcon( MSIHANDLE handle )
#ifdef _WIN32_WINNT_WINBLUE
    bool const bIsVistaOrLater = IsWindowsVistaOrGreater();
#else
    OSVERSIONINFO   osverinfo;
    osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx( &osverinfo );
    OSVERSIONINFOW osverinfo;
    osverinfo.dwOSVersionInfoSize = sizeof(osverinfo);
    GetVersionExW( &osverinfo );
    bool const bIsVistaOrLater = (osverinfo.dwMajorVersion >= 6);
#endif

diff --git a/setup_native/source/win32/customactions/shellextensions/upgrade.cxx b/setup_native/source/win32/customactions/shellextensions/upgrade.cxx
index 3a1cc76..9dd726f 100644
--- a/setup_native/source/win32/customactions/shellextensions/upgrade.cxx
+++ b/setup_native/source/win32/customactions/shellextensions/upgrade.cxx
@@ -17,53 +17,47 @@
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

// NB This file still makes use of largely ANSI MSI API calls
#undef UNICODE
#undef _UNICODE

#include "shlxtmsi.hxx"

#include <malloc.h>
#include <assert.h>

using namespace std;

namespace
{
    // The provided GUID must be without surrounding '{}'
    string GetGuidPart(const string& guid, int index)
    std::wstring GetGuidPart(const std::wstring& guid, int index)
    {
        assert((guid.length() == 36) && "No GUID or wrong format!");
        assert(((index > -1) && (index < 5)) && "Out of range!");

        if (index == 0) return string(guid.c_str(), 8);
        if (index == 1) return string(guid.c_str() + 9, 4);
        if (index == 2) return string(guid.c_str() + 14, 4);
        if (index == 3) return string(guid.c_str() + 19, 4);
        if (index == 4) return string(guid.c_str() + 24, 12);
        if (index == 0) return std::wstring(guid.c_str(), 8);
        if (index == 1) return std::wstring(guid.c_str() + 9, 4);
        if (index == 2) return std::wstring(guid.c_str() + 14, 4);
        if (index == 3) return std::wstring(guid.c_str() + 19, 4);
        if (index == 4) return std::wstring(guid.c_str() + 24, 12);

        return string();
        return std::wstring();
    }

    void Swap(char* p1, char* p2)
    void Swap(wchar_t* p1, wchar_t* p2)
    {
        char tmp = *p1;
        wchar_t tmp = *p1;
        *p1 = *p2;
        *p2 = tmp;
    }

    string Invert(const string& str)
    std::wstring Invert(const std::wstring& str)
    {
        char* buff = static_cast<char*>(_alloca(str.length()));
        strncpy(buff, str.c_str(), str.length());
        wchar_t* buff = static_cast<wchar_t*>(_alloca(str.length()*sizeof(wchar_t)));
        wcsncpy(buff, str.c_str(), str.length());

        char* front = buff;
        char* back = buff + str.length() - 1;
        wchar_t* front = buff;
        wchar_t* back = buff + str.length() - 1;

        while (front < back)
            Swap(front++, back--);

        return string(buff, str.length());
        return std::wstring(buff, str.length());
    }

    // Convert the upgrade code (which is a GUID) according
@@ -72,11 +66,11 @@ namespace
    // The first 8 bytes will be inverted, from the last
    // 8 bytes always the nibbles will be inverted for further
    // details look in the MSDN under compressed registry keys
    string ConvertGuid(const string& guid)
    std::wstring ConvertGuid(const std::wstring& guid)
    {
        string convertedGuid;
        std::wstring convertedGuid;

        string part = GetGuidPart(guid, 0);
        std::wstring part = GetGuidPart(guid, 0);
        convertedGuid = Invert(part);

        part = GetGuidPart(guid, 1);
@@ -86,53 +80,31 @@ namespace
        convertedGuid += Invert(part);

        part = GetGuidPart(guid, 3);
        convertedGuid += Invert(string(part.c_str(), 2));
        convertedGuid += Invert(string(part.c_str() + 2, 2));
        convertedGuid += Invert(std::wstring(part.c_str(), 2));
        convertedGuid += Invert(std::wstring(part.c_str() + 2, 2));

        part = GetGuidPart(guid, 4);
        int pos = 0;
        for (int i = 0; i < 6; i++)
        {
            convertedGuid += Invert(string(part.c_str() + pos, 2));
            convertedGuid += Invert(std::wstring(part.c_str() + pos, 2));
            pos += 2;
        }
        return convertedGuid;
    }

    string GetMsiPropertyA(MSIHANDLE handle, const string& sProperty)
    inline bool IsSetMsiPropertyW(MSIHANDLE handle, const std::wstring& sProperty)
    {
        string  result;
        CHAR    szDummy[1] = "";
        DWORD   nChars = 0;

        if (MsiGetPropertyA(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
        {
            DWORD nBytes = ++nChars * sizeof(CHAR);
            LPSTR buffer = static_cast<LPSTR>(_alloca(nBytes));
            ZeroMemory( buffer, nBytes );
            MsiGetPropertyA( handle, sProperty.c_str(), buffer, &nChars );
            result = buffer;
        }
        return  result;
        return (GetMsiPropertyW(handle, sProperty).length() > 0);
    }

    inline bool IsSetMsiPropertyA(MSIHANDLE handle, const string& sProperty)
    inline void SetMsiPropertyW(MSIHANDLE handle, const std::wstring& sProperty)
    {
        return (GetMsiPropertyA(handle, sProperty).length() > 0);
    }

    inline void UnsetMsiPropertyA(MSIHANDLE handle, const string& sProperty)
    {
        MsiSetPropertyA(handle, sProperty.c_str(), nullptr);
    }

    inline void SetMsiPropertyA(MSIHANDLE handle, const string& sProperty)
    {
        MsiSetPropertyA(handle, sProperty.c_str(), "1");
        MsiSetPropertyW(handle, sProperty.c_str(), L"1");
    }

    bool RegistryKeyHasUpgradeSubKey(
        HKEY hRootKey, const wstring& regKey, const string& upgradeKey)
        HKEY hRootKey, const std::wstring& regKey, const std::wstring& upgradeKey)
    {
        HKEY hKey;
        if (RegOpenKeyW(hRootKey, regKey.c_str(), &hKey) == ERROR_SUCCESS)
@@ -140,14 +112,14 @@ namespace
            DWORD nSubKeys;
            DWORD lLongestSubKey;

            if (RegQueryInfoKeyA(
            if (RegQueryInfoKeyW(
                hKey, nullptr, nullptr, nullptr, &nSubKeys, &lLongestSubKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS)
            {
                LPSTR buffer = static_cast<LPSTR>(_alloca(lLongestSubKey + 1));
                LPWSTR buffer = static_cast<LPWSTR>(_alloca((lLongestSubKey + 1)*sizeof(WCHAR)));

                for (DWORD i = 0; i < nSubKeys; i++)
                {
                    LONG ret = RegEnumKeyA(hKey, i, buffer, lLongestSubKey + 1);
                    LONG ret = RegEnumKeyW(hKey, i, buffer, lLongestSubKey + 1);
                    if ((ret == ERROR_SUCCESS) && (buffer == upgradeKey))
                        return true;
                }
@@ -159,25 +131,25 @@ namespace

extern "C" UINT __stdcall SetProductInstallMode(MSIHANDLE handle)
{
    string upgradeCode = GetMsiPropertyA(handle, "UpgradeCode");
    upgradeCode = ConvertGuid(string(upgradeCode.c_str() + 1, upgradeCode.length() - 2));
    std::wstring upgradeCode = GetMsiPropertyW(handle, L"UpgradeCode");
    upgradeCode = ConvertGuid(std::wstring(upgradeCode.c_str() + 1, upgradeCode.length() - 2));

    // MessageBoxA(NULL, upgradeCode.c_str(), "Debug", MB_OK);
    // MessageBoxW(NULL, upgradeCode.c_str(), "Debug", MB_OK);

    if (RegistryKeyHasUpgradeSubKey(
        HKEY_CURRENT_USER,
        L"Software\\Microsoft\\Installer\\UpgradeCodes",
        upgradeCode) && IsSetMsiPropertyA(handle, "ALLUSERS"))
        upgradeCode) && IsSetMsiPropertyW(handle, L"ALLUSERS"))
    {
        UnsetMsiPropertyA(handle, "ALLUSERS");
        UnsetMsiPropertyW(handle, L"ALLUSERS");
        // MessageBoxW(NULL, L"ALLUSERS removed", L"DEBUG", MB_OK);
    }
    else if (RegistryKeyHasUpgradeSubKey(
             HKEY_LOCAL_MACHINE,
             L"Software\\Classes\\Installer\\UpgradeCodes",
             upgradeCode) && !IsSetMsiPropertyA(handle, "ALLUSERS"))
             upgradeCode) && !IsSetMsiPropertyW(handle, L"ALLUSERS"))
    {
        SetMsiPropertyA(handle, "ALLUSERS");
        SetMsiPropertyW(handle, L"ALLUSERS");
        // MessageBoxW(NULL, L"ALLUSERS set", L"DEBUG", MB_OK);
    }
    return ERROR_SUCCESS;
diff --git a/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx b/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx
index dd2b867..0ec17b0 100644
--- a/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx
+++ b/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx
@@ -19,11 +19,6 @@

#include "shlxtmsi.hxx"

#include <malloc.h>
#include <assert.h>

#include <queue>
#include <stdio.h>
#include <strsafe.h>

#include <systools/win32/uwinapi.h>
@@ -34,7 +29,7 @@ static BOOL RemoveCompleteDirectoryW(const std::wstring& rPath)
    bool bDirectoryRemoved = true;

    std::wstring sPattern = rPath + L"\\" + L"*.*";
    WIN32_FIND_DATA aFindData;
    WIN32_FIND_DATAW aFindData;

    // Finding all content in rPath

@@ -106,6 +101,7 @@ extern "C" UINT __stdcall RenamePrgFolder( MSIHANDLE handle )
        }
    }

    // ? This succeeds unconditionally, even if bSuccess is false!
    return ERROR_SUCCESS;
}

diff --git a/setup_native/source/win32/customactions/tools/checkversion.cxx b/setup_native/source/win32/customactions/tools/checkversion.cxx
index 8de4680..3d73df8 100644
--- a/setup_native/source/win32/customactions/tools/checkversion.cxx
+++ b/setup_native/source/win32/customactions/tools/checkversion.cxx
@@ -38,14 +38,14 @@
BOOL GetMsiPropW( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
{
    DWORD sz = 0;
       if ( MsiGetPropertyW( hMSI, pPropName, const_cast<wchar_t *>(L""), &sz ) == ERROR_MORE_DATA )
       {
           sz++;
           DWORD nbytes = sz * sizeof( wchar_t );
           wchar_t* buff = static_cast<wchar_t*>( malloc( nbytes ) );
           ZeroMemory( buff, nbytes );
           MsiGetPropertyW( hMSI, pPropName, buff, &sz );
           *ppValue = buff;
    if ( MsiGetPropertyW( hMSI, pPropName, const_cast<wchar_t *>(L""), &sz ) == ERROR_MORE_DATA )
    {
        sz++;
        DWORD nbytes = sz * sizeof( wchar_t );
        wchar_t* buff = static_cast<wchar_t*>( malloc( nbytes ) );
        ZeroMemory( buff, nbytes );
        MsiGetPropertyW( hMSI, pPropName, buff, &sz );
        *ppValue = buff;

        return TRUE;
    }