MSI: Correctly ensure properties set from resolved directory
paths are backslash terminated
Mike McCormack
mike at codeweavers.com
Fri Feb 4 19:53:04 CST 2005
This patch adds way too many TRACEs for my liking. If you want to add
traces to help your understanding, please remove them before submitting
the patch.
I also created a function build_directory_name which can do the same
thing as your ensure_terminated_by_backslash, so it would be better to
use that instead of creating a new function that does the same thing.
thanks,
Mike
Mike Hearn wrote:
> With this patch Lotus Notes 6.5 can install correctly using builtin MSI.
> However there is no progress GUI at all.
>
> - Correctly ensure properties set from resolved directory paths are
> backslash terminated
> - Add a new function, ensure_terminated_by_backslash and replace a few
> bits of custom handling with it.
> - Add more debug tracing
>
>
>
>
> ------------------------------------------------------------------------
>
> Index: dlls/msi/action.c
> ===================================================================
> RCS file: /home/wine/wine/dlls/msi/action.c,v
> retrieving revision 1.80
> diff -u -p -d -r1.80 action.c
> --- dlls/msi/action.c 2 Feb 2005 09:29:30 -0000 1.80
> +++ dlls/msi/action.c 5 Feb 2005 01:02:06 -0000
> @@ -354,6 +354,20 @@ inline static void reduce_to_longfilenam
> memmove(filename, p+1, (strlenW(p+1)+1)*sizeof(WCHAR));
> }
>
> +static void ensure_terminated_by_backslash(WCHAR **path)
> +{
> + DWORD len = strlenW(*path);
> + if ((*path)[len-1] != '\\')
> + {
> + LPWSTR t = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (len + 2)*sizeof(WCHAR));
> + strcpyW(t, *path);
> + strcatW(t, cszbs);
> + HeapFree(GetProcessHeap(), 0, *path);
> + *path = t;
> + }
> +}
> +
> +
> WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)
> {
> UINT rc;
> @@ -1246,6 +1260,7 @@ BOOL ACTION_HandleStandardAction(MSIPACK
> ui_actionstart(package, action);
> if (StandardActions[i].handler)
> {
> + TRACE("handling action %s\n", debugstr_w(action));
> *rc = StandardActions[i].handler(package);
> }
> else
> @@ -1911,7 +1926,7 @@ static INT load_folder(MSIPACKAGE *packa
> }
>
> if (srcdir)
> - package->folders[index].SourceDefault = dupstrW(srcdir);
> + package->folders[index].SourceDefault = dupstrW(srcdir);
> else if (targetdir)
> package->folders[index].SourceDefault = dupstrW(targetdir);
> HeapFree(GetProcessHeap(), 0, targetdir);
> @@ -1919,6 +1934,7 @@ static INT load_folder(MSIPACKAGE *packa
> parent = load_dynamic_stringW(row,2);
> if (parent)
> {
> + TRACE("recursing to load parent: %s\n", debugstr_w(parent));
> i = load_folder(package,parent);
> package->folders[index].ParentIndex = i;
> TRACE("Parent is index %i... %s %s\n",
> @@ -1931,6 +1947,7 @@ static INT load_folder(MSIPACKAGE *packa
> HeapFree(GetProcessHeap(), 0, parent);
>
> package->folders[index].Property = load_dynamic_property(package, dir,NULL);
> + TRACE("Property is %s\n", debugstr_w(package->folders[index].Property));
>
> msiobj_release(&row->hdr);
> MSI_ViewClose(view);
> @@ -2023,6 +2040,8 @@ LPWSTR resolve_folder(MSIPACKAGE *packag
> else if (!source && package->folders[i].Property)
> {
> path = dupstrW(package->folders[i].Property);
> + ensure_terminated_by_backslash(&path);
> +
> TRACE(" internally set to %s\n",debugstr_w(path));
> if (set_prop)
> MSI_SetPropertyW(package,name,path);
> @@ -4769,7 +4788,6 @@ static UINT ACTION_WriteIniValues(MSIPAC
> ' ','f','r','o','m',' ','I','n','i','F','i','l','e',0};
> static const WCHAR szWindowsFolder[] =
> {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
> - static const WCHAR szbs[] = {'\\',0};
>
> rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
> if (rc != ERROR_SUCCESS)
> @@ -4781,6 +4799,7 @@ static UINT ACTION_WriteIniValues(MSIPAC
> rc = MSI_ViewExecute(view, 0);
> if (rc != ERROR_SUCCESS)
> {
> + WARN("view execute failed\n");
> MSI_ViewClose(view);
> msiobj_release(&view->hdr);
> return rc;
> @@ -4797,6 +4816,7 @@ static UINT ACTION_WriteIniValues(MSIPAC
> rc = MSI_ViewFetch(view,&row);
> if (rc != ERROR_SUCCESS)
> {
> + TRACE("no more rows\n");
> rc = ERROR_SUCCESS;
> break;
> }
> @@ -4849,11 +4869,10 @@ static UINT ACTION_WriteIniValues(MSIPAC
>
>
> fullname = HeapAlloc(GetProcessHeap(),0,
> - (strlenW(folder)+strlenW(filename)+2)*sizeof(WCHAR));
> + (strlenW(folder)+strlenW(filename)+1)*sizeof(WCHAR));
>
> strcpyW(fullname,folder);
> - if (fullname[strlenW(folder)] != '\\')
> - strcatW(fullname,szbs);
> + ensure_terminated_by_backslash(&fullname);
> strcatW(fullname,filename);
>
> if (action == 0)
> @@ -5429,6 +5448,7 @@ UINT WINAPI MsiGetTargetPathW( MSIHANDLE
>
> if (path && (strlenW(path) > *pcchPathBuf))
> {
> + TRACE("not enough space for target path in buffer: %s\n", debugstr_w(path));
> *pcchPathBuf = strlenW(path)+1;
> rc = ERROR_MORE_DATA;
> }
> @@ -5436,7 +5456,7 @@ UINT WINAPI MsiGetTargetPathW( MSIHANDLE
> {
> *pcchPathBuf = strlenW(path)+1;
> strcpyW(szPathBuf,path);
> - TRACE("Returning Path %s\n",debugstr_w(path));
> + TRACE("Returning Path %s for folder %s\n",debugstr_w(path), debugstr_w(szFolder));
> rc = ERROR_SUCCESS;
> }
> HeapFree(GetProcessHeap(),0,path);
> @@ -5546,7 +5566,6 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *pack
> DWORD i;
> LPWSTR path = NULL;
> LPWSTR path2 = NULL;
> - INT len;
> MSIFOLDER *folder;
>
> TRACE("(%p %s %s)\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));
> @@ -5566,25 +5585,17 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *pack
> return ERROR_INVALID_PARAMETER;
>
> HeapFree(GetProcessHeap(),0,folder->Property);
> + folder->Property = dupstrW(szFolderPath);
> + ensure_terminated_by_backslash(&folder->Property);
>
> - len = strlenW(szFolderPath);
> -
> - if (szFolderPath[len-1]!='\\')
> - {
> - len +=2;
> - folder->Property = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
> - strcpyW(folder->Property,szFolderPath);
> - strcatW(folder->Property,cszbs);
> - }
> - else
> - folder->Property = dupstrW(szFolderPath);
> -
> - if (strcmpiW(path, szFolderPath) == 0)
> + TRACE("comparing %s to %s\n", debugstr_w(path), debugstr_w(folder->Property));
> + if (strcmpiW(path, folder->Property) == 0)
> {
> /*
> * Resolved Target has not really changed, so just
> * set this folder and do not recalculate everything.
> */
> + TRACE("no change, not recalculating\n");
> HeapFree(GetProcessHeap(),0,folder->ResolvedTarget);
> folder->ResolvedTarget = NULL;
> path2 = resolve_folder(package,szFolder,FALSE,TRUE,NULL);
> @@ -5600,6 +5611,7 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *pack
>
> for (i = 0; i < package->loaded_folders; i++)
> {
> + TRACE("reresolving folder %ld\n", i);
> path2=resolve_folder(package, package->folders[i].Directory, FALSE,
> TRUE, NULL);
> HeapFree(GetProcessHeap(),0,path2);
> @@ -5607,6 +5619,8 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *pack
> }
> HeapFree(GetProcessHeap(),0,path);
>
> + TRACE("done\n");
> +
> return ERROR_SUCCESS;
> }
>
> Index: dlls/msi/package.c
> ===================================================================
> RCS file: /home/wine/wine/dlls/msi/package.c,v
> retrieving revision 1.35
> diff -u -p -d -r1.35 package.c
> --- dlls/msi/package.c 2 Feb 2005 09:55:51 -0000 1.35
> +++ dlls/msi/package.c 5 Feb 2005 01:02:07 -0000
> @@ -81,6 +81,8 @@ static const UINT clone_properties(MSIDA
> '`','V','a','l','u','e','`',')',' ',
> 'V','A','L','U','E','S',' ','(','?',',','?',')',0};
>
> + TRACE("\n");
> +
> /* create the temporary properties table */
> rc = MSI_DatabaseOpenViewW(db, CreateSql, &view);
> if (rc != ERROR_SUCCESS)
> @@ -124,6 +126,8 @@ static const UINT clone_properties(MSIDA
> }
> MSI_ViewClose(view);
> msiobj_release(&view->hdr);
> +
> + TRACE("done\n");
>
> return rc;
> }
> @@ -234,6 +238,10 @@ Date
> Privileged
> */
>
> +
> +
> + TRACE("\n");
> +
> SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES_COMMON,NULL,0,pth);
> strcatW(pth,cszbs);
> MSI_SetPropertyW(package, CFF, pth);
> @@ -352,6 +360,8 @@ Privileged
> sprintfW( bufstr, szScreenFormat, GetDeviceCaps( dc, BITSPIXEL ));
> MSI_SetPropertyW( package, szColorBits, bufstr );
> ReleaseDC(0, dc);
> +
> + TRACE("done\n");
> }
>
> MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db )
> @@ -388,10 +398,14 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABA
>
> clone_properties(db);
> set_installer_properties(package);
> +
> + TRACE("setting UI level\n");
> sprintfW(uilevel,szpi,gUILevel);
> MSI_SetPropertyW(package, szLevel, uilevel);
> }
>
> + TRACE("done\n");
> +
> return package;
> }
>
> @@ -696,6 +710,7 @@ UINT MSI_SetPropertyW( MSIPACKAGE *packa
> rc = MSI_GetPropertyW(package,szName,0,&sz);
> if (rc==ERROR_MORE_DATA || rc == ERROR_SUCCESS)
> {
> + TRACE("updating pre-existing property for %s\n", debugstr_w(szName));
> sprintfW(Query,Update,szName);
>
> row = MSI_CreateRecord(1);
> @@ -704,7 +719,8 @@ UINT MSI_SetPropertyW( MSIPACKAGE *packa
> }
> else
> {
> - strcpyW(Query,Insert);
> + TRACE("inseting new property for %s\n", debugstr_w(szName));
> + strcpyW(Query,Insert);
>
> row = MSI_CreateRecord(2);
> MSI_RecordSetStringW(row,1,szName);
> @@ -725,6 +741,9 @@ UINT MSI_SetPropertyW( MSIPACKAGE *packa
> MSI_ViewClose(view);
> msiobj_release(&view->hdr);
>
> + TRACE("done for %s\n", debugstr_w(szName));
> +
> +
> return rc;
> }
>
> @@ -799,7 +818,7 @@ UINT MSI_GetPropertyW(MSIPACKAGE *packag
> else
> {
> *pchValueBuf = 0;
> - TRACE("property not found\n");
> + TRACE("property %s not found\n", debugstr_w(szName));
> }
>
> return rc;
> Index: dlls/msi/record.c
> ===================================================================
> RCS file: /home/wine/wine/dlls/msi/record.c,v
> retrieving revision 1.22
> diff -u -p -d -r1.22 record.c
> --- dlls/msi/record.c 31 Jan 2005 11:30:59 -0000 1.22
> +++ dlls/msi/record.c 5 Feb 2005 01:02:08 -0000
> @@ -386,6 +386,8 @@ UINT MSI_RecordGetStringW(MSIRECORD *rec
> ret = ERROR_MORE_DATA;
> *pcchValue = len;
>
> + TRACE("result: %s\n", debugstr_w(szValue));
> +
> return ret;
> }
>
> Index: dlls/msi/string.c
> ===================================================================
> RCS file: /home/wine/wine/dlls/msi/string.c,v
> retrieving revision 1.13
> diff -u -p -d -r1.13 string.c
> --- dlls/msi/string.c 20 Jan 2005 10:36:35 -0000 1.13
> +++ dlls/msi/string.c 5 Feb 2005 01:02:08 -0000
> @@ -292,6 +292,8 @@ UINT msi_id2stringW( string_table *st, U
> memcpy( buffer, str, (*sz)*sizeof(WCHAR) );
> *sz = len;
>
> + TRACE("found %s\n", debugstr_wn( buffer, len - 1 ));
> +
> return ERROR_SUCCESS;
> }
>
> @@ -339,6 +341,8 @@ UINT msi_id2stringA( string_table *st, U
>
> *sz = WideCharToMultiByte( st->codepage, 0, str, n, buffer, len, NULL, NULL );
>
> + TRACE("found %s\n", debugstr_an( buffer, len - 1 ));
> +
> return ERROR_SUCCESS;
> }
>
More information about the wine-patches
mailing list