Example #1
0
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;
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
0
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;
}
Example #5
0
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;
}