Move around and rename some functions.

This commit is contained in:
Aric Stewart 2004-12-22 18:46:17 +00:00 committed by Alexandre Julliard
parent bcfa5b0900
commit fa384f6b10

View file

@ -122,7 +122,7 @@ typedef struct tagMSIFILE
/* 2 = present but replace */ /* 2 = present but replace */
/* 3 = present do not replace */ /* 3 = present do not replace */
/* 4 = Installed */ /* 4 = Installed */
WCHAR SourcePath[MAX_PATH]; LPWSTR SourcePath;
LPWSTR TargetPath; LPWSTR TargetPath;
BOOL Temporary; BOOL Temporary;
}MSIFILE; }MSIFILE;
@ -252,6 +252,15 @@ inline static WCHAR *strdupAtoW( const char *str )
return ret; return ret;
} }
static LPWSTR dupstrW(LPCWSTR src)
{
LPWSTR dest;
if (!src) return NULL;
dest = HeapAlloc(GetProcessHeap(), 0, (strlenW(src)+1)*sizeof(WCHAR));
strcpyW(dest, src);
return dest;
}
inline static WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index) inline static WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)
{ {
UINT rc; UINT rc;
@ -259,22 +268,33 @@ inline static WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)
LPWSTR ret; LPWSTR ret;
sz = 0; sz = 0;
rc = MSI_RecordGetStringW(row,index,NULL,&sz); if (MSI_RecordIsNull(row,index))
if (sz <= 0)
return NULL; return NULL;
rc = MSI_RecordGetStringW(row,index,NULL,&sz);
/* having an empty string is different than NULL */
if (sz == 0)
{
ret = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR));
ret[0] = 0;
return ret;
}
sz ++; sz ++;
ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR)); ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR));
rc = MSI_RecordGetStringW(row,index,ret,&sz); rc = MSI_RecordGetStringW(row,index,ret,&sz);
if (rc!=ERROR_SUCCESS) if (rc!=ERROR_SUCCESS)
{ {
ERR("Unable to load dynamic string\n");
HeapFree(GetProcessHeap(), 0, ret); HeapFree(GetProcessHeap(), 0, ret);
ret = NULL; ret = NULL;
} }
return ret; return ret;
} }
static LPWSTR PACKAGE_GetProperty(MSIPACKAGE *package, LPCWSTR prop) inline static LPWSTR load_dynamic_property(MSIPACKAGE *package, LPCWSTR prop,
UINT* rc)
{ {
DWORD sz = 0; DWORD sz = 0;
LPWSTR str; LPWSTR str;
@ -282,7 +302,11 @@ static LPWSTR PACKAGE_GetProperty(MSIPACKAGE *package, LPCWSTR prop)
r = MSI_GetPropertyW(package, prop, NULL, &sz); r = MSI_GetPropertyW(package, prop, NULL, &sz);
if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA) if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
{
if (rc)
*rc = r;
return NULL; return NULL;
}
sz++; sz++;
str = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR)); str = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
r = MSI_GetPropertyW(package, prop, str, &sz); r = MSI_GetPropertyW(package, prop, str, &sz);
@ -291,6 +315,8 @@ static LPWSTR PACKAGE_GetProperty(MSIPACKAGE *package, LPCWSTR prop)
HeapFree(GetProcessHeap(),0,str); HeapFree(GetProcessHeap(),0,str);
str = NULL; str = NULL;
} }
if (rc)
*rc = r;
return str; return str;
} }
@ -342,14 +368,6 @@ inline static int get_loaded_file(MSIPACKAGE* package, LPCWSTR file)
return rc; return rc;
} }
static LPWSTR PACKAGE_dupstrW(LPCWSTR src)
{
LPWSTR dest;
if (!src) return NULL;
dest = HeapAlloc(GetProcessHeap(), 0, (strlenW(src)+1)*sizeof(WCHAR));
strcpyW(dest, src);
return dest;
}
static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path) static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path)
{ {
@ -373,10 +391,8 @@ static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path)
memset(&package->files[index],0,sizeof(MSIFILE)); memset(&package->files[index],0,sizeof(MSIFILE));
package->files[index].File = PACKAGE_dupstrW(name); package->files[index].File = dupstrW(name);
if (package->files[index].TargetPath) package->files[index].TargetPath = dupstrW(path);
HeapFree(GetProcessHeap(),0,package->files[index].TargetPath);
package->files[index].TargetPath = PACKAGE_dupstrW(path);
package->files[index].Temporary = TRUE; package->files[index].Temporary = TRUE;
TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File)); TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File));
@ -399,19 +415,6 @@ void ACTION_remove_tracked_tempfiles(MSIPACKAGE* package)
} }
} }
static void ui_progress(MSIPACKAGE *package, int a, int b, int c, int d )
{
MSIRECORD * row;
row = MSI_CreateRecord(4);
MSI_RecordSetInteger(row,1,a);
MSI_RecordSetInteger(row,2,b);
MSI_RecordSetInteger(row,3,c);
MSI_RecordSetInteger(row,4,d);
MSI_ProcessMessage(package, INSTALLMESSAGE_PROGRESS, row);
msiobj_release(&row->hdr);
}
static UINT ACTION_OpenQuery( MSIDATABASE *db, MSIQUERY **view, LPCWSTR fmt, ... ) static UINT ACTION_OpenQuery( MSIDATABASE *db, MSIQUERY **view, LPCWSTR fmt, ... )
{ {
LPWSTR szQuery; LPWSTR szQuery;
@ -460,6 +463,19 @@ static UINT ACTION_OpenQuery( MSIDATABASE *db, MSIQUERY **view, LPCWSTR fmt, ...
return rc; return rc;
} }
static void ui_progress(MSIPACKAGE *package, int a, int b, int c, int d )
{
MSIRECORD * row;
row = MSI_CreateRecord(4);
MSI_RecordSetInteger(row,1,a);
MSI_RecordSetInteger(row,2,b);
MSI_RecordSetInteger(row,3,c);
MSI_RecordSetInteger(row,4,d);
MSI_ProcessMessage(package, INSTALLMESSAGE_PROGRESS, row);
msiobj_release(&row->hdr);
}
static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record) static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)
{ {
static const WCHAR Query_t[] = static const WCHAR Query_t[] =
@ -505,8 +521,8 @@ static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * recor
package->ActionFormat = load_dynamic_stringW(row,3); package->ActionFormat = load_dynamic_stringW(row,3);
if (package->LastAction) if (package->LastAction)
HeapFree(GetProcessHeap(),0,package->ActionFormat); HeapFree(GetProcessHeap(),0,package->LastAction);
package->LastAction = PACKAGE_dupstrW(action); package->LastAction = dupstrW(action);
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
MSI_ViewClose(view); MSI_ViewClose(view);
@ -634,6 +650,58 @@ static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start,
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
} }
/*
* build_directory_name()
*
* This function is to save messing round with directory names
* It handles adding backslashes between path segments,
* and can add \ at the end of the directory name if told to.
*
* It takes a variable number of arguments.
* It always allocates a new string for the result, so make sure
* to free the return value when finished with it.
*
* The first arg is the number of path segments that follow.
* The arguments following count are a list of path segments.
* A path segment may be NULL.
*
* Path segments will be added with a \ seperating them.
* A \ will not be added after the last segment, however if the
* last segment is NULL, then the last character will be a \
*
*/
static LPWSTR build_directory_name(DWORD count, ...)
{
DWORD sz = 1, i;
LPWSTR dir;
va_list va;
va_start(va,count);
for(i=0; i<count; i++)
{
LPCWSTR str = va_arg(va,LPCWSTR);
if (str)
sz += strlenW(str) + 1;
}
va_end(va);
dir = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR));
dir[0]=0;
va_start(va,count);
for(i=0; i<count; i++)
{
LPCWSTR str = va_arg(va,LPCWSTR);
if (!str)
continue;
strcatW(dir, str);
if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\')
strcatW(dir, cszbs);
}
return dir;
}
/**************************************************** /****************************************************
* TOP level entry points * TOP level entry points
*****************************************************/ *****************************************************/
@ -650,7 +718,7 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
{ {
LPWSTR p, check, path; LPWSTR p, check, path;
path = PACKAGE_dupstrW(szPackagePath); path = dupstrW(szPackagePath);
p = strrchrW(path,'\\'); p = strrchrW(path,'\\');
if (p) if (p)
{ {
@ -658,12 +726,12 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
*p=0; *p=0;
} }
check = PACKAGE_GetProperty(package, cszSourceDir); check = load_dynamic_property(package, cszSourceDir,NULL);
if (!check) if (!check)
{
MSI_SetPropertyW(package, cszSourceDir, path); MSI_SetPropertyW(package, cszSourceDir, path);
else
HeapFree(GetProcessHeap(), 0, check); HeapFree(GetProcessHeap(), 0, check);
}
HeapFree(GetProcessHeap(), 0, path); HeapFree(GetProcessHeap(), 0, path);
} }
@ -709,7 +777,8 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
if (strlenW(prop) > 0) if (strlenW(prop) > 0)
{ {
TRACE("Found commandline property (%s) = (%s)\n", debugstr_w(prop), debugstr_w(val)); TRACE("Found commandline property (%s) = (%s)\n",
debugstr_w(prop), debugstr_w(val));
MSI_SetPropertyW(package,prop,val); MSI_SetPropertyW(package,prop,val);
} }
} }
@ -1193,7 +1262,6 @@ static UINT store_binary_to_temp(MSIPACKAGE *package, const LPWSTR source,
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
typedef UINT __stdcall CustomEntry(MSIHANDLE); typedef UINT __stdcall CustomEntry(MSIHANDLE);
typedef struct typedef struct
{ {
@ -1313,28 +1381,38 @@ static UINT HANDLE_CustomType1(MSIPACKAGE *package, const LPWSTR source,
static UINT HANDLE_CustomType2(MSIPACKAGE *package, const LPWSTR source, static UINT HANDLE_CustomType2(MSIPACKAGE *package, const LPWSTR source,
const LPWSTR target, const INT type) const LPWSTR target, const INT type)
{ {
WCHAR tmp_file[MAX_PATH*2]; WCHAR tmp_file[MAX_PATH];
STARTUPINFOW si; STARTUPINFOW si;
PROCESS_INFORMATION info; PROCESS_INFORMATION info;
BOOL rc; BOOL rc;
INT len;
WCHAR *deformated; WCHAR *deformated;
WCHAR *cmd;
static const WCHAR spc[] = {' ',0}; static const WCHAR spc[] = {' ',0};
memset(&si,0,sizeof(STARTUPINFOW)); memset(&si,0,sizeof(STARTUPINFOW));
store_binary_to_temp(package, source, tmp_file); store_binary_to_temp(package, source, tmp_file);
strcatW(tmp_file,spc);
deformat_string(package,target,&deformated); deformat_string(package,target,&deformated);
strcatW(tmp_file,deformated);
len = strlenW(tmp_file) + strlenW(deformated) + 2;
cmd = (WCHAR*)HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*len);
strcpyW(cmd,tmp_file);
strcatW(cmd,spc);
strcatW(cmd,deformated);
HeapFree(GetProcessHeap(),0,deformated); HeapFree(GetProcessHeap(),0,deformated);
TRACE("executing exe %s \n",debugstr_w(tmp_file)); TRACE("executing exe %s \n",debugstr_w(cmd));
rc = CreateProcessW(NULL, tmp_file, NULL, NULL, FALSE, 0, NULL, rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info); c_collen, &si, &info);
HeapFree(GetProcessHeap(),0,cmd);
if ( !rc ) if ( !rc )
{ {
ERR("Unable to execute command\n"); ERR("Unable to execute command\n");
@ -1352,30 +1430,40 @@ static UINT HANDLE_CustomType2(MSIPACKAGE *package, const LPWSTR source,
static UINT HANDLE_CustomType18(MSIPACKAGE *package, const LPWSTR source, static UINT HANDLE_CustomType18(MSIPACKAGE *package, const LPWSTR source,
const LPWSTR target, const INT type) const LPWSTR target, const INT type)
{ {
WCHAR filename[MAX_PATH*2];
STARTUPINFOW si; STARTUPINFOW si;
PROCESS_INFORMATION info; PROCESS_INFORMATION info;
BOOL rc; BOOL rc;
WCHAR *deformated; WCHAR *deformated;
WCHAR *cmd;
INT len;
static const WCHAR spc[] = {' ',0}; static const WCHAR spc[] = {' ',0};
int index; int index;
memset(&si,0,sizeof(STARTUPINFOW)); memset(&si,0,sizeof(STARTUPINFOW));
index = get_loaded_file(package,source); index = get_loaded_file(package,source);
strcpyW(filename,package->files[index].TargetPath);
strcatW(filename,spc); len = strlenW(package->files[index].TargetPath);
deformat_string(package,target,&deformated); deformat_string(package,target,&deformated);
strcatW(filename,deformated); len += strlenW(deformated);
len += 2;
cmd = (WCHAR*)HeapAlloc(GetProcessHeap(),0,len * sizeof(WCHAR));
strcpyW(cmd, package->files[index].TargetPath);
strcatW(cmd, spc);
strcatW(cmd, deformated);
HeapFree(GetProcessHeap(),0,deformated); HeapFree(GetProcessHeap(),0,deformated);
TRACE("executing exe %s \n",debugstr_w(filename)); TRACE("executing exe %s \n",debugstr_w(cmd));
rc = CreateProcessW(NULL, filename, NULL, NULL, FALSE, 0, NULL, rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info); c_collen, &si, &info);
HeapFree(GetProcessHeap(),0,cmd);
if ( !rc ) if ( !rc )
{ {
ERR("Unable to execute command\n"); ERR("Unable to execute command\n");
@ -1393,31 +1481,40 @@ static UINT HANDLE_CustomType18(MSIPACKAGE *package, const LPWSTR source,
static UINT HANDLE_CustomType50(MSIPACKAGE *package, const LPWSTR source, static UINT HANDLE_CustomType50(MSIPACKAGE *package, const LPWSTR source,
const LPWSTR target, const INT type) const LPWSTR target, const INT type)
{ {
WCHAR filename[MAX_PATH*2];
STARTUPINFOW si; STARTUPINFOW si;
PROCESS_INFORMATION info; PROCESS_INFORMATION info;
WCHAR *prop;
BOOL rc; BOOL rc;
WCHAR *deformated; WCHAR *deformated;
WCHAR *cmd;
INT len;
UINT prc;
static const WCHAR spc[] = {' ',0}; static const WCHAR spc[] = {' ',0};
DWORD sz;
memset(&si,0,sizeof(STARTUPINFOW)); memset(&si,0,sizeof(STARTUPINFOW));
memset(&info,0,sizeof(PROCESS_INFORMATION));
sz = MAX_PATH*2; prop = load_dynamic_property(package,source,&prc);
if (MSI_GetPropertyW(package,source,filename,&sz) != ERROR_SUCCESS) if (!prop)
return ERROR_FUNCTION_FAILED; return prc;
strcatW(filename,spc);
deformat_string(package,target,&deformated); deformat_string(package,target,&deformated);
strcatW(filename,deformated); len = strlenW(prop) + strlenW(deformated) + 2;
cmd = (WCHAR*)HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*len);
strcpyW(cmd,prop);
strcatW(cmd,spc);
strcatW(cmd,deformated);
HeapFree(GetProcessHeap(),0,deformated); HeapFree(GetProcessHeap(),0,deformated);
TRACE("executing exe %s \n",debugstr_w(filename)); TRACE("executing exe %s \n",debugstr_w(cmd));
rc = CreateProcessW(NULL, filename, NULL, NULL, FALSE, 0, NULL, rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info); c_collen, &si, &info);
HeapFree(GetProcessHeap(),0,cmd);
if ( !rc ) if ( !rc )
{ {
ERR("Unable to execute command\n"); ERR("Unable to execute command\n");
@ -1443,6 +1540,7 @@ static UINT HANDLE_CustomType34(MSIPACKAGE *package, const LPWSTR source,
memset(&si,0,sizeof(STARTUPINFOW)); memset(&si,0,sizeof(STARTUPINFOW));
filename = resolve_folder(package, source, FALSE, FALSE, NULL); filename = resolve_folder(package, source, FALSE, FALSE, NULL);
if (!filename) if (!filename)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
@ -1485,7 +1583,8 @@ static BOOL create_full_pathW(const WCHAR *path)
WCHAR *new_path; WCHAR *new_path;
new_path = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1) * new_path = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1) *
sizeof(WCHAR)); sizeof(WCHAR));
strcpyW(new_path, path); strcpyW(new_path, path);
while((len = strlenW(new_path)) && new_path[len - 1] == '\\') while((len = strlenW(new_path)) && new_path[len - 1] == '\\')
@ -1796,7 +1895,6 @@ static UINT ACTION_CostInitialize(MSIPACKAGE *package)
{ {
MSIQUERY * view; MSIQUERY * view;
MSIRECORD * row; MSIRECORD * row;
DWORD sz;
UINT rc; UINT rc;
static const WCHAR Query_all[] = { static const WCHAR Query_all[] = {
'S','E','L','E','C','T',' ','*',' ', 'S','E','L','E','C','T',' ','*',' ',
@ -1808,7 +1906,6 @@ static UINT ACTION_CostInitialize(MSIPACKAGE *package)
MSI_SetPropertyW(package, szCosting, szZero); MSI_SetPropertyW(package, szCosting, szZero);
MSI_SetPropertyW(package, cszRootDrive , c_collen); MSI_SetPropertyW(package, cszRootDrive , c_collen);
sz = 0x100;
rc = MSI_DatabaseOpenViewW(package->db,Query_all,&view); rc = MSI_DatabaseOpenViewW(package->db,Query_all,&view);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return rc; return rc;
@ -1965,7 +2062,7 @@ static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
memset(&package->folders[index],0,sizeof(MSIFOLDER)); memset(&package->folders[index],0,sizeof(MSIFOLDER));
package->folders[index].Directory = PACKAGE_dupstrW(dir); package->folders[index].Directory = dupstrW(dir);
rc = ACTION_OpenQuery(package->db, &view, Query, dir); rc = ACTION_OpenQuery(package->db, &view, Query, dir);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
@ -2023,14 +2120,15 @@ static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
if (targetdir) if (targetdir)
{ {
TRACE(" TargetDefault = %s\n",debugstr_w(targetdir)); TRACE(" TargetDefault = %s\n",debugstr_w(targetdir));
HeapFree(GetProcessHeap(), 0, package->folders[index].TargetDefault); if (package->folders[index].TargetDefault)
package->folders[index].TargetDefault = PACKAGE_dupstrW(targetdir); HeapFree(GetProcessHeap(),0, package->folders[index].TargetDefault);
package->folders[index].TargetDefault = dupstrW(targetdir);
} }
if (srcdir) if (srcdir)
package->folders[index].SourceDefault = PACKAGE_dupstrW(srcdir); package->folders[index].SourceDefault = dupstrW(srcdir);
else if (targetdir) else if (targetdir)
package->folders[index].SourceDefault = PACKAGE_dupstrW(targetdir); package->folders[index].SourceDefault = dupstrW(targetdir);
HeapFree(GetProcessHeap(), 0, targetdir); HeapFree(GetProcessHeap(), 0, targetdir);
parent = load_dynamic_stringW(row,2); parent = load_dynamic_stringW(row,2);
@ -2047,7 +2145,7 @@ static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
package->folders[index].ParentIndex = -2; package->folders[index].ParentIndex = -2;
HeapFree(GetProcessHeap(), 0, parent); HeapFree(GetProcessHeap(), 0, parent);
package->folders[index].Property = PACKAGE_GetProperty(package, dir); package->folders[index].Property = load_dynamic_property(package, dir,NULL);
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
MSI_ViewClose(view); MSI_ViewClose(view);
@ -2056,56 +2154,6 @@ static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
return index; return index;
} }
/*
* build_directory_name()
*
* This function is to save messing round with directory names
* It handles adding backslashes between path segments,
* and can add \ at the end of the directory name if told to.
*
* It takes a variable number of arguments.
* It always allocates a new string for the result, so make sure
* to free the return value when finished with it.
*
* The first arg is the number of path segments that follow.
* The arguments following count are a list of path segments.
* A path segment may be NULL.
*
* Path segments will be added with a \ seperating them.
* A \ will not be added after the last segment, however if the
* last segment is NULL, then the last character will be a \
*
*/
static LPWSTR build_directory_name(DWORD count, ...)
{
DWORD sz = 1, i;
LPWSTR dir;
va_list va;
va_start(va,count);
for(i=0; i<count; i++)
{
LPCWSTR str = va_arg(va,LPCWSTR);
if (str)
sz += strlenW(str) + 1;
}
va_end(va);
dir = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR));
dir[0]=0;
va_start(va,count);
for(i=0; i<count; i++)
{
LPCWSTR str = va_arg(va,LPCWSTR);
if (!str)
continue;
strcatW(dir, str);
if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\')
strcatW(dir, cszbs);
}
return dir;
}
static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name,
BOOL source, BOOL set_prop, MSIFOLDER **folder) BOOL source, BOOL set_prop, MSIFOLDER **folder)
@ -2120,10 +2168,10 @@ static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name,
{ {
if (!source) if (!source)
{ {
path = PACKAGE_GetProperty(package,cszTargetDir); path = load_dynamic_property(package,cszTargetDir,NULL);
if (!path) if (!path)
{ {
path = PACKAGE_GetProperty(package,cszRootDrive); path = load_dynamic_property(package,cszRootDrive,NULL);
if (set_prop) if (set_prop)
MSI_SetPropertyW(package,cszTargetDir,path); MSI_SetPropertyW(package,cszTargetDir,path);
} }
@ -2133,10 +2181,10 @@ static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name,
} }
else else
{ {
path = PACKAGE_GetProperty(package,cszSourceDir); path = load_dynamic_property(package,cszSourceDir,NULL);
if (!path) if (!path)
{ {
path = PACKAGE_GetProperty(package,cszDatabase); path = load_dynamic_property(package,cszDatabase,NULL);
if (path) if (path)
{ {
p = strrchrW(path,'\\'); p = strrchrW(path,'\\');
@ -2164,18 +2212,18 @@ static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name,
if (!source && package->folders[i].ResolvedTarget) if (!source && package->folders[i].ResolvedTarget)
{ {
path = PACKAGE_dupstrW(package->folders[i].ResolvedTarget); path = dupstrW(package->folders[i].ResolvedTarget);
TRACE(" already resolved to %s\n",debugstr_w(path)); TRACE(" already resolved to %s\n",debugstr_w(path));
return path; return path;
} }
else if (source && package->folders[i].ResolvedSource) else if (source && package->folders[i].ResolvedSource)
{ {
path = PACKAGE_dupstrW(package->folders[i].ResolvedSource); path = dupstrW(package->folders[i].ResolvedSource);
return path; return path;
} }
else if (!source && package->folders[i].Property) else if (!source && package->folders[i].Property)
{ {
path = PACKAGE_dupstrW(package->folders[i].Property); path = dupstrW(package->folders[i].Property);
TRACE(" internally set to %s\n",debugstr_w(path)); TRACE(" internally set to %s\n",debugstr_w(path));
if (set_prop) if (set_prop)
MSI_SetPropertyW(package,name,path); MSI_SetPropertyW(package,name,path);
@ -2193,7 +2241,7 @@ static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name,
{ {
TRACE(" TargetDefault = %s\n",debugstr_w(package->folders[i].TargetDefault)); TRACE(" TargetDefault = %s\n",debugstr_w(package->folders[i].TargetDefault));
path = build_directory_name(3, p, package->folders[i].TargetDefault, NULL); path = build_directory_name(3, p, package->folders[i].TargetDefault, NULL);
package->folders[i].ResolvedTarget = PACKAGE_dupstrW(path); package->folders[i].ResolvedTarget = dupstrW(path);
TRACE(" resolved into %s\n",debugstr_w(path)); TRACE(" resolved into %s\n",debugstr_w(path));
if (set_prop) if (set_prop)
MSI_SetPropertyW(package,name,path); MSI_SetPropertyW(package,name,path);
@ -2201,7 +2249,7 @@ static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name,
else else
{ {
path = build_directory_name(3, p, package->folders[i].SourceDefault, NULL); path = build_directory_name(3, p, package->folders[i].SourceDefault, NULL);
package->folders[i].ResolvedSource = PACKAGE_dupstrW(path); package->folders[i].ResolvedSource = dupstrW(path);
} }
HeapFree(GetProcessHeap(),0,p); HeapFree(GetProcessHeap(),0,p);
} }
@ -2283,17 +2331,29 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
if (file->ComponentIndex >= 0) if (file->ComponentIndex >= 0)
comp = &package->components[file->ComponentIndex]; comp = &package->components[file->ComponentIndex];
if (file->Temporary == TRUE)
continue;
if (comp) if (comp)
{ {
LPWSTR p; LPWSTR p;
/* calculate target */ /* calculate target */
p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL); p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);
if (file->TargetPath)
HeapFree(GetProcessHeap(),0,file->TargetPath);
TRACE("file %s is named %s\n",
debugstr_w(file->File),debugstr_w(file->FileName));
file->TargetPath = build_directory_name(2, p, file->FileName); file->TargetPath = build_directory_name(2, p, file->FileName);
HeapFree(GetProcessHeap(),0,p);
TRACE("file %s resolves to %s\n", TRACE("file %s resolves to %s\n",
debugstr_w(file->File),debugstr_w(file->TargetPath)); debugstr_w(file->File),debugstr_w(file->TargetPath));
if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES)
{ {
file->State = 1; file->State = 1;
@ -2820,7 +2880,7 @@ static UINT ACTION_InstallFiles(MSIPACKAGE *package)
} }
inline static UINT get_file_target(MSIPACKAGE *package, LPCWSTR file_key, inline static UINT get_file_target(MSIPACKAGE *package, LPCWSTR file_key,
LPWSTR file_source) LPWSTR* file_source)
{ {
DWORD index; DWORD index;
@ -2833,7 +2893,7 @@ inline static UINT get_file_target(MSIPACKAGE *package, LPCWSTR file_key,
{ {
if (package->files[index].State >= 3) if (package->files[index].State >= 3)
{ {
strcpyW(file_source,package->files[index].TargetPath); *file_source = dupstrW(package->files[index].TargetPath);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
else else
@ -2871,7 +2931,7 @@ static UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
while (1) while (1)
{ {
WCHAR file_key[0x100]; WCHAR file_key[0x100];
WCHAR file_source[MAX_PATH]; WCHAR *file_source = NULL;
WCHAR dest_name[0x100]; WCHAR dest_name[0x100];
LPWSTR dest_path, dest; LPWSTR dest_path, dest;
WCHAR component[0x100]; WCHAR component[0x100];
@ -2913,12 +2973,14 @@ static UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
break; break;
} }
rc = get_file_target(package,file_key,file_source); rc = get_file_target(package,file_key,&file_source);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
ERR("Original file unknown %s\n",debugstr_w(file_key)); ERR("Original file unknown %s\n",debugstr_w(file_key));
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
if (file_source)
HeapFree(GetProcessHeap(),0,file_source);
break; break;
} }
@ -2936,7 +2998,7 @@ static UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
if (MSI_RecordIsNull(row,5)) if (MSI_RecordIsNull(row,5))
{ {
LPWSTR p; LPWSTR p;
dest_path = PACKAGE_dupstrW(file_source); dest_path = dupstrW(file_source);
p = strrchrW(dest_path,'\\'); p = strrchrW(dest_path,'\\');
if (p) if (p)
*p=0; *p=0;
@ -2952,6 +3014,8 @@ static UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
{ {
ERR("Unable to get destination folder\n"); ERR("Unable to get destination folder\n");
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
if (file_source)
HeapFree(GetProcessHeap(),0,file_source);
break; break;
} }
} }
@ -2960,10 +3024,10 @@ static UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
HeapFree(GetProcessHeap(), 0, dest_path); HeapFree(GetProcessHeap(), 0, dest_path);
TRACE("Duplicating file %s to %s\n",debugstr_w(file_source), TRACE("Duplicating file %s to %s\n",debugstr_w(file_source),
debugstr_w(dest_path)); debugstr_w(dest));
if (strcmpW(file_source,dest_path)) if (strcmpW(file_source,dest))
rc = !CopyFileW(file_source,dest_path,TRUE); rc = !CopyFileW(file_source,dest,TRUE);
else else
rc = ERROR_SUCCESS; rc = ERROR_SUCCESS;
@ -2973,11 +3037,12 @@ static UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
FIXME("We should track these duplicate files as well\n"); FIXME("We should track these duplicate files as well\n");
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
HeapFree(GetProcessHeap(),0,dest);
HeapFree(GetProcessHeap(),0,file_source);
} }
MSI_ViewClose(view); MSI_ViewClose(view);
msiobj_release(&view->hdr); msiobj_release(&view->hdr);
return rc; return rc;
} }
@ -3327,7 +3392,7 @@ static UINT ACTION_InstallInitialize(MSIPACKAGE *package)
TRACE("Checking Install Level\n"); TRACE("Checking Install Level\n");
level = PACKAGE_GetProperty(package,szlevel); level = load_dynamic_property(package,szlevel,NULL);
if (level) if (level)
{ {
install_level = atoiW(level); install_level = atoiW(level);
@ -3336,7 +3401,7 @@ static UINT ACTION_InstallInitialize(MSIPACKAGE *package)
else else
install_level = 1; install_level = 1;
override = PACKAGE_GetProperty(package,szAddLocal); override = load_dynamic_property(package,szAddLocal,NULL);
/* /*
* Components FeatureState defaults to FALSE. The idea is we want to * Components FeatureState defaults to FALSE. The idea is we want to
@ -3470,22 +3535,20 @@ static UINT ACTION_LaunchConditions(MSIPACKAGE *package)
return rc; return rc;
} }
static void resolve_keypath( MSIPACKAGE* package, INT static LPWSTR resolve_keypath( MSIPACKAGE* package, INT
component_index, WCHAR *keypath) component_index)
{ {
MSICOMPONENT* cmp = &package->components[component_index]; MSICOMPONENT* cmp = &package->components[component_index];
if (cmp->KeyPath[0]==0) if (cmp->KeyPath[0]==0)
{ {
LPWSTR p = resolve_folder(package,cmp->Directory,FALSE,FALSE,NULL); LPWSTR p = resolve_folder(package,cmp->Directory,FALSE,FALSE,NULL);
strcpyW(keypath,p); return p;
HeapFree(GetProcessHeap(),0,p);
return;
} }
if ((cmp->Attributes & 0x4) || (cmp->Attributes & 0x20)) if ((cmp->Attributes & 0x4) || (cmp->Attributes & 0x20))
{ {
FIXME("UNIMPLEMENTED keypath as Registry or ODBC Source\n"); FIXME("UNIMPLEMENTED keypath as Registry or ODBC Source\n");
keypath[0]=0; return NULL;
} }
else else
{ {
@ -3493,8 +3556,12 @@ static void resolve_keypath( MSIPACKAGE* package, INT
j = get_loaded_file(package,cmp->KeyPath); j = get_loaded_file(package,cmp->KeyPath);
if (j>=0) if (j>=0)
strcpyW(keypath,package->files[j].TargetPath); {
LPWSTR p = dupstrW(package->files[j].TargetPath);
return p;
}
} }
return NULL;
} }
/* /*
@ -3529,9 +3596,9 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
/* writes the Component and Features values to the registry */ /* writes the Component and Features values to the registry */
productcode = PACKAGE_GetProperty(package,szProductCode); productcode = load_dynamic_property(package,szProductCode,&rc);
if (!productcode) if (!productcode)
return ERROR_SUCCESS; return rc;
squash_guid(productcode,squished_pc); squash_guid(productcode,squished_pc);
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller,&hkey); rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller,&hkey);
@ -3588,7 +3655,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
{ {
if (package->components[i].ComponentId[0]!=0) if (package->components[i].ComponentId[0]!=0)
{ {
WCHAR keypath[0x1000]; WCHAR *keypath = NULL;
MSIRECORD * uirow; MSIRECORD * uirow;
squash_guid(package->components[i].ComponentId,squished_cc); squash_guid(package->components[i].ComponentId,squished_cc);
@ -3596,19 +3663,23 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
continue; continue;
resolve_keypath(package,i,keypath); keypath = resolve_keypath(package,i);
if (keypath)
RegSetValueExW(hkey3,squished_pc,0,REG_SZ,(LPVOID)keypath, {
RegSetValueExW(hkey3,squished_pc,0,REG_SZ,(LPVOID)keypath,
(strlenW(keypath)+1)*sizeof(WCHAR)); (strlenW(keypath)+1)*sizeof(WCHAR));
RegCloseKey(hkey3); RegCloseKey(hkey3);
/* UI stuff */ /* UI stuff */
uirow = MSI_CreateRecord(3); uirow = MSI_CreateRecord(3);
MSI_RecordSetStringW(uirow,1,productcode); MSI_RecordSetStringW(uirow,1,productcode);
MSI_RecordSetStringW(uirow,2,package->components[i].ComponentId); MSI_RecordSetStringW(uirow,2,package->components[i].
MSI_RecordSetStringW(uirow,3,keypath); ComponentId);
ui_actiondata(package,szProcessComponents,uirow); MSI_RecordSetStringW(uirow,3,keypath);
msiobj_release( &uirow->hdr ); ui_actiondata(package,szProcessComponents,uirow);
msiobj_release( &uirow->hdr );
HeapFree(GetProcessHeap(),0,keypath);
}
} }
} }
end: end:
@ -4187,10 +4258,13 @@ static UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package)
} }
static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name, static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name,
LPWSTR FilePath) LPWSTR *FilePath)
{ {
LPWSTR ProductCode; LPWSTR ProductCode;
LPWSTR SystemFolder; LPWSTR SystemFolder;
LPWSTR dest;
UINT rc;
static const WCHAR szInstaller[] = static const WCHAR szInstaller[] =
{'I','n','s','t','a','l','l','e','r','\\',0}; {'I','n','s','t','a','l','l','e','r','\\',0};
static const WCHAR szProductCode[] = static const WCHAR szProductCode[] =
@ -4198,21 +4272,21 @@ static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name,
static const WCHAR szFolder[] = static const WCHAR szFolder[] =
{'W','i','n','d','o','w','s','F','o','l','d','e','r',0}; {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
ProductCode = PACKAGE_GetProperty(package,szProductCode); ProductCode = load_dynamic_property(package,szProductCode,&rc);
if (!ProductCode) if (!ProductCode)
return ERROR_FUNCTION_FAILED; return rc;
SystemFolder = PACKAGE_GetProperty(package,szFolder); SystemFolder = load_dynamic_property(package,szFolder,NULL);
strcatW(SystemFolder,szInstaller); dest = build_directory_name(3, SystemFolder, szInstaller, ProductCode);
strcatW(SystemFolder,ProductCode);
create_full_pathW(SystemFolder); create_full_pathW(dest);
*FilePath = build_directory_name(2, dest, icon_name);
strcpyW(FilePath,SystemFolder);
strcatW(FilePath,cszbs);
strcatW(FilePath,icon_name);
HeapFree(GetProcessHeap(),0,SystemFolder); HeapFree(GetProcessHeap(),0,SystemFolder);
HeapFree(GetProcessHeap(),0,ProductCode); HeapFree(GetProcessHeap(),0,ProductCode);
HeapFree(GetProcessHeap(),0,dest);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -4357,16 +4431,17 @@ static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
if (!MSI_RecordIsNull(row,9)) if (!MSI_RecordIsNull(row,9))
{ {
WCHAR Path[MAX_PATH]; WCHAR *Path = NULL;
INT index; INT index;
sz = 0x100; sz = 0x100;
MSI_RecordGetStringW(row,9,buffer,&sz); MSI_RecordGetStringW(row,9,buffer,&sz);
build_icon_path(package,buffer,Path); build_icon_path(package,buffer,&Path);
index = MSI_RecordGetInteger(row,10); index = MSI_RecordGetInteger(row,10);
IShellLinkW_SetIconLocation(sl,Path,index); IShellLinkW_SetIconLocation(sl,Path,index);
HeapFree(GetProcessHeap(),0,Path);
} }
if (!MSI_RecordIsNull(row,11)) if (!MSI_RecordIsNull(row,11))
@ -4384,7 +4459,9 @@ static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
TRACE("Writing shortcut to %s\n",debugstr_w(target_file)); TRACE("Writing shortcut to %s\n",debugstr_w(target_file));
IPersistFile_Save(pf,target_file,FALSE); IPersistFile_Save(pf,target_file,FALSE);
HeapFree(GetProcessHeap(),0,target_file);
IPersistFile_Release( pf ); IPersistFile_Release( pf );
IShellLinkW_Release( sl ); IShellLinkW_Release( sl );
@ -4434,8 +4511,8 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
while (1) while (1)
{ {
HANDLE the_file; HANDLE the_file;
WCHAR FilePath[MAX_PATH]; WCHAR *FilePath=NULL;
WCHAR FileName[MAX_PATH]; WCHAR *FileName=NULL;
CHAR buffer[1024]; CHAR buffer[1024];
rc = MSI_ViewFetch(view,&row); rc = MSI_ViewFetch(view,&row);
@ -4445,16 +4522,17 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
break; break;
} }
sz = MAX_PATH; FileName = load_dynamic_stringW(row,1);
MSI_RecordGetStringW(row,1,FileName,&sz); if (!FileName)
if (sz == 0)
{ {
ERR("Unable to get FileName\n"); ERR("Unable to get FileName\n");
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
continue; continue;
} }
build_icon_path(package,FileName,FilePath); build_icon_path(package,FileName,&FilePath);
HeapFree(GetProcessHeap(),0,FileName);
TRACE("Creating icon file at %s\n",debugstr_w(FilePath)); TRACE("Creating icon file at %s\n",debugstr_w(FilePath));
@ -4465,6 +4543,7 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
{ {
ERR("Unable to create file %s\n",debugstr_w(FilePath)); ERR("Unable to create file %s\n",debugstr_w(FilePath));
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
HeapFree(GetProcessHeap(),0,FilePath);
continue; continue;
} }
@ -4483,6 +4562,8 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
WriteFile(the_file,buffer,sz,&write,NULL); WriteFile(the_file,buffer,sz,&write,NULL);
} while (sz == 1024); } while (sz == 1024);
HeapFree(GetProcessHeap(),0,FilePath);
CloseHandle(the_file); CloseHandle(the_file);
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
} }
@ -4584,11 +4665,12 @@ UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
*pcchPathBuf = strlenW(path)+1; *pcchPathBuf = strlenW(path)+1;
rc = ERROR_MORE_DATA; rc = ERROR_MORE_DATA;
} }
else if (rc == ERROR_SUCCESS) else if (path)
{ {
*pcchPathBuf = strlenW(path)+1; *pcchPathBuf = strlenW(path)+1;
strcpyW(szPathBuf,path); strcpyW(szPathBuf,path);
TRACE("Returning Path %s\n",debugstr_w(path)); TRACE("Returning Path %s\n",debugstr_w(path));
rc = ERROR_SUCCESS;
} }
HeapFree(GetProcessHeap(),0,path); HeapFree(GetProcessHeap(),0,path);
@ -4645,14 +4727,16 @@ UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
if (path && strlenW(path) > *pcchPathBuf) if (path && strlenW(path) > *pcchPathBuf)
{ {
*pcchPathBuf = strlenW(path)+1; *pcchPathBuf = strlenW(path)+1;
return ERROR_MORE_DATA; rc = ERROR_MORE_DATA;
} }
else if (rc == ERROR_SUCCESS) else if (path)
{ {
*pcchPathBuf = strlenW(path)+1; *pcchPathBuf = strlenW(path)+1;
strcpyW(szPathBuf,path); strcpyW(szPathBuf,path);
TRACE("Returning Path %s\n",debugstr_w(path)); TRACE("Returning Path %s\n",debugstr_w(path));
rc = ERROR_SUCCESS;
} }
HeapFree(GetProcessHeap(),0,path);
return rc; return rc;
} }