MSI: Implement ProcessComponents
Mike McCormack
mike at codeweavers.com
Sat Jul 3 20:23:48 CDT 2004
ChangeLog:
<aric at codeweavers.com>
* Implement ProcessComponents
-------------- next part --------------
diff -ur dlls/msi.old/action.c dlls/msi/action.c
--- dlls/msi.old/action.c 2004-07-03 20:20:24.000000000 -0500
+++ dlls/msi/action.c 2004-07-03 20:20:46.000000000 -0500
@@ -141,6 +141,7 @@
static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action);
static UINT ACTION_InstallInitialize(MSIHANDLE hPackage);
static UINT ACTION_InstallValidate(MSIHANDLE hPackage);
+static UINT ACTION_ProcessComponents(MSIHANDLE hPackage);
static UINT HANDLE_CustomType1(MSIHANDLE hPackage, const LPWSTR source,
const LPWSTR target, const INT type);
@@ -186,6 +187,8 @@
{'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e',0};
const static WCHAR szLaunchConditions[] =
{'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','s',0};
+const static WCHAR szProcessComponents[] =
+ {'P','r','o','c','e','s','s','C','o','m','p','o','n','e','n','t','s',0};
/********************************************************
@@ -806,6 +809,8 @@
rc = ACTION_InstallValidate(hPackage);
/* install block */
+ else if (strcmpW(action,szProcessComponents)==0)
+ rc = ACTION_ProcessComponents(hPackage);
else if (strcmpW(action,szInstallInitialize)==0)
rc = ACTION_InstallInitialize(hPackage);
else if (strcmpW(action,szCreateFolders)==0)
@@ -818,64 +823,17 @@
rc = ACTION_WriteRegistryValues(hPackage);
/*
- Current called during itunes but unimplemented
+ Current called during itunes but unimplemented and seem important
- AppSearch
- FindRelatedProducts
- CostInitialize
- MigrateFeatureStates
ResolveSource (sets SourceDir)
ValidateProductID (sets ProductID)
- IsolateComponents (Empty)
- SetODBCFolders
- MigrateFeatureStates
- RemoveExistingProducts
- AllocateRegistrySpace
- ProcessComponents
- UnpublishComponents
- UnpublishFeatures
- StopServices
- DeleteServices
- UnregisterComPlus
- SelfUnregModules (Empty)
- UnregisterTypeLibraries
- RemoveODBC
- UnregisterFonts
- RemoveRegistryValues
- UnregisterClassInfo
- UnregisterExtensionInfo
- UnregisterProgIdInfo
- UnregisterMIMEInfo
- RemoveIniValues
- RemoveShortcuts
- RemoveEnviromentStrings
- RemoveDuplicateFiles
- RemoveFiles (Empty)
- MoveFiles (Empty)
- RemoveRegistryValues (Empty)
- SelfRegModules (Empty)
- RemoveFolders
- PatchFiles
- BindImage (Empty)
CreateShortcuts (would be nice to have soon)
RegisterClassInfo
- RegisterExtensionInfo (Empty)
RegisterProgIdInfo (Lots to do)
- RegisterMIMEInfo (Empty)
- WriteIniValues (Empty)
- WriteEnvironmentStrings (Empty)
- RegisterFonts(Empty)
- InstallODBC
RegisterTypeLibraries
- SelfRegModules
- RegisterComPlus
RegisterUser
RegisterProduct
- PublishComponents
- PublishFeatures
- PublishProduct
InstallFinalize
- .
*/
else if ((rc = ACTION_CustomAction(hPackage,action)) != ERROR_SUCCESS)
{
@@ -2381,7 +2339,10 @@
ui_progress(hPackage,2,0,0,0);
if (rc)
- ERR("Unable to move file\n");
+ {
+ ERR("Unable to move file (error %li)\n",GetLastError());
+ rc = ERROR_SUCCESS;
+ }
else
file->State = 4;
}
@@ -2779,6 +2740,7 @@
HeapFree(GetProcessHeap(),0,value);
MsiCloseHandle(row);
+ RegCloseKey(hkey);
}
MsiViewClose(view);
MsiCloseHandle(view);
@@ -3036,6 +2998,123 @@
return rc;
}
+static void resolve_keypath(MSIHANDLE hPackage, MSIPACKAGE* package, INT
+ component_index, WCHAR *keypath)
+{
+ MSICOMPONENT* cmp = &package->components[component_index];
+
+ if (cmp->KeyPath[0]==0)
+ {
+ resolve_folder(hPackage,cmp->Directory,keypath,FALSE,FALSE,NULL);
+ return;
+ }
+ if ((cmp->Attributes & 0x4) || (cmp->Attributes & 0x20))
+ {
+ FIXME("UNIMPLEMENTED keypath as Registry or ODBC Source\n");
+ keypath[0]=0;
+ }
+ else
+ {
+ int j;
+ for (j = 0; j < package->loaded_files; j++)
+ if (strcmpW(package->files[j].File,cmp->KeyPath)==0)
+ break;
+ if (j < package->loaded_files)
+ strcpyW(keypath,package->files[j].TargetPath);
+ }
+}
+
+static UINT ACTION_ProcessComponents(MSIHANDLE hPackage)
+{
+ MSIPACKAGE* package;
+ WCHAR productcode[0x100];
+ WCHAR squished_pc[0x100];
+ WCHAR squished_cc[0x100];
+ DWORD sz;
+ UINT rc;
+ INT i;
+ HKEY hkey=0,hkey2=0,hkey3=0;
+ static const WCHAR szProductCode[]=
+{'P','r','o','d','u','c','t','C','o','d','e',0};
+ static const WCHAR szInstaller[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'I','n','s','t','a','l','l','e','r',0 };
+ static const WCHAR szFeatures[] = {
+'F','e','a','t','u','r','e','s',0 };
+ static const WCHAR szComponents[] = {
+'C','o','m','p','o','n','e','n','t','s',0 };
+
+ package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ return ERROR_INVALID_HANDLE;
+
+ /* writes the Component and Features values to the registry */
+ sz = 0x100;
+ rc = MsiGetPropertyW(hPackage,szProductCode,productcode,&sz);
+
+ if (rc != ERROR_SUCCESS)
+ return ERROR_SUCCESS;
+
+ squash_guid(productcode,squished_pc);
+ rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller,&hkey);
+ if (rc != ERROR_SUCCESS)
+ goto end;
+
+ rc = RegCreateKeyW(hkey,szFeatures,&hkey2);
+ if (rc != ERROR_SUCCESS)
+ goto end;
+
+ rc = RegCreateKeyW(hkey2,squished_pc,&hkey3);
+ if (rc != ERROR_SUCCESS)
+ goto end;
+
+ /* I have no idea what goes in here */
+ for (i = 0; i < package->loaded_features; i++)
+ RegSetValueExW(hkey3,package->features[i].Feature,0,REG_SZ,NULL,0);
+
+ RegCloseKey(hkey3);
+ RegCloseKey(hkey2);
+
+ rc = RegCreateKeyW(hkey,szComponents,&hkey2);
+ if (rc != ERROR_SUCCESS)
+ goto end;
+
+ for (i = 0; i < package->loaded_components; i++)
+ {
+ if (package->components[i].ComponentId[0]!=0)
+ {
+ WCHAR keypath[0x1000];
+ MSIHANDLE uirow;
+
+ squash_guid(package->components[i].ComponentId,squished_cc);
+ rc = RegCreateKeyW(hkey2,squished_cc,&hkey3);
+ if (rc != ERROR_SUCCESS)
+ continue;
+
+ resolve_keypath(hPackage,package,i,keypath);
+
+ RegSetValueExW(hkey3,squished_pc,0,REG_SZ,(LPVOID)keypath,
+ (strlenW(keypath)+1)*sizeof(WCHAR));
+ RegCloseKey(hkey3);
+
+ /* UI stuff */
+ uirow = MsiCreateRecord(3);
+ MsiRecordSetStringW(uirow,1,productcode);
+ MsiRecordSetStringW(uirow,2,package->components[i].ComponentId);
+ MsiRecordSetStringW(uirow,3,keypath);
+ ui_actiondata(hPackage,szProcessComponents,uirow);
+ MsiCloseHandle(uirow);
+ }
+ }
+end:
+ RegCloseKey(hkey2);
+ RegCloseKey(hkey);
+ return rc;
+}
+
/* Msi functions that seem approperate here */
UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
{
diff -ur dlls/msi.old/cond.y dlls/msi/cond.y
--- dlls/msi.old/cond.y 2004-07-03 20:20:24.000000000 -0500
+++ dlls/msi/cond.y 2004-07-03 20:20:46.000000000 -0500
@@ -493,6 +493,19 @@
%%
+static int COND_IsAlpha( WCHAR x )
+{
+ return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
+ ( ( x >= 'a' ) && ( x <= 'z' ) ) ||
+ ( ( x == '_' ) ) );
+}
+
+static int COND_IsNumber( WCHAR x )
+{
+ return( ( x >= '0' ) && ( x <= '9' ) );
+}
+
+
/* the mess of comparison functions */
static INT comp_lt_i(INT a, INT b)
@@ -544,43 +557,32 @@
static INT comp_eq_m1(LPWSTR a, INT b)
-{ return atoiW(a)==b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)==b; else return 0;}
static INT comp_ne_m1(LPWSTR a, INT b)
-{ return atoiW(a)!=b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)!=b; else return 1;}
static INT comp_lt_m1(LPWSTR a, INT b)
-{ return atoiW(a)<b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)<b; else return 0;}
static INT comp_gt_m1(LPWSTR a, INT b)
-{ return atoiW(a)>b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)>b; else return 0;}
static INT comp_le_m1(LPWSTR a, INT b)
-{ return atoiW(a)<=b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)<=b; else return 0;}
static INT comp_ge_m1(LPWSTR a, INT b)
-{ return atoiW(a)>=b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)>=b; else return 0;}
static INT comp_eq_m2(INT a, LPWSTR b)
-{ return a == atoiW(b); }
+{ if (COND_IsNumber(b[0])) return a == atoiW(b); else return 0;}
static INT comp_ne_m2(INT a, LPWSTR b)
-{ return a != atoiW(b); }
+{ if (COND_IsNumber(b[0])) return a != atoiW(b); else return 1;}
static INT comp_lt_m2(INT a, LPWSTR b)
-{ return a < atoiW(b); }
+{ if (COND_IsNumber(b[0])) return a < atoiW(b); else return 0;}
static INT comp_gt_m2(INT a, LPWSTR b)
-{ return a > atoiW(b); }
+{ if (COND_IsNumber(b[0])) return a > atoiW(b); else return 0;}
static INT comp_le_m2(INT a, LPWSTR b)
-{ return a <= atoiW(b); }
+{ if (COND_IsNumber(b[0])) return a <= atoiW(b); else return 0;}
static INT comp_ge_m2(INT a, LPWSTR b)
-{ return a >= atoiW(b); }
-
+{ if (COND_IsNumber(b[0])) return a >= atoiW(b); else return 0;}
-static int COND_IsAlpha( WCHAR x )
-{
- return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
- ( ( x >= 'a' ) && ( x <= 'z' ) ) ||
- ( ( x == '_' ) ) );
-}
-static int COND_IsNumber( WCHAR x )
-{
- return( ( x >= '0' ) && ( x <= '9' ) );
-}
static int COND_IsIdent( WCHAR x )
{
diff -ur dlls/msi.old/msipriv.h dlls/msi/msipriv.h
--- dlls/msi.old/msipriv.h 2004-07-03 20:20:24.000000000 -0500
+++ dlls/msi/msipriv.h 2004-07-03 20:20:46.000000000 -0500
@@ -235,6 +235,8 @@
extern UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm );
extern void enum_stream_names( IStorage *stg );
+BOOL unsquash_guid(LPCWSTR in, LPWSTR out);
+BOOL squash_guid(LPCWSTR in, LPWSTR out);
/* UI globals */
extern INSTALLUILEVEL gUILevel;
diff -ur dlls/msi.old/package.c dlls/msi/package.c
--- dlls/msi.old/package.c 2004-07-03 20:20:24.000000000 -0500
+++ dlls/msi/package.c 2004-07-03 20:20:46.000000000 -0500
@@ -381,7 +381,7 @@
DWORD total_size = 0;
INT msg_field=1;
INT i;
- FIXME("STUB: %x \n",eMessageType);
+ TRACE("%x \n",eMessageType);
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ERROR)
log_type |= INSTALLLOGMODE_ERROR;
More information about the wine-patches
mailing list