Exemple #1
0
/////////////////////////////////////////////////////////////////////
// 
// Function:    Execute
//
// Description: 
//
/////////////////////////////////////////////////////////////////////
UINT BOINCCABase::Execute()
{
    UINT    uiReturnValue = 0;

    OnInitialize();

    if      ( TRUE == MsiGetMode( m_hMSIHandle, MSIRUNMODE_SCHEDULED ) )
    {
        uiReturnValue = OnInstall();
    }
    else if ( TRUE == MsiGetMode( m_hMSIHandle, MSIRUNMODE_COMMIT ) )
    {
        uiReturnValue = OnCommit();
    }
    else if ( TRUE == MsiGetMode( m_hMSIHandle, MSIRUNMODE_ROLLBACK ) )
    {
        uiReturnValue = OnRollback();
    }
    else
    {
        uiReturnValue = OnExecution();
    }

    OnCleanup();

    return uiReturnValue;
}
UINT WIXAPI CloseAndReopen(MSIHANDLE hInstaller) {
    std::vector<PairHwndPath> windows;
    BOOL rollback = MsiGetMode(hInstaller, MSIRUNMODE_ROLLBACK);
    GetExplorerWindows(windows, true);
    if(windows.size() == 0) return ERROR_SUCCESS;
    int length = 0;
    for(UINT i = 0; i < windows.size(); ++i) {
        HWND hwnd = GetParent(windows[i].hwnd);
        if(hwnd == 0) hwnd = windows[i].hwnd;
        SendMessage(hwnd, WM_CLOSE, 0, 0);
        int l = _tcslen(windows[i].path);
        if(l > 0 && i > 0) length += l + 1;
    }
    TCHAR* build = new TCHAR[length + 1];
    build[0] = 0;
    for(UINT i = 1; i < windows.size(); ++i) {
        UINT l = _tcslen(windows[i].path);
        _tcscat(build, windows[i].path);
        _tcscat(build, _T(";"));
    }
    HKEY key;
    REGSAM access = KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_WOW64_64KEY;
    if(RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Quizo\\QTTabBar\\"), 0, access, &key) == ERROR_SUCCESS) {
        RegSetValueEx(key, _T("TabsOnLastClosedWindow"), 0, REG_SZ, (LPBYTE)build, length + 1);
    }
    RegCloseKey(key);
    delete[] build;
    ShellExecute(NULL, NULL, windows[0].path, NULL, NULL, SW_SHOWNORMAL);
    return ERROR_SUCCESS;
}
UINT WIXAPI HideBars(MSIHANDLE hInstaller) {
    std::vector<PairHwndPath> windows;
    BOOL rollback = MsiGetMode(hInstaller, MSIRUNMODE_ROLLBACK);
    GetExplorerWindows(windows, false);
    for(UINT i = 0; i < windows.size(); ++i) {
        HWND hwnd = GetParent(windows[i].hwnd);
        if(hwnd == 0) hwnd = windows[i].hwnd;
        SendMessage(hwnd, WM_SHOWHIDEBARS, rollback ? 1 : 0, 0);
    }
    return ERROR_SUCCESS;
}
UINT
pxDiMsiInstallFromInfSection(
	__in MSIHANDLE hInstall,
	__in const XDIMSI_PROCESS_RECORD* ProcessRecord)
{
	//
	// InfSection: <InstallSection>[;<RollbackSection>]
	//

	WCHAR section[128];
	HRESULT hr = StringCchCopy(section, RTL_NUMBER_OF(section), ProcessRecord->InfSectionList);
	_ASSERT(SUCCEEDED(hr));

	LPWSTR rollbackSection = NULL;
	for (LPWSTR p = section; *p != NULL; ++p)
	{
		if (L';' == *p)
		{
			*p = L'\0';
			rollbackSection = p + 1;
			break;
		}
	}

	pxMsiTraceW(hInstall, L"InstallFromInfSection: Section=%ls, RollbackSection=%ls\n", 
		section, rollbackSection);

	LPWSTR processingSection = section;

	if (MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK))
	{
		if (NULL == rollbackSection)
		{
			return ERROR_SUCCESS;
		}
		processingSection = rollbackSection;
	}

	while (TRUE)
	{
		BOOL needsReboot = FALSE, needsRebootForService = FALSE;

		hr = xDiInstallFromInfSection(
			NULL,
			ProcessRecord->InfPath,
			processingSection,
			0,
			0,
			&needsReboot,
			&needsRebootForService);

		if (FAILED(hr))
		{
			pxMsiTraceW(hInstall, L"InstallFromInf failed, hr=0x%x\n", hr);

			if (!MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK))
			{
				UINT response = pxMsiErrorMessageBox(
					hInstall, ProcessRecord->ErrorNumber, hr);
				switch (response)
				{
				case IDRETRY:
					continue;
				case IDIGNORE:
					break;
				case 0:
				case IDABORT:
				default:
					return ERROR_INSTALL_FAILURE;
				}
			}
		}

		if (needsReboot)
		{
			pxMsiTraceW(hInstall, L"Reboot required for the file operation.\n");
			if (ProcessRecord->Flags & XDIMSI_INSTALL_INF_FLAGS_IGNORE_FILE_REBOOT)
			{
				pxMsiTraceW(hInstall, L"Dismissed reboot request for files.\n");
			}
			else
			{
				pxMsiQueueScheduleReboot(hInstall);
			}
		}

		if (needsRebootForService)
		{
			pxMsiTraceW(hInstall, L"Reboot required for the service installation.\n");
			if (ProcessRecord->Flags & XDIMSI_INSTALL_INF_FLAGS_IGNORE_SERVICE_REBOOT)
			{
				pxMsiTraceW(hInstall, L"Dismissed reboot request for the service.\n");
			}
			else
			{
				pxMsiQueueScheduleReboot(hInstall);
			}
		}

		break;
	}

	return ERROR_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////
// RemoveUserAccount
//
//     Attempts to remove a user account on the local machine according
//       to the "instructions" provided in the CustomActionData property
//
//     As a deferred custom action, you do not have access to the database.
//       The only source of information comes from a property that an immediate
//       custom action can set to provide the information you need.  This
//       property is written into the script
//
                                                           UINT __stdcall RemoveUserAccount(MSIHANDLE hInstall)
{
    // determine mode in which we are called
    BOOL bRollback = MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK); // true for rollback, else regular deferred version (for uninstall)

    BOOL fSuccess = FALSE;

    // id's for error and warning messages
    const int iRemoveError = 25003;
    const int iRemoveWarning = 25004;

    // Grab the CustomActionData property
    DWORD cchCAData = 0;

    if (ERROR_MORE_DATA == MsiGetPropertyW(hInstall, IPROPNAME_CUSTOMACTIONDATA, L"", &cchCAData))
    {
        WCHAR* wszCAData = new WCHAR[++cchCAData]; // add 1 for null-terminator which is not included in size on return
        if (wszCAData)
        {
            if (ERROR_SUCCESS == MsiGetPropertyW(hInstall, IPROPNAME_CUSTOMACTIONDATA, wszCAData, &cchCAData))
            {
                // send ActionData message (template in ActionText table)
                // send ActionData message (template in ActionText table)
                PMSIHANDLE hRec = MsiCreateRecord(1);
                if (!hRec
                        || ERROR_SUCCESS != MsiRecordSetStringW(hRec, 1, wszCAData))
                {
                    delete [] wszCAData;
                    return ERROR_INSTALL_FAILURE;
                }

                int iRet = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRec);
                if (IDCANCEL == iRet || IDABORT == iRet)
                {
                    delete [] wszCAData;
                    return ERROR_INSTALL_USEREXIT;
                }

                //
                // Call the NetUserDel function,
                //
                NET_API_STATUS nStatus = NetUserDel(NULL /*local machine*/, wszCAData /*user name*/);

                if (NERR_Success != nStatus)
                {
                    PMSIHANDLE hRecErr = MsiCreateRecord(3);
                    if ( !hRecErr
                            || ERROR_SUCCESS != MsiRecordSetStringW(hRecErr, 2, wszCAData))
                    {
                        delete [] wszCAData;
                        return ERROR_INSTALL_FAILURE;
                    }

                    // In rollback mode, NERR_UserNotFound means cancel button depressed in middle of deferred CA trying to create this account
                    if (bRollback && NERR_UserNotFound == nStatus)
                    {
                        fSuccess = TRUE;
                    }
                    else if (NERR_UserNotFound == nStatus)
                    {
                        // treat this as a warning, but success since we are attempting to delete and it is not present
                        if (ERROR_SUCCESS != MsiRecordSetInteger(hRecErr, 1, iRemoveWarning))
                        {
                            delete [] wszCAData;
                            return ERROR_INSTALL_FAILURE;
                        }

                        // just pop up an OK button
                        // OPTIONALLY, could specify multiple buttons and cancel
                        // install based on user selection by handling the return value
                        // from MsiProcessMessage, but here we are ignoring the MsiProcessMessage return
                        MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING|MB_ICONWARNING|MB_OK), hRecErr);
                        fSuccess = TRUE;
                    }
                    else
                    {
                        if (ERROR_SUCCESS == MsiRecordSetInteger(hRecErr, 1, iRemoveError)
                                && ERROR_SUCCESS == MsiRecordSetInteger(hRecErr, 3, nStatus))
                        {
                            // returning failure anyway, so ignoring MsiProcessMessage return
                            MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecErr);
                        }
                    }
                }
                else // NERR_Success
                {
                    fSuccess = TRUE;
                }
            }

            delete [] wszCAData;
        }
    }

    return fSuccess ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
}