MSI: Implement MsiGetTargetPath
Mike McCormack
mike at codeweavers.com
Mon Jun 28 18:47:47 CDT 2004
ChangeLog:
<aric at codeweavers.com>
* Implement MsiGetTargetPathA/W
-------------- next part --------------
diff -ur dlls/msi.old/action.c dlls/msi/action.c
--- dlls/msi.old/action.c 2004-06-28 18:33:57.000000000 -0500
+++ dlls/msi/action.c 2004-06-28 18:34:17.000000000 -0500
@@ -62,7 +62,7 @@
} internal_property;
static internal_property PropTableHack[MAX_PROP];
-static INT PropCount = 0;
+static INT PropCount = -1;
WINE_DEFAULT_DEBUG_CHANNEL(msi);
@@ -70,6 +70,7 @@
* Prototypes
*/
UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action);
+static UINT ACTION_CostInitialize(MSIHANDLE hPackage);
static UINT ACTION_CreateFolders(MSIHANDLE hPackage);
static UINT ACTION_CostFinalize(MSIHANDLE hPackage);
static UINT ACTION_InstallFiles(MSIHANDLE hPackage);
@@ -79,11 +80,10 @@
static UINT set_property(MSIHANDLE hPackage, const WCHAR* prop,
const WCHAR* value);
-UINT get_property(MSIHANDLE hPackage, const WCHAR* prop, 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,
- const WCHAR* szPackagePath,
- const WCHAR* szCommandLine);
+static VOID set_installer_properties(MSIHANDLE hPackage);
static DWORD deformat_string(MSIHANDLE hPackage, WCHAR* ptr,WCHAR** data);
/*
@@ -104,7 +104,12 @@
static VOID blitz_propertytable()
{
- if (PropCount > 0)
+ if (PropCount == -1)
+ {
+ PropCount = 0;
+ memset(&PropTableHack,0,sizeof(PropTableHack));
+ }
+ else if (PropCount > 0)
{
int i;
TRACE("Clearing %i properties\n",PropCount);
@@ -113,14 +118,15 @@
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)
+UINT get_property(MSIHANDLE hPackage, const WCHAR* prop, WCHAR* value,
+ DWORD* size)
{
UINT rc = 1;
- DWORD sz=0x100;
int index = 0;
WCHAR* pName = PropTableHack[0].prop_name;
@@ -134,14 +140,24 @@
pName = PropTableHack[index].prop_name;
}
- if (pName)
+ if (pName && index < PropCount)
{
- strcpyW(value,PropTableHack[index].prop_value);
- TRACE(" found value %s\n",debugstr_w(value));
- return 0;
+ 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,&sz);
+ rc = MsiGetPropertyW(hPackage,prop,value,size);
if (rc == ERROR_SUCCESS)
TRACE(" found value %s\n",debugstr_w(value));
@@ -157,24 +173,30 @@
/* prop table hacks take precedence */
UINT rc;
int index = 0;
- WCHAR* pName = PropTableHack[0].prop_name;
+ 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 < PropCount)
+ while (pName && strcmpW(pName,prop) && index < MAX_PROP)
{
index ++;
pName = PropTableHack[index].prop_name;
}
- if (pName)
+ if (pName && index < MAX_PROP)
{
+ TRACE("property index %i\n",index);
strcpyW(PropTableHack[index].prop_value,value);
return 0;
}
else
{
- if (index > MAX_PROP)
+ if (index >= MAX_PROP)
{
ERR("EXCEEDING MAX PROP!!!!\n");
return ERROR_FUNCTION_FAILED;
@@ -184,6 +206,7 @@
strcpyW(PropTableHack[index].prop_name,prop);
strcpyW(PropTableHack[index].prop_value,value);
PropCount++;
+ TRACE("new property index %i (%i)\n",index,PropCount);
return 0;
}
@@ -199,16 +222,10 @@
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/properties.asp
*/
-static VOID set_installer_properties(MSIHANDLE hPackage,
- const WCHAR* szPackagePath,
- const WCHAR* szCommandLine)
+static VOID set_installer_properties(MSIHANDLE hPackage)
{
WCHAR pth[MAX_PATH];
- WCHAR *p;
- WCHAR check[MAX_PATH];
- static const WCHAR OriginalDatabase[] =
-{'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
static const WCHAR c_col[] =
{'C',':','\\',0};
static const WCHAR CFF[] =
@@ -257,20 +274,8 @@
*
* GlobalAssemblyCache
*/
-
- set_property(hPackage, OriginalDatabase, szPackagePath);
- set_property(hPackage, cszRootDrive, c_col);
- strcpyW(pth,szPackagePath);
- p = strrchrW(pth,'\\');
- if (p)
- {
- p++;
- *p=0;
- }
-
- if (get_property(hPackage,cszSourceDir,check) != ERROR_SUCCESS )
- set_property(hPackage, cszSourceDir, pth);
+ set_property(hPackage, cszRootDrive, c_col);
SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES_COMMON,NULL,0,pth);
strcatW(pth,cszbs);
@@ -329,9 +334,31 @@
FIXME("****We do not do any of the UI level stuff yet***\n");
/* reset our properties */
- /* HACK ! */
- memset (&PropTableHack, sizeof(PropTableHack),0);
- set_installer_properties(hPackage, szPackagePath, szCommandLine);
+ 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)
+ {
+ p++;
+ *p=0;
+ }
+
+ size = MAX_PATH;
+ if (get_property(hPackage,cszSourceDir,check,&size) != ERROR_SUCCESS )
+ set_property(hPackage, cszSourceDir, pth);
+ }
rc = MsiDatabaseOpenViewA(hPackage, ExecSeqQuery, &view);
@@ -437,9 +464,13 @@
{'D','u','p','l','i','c','a','t','e','F','i','l','e','s',0};
const static WCHAR szWriteRegistryValues[] =
{'W','r','i','t','e','R','e','g','i','s','t','r','y','V','a','l','u','e','s',0};
+ const static WCHAR szCostInitialize[] =
+ {'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0};
TRACE("Performing action (%s)\n",debugstr_w(action));
+ if (strcmpW(action,szCostInitialize)==0)
+ return ACTION_CostInitialize(hPackage);
if (strcmpW(action,szCreateFolders)==0)
return ACTION_CreateFolders(hPackage);
if (strcmpW(action,szCostFinalize)==0)
@@ -625,7 +656,8 @@
continue;
}
- rc = get_property(hPackage, dir,full_path);
+ sz = MAX_PATH;
+ rc = get_property(hPackage, dir,full_path,&sz);
if (rc != ERROR_SUCCESS)
{
@@ -673,8 +705,9 @@
MSIHANDLE row = 0;
WCHAR full_path[MAX_PATH];
WCHAR name_source[0x100];
-
- if (get_property(hPackage,dir,path)==ERROR_SUCCESS)
+
+ sz = MAX_PATH;
+ if (get_property(hPackage,dir,path,&sz)==ERROR_SUCCESS)
return ERROR_SUCCESS;
TRACE("Working to resolve %s\n",debugstr_w(dir));
@@ -684,7 +717,8 @@
{
if (!source)
{
- if(!get_property(hPackage,cszRootDrive,buffer))
+ sz = 0x100;
+ if(!get_property(hPackage,cszRootDrive,buffer,&sz))
{
set_property(hPackage,cszTargetDir,buffer);
strcpyW(path,buffer);
@@ -808,6 +842,16 @@
return rc;
}
+/*
+ * This is the action where all the features and components are loaded into
+ * memory... so when we start doing that that will be important.
+ *
+ */
+static UINT ACTION_CostInitialize(MSIHANDLE hPackage)
+{
+ return ERROR_SUCCESS;
+}
+
/*
* Alot is done in this function aside from just the costing.
* The costing needs to be implemented at some point but for now i am going
@@ -823,6 +867,11 @@
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);
+
TRACE("Building Directory properties\n");
rc = MsiDatabaseOpenViewA(hPackage, ExecSeqQuery, &view);
@@ -885,7 +934,8 @@
if (rc != ERROR_SUCCESS)
return rc;
- if (get_property(hPackage, cszSourceDir, source))
+ write = 0x100;
+ if (get_property(hPackage, cszSourceDir, source, &write))
{
ERR("No Source dir defined \n");
rc = ERROR_FUNCTION_FAILED;
@@ -1021,7 +1071,8 @@
}
else
{
- if (get_property(hPackage, cszSourceDir, source))
+ sz = 0x100;
+ if (get_property(hPackage, cszSourceDir, source, &sz))
{
ERR("No Source dir defined \n");
rc = ERROR_FUNCTION_FAILED;
@@ -1091,7 +1142,8 @@
sz=0x100;
MsiRecordGetStringW(row,3,dir,&sz);
- rc = get_property(hPackage, dir, install_path);
+ sz=MAX_PATH;
+ rc = get_property(hPackage, dir, install_path, &sz);
MsiCloseHandle(row);
MsiViewClose(view);
@@ -1261,7 +1313,8 @@
break;
}
- rc = get_property(hPackage,file_key,file_source);
+ sz = 0x100;
+ rc = get_property(hPackage,file_key,file_source,&sz);
if (rc != ERROR_SUCCESS)
{
ERR("Original file unknown %s\n",debugstr_w(file_key));
@@ -1288,7 +1341,8 @@
WCHAR destkey[0x100];
sz=0x100;
MsiRecordGetStringW(row,5,destkey,&sz);
- rc = get_property(hPackage, destkey, dest_path);
+ sz = 0x100;
+ rc = get_property(hPackage, destkey, dest_path, &sz);
if (rc != ERROR_SUCCESS)
{
ERR("Unable to get destination folder\n");
@@ -1456,6 +1510,7 @@
DWORD chunk=0;
WCHAR key[0x100];
WCHAR value[0x100];
+ DWORD sz;
/* scan for special characters */
if (!strchrW(ptr,'[') || (strchrW(ptr,'[') && !strchrW(ptr,']')))
@@ -1491,7 +1546,8 @@
mark = strchrW(mark,']');
mark++;
TRACE("Current %s .. %s\n",debugstr_w(*data),debugstr_w(mark));
- if (get_property(hPackage, key, value) == ERROR_SUCCESS)
+ sz = 0x100;
+ if (get_property(hPackage, key, value,&sz) == ERROR_SUCCESS)
{
LPWSTR newdata;
chunk = (strlenW(value)+1) * sizeof(WCHAR);
@@ -1522,6 +1578,79 @@
return size;
}
+/* Msi functions that seem approperate here */
+UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
+{
+ LPWSTR szwAction;
+ UINT len,rc;
+
+ TRACE(" exteral attempt at action %s\n",szAction);
+
+ if (!szAction)
+ return ERROR_FUNCTION_FAILED;
+ if (hInstall == 0)
+ return ERROR_FUNCTION_FAILED;
+
+ len = MultiByteToWideChar( CP_ACP, 0, szAction, -1, NULL, 0);
+ szwAction = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR));
+
+ if (!szwAction)
+ return ERROR_FUNCTION_FAILED;
+
+ MultiByteToWideChar( CP_ACP, 0, szAction, -1, szwAction, len);
+
+ rc = MsiDoActionW(hInstall, szwAction);
+ HeapFree(GetProcessHeap(),0,szwAction);
+ return rc;
+}
+
+UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
+{
+ TRACE(" exteral attempt at action %s \n",debugstr_w(szAction));
+ return ACTION_PerformAction(hInstall,szAction);
+}
+
+UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
+ LPSTR szPathBuf, DWORD* pcchPathBuf)
+{
+ LPWSTR szwFolder;
+ LPWSTR szwPathBuf;
+ UINT len,rc;
+
+ TRACE("getting folder %s %p %li\n",szFolder,szPathBuf, *pcchPathBuf);
+
+ if (!szFolder)
+ return ERROR_FUNCTION_FAILED;
+ if (hInstall == 0)
+ return ERROR_FUNCTION_FAILED;
+
+ len = MultiByteToWideChar( CP_ACP, 0, szFolder, -1, NULL, 0);
+ szwFolder= HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR));
+
+ if (!szwFolder)
+ return ERROR_FUNCTION_FAILED;
+
+ szwPathBuf = HeapAlloc( GetProcessHeap(), 0 , *pcchPathBuf * sizeof(WCHAR));
+
+ MultiByteToWideChar( CP_ACP, 0, szFolder, -1, szwFolder, len);
+
+ rc = MsiGetTargetPathW(hInstall, szwFolder, szwPathBuf,pcchPathBuf);
+
+ WideCharToMultiByte( CP_ACP, 0, szwPathBuf, *pcchPathBuf, szPathBuf,
+ *pcchPathBuf, NULL, NULL );
+
+ HeapFree(GetProcessHeap(),0,szwFolder);
+ HeapFree(GetProcessHeap(),0,szwPathBuf);
+
+ return rc;
+}
+
+UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
+ szPathBuf, DWORD* pcchPathBuf)
+{
+ TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf);
+ return get_property(hInstall,szFolder,szPathBuf,pcchPathBuf);
+}
#if 0
@@ -1560,3 +1689,4 @@
return rc;
}
#endif
+
diff -ur dlls/msi.old/cond.y dlls/msi/cond.y
--- dlls/msi.old/cond.y 2004-06-28 18:33:57.000000000 -0500
+++ dlls/msi/cond.y 2004-06-28 18:39:41.000000000 -0500
@@ -56,7 +56,8 @@
static LPWSTR COND_GetString( struct cond_str *str );
static int COND_lex( void *COND_lval, COND_input *info);
-UINT get_property(MSIHANDLE hPackage, const WCHAR* prop, WCHAR* value);
+UINT get_property(MSIHANDLE hPackage, const WCHAR* prop, WCHAR* value,
+ DWORD* size);
typedef INT (*comp_int)(INT a, INT b);
typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless);
@@ -443,6 +444,7 @@
symbol_s:
identifier
{
+ DWORD sz;
COND_input* cond = (COND_input*) info;
$$ = HeapAlloc( GetProcessHeap(), 0, 0x100*sizeof (WCHAR) );
@@ -450,7 +452,8 @@
/* This will not really work until we have write access to the table*/
/* HACK ALERT HACK ALERT... */
- if (get_property(cond->hInstall,$1,$$) != ERROR_SUCCESS)
+ sz=0x100;
+ if (get_property(cond->hInstall,$1,$$,&sz) != ERROR_SUCCESS)
{
$$[0]=0;
}
diff -ur dlls/msi.old/msi.spec dlls/msi/msi.spec
--- dlls/msi.old/msi.spec 2004-06-28 18:33:57.000000000 -0500
+++ dlls/msi/msi.spec 2004-06-28 18:34:17.000000000 -0500
@@ -76,8 +76,8 @@
76 stub MsiGetSourcePathW
77 stdcall MsiGetSummaryInformationA(long str long ptr)
78 stdcall MsiGetSummaryInformationW(long wstr long ptr)
-79 stub MsiGetTargetPathA
-80 stub MsiGetTargetPathW
+79 stdcall MsiGetTargetPathA(long str ptr ptr)
+80 stdcall MsiGetTargetPathW(long wstr ptr ptr)
81 stub MsiGetUserInfoA
82 stub MsiGetUserInfoW
83 stub MsiInstallMissingComponentA
diff -ur dlls/msi.old/msipriv.h dlls/msi/msipriv.h
--- dlls/msi.old/msipriv.h 2004-06-28 18:33:57.000000000 -0500
+++ dlls/msi/msipriv.h 2004-06-28 18:34:17.000000000 -0500
@@ -35,6 +35,8 @@
#define MSITYPE_NULLABLE 0x1000
#define MSITYPE_KEY 0x2000
+#define MSITYPE_BINARY 0x8900
+
struct tagMSITABLE;
typedef struct tagMSITABLE MSITABLE;
diff -ur dlls/msi.old/msiquery.c dlls/msi/msiquery.c
--- dlls/msi.old/msiquery.c 2004-06-28 18:33:57.000000000 -0500
+++ dlls/msi/msiquery.c 2004-06-28 18:34:17.000000000 -0500
@@ -211,7 +211,7 @@
{
LPWSTR sval;
- if( type & MSI_DATASIZEMASK )
+ if( type != MSITYPE_BINARY)
{
sval = MSI_makestring( query->db, ival );
MsiRecordSetStringW( handle, i, sval );
@@ -344,19 +344,6 @@
return ERROR_SUCCESS;
}
-
-UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
-{
- FIXME("%ld %s\n", hInstall, debugstr_a(szAction) );
- return ERROR_CALL_NOT_IMPLEMENTED;
-}
-
-UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
-{
- FIXME("%ld %s\n", hInstall, debugstr_w(szAction) );
- return ERROR_CALL_NOT_IMPLEMENTED;
-}
-
UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb,
LPCSTR szTransformFile, int iErrorCond)
{
diff -ur dlls/msi.old/table.c dlls/msi/table.c
--- dlls/msi.old/table.c 2004-06-28 18:33:57.000000000 -0500
+++ dlls/msi/table.c 2004-06-28 18:34:17.000000000 -0500
@@ -301,9 +301,8 @@
STATSTG stat;
r = get_raw_stream( hdb, stname, &stm );
- if( r != ERROR_FUNCTION_FAILED )
+ if( r != ERROR_SUCCESS)
goto end;
-
ret = ERROR_FUNCTION_FAILED;
r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
if( FAILED( r ) )
More information about the wine-patches
mailing list