///////////////////////////////////////////////////////////////////// // // 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; }