Ejemplo n.º 1
0
static void test_AddERExcludedApplicationA(void)
{
    BOOL res;
    LONG lres;
    HKEY hroot;
    HKEY hexclude = 0;

    /* clean state */
    lres = RegCreateKeyA(HKEY_LOCAL_MACHINE, regpath_root, &hroot);
    if (lres == ERROR_ACCESS_DENIED)
    {
        skip("Not enough access rights\n");
        return;
    }

    if (!lres)
        lres = RegOpenKeyA(hroot, regpath_exclude, &hexclude);

    if (!lres)
        RegDeleteValueA(hexclude, "winetest_faultrep.exe");


    SetLastError(0xdeadbeef);
    res = AddERExcludedApplicationA(NULL);
    ok(!res, "got %d and 0x%x (expected FALSE)\n", res, GetLastError());

    SetLastError(0xdeadbeef);
    res = AddERExcludedApplicationA("");
    ok(!res, "got %d and 0x%x (expected FALSE)\n", res, GetLastError());

    SetLastError(0xdeadbeef);
    /* existence of the path doesn't matter this function succeeded */
    res = AddERExcludedApplicationA("winetest_faultrep.exe");
    if (is_process_limited())
    {
        /* LastError is not set! */
        ok(!res, "AddERExcludedApplicationA should have failed got %d\n", res);
    }
    else
    {
        ok(res, "AddERExcludedApplicationA failed (le=0x%x)\n", GetLastError());

        /* add, when already present */
        SetLastError(0xdeadbeef);
        res = AddERExcludedApplicationA("winetest_faultrep.exe");
        ok(res, "AddERExcludedApplicationA failed (le=0x%x)\n", GetLastError());
    }

    /* cleanup */
    RegDeleteValueA(hexclude, "winetest_faultrep.exe");

    RegCloseKey(hexclude);
    RegCloseKey(hroot);
}
Ejemplo n.º 2
0
static void test_regcat(void)
{
    unsigned char b;
    HRESULT hres;

    const struct _ATL_CATMAP_ENTRY catmap[] = {
        {_ATL_CATMAP_ENTRY_IMPLEMENTED, &CATID_CatTest1},
        {_ATL_CATMAP_ENTRY_REQUIRED, &CATID_CatTest2},
        {_ATL_CATMAP_ENTRY_END}
    };

    if (is_process_limited())
    {
        skip("process is limited\n");
        return;
    }

    hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, catmap, TRUE);
    ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);

    test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");
    test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Implemented Categories\\{" CATID_CATTEST1_STR "}");
    test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Required Categories\\{" CATID_CATTEST2_STR "}");

    hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, catmap, FALSE);
    ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);

    test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Implemented Categories");
    test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Required Categories");
    test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");

    ok(RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}") == ERROR_SUCCESS, "Could not delete key\n");

    hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, NULL, TRUE);
    ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);

    test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");

    b = 10;
    hres = AtlGetPerUserRegistration(&b);
    ok(hres == S_OK, "AtlGetPerUserRegistration failed: %08x\n", hres);
    ok(!b, "AtlGetPerUserRegistration returned %x\n", b);
}
Ejemplo n.º 3
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" );
}
Ejemplo n.º 4
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" );
}
Ejemplo n.º 5
0
static void test_patch_registration( void )
{
    UINT r, size;
    char buffer[MAX_PATH], patch_code[39];

    if (!pMsiApplyPatchA || !pMsiGetPatchInfoExA || !pMsiEnumPatchesExA)
    {
        win_skip("required functions 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 = 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;
    }

    buffer[0] = 0;
    size = sizeof(buffer);
    r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
                             "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
                              NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
                              INSTALLPROPERTY_LOCALPACKAGE, buffer, &size );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
    ok( buffer[0], "buffer empty\n" );

    buffer[0] = 0;
    size = sizeof(buffer);
    r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
                             "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
                             NULL, MSIINSTALLCONTEXT_MACHINE,
                             INSTALLPROPERTY_LOCALPACKAGE, buffer, &size );
    ok( r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r );

    buffer[0] = 0;
    size = sizeof(buffer);
    r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
                             "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
                             INSTALLPROPERTY_LOCALPACKAGE, buffer, &size );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
    ok( !buffer[0], "got %s\n", buffer );

    r = pMsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
                           NULL, MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_APPLIED,
                           0, patch_code, NULL, NULL, NULL, NULL );
    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
    ok( !strcmp( patch_code, "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}" ), "wrong patch code\n" );

    r = pMsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
                           NULL, MSIINSTALLCONTEXT_MACHINE, MSIPATCHSTATE_APPLIED,
                           0, patch_code, NULL, NULL, NULL, NULL );
    ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );

    r = pMsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
                           NULL, MSIINSTALLCONTEXT_USERMANAGED, MSIPATCHSTATE_APPLIED,
                           0, patch_code, NULL, NULL, NULL, NULL );
    ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );

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

    buffer[0] = 0;
    size = sizeof(buffer);
    r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
                             "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
                              NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
                              INSTALLPROPERTY_LOCALPACKAGE, buffer, &size );
    ok( r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r );

cleanup:
    DeleteFileA( msifile );
    DeleteFileA( mspfile );
    DeleteFileA( "msitest\\patch.txt" );
    RemoveDirectoryA( "msitest" );
}