MSI: start implementing MsiOpenPackage
Mike McCormack
mike at codeweavers.com
Tue Jun 29 07:44:50 CDT 2004
ChangeLog:
<aric at codeweavers.com>
* start implementing MsiOpenPackage
-------------- next part --------------
diff -ur dlls/msi.old/Makefile.in dlls/msi/Makefile.in
--- dlls/msi.old/Makefile.in 2004-06-29 07:27:41.000000000 -0500
+++ dlls/msi/Makefile.in 2004-06-29 07:41:17.000000000 -0500
@@ -15,6 +15,7 @@
msi.c \
msiquery.c \
order.c \
+ package.c \
record.c \
regsvr.c \
select.c \
diff -ur dlls/msi.old/action.c dlls/msi/action.c
--- dlls/msi.old/action.c 2004-06-29 07:27:41.000000000 -0500
+++ dlls/msi/action.c 2004-06-29 07:29:03.000000000 -0500
@@ -47,23 +47,6 @@
#define CUSTOM_ACTION_TYPE_MASK 0x3F
-/*
- * These are hacks to get around the inability to write
- * to the database and the inability to select on string values
- * once those values are done then it will be possible to do
- * all this inside the database.
- */
-
-#define MAX_PROP 1024
-
-typedef struct {
- WCHAR *prop_name;
- WCHAR *prop_value;
- } internal_property;
-
-static internal_property PropTableHack[MAX_PROP];
-static INT PropCount = -1;
-
WINE_DEFAULT_DEBUG_CHANNEL(msi);
/*
@@ -83,13 +66,6 @@
static UINT HANDLE_CustomType2(MSIHANDLE hPackage, const LPWSTR source,
const LPWSTR target, const INT type);
-
-static UINT set_property(MSIHANDLE hPackage, const WCHAR* prop,
- const WCHAR* value);
-UINT get_property(MSIHANDLE hPackage, const WCHAR* prop, WCHAR* value,
- DWORD* size);
-static VOID blitz_propertytable();
-static VOID set_installer_properties(MSIHANDLE hPackage);
static DWORD deformat_string(MSIHANDLE hPackage, WCHAR* ptr,WCHAR** data);
/*
@@ -98,7 +74,8 @@
static const WCHAR cszSourceDir[] = {'S','o','u','r','c','e','D','i','r',0};
static const WCHAR cszRootDrive[] = {'R','O','O','T','D','R','I','V','E',0};
static const WCHAR cszTargetDir[] = {'T','A','R','G','E','T','D','I','R',0};
-
+static const WCHAR c_collen[] = {'C',':','\\',0};
+
static const WCHAR cszlsb[]={'[',0};
static const WCHAR cszrsb[]={']',0};
static const WCHAR cszbs[]={'\\',0};
@@ -120,226 +97,6 @@
return ret;
}
-static VOID blitz_propertytable()
-{
- if (PropCount == -1)
- {
- PropCount = 0;
- memset(&PropTableHack,0,sizeof(PropTableHack));
- }
- else if (PropCount > 0)
- {
- int i;
- TRACE("Clearing %i properties\n",PropCount);
- for (i = 0; i < PropCount; i++)
- {
- HeapFree(GetProcessHeap(), 0, PropTableHack[i].prop_name);
- HeapFree(GetProcessHeap(), 0, PropTableHack[i].prop_value);
- }
- memset(&PropTableHack,0,sizeof(PropTableHack));
- PropCount = 0;
- }
-}
-
-UINT get_property(MSIHANDLE hPackage, const WCHAR* prop, WCHAR* value,
- DWORD* size)
-{
- UINT rc = 1;
- int index = 0;
- WCHAR* pName = PropTableHack[0].prop_name;
-
- TRACE("Looking for property %s\n",debugstr_w(prop));
-
- /* prop table hacks take presidence */
-
- while (pName && strcmpW(pName,prop) && index < PropCount)
- {
- index ++;
- pName = PropTableHack[index].prop_name;
- }
-
- if (pName && index < PropCount)
- {
- if (*size > strlenW(PropTableHack[index].prop_value))
- {
- *size = strlenW(PropTableHack[index].prop_value)+1;
- TRACE(" index %i\n", index);
- strcpyW(value , PropTableHack[index].prop_value);
- TRACE(" found value %s\n",debugstr_w(value));
- return 0;
- }
- else
- {
- *size = strlenW(PropTableHack[index].prop_value);
- return ERROR_MORE_DATA;
- }
- }
-
- rc = MsiGetPropertyW(hPackage,prop,value,size);
-
- if (rc == ERROR_SUCCESS)
- TRACE(" found value %s\n",debugstr_w(value));
- else
- TRACE(" value not found\n");
-
- return rc;
-}
-
-static UINT set_property(MSIHANDLE hPackage, const WCHAR* prop,
- const WCHAR* value)
-{
- /* prop table hacks take precedence */
- UINT rc;
- int index = 0;
- WCHAR* pName;
-
- if (PropCount == -1)
- blitz_propertytable();
-
- pName = PropTableHack[0].prop_name;
-
- TRACE("Setting property %s to %s\n",debugstr_w(prop),debugstr_w(value));
-
- while (pName && strcmpW(pName,prop) && index < MAX_PROP)
- {
- index ++;
- pName = PropTableHack[index].prop_name;
- }
-
- if (pName && index < MAX_PROP)
- {
- TRACE("property index %i\n",index);
- strcpyW(PropTableHack[index].prop_value,value);
- return 0;
- }
- else
- {
- if (index >= MAX_PROP)
- {
- ERR("EXCEEDING MAX PROP!!!!\n");
- return ERROR_FUNCTION_FAILED;
- }
- PropTableHack[index].prop_name = HeapAlloc(GetProcessHeap(),0,1024);
- PropTableHack[index].prop_value= HeapAlloc(GetProcessHeap(),0,1024);
- strcpyW(PropTableHack[index].prop_name,prop);
- strcpyW(PropTableHack[index].prop_value,value);
- PropCount++;
- TRACE("new property index %i (%i)\n",index,PropCount);
- return 0;
- }
-
- /* currently unreachable */
- rc = MsiSetPropertyW(hPackage,prop,value);
- return rc;
-}
-
-/*
- * There are a whole slew of these we need to set
- *
- *
-http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/properties.asp
- */
-
-static VOID set_installer_properties(MSIHANDLE hPackage)
-{
- WCHAR pth[MAX_PATH];
-
- static const WCHAR c_col[] =
-{'C',':','\\',0};
- static const WCHAR CFF[] =
-{'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0};
- static const WCHAR PFF[] =
-{'P','r','o','g','r','a','m','F','i','l','e','s','F','o','l','d','e','r',0};
- static const WCHAR CADF[] =
-{'C','o','m','m','o','n','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
- static const WCHAR ATF[] =
-{'A','d','m','i','n','T','o','o','l','s','F','o','l','d','e','r',0};
- static const WCHAR ADF[] =
-{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
- static const WCHAR SF[] =
-{'S','y','s','t','e','m','F','o','l','d','e','r',0};
- static const WCHAR LADF[] =
-{'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
- static const WCHAR MPF[] =
-{'M','y','P','i','c','t','u','r','e','s','F','o','l','d','e','r',0};
- static const WCHAR PF[] =
-{'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
- static const WCHAR WF[] =
-{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
- static const WCHAR TF[]=
-{'T','e','m','p','F','o','l','d','e','r',0};
-
-/* Not yet set ... but needed by iTunes
- *
- static const WCHAR DF[] =
-{'D','e','s','k','t','o','p','F','o','l','d','e','r',0};
- static const WCHAR FF[] =
-{'F','a','v','o','r','i','t','e','s','F','o','l','d','e','r',0};
- static const WCHAR FoF[] =
-{'F','o','n','t','s','F','o','l','d','e','r',0};
-PrimaryVolumePath
-ProgramFiles64Folder
-ProgramMenuFolder
-SendToFolder
-StartMenuFolder
-StartupFolder
-System16Folder
-System64Folder
-TemplateFolder
- */
-
-/* asked for by iTunes ... but are they installer set?
- *
- * GlobalAssemblyCache
- */
-
- set_property(hPackage, cszRootDrive, c_col);
-
- SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES_COMMON,NULL,0,pth);
- strcatW(pth,cszbs);
- set_property(hPackage, CFF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES,NULL,0,pth);
- strcatW(pth,cszbs);
- set_property(hPackage, PFF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_COMMON_APPDATA,NULL,0,pth);
- strcatW(pth,cszbs);
- set_property(hPackage, CADF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_ADMINTOOLS,NULL,0,pth);
- strcatW(pth,cszbs);
- set_property(hPackage, ATF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_APPDATA,NULL,0,pth);
- strcatW(pth,cszbs);
- set_property(hPackage, ADF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_SYSTEM,NULL,0,pth);
- strcatW(pth,cszbs);
- set_property(hPackage, SF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_LOCAL_APPDATA,NULL,0,pth);
- strcatW(pth,cszbs);
- set_property(hPackage, LADF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_MYPICTURES,NULL,0,pth);
- strcatW(pth,cszbs);
- set_property(hPackage, MPF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_PERSONAL,NULL,0,pth);
- strcatW(pth,cszbs);
- set_property(hPackage, PF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth);
- strcatW(pth,cszbs);
- set_property(hPackage, WF, pth);
-
- GetTempPathW(MAX_PATH,pth);
- set_property(hPackage, TF, pth);
-}
-
-
/****************************************************
* TOP level entry points
*****************************************************/
@@ -351,23 +108,17 @@
UINT rc;
static const CHAR *ExecSeqQuery =
"select * from InstallExecuteSequence where Sequence > 0 order by Sequence";
+ MSIHANDLE db;
FIXME("****We do not do any of the UI level stuff yet***\n");
- /* reset our properties */
- blitz_propertytable();
-
if (szPackagePath)
{
- static const WCHAR OriginalDatabase[] =
-{'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
LPWSTR p;
WCHAR check[MAX_PATH];
WCHAR pth[MAX_PATH];
DWORD size;
- set_property(hPackage, OriginalDatabase, szPackagePath);
-
strcpyW(pth,szPackagePath);
p = strrchrW(pth,'\\');
if (p)
@@ -377,11 +128,13 @@
}
size = MAX_PATH;
- if (get_property(hPackage,cszSourceDir,check,&size) != ERROR_SUCCESS )
- set_property(hPackage, cszSourceDir, pth);
+ if (MsiGetPropertyW(hPackage,cszSourceDir,check,&size) != ERROR_SUCCESS )
+ MsiSetPropertyW(hPackage, cszSourceDir, pth);
}
- rc = MsiDatabaseOpenViewA(hPackage, ExecSeqQuery, &view);
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view);
+ MsiCloseHandle(db);
if (rc == ERROR_SUCCESS)
{
@@ -456,7 +209,6 @@
}
end:
- blitz_propertytable();
return rc;
}
@@ -588,10 +340,15 @@
WCHAR source[0x100];
WCHAR target[0x200];
WCHAR *deformated=NULL;
+ MSIHANDLE db;
strcatW(ExecSeqQuery,action);
strcatW(ExecSeqQuery,end);
- rc = MsiDatabaseOpenViewW(hPackage, ExecSeqQuery, &view);
+
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewW(db, ExecSeqQuery, &view);
+ MsiCloseHandle(db);
+
if (rc != ERROR_SUCCESS)
return rc;
@@ -633,7 +390,7 @@
case 35: /* Directory set with formatted text. */
case 51: /* Property set with formatted text. */
deformat_string(hPackage,target,&deformated);
- set_property(hPackage,source,deformated);
+ MsiSetPropertyW(hPackage,source,deformated);
HeapFree(GetProcessHeap(),0,deformated);
break;
default:
@@ -654,7 +411,7 @@
static const WCHAR TF[]= {'T','e','m','p','F','o','l','d','e','r',0};
DWORD sz=MAX_PATH;
- if (get_property(hPackage, TF,tmp_file, &sz) != ERROR_SUCCESS)
+ if (MsiGetPropertyW(hPackage, TF,tmp_file, &sz) != ERROR_SUCCESS)
GetTempPathW(MAX_PATH,tmp_file);
strcatW(tmp_file,source);
@@ -676,6 +433,7 @@
static const WCHAR end[]={'`',0};
HANDLE the_file;
CHAR buffer[1024];
+ MSIHANDLE db;
the_file = CreateFileW(tmp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
@@ -685,7 +443,11 @@
strcatW(Query,source);
strcatW(Query,end);
- rc = MsiDatabaseOpenViewW(hPackage, Query, &view);
+
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewW(db, Query, &view);
+ MsiCloseHandle(db);
+
if (rc != ERROR_SUCCESS)
return rc;
@@ -782,7 +544,6 @@
PROCESS_INFORMATION info;
BOOL rc;
WCHAR *deformated;
- static const WCHAR c_collen[] = {'C',':','\\',0};
static const WCHAR spc[] = {' ',0};
memset(&si,0,sizeof(STARTUPINFOW));
@@ -875,8 +636,12 @@
static const CHAR *ExecSeqQuery = "select * from CreateFolder";
UINT rc;
MSIHANDLE view;
+ MSIHANDLE db;
+
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view);
+ MsiCloseHandle(db);
- rc = MsiDatabaseOpenViewA(hPackage, ExecSeqQuery, &view);
if (rc != ERROR_SUCCESS)
return rc;
@@ -913,7 +678,7 @@
}
sz = MAX_PATH;
- rc = get_property(hPackage, dir,full_path,&sz);
+ rc = MsiGetPropertyW(hPackage, dir,full_path,&sz);
if (rc != ERROR_SUCCESS)
{
@@ -961,9 +726,10 @@
MSIHANDLE row = 0;
WCHAR full_path[MAX_PATH];
WCHAR name_source[0x100];
+ MSIHANDLE db;
sz = MAX_PATH;
- if (get_property(hPackage,dir,path,&sz)==ERROR_SUCCESS)
+ if (MsiGetPropertyW(hPackage,dir,path,&sz)==ERROR_SUCCESS)
return ERROR_SUCCESS;
TRACE("Working to resolve %s\n",debugstr_w(dir));
@@ -974,18 +740,14 @@
if (!source)
{
sz = 0x100;
- if(!get_property(hPackage,cszRootDrive,buffer,&sz))
+ if(!MsiGetPropertyW(hPackage,cszRootDrive,buffer,&sz))
{
- set_property(hPackage,cszTargetDir,buffer);
+ MsiSetPropertyW(hPackage,cszTargetDir,buffer);
strcpyW(path,buffer);
}
else
{
- ERR("No RootDrive property defined disaster!\n");
- MsiCloseHandle(row);
- MsiViewClose(view);
- MsiCloseHandle(view);
- return ERROR_FUNCTION_FAILED;
+ strcpyW(path,c_collen);
}
}
else
@@ -996,7 +758,11 @@
strcatW(Query,dir);
strcatW(Query,end);
- rc = MsiDatabaseOpenViewW(hPackage, Query, &view);
+
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewW(db, Query, &view);
+ MsiCloseHandle(db);
+
if (rc != ERROR_SUCCESS)
return rc;
@@ -1068,7 +834,7 @@
strcatW(full_path,targetdir);
strcatW(full_path,cszbs);
}
- set_property(hPackage,dir,full_path);
+ MsiSetPropertyW(hPackage,dir,full_path);
if (!source)
strcpyW(path,full_path);
@@ -1087,7 +853,7 @@
strcpyW(name_source,dir);
strcatW(name_source,cszsrc);
- set_property(hPackage,name_source,full_path);
+ MsiSetPropertyW(hPackage,name_source,full_path);
if (source)
strcpyW(path,full_path);
}
@@ -1122,15 +888,14 @@
static const CHAR *ExecSeqQuery = "select * from Directory";
UINT rc;
MSIHANDLE view;
-
- /* According to MSDN these properties are set when CostFinalize is run
- * or MsiSetInstallLevel is called */
- TRACE("Setting installer properties\n");
- set_installer_properties(hPackage);
+ MSIHANDLE db;
TRACE("Building Directory properties\n");
- rc = MsiDatabaseOpenViewA(hPackage, ExecSeqQuery, &view);
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view);
+ MsiCloseHandle(db);
+
if (rc != ERROR_SUCCESS)
return rc;
@@ -1184,14 +949,17 @@
UINT size;
DWORD write;
HANDLE the_file;
+ MSIHANDLE db;
- rc = read_raw_stream_data(hPackage,stream_name,&data,&size);
+ db = MsiGetActiveDatabase(hPackage);
+ rc = read_raw_stream_data(db,stream_name,&data,&size);
+ MsiCloseHandle(db);
if (rc != ERROR_SUCCESS)
return rc;
write = 0x100;
- if (get_property(hPackage, cszSourceDir, source, &write))
+ if (MsiGetPropertyW(hPackage, cszSourceDir, source, &write))
{
ERR("No Source dir defined \n");
rc = ERROR_FUNCTION_FAILED;
@@ -1271,6 +1039,7 @@
DWORD sz=0x100;
INT seq;
static INT last_sequence = 0;
+ MSIHANDLE db;
if (sequence <= last_sequence)
{
@@ -1280,7 +1049,10 @@
sprintf(Query,ExecSeqQuery,sequence);
- rc = MsiDatabaseOpenViewA(hPackage, Query, &view);
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewA(db, Query, &view);
+ MsiCloseHandle(db);
+
if (rc != ERROR_SUCCESS)
return rc;
@@ -1316,7 +1088,7 @@
else
{
sz = 0x100;
- if (get_property(hPackage, cszSourceDir, source, &sz))
+ if (MsiGetPropertyW(hPackage, cszSourceDir, source, &sz))
{
ERR("No Source dir defined \n");
rc = ERROR_FUNCTION_FAILED;
@@ -1358,11 +1130,14 @@
static const WCHAR end[]={'`',0};
WCHAR dir[0x100];
DWORD sz=0x100;
+ MSIHANDLE db;
strcatW(ExecSeqQuery,component);
strcatW(ExecSeqQuery,end);
- rc = MsiDatabaseOpenViewW(hPackage, ExecSeqQuery, &view);
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewW(db, ExecSeqQuery, &view);
+ MsiCloseHandle(db);
if (rc != ERROR_SUCCESS)
return rc;
@@ -1387,7 +1162,7 @@
sz=0x100;
MsiRecordGetStringW(row,3,dir,&sz);
sz=MAX_PATH;
- rc = get_property(hPackage, dir, install_path, &sz);
+ rc = MsiGetPropertyW(hPackage, dir, install_path, &sz);
MsiCloseHandle(row);
MsiViewClose(view);
@@ -1402,6 +1177,7 @@
MSIHANDLE row = 0;
static const CHAR *ExecSeqQuery =
"select * from File order by Sequence";
+ MSIHANDLE db;
/* REALLY what we want to do is go through all the enabled
* features and check all the components of that feature and
@@ -1410,8 +1186,10 @@
* but for sheer gratification I am going to just brute force
* install all the files
*/
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view);
+ MsiCloseHandle(db);
- rc = MsiDatabaseOpenViewA(hPackage, ExecSeqQuery, &view);
if (rc != ERROR_SUCCESS)
return rc;
@@ -1497,7 +1275,7 @@
}
/* for future use lets keep track of this file and where it went */
- set_property(hPackage,sourcename,install_path);
+ MsiSetPropertyW(hPackage,sourcename,install_path);
MsiCloseHandle(row);
}
@@ -1513,14 +1291,17 @@
MSIHANDLE view;
MSIHANDLE row = 0;
static const CHAR *ExecSeqQuery = "select * from DuplicateFile";
+ MSIHANDLE db;
/*
* Yes we should only do this for componenets that are installed
* but again I need to do that went I track components.
*/
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view);
+ MsiCloseHandle(db);
- rc = MsiDatabaseOpenViewA(hPackage, ExecSeqQuery, &view);
if (rc != ERROR_SUCCESS)
return rc;
@@ -1558,7 +1339,7 @@
}
sz = 0x100;
- rc = get_property(hPackage,file_key,file_source,&sz);
+ rc = MsiGetPropertyW(hPackage,file_key,file_source,&sz);
if (rc != ERROR_SUCCESS)
{
ERR("Original file unknown %s\n",debugstr_w(file_key));
@@ -1586,7 +1367,7 @@
sz=0x100;
MsiRecordGetStringW(row,5,destkey,&sz);
sz = 0x100;
- rc = get_property(hPackage, destkey, dest_path, &sz);
+ rc = MsiGetPropertyW(hPackage, destkey, dest_path, &sz);
if (rc != ERROR_SUCCESS)
{
ERR("Unable to get destination folder\n");
@@ -1700,12 +1481,15 @@
MSIHANDLE view;
MSIHANDLE row = 0;
static const CHAR *ExecSeqQuery = "select * from Registry";
+ MSIHANDLE db;
/* Again here we want to key off of the components being installed...
* oh well
*/
-
- rc = MsiDatabaseOpenViewA(hPackage, ExecSeqQuery, &view);
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view);
+ MsiCloseHandle(db);
+
if (rc != ERROR_SUCCESS)
return rc;
@@ -1851,7 +1635,7 @@
mark++;
TRACE("Current %s .. %s\n",debugstr_w(*data),debugstr_w(mark));
sz = 0x100;
- if (get_property(hPackage, key, value,&sz) == ERROR_SUCCESS)
+ if (MsiGetPropertyW(hPackage, key, value,&sz) == ERROR_SUCCESS)
{
LPWSTR newdata;
chunk = (strlenW(value)+1) * sizeof(WCHAR);
@@ -1953,7 +1737,7 @@
szPathBuf, DWORD* pcchPathBuf)
{
TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf);
- return get_property(hInstall,szFolder,szPathBuf,pcchPathBuf);
+ return MsiGetPropertyW(hInstall,szFolder,szPathBuf,pcchPathBuf);
}
@@ -2007,11 +1791,11 @@
(strlenW(szFolder)+8)*sizeof(WCHAR));
strcpyW(newfolder,szFolder);
strcatW(newfolder,cszsrc);
- rc = get_property(hInstall,newfolder,szPathBuf,pcchPathBuf);
+ rc = MsiGetPropertyW(hInstall,newfolder,szPathBuf,pcchPathBuf);
HeapFree(GetProcessHeap(),0,newfolder);
}
else
- rc = get_property(hInstall,szFolder,szPathBuf,pcchPathBuf);
+ rc = MsiGetPropertyW(hInstall,szFolder,szPathBuf,pcchPathBuf);
return rc;
}
@@ -2028,8 +1812,12 @@
MSIHANDLE view;
MSIHANDLE row = 0;
static const CHAR *ExecSeqQuery;
+ MSIHANDLE db;
+
+ db = MsiGetActiveDatabase(hPackage);
+ rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view);
+ MsiCloseHandle(db);
- rc = MsiDatabaseOpenViewA(hPackage, ExecSeqQuery, &view);
if (rc != ERROR_SUCCESS)
return rc;
diff -ur dlls/msi.old/cond.y dlls/msi/cond.y
--- dlls/msi.old/cond.y 2004-06-29 07:27:41.000000000 -0500
+++ dlls/msi/cond.y 2004-06-29 07:29:03.000000000 -0500
@@ -449,11 +449,9 @@
$$ = HeapAlloc( GetProcessHeap(), 0, 0x100*sizeof (WCHAR) );
/* Lookup the identifier */
- /* This will not really work until we have write access to the table*/
- /* HACK ALERT HACK ALERT... */
sz=0x100;
- if (get_property(cond->hInstall,$1,$$,&sz) != ERROR_SUCCESS)
+ if (MsiGetPropertyW(cond->hInstall,$1,$$,&sz) != ERROR_SUCCESS)
{
$$[0]=0;
}
diff -ur dlls/msi.old/msi.c dlls/msi/msi.c
--- dlls/msi.old/msi.c 2004-06-29 07:27:41.000000000 -0500
+++ dlls/msi/msi.c 2004-06-29 07:32:19.000000000 -0500
@@ -375,32 +375,6 @@
return r;
}
-UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
-{
- FIXME("%s %p\n",debugstr_a(szPackage), phPackage);
- return ERROR_CALL_NOT_IMPLEMENTED;
-}
-
-UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
-{
- UINT rc;
- FIXME("%s %p\n",debugstr_w(szPackage), phPackage);
- rc = MsiOpenDatabaseW(szPackage,MSIDBOPEN_READONLY,phPackage);
- return rc;
-}
-
-UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
-{
- FIXME("%s 0x%08lx %p\n",debugstr_a(szPackage), dwOptions, phPackage);
- return ERROR_CALL_NOT_IMPLEMENTED;
-}
-
-UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
-{
- FIXME("%s 0x%08lx %p\n",debugstr_w(szPackage), dwOptions, phPackage);
- return ERROR_CALL_NOT_IMPLEMENTED;
-}
-
UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath, LPCSTR szTransforms, LANGID lgidLanguage)
{
FIXME("%s %s %s 0x%08x\n",debugstr_a(szPackagePath), debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
@@ -466,7 +440,7 @@
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
{
- MSIHANDLE dbhandle;
+ MSIHANDLE packagehandle;
UINT rc = ERROR_SUCCESS;
FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
@@ -475,13 +449,13 @@
if (rc != ERROR_SUCCESS)
return rc;
- rc = MsiOpenDatabaseW(szPackagePath,MSIDBOPEN_READONLY,&dbhandle);
+ rc = MsiOpenPackageW(szPackagePath,&packagehandle);
if (rc != ERROR_SUCCESS)
return rc;
- ACTION_DoTopLevelINSTALL(dbhandle, szPackagePath, szCommandLine);
+ ACTION_DoTopLevelINSTALL(packagehandle, szPackagePath, szCommandLine);
- MsiCloseHandle(dbhandle);
+ MsiCloseHandle(packagehandle);
return rc;
}
@@ -1224,151 +1198,6 @@
return S_FALSE;
}
-/* property code */
-UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue)
-{
- FIXME("STUB until write access is done: (%s %s)\n", szName,
- szValue);
-
- if (!hInstall)
- return ERROR_INVALID_HANDLE;
-
- return ERROR_SUCCESS;
-}
-
-UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue)
-{
- FIXME("STUB until write access is done: (%s %s)\n",debugstr_w(szName),
- debugstr_w(szValue));
-
- if (!hInstall)
- return ERROR_INVALID_HANDLE;
-
- return ERROR_SUCCESS;
-}
-
-UINT WINAPI MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPSTR szValueBuf, DWORD* pchValueBuf)
-{
- LPWSTR szwName = NULL, szwValueBuf = NULL;
- UINT hr = ERROR_INSTALL_FAILURE;
-
- if (0 == hInstall) {
- return ERROR_INVALID_HANDLE;
- }
- if (NULL == szName) {
- return ERROR_INVALID_PARAMETER;
- }
-
- FIXME("%lu %s %lu\n", hInstall, debugstr_a(szName), *pchValueBuf);
-
- if (NULL != szValueBuf && NULL == pchValueBuf) {
- return ERROR_INVALID_PARAMETER;
- }
- if( szName )
- {
- UINT len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
- szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
- if( !szwName )
- goto end;
- MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
- } else {
- return ERROR_INVALID_PARAMETER;
- }
- if( szValueBuf )
- {
- szwValueBuf = HeapAlloc( GetProcessHeap(), 0, (*pchValueBuf) * sizeof(WCHAR) );
- if( !szwValueBuf )
- goto end;
- }
-
- hr = MsiGetPropertyW( hInstall, szwName, szwValueBuf, pchValueBuf );
-
- if( ERROR_SUCCESS == hr )
- {
- WideCharToMultiByte(CP_ACP, 0, szwValueBuf, -1, szValueBuf, *pchValueBuf, NULL, NULL);
- }
-
-end:
- if( szwName )
- HeapFree( GetProcessHeap(), 0, szwName );
- if( szwValueBuf )
- HeapFree( GetProcessHeap(), 0, szwValueBuf );
-
- return hr;
-}
-
-UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName,
- LPWSTR szValueBuf, DWORD* pchValueBuf)
-{
- MSIHANDLE view,row;
- UINT rc;
- WCHAR Query[1024]=
- {'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' '
- ,'P','r','o','p','e','r','t','y',' ','w','h','e','r','e',' ','`'
- ,'P','r','o','p','e','r','t','y','`','=','`',0};
-
- static const WCHAR szEnd[]={'`',0};
-
- if (0 == hInstall) {
- return ERROR_INVALID_HANDLE;
- }
- if (NULL == szName) {
- return ERROR_INVALID_PARAMETER;
- }
-
- strcatW(Query,szName);
- strcatW(Query,szEnd);
-
- rc = MsiDatabaseOpenViewW(hInstall, Query, &view);
- if (rc == ERROR_SUCCESS)
- {
- DWORD sz;
- WCHAR value[0x100];
-
- rc = MsiViewExecute(view, 0);
- if (rc != ERROR_SUCCESS)
- {
- MsiViewClose(view);
- MsiCloseHandle(view);
- return rc;
- }
-
- rc = MsiViewFetch(view,&row);
- if (rc == ERROR_SUCCESS)
- {
- sz=0x100;
- rc = MsiRecordGetStringW(row,2,value,&sz);
- strncpyW(szValueBuf,value,min(sz+1,*pchValueBuf));
- *pchValueBuf = sz+1;
- MsiCloseHandle(row);
- }
- MsiViewClose(view);
- MsiCloseHandle(view);
- }
-
- if (rc == ERROR_SUCCESS)
- TRACE("returning %s for property %s\n", debugstr_w(szValueBuf),
- debugstr_w(szName));
-
- return rc;
-}
-
-
-INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
- MSIHANDLE hRecord)
-{
- FIXME("STUB: \n");
- return ERROR_SUCCESS;
-}
-
-
-MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
-{
- FIXME("Is this correct?\n");
- msihandle_addref(hInstall);
- return hInstall;
-}
-
UINT WINAPI MsiEnumRelatedProductsA (LPCSTR lpUpgradeCode, DWORD dwReserved,
DWORD iProductIndex, LPSTR lpProductBuf)
{
diff -ur dlls/msi.old/msipriv.h dlls/msi/msipriv.h
--- dlls/msi.old/msipriv.h 2004-06-29 07:27:41.000000000 -0500
+++ dlls/msi/msipriv.h 2004-06-29 07:29:10.000000000 -0500
@@ -145,6 +145,7 @@
#define MSIHANDLETYPE_SUMMARYINFO 2
#define MSIHANDLETYPE_VIEW 3
#define MSIHANDLETYPE_RECORD 4
+#define MSIHANDLETYPE_PACKAGE 5
#define MSI_MAJORVERSION 1
#define MSI_MINORVERSION 10
--- /dev/null 1994-07-17 18:46:18.000000000 -0500
+++ dlls/msi/package.c 2004-06-29 07:35:58.000000000 -0500
@@ -0,0 +1,541 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2004 Aric Stewart for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define NONAMELESSUNION
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+#include "objidl.h"
+#include "wincrypt.h"
+#include "winuser.h"
+#include "shlobj.h"
+#include "wine/unicode.h"
+#include "objbase.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+ * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
+ * which is a problem because LPCTSTR isn't defined when compiling wine.
+ * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
+ * and make sure to only use it in W functions.
+ */
+#define LPCTSTR LPCWSTR
+
+void MSI_FreePackage( VOID *arg);
+
+typedef struct tagMSIPACKAGE
+{
+ MSIHANDLE db;
+} MSIPACKAGE;
+
+void MSI_FreePackage( VOID *arg)
+{
+ MSIPACKAGE *package= arg;
+
+ MsiCloseHandle(package->db);
+}
+
+UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
+{
+ LPWSTR szwPack = NULL;
+ UINT len, ret;
+
+ TRACE("%s %p\n",debugstr_a(szPackage), phPackage);
+
+ if( szPackage )
+ {
+ len = MultiByteToWideChar( CP_ACP, 0, szPackage, -1, NULL, 0 );
+ szwPack = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+ if( szwPack )
+ MultiByteToWideChar( CP_ACP, 0, szPackage, -1, szwPack, len );
+ }
+
+ ret = MsiOpenPackageW( szwPack, phPackage );
+
+ if( szwPack )
+ HeapFree( GetProcessHeap(), 0, szwPack );
+
+ return ret;
+}
+
+
+static const void clone_properties(MSIHANDLE db)
+{
+ MSIHANDLE view;
+ UINT rc;
+ static const CHAR CreateSql[] = "CREATE TABLE `_Property` ( `_Property` "
+"CHAR(56) NOT NULL, `Value` CHAR(98) NOT NULL PRIMARY KEY `_Property`)";
+ static const CHAR Query[] = "SELECT * from Property";
+ static const CHAR Insert[] =
+ "INSERT into `_Property` (`_Property`,`Value`) VALUES (?)";
+
+ /* create the temporary properties table */
+ MsiDatabaseOpenViewA(db, CreateSql, &view);
+ MsiViewExecute(view,0);
+ MsiViewClose(view);
+ MsiCloseHandle(view);
+
+ /* clone the existing properties */
+ MsiDatabaseOpenViewA(db, Query, &view);
+
+ MsiViewExecute(view, 0);
+ while (1)
+ {
+ MSIHANDLE row;
+ MSIHANDLE view2;
+
+ rc = MsiViewFetch(view,&row);
+ if (rc != ERROR_SUCCESS)
+ break;
+
+ MsiDatabaseOpenViewA(db,Insert,&view2);
+ MsiViewExecute(view2,row);
+ MsiViewClose(view2);
+ MsiCloseHandle(view2);
+
+ MsiCloseHandle(row);
+ }
+ MsiViewClose(view);
+ MsiCloseHandle(view);
+
+}
+
+/*
+ * There are a whole slew of these we need to set
+ *
+ *
+http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/properties.asp
+ */
+static VOID set_installer_properties(MSIHANDLE hPackage)
+{
+ WCHAR pth[MAX_PATH];
+
+ static const WCHAR cszbs[]={'\\',0};
+ static const WCHAR CFF[] =
+{'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0};
+ static const WCHAR PFF[] =
+{'P','r','o','g','r','a','m','F','i','l','e','s','F','o','l','d','e','r',0};
+ static const WCHAR CADF[] =
+{'C','o','m','m','o','n','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+ static const WCHAR ATF[] =
+{'A','d','m','i','n','T','o','o','l','s','F','o','l','d','e','r',0};
+ static const WCHAR ADF[] =
+{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+ static const WCHAR SF[] =
+{'S','y','s','t','e','m','F','o','l','d','e','r',0};
+ static const WCHAR LADF[] =
+{'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+ static const WCHAR MPF[] =
+{'M','y','P','i','c','t','u','r','e','s','F','o','l','d','e','r',0};
+ static const WCHAR PF[] =
+{'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
+ static const WCHAR WF[] =
+{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
+ static const WCHAR TF[]=
+{'T','e','m','p','F','o','l','d','e','r',0};
+
+/* Not yet set ... but needed by iTunes
+ *
+DesktopFolder
+FavoritesFolder
+FontsFolder
+PrimaryVolumePath
+ProgramFiles64Folder
+ProgramMenuFolder
+SendToFolder
+StartMenuFolder
+StartupFolder
+System16Folder
+System64Folder
+TemplateFolder
+ */
+
+/* asked for by iTunes ... but are they installer set?
+ *
+ * GlobalAssemblyCache
+ */
+
+/*
+ * Other things i notice set
+ *
+ScreenY
+ScreenX
+SystemLanguageID
+ComputerName
+UserLanguageID
+LogonUser
+VirtualMemory
+PhysicalMemory
+Intel
+ShellAdvSupport
+ServicePackLevel
+WindowsBuild
+Version9x
+Version95
+VersionNT
+AdminUser
+DefaultUIFont
+VersionMsi
+VersionDatabase
+PackagecodeChanging
+ProductState
+CaptionHeight
+BorderTop
+BorderSide
+TextHeight
+ColorBits
+RedirectedDllSupport
+Time
+Date
+Privilaged
+DATABASE
+OriginalDatabase
+UILevel
+*/
+
+ SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES_COMMON,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MsiSetPropertyW(hPackage, CFF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MsiSetPropertyW(hPackage, PFF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_COMMON_APPDATA,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MsiSetPropertyW(hPackage, CADF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_ADMINTOOLS,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MsiSetPropertyW(hPackage, ATF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_APPDATA,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MsiSetPropertyW(hPackage, ADF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_SYSTEM,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MsiSetPropertyW(hPackage, SF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_LOCAL_APPDATA,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MsiSetPropertyW(hPackage, LADF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_MYPICTURES,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MsiSetPropertyW(hPackage, MPF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_PERSONAL,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MsiSetPropertyW(hPackage, PF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MsiSetPropertyW(hPackage, WF, pth);
+
+ GetTempPathW(MAX_PATH,pth);
+ MsiSetPropertyW(hPackage, TF, pth);
+}
+
+
+UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
+{
+ UINT rc;
+ MSIHANDLE handle;
+ MSIHANDLE db;
+ MSIPACKAGE *package;
+
+ static const WCHAR OriginalDatabase[] =
+{'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
+ static const WCHAR Database[] =
+{'D','A','T','A','B','A','S','E',0};
+
+ TRACE("%s %p\n",debugstr_w(szPackage), phPackage);
+
+ rc = MsiOpenDatabaseW(szPackage, MSIDBOPEN_READONLY, &db);
+
+ if (rc != ERROR_SUCCESS)
+ return ERROR_FUNCTION_FAILED;
+
+ handle = alloc_msihandle(MSIHANDLETYPE_PACKAGE, sizeof (MSIPACKAGE),
+ MSI_FreePackage, (void**)&package);
+
+ if (!handle)
+ {
+ MsiCloseHandle(db);
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ package->db = db;
+
+ /* ok here is where we do a slew of things to the database to
+ * prep for all that is to come as a package */
+
+ clone_properties(db);
+ set_installer_properties(handle);
+ MsiSetPropertyW(handle, OriginalDatabase, szPackage);
+ MsiSetPropertyW(handle, Database, szPackage);
+
+ *phPackage = handle;
+
+ return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
+{
+ FIXME("%s 0x%08lx %p\n",debugstr_a(szPackage), dwOptions, phPackage);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
+{
+ FIXME("%s 0x%08lx %p\n",debugstr_w(szPackage), dwOptions, phPackage);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
+{
+ MSIPACKAGE *package;
+
+ TRACE("(%i)\n",(INT)hInstall);
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+
+ if( !package)
+ return ERROR_INVALID_HANDLE;
+
+ msihandle_addref(package->db);
+ return package->db;
+}
+
+INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
+ MSIHANDLE hRecord)
+{
+ FIXME("STUB: \n");
+ return ERROR_SUCCESS;
+}
+
+/* property code */
+UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue)
+{
+ LPWSTR szwName = NULL, szwValue = NULL;
+ UINT hr = ERROR_INSTALL_FAILURE;
+ UINT len;
+
+ if (0 == hInstall) {
+ return ERROR_INVALID_HANDLE;
+ }
+ if (NULL == szName) {
+ return ERROR_INVALID_PARAMETER;
+ }
+ if (NULL == szValue) {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
+ szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwName )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
+
+ len = MultiByteToWideChar( CP_ACP, 0, szValue, -1, NULL, 0 );
+ szwValue = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwValue)
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szValue , -1, szwValue, len );
+
+ hr = MsiSetPropertyW( hInstall, szwName, szwValue);
+
+end:
+ if( szwName )
+ HeapFree( GetProcessHeap(), 0, szwName );
+ if( szwValue )
+ HeapFree( GetProcessHeap(), 0, szwValue );
+
+ return hr;
+}
+
+UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue)
+{
+ MSIPACKAGE *package;
+ MSIHANDLE view,row;
+ UINT rc;
+ DWORD sz = 0;
+ static const CHAR Insert[]=
+ "INSERT into `_Property` (`_Property`,`Value`) VALUES (?)";
+
+ TRACE("Setting property (%s %s)\n",debugstr_w(szName),
+ debugstr_w(szValue));
+
+ if (!hInstall)
+ return ERROR_INVALID_HANDLE;
+
+ if (MsiGetPropertyW(hInstall,szName,0,&sz)==ERROR_MORE_DATA)
+ {
+ FIXME("Cannot set exising properties! FIXME MIKE!\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+ if( !package)
+ return ERROR_INVALID_HANDLE;
+
+ rc = MsiDatabaseOpenViewA(package->db,Insert,&view);
+ if (rc!= ERROR_SUCCESS)
+ return rc;
+
+ row = MsiCreateRecord(2);
+ MsiRecordSetStringW(row,1,szName);
+ MsiRecordSetStringW(row,2,szValue);
+
+ rc = MsiViewExecute(view,row);
+
+ MsiCloseHandle(row);
+ MsiViewClose(view);
+ MsiCloseHandle(view);
+
+ return rc;
+}
+
+UINT WINAPI MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPSTR szValueBuf, DWORD* pchValueBuf)
+{
+ LPWSTR szwName = NULL, szwValueBuf = NULL;
+ UINT hr = ERROR_INSTALL_FAILURE;
+
+ if (0 == hInstall) {
+ return ERROR_INVALID_HANDLE;
+ }
+ if (NULL == szName) {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ TRACE("%lu %s %lu\n", hInstall, debugstr_a(szName), *pchValueBuf);
+
+ if (NULL != szValueBuf && NULL == pchValueBuf) {
+ return ERROR_INVALID_PARAMETER;
+ }
+ if( szName )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
+ szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwName )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
+ } else {
+ return ERROR_INVALID_PARAMETER;
+ }
+ if( szValueBuf )
+ {
+ szwValueBuf = HeapAlloc( GetProcessHeap(), 0, (*pchValueBuf) * sizeof(WCHAR) );
+ if( !szwValueBuf )
+ goto end;
+ }
+
+ hr = MsiGetPropertyW( hInstall, szwName, szwValueBuf, pchValueBuf );
+
+ if( *pchValueBuf > 0 )
+ {
+ WideCharToMultiByte(CP_ACP, 0, szwValueBuf, -1, szValueBuf, *pchValueBuf, NULL, NULL);
+ }
+
+end:
+ if( szwName )
+ HeapFree( GetProcessHeap(), 0, szwName );
+ if( szwValueBuf )
+ HeapFree( GetProcessHeap(), 0, szwValueBuf );
+
+ return hr;
+}
+
+UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName,
+ LPWSTR szValueBuf, DWORD* pchValueBuf)
+{
+ MSIHANDLE view,row;
+ UINT rc;
+ WCHAR Query[1024]=
+ {'s','e','l','e','c','t',' ','V','a','l','u','e',' ','f','r','o','m',' '
+ ,'_','P','r','o','p','e','r','t','y',' ','w','h','e','r','e',' '
+ ,'_','P','r','o','p','e','r','t','y','=','`',0};
+
+ static const WCHAR szEnd[]={'`',0};
+ MSIPACKAGE *package;
+
+ if (0 == hInstall) {
+ return ERROR_INVALID_HANDLE;
+ }
+ if (NULL == szName) {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+ if( !package)
+ return ERROR_INVALID_HANDLE;
+
+ strcatW(Query,szName);
+ strcatW(Query,szEnd);
+
+ rc = MsiDatabaseOpenViewW(package->db, Query, &view);
+ if (rc == ERROR_SUCCESS)
+ {
+ DWORD sz;
+ WCHAR value[0x100];
+
+ rc = MsiViewExecute(view, 0);
+ if (rc != ERROR_SUCCESS)
+ {
+ MsiViewClose(view);
+ MsiCloseHandle(view);
+ return rc;
+ }
+
+ rc = MsiViewFetch(view,&row);
+ if (rc == ERROR_SUCCESS)
+ {
+ sz=0x100;
+ rc = MsiRecordGetStringW(row,1,value,&sz);
+ strncpyW(szValueBuf,value,min(sz+1,*pchValueBuf));
+ *pchValueBuf = sz+1;
+ MsiCloseHandle(row);
+ }
+ MsiViewClose(view);
+ MsiCloseHandle(view);
+ }
+
+ if (rc == ERROR_SUCCESS)
+ TRACE("returning %s for property %s\n", debugstr_w(szValueBuf),
+ debugstr_w(szName));
+ else
+ {
+ *pchValueBuf = 0;
+ TRACE("property not found\n");
+ }
+
+ return rc;
+}
+
More information about the wine-patches
mailing list