Esempio n. 1
0
void GetMsiProperty (MSIHANDLE hModule, char* propertyValue, char* propertyName) {
    if(!propertyName)
        return;

    MSIHANDLE hRecord, hView, hDatabase;

    // get hView & hDatabase
    hDatabase = MsiGetActiveDatabase(hModule);
    char pSelectSql[256] = {0};
    sprintf(pSelectSql, "select * from Property where `Property`='%s'", propertyName);

    MsiDatabaseOpenView(hDatabase, pSelectSql, &hView);
    MsiViewExecute(hView, NULL);

    DWORD dwLength = 256;
    if (MsiViewFetch(hView, &hRecord) != ERROR_SUCCESS)
        return;
    MsiRecordGetString(hRecord, 2, propertyValue, &dwLength);

    // close all handles
    MsiCloseHandle(hRecord);
    MsiViewClose(hView);
    MsiCloseHandle(hView);
    MsiCloseHandle(hDatabase);
}
Esempio n. 2
0
File: msidb.c Progetto: CaoMomo/core
/***********************************************************************
 * msidbExportStream
 *
 * Exports a stream to a file with an .idb extension.
 *
 * Examples (note wildcard escape for *nix/bash):
 * msidb -d <pathtomsi>.msi -f <workdir> -x <streamname>
 * msidb -d <pathtomsi>.msi -f <workdir> -x data.cab
 **********************************************************************/
static BOOL msidbExportStream(LPCWSTR dbfile, LPCWSTR wdir, LPCWSTR streamName)
{
    static const char ext[] = {'.', 'i', 'd', 'b', 0};
    UINT r, len;
    MSIHANDLE dbhandle, streamListView, rec;
    char queryBuffer[100];
    FILE *fp = 0;
    char *streamNameA = strdupWtoA(CP_ACP, streamName);
    char *wdirA = strdupWtoA(CP_ACP, wdir);
    char *streamFileA = 0;
    char streamPath[MAX_PATH];
    char *dataBuffer;
    DWORD dataLen = 0;

    r = MsiOpenDatabaseW(dbfile, (LPCWSTR) MSIDBOPEN_READONLY, &dbhandle);
    if (r != ERROR_SUCCESS) return FALSE;

    sprintf(queryBuffer, "SELECT * FROM _Streams WHERE Name = '%s'", streamNameA);
    MsiDatabaseOpenView(dbhandle, queryBuffer, &streamListView);
    MsiViewExecute(streamListView, 0);
    r = MsiViewFetch(streamListView, &rec);
    if (r != ERROR_SUCCESS) return FALSE;

    if (MsiRecordReadStream(rec, 2, 0, &dataLen) != ERROR_SUCCESS)
        return FALSE;
    dataBuffer = malloc(dataLen);
    if (!dataBuffer) return FALSE;
    if (MsiRecordReadStream(rec, 2, dataBuffer, &dataLen) != ERROR_SUCCESS)
        return FALSE;

    len = strlen(streamNameA) + 5;
    streamFileA = malloc(len);
    if (streamFileA == NULL) return FALSE;

    strcpy(streamFileA, streamNameA);
    strcat(streamFileA, ext);

    strcpy(streamPath, wdirA);
    strcat(streamPath, PATH_DELIMITER);
    strcat(streamPath, streamFileA);

    fp = fopen(streamPath , "wb");
    if (fp != NULL)
    {
        fwrite(dataBuffer, 1, dataLen, fp);
        fclose(fp);
    }

    free(streamFileA);
    MsiCloseHandle(rec);

    MsiViewClose(streamListView);
    MsiCloseHandle(streamListView);
    MsiCloseHandle(dbhandle);
    free(wdirA);
    free(streamNameA);
    return TRUE;
}
Esempio n. 3
0
File: msidb.c Progetto: CaoMomo/core
static BOOL msidbExportStorage(LPCWSTR dbfile, LPCWSTR wdir, LPWSTR storageName)
{
    UINT r, len;
    MSIHANDLE dbhandle, view, rec;
    char queryBuffer[100];
    char *storageNameA = strdupWtoA(CP_ACP, storageName);
    char *wdirA = strdupWtoA(CP_ACP, wdir);
    char *storagePath = NULL;
    char *dataBuffer;
    DWORD dataLen = 0;
    FILE *fp = NULL;
    sprintf(queryBuffer, "SELECT * FROM _Storages WHERE Name = '%s'", storageNameA);

    r = MsiOpenDatabaseW(dbfile, (LPWSTR) MSIDBOPEN_READONLY, &dbhandle);
    if (r != ERROR_SUCCESS) return FALSE;

    MsiDatabaseOpenView(dbhandle, queryBuffer, &view);
    MsiViewExecute(view, 0);
    r = MsiViewFetch(view, &rec);
    if (r != ERROR_SUCCESS) return FALSE;

    if ((r = MsiRecordReadStream(rec, 2, 0, &dataLen)) != ERROR_SUCCESS)
    {
        return FALSE;
    }

    if ((dataBuffer = malloc(dataLen)) == NULL) return FALSE;
    if (MsiRecordReadStream(rec, 2, dataBuffer, &dataLen) != ERROR_SUCCESS) return FALSE;

    len = strlen(wdirA) + strlen(storageNameA) + 2;
    storagePath = malloc(len * sizeof(WCHAR));
    if (storagePath == NULL) return FALSE;

    strcpy(storagePath, wdirA);
    strcat(storagePath, "/");
    strcat(storagePath, storageNameA);

    fp = fopen(storagePath , "wb");
    if (fp != NULL)
    {
        fwrite(dataBuffer, 1, dataLen, fp);
        fclose(fp);
    }

    free(storagePath);
    MsiCloseHandle(rec);

    MsiViewClose(view);
    MsiCloseHandle(view);
    MsiCloseHandle(dbhandle);
    free(storageNameA);
    free(wdirA);
    return TRUE;
}
Esempio n. 4
0
File: msidb.c Progetto: CaoMomo/core
static BOOL msidbImportStorages(LPCWSTR dbfile, LPCWSTR wdir, LPWSTR storageNames[])
{
    static const WCHAR delim[] = {'/', 0};
    UINT r, len, i;
    MSIHANDLE dbhandle, view, rec;
    WCHAR *storagePath = 0;
    char *query = "INSERT INTO _Storages (Name, Data) VALUES(?, ?)";

    r = MsiOpenDatabaseW(dbfile, (LPWSTR) MSIDBOPEN_TRANSACT, &dbhandle);
    if (r != ERROR_SUCCESS) return FALSE;

    r = MsiDatabaseOpenView(dbhandle, query, &view);
    if (r != ERROR_SUCCESS) return FALSE;
    MsiViewExecute(view, 0);
    r = MsiViewFetch(view, &rec);
    if (r != ERROR_SUCCESS) return FALSE;

    for (i = 0; i < MAX_STORAGES && storageNames[i] != 0; ++i)
    {
        len = lstrlenW(wdir) + lstrlenW(storageNames[i]) + 2;
        storagePath = malloc(len * sizeof(WCHAR));
        if (storagePath == NULL) return FALSE;

        lstrcpyW(storagePath, wdir);
        lstrcatW(storagePath, delim);
        lstrcatW(storagePath, storageNames[i]);

        rec = MsiCreateRecord(2);
        MsiRecordSetStringW(rec, 1, storageNames[i]);
        r = MsiRecordSetStreamW(rec, 2, storagePath);
        if (r != ERROR_SUCCESS)
        {
            return FALSE;
        }

        r = MsiViewExecute(view, rec);
        if (r != ERROR_SUCCESS)
        {
            return FALSE;
        }

        MsiCloseHandle(rec);
    }

    MsiViewClose(view);
    MsiCloseHandle(view);
    MsiDatabaseCommit(dbhandle);
    MsiCloseHandle(dbhandle);
    return TRUE;
}
Esempio n. 5
0
File: msidb.c Progetto: CaoMomo/core
static BOOL msidbImportStreams(LPCWSTR dbfile, LPCWSTR wdir, LPWSTR streamNames[])
{
    UINT r, len;
    MSIHANDLE dbhandle, view, rec;
    int i = 0;
    WCHAR *streamPath = 0;
    char *query = "INSERT INTO _Streams (Name, Data) VALUES(?, ?)";

    r = MsiOpenDatabaseW(dbfile, (LPWSTR) MSIDBOPEN_TRANSACT, &dbhandle);
    if (r != ERROR_SUCCESS) return FALSE;

    r = MsiDatabaseOpenView(dbhandle, query, &view);
    if (r != ERROR_SUCCESS) return FALSE;

    for (i = 0; i < MAX_STREAMS && streamNames[i] != NULL; i++)
    {
        len = lstrlenW(wdir) + lstrlenW(streamNames[i]) + 2;
        streamPath = malloc(len * sizeof(WCHAR));
        if (streamPath == NULL) return FALSE;

        lstrcpyW(streamPath, wdir);
        lstrcatW(streamPath, PATH_DELIMITERW);
        lstrcatW(streamPath, streamNames[i]);

        rec = MsiCreateRecord(2);
        MsiRecordSetStringW(rec, 1, streamNames[i]);
        r = MsiRecordSetStreamW(rec, 2, streamPath);
        if (r != ERROR_SUCCESS)
        {
            return FALSE;
        }

        r = MsiViewExecute(view, rec);
        if (r != ERROR_SUCCESS)
        {
            return FALSE;
        }

        MsiCloseHandle(rec);
    }

    MsiViewClose(view);
    MsiCloseHandle(view);
    MsiDatabaseCommit(dbhandle);
    MsiCloseHandle(dbhandle);
    return TRUE;
}
Esempio n. 6
0
/**
 * Extracts the jar file from the MSI database binary field
 *
 * @param hModule Specify the handle for the MSI database
 */
void ExtractBinaryFile (MSIHANDLE hModule, const char* pFieldName, const char* pDstFileName) {
    char cSelectSql[MAX_PATH_SIZE] = {0};
    MSIHANDLE hRecord, hView, hDatabase;

    // get hView & hDatabase
    hDatabase = MsiGetActiveDatabase(hModule);
    sprintf(cSelectSql, "select * from Binary where `Name`='%s'", pFieldName);
    MsiDatabaseOpenView(hDatabase, cSelectSql, &hView);
    MsiViewExecute(hView, NULL);
    char szTemp[256] = {0};
    DWORD dwLength = 256;
    if (MsiViewFetch(hView, &hRecord) != ERROR_SUCCESS)
    {
        return;
    }
    MsiRecordGetString(hRecord, 1, szTemp, &dwLength);
    if (strncmp(szTemp, pFieldName, strlen(pFieldName)))
    {
        return;
    }
    // write into installer.jar
    #define BUFFERSIZE 1024
    char  szBuffer[BUFFERSIZE] = {0};
    DWORD cbBuf = BUFFERSIZE;
    DWORD countWrite = 0;

    FILE* fp = NULL;
    fp = fopen(pDstFileName, "wb+");
    if (NULL == fp) {
        return;
    }

    do {
        if (MsiRecordReadStream(hRecord, 2, szBuffer, &cbBuf) !=ERROR_SUCCESS)
            break; // error 
        countWrite = fwrite(szBuffer, 1, cbBuf, fp);
    } while (countWrite == BUFFERSIZE);

    fclose(fp);

    // close all handles
    MsiCloseHandle(hRecord);
    MsiViewClose(hView);
    MsiCloseHandle(hView);
    MsiCloseHandle(hDatabase);
}
Esempio n. 7
0
static UINT find_entry( MSIHANDLE hdb, const char *table, const char *entry )
{
    static char fmt[] = "SELECT * FROM `%s` WHERE `Name` = '%s'";
    char query[0x100];
    UINT r;
    MSIHANDLE hview, hrec;

    sprintf( query, fmt, table, entry );
    r = MsiDatabaseOpenView( hdb, query, &hview );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewExecute( hview, 0 );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewFetch( hview, &hrec );
    MsiViewClose( hview );
    MsiCloseHandle( hview );
    MsiCloseHandle( hrec );
    return r;
}
Esempio n. 8
0
File: msidb.c Progetto: CaoMomo/core
/***********************************************************************
 * msidbExportTables
 *
 * Takes a list of tables or '*' (for all) to export to text archive
 * files in specified folder
 *
 * For each table, a file called <tablename>.idt is exported containing
 * tab separated ASCII.
 *
 * Examples (note wildcard escape for *nix/bash):
 * msidb -d <pathtomsi>.msi -f <workdir> -e \*
 * msidb -d <pathtomsi>.msi -f <workdir> -e File Directory Binary
 **********************************************************************/
static BOOL msidbExportTables(LPCWSTR dbfile, LPCWSTR wdir, LPWSTR tables[])
{
    static const WCHAR ext[] = {'.', 'i', 'd', 't', 0};
    static const WCHAR all[] = {'*', 0};
    UINT r, len;
    MSIHANDLE dbhandle, tableListView, rec;
    LPWSTR tableFile = 0;
    WCHAR tableName[MAX_TABLE_NAME];
    DWORD size = sizeof(tableName) / sizeof(tableName[0]);
    int i = 0;

    r = MsiOpenDatabaseW(dbfile, (LPCWSTR) MSIDBOPEN_READONLY, &dbhandle);

    if (r != ERROR_SUCCESS) return FALSE;

    if (strcmpW(tables[0], all) == 0)
    {
        r = MsiDatabaseOpenView(dbhandle, "SELECT Name FROM _Tables", &tableListView);
        r = MsiViewExecute(tableListView, 0);
        r = MsiViewFetch(tableListView, &rec);

        while (r == ERROR_SUCCESS)
        {
            size = sizeof(tableName) / sizeof(tableName[0]);
            r = MsiRecordGetStringW(rec, 1, tableName, &size);
            if (r == ERROR_SUCCESS)
            {
                len = lstrlenW(tableName) + 5;
                tableFile = malloc(len * sizeof (WCHAR));
                if (tableFile == NULL) return FALSE;

                lstrcpyW(tableFile, tableName);
                lstrcatW(tableFile, ext);

                r = MsiDatabaseExportW(dbhandle, tableName, wdir, tableFile);

                free(tableFile);
                MsiCloseHandle(rec);
            }

            r = MsiViewFetch(tableListView, &rec);
        }

        MsiViewClose(tableListView);
        MsiCloseHandle(tableListView);
    }
    else
    {
        for (i = 0; i < MAX_TABLES && tables[i] != 0; ++i)
        {
            len = lstrlenW(tables[i]) + 5;
            tableFile = malloc(len * sizeof (WCHAR));
            if (tableFile == NULL) return FALSE;

            lstrcpyW(tableFile, tables[i]);
            lstrcatW(tableFile, ext);
            r = MsiDatabaseExportW(dbhandle, tables[i], wdir, tableFile);

            free(tableFile);
        }
    }

    MsiCloseHandle(dbhandle);
    return TRUE;
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
static void test_system_tables( void )
{
    UINT r;
    const char *query;
    MSIHANDLE hproduct, hdb, hview, hrec;

    if (!pMsiApplyPatchA)
    {
        win_skip("MsiApplyPatchA is not available\n");
        return;
    }
    if (is_process_limited())
    {
        skip("process is limited\n");
        return;
    }

    CreateDirectoryA( "msitest", NULL );
    create_file( "msitest\\patch.txt", 1000 );

    create_database( msifile, tables, sizeof(tables) / sizeof(struct msi_table) );
    create_patch( mspfile );

    MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );

    r = MsiInstallProductA( msifile, NULL );
    if (r != ERROR_SUCCESS)
    {
        skip("Product installation failed with error code %d\n", r);
        goto cleanup;
    }

    r = MsiOpenProductA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", &hproduct );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    hdb = MsiGetActiveDatabase( hproduct );
    ok( hdb, "failed to get database handle\n" );

    r = find_entry( hdb, "_Streams", "\5SummaryInformation" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    query = "SELECT * FROM `_Storages`";
    r = MsiDatabaseOpenView( hdb, query, &hview );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewExecute( hview, 0 );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewFetch( hview, &hrec );
    ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );

    r = find_entry( hdb, "_Tables", "Directory" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "File" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "Component" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "Feature" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "FeatureComponents" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "Property" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "InstallExecuteSequence" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "Media" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "_Property" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    MsiCloseHandle( hrec );
    MsiViewClose( hview );
    MsiCloseHandle( hview );
    MsiCloseHandle( hdb );
    MsiCloseHandle( hproduct );

    r = MsiApplyPatchA( mspfile, NULL, INSTALLTYPE_DEFAULT, NULL );
    ok( r == ERROR_SUCCESS || broken( r == ERROR_PATCH_PACKAGE_INVALID ), /* version 2.0 */
        "expected ERROR_SUCCESS, got %u\n", r );

    if (r == ERROR_PATCH_PACKAGE_INVALID)
    {
        win_skip("Windows Installer < 3.0 detected\n");
        goto uninstall;
    }

    r = MsiOpenProductA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", &hproduct );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    hdb = MsiGetActiveDatabase( hproduct );
    ok( hdb, "failed to get database handle\n" );

    r = find_entry( hdb, "_Streams", "\5SummaryInformation" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    query = "SELECT * FROM `_Storages`";
    r = MsiDatabaseOpenView( hdb, query, &hview );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewExecute( hview, 0 );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewFetch( hview, &hrec );
    ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );

    r = find_entry( hdb, "_Tables", "Directory" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "File" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "Component" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "Feature" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "FeatureComponents" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "Property" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "InstallExecuteSequence" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "Media" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "_Property" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "MsiPatchHeaders" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "Patch" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    r = find_entry( hdb, "_Tables", "PatchPackage" );
    ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );

    MsiCloseHandle( hrec );
    MsiViewClose( hview );
    MsiCloseHandle( hview );
    MsiCloseHandle( hdb );
    MsiCloseHandle( hproduct );

uninstall:
    r = MsiInstallProductA( msifile, "REMOVE=ALL" );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

cleanup:
    DeleteFileA( msifile );
    DeleteFileA( mspfile );
    DeleteFileA( "msitest\\patch.txt" );
    RemoveDirectoryA( "msitest" );
}
Esempio n. 11
0
static void test_simple_patch( void )
{
    UINT r;
    DWORD size;
    char path[MAX_PATH], install_source[MAX_PATH], buffer[32];
    const char *query;
    MSIHANDLE hpackage, hdb, hview, hrec;

    if (!pMsiApplyPatchA)
    {
        win_skip("MsiApplyPatchA is not available\n");
        return;
    }
    if (is_process_limited())
    {
        skip("process is limited\n");
        return;
    }

    CreateDirectoryA( "msitest", NULL );
    create_file( "msitest\\patch.txt", 1000 );

    create_database( msifile, tables, sizeof(tables) / sizeof(struct msi_table) );
    create_patch( mspfile );

    MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );

    r = MsiInstallProductA( msifile, NULL );
    if (r != ERROR_SUCCESS)
    {
        skip("Product installation failed with error code %u\n", r);
        goto cleanup;
    }

    size = get_pf_file_size( "msitest\\patch.txt" );
    ok( size == 1000, "expected 1000, got %u\n", size );

    size = sizeof(install_source);
    r = MsiGetProductInfoA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
                            "InstallSource", install_source, &size );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    strcpy( path, CURR_DIR );
    strcat( path, "\\" );
    strcat( path, msifile );

    r = MsiOpenPackageA( path, &hpackage );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    hdb = MsiGetActiveDatabase( hpackage );
    ok( hdb, "failed to get database handle\n" );

    query = "SELECT * FROM `Property` where `Property` = 'PATCHNEWPACKAGECODE'";
    r = MsiDatabaseOpenView( hdb, query, &hview );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewExecute( hview, 0 );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewFetch( hview, &hrec );
    ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );

    MsiCloseHandle( hrec );
    MsiViewClose( hview );
    MsiCloseHandle( hview );

    query = "SELECT * FROM `Property` WHERE `Property` = 'PATCHNEWSUMMARYSUBJECT' "
            "AND `Value` = 'Installer Database'";
    r = MsiDatabaseOpenView( hdb, query, &hview );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewExecute( hview, 0 );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewFetch( hview, &hrec );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    MsiCloseHandle( hrec );
    MsiViewClose( hview );
    MsiCloseHandle( hview );

    buffer[0] = 0;
    size = sizeof(buffer);
    r = MsiGetProperty( hpackage, "PATCHNEWSUMMARYSUBJECT", buffer, &size );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
    ok( !strcmp( buffer, "Installer Database" ), "expected \'Installer Database\', got \'%s\'\n", buffer );

    MsiCloseHandle( hdb );
    MsiCloseHandle( hpackage );

    r = MsiApplyPatchA( mspfile, NULL, INSTALLTYPE_DEFAULT, NULL );
    ok( r == ERROR_SUCCESS || broken( r == ERROR_PATCH_PACKAGE_INVALID ), /* version 2.0 */
        "expected ERROR_SUCCESS, got %u\n", r );

    if (r == ERROR_PATCH_PACKAGE_INVALID)
    {
        win_skip("Windows Installer < 3.0 detected\n");
        goto uninstall;
    }

    size = get_pf_file_size( "msitest\\patch.txt" );
    ok( size == 1002, "expected 1002, got %u\n", size );

    /* show that MsiOpenPackage applies registered patches */
    r = MsiOpenPackageA( path, &hpackage );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    hdb = MsiGetActiveDatabase( hpackage );
    ok( hdb, "failed to get database handle\n" );

    query = "SELECT * FROM `Property` where `Property` = 'PATCHNEWPACKAGECODE'";
    r = MsiDatabaseOpenView( hdb, query, &hview );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewExecute( hview, 0 );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewFetch( hview, &hrec );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    MsiCloseHandle( hrec );
    MsiViewClose( hview );
    MsiCloseHandle( hview );

    query = "SELECT * FROM `Property` WHERE `Property` = 'PATCHNEWSUMMARYSUBJECT' "
            "AND `Value` = 'Installation Database'";
    r = MsiDatabaseOpenView( hdb, query, &hview );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewExecute( hview, 0 );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewFetch( hview, &hrec );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    MsiCloseHandle( hrec );
    MsiViewClose( hview );
    MsiCloseHandle( hview );

    buffer[0] = 0;
    size = sizeof(buffer);
    r = MsiGetProperty( hpackage, "PATCHNEWSUMMARYSUBJECT", buffer, &size );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
    ok( !strcmp( buffer, "Installation Database" ), "expected \'Installation Database\', got \'%s\'\n", buffer );

    MsiCloseHandle( hdb );
    MsiCloseHandle( hpackage );

    /* show that patches are not committed to the local package database */
    size = sizeof(path);
    r = MsiGetProductInfoA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
                            "LocalPackage", path, &size );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiOpenDatabaseA( path, MSIDBOPEN_READONLY, &hdb );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiDatabaseOpenView( hdb, query, &hview );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewExecute( hview, 0 );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    r = MsiViewFetch( hview, &hrec );
    ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );

    MsiCloseHandle( hrec );
    MsiViewClose( hview );
    MsiCloseHandle( hview );
    MsiCloseHandle( hdb );

uninstall:
    size = sizeof(path);
    r = MsiGetProductInfoA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
                            "InstallSource", path, &size );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
    ok( !strcasecmp( path, install_source ), "wrong path %s\n", path );

    r = MsiInstallProductA( msifile, "REMOVE=ALL" );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );

    ok( !delete_pf( "msitest\\patch.txt", TRUE ), "file not removed\n" );
    ok( !delete_pf( "msitest", FALSE ), "directory not removed\n" );

cleanup:
    DeleteFileA( msifile );
    DeleteFileA( mspfile );
    DeleteFileA( "msitest\\patch.txt" );
    RemoveDirectoryA( "msitest" );
}
Esempio n. 12
0
/////////////////////////////////////////////////////////////////////
// 
// 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;
}