MSI: various registry related fixes
Aric Stewart
aric at codeweavers.com
Tue May 31 12:31:13 CDT 2005
A few changes
write the skipped actions for ExecSequence as well as ExecUISequence
Further refind Class and ProgId registration to include FileType masks and the VersionIndependentProgIds
handled install_on_demand processing, even if it is a constant right now.
Dont use short filenames for InprocServer32
Respect features that report that they cannot be installed ADVERTISED
-------------- next part --------------
Index: dlls/msi/action.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/action.c,v
retrieving revision 1.126
diff -u -r1.126 action.c
--- dlls/msi/action.c 31 May 2005 13:20:09 -0000 1.126
+++ dlls/msi/action.c 31 May 2005 17:07:53 -0000
@@ -1268,6 +1268,15 @@
break;
}
+ sz=0x100;
+ rc = MSI_RecordGetStringW(row,1,buffer,&sz);
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Error is %x\n",rc);
+ msiobj_release(&row->hdr);
+ break;
+ }
+
/* check conditions */
if (!MSI_RecordIsNull(row,2))
{
@@ -1282,6 +1291,8 @@
{
HeapFree(GetProcessHeap(),0,cond);
msiobj_release(&row->hdr);
+ TRACE("Skipping action: %s (condition is false)\n",
+ debugstr_w(buffer));
continue;
}
else
@@ -1289,15 +1300,6 @@
}
}
- sz=0x100;
- rc = MSI_RecordGetStringW(row,1,buffer,&sz);
- if (rc != ERROR_SUCCESS)
- {
- ERR("Error is %x\n",rc);
- msiobj_release(&row->hdr);
- break;
- }
-
rc = ACTION_PerformAction(package,buffer, FALSE);
if (rc == ERROR_FUNCTION_NOT_CALLED)
@@ -4395,8 +4397,13 @@
sz = strlenW(tl_struct->source)+4;
sz *= sizeof(WCHAR);
- tl_struct->path = HeapAlloc(GetProcessHeap(),0,sz);
- sprintfW(tl_struct->path,fmt,tl_struct->source, lpszName);
+ if ((INT)lpszName == 1)
+ tl_struct->path = strdupW(tl_struct->source);
+ else
+ {
+ tl_struct->path = HeapAlloc(GetProcessHeap(),0,sz);
+ sprintfW(tl_struct->path,fmt,tl_struct->source, lpszName);
+ }
TRACE("trying %s\n", debugstr_w(tl_struct->path));
res = LoadTypeLib(tl_struct->path,&tl_struct->ptLib);
@@ -4706,6 +4713,7 @@
}
package->progids[index].CurVerIndex = -1;
+ package->progids[index].VersionIndIndex = -1;
/* if we have a parent then we may be that parents CurVer */
if (package->progids[index].ParentIndex >= 0)
@@ -4717,6 +4725,7 @@
FIXME("BAD BAD need to determing if we are really the CurVer\n");
package->progids[index].CurVerIndex = pindex;
+ package->progids[pindex].VersionIndIndex = index;
}
return index;
@@ -5519,7 +5528,10 @@
static const WCHAR szVIProgID[] = { 'V','e','r','s','i','o','n','I','n','d','e','p','e','n','d','e','n','t','P','r','o','g','I','D',0 };
static const WCHAR szAppID[] = { 'A','p','p','I','D',0 };
static const WCHAR szSpace[] = {' ',0};
+ static const WCHAR szInprocServer32[] = {'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
+ static const WCHAR szFileType_fmt[] = {'F','i','l','e','T','y','p','e','\\','%','s','\\','%','i',0};
HKEY hkey,hkey2,hkey3;
+ BOOL install_on_demand = FALSE;
int i;
if (!package)
@@ -5530,6 +5542,11 @@
if (rc != ERROR_SUCCESS)
return ERROR_FUNCTION_FAILED;
+ /* install_on_demand should be set if OLE supports install on demand OLE
+ * servers. For now i am defaulting to FALSE because i do not know how to
+ * check, and i am told our builtin OLE does not support it
+ */
+
for (i = 0; i < package->loaded_classes; i++)
{
INT index,f_index;
@@ -5550,8 +5567,8 @@
*/
if ((!ACTION_VerifyFeatureForAction(package, f_index,
INSTALLSTATE_LOCAL)) &&
- (!ACTION_VerifyFeatureForAction(package, f_index,
- INSTALLSTATE_ADVERTISED)))
+ !(install_on_demand && ACTION_VerifyFeatureForAction(package,
+ f_index, INSTALLSTATE_ADVERTISED)))
{
TRACE("Skipping class %s reg due to disabled feature %s\n",
debugstr_w(package->classes[i].CLSID),
@@ -5578,16 +5595,43 @@
index = get_loaded_file(package,package->components[index].KeyPath);
- /* the context server is a short path name */
- sz = 0;
- sz = GetShortPathNameW(package->files[index].TargetPath, NULL, 0);
- if (sz == 0)
+ /* the context server is a short path name
+ * except for if it is InprocServer32...
+ */
+ if (strcmpiW(package->classes[i].Context,szInprocServer32)!=0)
{
- ERR("Unable to find short path for CLSID COM Server\n");
+ sz = 0;
+ sz = GetShortPathNameW(package->files[index].TargetPath, NULL, 0);
+ if (sz == 0)
+ {
+ ERR("Unable to find short path for CLSID COM Server\n");
+ argument = NULL;
+ }
+ else
+ {
+ size = sz * sizeof(WCHAR);
+
+ if (package->classes[i].Argument)
+ {
+ size += strlenW(package->classes[i].Argument) *
+ sizeof(WCHAR);
+ size += sizeof(WCHAR);
+ }
+
+ argument = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
+ GetShortPathNameW(package->files[index].TargetPath, argument,
+ sz);
+
+ if (package->classes[i].Argument)
+ {
+ strcatW(argument,szSpace);
+ strcatW(argument,package->classes[i].Argument);
+ }
+ }
}
else
{
- size = sz * sizeof(WCHAR);
+ size = lstrlenW(package->files[index].TargetPath) * sizeof(WCHAR);
if (package->classes[i].Argument)
{
@@ -5596,14 +5640,17 @@
}
argument = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
- GetShortPathNameW(package->files[index].TargetPath, argument, sz);
+ strcpyW(argument, package->files[index].TargetPath);
if (package->classes[i].Argument)
{
strcatW(argument,szSpace);
strcatW(argument,package->classes[i].Argument);
}
+ }
+ if (argument)
+ {
RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)argument, size);
HeapFree(GetProcessHeap(),0,argument);
}
@@ -5627,12 +5674,12 @@
RegCloseKey(hkey3);
if (package->classes[i].ProgIDIndex >= 0 &&
- package->progids[package->classes[i].ProgIDIndex].ParentIndex
- >= 0)
+ package->progids[package->classes[i].ProgIDIndex].
+ VersionIndIndex >= 0)
{
- progid = package->progids[package->progids[
- package->classes[i].ProgIDIndex].ParentIndex].ProgID;
-
+ progid = strdupW(package->progids[package->progids[
+ package->classes[i].ProgIDIndex].VersionIndIndex].
+ ProgID);
RegCreateKeyW(hkey2,szVIProgID,&hkey3);
RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPVOID)progid,
(strlenW(progid)+1) *sizeof(WCHAR));
@@ -5700,6 +5747,37 @@
RegCloseKey(hkey2);
+ /* if there is a FileTypeMask, register the FileType */
+ if (package->classes[i].FileTypeMask)
+ {
+ LPWSTR ptr, ptr2;
+ LPWSTR keyname;
+ INT index = 0;
+ ptr = package->classes[i].FileTypeMask;
+ while (ptr && *ptr)
+ {
+ ptr2 = strchrW(ptr,';');
+ if (ptr2)
+ *ptr2 = 0;
+ keyname = HeapAlloc(GetProcessHeap(),0,(strlenW(szFileType_fmt)+
+ strlenW(package->classes[i].CLSID) + 4)
+ * sizeof(WCHAR));
+ sprintfW(keyname,szFileType_fmt, package->classes[i].CLSID,
+ index);
+
+ RegCreateKeyW(HKEY_CLASSES_ROOT,keyname,&hkey2);
+ RegSetValueExW(hkey2,NULL,0,REG_SZ, (LPVOID)ptr,
+ strlenW(ptr)*sizeof(WCHAR));
+
+ if (ptr2)
+ ptr = ptr2+1;
+ else
+ ptr = NULL;
+
+ index ++;
+ }
+ }
+
uirow = MSI_CreateRecord(1);
MSI_RecordSetStringW(uirow,1,package->classes[i].CLSID);
@@ -5844,6 +5922,9 @@
WCHAR clsid[0x1000];
/* check if this progid is to be installed */
+ package->progids[i].InstallMe = ((package->progids[i].InstallMe) ||
+ (package->progids[i].ClassIndex >= 0 &&
+ package->classes[package->progids[i].ClassIndex].Installed));
if (!package->progids[i].InstallMe)
{
@@ -6995,12 +7076,18 @@
HKEY hkey;
INT i;
MSIRECORD *uirow;
+ BOOL install_on_demand = TRUE;
if (!package)
return ERROR_INVALID_HANDLE;
load_classes_and_such(package);
+ /* We need to set install_on_demand based on if the shell handles advertised
+ * shortcuts and the like. Because Mike McCormack is working on this i am
+ * going to default to TRUE
+ */
+
for (i = 0; i < package->loaded_extensions; i++)
{
WCHAR extension[257];
@@ -7018,8 +7105,8 @@
*/
if ((!ACTION_VerifyFeatureForAction(package, f_index,
INSTALLSTATE_LOCAL)) &&
- (!ACTION_VerifyFeatureForAction(package, f_index,
- INSTALLSTATE_ADVERTISED)))
+ !(install_on_demand && ACTION_VerifyFeatureForAction(package,
+ f_index, INSTALLSTATE_ADVERTISED)))
{
TRACE("Skipping extension %s reg due to disabled feature %s\n",
debugstr_w(package->extensions[i].Extension),
@@ -7033,7 +7120,11 @@
package->extensions[i].Installed = TRUE;
- if (package->extensions[i].ProgIDIndex >= 0)
+ /* this is only registered if the extension has at least 1 verb
+ * according to MSDN
+ */
+ if (package->extensions[i].ProgIDIndex >= 0 &&
+ package->extensions[i].VerbCount > 0)
mark_progid_for_install(package, package->extensions[i].ProgIDIndex);
if (package->extensions[i].MIMEIndex >= 0)
@@ -7948,6 +8039,11 @@
index = get_loaded_feature(package,szFeature);
if (index < 0)
return ERROR_UNKNOWN_FEATURE;
+
+ if (iState == INSTALLSTATE_ADVERTISED &&
+ package->features[index].Attributes &
+ msidbFeatureAttributesDisallowAdvertise)
+ return ERROR_FUNCTION_FAILED;
package->features[index].ActionRequest= iState;
package->features[index].Action= iState;
Index: dlls/msi/action.h
===================================================================
RCS file: /home/wine/wine/dlls/msi/action.h,v
retrieving revision 1.12
diff -u -r1.12 action.h
--- dlls/msi/action.h 30 May 2005 09:56:56 -0000 1.12
+++ dlls/msi/action.h 31 May 2005 17:07:53 -0000
@@ -147,6 +147,7 @@
/* not in the table, set during installation */
BOOL InstallMe;
INT CurVerIndex;
+ INT VersionIndIndex;
} MSIPROGID;
typedef struct tagMSIVERB
More information about the wine-patches
mailing list