static void test_MsiRecordGetInteger(void) { MSIHANDLE rec; INT val; UINT r; rec = MsiCreateRecord(1); ok(rec != 0, "Expected a valid handle\n"); r = MsiRecordSetString(rec, 1, "5"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); val = MsiRecordGetInteger(rec, 1); ok(val == 5, "Expected 5, got %d\n", val); r = MsiRecordSetString(rec, 1, "-5"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); val = MsiRecordGetInteger(rec, 1); ok(val == -5, "Expected -5, got %d\n", val); r = MsiRecordSetString(rec, 1, "5apple"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); val = MsiRecordGetInteger(rec, 1); ok(val == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", val); MsiCloseHandle(rec); }
///////////////////////////////////////////////////////////////////// // // Function: OnInitialize // // Description: // ///////////////////////////////////////////////////////////////////// UINT BOINCCABase::OnInitialize() { UINT uiReturnValue = 0; m_phActionStartRec = MsiCreateRecord(3); assert(NULL != m_phActionStartRec); MsiRecordSetString(m_phActionStartRec, 1, m_strActionName.c_str()); MsiRecordSetString(m_phActionStartRec, 2, m_strProgressTitle.c_str()); MsiRecordSetString(m_phActionStartRec, 3, _T("[1]")); uiReturnValue = MsiProcessMessage(m_hMSIHandle, INSTALLMESSAGE_ACTIONSTART, m_phActionStartRec); if ((uiReturnValue == IDCANCEL)) return ERROR_INSTALL_USEREXIT; // Give the UI a chance to refresh. Sleep(0); m_phActionDataRec = MsiCreateRecord(3); assert(NULL != m_phActionDataRec); m_phProgressRec = MsiCreateRecord(3); assert(NULL != m_phProgressRec); MsiRecordSetInteger(m_phProgressRec, 1, 1); MsiRecordSetInteger(m_phProgressRec, 2, 1); MsiRecordSetInteger(m_phProgressRec, 3, 0); uiReturnValue = MsiProcessMessage(m_hMSIHandle, INSTALLMESSAGE_PROGRESS, m_phProgressRec); if ((uiReturnValue == IDCANCEL)) return ERROR_INSTALL_USEREXIT; m_phLogInfoRec = MsiCreateRecord(3); assert(NULL != m_phLogInfoRec); MsiRecordSetString (m_phLogInfoRec, 0, _T("Custom Message : Action Name: [1] Description: [2] Error Code: [3] ")); MsiRecordSetString (m_phLogInfoRec, 1, m_strActionName.c_str()); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Starting Custom Action") ); return ERROR_SUCCESS; }
///////////////////////////////////////////////////////////////////// // // Function: LogMessage // // Description: This function writes to the MSI log file and displays // the SetupError dialog box as appropriate. // ///////////////////////////////////////////////////////////////////// UINT BOINCCABase::LogMessage( const UINT uiInstallMessageType, // message type to send to Windows Installer const UINT uiPushButtonStyle, // push button sstyle to use in message box const UINT uiIconStyle, // icon style to use in message box const UINT uiErrorNumber, // number of error in Error table const UINT uiErrorCode, // the return value from an api const tstring strMessage // message ) { UINT uiReturnValue = 0; switch(uiInstallMessageType) { // Send informational message to the log file case INSTALLMESSAGE_INFO: MsiRecordSetString (m_phLogInfoRec, 2, strMessage.c_str()); MsiRecordSetInteger(m_phLogInfoRec, 3, uiErrorCode); // returns IDOK if successful uiReturnValue = MsiProcessMessage( m_hMSIHandle, INSTALLMESSAGE(uiInstallMessageType), m_phLogInfoRec ); break; // Display a dialog and send error message to log file case INSTALLMESSAGE_ERROR: case INSTALLMESSAGE_WARNING: case INSTALLMESSAGE_USER: PMSIHANDLE phLogErrorRec = MsiCreateRecord(2); MsiRecordSetString (phLogErrorRec, 0, _T("[1]")); MsiRecordSetString (phLogErrorRec, 1, strMessage.c_str()); // Return value to indicate which button is // pushed on message box uiReturnValue = MsiProcessMessage( m_hMSIHandle, INSTALLMESSAGE(uiInstallMessageType|uiPushButtonStyle|uiIconStyle), phLogErrorRec ); break; } return uiReturnValue; }
/* Abort the installation (called as an immediate custom action) */ MSIDLLEXPORT AbortMsiImmediate( MSIHANDLE hInstall ) { DWORD rv; DWORD dwSize = 0; LPTSTR sReason = NULL; LPTSTR sFormatted = NULL; MSIHANDLE hRecord = NULL; LPTSTR cAbortReason = _T("ABORTREASON"); rv = MsiGetProperty( hInstall, cAbortReason, _T(""), &dwSize ); if(rv != ERROR_MORE_DATA) goto _cleanup; sReason = new TCHAR[ ++dwSize ]; rv = MsiGetProperty( hInstall, cAbortReason, sReason, &dwSize ); if(rv != ERROR_SUCCESS) goto _cleanup; hRecord = MsiCreateRecord(3); MsiRecordClearData(hRecord); MsiRecordSetString(hRecord, 0, sReason); dwSize = 0; rv = MsiFormatRecord(hInstall, hRecord, "", &dwSize); if(rv != ERROR_MORE_DATA) goto _cleanup; sFormatted = new TCHAR[ ++dwSize ]; rv = MsiFormatRecord(hInstall, hRecord, sFormatted, &dwSize); if(rv != ERROR_SUCCESS) goto _cleanup; MsiCloseHandle(hRecord); hRecord = MsiCreateRecord(3); MsiRecordClearData(hRecord); MsiRecordSetInteger(hRecord, 1, ERR_ABORT); MsiRecordSetString(hRecord,2, sFormatted); MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecord); _cleanup: if(sFormatted) delete[] sFormatted; if(hRecord) MsiCloseHandle( hRecord ); if(sReason) delete[] sReason; return ~ERROR_SUCCESS; }
// Adds a line to the log file of the installer. void WriteMsiLogEntry(MSIHANDLE hInstall, const char * pszMessage) { #ifdef TEST_HARNESS if (!hInstall) { MessageBox(NULL, pszMessage, "Test harness message", 0); return; } #endif PMSIHANDLE hRecord = MsiCreateRecord(1); // field 0 is the template MsiRecordSetString(hRecord, 0, "RemoveSampleDatabases: [1]"); // field 1, to be placed in [1] placeholder MsiRecordSetString(hRecord, 1, pszMessage); // send message to running installer MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hRecord); }
int MsiMessageBox(MSIHANDLE hInstall, TCHAR* szString, DWORD dwDlgFlags) { // I am not aware of anyway to programmatically set the dialog title through this code. // I think you may just have to author the Error Dialog in your .msi to use the text that you want. // chances are you will want to use [ProgramName] because the Error Dialog can get called from the MSI // it self, if it encounters an error, and it would be weird if you hard-coded the title bar to // "Desktop Shortcut?" or something like that. PMSIHANDLE newHandle = ::MsiCreateRecord(2); MsiRecordSetString(newHandle, 0, szString); return (MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_USER + dwDlgFlags), newHandle)); }
void LogString(MSIHANDLE hInstall, TCHAR* szString) { // if you are curious what the PMSIHANDLE is, look it up in the msi.chm. It is actually a good idea to use it // rather than MSIHANDLE. Basically it will free itself when it goes out of scope. In the past I helped // track a bug down to the fact that they weren't using it... PMSIHANDLE newHandle = ::MsiCreateRecord(2); TCHAR szTemp[MAX_PATH * 2]; wsprintf(szTemp, L"-- MSI_LOGGING -- %s", szString); MsiRecordSetString(newHandle, 0, szTemp); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_INFO), newHandle); // if you get one of those: cannot convert parameter 2 from 'enum tagINSTALLMESSAGE' to 'enum tagMSIMESSAGE' // errors on the line above, then chances are you: // 1) havent installed the latest MSI SDK (now apart of the Platform SDK) // or 2) havent added the \include\ and \lib\ directories to the Visual Studio path (tools | options, directory tab). }
BOOL UpdateComponentIds(MSIHANDLE hDatabase, int idx) { MSIHANDLE hView, hRecord; if (!(MsiDatabaseOpenView(hDatabase, "SELECT Component, ComponentId FROM Component", &hView)==ERROR_SUCCESS)) { return FALSE; } if (!(MsiViewExecute(hView, 0)==ERROR_SUCCESS)) return FALSE; while (MsiViewFetch(hView, &hRecord)!=ERROR_NO_MORE_ITEMS) { char szValueBuf[39]; DWORD cchValueBuf=sizeof(szValueBuf); char *token, *tokens[5]; int num=0; MsiRecordGetString(hRecord, 2, szValueBuf, &cchValueBuf); token=strtok(szValueBuf, "{-}"); while (token != NULL ) { tokens[num]=token; token=strtok(NULL, "{-}"); num++; } sprintf(szValueBuf, "{%s-%s-%s-%04X-%012X}", tokens[0], tokens[1], tokens[2], idx, idx*idx); MsiRecordSetString(hRecord, 2, szValueBuf); if (!(MsiViewModify(hView, MSIMODIFY_UPDATE, hRecord)==ERROR_SUCCESS)) return FALSE; MsiCloseHandle(hRecord); } if (!(MsiCloseHandle(hView)==ERROR_SUCCESS)) return FALSE; return TRUE; }
///////////////////////////////////////////////////////////////////// // // Function: LogProgress // // Description: // ///////////////////////////////////////////////////////////////////// UINT BOINCCABase::LogProgress( const tstring strProgress ) { UINT uiReturnValue = 0; MsiRecordSetString(m_phActionDataRec, 2, strProgress.c_str()); // returns IDOK if successful uiReturnValue = MsiProcessMessage( m_hMSIHandle, INSTALLMESSAGE_ACTIONDATA, m_phActionDataRec ); if ((uiReturnValue == IDCANCEL)) return ERROR_INSTALL_USEREXIT; // Give the UI a chance to refresh. Sleep(0); return ERROR_SUCCESS; }
void pacifica_msi_log(MSIHANDLE hInstall, const WCHAR *str, ...) { va_list args; WCHAR buffer[10240]; UINT err; MSIHANDLE record = MsiCreateRecord(1); va_start(args, str); vswprintf(buffer, str, args); va_end(args); if(record == ERROR_INVALID_HANDLE) { return; } err = MsiRecordSetString(record, 0, buffer); if(err == ERROR_SUCCESS) { MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, record); } MsiCloseHandle(record); }
/* Uninstall NSIS */ MSIDLLEXPORT UninstallNsisInstallation( MSIHANDLE hInstall ) { DWORD rv = ERROR_SUCCESS; // lookup the NSISUNINSTALL property value LPTSTR cNsisUninstall = _T("UPGRADENSIS"); HANDLE hIo = NULL; DWORD dwSize = 0; LPTSTR strPathUninst = NULL; HANDLE hJob = NULL; STARTUPINFO sInfo; PROCESS_INFORMATION pInfo; pInfo.hProcess = NULL; pInfo.hThread = NULL; rv = MsiGetProperty( hInstall, cNsisUninstall, _T(""), &dwSize ); if(rv != ERROR_MORE_DATA) goto _cleanup; strPathUninst = new TCHAR[ ++dwSize ]; rv = MsiGetProperty( hInstall, cNsisUninstall, strPathUninst, &dwSize ); if(rv != ERROR_SUCCESS) goto _cleanup; // Create a process for the uninstaller sInfo.cb = sizeof(sInfo); sInfo.lpReserved = NULL; sInfo.lpDesktop = _T(""); sInfo.lpTitle = _T("NSIS Uninstaller for Kerberos for Windows"); sInfo.dwX = 0; sInfo.dwY = 0; sInfo.dwXSize = 0; sInfo.dwYSize = 0; sInfo.dwXCountChars = 0; sInfo.dwYCountChars = 0; sInfo.dwFillAttribute = 0; sInfo.dwFlags = 0; sInfo.wShowWindow = 0; sInfo.cbReserved2 = 0; sInfo.lpReserved2 = 0; sInfo.hStdInput = 0; sInfo.hStdOutput = 0; sInfo.hStdError = 0; if(!CreateProcess( strPathUninst, _T("Uninstall /S"), NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sInfo, &pInfo)) { DWORD lastError = GetLastError(); MSIHANDLE hRecord; hRecord = MsiCreateRecord(4); MsiRecordClearData(hRecord); MsiRecordSetInteger(hRecord, 1, ERR_NSS_FAILED_CP); MsiRecordSetString(hRecord, 2, strPathUninst); MsiRecordSetInteger(hRecord, 3, lastError); MsiProcessMessage( hInstall, INSTALLMESSAGE_ERROR, hRecord ); MsiCloseHandle( hRecord ); pInfo.hProcess = NULL; pInfo.hThread = NULL; rv = 40; goto _cleanup; }; // Create a job object to contain the NSIS uninstall process tree JOBOBJECT_ASSOCIATE_COMPLETION_PORT acp; acp.CompletionKey = 0; hJob = CreateJobObject(NULL, _T("NSISUninstallObject")); if(!hJob) { rv = 41; goto _cleanup; } hIo = CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0); if(!hIo) { rv = 42; goto _cleanup; } acp.CompletionPort = hIo; SetInformationJobObject( hJob, JobObjectAssociateCompletionPortInformation, &acp, sizeof(acp)); AssignProcessToJobObject( hJob, pInfo.hProcess ); ResumeThread( pInfo.hThread ); DWORD a,b,c; for(;;) { if(!GetQueuedCompletionStatus(hIo, &a, (PULONG_PTR) &b, (LPOVERLAPPED *) &c, INFINITE)) { Sleep(1000); continue; } if(a == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO) { break; } } rv = ERROR_SUCCESS; _cleanup: if(hIo) CloseHandle(hIo); if(pInfo.hProcess) CloseHandle( pInfo.hProcess ); if(pInfo.hThread) CloseHandle( pInfo.hThread ); if(hJob) CloseHandle(hJob); if(strPathUninst) delete strPathUninst; if(rv != ERROR_SUCCESS && rv != 40) { ShowMsiError( hInstall, ERR_NSS_FAILED, rv ); } return rv; }
/* ** Name:ingres_prepare_remove_dbms_files ** ** Description: ** Set up the RemoveFile table in DBMS Merge Module for the ** directories and files that were not installed as part of ** the initial installation so that they can be removed from ** the system during an uninstall. ** ** Inputs: ** hInstall Handle to the installation. ** ** Outputs: ** None. ** Returns: ** ERROR_SUCCESS The function succeeds. ** ERROR_INSTALL_FAILURE The function fails. ** Exceptions: ** None. ** ** Side Effects: ** None. ** ** History: ** 16-Aug-2001 (penga03) ** Created. ** 17-Aug-2001 (penga03) ** Do not put the INSTALLDIR in the RemoveFile table. ** 14-may-2004 (somsa01) ** Make sure we use the 64-bit GUID, ** 8CCBF50C_6C17_4366_B8FE_FBB31A4092E0, when needed. ** 17-may-2004 (somsa01) ** Backed out prior change, as it does NOT properly fix the problem. */ UINT __stdcall ingres_prepare_remove_dbms_files(MSIHANDLE hInstall) { TCHAR tchValue[MAX_PATH+1], ii_system[MAX_PATH+1], szBuf[MAX_PATH+1]; DWORD dwSize; MSIHANDLE hDatabase, hView, hRecord; TCHAR ConfigKey[256], Host[64]; INSTALLSTATE iInstalled, iAction; TCHAR inst_id[64] = "INSTALLDIR.870341B5_2D6D_11D5_BDFC_00B0D0AD4485"; TCHAR bin_id[64] = "Bin.870341B5_2D6D_11D5_BDFC_00B0D0AD4485"; char sharedDisk[3]; MsiGetFeatureState(hInstall, "IngresDBMS", &iInstalled, &iAction); if(iAction!=INSTALLSTATE_ABSENT) return ERROR_SUCCESS; dwSize=sizeof(ii_system); if(MsiGetTargetPath(hInstall, inst_id, ii_system, &dwSize)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; if(ii_system[lstrlen(ii_system)-1] == '\\') ii_system[lstrlen(ii_system)-1] = '\0'; SetEnvironmentVariable("II_SYSTEM", ii_system); MsiSetProperty(hInstall, "INGRES_CLUSTER_RESOURCE_INUSE", "0"); if(Local_NMgtIngAt("II_DATABASE", tchValue)==ERROR_SUCCESS) { strncpy(sharedDisk, tchValue, 2); sharedDisk[2]='\0'; if (GetFileAttributes(sharedDisk) == -1) { MsiSetProperty(hInstall, "INGRES_CLUSTER_RESOURCE_INUSE", "1"); return ERROR_SUCCESS; } } hDatabase=MsiGetActiveDatabase(hInstall); if(!hDatabase) return ERROR_INSTALL_FAILURE; if(MsiDatabaseOpenView(hDatabase, "INSERT INTO `RemoveFile` (`FileKey`, `Component_`, `FileName`, `DirProperty`, `InstallMode`) VALUES (?, ?, ?, ?, ?) TEMPORARY", &hView)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; hRecord=MsiCreateRecord(5); if(!hRecord) return ERROR_INSTALL_FAILURE; if(Local_NMgtIngAt("II_DATABASE", tchValue)==ERROR_SUCCESS) { int KeyCount; char szKey[MAX_PATH+1], szKey2[MAX_PATH+1]; wsprintf(szBuf, "%s\\ingres\\data", tchValue); Count=-1; CreateDirList(szBuf); for(KeyCount=0; KeyCount<=Count; KeyCount++) { wsprintf(szKey, "RemoveDatabaseDir_%d", KeyCount); wsprintf(szKey2, "RemoveDatabaseDir_%d_Dir", KeyCount); MsiSetProperty(hInstall, szKey, DirList[KeyCount].DirName); MsiRecordSetString(hRecord, 1, szKey); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, "*.*"); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } Count++; wsprintf(szKey, "RemoveDatabaseDir_%d", Count); wsprintf(szKey2, "RemoveDatabaseDir_%d_Dir", Count); wsprintf(szBuf, "%s\\ingres", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; Count++; wsprintf(szKey, "RemoveDatabaseDir_%d", Count); wsprintf(szKey2, "RemoveDatabaseDir_%d_Dir", Count); wsprintf(szBuf, "%s", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } if(Local_NMgtIngAt("II_CHECKPOINT", tchValue)==ERROR_SUCCESS) { int KeyCount; char szKey[MAX_PATH+1], szKey2[MAX_PATH+1]; wsprintf(szBuf, "%s\\ingres\\ckp", tchValue); Count=-1; CreateDirList(szBuf); for(KeyCount=0; KeyCount<=Count; KeyCount++) { wsprintf(szKey, "RemovecCheckpointDir_%d", KeyCount); wsprintf(szKey2, "RemoveCheckpointDir_%d_Dir", KeyCount); MsiSetProperty(hInstall, szKey, DirList[KeyCount].DirName); MsiRecordSetString(hRecord, 1, szKey); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, "*.*"); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } Count++; wsprintf(szKey, "RemovecCheckpointDir_%d", Count); wsprintf(szKey2, "RemovecCheckpointDir_%d_Dir", Count); wsprintf(szBuf, "%s\\ingres", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; Count++; wsprintf(szKey, "RemovecCheckpointDir_%d", Count); wsprintf(szKey2, "RemovecCheckpointDir_%d_Dir", Count); wsprintf(szBuf, "%s", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } if(Local_NMgtIngAt("II_JOURNAL", tchValue)==ERROR_SUCCESS) { int KeyCount; char szKey[MAX_PATH+1], szKey2[MAX_PATH+1]; wsprintf(szBuf, "%s\\ingres\\jnl", tchValue); Count=-1; CreateDirList(szBuf); for(KeyCount=0; KeyCount<=Count; KeyCount++) { wsprintf(szKey, "RemoveJournalDir_%d", KeyCount); wsprintf(szKey2, "RemoveJournalDir_%d_Dir", KeyCount); MsiSetProperty(hInstall, szKey, DirList[KeyCount].DirName); MsiRecordSetString(hRecord, 1, szKey); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, "*.*"); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } Count++; wsprintf(szKey, "RemoveJournalDir_%d", Count); wsprintf(szKey2, "RemoveJournalDir_%d_Dir", Count); wsprintf(szBuf, "%s\\ingres", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; Count++; wsprintf(szKey, "RemoveJournalDir_%d", Count); wsprintf(szKey2, "RemoveJournalDir_%d_Dir", Count); wsprintf(szBuf, "%s", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } if(Local_NMgtIngAt("II_DUMP", tchValue)==ERROR_SUCCESS) { int KeyCount; char szKey[MAX_PATH+1], szKey2[MAX_PATH+1]; wsprintf(szBuf, "%s\\ingres\\dmp", tchValue); Count=-1; CreateDirList(szBuf); for(KeyCount=0; KeyCount<=Count; KeyCount++) { wsprintf(szKey, "RemoveDumpDir_%d", KeyCount); wsprintf(szKey2, "RemoveDumpDir_%d_Dir", KeyCount); MsiSetProperty(hInstall, szKey, DirList[KeyCount].DirName); MsiRecordSetString(hRecord, 1, szKey); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, "*.*"); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } Count++; wsprintf(szKey, "RemoveDumpDir_%d", Count); wsprintf(szKey2, "RemoveDumpDir_%d_Dir", Count); wsprintf(szBuf, "%s\\ingres", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; Count++; wsprintf(szKey, "RemoveDumpDir_%d", Count); wsprintf(szKey2, "RemoveDumpDir_%d_Dir", Count); wsprintf(szBuf, "%s", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } if(Local_NMgtIngAt("II_WORK", tchValue)==ERROR_SUCCESS) { int KeyCount; char szKey[MAX_PATH+1], szKey2[MAX_PATH+1]; wsprintf(szBuf, "%s\\ingres\\work", tchValue); Count=-1; CreateDirList(szBuf); for(KeyCount=0; KeyCount<=Count; KeyCount++) { wsprintf(szKey, "RemoveWorkDir_%d", KeyCount); wsprintf(szKey2, "RemoveWorkDir_%d_Dir", KeyCount); MsiSetProperty(hInstall, szKey, DirList[KeyCount].DirName); MsiRecordSetString(hRecord, 1, szKey); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, "*.*"); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } Count++; wsprintf(szKey, "RemoveWorkDir_%d", Count); wsprintf(szKey2, "RemoveWorkDir_%d_Dir", Count); wsprintf(szBuf, "%s\\ingres", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; Count++; wsprintf(szKey, "RemoveWorkDir_%d", Count); wsprintf(szKey2, "RemoveWorkDir_%d_Dir", Count); wsprintf(szBuf, "%s", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } Local_PMhost(Host); wsprintf(ConfigKey, "ii.%s.rcp.log.log_file_parts", Host); if(Local_PMget(ConfigKey, tchValue) == ERROR_SUCCESS) { int num_logs, i; num_logs=atoi(tchValue); for(i=1; i<=num_logs; i++) { wsprintf(ConfigKey, "ii.%s.rcp.log.log_file_%d", Host, i); if(Local_PMget(ConfigKey, tchValue) == ERROR_SUCCESS) { int KeyCount; char szKey[MAX_PATH+1], szKey2[MAX_PATH+1]; StringReplace(tchValue); wsprintf(szBuf, "%s\\ingres\\log", tchValue); Count=-1; CreateDirList(szBuf); for(KeyCount=0; KeyCount<=Count; KeyCount++) { wsprintf(szKey, "RemoveLogDir_%d", KeyCount); wsprintf(szKey2, "RemoveLogDir_%d_Dir", KeyCount); MsiSetProperty(hInstall, szKey, DirList[KeyCount].DirName); MsiRecordSetString(hRecord, 1, szKey); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, "*.*"); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } Count++; wsprintf(szKey, "RemoveLogDir_%d", Count); wsprintf(szKey2, "RemoveLogDir_%d_Dir", Count); wsprintf(szBuf, "%s\\ingres", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; Count++; wsprintf(szKey, "RemoveLogDir_%d", Count); wsprintf(szKey2, "RemoveLogDir_%d_Dir", Count); wsprintf(szBuf, "%s", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } } } wsprintf(ConfigKey, "ii.%s.rcp.log.dual_log_1", Host); if(Local_PMget(ConfigKey, tchValue) == ERROR_SUCCESS) { int KeyCount; char szKey[MAX_PATH+1], szKey2[MAX_PATH+1]; StringReplace(tchValue); wsprintf(szBuf, "%s\\ingres\\log", tchValue); Count=-1; CreateDirList(szBuf); for(KeyCount=0; KeyCount<=Count; KeyCount++) { wsprintf(szKey, "RemoveDuallogDir_%d", KeyCount); wsprintf(szKey2, "RemoveDuallogDir_%d_Dir", KeyCount); MsiSetProperty(hInstall, szKey, DirList[KeyCount].DirName); MsiRecordSetString(hRecord, 1, szKey); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, "*.*"); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } Count++; wsprintf(szKey, "RemoveDuallogDir_%d", Count); wsprintf(szKey2, "RemoveDuallogDir_%d_Dir", Count); wsprintf(szBuf, "%s\\ingres", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; Count++; wsprintf(szKey, "RemoveDuallogDir_%d", Count); wsprintf(szKey2, "RemoveDuallogDir_%d_Dir", Count); wsprintf(szBuf, "%s", tchValue); MsiSetProperty(hInstall, szKey, szBuf); MsiRecordSetString(hRecord, 1, szKey2); MsiRecordSetString(hRecord, 2, bin_id); MsiRecordSetString(hRecord, 3, ""); MsiRecordSetString(hRecord, 4, szKey); MsiRecordSetInteger(hRecord, 5, 2); if(MsiViewExecute(hView, hRecord)!=ERROR_SUCCESS) return ERROR_INSTALL_FAILURE; } MsiCloseHandle(hRecord); MsiCloseHandle(hView); MsiCloseHandle(hDatabase); return ERROR_SUCCESS; }
static void test_msirecord(void) { DWORD r, sz; INT i; MSIHANDLE h; char buf[10]; WCHAR bufW[10]; const char str[] = "hello"; const WCHAR strW[] = { 'h','e','l','l','o',0}; char filename[MAX_PATH]; /* check behaviour with an invalid record */ r = MsiRecordGetFieldCount(0); ok(r==-1, "field count for invalid record not -1\n"); SetLastError(0); r = MsiRecordIsNull(0, 0); ok(r==0, "invalid handle not considered to be non-null...\n"); ok(GetLastError()==0, "MsiRecordIsNull set LastError\n"); r = MsiRecordGetInteger(0,0); ok(r == MSI_NULL_INTEGER, "got integer from invalid record\n"); r = MsiRecordSetInteger(0,0,0); ok(r == ERROR_INVALID_HANDLE, "MsiRecordSetInteger returned wrong error\n"); r = MsiRecordSetInteger(0,-1,0); ok(r == ERROR_INVALID_HANDLE, "MsiRecordSetInteger returned wrong error\n"); SetLastError(0); h = MsiCreateRecord(-1); ok(h==0, "created record with -1 elements\n"); h = MsiCreateRecord(0x10000); ok(h==0, "created record with 0x10000 elements\n"); /* doesn't set LastError */ ok(GetLastError()==0, "MsiCreateRecord set last error\n"); r = MsiRecordClearData(0); ok(r == ERROR_INVALID_HANDLE, "MsiRecordClearData returned wrong error\n"); r = MsiRecordDataSize(0,0); ok(r == 0, "MsiRecordDataSize returned wrong error\n"); /* check behaviour of a record with 0 elements */ h = MsiCreateRecord(0); ok(h!=0, "couldn't create record with zero elements\n"); r = MsiRecordGetFieldCount(h); ok(r==0, "field count should be zero\n"); r = MsiRecordIsNull(h,0); ok(r, "new record wasn't null\n"); r = MsiRecordIsNull(h,1); ok(r, "out of range record wasn't null\n"); r = MsiRecordIsNull(h,-1); ok(r, "out of range record wasn't null\n"); r = MsiRecordDataSize(h,0); ok(r==0, "size of null record is 0\n"); sz = sizeof buf; strcpy(buf,"x"); r = MsiRecordGetString(h, 0, buf, &sz); ok(r==ERROR_SUCCESS, "failed to get null string\n"); ok(sz==0, "null string too long\n"); ok(buf[0]==0, "null string not set\n"); /* same record, but add an integer to it */ r = MsiRecordSetInteger(h, 0, 0); ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 0\n"); r = MsiRecordIsNull(h,0); ok(r==0, "new record is null after setting an integer\n"); r = MsiRecordDataSize(h,0); ok(r==sizeof(DWORD), "size of integer record is 4\n"); r = MsiRecordSetInteger(h, 0, 1); ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 1\n"); r = MsiRecordSetInteger(h, 1, 1); ok(r == ERROR_INVALID_PARAMETER, "set integer at 1\n"); r = MsiRecordSetInteger(h, -1, 0); ok(r == ERROR_INVALID_PARAMETER, "set integer at -1\n"); r = MsiRecordIsNull(h,0); ok(r==0, "new record is null after setting an integer\n"); r = MsiRecordGetInteger(h, 0); ok(r == 1, "failed to get integer\n"); /* same record, but add a string to it */ r = MsiRecordSetString(h, 0, NULL); ok(r == ERROR_SUCCESS, "Failed to set null string at 0\n"); r = MsiRecordIsNull(h, 0); ok(r == TRUE, "null string not null field\n"); r = MsiRecordSetString(h, 0, ""); ok(r == ERROR_SUCCESS, "Failed to set empty string at 0\n"); r = MsiRecordIsNull(h, 0); ok(r == TRUE, "null string not null field\n"); r = MsiRecordSetString(h,0,str); ok(r == ERROR_SUCCESS, "Failed to set string at 0\n"); r = MsiRecordGetInteger(h, 0); ok(r == MSI_NULL_INTEGER, "should get invalid integer\n"); r = MsiRecordDataSize(h,0); ok(r==sizeof str-1, "size of string record is strlen\n"); buf[0]=0; sz = sizeof buf; r = MsiRecordGetString(h,0,buf,&sz); ok(r == ERROR_SUCCESS, "Failed to get string at 0\n"); ok(0==strcmp(buf,str), "MsiRecordGetString returned the wrong string\n"); ok(sz == sizeof str-1, "MsiRecordGetString returned the wrong length\n"); buf[0]=0; sz = sizeof str - 2; r = MsiRecordGetString(h,0,buf,&sz); ok(r == ERROR_MORE_DATA, "small buffer should yield ERROR_MORE_DATA\n"); ok(sz == sizeof str-1, "MsiRecordGetString returned the wrong length\n"); ok(0==strncmp(buf,str,sizeof str-3), "MsiRecordGetString returned the wrong string\n"); ok(buf[sizeof str - 3]==0, "string wasn't nul terminated\n"); buf[0]=0; sz = sizeof str; r = MsiRecordGetString(h,0,buf,&sz); ok(r == ERROR_SUCCESS, "wrong error\n"); ok(sz == sizeof str-1, "MsiRecordGetString returned the wrong length\n"); ok(0==strcmp(buf,str), "MsiRecordGetString returned the wrong string\n"); memset(bufW, 0, sizeof bufW); sz = 5; r = MsiRecordGetStringW(h,0,bufW,&sz); ok(r == ERROR_MORE_DATA, "wrong error\n"); ok(sz == 5, "MsiRecordGetString returned the wrong length\n"); ok(0==memcmp(bufW,strW,8), "MsiRecordGetString returned the wrong string\n"); sz = 0; bufW[0] = 'x'; r = MsiRecordGetStringW(h,0,bufW,&sz); ok(r == ERROR_MORE_DATA, "wrong error\n"); ok(sz == 5, "MsiRecordGetString returned the wrong length\n"); ok('x'==bufW[0], "MsiRecordGetString returned the wrong string\n"); memset(buf, 0, sizeof buf); sz = 5; r = MsiRecordGetStringA(h,0,buf,&sz); ok(r == ERROR_MORE_DATA, "wrong error\n"); ok(sz == 5, "MsiRecordGetString returned the wrong length\n"); ok(0==memcmp(buf,str,4), "MsiRecordGetString returned the wrong string\n"); sz = 0; buf[0] = 'x'; r = MsiRecordGetStringA(h,0,buf,&sz); ok(r == ERROR_MORE_DATA, "wrong error\n"); ok(sz == 5, "MsiRecordGetString returned the wrong length\n"); ok('x'==buf[0], "MsiRecordGetString returned the wrong string\n"); /* same record, check we can wipe all the data */ r = MsiRecordClearData(h); ok(r == ERROR_SUCCESS, "Failed to clear record\n"); r = MsiRecordClearData(h); ok(r == ERROR_SUCCESS, "Failed to clear record again\n"); r = MsiRecordIsNull(h,0); ok(r, "cleared record wasn't null\n"); /* same record, try converting strings to integers */ i = MsiRecordSetString(h,0,"42"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == 42, "should get invalid integer\n"); i = MsiRecordSetString(h,0,"-42"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == -42, "should get invalid integer\n"); i = MsiRecordSetString(h,0," 42"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == MSI_NULL_INTEGER, "should get invalid integer\n"); i = MsiRecordSetString(h,0,"42 "); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == MSI_NULL_INTEGER, "should get invalid integer\n"); i = MsiRecordSetString(h,0,"42.0"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == MSI_NULL_INTEGER, "should get invalid integer\n"); i = MsiRecordSetString(h,0,"0x42"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == MSI_NULL_INTEGER, "should get invalid integer\n"); i = MsiRecordSetString(h,0,"1000000000000000"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == -1530494976, "should get truncated integer\n"); i = MsiRecordSetString(h,0,"2147483647"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == 2147483647, "should get maxint\n"); i = MsiRecordSetString(h,0,"-2147483647"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == -2147483647, "should get -maxint-1\n"); i = MsiRecordSetString(h,0,"4294967297"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == 1, "should get one\n"); i = MsiRecordSetString(h,0,"foo"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == MSI_NULL_INTEGER, "should get zero\n"); i = MsiRecordSetString(h,0,""); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == MSI_NULL_INTEGER, "should get zero\n"); i = MsiRecordSetString(h,0,"+1"); ok(i == ERROR_SUCCESS, "Failed to set string at 0\n"); i = MsiRecordGetInteger(h, 0); ok(i == MSI_NULL_INTEGER, "should get zero\n"); /* same record, try converting integers to strings */ r = MsiRecordSetInteger(h, 0, 32); ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 32\n"); sz = 1; r = MsiRecordGetString(h, 0, NULL, &sz); ok(r == ERROR_SUCCESS, "failed to get string from integer\n"); ok(sz == 2, "length wrong\n"); buf[0]=0; sz = sizeof buf; r = MsiRecordGetString(h, 0, buf, &sz); ok(r == ERROR_SUCCESS, "failed to get string from integer\n"); ok(0==strcmp(buf,"32"), "failed to get string from integer\n"); r = MsiRecordSetInteger(h, 0, -32); ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 32\n"); buf[0]=0; sz = 1; r = MsiRecordGetString(h, 0, NULL, &sz); ok(r == ERROR_SUCCESS, "failed to get string from integer\n"); ok(sz == 3, "length wrong\n"); sz = sizeof buf; r = MsiRecordGetString(h, 0, buf, &sz); ok(r == ERROR_SUCCESS, "failed to get string from integer\n"); ok(0==strcmp(buf,"-32"), "failed to get string from integer\n"); buf[0]=0; /* same record, now try streams */ r = MsiRecordSetStream(h, 0, NULL); ok(r == ERROR_INVALID_PARAMETER, "set NULL stream\n"); sz = sizeof buf; r = MsiRecordReadStream(h, 0, buf, &sz); ok(r == ERROR_INVALID_DATATYPE, "read non-stream type\n"); ok(sz == sizeof buf, "set sz\n"); r = MsiRecordDataSize( h, -1); ok(r == 0,"MsiRecordDataSize returned wrong size\n"); r = MsiRecordDataSize( h, 0); ok(r == 4,"MsiRecordDataSize returned wrong size\n"); /* same record, now close it */ r = MsiCloseHandle(h); ok(r == ERROR_SUCCESS, "Failed to close handle\n"); /* now try streams in a new record - need to create a file to play with */ r = create_temp_file(filename); if(!r) return; /* streams can't be inserted in field 0 for some reason */ h = MsiCreateRecord(2); ok(h, "couldn't create a two field record\n"); r = MsiRecordSetStream(h, 0, filename); ok(r == ERROR_INVALID_PARAMETER, "added stream to field 0\n"); r = MsiRecordSetStream(h, 1, filename); ok(r == ERROR_SUCCESS, "failed to add stream to record\n"); r = MsiRecordReadStream(h, 1, buf, NULL); ok(r == ERROR_INVALID_PARAMETER, "should return error\n"); /* http://test.winehq.org/data/200503181000/98_jmelgarejo98casa/msi:record.txt */ DeleteFile(filename); /* Windows 98 doesn't like this at all, so don't check return. */ r = MsiRecordReadStream(h, 1, NULL, NULL); ok(r == ERROR_INVALID_PARAMETER, "should return error\n"); sz = sizeof buf; r = MsiRecordReadStream(h, 1, NULL, &sz); ok(r == ERROR_SUCCESS, "failed to read stream\n"); ok(sz==26,"couldn't get size of stream\n"); sz = 0; r = MsiRecordReadStream(h, 1, buf, &sz); ok(r == ERROR_SUCCESS, "failed to read stream\n"); ok(sz==0,"short read\n"); sz = sizeof buf; r = MsiRecordReadStream(h, 1, buf, &sz); ok(r == ERROR_SUCCESS, "failed to read stream\n"); ok(sz==sizeof buf,"short read\n"); ok(!strncmp(buf,"abcdefghij",10), "read the wrong thing\n"); sz = sizeof buf; r = MsiRecordReadStream(h, 1, buf, &sz); ok(r == ERROR_SUCCESS, "failed to read stream\n"); ok(sz==sizeof buf,"short read\n"); ok(!strncmp(buf,"klmnopqrst",10), "read the wrong thing\n"); memset(buf,0,sizeof buf); sz = sizeof buf; r = MsiRecordReadStream(h, 1, buf, &sz); ok(r == ERROR_SUCCESS, "failed to read stream\n"); ok(sz==6,"short read\n"); ok(!strcmp(buf,"uvwxyz"), "read the wrong thing\n"); memset(buf,0,sizeof buf); sz = sizeof buf; r = MsiRecordReadStream(h, 1, buf, &sz); ok(r == ERROR_SUCCESS, "failed to read stream\n"); ok(sz==0,"size non-zero at end of stream\n"); ok(buf[0]==0, "read something at end of the stream\n"); r = MsiRecordSetStream(h, 1, NULL); ok(r == ERROR_SUCCESS, "failed to reset stream\n"); sz = 0; r = MsiRecordReadStream(h, 1, NULL, &sz); ok(r == ERROR_SUCCESS, "bytes left wrong after reset\n"); ok(sz==26,"couldn't get size of stream\n"); r = MsiRecordDataSize(h,1); ok(r == 26,"MsiRecordDataSize returned wrong size\n"); /* now close the stream record */ r = MsiCloseHandle(h); ok(r == ERROR_SUCCESS, "Failed to close handle\n"); DeleteFile(filename); /* Delete it for sure, when everything else is closed. */ }
static void test_fieldzero(void) { MSIHANDLE hdb, hview, rec; CHAR buf[MAX_PATH]; LPCSTR query; DWORD sz; UINT r; rec = MsiCreateRecord(1); ok(rec != 0, "Expected a valid handle\n"); r = MsiRecordGetInteger(rec, 0); ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); sz = MAX_PATH; lstrcpyA(buf, "apple"); r = MsiRecordGetString(rec, 0, buf, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); ok(sz == 0, "Expectd 0, got %d\n", sz); r = MsiRecordIsNull(rec, 0); ok(r == TRUE, "Expected TRUE, got %d\n", r); r = MsiRecordGetInteger(rec, 1); ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); r = MsiRecordSetInteger(rec, 1, 42); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiRecordGetInteger(rec, 0); ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); sz = MAX_PATH; lstrcpyA(buf, "apple"); r = MsiRecordGetString(rec, 0, buf, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); ok(sz == 0, "Expectd 0, got %d\n", sz); r = MsiRecordIsNull(rec, 0); ok(r == TRUE, "Expected TRUE, got %d\n", r); r = MsiRecordGetInteger(rec, 1); ok(r == 42, "Expected 42, got %d\n", r); r = MsiRecordSetString(rec, 1, "bologna"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiRecordGetInteger(rec, 0); ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); sz = MAX_PATH; lstrcpyA(buf, "apple"); r = MsiRecordGetString(rec, 0, buf, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf); ok(sz == 0, "Expectd 0, got %d\n", sz); r = MsiRecordIsNull(rec, 0); ok(r == TRUE, "Expected TRUE, got %d\n", r); sz = MAX_PATH; lstrcpyA(buf, "apple"); r = MsiRecordGetString(rec, 1, buf, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(buf, "bologna"), "Expected \"bologna\", got \"%s\"\n", buf); ok(sz == 7, "Expectd 7, got %d\n", sz); MsiCloseHandle(rec); r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb); ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n"); query = "CREATE TABLE `drone` ( " "`id` INT, `name` CHAR(32), `number` CHAR(32) " "PRIMARY KEY `id`)"; r = MsiDatabaseOpenView(hdb, query, &hview); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiViewExecute(hview, 0); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiViewClose(hview); ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); r = MsiCloseHandle(hview); ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); query = "INSERT INTO `drone` ( `id`, `name`, `number` )" "VALUES('1', 'Abe', '8675309')"; r = MsiDatabaseOpenView(hdb, query, &hview); ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n"); r = MsiViewExecute(hview, 0); ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n"); r = MsiViewClose(hview); ok(r == ERROR_SUCCESS, "MsiViewClose failed\n"); r = MsiCloseHandle(hview); ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); r = MsiDatabaseGetPrimaryKeysA(hdb, "drone", &rec); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiRecordGetInteger(rec, 0); ok(r == MSI_NULL_INTEGER, "Expected MSI_NULL_INTEGER, got %d\n", r); sz = MAX_PATH; lstrcpyA(buf, "apple"); r = MsiRecordGetString(rec, 0, buf, &sz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(!lstrcmpA(buf, "drone"), "Expected \"drone\", got \"%s\"\n", buf); ok(sz == 5, "Expectd 5, got %d\n", sz); r = MsiRecordIsNull(rec, 0); ok(r == FALSE, "Expected FALSE, got %d\n", r); MsiCloseHandle(rec); r = MsiDatabaseGetPrimaryKeysA(hdb, "nosuchtable", &rec); ok(r == ERROR_INVALID_TABLE, "Expected ERROR_INVALID_TABLE, got %d\n", r); query = "SELECT * FROM `drone` WHERE `id` = 1"; r = MsiDatabaseOpenView(hdb, query, &hview); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiViewExecute(hview, 0); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiViewFetch(hview, &rec); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); r = MsiRecordGetInteger(rec, 0); ok(r != MSI_NULL_INTEGER && r != 0, "Expected non-NULL value, got %d\n", r); r = MsiRecordIsNull(rec, 0); ok(r == FALSE, "Expected FALSE, got %d\n", r); r = MsiCloseHandle(hview); ok(r == ERROR_SUCCESS, "MsiCloseHandle failed\n"); MsiCloseHandle(rec); MsiCloseHandle(hdb); DeleteFileA(msifile); }
///////////////////////////////////////////////////////////////////// // // Function: GetComponentKeyFilename // // Description: // ///////////////////////////////////////////////////////////////////// UINT BOINCCABase::GetComponentKeyFilename( const tstring strComponentName, tstring& strComponentKeyFilename ) { UINT uiReturnValue = 0; tstring strMessage; tstring strQuery; TCHAR szBuffer[256]; DWORD dwBufferSize = sizeof(szBuffer); MSIHANDLE hDatabase; MSIHANDLE hView; MSIHANDLE hRecComponentName; MSIHANDLE hRec; // Get the handle to the MSI package we are executing for. hDatabase = MsiGetActiveDatabase(m_hMSIHandle); if (!hDatabase) return ERROR_INSTALL_FAILURE; // Construct the query that is going to give us the result we need. strQuery = _T("SELECT `KeyPath` FROM `Component` WHERE `Component`= ?"); // Create the view uiReturnValue = MsiDatabaseOpenView(hDatabase, strQuery.c_str(), &hView); switch(uiReturnValue) { case ERROR_BAD_QUERY_SYNTAX: MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiDatabaseOpenView reports an invalid query was issued") ); return ERROR_INSTALL_FAILURE; break; case ERROR_INVALID_HANDLE: MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiDatabaseOpenView reports an invalid handle was used") ); return ERROR_INSTALL_FAILURE; break; } // Create query parameter hRecComponentName = MsiCreateRecord(1); uiReturnValue = MsiRecordSetString(hRecComponentName, 1, strComponentName.c_str()); switch(uiReturnValue) { case ERROR_INVALID_HANDLE: MsiCloseHandle(hRecComponentName); MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiRecordSetString reports an invalid handle was used") ); return ERROR_INSTALL_FAILURE; break; case ERROR_INVALID_PARAMETER: MsiCloseHandle(hRecComponentName); MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiRecordSetString reports an invalid parameter was used") ); return ERROR_INSTALL_FAILURE; break; } // Execute the query uiReturnValue = MsiViewExecute(hView, hRecComponentName); switch(uiReturnValue) { case ERROR_FUNCTION_FAILED: MsiViewClose(hView); MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiViewExecute failed to execute the view") ); return ERROR_INSTALL_FAILURE; break; case ERROR_INVALID_HANDLE: MsiViewClose(hView); MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiViewExecute reports an invalid handle was used") ); return ERROR_INSTALL_FAILURE; break; } // Only one row should be returned by the resultset, so there is no need // to execute MsiViewFetch more than once. uiReturnValue = MsiViewFetch(hView, &hRec); switch(uiReturnValue) { case ERROR_FUNCTION_FAILED: MsiViewClose(hView); MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiViewFetch: An error occurred during fetching") ); return ERROR_INSTALL_FAILURE; break; case ERROR_INVALID_HANDLE: MsiViewClose(hView); MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiViewFetch reports an invalid handle was used") ); return ERROR_INSTALL_FAILURE; break; case ERROR_INVALID_HANDLE_STATE: MsiViewClose(hView); MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiViewFetch reports the handle was in an invalid state") ); return ERROR_INSTALL_FAILURE; break; } // Okay, now it is time to parse the string that was returned. uiReturnValue = MsiRecordGetString(hRec, 1, (LPTSTR)&szBuffer, &dwBufferSize); switch(uiReturnValue) { case ERROR_INVALID_HANDLE: MsiCloseHandle(hRec); MsiViewClose(hView); MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiRecordGetString reports an invalid handle was used") ); return ERROR_INSTALL_FAILURE; break; case ERROR_INVALID_PARAMETER: MsiCloseHandle(hRec); MsiViewClose(hView); MsiCloseHandle(hDatabase); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("MsiRecordGetString reports an invalid parameter was used") ); return ERROR_INSTALL_FAILURE; break; } // Save the string strComponentKeyFilename = szBuffer; strMessage = _T("The key filename for component '"); strMessage += strComponentName; strMessage += _T("' is '"); strMessage += strComponentKeyFilename; strMessage += _T("'"); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, strMessage.c_str() ); return ERROR_SUCCESS; }
void x_msg_va(const unsigned int flags, const char *format, va_list arglist) { /* Secure last error before it is overridden. */ DWORD dwResult = (flags & M_ERRNO) != 0 ? GetLastError() : ERROR_SUCCESS; struct openvpnmsica_thread_data *s = (struct openvpnmsica_thread_data *)TlsGetValue(openvpnmsica_thread_data_idx); if (s->hInstall == 0) { /* No MSI session, no fun. */ return; } /* Prepare the message record. The record will contain up to four fields. */ MSIHANDLE hRecordProg = MsiCreateRecord(4); { /* Field 2: The message string. */ char szBufStack[128]; int iResultLen = vsnprintf(szBufStack, _countof(szBufStack), format, arglist); if (iResultLen < _countof(szBufStack)) { /* Use from stack. */ MsiRecordSetStringA(hRecordProg, 2, szBufStack); } else { /* Allocate on heap and retry. */ char *szMessage = (char *)malloc(++iResultLen * sizeof(char)); if (szMessage != NULL) { vsnprintf(szMessage, iResultLen, format, arglist); MsiRecordSetStringA(hRecordProg, 2, szMessage); free(szMessage); } else { /* Use stack variant anyway, but make sure it's zero-terminated. */ szBufStack[_countof(szBufStack) - 1] = 0; MsiRecordSetStringA(hRecordProg, 2, szBufStack); } } } if ((flags & M_ERRNO) == 0) { /* Field 1: MSI Error Code */ MsiRecordSetInteger(hRecordProg, 1, ERROR_MSICA); } else { /* Field 1: MSI Error Code */ MsiRecordSetInteger(hRecordProg, 1, ERROR_MSICA_ERRNO); /* Field 3: The Windows error number. */ MsiRecordSetInteger(hRecordProg, 3, dwResult); /* Field 4: The Windows error description. */ LPTSTR szErrMessage = NULL; if (FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, 0, dwResult, 0, (LPTSTR)&szErrMessage, 0, NULL) && szErrMessage) { /* Trim trailing whitespace. Set terminator after the last non-whitespace character. This prevents excessive trailing line breaks. */ for (size_t i = 0, i_last = 0;; i++) { if (szErrMessage[i]) { if (!_istspace(szErrMessage[i])) { i_last = i + 1; } } else { szErrMessage[i_last] = 0; break; } } MsiRecordSetString(hRecordProg, 4, szErrMessage); LocalFree(szErrMessage); } } MsiProcessMessage(s->hInstall, INSTALLMESSAGE_ERROR, hRecordProg); MsiCloseHandle(hRecordProg); }
i4 main(i4 argc, char* argv[]) { MSIHANDLE hDatabase; char view[1024]; int Branding_Width, DlgLine_Width, DlgLine_X; char Branding_Text[64]; if((argc < 2) || (GetFileAttributes(argv[1])==-1)) { printf ("usage:\nmsiupd <full path to MSI file>\nmsiupd <full path to MSM file> <%II_INSTALLATION%>"); return 1; } if(strstr(argv[1], "Ingres SDK") != NULL) { Branding_Width=40; DlgLine_X=45; DlgLine_Width=329; strcpy(Branding_Text, "Ingres SDK"); } else { Branding_Width=30; DlgLine_X=35; DlgLine_Width=339; strcpy(Branding_Text, "Ingres"); } MsiOpenDatabase(argv[1], MSIDBOPEN_DIRECT, &hDatabase); if (!hDatabase) return 1; if (argc==2 && strstr(argv[1], ".msi")) { /* ** Change the brandings on each page from InstallShield to ** Advantage Ingres. */ sprintf(view, "UPDATE Control SET Width = '%d' WHERE Control = 'Branding1'", Branding_Width); if(!ViewExecute(hDatabase, view)) return 1; sprintf(view, "UPDATE Control SET Width = '%d' WHERE Control = 'Branding2'", Branding_Width); if(!ViewExecute(hDatabase, view)) return 1; sprintf(view, "UPDATE Control SET X = '%d' WHERE Control = 'DlgLine'", DlgLine_X ); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET X = '0' WHERE Dialog_ = 'AdminWelcome' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET X = '0' WHERE Dialog_ = 'InstallWelcome' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET X = '0' WHERE Dialog_ = 'PatchWelcome' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET X = '0' WHERE Dialog_ = 'SetupCompleteError' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET X = '0' WHERE Dialog_ = 'SetupInterrupted' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET X = '0' WHERE Dialog_ = 'SetupCompleteSuccess' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET X = '0' WHERE Dialog_ = 'SetupInitialization' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET X = '0' WHERE Dialog_ = 'SetupResume' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET X = '0' WHERE Dialog_ = 'MaintenanceWelcome'AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; sprintf(view, "UPDATE Control SET Width = '%d' WHERE Control = 'DlgLine'", DlgLine_Width ); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Width = '374' WHERE Dialog_ = 'AdminWelcome' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Width = '374' WHERE Dialog_ = 'InstallWelcome' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Width = '374' WHERE Dialog_ = 'PatchWelcome' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Width = '374' WHERE Dialog_ = 'SetupCompleteError' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Width = '374' WHERE Dialog_ = 'SetupInterrupted' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Width = '374' WHERE Dialog_ = 'SetupCompleteSuccess' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Width = '374' WHERE Dialog_ = 'SetupInitialization' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Width = '374' WHERE Dialog_ = 'SetupResume' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Width = '374' WHERE Dialog_ = 'MaintenanceWelcome' AND Control = 'DlgLine'"); if(!ViewExecute(hDatabase, view)) return 1; sprintf(view, "UPDATE Control SET Text = '{&MSSWhiteSerif8}%s' WHERE Control = 'Branding1'", Branding_Text); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'AdminWelcome' AND Control = 'Branding1'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'InstallWelcome' AND Control = 'Branding1'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'PatchWelcome' AND Control = 'Branding1'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'SetupCompleteError' AND Control = 'Branding1'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'SetupInterrupted' AND Control = 'Branding1'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'SetupCompleteSuccess' AND Control = 'Branding1'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'SetupInitialization' AND Control = 'Branding1'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'SetupResume' AND Control = 'Branding1'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'MaintenanceWelcome'AND Control = 'Branding1'"); if(!ViewExecute(hDatabase, view)) return 1; sprintf(view, "UPDATE Control SET Text = '{&Tahoma8}%s' WHERE Control = 'Branding2'", Branding_Text); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'AdminWelcome' AND Control = 'Branding2'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'InstallWelcome' AND Control = 'Branding2'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'PatchWelcome' AND Control = 'Branding2'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'SetupCompleteError' AND Control = 'Branding2'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'SetupInterrupted' AND Control = 'Branding2'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'SetupCompleteSuccess' AND Control = 'Branding2'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'SetupInitialization' AND Control = 'Branding2'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'SetupResume' AND Control = 'Branding2'"); if(!ViewExecute(hDatabase, view)) return 1; strcpy(view, "UPDATE Control SET Text = '' WHERE Dialog_ = 'MaintenanceWelcome'AND Control = 'Branding2'"); if(!ViewExecute(hDatabase, view)) return 1; } else if(argc==3 && strstr(argv[1], ".msm")) { /* Update Merge Module database with II_INSTALLATION. */ MSIHANDLE hView, hRecord; int idx; char szID[3]; strcpy(szID, _strupr(argv[2])); if (strlen(szID)!=2 || !isalpha(szID[0]) || !isalnum(szID[1])) { printf ("Invalid installation identifier!"); return 1; } if (!strcmp(szID, "II")) { if(MsiDatabaseCommit(hDatabase)!=ERROR_SUCCESS) return 1; if(MsiCloseHandle(hDatabase)!=ERROR_SUCCESS) return 1; return 0; } /* Update shortcut folders. */ if (!MsiDatabaseOpenView (hDatabase, "SELECT Directory, DefaultDir FROM Directory", &hView)) { if (!MsiViewExecute(hView, 0)) { while (MsiViewFetch(hView, &hRecord)!=ERROR_NO_MORE_ITEMS) { char szValue[80]; DWORD dwSize=sizeof(szValue); MsiRecordGetString(hRecord, 2, szValue, &dwSize); if (strstr(szValue, "Ingres II [ ")) sprintf(szValue, "Ingres II [ %s ]", szID); else if (strstr(szValue, "Ingres [ ")) sprintf(szValue, "Ingres [ %s ]", szID); MsiRecordSetString(hRecord, 2, szValue); MsiViewModify(hView, MSIMODIFY_UPDATE, hRecord); MsiCloseHandle(hRecord); } } MsiCloseHandle(hView); } /* Update IVM Startup shortcut. */ if (!MsiDatabaseOpenView(hDatabase, "SELECT Name, Component_ FROM Shortcut", &hView)) { if(!MsiViewExecute(hView, 0)) { while (MsiViewFetch(hView, &hRecord)!=ERROR_NO_MORE_ITEMS) { char szValue[80], szValue2[80]; DWORD dwSize, dwSize2; dwSize=sizeof(szValue); dwSize2=sizeof(szValue2); MsiRecordGetString(hRecord, 1, szValue, &dwSize); MsiRecordGetString(hRecord, 2, szValue2, &dwSize2); if (strstr(szValue, "Ingres Visual Manager [ ") && strstr(szValue2, "Shortcuts.") && !strstr(szValue2, "SDKShortcuts.")) sprintf(szValue, "Ingres Visual Manager [ %s ]", szID); MsiRecordSetString(hRecord, 1, szValue); MsiViewModify(hView, MSIMODIFY_UPDATE, hRecord); MsiCloseHandle(hRecord); } } MsiCloseHandle(hView); } /* Update Component GUIDs. */ idx = (toupper(szID[0]) - 'A') * 26 + toupper(szID[1]) - 'A'; if (idx <= 0) idx = (toupper(szID[0]) - 'A') * 26 + toupper(szID[1]) - '0'; UpdateComponentIds(hDatabase, idx); } else { printf ("usage:\nmsiupd <full path to MSI file>\nmsiupd <full path to MSM file> <%II_INSTALLATION%>"); return 1; } if(MsiDatabaseCommit(hDatabase)!=ERROR_SUCCESS) return 1; if(MsiCloseHandle(hDatabase)!=ERROR_SUCCESS) return 1; return 0; }
UINT KillRunningProcessesSlave( MSIHANDLE hInstall, BOOL bKill ) { UINT rv = ERROR_SUCCESS; _KillProc * kpList; int nKpList = 0; int i; int rowNum = 1; DWORD size; BOOL found = FALSE; MSIHANDLE hDatabase = NULL; MSIHANDLE hView = NULL; MSIHANDLE hViewInsert = NULL; MSIHANDLE hRecord = NULL; MSIHANDLE hRecordInsert = NULL; HANDLE hSnapshot = NULL; PROCESSENTRY32 pe; kpList = new _KillProc[MAX_KILL_PROCESSES]; memset(kpList, 0, sizeof(*kpList) * MAX_KILL_PROCESSES); hDatabase = MsiGetActiveDatabase( hInstall ); if( hDatabase == NULL ) { rv = GetLastError(); goto _cleanup; } // If we are only going to list out the processes, delete all the existing // entries first. if(!bKill) { rv = MsiDatabaseOpenView( hDatabase, _T( "DELETE FROM `ListBox` WHERE `ListBox`.`Property` = 'KillableProcesses'" ), &hView); RV_BAIL; rv = MsiViewExecute( hView, NULL ); RV_BAIL; MsiCloseHandle( hView ); hView = NULL; rv = MsiDatabaseOpenView( hDatabase, _T( "SELECT * FROM `ListBox` WHERE `Property` = 'KillableProcesses'" ), &hViewInsert); RV_BAIL; MsiViewExecute(hViewInsert, NULL); hRecordInsert = MsiCreateRecord(4); if(hRecordInsert == NULL) { rv = GetLastError(); goto _cleanup; } } // Open a view rv = MsiDatabaseOpenView( hDatabase, _T( "SELECT `Image`,`Desc` FROM `KillProcess`" ), &hView); RV_BAIL; rv = MsiViewExecute( hView, NULL ); RV_BAIL; do { rv = MsiViewFetch( hView, &hRecord ); if(rv != ERROR_SUCCESS) { if(hRecord) MsiCloseHandle(hRecord); hRecord = NULL; break; } kpList[nKpList].image = new TCHAR[ FIELD_SIZE ]; kpList[nKpList].image[0] = _T('\0'); kpList[nKpList].desc = new TCHAR[ FIELD_SIZE ]; kpList[nKpList].desc[0] = _T('\0'); nKpList++; size = FIELD_SIZE; rv = MsiRecordGetString(hRecord, 1, kpList[nKpList-1].image, &size); RV_BAIL; size = FIELD_SIZE; rv = MsiRecordGetString(hRecord, 2, kpList[nKpList-1].desc, &size); RV_BAIL; MsiCloseHandle(hRecord); } while(nKpList < MAX_KILL_PROCESSES); hRecord = NULL; // now we have all the processes in the array. Check if they are running. hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if(hSnapshot == INVALID_HANDLE_VALUE) { rv = GetLastError(); goto _cleanup; } pe.dwSize = sizeof( PROCESSENTRY32 ); if(!Process32First( hSnapshot, &pe )) { // technically we should at least find the MSI process, but we let this pass rv = ERROR_SUCCESS; goto _cleanup; } do { for(i=0; i<nKpList; i++) { if(!_tcsicmp( kpList[i].image, pe.szExeFile )) { // got one if(bKill) { // try to kill the process HANDLE hProcess = NULL; // If we encounter an error, instead of bailing // out, we continue on to the next process. We // may not have permission to kill all the // processes we want to kill anyway. If there are // any files that we want to replace that is in // use, Windows Installer will schedule a reboot. // Also, it's not like we have an exhaustive list // of all the programs that use Kerberos anyway. hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe.th32ProcessID); if(hProcess == NULL) { rv = GetLastError(); break; } if(!TerminateProcess(hProcess, 0)) { rv = GetLastError(); CloseHandle(hProcess); break; } CloseHandle(hProcess); } else { TCHAR buf[256]; // we are supposed to just list out the processes rv = MsiRecordClearData( hRecordInsert ); RV_BAIL; rv = MsiRecordSetString( hRecordInsert, 1, _T("KillableProcesses")); rv = MsiRecordSetInteger( hRecordInsert, 2, rowNum++ ); RV_BAIL; _itot( rowNum, buf, 10 ); rv = MsiRecordSetString( hRecordInsert, 3, buf ); RV_BAIL; if(_tcslen(kpList[i].desc)) { rv = MsiRecordSetString( hRecordInsert, 4, kpList[i].desc ); RV_BAIL; } else { rv = MsiRecordSetString( hRecordInsert, 4, kpList[i].image ); RV_BAIL; } MsiViewModify(hViewInsert, MSIMODIFY_INSERT_TEMPORARY, hRecordInsert); RV_BAIL; found = TRUE; } break; } } } while( Process32Next( hSnapshot, &pe ) ); if(!bKill) { // set the 'FoundProcceses' property if(found) { MsiSetProperty( hInstall, _T("FoundProcesses"), _T("1")); } else { MsiSetProperty( hInstall, _T("FoundProcesses"), _T("")); } } // Finally: rv = ERROR_SUCCESS; _cleanup: if(hRecordInsert) MsiCloseHandle(hRecordInsert); if(hViewInsert) MsiCloseHandle(hView); if(hSnapshot && hSnapshot != INVALID_HANDLE_VALUE) CloseHandle(hSnapshot); while(nKpList) { nKpList--; delete kpList[nKpList].image; delete kpList[nKpList].desc; } delete kpList; if(hRecord) MsiCloseHandle(hRecord); if(hView) MsiCloseHandle(hView); if(hDatabase) MsiCloseHandle(hDatabase); if(rv != ERROR_SUCCESS) { ShowMsiError(hInstall, ERR_PROC_LIST, rv); } return rv; }