Andrew Eikum : msi: Publish icons into the correct directory.
Alexandre Julliard
julliard at winehq.org
Mon May 31 11:21:35 CDT 2010
Module: wine
Branch: master
Commit: beb0b2bc050faeee5b6afba0bc7829d1cbbc8603
URL: http://source.winehq.org/git/wine.git/?a=commit;h=beb0b2bc050faeee5b6afba0bc7829d1cbbc8603
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Fri May 28 14:52:52 2010 -0500
msi: Publish icons into the correct directory.
---
dlls/msi/helpers.c | 18 +++++--
dlls/msi/tests/install.c | 129 ++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 139 insertions(+), 8 deletions(-)
diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c
index 54d2199..d3f2d90 100644
--- a/dlls/msi/helpers.c
+++ b/dlls/msi/helpers.c
@@ -41,13 +41,23 @@ LPWSTR build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name )
{
LPWSTR SystemFolder, dest, FilePath;
+ static const WCHAR szMicrosoft[] =
+ {'M','i','c','r','o','s','o','f','t','\\',0};
static const WCHAR szInstaller[] =
- {'M','i','c','r','o','s','o','f','t','\\',
- 'I','n','s','t','a','l','l','e','r','\\',0};
- static const WCHAR szFolder[] =
+ {'I','n','s','t','a','l','l','e','r','\\',0};
+ static const WCHAR szADFolder[] =
{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+ static const WCHAR szWFolder[] =
+ {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
- SystemFolder = msi_dup_property( package->db, szFolder );
+ if(package->Context == MSIINSTALLCONTEXT_MACHINE)
+ SystemFolder = msi_dup_property( package->db, szWFolder );
+ else
+ {
+ LPWSTR ADTgt = msi_dup_property( package->db, szADFolder );
+ SystemFolder = build_directory_name(2, ADTgt, szMicrosoft);
+ msi_free(ADTgt);
+ }
dest = build_directory_name(3, SystemFolder, szInstaller, package->ProductCode);
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index f3410f6..22309c2 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -30,6 +30,7 @@
#include <fci.h>
#include <objidl.h>
#include <srrestoreptapi.h>
+#include <shlobj.h>
#include "wine/test.h"
@@ -56,6 +57,8 @@ static const char *mstfile = "winetest.mst";
static CHAR CURR_DIR[MAX_PATH];
static CHAR PROG_FILES_DIR[MAX_PATH];
static CHAR COMMON_FILES_DIR[MAX_PATH];
+static CHAR APP_DATA_DIR[MAX_PATH];
+static CHAR WINDOWS_DIR[MAX_PATH];
/* msi database data */
@@ -209,6 +212,28 @@ static const CHAR aup2_property_dat[] = "Property\tValue\n"
"SERVNAME\tTestService\n"
"SERVDISP\tTestServiceDisp\n";
+static const CHAR icon_property_dat[] = "Property\tValue\n"
+ "s72\tl0\n"
+ "Property\tProperty\n"
+ "DefaultUIFont\tDlgFont8\n"
+ "HASUIRUN\t0\n"
+ "INSTALLLEVEL\t3\n"
+ "InstallMode\tTypical\n"
+ "Manufacturer\tWine\n"
+ "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n"
+ "ProductCode\t{7DF88A49-996F-4EC8-A022-BF956F9B2CBB}\n"
+ "ProductID\tnone\n"
+ "ProductLanguage\t1033\n"
+ "ProductName\tMSITEST\n"
+ "ProductVersion\t1.1.1\n"
+ "PROMPTROLLBACKCOST\tP\n"
+ "Setup\tSetup\n"
+ "UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
+ "AdminProperties\tPOSTADMIN\n"
+ "ROOTDRIVE\tC:\\\n"
+ "SERVNAME\tTestService\n"
+ "SERVDISP\tTestServiceDisp\n";
+
static const CHAR shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
"s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n"
"Shortcut\tShortcut\n"
@@ -2893,6 +2918,18 @@ static const msi_table fo_tables[] =
ADD_TABLE(property)
};
+static const msi_table icon_base_tables[] =
+{
+ ADD_TABLE(ci_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(rof_feature),
+ ADD_TABLE(rof_feature_comp),
+ ADD_TABLE(rof_file),
+ ADD_TABLE(pp_install_exec_seq),
+ ADD_TABLE(rof_media),
+ ADD_TABLE(icon_property),
+};
+
/* cabinet definitions */
/* make the max size large so there is only one cab file */
@@ -3179,7 +3216,18 @@ static void create_cab_file(const CHAR *name, DWORD max_size, const CHAR *files)
ok(res, "Failed to destroy the cabinet\n");
}
-static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
+static BOOL get_user_dirs(void)
+{
+ HRESULT hres;
+
+ hres = SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, 0, APP_DATA_DIR);
+ if(FAILED(hres))
+ return FALSE;
+
+ return TRUE;
+}
+
+static BOOL get_system_dirs(void)
{
HKEY hkey;
DWORD type, size;
@@ -3189,18 +3237,22 @@ static BOOL get_program_files_dir(LPSTR buf, LPSTR buf2)
return FALSE;
size = MAX_PATH;
- if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size)) {
+ if (RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)PROG_FILES_DIR, &size)) {
RegCloseKey(hkey);
return FALSE;
}
size = MAX_PATH;
- if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size)) {
+ if (RegQueryValueExA(hkey, "CommonFilesDir", 0, &type, (LPBYTE)COMMON_FILES_DIR, &size)) {
RegCloseKey(hkey);
return FALSE;
}
RegCloseKey(hkey);
+
+ if(GetWindowsDirectoryA(WINDOWS_DIR, MAX_PATH) != ERROR_SUCCESS)
+ return FALSE;
+
return TRUE;
}
@@ -9369,6 +9421,73 @@ static void test_register_mime_info(void)
delete_test_files();
}
+static void test_icon_table(void)
+{
+ MSIHANDLE hdb = 0, record;
+ LPCSTR query;
+ UINT res;
+ CHAR path[MAX_PATH];
+ static const char prodcode[] = "{7DF88A49-996F-4EC8-A022-BF956F9B2CBB}";
+
+ create_database(msifile, icon_base_tables, sizeof(icon_base_tables) / sizeof(msi_table));
+
+ res = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb);
+ ok(res == ERROR_SUCCESS, "failed to open db: %d\n", res);
+
+ query = "CREATE TABLE `Icon` (`Name` CHAR(72) NOT NULL, `Data` OBJECT NOT NULL PRIMARY KEY `Name`)";
+ res = run_query( hdb, 0, query );
+ ok(res == ERROR_SUCCESS, "Can't create Icon table: %d\n", res);
+
+ create_file("icon.ico", 100);
+ record = MsiCreateRecord(1);
+ res = MsiRecordSetStream(record, 1, "icon.ico");
+ ok(res == ERROR_SUCCESS, "Failed to add stream data to record: %d\n", res);
+ DeleteFile("icon.ico");
+
+ query = "INSERT INTO `Icon` (`Name`, `Data`) VALUES ('testicon', ?)";
+ res = run_query(hdb, record, query);
+ ok(res == ERROR_SUCCESS, "Insert into Icon table failed: %d\n", res);
+
+ res = MsiCloseHandle(record);
+ ok(res == ERROR_SUCCESS, "Failed to close record handle: %d\n", res);
+ res = MsiDatabaseCommit(hdb);
+ ok(res == ERROR_SUCCESS, "Failed to commit database: %d\n", res);
+ res = MsiCloseHandle(hdb);
+ ok(res == ERROR_SUCCESS, "Failed to close database: %d\n", res);
+
+ /* per-user */
+ res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1");
+ ok(res == ERROR_SUCCESS, "Failed to do per-user install: %d\n", res);
+
+ lstrcpyA(path, APP_DATA_DIR);
+ lstrcatA(path, "\\");
+ lstrcatA(path, "Microsoft\\Installer\\");
+ lstrcatA(path, prodcode);
+ lstrcatA(path, "\\testicon");
+ ok(file_exists(path), "Per-user icon file isn't where it's expected (%s)\n", path);
+
+ res = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(res == ERROR_SUCCESS, "Failed to uninstall per-user\n");
+
+ /* system-wide */
+ res = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 ALLUSERS=1");
+ ok(res == ERROR_SUCCESS, "Failed to system-wide install: %d\n", res);
+
+ lstrcpyA(path, WINDOWS_DIR);
+ lstrcatA(path, "\\");
+ lstrcatA(path, "Installer\\");
+ lstrcatA(path, prodcode);
+ lstrcatA(path, "\\testicon");
+ ok(file_exists(path), "System-wide icon file isn't where it's expected (%s)\n", path);
+
+ res = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(res == ERROR_SUCCESS, "Failed to uninstall system-wide\n");
+
+ delete_pfmsitest_files();
+
+ DeleteFile(msifile);
+}
+
START_TEST(install)
{
DWORD len;
@@ -9390,7 +9509,8 @@ START_TEST(install)
if(len && (CURR_DIR[len - 1] == '\\'))
CURR_DIR[len - 1] = 0;
- get_program_files_dir(PROG_FILES_DIR, COMMON_FILES_DIR);
+ get_system_dirs();
+ get_user_dirs();
/* Create a restore point ourselves so we circumvent the multitude of restore points
* that would have been created by all the installation and removal tests.
@@ -9479,6 +9599,7 @@ START_TEST(install)
test_register_class_info();
test_register_extension_info();
test_register_mime_info();
+ test_icon_table();
DeleteFileA(log_file);
More information about the wine-cvs
mailing list