Commit 6269f00c authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

Implementations for SelfRegModules and PublishFeatures.

Set default ACTION property for Install. Deformat more than JUST properties properly. Allows for Files and Component paths in deformat. Properly deformat a LaunchCondition failure dialog box. Resolve and save registry Keypaths. Write the Features published keys more correctly. Still some problems.
parent 82a6a3b8
...@@ -160,6 +160,8 @@ static UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package); ...@@ -160,6 +160,8 @@ static UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package);
static UINT ACTION_CreateShortcuts(MSIPACKAGE *package); static UINT ACTION_CreateShortcuts(MSIPACKAGE *package);
static UINT ACTION_PublishProduct(MSIPACKAGE *package); static UINT ACTION_PublishProduct(MSIPACKAGE *package);
static UINT ACTION_WriteIniValues(MSIPACKAGE *package); static UINT ACTION_WriteIniValues(MSIPACKAGE *package);
static UINT ACTION_SelfRegModules(MSIPACKAGE *package);
static UINT ACTION_PublishFeatures(MSIPACKAGE *package);
static UINT HANDLE_CustomType1(MSIPACKAGE *package, const LPWSTR source, static UINT HANDLE_CustomType1(MSIPACKAGE *package, const LPWSTR source,
const LPWSTR target, const INT type); const LPWSTR target, const INT type);
...@@ -175,7 +177,8 @@ static UINT HANDLE_CustomType34(MSIPACKAGE *package, const LPWSTR source, ...@@ -175,7 +177,8 @@ static UINT HANDLE_CustomType34(MSIPACKAGE *package, const LPWSTR source,
static DWORD deformat_string(MSIPACKAGE *package, WCHAR* ptr,WCHAR** data); static DWORD deformat_string(MSIPACKAGE *package, WCHAR* ptr,WCHAR** data);
static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, static LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name,
BOOL source, BOOL set_prop, MSIFOLDER **folder); BOOL source, BOOL set_prop, MSIFOLDER **folder);
static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name,
LPWSTR *FilePath);
static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path); static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
/* /*
...@@ -226,6 +229,10 @@ const static WCHAR szPublishProduct[] = ...@@ -226,6 +229,10 @@ const static WCHAR szPublishProduct[] =
{'P','u','b','l','i','s','h','P','r','o','d','u','c','t',0}; {'P','u','b','l','i','s','h','P','r','o','d','u','c','t',0};
const static WCHAR szWriteIniValues[] = const static WCHAR szWriteIniValues[] =
{'W','r','i','t','e','I','n','i','V','a','l','u','e','s',0}; {'W','r','i','t','e','I','n','i','V','a','l','u','e','s',0};
const static WCHAR szSelfRegModules[] =
{'S','e','l','f','R','e','g','M','o','d','u','l','e','s',0};
const static WCHAR szPublishFeatures[] =
{'P','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};
/******************************************************** /********************************************************
* helper functions to get around current HACKS and such * helper functions to get around current HACKS and such
...@@ -767,6 +774,10 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath, ...@@ -767,6 +774,10 @@ UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
WCHAR buffer[10]; WCHAR buffer[10];
UINT rc; UINT rc;
static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0}; static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
static const WCHAR szAction[] = {'A','C','T','I','O','N',0};
static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0};
MSI_SetPropertyW(package, szAction, szInstall);
if (szPackagePath) if (szPackagePath)
{ {
...@@ -1225,6 +1236,10 @@ UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action) ...@@ -1225,6 +1236,10 @@ UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action)
rc = ACTION_PublishProduct(package); rc = ACTION_PublishProduct(package);
else if (strcmpW(action,szWriteIniValues)==0) else if (strcmpW(action,szWriteIniValues)==0)
rc = ACTION_WriteIniValues(package); rc = ACTION_WriteIniValues(package);
else if (strcmpW(action,szSelfRegModules)==0)
rc = ACTION_SelfRegModules(package);
else if (strcmpW(action,szPublishFeatures)==0)
rc = ACTION_PublishFeatures(package);
/* /*
Called during iTunes but unimplemented and seem important Called during iTunes but unimplemented and seem important
...@@ -1411,6 +1426,8 @@ static UINT store_binary_to_temp(MSIPACKAGE *package, const LPWSTR source, ...@@ -1411,6 +1426,8 @@ static UINT store_binary_to_temp(MSIPACKAGE *package, const LPWSTR source,
} }
typedef UINT __stdcall CustomEntry(MSIHANDLE); typedef UINT __stdcall CustomEntry(MSIHANDLE);
typedef UINT __stdcall DllRegisterServer();
typedef struct typedef struct
{ {
MSIPACKAGE *package; MSIPACKAGE *package;
...@@ -2684,7 +2701,7 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) ...@@ -2684,7 +2701,7 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
WCHAR filever[0x100]; WCHAR filever[0x100];
VS_FIXEDFILEINFO *lpVer; VS_FIXEDFILEINFO *lpVer;
FIXME("Version comparison.. \n"); TRACE("Version comparison.. \n");
versize = GetFileVersionInfoSizeW(file->TargetPath,&handle); versize = GetFileVersionInfoSizeW(file->TargetPath,&handle);
version = HeapAlloc(GetProcessHeap(),0,versize); version = HeapAlloc(GetProcessHeap(),0,versize);
GetFileVersionInfoW(file->TargetPath, 0, versize, version); GetFileVersionInfoW(file->TargetPath, 0, versize, version);
...@@ -3694,9 +3711,10 @@ static DWORD deformat_string(MSIPACKAGE *package, WCHAR* ptr,WCHAR** data) ...@@ -3694,9 +3711,10 @@ static DWORD deformat_string(MSIPACKAGE *package, WCHAR* ptr,WCHAR** data)
DWORD size=0; DWORD size=0;
DWORD chunk=0; DWORD chunk=0;
WCHAR key[0x100]; WCHAR key[0x100];
LPWSTR value; LPWSTR value = NULL;
DWORD sz; DWORD sz;
UINT rc; UINT rc;
INT index;
if (ptr==NULL) if (ptr==NULL)
{ {
...@@ -3741,14 +3759,59 @@ static DWORD deformat_string(MSIPACKAGE *package, WCHAR* ptr,WCHAR** data) ...@@ -3741,14 +3759,59 @@ static DWORD deformat_string(MSIPACKAGE *package, WCHAR* ptr,WCHAR** data)
mark++; mark++;
TRACE("Current %s .. %s\n",debugstr_w(*data),debugstr_w(mark)); TRACE("Current %s .. %s\n",debugstr_w(*data),debugstr_w(mark));
sz = 0; sz = 0;
rc = MSI_GetPropertyW(package, key, NULL, &sz); /* expand what we can deformat... Again, this should become a bison file */
if ((rc == ERROR_SUCCESS) || (rc == ERROR_MORE_DATA)) switch (key[0])
{ {
LPWSTR newdata; case '~':
ERR("UNHANDLED DEFORMAT.. [~] should be NULL\n");
rc = ERROR_FUNCTION_FAILED;
break;
case '$':
ERR("POORLY HANDLED DEFORMAT.. [$componentkey] \n");
index = get_loaded_component(package,&key[1]);
if (index >= 0)
{
value = resolve_folder(package,
package->components[index].Directory,
FALSE, FALSE, NULL);
rc = 0;
}
else
rc = ERROR_FUNCTION_FAILED;
break;
case '#':
index = get_loaded_file(package,&key[1]);
if (index >=0)
{
sz = strlenW(package->files[index].TargetPath);
value = dupstrW(package->files[index].TargetPath);
rc= ERROR_SUCCESS;
}
else
rc = ERROR_FUNCTION_FAILED;
break;
case '\\':
value = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*2);
value[0] = key[1];
rc = ERROR_SUCCESS;
break;
case '%':
sz = GetEnvironmentVariableW(&key[1],NULL,0);
sz++;
value = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
GetEnvironmentVariableW(&key[1],value,sz);
rc = ERROR_SUCCESS;
break;
default:
rc = MSI_GetPropertyW(package, key, NULL, &sz);
sz++; sz++;
value = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR)); value = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
MSI_GetPropertyW(package, key, value, &sz); MSI_GetPropertyW(package, key, value, &sz);
break;
}
if (((rc == ERROR_SUCCESS) || (rc == ERROR_MORE_DATA))&& value!=NULL)
{
LPWSTR newdata;
chunk = (strlenW(value)+1) * sizeof(WCHAR); chunk = (strlenW(value)+1) * sizeof(WCHAR);
size+=chunk; size+=chunk;
...@@ -3875,9 +3938,12 @@ static UINT ACTION_LaunchConditions(MSIPACKAGE *package) ...@@ -3875,9 +3938,12 @@ static UINT ACTION_LaunchConditions(MSIPACKAGE *package)
if (MSI_EvaluateConditionW(package,cond) != MSICONDITION_TRUE) if (MSI_EvaluateConditionW(package,cond) != MSICONDITION_TRUE)
{ {
LPWSTR deformated;
message = load_dynamic_stringW(row,2); message = load_dynamic_stringW(row,2);
MessageBoxW(NULL,message,title,MB_OK); deformat_string(package,message,&deformated);
MessageBoxW(NULL,deformated,title,MB_OK);
HeapFree(GetProcessHeap(),0,message); HeapFree(GetProcessHeap(),0,message);
HeapFree(GetProcessHeap(),0,deformated);
rc = ERROR_FUNCTION_FAILED; rc = ERROR_FUNCTION_FAILED;
} }
HeapFree(GetProcessHeap(),0,cond); HeapFree(GetProcessHeap(),0,cond);
...@@ -3898,9 +3964,71 @@ static LPWSTR resolve_keypath( MSIPACKAGE* package, INT ...@@ -3898,9 +3964,71 @@ static LPWSTR resolve_keypath( MSIPACKAGE* package, INT
LPWSTR p = resolve_folder(package,cmp->Directory,FALSE,FALSE,NULL); LPWSTR p = resolve_folder(package,cmp->Directory,FALSE,FALSE,NULL);
return p; return p;
} }
if ((cmp->Attributes & 0x4) || (cmp->Attributes & 0x20)) if (cmp->Attributes & 0x4)
{
MSIQUERY * view;
MSIRECORD * row = 0;
UINT rc,root,len;
LPWSTR key,deformated,buffer,name,deformated_name;
static const WCHAR ExecSeqQuery[] = {
's','e','l','e','c','t',' ','*',' ',
'f','r','o','m',' ','R','e','g','i','s','t','r','y',' ',
'w','h','e','r','e',' ','R','e','g','i','s','t','r','y',' ','=',' '
,'`','%','s','`',0 };
static const WCHAR fmt[]={'%','0','2','i',':','%','s',0};
static const WCHAR fmt2[]={'%','0','2','i',':','%','s','\\','%','s',0};
rc = ACTION_OpenQuery(package->db,&view,ExecSeqQuery,cmp->KeyPath);
if (rc!=ERROR_SUCCESS)
return NULL;
rc = MSI_ViewExecute(view, 0);
if (rc != ERROR_SUCCESS)
{
MSI_ViewClose(view);
msiobj_release(&view->hdr);
return NULL;
}
rc = MSI_ViewFetch(view,&row);
if (rc != ERROR_SUCCESS)
{ {
FIXME("UNIMPLEMENTED keypath as Registry or ODBC Source\n"); MSI_ViewClose(view);
msiobj_release(&view->hdr);
return NULL;
}
root = MSI_RecordGetInteger(row,2);
key = load_dynamic_stringW(row, 3);
name = load_dynamic_stringW(row, 4);
deformat_string(package, key , &deformated);
deformat_string(package, name, &deformated_name);
len = strlenW(deformated) + 5;
if (deformated_name)
len+=strlenW(deformated_name);
buffer = HeapAlloc(GetProcessHeap(),0, len *sizeof(WCHAR));
if (deformated_name)
sprintfW(buffer,fmt2,root,deformated,deformated_name);
else
sprintfW(buffer,fmt,root,deformated);
HeapFree(GetProcessHeap(),0,key);
HeapFree(GetProcessHeap(),0,deformated);
HeapFree(GetProcessHeap(),0,name);
HeapFree(GetProcessHeap(),0,deformated_name);
msiobj_release(&row->hdr);
MSI_ViewClose(view);
msiobj_release(&view->hdr);
return buffer;
}
else if (cmp->Attributes & 0x20)
{
FIXME("UNIMPLEMENTED keypath as ODBC Source\n");
return NULL; return NULL;
} }
else else
...@@ -3940,8 +4068,6 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) ...@@ -3940,8 +4068,6 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
'W','i','n','d','o','w','s','\\', 'W','i','n','d','o','w','s','\\',
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'I','n','s','t','a','l','l','e','r',0 }; '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[] = { static const WCHAR szComponents[] = {
'C','o','m','p','o','n','e','n','t','s',0 }; 'C','o','m','p','o','n','e','n','t','s',0 };
...@@ -3958,48 +4084,6 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) ...@@ -3958,48 +4084,6 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
goto end; 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;
/* here the guids are base 85 encoded */
for (i = 0; i < package->loaded_features; i++)
{
LPWSTR data = NULL;
GUID clsid;
int j;
INT size;
size = package->features[i].ComponentCount*21*sizeof(WCHAR);
data = HeapAlloc(GetProcessHeap(), 0, size);
data[0] = 0;
for (j = 0; j < package->features[i].ComponentCount; j++)
{
WCHAR buf[21];
TRACE("From %s\n",debugstr_w(package->components
[package->features[i].Components[j]].ComponentId));
CLSIDFromString(package->components
[package->features[i].Components[j]].ComponentId,
&clsid);
encode_base85_guid(&clsid,buf);
TRACE("to %s\n",debugstr_w(buf));
strcatW(data,buf);
}
size = strlenW(data)*sizeof(WCHAR);
RegSetValueExW(hkey3,package->features[i].Feature,0,REG_SZ,
(LPSTR)data,size);
HeapFree(GetProcessHeap(),0,data);
}
RegCloseKey(hkey3);
RegCloseKey(hkey2);
rc = RegCreateKeyW(hkey,szComponents,&hkey2); rc = RegCreateKeyW(hkey,szComponents,&hkey2);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
goto end; goto end;
...@@ -4418,9 +4502,12 @@ end: ...@@ -4418,9 +4502,12 @@ end:
return rc; return rc;
} }
static UINT register_progid_base(MSIRECORD * row, LPWSTR clsid) static UINT register_progid_base(MSIPACKAGE* package, MSIRECORD * row,
LPWSTR clsid)
{ {
static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 }; static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };
static const WCHAR szDefaultIcon[] = {
'D','e','f','a','u','l','t','I','c','o','n',0};
HKEY hkey,hkey2; HKEY hkey,hkey2;
WCHAR buffer[0x100]; WCHAR buffer[0x100];
DWORD sz; DWORD sz;
...@@ -4458,7 +4545,25 @@ static UINT register_progid_base(MSIRECORD * row, LPWSTR clsid) ...@@ -4458,7 +4545,25 @@ static UINT register_progid_base(MSIRECORD * row, LPWSTR clsid)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
} }
if (!MSI_RecordIsNull(row,5)) if (!MSI_RecordIsNull(row,5))
FIXME ("UNHANDLED icon in Progid\n"); {
INT index = MSI_RecordGetInteger(row,6);
LPWSTR FileName = load_dynamic_stringW(row,5);
LPWSTR FilePath,IconPath;
static const WCHAR fmt[] = {'%','s',',','%','i',0};
RegCreateKeyW(hkey,szDefaultIcon,&hkey2);
build_icon_path(package,FileName,&FilePath);
IconPath = HeapAlloc(GetProcessHeap(),0,(strlenW(FilePath)+5)*
sizeof(WCHAR));
sprintfW(IconPath,fmt,FilePath,index);
RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)IconPath,
(strlenW(IconPath)+1) * sizeof(WCHAR));
HeapFree(GetProcessHeap(),0,FilePath);
HeapFree(GetProcessHeap(),0,FileName);
RegCloseKey(hkey2);
}
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -4511,13 +4616,15 @@ static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid) ...@@ -4511,13 +4616,15 @@ static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid)
UINT rc = ERROR_SUCCESS; UINT rc = ERROR_SUCCESS;
if (MSI_RecordIsNull(row,2)) if (MSI_RecordIsNull(row,2))
rc = register_progid_base(row,clsid); rc = register_progid_base(package,row,clsid);
else else
{ {
WCHAR buffer[0x1000]; WCHAR buffer[0x1000];
DWORD sz, disp; DWORD sz, disp;
HKEY hkey,hkey2; HKEY hkey,hkey2;
static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 }; static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };
static const WCHAR szDefaultIcon[] = {
'D','e','f','a','u','l','t','I','c','o','n',0};
/* check if already registered */ /* check if already registered */
sz = 0x100; sz = 0x100;
...@@ -4530,6 +4637,11 @@ static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid) ...@@ -4530,6 +4637,11 @@ static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid)
RegCloseKey(hkey); RegCloseKey(hkey);
return rc; return rc;
} }
sz = 0x100;
MSI_RecordGetStringW(row,2,buffer,&sz);
rc = register_parent_progid(package,buffer,clsid);
/* clsid is same as parent */ /* clsid is same as parent */
RegCreateKeyW(hkey,szCLSID,&hkey2); RegCreateKeyW(hkey,szCLSID,&hkey2);
RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)clsid, (strlenW(clsid)+1) * RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)clsid, (strlenW(clsid)+1) *
...@@ -4537,9 +4649,6 @@ static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid) ...@@ -4537,9 +4649,6 @@ static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid)
RegCloseKey(hkey2); RegCloseKey(hkey2);
sz = 0x100;
MSI_RecordGetStringW(row,2,buffer,&sz);
rc = register_parent_progid(package,buffer,clsid);
if (!MSI_RecordIsNull(row,4)) if (!MSI_RecordIsNull(row,4))
{ {
...@@ -4550,7 +4659,17 @@ static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid) ...@@ -4550,7 +4659,17 @@ static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid)
} }
if (!MSI_RecordIsNull(row,5)) if (!MSI_RecordIsNull(row,5))
FIXME ("UNHANDLED icon in Progid\n"); {
LPWSTR FileName = load_dynamic_stringW(row,5);
LPWSTR FilePath;
RegCreateKeyW(hkey,szDefaultIcon,&hkey2);
build_icon_path(package,FileName,&FilePath);
RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)FilePath,
(strlenW(FilePath)+1) * sizeof(WCHAR));
HeapFree(GetProcessHeap(),0,FilePath);
HeapFree(GetProcessHeap(),0,FileName);
RegCloseKey(hkey2);
}
RegCloseKey(hkey); RegCloseKey(hkey);
} }
...@@ -4847,6 +4966,29 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package) ...@@ -4847,6 +4966,29 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
'S','E','L','E','C','T',' ','*',' ', 'S','E','L','E','C','T',' ','*',' ',
'f','r','o','m',' ','I','c','o','n',0}; 'f','r','o','m',' ','I','c','o','n',0};
DWORD sz; DWORD sz;
/* for registry stuff */
LPWSTR productcode;
WCHAR squished_pc[0x100];
HKEY hkey=0,hkey2=0,hkey3=0;
HKEY hukey=0,hukey2=0,hukey3=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 szUserInstaller[] = {
'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'I','n','s','t','a','l','l','e','r',0 };
static const WCHAR szProducts[] = {
'P','r','o','d','u','c','t','s',0};
static const WCHAR szProductName[] = {
'P','r','o','d','u','c','t','N','a','m','e',0};
LPWSTR buffer;
DWORD size;
if (!package) if (!package)
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
...@@ -4924,6 +5066,53 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package) ...@@ -4924,6 +5066,53 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
} }
MSI_ViewClose(view); MSI_ViewClose(view);
msiobj_release(&view->hdr); msiobj_release(&view->hdr);
/* ok there is alot more done here but i need to figure out what */
productcode = load_dynamic_property(package,szProductCode,&rc);
if (!productcode)
return rc;
squash_guid(productcode,squished_pc);
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller,&hkey);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegCreateKeyW(HKEY_CURRENT_USER,szUserInstaller,&hukey);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegCreateKeyW(hkey,szProducts,&hkey2);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegCreateKeyW(hukey,szProducts,&hukey2);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegCreateKeyW(hkey2,squished_pc,&hkey3);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegCreateKeyW(hukey2,squished_pc,&hukey3);
if (rc != ERROR_SUCCESS)
goto end;
buffer = load_dynamic_property(package,szProductName,NULL);
size = strlenW(buffer)*sizeof(WCHAR);
RegSetValueExW(hukey3,szProductName,0,REG_SZ, (LPSTR)buffer,size);
HeapFree(GetProcessHeap(),0,buffer);
end:
HeapFree(GetProcessHeap(),0,productcode);
RegCloseKey(hkey3);
RegCloseKey(hkey2);
RegCloseKey(hkey);
RegCloseKey(hukey3);
RegCloseKey(hukey2);
RegCloseKey(hukey);
return rc; return rc;
} }
...@@ -5072,6 +5261,188 @@ cleanup: ...@@ -5072,6 +5261,188 @@ cleanup:
return rc; return rc;
} }
static UINT ACTION_SelfRegModules(MSIPACKAGE *package)
{
UINT rc;
MSIQUERY * view;
MSIRECORD * row = 0;
static const WCHAR ExecSeqQuery[] = {'S','e','l','e','c','t',' ','*',' ',
'f','r','o','m',' ','S','e','l','f','R','e','g',0};
rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
if (rc != ERROR_SUCCESS)
{
TRACE("no SelfReg table\n");
return ERROR_SUCCESS;
}
rc = MSI_ViewExecute(view, 0);
if (rc != ERROR_SUCCESS)
{
MSI_ViewClose(view);
msiobj_release(&view->hdr);
return rc;
}
while (1)
{
LPWSTR filename;
INT index;
HMODULE dll;
DllRegisterServer* regfunc;
rc = MSI_ViewFetch(view,&row);
if (rc != ERROR_SUCCESS)
{
rc = ERROR_SUCCESS;
break;
}
filename = load_dynamic_stringW(row,1);
index = get_loaded_file(package,filename);
if (index < 0)
{
ERR("Unable to find file id %s\n",debugstr_w(filename));
HeapFree(GetProcessHeap(),0,filename);
msiobj_release(&row->hdr);
continue;
}
HeapFree(GetProcessHeap(),0,filename);
dll = LoadLibraryW(package->files[index].TargetPath);
if (!dll)
{
ERR("Unable to load dll %s\n",
debugstr_w(package->files[index].TargetPath));
msiobj_release(&row->hdr);
continue;
}
regfunc = (DllRegisterServer*)GetProcAddress(dll,"DllRegisterServer");
if (regfunc)
regfunc();
msiobj_release(&row->hdr);
}
MSI_ViewClose(view);
msiobj_release(&view->hdr);
return rc;
}
static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
{
LPWSTR productcode;
WCHAR squished_pc[0x100];
UINT rc;
DWORD i;
HKEY hkey=0,hkey2=0,hkey3=0;
HKEY hukey=0,hukey2=0,hukey3=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 szUserInstaller[] = {
'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'I','n','s','t','a','l','l','e','r',0 };
static const WCHAR szFeatures[] = {
'F','e','a','t','u','r','e','s',0 };
if (!package)
return ERROR_INVALID_HANDLE;
productcode = load_dynamic_property(package,szProductCode,&rc);
if (!productcode)
return rc;
squash_guid(productcode,squished_pc);
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller,&hkey);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegCreateKeyW(HKEY_CURRENT_USER,szUserInstaller,&hukey);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegCreateKeyW(hkey,szFeatures,&hkey2);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegCreateKeyW(hukey,szFeatures,&hukey2);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegCreateKeyW(hkey2,squished_pc,&hkey3);
if (rc != ERROR_SUCCESS)
goto end;
rc = RegCreateKeyW(hukey2,squished_pc,&hukey3);
if (rc != ERROR_SUCCESS)
goto end;
/* here the guids are base 85 encoded */
for (i = 0; i < package->loaded_features; i++)
{
LPWSTR data = NULL;
GUID clsid;
int j;
INT size;
size = package->features[i].ComponentCount*21;
size +=1;
if (package->features[i].Feature_Parent[0])
size += strlenW(package->features[i].Feature_Parent)+2;
data = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
data[0] = 0;
for (j = 0; j < package->features[i].ComponentCount; j++)
{
WCHAR buf[21];
memset(buf,0,sizeof(buf));
TRACE("From %s\n",debugstr_w(package->components
[package->features[i].Components[j]].ComponentId));
CLSIDFromString(package->components
[package->features[i].Components[j]].ComponentId,
&clsid);
encode_base85_guid(&clsid,buf);
TRACE("to %s\n",debugstr_w(buf));
strcatW(data,buf);
}
if (package->features[i].Feature_Parent[0])
{
static const WCHAR sep[] = {'\2',0};
strcatW(data,sep);
strcatW(data,package->features[i].Feature_Parent);
}
size = (strlenW(data)+2)*sizeof(WCHAR);
RegSetValueExW(hkey3,package->features[i].Feature,0,REG_SZ,
(LPSTR)data,size);
HeapFree(GetProcessHeap(),0,data);
size = strlenW(package->features[i].Feature_Parent)*sizeof(WCHAR);
RegSetValueExW(hukey3,package->features[i].Feature,0,REG_SZ,
(LPSTR)package->features[i].Feature_Parent,size);
}
RegCloseKey(hkey3);
RegCloseKey(hukey3);
end:
HeapFree(GetProcessHeap(), 0, productcode);
RegCloseKey(hkey2);
RegCloseKey(hukey2);
RegCloseKey(hkey);
RegCloseKey(hukey);
return rc;
}
/* Msi functions that seem appropriate here */ /* Msi functions that seem appropriate here */
UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction ) UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
{ {
...@@ -5554,21 +5925,21 @@ static UINT ACTION_Template(MSIPACKAGE *package) ...@@ -5554,21 +5925,21 @@ static UINT ACTION_Template(MSIPACKAGE *package)
MSIRECORD * row = 0; MSIRECORD * row = 0;
static const WCHAR ExecSeqQuery[] = {0}; static const WCHAR ExecSeqQuery[] = {0};
rc = MsiDatabaseOpenViewW(package->db, ExecSeqQuery, &view); rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return rc; return rc;
rc = MsiViewExecute(view, 0); rc = MSI_ViewExecute(view, 0);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
MsiViewClose(view); MSI_ViewClose(view);
msiobj_release(&view->hdr); msiobj_release(&view->hdr);
return rc; return rc;
} }
while (1) while (1)
{ {
rc = MsiViewFetch(view,&row); rc = MSI_ViewFetch(view,&row);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
rc = ERROR_SUCCESS; rc = ERROR_SUCCESS;
...@@ -5577,7 +5948,7 @@ static UINT ACTION_Template(MSIPACKAGE *package) ...@@ -5577,7 +5948,7 @@ static UINT ACTION_Template(MSIPACKAGE *package)
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
} }
MsiViewClose(view); MSI_ViewClose(view);
msiobj_release(&view->hdr); msiobj_release(&view->hdr);
return rc; return rc;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment