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; }
MSICA_IMP ReplaceEula(MSIHANDLE hInstall) { // ::DebugBreak(); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); // // EULA File Content is MBCS (RTF) not Unicode AutoProcessHeapPtr<LPSTR> lpEula = pReadEulaFromFileA(hInstall); if (NULL == (LPSTR) lpEula) { _RPT0(_CRT_ERROR, "pReadEulaFromFile failed\n"); return ERROR_INSTALL_FAILURE; } _RPT0(_CRT_WARN, "ReplaceEula\n"); PMSIHANDLE hDatabase = MsiGetActiveDatabase(hInstall); if (0 == hDatabase) { _RPT0(_CRT_ERROR, "MsiGetActiveDatabase failed\n"); return ERROR_INSTALL_FAILURE; } PMSIHANDLE hView; LPCTSTR query = _T("SELECT * FROM `Control` WHERE `Dialog_` = 'LicenseAgreement' AND `Control` = 'Memo'"); UINT msiret = MsiDatabaseOpenView(hDatabase, query, &hView); if (ERROR_SUCCESS != msiret) { _RPT0(_CRT_ERROR, "MsiDatabaseOpenView failed\n"); return ERROR_INSTALL_FAILURE; } msiret = MsiViewExecute(hView, 0); if (ERROR_SUCCESS != msiret) { _RPT0(_CRT_ERROR, "MsiViewExecute failed\n"); return ERROR_INSTALL_FAILURE; } PMSIHANDLE hRecord; msiret = MsiViewFetch(hView, &hRecord); if (ERROR_SUCCESS != msiret) { _RPT0(_CRT_ERROR, "MsiViewFetch failed\n"); return ERROR_INSTALL_FAILURE; } msiret = MsiViewModify(hView, MSIMODIFY_DELETE, hRecord); if (ERROR_SUCCESS != msiret) { _RPT0(_CRT_ERROR, "MsiViewModify failed\n"); return ERROR_INSTALL_FAILURE; } UINT nFields = MsiRecordGetFieldCount(hRecord); AutoProcessHeapPtr<LPTSTR> buffer; DWORD chBuffer = 0; msiret = MsiRecordGetString(hRecord, 10, _T(""), &chBuffer); if (ERROR_MORE_DATA == msiret) { ++chBuffer; buffer = (LPTSTR) ::HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, chBuffer * sizeof(TCHAR)); msiret = MsiRecordGetString(hRecord, 1, buffer, &chBuffer); } msiret = MsiRecordSetStringA(hRecord, 10, lpEula); if (ERROR_SUCCESS != msiret) { _RPT0(_CRT_ERROR, "MsiRecordSetString failed\n"); return ERROR_INSTALL_FAILURE; } msiret = MsiViewModify(hView, MSIMODIFY_INSERT_TEMPORARY, hRecord); if (ERROR_SUCCESS != msiret) { _RPT0(_CRT_ERROR, "MsiViewModify failed\n"); return ERROR_INSTALL_FAILURE; } //msiret = MsiViewExecute(hView, hRecord); //if (ERROR_SUCCESS != msiret) //{ // return ERROR_INSTALL_FAILURE; //} _RPT0(_CRT_WARN, "ReplaceEula completed successfully.\n"); return ERROR_SUCCESS; }
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; }
MSICA_IMP ReplaceEula(MSIHANDLE hInstall) { // ::DebugBreak(); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); // // EULA File Content is MBCS (RTF) not Unicode // XTL::AutoProcessHeapPtr<CHAR> lpEula = pReadEulaFromFile(hInstall); if (NULL == (LPSTR) lpEula) { pMsiLogMessage( hInstall, _T("EULACA: ReadEulaFromFile failed, error=0x%X"), GetLastError()); return ERROR_INSTALL_FAILURE; } // // Replacing EULA text control in the database // PMSIHANDLE hDatabase = MsiGetActiveDatabase(hInstall); if (0 == hDatabase) { pMsiLogMessage( hInstall, _T("EULACA: MsiGetActiveDatabase failed, error=0x%X"), GetLastError()); return ERROR_INSTALL_FAILURE; } PMSIHANDLE hView; LPCTSTR query = _T("SELECT * FROM `Control` ") _T(" WHERE `Dialog_` = 'LicenseAgreement' AND `Control` = 'Memo' "); UINT ret = MsiDatabaseOpenView(hDatabase, query, &hView); if (ERROR_SUCCESS != ret) { pMsiLogMessage( hInstall, _T("EULACA: MsiDatabaseOpenView failed, error=0x%X"), ret); return ERROR_INSTALL_FAILURE; } ret = MsiViewExecute(hView, 0); if (ERROR_SUCCESS != ret) { pMsiLogMessage( hInstall, _T("EULACA: MsiViewExecute failed, error=0x%X"), ret); return ERROR_INSTALL_FAILURE; } PMSIHANDLE hRecord; ret = MsiViewFetch(hView, &hRecord); if (ERROR_SUCCESS != ret) { pMsiLogMessage( hInstall, _T("EULACA: MsiViewFetch failed, error=0x%X"), ret); return ERROR_INSTALL_FAILURE; } ret = MsiViewModify(hView, MSIMODIFY_DELETE, hRecord); if (ERROR_SUCCESS != ret) { pMsiLogMessage( hInstall, _T("EULACA: MsiViewModify failed, error=0x%X"), ret); return ERROR_INSTALL_FAILURE; } // // 10th field is the Text column // // Dialog_, Control, Type, X, Y, // Width, Height, Attributes, Property, Text // Control_Next, Help // ret = MsiRecordSetStringA(hRecord, 10, lpEula); if (ERROR_SUCCESS != ret) { pMsiLogMessage( hInstall, _T("EULACA: MsiRecordSetString failed, error=0x%X"), ret); return ERROR_INSTALL_FAILURE; } // // Commit the changes temporarily // ret = MsiViewModify(hView, MSIMODIFY_INSERT_TEMPORARY, hRecord); if (ERROR_SUCCESS != ret) { pMsiLogMessage( hInstall, _T("EULACA: MsiViewModify failed, error=0x%X"), ret); return ERROR_INSTALL_FAILURE; } pMsiLogMessage( hInstall, _T("EULACA: EULA is replaced successfully.")); return ERROR_SUCCESS; }
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; }