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