2006-02-17 00:04:10 +00:00
|
|
|
/*
|
|
|
|
* Implementation of the Microsoft Installer (msi.dll)
|
|
|
|
*
|
|
|
|
* Copyright 2004 Aric Stewart for CodeWeavers
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2006-08-01 23:12:11 +00:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2006-02-17 00:04:10 +00:00
|
|
|
*/
|
|
|
|
|
2013-12-25 20:42:59 +00:00
|
|
|
#include "msipriv.h"
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2013-01-24 23:00:42 +00:00
|
|
|
#include <wininet.h>
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
|
|
|
|
2010-02-06 21:28:28 +00:00
|
|
|
static void remove_tracked_tempfiles( MSIPACKAGE *package )
|
|
|
|
{
|
|
|
|
struct list *item, *cursor;
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->tempfiles )
|
|
|
|
{
|
|
|
|
MSITEMPFILE *temp = LIST_ENTRY( item, MSITEMPFILE, entry );
|
|
|
|
|
|
|
|
list_remove( &temp->entry );
|
|
|
|
TRACE("deleting temp file %s\n", debugstr_w( temp->Path ));
|
2011-03-20 08:47:41 +00:00
|
|
|
DeleteFileW( temp->Path );
|
2010-02-06 21:28:28 +00:00
|
|
|
msi_free( temp->Path );
|
|
|
|
msi_free( temp );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_feature( MSIFEATURE *feature )
|
|
|
|
{
|
|
|
|
struct list *item, *cursor;
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &feature->Children )
|
|
|
|
{
|
|
|
|
FeatureList *fl = LIST_ENTRY( item, FeatureList, entry );
|
|
|
|
list_remove( &fl->entry );
|
|
|
|
msi_free( fl );
|
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &feature->Components )
|
|
|
|
{
|
|
|
|
ComponentList *cl = LIST_ENTRY( item, ComponentList, entry );
|
|
|
|
list_remove( &cl->entry );
|
|
|
|
msi_free( cl );
|
|
|
|
}
|
|
|
|
msi_free( feature->Feature );
|
|
|
|
msi_free( feature->Feature_Parent );
|
|
|
|
msi_free( feature->Directory );
|
|
|
|
msi_free( feature->Description );
|
|
|
|
msi_free( feature->Title );
|
|
|
|
msi_free( feature );
|
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
static void free_folder( MSIFOLDER *folder )
|
|
|
|
{
|
|
|
|
struct list *item, *cursor;
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &folder->children )
|
|
|
|
{
|
|
|
|
FolderList *fl = LIST_ENTRY( item, FolderList, entry );
|
|
|
|
list_remove( &fl->entry );
|
|
|
|
msi_free( fl );
|
|
|
|
}
|
|
|
|
msi_free( folder->Parent );
|
|
|
|
msi_free( folder->Directory );
|
|
|
|
msi_free( folder->TargetDefault );
|
|
|
|
msi_free( folder->SourceLongPath );
|
|
|
|
msi_free( folder->SourceShortPath );
|
|
|
|
msi_free( folder->ResolvedTarget );
|
|
|
|
msi_free( folder->ResolvedSource );
|
|
|
|
msi_free( folder );
|
|
|
|
}
|
|
|
|
|
2010-02-06 21:28:28 +00:00
|
|
|
static void free_extension( MSIEXTENSION *ext )
|
|
|
|
{
|
|
|
|
struct list *item, *cursor;
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &ext->verbs )
|
|
|
|
{
|
|
|
|
MSIVERB *verb = LIST_ENTRY( item, MSIVERB, entry );
|
|
|
|
|
|
|
|
list_remove( &verb->entry );
|
|
|
|
msi_free( verb->Verb );
|
|
|
|
msi_free( verb->Command );
|
|
|
|
msi_free( verb->Argument );
|
|
|
|
msi_free( verb );
|
|
|
|
}
|
|
|
|
|
|
|
|
msi_free( ext->Extension );
|
|
|
|
msi_free( ext->ProgIDText );
|
|
|
|
msi_free( ext );
|
|
|
|
}
|
|
|
|
|
2011-03-20 08:47:41 +00:00
|
|
|
static void free_assembly( MSIASSEMBLY *assembly )
|
|
|
|
{
|
|
|
|
msi_free( assembly->feature );
|
|
|
|
msi_free( assembly->manifest );
|
|
|
|
msi_free( assembly->application );
|
|
|
|
msi_free( assembly->display_name );
|
|
|
|
if (assembly->tempdir) RemoveDirectoryW( assembly->tempdir );
|
|
|
|
msi_free( assembly->tempdir );
|
|
|
|
msi_free( assembly );
|
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
void msi_free_action_script( MSIPACKAGE *package, UINT script )
|
|
|
|
{
|
|
|
|
UINT i;
|
|
|
|
for (i = 0; i < package->script->ActionCount[script]; i++)
|
|
|
|
msi_free( package->script->Actions[script][i] );
|
|
|
|
|
|
|
|
msi_free( package->script->Actions[script] );
|
|
|
|
package->script->Actions[script] = NULL;
|
|
|
|
package->script->ActionCount[script] = 0;
|
|
|
|
}
|
|
|
|
|
2010-02-06 21:28:28 +00:00
|
|
|
static void free_package_structures( MSIPACKAGE *package )
|
|
|
|
{
|
|
|
|
struct list *item, *cursor;
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->features )
|
|
|
|
{
|
|
|
|
MSIFEATURE *feature = LIST_ENTRY( item, MSIFEATURE, entry );
|
|
|
|
list_remove( &feature->entry );
|
|
|
|
free_feature( feature );
|
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->folders )
|
|
|
|
{
|
|
|
|
MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
|
|
|
|
list_remove( &folder->entry );
|
2012-01-21 17:19:12 +00:00
|
|
|
free_folder( folder );
|
2010-02-06 21:28:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->components )
|
|
|
|
{
|
|
|
|
MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
|
|
|
|
|
|
|
|
list_remove( &comp->entry );
|
|
|
|
msi_free( comp->Component );
|
|
|
|
msi_free( comp->ComponentId );
|
|
|
|
msi_free( comp->Directory );
|
|
|
|
msi_free( comp->Condition );
|
|
|
|
msi_free( comp->KeyPath );
|
|
|
|
msi_free( comp->FullKeypath );
|
2011-03-20 08:47:41 +00:00
|
|
|
if (comp->assembly) free_assembly( comp->assembly );
|
2010-02-06 21:28:28 +00:00
|
|
|
msi_free( comp );
|
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->files )
|
|
|
|
{
|
|
|
|
MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry );
|
|
|
|
|
|
|
|
list_remove( &file->entry );
|
|
|
|
msi_free( file->File );
|
|
|
|
msi_free( file->FileName );
|
|
|
|
msi_free( file->ShortName );
|
|
|
|
msi_free( file->LongName );
|
|
|
|
msi_free( file->Version );
|
|
|
|
msi_free( file->Language );
|
|
|
|
msi_free( file->TargetPath );
|
|
|
|
msi_free( file );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clean up extension, progid, class and verb structures */
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->classes )
|
|
|
|
{
|
|
|
|
MSICLASS *cls = LIST_ENTRY( item, MSICLASS, entry );
|
|
|
|
|
|
|
|
list_remove( &cls->entry );
|
|
|
|
msi_free( cls->clsid );
|
|
|
|
msi_free( cls->Context );
|
|
|
|
msi_free( cls->Description );
|
|
|
|
msi_free( cls->FileTypeMask );
|
|
|
|
msi_free( cls->IconPath );
|
|
|
|
msi_free( cls->DefInprocHandler );
|
|
|
|
msi_free( cls->DefInprocHandler32 );
|
|
|
|
msi_free( cls->Argument );
|
|
|
|
msi_free( cls->ProgIDText );
|
|
|
|
msi_free( cls );
|
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->extensions )
|
|
|
|
{
|
|
|
|
MSIEXTENSION *ext = LIST_ENTRY( item, MSIEXTENSION, entry );
|
|
|
|
|
|
|
|
list_remove( &ext->entry );
|
|
|
|
free_extension( ext );
|
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->progids )
|
|
|
|
{
|
|
|
|
MSIPROGID *progid = LIST_ENTRY( item, MSIPROGID, entry );
|
|
|
|
|
|
|
|
list_remove( &progid->entry );
|
|
|
|
msi_free( progid->ProgID );
|
|
|
|
msi_free( progid->Description );
|
|
|
|
msi_free( progid->IconPath );
|
|
|
|
msi_free( progid );
|
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->mimes )
|
|
|
|
{
|
|
|
|
MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry );
|
|
|
|
|
|
|
|
list_remove( &mt->entry );
|
2010-05-29 08:55:43 +00:00
|
|
|
msi_free( mt->suffix );
|
2010-02-06 21:28:28 +00:00
|
|
|
msi_free( mt->clsid );
|
|
|
|
msi_free( mt->ContentType );
|
|
|
|
msi_free( mt );
|
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->appids )
|
|
|
|
{
|
|
|
|
MSIAPPID *appid = LIST_ENTRY( item, MSIAPPID, entry );
|
|
|
|
|
|
|
|
list_remove( &appid->entry );
|
|
|
|
msi_free( appid->AppID );
|
|
|
|
msi_free( appid->RemoteServerName );
|
|
|
|
msi_free( appid->LocalServer );
|
|
|
|
msi_free( appid->ServiceParameters );
|
|
|
|
msi_free( appid->DllSurrogate );
|
|
|
|
msi_free( appid );
|
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_info )
|
|
|
|
{
|
|
|
|
MSISOURCELISTINFO *info = LIST_ENTRY( item, MSISOURCELISTINFO, entry );
|
|
|
|
|
|
|
|
list_remove( &info->entry );
|
|
|
|
msi_free( info->value );
|
|
|
|
msi_free( info );
|
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_media )
|
|
|
|
{
|
|
|
|
MSIMEDIADISK *info = LIST_ENTRY( item, MSIMEDIADISK, entry );
|
|
|
|
|
|
|
|
list_remove( &info->entry );
|
|
|
|
msi_free( info->volume_label );
|
|
|
|
msi_free( info->disk_prompt );
|
|
|
|
msi_free( info );
|
|
|
|
}
|
|
|
|
|
|
|
|
if (package->script)
|
|
|
|
{
|
2013-04-03 21:58:03 +00:00
|
|
|
INT i;
|
|
|
|
UINT j;
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
for (i = 0; i < SCRIPT_MAX; i++)
|
2010-02-06 21:28:28 +00:00
|
|
|
msi_free_action_script( package, i );
|
|
|
|
|
2013-04-03 21:58:03 +00:00
|
|
|
for (j = 0; j < package->script->UniqueActionsCount; j++)
|
|
|
|
msi_free( package->script->UniqueActions[j] );
|
2010-02-06 21:28:28 +00:00
|
|
|
|
|
|
|
msi_free( package->script->UniqueActions );
|
|
|
|
msi_free( package->script );
|
|
|
|
}
|
|
|
|
|
2011-03-20 08:47:41 +00:00
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->binaries )
|
|
|
|
{
|
|
|
|
MSIBINARY *binary = LIST_ENTRY( item, MSIBINARY, entry );
|
|
|
|
|
|
|
|
list_remove( &binary->entry );
|
|
|
|
if (binary->module)
|
|
|
|
FreeLibrary( binary->module );
|
|
|
|
if (!DeleteFileW( binary->tmpfile ))
|
|
|
|
ERR("failed to delete %s (%u)\n", debugstr_w(binary->tmpfile), GetLastError());
|
|
|
|
msi_free( binary->source );
|
|
|
|
msi_free( binary->tmpfile );
|
|
|
|
msi_free( binary );
|
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->cabinet_streams )
|
|
|
|
{
|
|
|
|
MSICABINETSTREAM *cab = LIST_ENTRY( item, MSICABINETSTREAM, entry );
|
|
|
|
|
|
|
|
list_remove( &cab->entry );
|
|
|
|
IStorage_Release( cab->storage );
|
|
|
|
msi_free( cab->stream );
|
|
|
|
msi_free( cab );
|
|
|
|
}
|
|
|
|
|
|
|
|
LIST_FOR_EACH_SAFE( item, cursor, &package->patches )
|
|
|
|
{
|
|
|
|
MSIPATCHINFO *patch = LIST_ENTRY( item, MSIPATCHINFO, entry );
|
|
|
|
|
|
|
|
list_remove( &patch->entry );
|
|
|
|
if (patch->delete_on_close && !DeleteFileW( patch->localfile ))
|
|
|
|
{
|
|
|
|
ERR("failed to delete %s (%u)\n", debugstr_w(patch->localfile), GetLastError());
|
|
|
|
}
|
|
|
|
msi_free_patchinfo( patch );
|
|
|
|
}
|
|
|
|
|
2010-02-06 21:28:28 +00:00
|
|
|
msi_free( package->BaseURL );
|
|
|
|
msi_free( package->PackagePath );
|
|
|
|
msi_free( package->ProductCode );
|
|
|
|
msi_free( package->ActionFormat );
|
|
|
|
msi_free( package->LastAction );
|
2010-10-22 13:18:11 +00:00
|
|
|
msi_free( package->langids );
|
2010-02-06 21:28:28 +00:00
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
remove_tracked_tempfiles(package);
|
|
|
|
|
2010-02-06 21:28:28 +00:00
|
|
|
/* cleanup control event subscriptions */
|
2013-09-22 16:30:18 +00:00
|
|
|
msi_event_cleanup_all_subscriptions( package );
|
2010-02-06 21:28:28 +00:00
|
|
|
}
|
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
static void MSI_FreePackage( MSIOBJECTHDR *arg)
|
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
MSIPACKAGE *package = (MSIPACKAGE *)arg;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2012-08-13 16:17:18 +00:00
|
|
|
msi_destroy_assembly_caches( package );
|
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
if( package->dialog )
|
|
|
|
msi_dialog_destroy( package->dialog );
|
2008-01-16 10:11:22 +00:00
|
|
|
|
|
|
|
msiobj_release( &package->db->hdr );
|
2010-02-06 21:28:28 +00:00
|
|
|
free_package_structures(package);
|
2011-03-20 08:47:41 +00:00
|
|
|
CloseHandle( package->log_file );
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
if (package->delete_on_close) DeleteFileW( package->localfile );
|
|
|
|
msi_free( package->localfile );
|
2008-01-16 10:11:22 +00:00
|
|
|
}
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
static UINT create_temp_property_table(MSIPACKAGE *package)
|
|
|
|
{
|
2012-01-21 17:19:12 +00:00
|
|
|
static const WCHAR query[] = {
|
|
|
|
'C','R','E','A','T','E',' ','T','A','B','L','E',' ',
|
|
|
|
'`','_','P','r','o','p','e','r','t','y','`',' ','(',' ',
|
|
|
|
'`','_','P','r','o','p','e','r','t','y','`',' ',
|
|
|
|
'C','H','A','R','(','5','6',')',' ','N','O','T',' ','N','U','L','L',' ',
|
|
|
|
'T','E','M','P','O','R','A','R','Y',',',' ',
|
|
|
|
'`','V','a','l','u','e','`',' ','C','H','A','R','(','9','8',')',' ',
|
|
|
|
'N','O','T',' ','N','U','L','L',' ','T','E','M','P','O','R','A','R','Y',
|
|
|
|
' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ',
|
|
|
|
'`','_','P','r','o','p','e','r','t','y','`',')',' ','H','O','L','D',0};
|
|
|
|
MSIQUERY *view;
|
2008-01-16 10:11:22 +00:00
|
|
|
UINT rc;
|
2006-08-30 19:24:26 +00:00
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
rc = MSI_DatabaseOpenViewW(package->db, query, &view);
|
2008-01-16 10:11:22 +00:00
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
rc = MSI_ViewExecute(view, 0);
|
|
|
|
MSI_ViewClose(view);
|
|
|
|
msiobj_release(&view->hdr);
|
|
|
|
return rc;
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
UINT msi_clone_properties(MSIPACKAGE *package)
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
static const WCHAR query_select[] = {
|
2012-01-21 17:19:12 +00:00
|
|
|
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
|
|
|
'`','P','r','o','p','e','r','t','y','`',0};
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
static const WCHAR query_insert[] = {
|
2012-01-21 17:19:12 +00:00
|
|
|
'I','N','S','E','R','T',' ','I','N','T','O',' ',
|
|
|
|
'`','_','P','r','o','p','e','r','t','y','`',' ',
|
|
|
|
'(','`','_','P','r','o','p','e','r','t','y','`',',','`','V','a','l','u','e','`',')',' ',
|
|
|
|
'V','A','L','U','E','S',' ','(','?',',','?',')',0};
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
static const WCHAR query_update[] = {
|
|
|
|
'U','P','D','A','T','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ',
|
|
|
|
'S','E','T',' ','`','V','a','l','u','e','`',' ','=',' ','?',' ',
|
|
|
|
'W','H','E','R','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','?',0};
|
2012-01-21 17:19:12 +00:00
|
|
|
MSIQUERY *view_select;
|
|
|
|
UINT rc;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
rc = MSI_DatabaseOpenViewW( package->db, query_select, &view_select );
|
2006-02-17 00:04:10 +00:00
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
return rc;
|
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
rc = MSI_ViewExecute( view_select, 0 );
|
2006-02-17 00:04:10 +00:00
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
{
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
MSI_ViewClose( view_select );
|
|
|
|
msiobj_release( &view_select->hdr );
|
2006-02-17 00:04:10 +00:00
|
|
|
return rc;
|
|
|
|
}
|
2008-01-16 10:11:22 +00:00
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
while (1)
|
|
|
|
{
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
MSIQUERY *view_insert, *view_update;
|
|
|
|
MSIRECORD *rec_select;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
rc = MSI_ViewFetch( view_select, &rec_select );
|
2006-02-17 00:04:10 +00:00
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
break;
|
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
rc = MSI_DatabaseOpenViewW( package->db, query_insert, &view_insert );
|
2008-01-16 10:11:22 +00:00
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
{
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
msiobj_release( &rec_select->hdr );
|
2008-01-16 10:11:22 +00:00
|
|
|
continue;
|
|
|
|
}
|
2006-08-30 19:24:26 +00:00
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
rc = MSI_ViewExecute( view_insert, rec_select );
|
|
|
|
MSI_ViewClose( view_insert );
|
|
|
|
msiobj_release( &view_insert->hdr );
|
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
MSIRECORD *rec_update;
|
2008-01-16 10:11:22 +00:00
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
TRACE("insert failed, trying update\n");
|
|
|
|
|
|
|
|
rc = MSI_DatabaseOpenViewW( package->db, query_update, &view_update );
|
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
WARN("open view failed %u\n", rc);
|
|
|
|
msiobj_release( &rec_select->hdr );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
rec_update = MSI_CreateRecord( 2 );
|
|
|
|
MSI_RecordCopyField( rec_select, 1, rec_update, 2 );
|
|
|
|
MSI_RecordCopyField( rec_select, 2, rec_update, 1 );
|
|
|
|
rc = MSI_ViewExecute( view_update, rec_update );
|
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
WARN("update failed %u\n", rc);
|
|
|
|
|
|
|
|
MSI_ViewClose( view_update );
|
|
|
|
msiobj_release( &view_update->hdr );
|
|
|
|
msiobj_release( &rec_update->hdr );
|
|
|
|
}
|
2006-08-30 19:24:26 +00:00
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
msiobj_release( &rec_select->hdr );
|
|
|
|
}
|
|
|
|
|
|
|
|
MSI_ViewClose( view_select );
|
|
|
|
msiobj_release( &view_select->hdr );
|
2006-02-17 00:04:10 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* set_installed_prop
|
|
|
|
*
|
|
|
|
* Sets the "Installed" property to indicate that
|
|
|
|
* the product is installed for the current user.
|
|
|
|
*/
|
|
|
|
static UINT set_installed_prop( MSIPACKAGE *package )
|
|
|
|
{
|
2012-01-21 17:19:12 +00:00
|
|
|
HKEY hkey;
|
2006-02-17 00:04:10 +00:00
|
|
|
UINT r;
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
if (!package->ProductCode) return ERROR_FUNCTION_FAILED;
|
|
|
|
|
|
|
|
r = MSIREG_OpenUninstallKey( package->ProductCode, package->platform, &hkey, FALSE );
|
2006-02-17 00:04:10 +00:00
|
|
|
if (r == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
RegCloseKey( hkey );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szInstalled, szOne, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
static UINT set_user_sid_prop( MSIPACKAGE *package )
|
|
|
|
{
|
|
|
|
SID_NAME_USE use;
|
|
|
|
LPWSTR user_name;
|
|
|
|
LPWSTR sid_str = NULL, dom = NULL;
|
|
|
|
DWORD size, dom_size;
|
|
|
|
PSID psid = NULL;
|
|
|
|
UINT r = ERROR_FUNCTION_FAILED;
|
|
|
|
|
|
|
|
size = 0;
|
|
|
|
GetUserNameW( NULL, &size );
|
|
|
|
|
|
|
|
user_name = msi_alloc( (size + 1) * sizeof(WCHAR) );
|
|
|
|
if (!user_name)
|
|
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
|
|
|
|
if (!GetUserNameW( user_name, &size ))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
size = 0;
|
|
|
|
dom_size = 0;
|
|
|
|
LookupAccountNameW( NULL, user_name, NULL, &size, NULL, &dom_size, &use );
|
|
|
|
|
|
|
|
psid = msi_alloc( size );
|
|
|
|
dom = msi_alloc( dom_size*sizeof (WCHAR) );
|
|
|
|
if (!psid || !dom)
|
|
|
|
{
|
|
|
|
r = ERROR_OUTOFMEMORY;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!LookupAccountNameW( NULL, user_name, psid, &size, dom, &dom_size, &use ))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (!ConvertSidToStringSidW( psid, &sid_str ))
|
|
|
|
goto done;
|
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
r = msi_set_property( package->db, szUserSID, sid_str, -1 );
|
2008-01-16 10:11:22 +00:00
|
|
|
|
|
|
|
done:
|
|
|
|
LocalFree( sid_str );
|
|
|
|
msi_free( dom );
|
|
|
|
msi_free( psid );
|
|
|
|
msi_free( user_name );
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LPWSTR get_fusion_filename(MSIPACKAGE *package)
|
|
|
|
{
|
|
|
|
HKEY netsetup;
|
|
|
|
LONG res;
|
2009-05-20 12:59:23 +00:00
|
|
|
LPWSTR file = NULL;
|
2008-01-16 10:11:22 +00:00
|
|
|
DWORD index = 0, size;
|
|
|
|
WCHAR ver[MAX_PATH];
|
|
|
|
WCHAR name[MAX_PATH];
|
|
|
|
WCHAR windir[MAX_PATH];
|
|
|
|
|
|
|
|
static const WCHAR fusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
|
|
|
|
static const WCHAR sub[] = {
|
|
|
|
'S','o','f','t','w','a','r','e','\\',
|
|
|
|
'M','i','c','r','o','s','o','f','t','\\',
|
|
|
|
'N','E','T',' ','F','r','a','m','e','w','o','r','k',' ','S','e','t','u','p','\\',
|
|
|
|
'N','D','P',0
|
|
|
|
};
|
|
|
|
static const WCHAR subdir[] = {
|
|
|
|
'M','i','c','r','o','s','o','f','t','.','N','E','T','\\',
|
|
|
|
'F','r','a','m','e','w','o','r','k','\\',0
|
|
|
|
};
|
|
|
|
|
|
|
|
res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, sub, 0, KEY_ENUMERATE_SUB_KEYS, &netsetup);
|
|
|
|
if (res != ERROR_SUCCESS)
|
|
|
|
return NULL;
|
|
|
|
|
2009-05-20 12:59:23 +00:00
|
|
|
GetWindowsDirectoryW(windir, MAX_PATH);
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
ver[0] = '\0';
|
|
|
|
size = MAX_PATH;
|
|
|
|
while (RegEnumKeyExW(netsetup, index, name, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
index++;
|
|
|
|
|
2009-05-20 12:59:23 +00:00
|
|
|
/* verify existence of fusion.dll .Net 3.0 does not install a new one */
|
2011-03-20 08:47:41 +00:00
|
|
|
if (strcmpW( ver, name ) < 0)
|
2009-05-20 12:59:23 +00:00
|
|
|
{
|
|
|
|
LPWSTR check;
|
|
|
|
size = lstrlenW(windir) + lstrlenW(subdir) + lstrlenW(name) +lstrlenW(fusion) + 3;
|
|
|
|
check = msi_alloc(size * sizeof(WCHAR));
|
2008-01-16 10:11:22 +00:00
|
|
|
|
2009-05-20 12:59:23 +00:00
|
|
|
if (!check)
|
|
|
|
{
|
|
|
|
msi_free(file);
|
|
|
|
return NULL;
|
|
|
|
}
|
2008-01-16 10:11:22 +00:00
|
|
|
|
2009-05-20 12:59:23 +00:00
|
|
|
lstrcpyW(check, windir);
|
2009-10-25 11:06:09 +00:00
|
|
|
lstrcatW(check, szBackSlash);
|
2009-05-20 12:59:23 +00:00
|
|
|
lstrcatW(check, subdir);
|
|
|
|
lstrcatW(check, name);
|
2009-10-25 11:06:09 +00:00
|
|
|
lstrcatW(check, szBackSlash);
|
2009-05-20 12:59:23 +00:00
|
|
|
lstrcatW(check, fusion);
|
2008-01-16 10:11:22 +00:00
|
|
|
|
2009-05-20 12:59:23 +00:00
|
|
|
if(GetFileAttributesW(check) != INVALID_FILE_ATTRIBUTES)
|
|
|
|
{
|
|
|
|
msi_free(file);
|
|
|
|
file = check;
|
|
|
|
lstrcpyW(ver, name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
msi_free(check);
|
|
|
|
}
|
|
|
|
}
|
2008-01-16 10:11:22 +00:00
|
|
|
|
2009-05-20 12:59:23 +00:00
|
|
|
RegCloseKey(netsetup);
|
2008-01-16 10:11:22 +00:00
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct tagLANGANDCODEPAGE
|
|
|
|
{
|
|
|
|
WORD wLanguage;
|
|
|
|
WORD wCodePage;
|
|
|
|
} LANGANDCODEPAGE;
|
|
|
|
|
|
|
|
static void set_msi_assembly_prop(MSIPACKAGE *package)
|
|
|
|
{
|
|
|
|
UINT val_len;
|
|
|
|
DWORD size, handle;
|
|
|
|
LPVOID version = NULL;
|
|
|
|
WCHAR buf[MAX_PATH];
|
|
|
|
LPWSTR fusion, verstr;
|
|
|
|
LANGANDCODEPAGE *translate;
|
|
|
|
|
|
|
|
static const WCHAR netasm[] = {
|
|
|
|
'M','s','i','N','e','t','A','s','s','e','m','b','l','y','S','u','p','p','o','r','t',0
|
|
|
|
};
|
|
|
|
static const WCHAR translation[] = {
|
|
|
|
'\\','V','a','r','F','i','l','e','I','n','f','o',
|
|
|
|
'\\','T','r','a','n','s','l','a','t','i','o','n',0
|
|
|
|
};
|
|
|
|
static const WCHAR verfmt[] = {
|
|
|
|
'\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
|
|
|
|
'\\','%','0','4','x','%','0','4','x',
|
|
|
|
'\\','P','r','o','d','u','c','t','V','e','r','s','i','o','n',0
|
|
|
|
};
|
|
|
|
|
|
|
|
fusion = get_fusion_filename(package);
|
|
|
|
if (!fusion)
|
|
|
|
return;
|
|
|
|
|
|
|
|
size = GetFileVersionInfoSizeW(fusion, &handle);
|
2012-12-09 19:43:59 +00:00
|
|
|
if (!size)
|
|
|
|
goto done;
|
2008-01-16 10:11:22 +00:00
|
|
|
|
|
|
|
version = msi_alloc(size);
|
2012-12-09 19:43:59 +00:00
|
|
|
if (!version)
|
|
|
|
goto done;
|
2008-01-16 10:11:22 +00:00
|
|
|
|
|
|
|
if (!GetFileVersionInfoW(fusion, handle, size, version))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (!VerQueryValueW(version, translation, (LPVOID *)&translate, &val_len))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
sprintfW(buf, verfmt, translate[0].wLanguage, translate[0].wCodePage);
|
|
|
|
|
|
|
|
if (!VerQueryValueW(version, buf, (LPVOID *)&verstr, &val_len))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (!val_len || !verstr)
|
|
|
|
goto done;
|
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, netasm, verstr, -1 );
|
2008-01-16 10:11:22 +00:00
|
|
|
|
|
|
|
done:
|
|
|
|
msi_free(fusion);
|
|
|
|
msi_free(version);
|
|
|
|
}
|
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
static VOID set_installer_properties(MSIPACKAGE *package)
|
|
|
|
{
|
|
|
|
WCHAR *ptr;
|
2008-01-16 10:11:22 +00:00
|
|
|
OSVERSIONINFOEXW OSVersion;
|
2006-02-17 00:04:10 +00:00
|
|
|
MEMORYSTATUSEX msex;
|
2009-12-06 14:55:00 +00:00
|
|
|
DWORD verval, len;
|
2012-08-13 16:17:18 +00:00
|
|
|
WCHAR pth[MAX_PATH], verstr[11], bufstr[22];
|
2006-02-17 00:04:10 +00:00
|
|
|
HDC dc;
|
2006-10-22 20:23:59 +00:00
|
|
|
HKEY hkey;
|
2008-04-04 13:43:40 +00:00
|
|
|
LPWSTR username, companyname;
|
2008-01-16 10:11:22 +00:00
|
|
|
SYSTEM_INFO sys_info;
|
|
|
|
SYSTEMTIME systemtime;
|
2008-04-04 13:43:40 +00:00
|
|
|
LANGID langid;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
static const WCHAR szCommonFilesFolder[] = {'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szProgramFilesFolder[] = {'P','r','o','g','r','a','m','F','i','l','e','s','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szCommonAppDataFolder[] = {'C','o','m','m','o','n','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szFavoritesFolder[] = {'F','a','v','o','r','i','t','e','s','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szFontsFolder[] = {'F','o','n','t','s','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szSendToFolder[] = {'S','e','n','d','T','o','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szStartMenuFolder[] = {'S','t','a','r','t','M','e','n','u','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szStartupFolder[] = {'S','t','a','r','t','u','p','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szTemplateFolder[] = {'T','e','m','p','l','a','t','e','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szDesktopFolder[] = {'D','e','s','k','t','o','p','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szProgramMenuFolder[] = {'P','r','o','g','r','a','m','M','e','n','u','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szAdminToolsFolder[] = {'A','d','m','i','n','T','o','o','l','s','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szSystemFolder[] = {'S','y','s','t','e','m','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szSystem16Folder[] = {'S','y','s','t','e','m','1','6','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szLocalAppDataFolder[] = {'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szMyPicturesFolder[] = {'M','y','P','i','c','t','u','r','e','s','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szPersonalFolder[] = {'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szWindowsVolume[] = {'W','i','n','d','o','w','s','V','o','l','u','m','e',0};
|
|
|
|
static const WCHAR szPrivileged[] = {'P','r','i','v','i','l','e','g','e','d',0};
|
|
|
|
static const WCHAR szVersion9x[] = {'V','e','r','s','i','o','n','9','X',0};
|
|
|
|
static const WCHAR szVersionNT[] = {'V','e','r','s','i','o','n','N','T',0};
|
|
|
|
static const WCHAR szMsiNTProductType[] = {'M','s','i','N','T','P','r','o','d','u','c','t','T','y','p','e',0};
|
2012-08-13 16:17:18 +00:00
|
|
|
static const WCHAR szFormat[] = {'%','u',0};
|
|
|
|
static const WCHAR szFormat2[] = {'%','u','.','%','u',0};
|
2010-10-22 13:18:11 +00:00
|
|
|
static const WCHAR szWindowsBuild[] = {'W','i','n','d','o','w','s','B','u','i','l','d',0};
|
|
|
|
static const WCHAR szServicePackLevel[] = {'S','e','r','v','i','c','e','P','a','c','k','L','e','v','e','l',0};
|
2006-02-17 00:04:10 +00:00
|
|
|
static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 };
|
2008-01-16 10:11:22 +00:00
|
|
|
static const WCHAR szVersionDatabase[] = { 'V','e','r','s','i','o','n','D','a','t','a','b','a','s','e',0 };
|
2006-02-17 00:04:10 +00:00
|
|
|
static const WCHAR szPhysicalMemory[] = { 'P','h','y','s','i','c','a','l','M','e','m','o','r','y',0 };
|
|
|
|
static const WCHAR szScreenX[] = {'S','c','r','e','e','n','X',0};
|
|
|
|
static const WCHAR szScreenY[] = {'S','c','r','e','e','n','Y',0};
|
|
|
|
static const WCHAR szColorBits[] = {'C','o','l','o','r','B','i','t','s',0};
|
2008-04-04 13:43:40 +00:00
|
|
|
static const WCHAR szIntFormat[] = {'%','d',0};
|
2010-10-22 13:18:11 +00:00
|
|
|
static const WCHAR szMsiAMD64[] = { 'M','s','i','A','M','D','6','4',0 };
|
|
|
|
static const WCHAR szMsix64[] = { 'M','s','i','x','6','4',0 };
|
|
|
|
static const WCHAR szSystem64Folder[] = { 'S','y','s','t','e','m','6','4','F','o','l','d','e','r',0 };
|
|
|
|
static const WCHAR szCommonFiles64Folder[] = { 'C','o','m','m','o','n','F','i','l','e','s','6','4','F','o','l','d','e','r',0 };
|
|
|
|
static const WCHAR szProgramFiles64Folder[] = { 'P','r','o','g','r','a','m','F','i','l','e','s','6','4','F','o','l','d','e','r',0 };
|
|
|
|
static const WCHAR szVersionNT64[] = { 'V','e','r','s','i','o','n','N','T','6','4',0 };
|
2008-04-04 13:43:40 +00:00
|
|
|
static const WCHAR szUserInfo[] = {
|
|
|
|
'S','O','F','T','W','A','R','E','\\',
|
|
|
|
'M','i','c','r','o','s','o','f','t','\\',
|
|
|
|
'M','S',' ','S','e','t','u','p',' ','(','A','C','M','E',')','\\',
|
|
|
|
'U','s','e','r',' ','I','n','f','o',0
|
|
|
|
};
|
|
|
|
static const WCHAR szDefName[] = { 'D','e','f','N','a','m','e',0 };
|
|
|
|
static const WCHAR szDefCompany[] = { 'D','e','f','C','o','m','p','a','n','y',0 };
|
2006-10-22 20:23:59 +00:00
|
|
|
static const WCHAR szCurrentVersion[] = {
|
|
|
|
'S','O','F','T','W','A','R','E','\\',
|
|
|
|
'M','i','c','r','o','s','o','f','t','\\',
|
|
|
|
'W','i','n','d','o','w','s',' ','N','T','\\',
|
|
|
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0
|
|
|
|
};
|
|
|
|
static const WCHAR szRegisteredUser[] = {'R','e','g','i','s','t','e','r','e','d','O','w','n','e','r',0};
|
2010-10-22 13:18:11 +00:00
|
|
|
static const WCHAR szRegisteredOrganization[] = {
|
2006-10-22 20:23:59 +00:00
|
|
|
'R','e','g','i','s','t','e','r','e','d','O','r','g','a','n','i','z','a','t','i','o','n',0
|
|
|
|
};
|
|
|
|
static const WCHAR szUSERNAME[] = {'U','S','E','R','N','A','M','E',0};
|
|
|
|
static const WCHAR szCOMPANYNAME[] = {'C','O','M','P','A','N','Y','N','A','M','E',0};
|
2008-01-16 10:11:22 +00:00
|
|
|
static const WCHAR szDate[] = {'D','a','t','e',0};
|
|
|
|
static const WCHAR szTime[] = {'T','i','m','e',0};
|
2010-10-22 13:18:11 +00:00
|
|
|
static const WCHAR szUserLanguageID[] = {'U','s','e','r','L','a','n','g','u','a','g','e','I','D',0};
|
2009-05-20 12:59:23 +00:00
|
|
|
static const WCHAR szSystemLangID[] = {'S','y','s','t','e','m','L','a','n','g','u','a','g','e','I','D',0};
|
2009-10-17 21:16:57 +00:00
|
|
|
static const WCHAR szProductState[] = {'P','r','o','d','u','c','t','S','t','a','t','e',0};
|
2009-12-06 14:55:00 +00:00
|
|
|
static const WCHAR szLogonUser[] = {'L','o','g','o','n','U','s','e','r',0};
|
2010-10-22 13:18:11 +00:00
|
|
|
static const WCHAR szNetHoodFolder[] = {'N','e','t','H','o','o','d','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szPrintHoodFolder[] = {'P','r','i','n','t','H','o','o','d','F','o','l','d','e','r',0};
|
|
|
|
static const WCHAR szRecentFolder[] = {'R','e','c','e','n','t','F','o','l','d','e','r',0};
|
2012-01-21 17:19:12 +00:00
|
|
|
static const WCHAR szComputerName[] = {'C','o','m','p','u','t','e','r','N','a','m','e',0};
|
2013-04-03 21:58:03 +00:00
|
|
|
static const WCHAR szBrowseProperty[] = {'_','B','r','o','w','s','e','P','r','o','p','e','r','t','y',0};
|
|
|
|
static const WCHAR szInstallDir[] = {'I','N','S','T','A','L','L','D','I','R',0};
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Other things that probably should be set:
|
|
|
|
*
|
2012-01-21 17:19:12 +00:00
|
|
|
* VirtualMemory ShellAdvSupport DefaultUIFont PackagecodeChanging
|
|
|
|
* CaptionHeight BorderTop BorderSide TextHeight RedirectedDllSupport
|
2006-02-17 00:04:10 +00:00
|
|
|
*/
|
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szCommonAppDataFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_FAVORITES, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szFavoritesFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szFontsFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_SENDTO, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szSendToFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_STARTMENU, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szStartMenuFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_STARTUP, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szStartupFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_TEMPLATES, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szTemplateFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szDesktopFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
/* FIXME: set to AllUsers profile path if ALLUSERS is set */
|
|
|
|
SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szProgramMenuFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_ADMINTOOLS, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szAdminToolsFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szAppDataFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szSystemFolder, pth, -1 );
|
|
|
|
msi_set_property( package->db, szSystem16Folder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szLocalAppDataFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_MYPICTURES, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szMyPicturesFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szPersonalFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth);
|
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szWindowsFolder, pth, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
|
|
|
|
SHGetFolderPathW(NULL, CSIDL_PRINTHOOD, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szPrintHoodFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_NETHOOD, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szNetHoodFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_RECENT, NULL, 0, pth);
|
2009-10-25 11:06:09 +00:00
|
|
|
strcatW(pth, szBackSlash);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szRecentFolder, pth, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
/* Physical Memory is specified in MB. Using total amount. */
|
|
|
|
msex.dwLength = sizeof(msex);
|
|
|
|
GlobalMemoryStatusEx( &msex );
|
2012-12-09 19:43:59 +00:00
|
|
|
len = sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys / 1024 / 1024) );
|
|
|
|
msi_set_property( package->db, szPhysicalMemory, bufstr, len );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth);
|
2006-02-17 00:04:10 +00:00
|
|
|
ptr = strchrW(pth,'\\');
|
2010-10-22 13:18:11 +00:00
|
|
|
if (ptr) *(ptr + 1) = 0;
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szWindowsVolume, pth, -1 );
|
2008-01-16 10:11:22 +00:00
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
len = GetTempPathW(MAX_PATH, pth);
|
|
|
|
msi_set_property( package->db, szTempFolder, pth, len );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
/* in a wine environment the user is always admin and privileged */
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szAdminUser, szOne, -1 );
|
|
|
|
msi_set_property( package->db, szPrivileged, szOne, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
/* set the os things */
|
2008-01-16 10:11:22 +00:00
|
|
|
OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
|
|
|
|
GetVersionExW((OSVERSIONINFOW *)&OSVersion);
|
2010-10-22 13:18:11 +00:00
|
|
|
verval = OSVersion.dwMinorVersion + OSVersion.dwMajorVersion * 100;
|
2012-12-09 19:43:59 +00:00
|
|
|
len = sprintfW( verstr, szFormat, verval );
|
2006-02-17 00:04:10 +00:00
|
|
|
switch (OSVersion.dwPlatformId)
|
|
|
|
{
|
2008-01-16 10:11:22 +00:00
|
|
|
case VER_PLATFORM_WIN32_WINDOWS:
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szVersion9x, verstr, len );
|
2006-02-17 00:04:10 +00:00
|
|
|
break;
|
|
|
|
case VER_PLATFORM_WIN32_NT:
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szVersionNT, verstr, len );
|
2013-09-22 16:30:18 +00:00
|
|
|
len = sprintfW( bufstr, szFormat,OSVersion.wProductType );
|
|
|
|
msi_set_property( package->db, szMsiNTProductType, bufstr, len );
|
2006-02-17 00:04:10 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-09-22 16:30:18 +00:00
|
|
|
len = sprintfW( bufstr, szFormat, OSVersion.dwBuildNumber );
|
|
|
|
msi_set_property( package->db, szWindowsBuild, bufstr, len );
|
|
|
|
len = sprintfW( bufstr, szFormat, OSVersion.wServicePackMajor );
|
|
|
|
msi_set_property( package->db, szServicePackLevel, bufstr, len );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
len = sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION );
|
|
|
|
msi_set_property( package->db, szVersionMsi, bufstr, len );
|
|
|
|
len = sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100 );
|
|
|
|
msi_set_property( package->db, szVersionDatabase, bufstr, len );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
GetNativeSystemInfo( &sys_info );
|
2012-12-09 19:43:59 +00:00
|
|
|
len = sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel );
|
|
|
|
msi_set_property( package->db, szIntel, bufstr, len );
|
2006-02-17 00:04:10 +00:00
|
|
|
if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
|
|
|
|
{
|
2010-10-22 13:18:11 +00:00
|
|
|
GetSystemDirectoryW( pth, MAX_PATH );
|
|
|
|
PathAddBackslashW( pth );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szSystemFolder, pth, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
|
|
|
|
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth );
|
|
|
|
PathAddBackslashW( pth );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szProgramFilesFolder, pth, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
|
|
|
|
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth );
|
|
|
|
PathAddBackslashW( pth );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szCommonFilesFolder, pth, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
}
|
|
|
|
else if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
|
|
|
|
{
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szMsiAMD64, bufstr, -1 );
|
|
|
|
msi_set_property( package->db, szMsix64, bufstr, -1 );
|
|
|
|
msi_set_property( package->db, szVersionNT64, verstr, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
|
|
|
|
GetSystemDirectoryW( pth, MAX_PATH );
|
|
|
|
PathAddBackslashW( pth );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szSystem64Folder, pth, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
|
|
|
|
GetSystemWow64DirectoryW( pth, MAX_PATH );
|
|
|
|
PathAddBackslashW( pth );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szSystemFolder, pth, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
|
|
|
|
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth );
|
|
|
|
PathAddBackslashW( pth );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szProgramFiles64Folder, pth, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
|
|
|
|
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, pth );
|
|
|
|
PathAddBackslashW( pth );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szProgramFilesFolder, pth, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
|
|
|
|
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth );
|
|
|
|
PathAddBackslashW( pth );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szCommonFiles64Folder, pth, -1 );
|
2010-10-22 13:18:11 +00:00
|
|
|
|
|
|
|
SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, pth );
|
|
|
|
PathAddBackslashW( pth );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szCommonFilesFolder, pth, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Screen properties. */
|
|
|
|
dc = GetDC(0);
|
2012-12-09 19:43:59 +00:00
|
|
|
len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, HORZRES) );
|
|
|
|
msi_set_property( package->db, szScreenX, bufstr, len );
|
|
|
|
len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, VERTRES) );
|
|
|
|
msi_set_property( package->db, szScreenY, bufstr, len );
|
|
|
|
len = sprintfW( bufstr, szIntFormat, GetDeviceCaps(dc, BITSPIXEL) );
|
|
|
|
msi_set_property( package->db, szColorBits, bufstr, len );
|
2006-02-17 00:04:10 +00:00
|
|
|
ReleaseDC(0, dc);
|
2006-10-22 20:23:59 +00:00
|
|
|
|
|
|
|
/* USERNAME and COMPANYNAME */
|
2010-05-29 08:55:43 +00:00
|
|
|
username = msi_dup_property( package->db, szUSERNAME );
|
|
|
|
companyname = msi_dup_property( package->db, szCOMPANYNAME );
|
2006-10-22 20:23:59 +00:00
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
if ((!username || !companyname) &&
|
|
|
|
RegOpenKeyW( HKEY_CURRENT_USER, szUserInfo, &hkey ) == ERROR_SUCCESS)
|
2006-10-22 20:23:59 +00:00
|
|
|
{
|
2008-04-04 13:43:40 +00:00
|
|
|
if (!username &&
|
|
|
|
(username = msi_reg_get_val_str( hkey, szDefName )))
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szUSERNAME, username, -1 );
|
2008-04-04 13:43:40 +00:00
|
|
|
if (!companyname &&
|
|
|
|
(companyname = msi_reg_get_val_str( hkey, szDefCompany )))
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szCOMPANYNAME, companyname, -1 );
|
2008-04-04 13:43:40 +00:00
|
|
|
CloseHandle( hkey );
|
2006-10-22 20:23:59 +00:00
|
|
|
}
|
2008-04-04 13:43:40 +00:00
|
|
|
if ((!username || !companyname) &&
|
|
|
|
RegOpenKeyW( HKEY_LOCAL_MACHINE, szCurrentVersion, &hkey ) == ERROR_SUCCESS)
|
2006-10-22 20:23:59 +00:00
|
|
|
{
|
2008-04-04 13:43:40 +00:00
|
|
|
if (!username &&
|
|
|
|
(username = msi_reg_get_val_str( hkey, szRegisteredUser )))
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szUSERNAME, username, -1 );
|
2008-04-04 13:43:40 +00:00
|
|
|
if (!companyname &&
|
2010-10-22 13:18:11 +00:00
|
|
|
(companyname = msi_reg_get_val_str( hkey, szRegisteredOrganization )))
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szCOMPANYNAME, companyname, -1 );
|
2008-04-04 13:43:40 +00:00
|
|
|
CloseHandle( hkey );
|
2006-10-22 20:23:59 +00:00
|
|
|
}
|
2008-04-04 13:43:40 +00:00
|
|
|
msi_free( username );
|
|
|
|
msi_free( companyname );
|
2006-10-22 20:23:59 +00:00
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
if ( set_user_sid_prop( package ) != ERROR_SUCCESS)
|
|
|
|
ERR("Failed to set the UserSID property\n");
|
|
|
|
|
|
|
|
/* Date and time properties */
|
|
|
|
GetSystemTime( &systemtime );
|
|
|
|
if (GetDateFormatW( LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemtime,
|
|
|
|
NULL, bufstr, sizeof(bufstr)/sizeof(bufstr[0]) ))
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szDate, bufstr, -1 );
|
2008-01-16 10:11:22 +00:00
|
|
|
else
|
|
|
|
ERR("Couldn't set Date property: GetDateFormat failed with error %d\n", GetLastError());
|
|
|
|
|
|
|
|
if (GetTimeFormatW( LOCALE_USER_DEFAULT,
|
|
|
|
TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER,
|
|
|
|
&systemtime, NULL, bufstr,
|
|
|
|
sizeof(bufstr)/sizeof(bufstr[0]) ))
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szTime, bufstr, -1 );
|
2008-01-16 10:11:22 +00:00
|
|
|
else
|
|
|
|
ERR("Couldn't set Time property: GetTimeFormat failed with error %d\n", GetLastError());
|
|
|
|
|
|
|
|
set_msi_assembly_prop( package );
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
langid = GetUserDefaultLangID();
|
2012-12-09 19:43:59 +00:00
|
|
|
len = sprintfW( bufstr, szIntFormat, langid );
|
|
|
|
msi_set_property( package->db, szUserLanguageID, bufstr, len );
|
2009-05-20 12:59:23 +00:00
|
|
|
|
|
|
|
langid = GetSystemDefaultLangID();
|
2012-12-09 19:43:59 +00:00
|
|
|
len = sprintfW( bufstr, szIntFormat, langid );
|
|
|
|
msi_set_property( package->db, szSystemLangID, bufstr, len );
|
2009-10-17 21:16:57 +00:00
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
len = sprintfW( bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode) );
|
|
|
|
msi_set_property( package->db, szProductState, bufstr, len );
|
2009-12-06 14:55:00 +00:00
|
|
|
|
|
|
|
len = 0;
|
2012-01-21 17:19:12 +00:00
|
|
|
if (!GetUserNameW( NULL, &len ) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
2009-12-06 14:55:00 +00:00
|
|
|
{
|
|
|
|
WCHAR *username;
|
2010-05-29 08:55:43 +00:00
|
|
|
if ((username = msi_alloc( len * sizeof(WCHAR) )))
|
2009-12-06 14:55:00 +00:00
|
|
|
{
|
|
|
|
if (GetUserNameW( username, &len ))
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szLogonUser, username, len - 1 );
|
2010-05-29 08:55:43 +00:00
|
|
|
msi_free( username );
|
2009-12-06 14:55:00 +00:00
|
|
|
}
|
|
|
|
}
|
2012-01-21 17:19:12 +00:00
|
|
|
len = 0;
|
|
|
|
if (!GetComputerNameW( NULL, &len ) && GetLastError() == ERROR_BUFFER_OVERFLOW)
|
|
|
|
{
|
|
|
|
WCHAR *computername;
|
|
|
|
if ((computername = msi_alloc( len * sizeof(WCHAR) )))
|
|
|
|
{
|
|
|
|
if (GetComputerNameW( computername, &len ))
|
2013-09-22 16:30:18 +00:00
|
|
|
msi_set_property( package->db, szComputerName, computername, len );
|
2012-01-21 17:19:12 +00:00
|
|
|
msi_free( computername );
|
|
|
|
}
|
|
|
|
}
|
2013-04-03 21:58:03 +00:00
|
|
|
msi_set_property( package->db, szBrowseProperty, szInstallDir, -1 );
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
static UINT msi_load_summary_properties( MSIPACKAGE *package )
|
2006-08-30 19:24:26 +00:00
|
|
|
{
|
|
|
|
UINT rc;
|
|
|
|
MSIHANDLE suminfo;
|
|
|
|
MSIHANDLE hdb = alloc_msihandle( &package->db->hdr );
|
2008-01-16 10:11:22 +00:00
|
|
|
INT count;
|
|
|
|
DWORD len;
|
|
|
|
LPWSTR package_code;
|
|
|
|
static const WCHAR szPackageCode[] = {
|
|
|
|
'P','a','c','k','a','g','e','C','o','d','e',0};
|
2006-08-30 19:24:26 +00:00
|
|
|
|
|
|
|
if (!hdb) {
|
|
|
|
ERR("Unable to allocate handle\n");
|
2008-01-16 10:11:22 +00:00
|
|
|
return ERROR_OUTOFMEMORY;
|
2006-08-30 19:24:26 +00:00
|
|
|
}
|
2008-01-16 10:11:22 +00:00
|
|
|
|
2006-08-30 19:24:26 +00:00
|
|
|
rc = MsiGetSummaryInformationW( hdb, NULL, 0, &suminfo );
|
|
|
|
MsiCloseHandle(hdb);
|
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
ERR("Unable to open Summary Information\n");
|
2008-01-16 10:11:22 +00:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = MsiSummaryInfoGetPropertyW( suminfo, PID_PAGECOUNT, NULL,
|
|
|
|
&count, NULL, NULL, NULL );
|
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
WARN("Unable to query page count: %d\n", rc);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* load package code property */
|
|
|
|
len = 0;
|
|
|
|
rc = MsiSummaryInfoGetPropertyW( suminfo, PID_REVNUMBER, NULL,
|
|
|
|
NULL, NULL, NULL, &len );
|
|
|
|
if (rc != ERROR_MORE_DATA)
|
|
|
|
{
|
|
|
|
WARN("Unable to query revision number: %d\n", rc);
|
|
|
|
rc = ERROR_FUNCTION_FAILED;
|
|
|
|
goto done;
|
2006-08-30 19:24:26 +00:00
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
len++;
|
|
|
|
package_code = msi_alloc( len * sizeof(WCHAR) );
|
|
|
|
rc = MsiSummaryInfoGetPropertyW( suminfo, PID_REVNUMBER, NULL,
|
|
|
|
NULL, NULL, package_code, &len );
|
2006-08-30 19:24:26 +00:00
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
{
|
2008-01-16 10:11:22 +00:00
|
|
|
WARN("Unable to query rev number: %d\n", rc);
|
2014-04-23 14:48:52 +00:00
|
|
|
msi_free( package_code );
|
2008-01-16 10:11:22 +00:00
|
|
|
goto done;
|
2006-08-30 19:24:26 +00:00
|
|
|
}
|
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szPackageCode, package_code, len );
|
2008-01-16 10:11:22 +00:00
|
|
|
msi_free( package_code );
|
|
|
|
|
|
|
|
/* load package attributes */
|
|
|
|
count = 0;
|
|
|
|
MsiSummaryInfoGetPropertyW( suminfo, PID_WORDCOUNT, NULL,
|
|
|
|
&count, NULL, NULL, NULL );
|
|
|
|
package->WordCount = count;
|
|
|
|
|
|
|
|
done:
|
2006-08-30 19:24:26 +00:00
|
|
|
MsiCloseHandle(suminfo);
|
2008-01-16 10:11:22 +00:00
|
|
|
return rc;
|
2006-08-30 19:24:26 +00:00
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
static MSIPACKAGE *msi_alloc_package( void )
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
2008-01-16 10:11:22 +00:00
|
|
|
MSIPACKAGE *package;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
package = alloc_msiobject( MSIHANDLETYPE_PACKAGE, sizeof (MSIPACKAGE),
|
|
|
|
MSI_FreePackage );
|
|
|
|
if( package )
|
|
|
|
{
|
|
|
|
list_init( &package->components );
|
|
|
|
list_init( &package->features );
|
|
|
|
list_init( &package->files );
|
2012-01-21 17:19:12 +00:00
|
|
|
list_init( &package->filepatches );
|
2006-02-17 00:04:10 +00:00
|
|
|
list_init( &package->tempfiles );
|
|
|
|
list_init( &package->folders );
|
|
|
|
list_init( &package->subscriptions );
|
|
|
|
list_init( &package->appids );
|
|
|
|
list_init( &package->classes );
|
|
|
|
list_init( &package->mimes );
|
|
|
|
list_init( &package->extensions );
|
|
|
|
list_init( &package->progids );
|
|
|
|
list_init( &package->RunningActions );
|
2008-01-16 10:11:22 +00:00
|
|
|
list_init( &package->sourcelist_info );
|
|
|
|
list_init( &package->sourcelist_media );
|
2010-05-29 08:55:43 +00:00
|
|
|
list_init( &package->patches );
|
2011-03-20 08:47:41 +00:00
|
|
|
list_init( &package->binaries );
|
2012-01-21 17:19:12 +00:00
|
|
|
list_init( &package->cabinet_streams );
|
2008-01-16 10:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return package;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UINT msi_load_admin_properties(MSIPACKAGE *package)
|
|
|
|
{
|
|
|
|
BYTE *data;
|
|
|
|
UINT r, sz;
|
|
|
|
|
|
|
|
static const WCHAR stmname[] = {'A','d','m','i','n','P','r','o','p','e','r','t','i','e','s',0};
|
2006-08-30 19:24:26 +00:00
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
r = read_stream_data(package->db->storage, stmname, FALSE, &data, &sz);
|
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
return r;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2008-12-27 15:10:14 +00:00
|
|
|
r = msi_parse_command_line(package, (WCHAR *)data, TRUE);
|
2006-08-30 19:24:26 +00:00
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
msi_free(data);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
void msi_adjust_privilege_properties( MSIPACKAGE *package )
|
2009-12-22 09:28:03 +00:00
|
|
|
{
|
|
|
|
/* FIXME: this should depend on the user's privileges */
|
2010-05-29 08:55:43 +00:00
|
|
|
if (msi_get_property_int( package->db, szAllUsers, 0 ) == 2)
|
2009-12-22 09:28:03 +00:00
|
|
|
{
|
|
|
|
TRACE("resetting ALLUSERS property from 2 to 1\n");
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szAllUsers, szOne, -1 );
|
2009-12-22 09:28:03 +00:00
|
|
|
}
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szAdminUser, szOne, -1 );
|
2009-12-22 09:28:03 +00:00
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
|
|
|
|
{
|
2012-05-14 21:41:31 +00:00
|
|
|
static const WCHAR fmtW[] = {'%','u',0};
|
2008-01-16 10:11:22 +00:00
|
|
|
MSIPACKAGE *package;
|
2012-05-14 21:41:31 +00:00
|
|
|
WCHAR uilevel[11];
|
2012-12-09 19:43:59 +00:00
|
|
|
int len;
|
2008-01-16 10:11:22 +00:00
|
|
|
UINT r;
|
|
|
|
|
|
|
|
TRACE("%p\n", db);
|
|
|
|
|
|
|
|
package = msi_alloc_package();
|
|
|
|
if (package)
|
|
|
|
{
|
|
|
|
msiobj_addref( &db->hdr );
|
|
|
|
package->db = db;
|
|
|
|
|
|
|
|
package->WordCount = 0;
|
|
|
|
package->PackagePath = strdupW( db->path );
|
|
|
|
package->BaseURL = strdupW( base_url );
|
|
|
|
|
|
|
|
create_temp_property_table( package );
|
|
|
|
msi_clone_properties( package );
|
2010-10-22 13:18:11 +00:00
|
|
|
msi_adjust_privilege_properties( package );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2010-05-29 08:55:43 +00:00
|
|
|
package->ProductCode = msi_dup_property( package->db, szProductCode );
|
|
|
|
package->script = msi_alloc_zero( sizeof(MSISCRIPT) );
|
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
set_installed_prop( package );
|
2009-10-17 21:16:57 +00:00
|
|
|
set_installer_properties( package );
|
|
|
|
|
2012-05-14 21:41:31 +00:00
|
|
|
package->ui_level = gUILevel;
|
2012-12-09 19:43:59 +00:00
|
|
|
len = sprintfW( uilevel, fmtW, gUILevel & INSTALLUILEVEL_MASK );
|
|
|
|
msi_set_property( package->db, szUILevel, uilevel, len );
|
2009-10-17 21:16:57 +00:00
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
r = msi_load_summary_properties( package );
|
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
msiobj_release( &package->hdr );
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-09-21 15:24:30 +00:00
|
|
|
if (package->WordCount & msidbSumInfoSourceTypeAdminImage)
|
2008-01-16 10:11:22 +00:00
|
|
|
msi_load_admin_properties( package );
|
2011-03-20 08:47:41 +00:00
|
|
|
|
|
|
|
package->log_file = INVALID_HANDLE_VALUE;
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
return package;
|
|
|
|
}
|
|
|
|
|
2009-12-22 09:28:03 +00:00
|
|
|
UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename )
|
2006-08-01 23:12:11 +00:00
|
|
|
{
|
|
|
|
LPINTERNET_CACHE_ENTRY_INFOW cache_entry;
|
|
|
|
DWORD size = 0;
|
|
|
|
HRESULT hr;
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
/* call will always fail, because size is 0,
|
2006-08-01 23:12:11 +00:00
|
|
|
* but will return ERROR_FILE_NOT_FOUND first
|
|
|
|
* if the file doesn't exist
|
|
|
|
*/
|
|
|
|
GetUrlCacheEntryInfoW( szUrl, NULL, &size );
|
|
|
|
if ( GetLastError() != ERROR_FILE_NOT_FOUND )
|
|
|
|
{
|
2010-05-29 08:55:43 +00:00
|
|
|
cache_entry = msi_alloc( size );
|
2006-08-01 23:12:11 +00:00
|
|
|
if ( !GetUrlCacheEntryInfoW( szUrl, cache_entry, &size ) )
|
|
|
|
{
|
2009-12-22 09:28:03 +00:00
|
|
|
UINT error = GetLastError();
|
2010-05-29 08:55:43 +00:00
|
|
|
msi_free( cache_entry );
|
2009-12-22 09:28:03 +00:00
|
|
|
return error;
|
2006-08-01 23:12:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
lstrcpyW( filename, cache_entry->lpszLocalFileName );
|
2010-05-29 08:55:43 +00:00
|
|
|
msi_free( cache_entry );
|
2009-12-22 09:28:03 +00:00
|
|
|
return ERROR_SUCCESS;
|
2006-08-01 23:12:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
hr = URLDownloadToCacheFileW( NULL, szUrl, filename, MAX_PATH, 0, NULL );
|
|
|
|
if ( FAILED(hr) )
|
2009-12-22 09:28:03 +00:00
|
|
|
{
|
|
|
|
WARN("failed to download %s to cache file\n", debugstr_w(szUrl));
|
|
|
|
return ERROR_FUNCTION_FAILED;
|
|
|
|
}
|
2006-08-01 23:12:11 +00:00
|
|
|
|
2009-12-22 09:28:03 +00:00
|
|
|
return ERROR_SUCCESS;
|
2006-08-01 23:12:11 +00:00
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
UINT msi_create_empty_local_file( LPWSTR path, LPCWSTR suffix )
|
2009-10-25 11:06:09 +00:00
|
|
|
{
|
|
|
|
static const WCHAR szInstaller[] = {
|
|
|
|
'\\','I','n','s','t','a','l','l','e','r','\\',0};
|
2010-05-29 08:55:43 +00:00
|
|
|
static const WCHAR fmt[] = {'%','x',0};
|
|
|
|
DWORD time, len, i, offset;
|
2009-10-25 11:06:09 +00:00
|
|
|
HANDLE handle;
|
|
|
|
|
|
|
|
time = GetTickCount();
|
|
|
|
GetWindowsDirectoryW( path, MAX_PATH );
|
|
|
|
strcatW( path, szInstaller );
|
|
|
|
CreateDirectoryW( path, NULL );
|
|
|
|
|
|
|
|
len = strlenW(path);
|
|
|
|
for (i = 0; i < 0x10000; i++)
|
|
|
|
{
|
2010-05-29 08:55:43 +00:00
|
|
|
offset = snprintfW( path + len, MAX_PATH - len, fmt, (time + i) & 0xffff );
|
|
|
|
memcpy( path + len + offset, suffix, (strlenW( suffix ) + 1) * sizeof(WCHAR) );
|
2009-10-25 11:06:09 +00:00
|
|
|
handle = CreateFileW( path, GENERIC_WRITE, 0, NULL,
|
|
|
|
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
|
|
|
|
if (handle != INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
CloseHandle(handle);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (GetLastError() != ERROR_FILE_EXISTS &&
|
|
|
|
GetLastError() != ERROR_SHARING_VIOLATION)
|
|
|
|
return ERROR_FUNCTION_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-04-03 21:58:03 +00:00
|
|
|
static enum platform parse_platform( WCHAR *str )
|
|
|
|
{
|
|
|
|
if (!str[0] || !strcmpW( str, szIntel )) return PLATFORM_INTEL;
|
|
|
|
else if (!strcmpW( str, szIntel64 )) return PLATFORM_INTEL64;
|
|
|
|
else if (!strcmpW( str, szX64 ) || !strcmpW( str, szAMD64 )) return PLATFORM_X64;
|
|
|
|
else if (!strcmpW( str, szARM )) return PLATFORM_ARM;
|
|
|
|
return PLATFORM_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
|
|
|
|
{
|
2013-04-03 21:58:03 +00:00
|
|
|
WCHAR *template, *p, *q, *platform;
|
2010-10-22 13:18:11 +00:00
|
|
|
DWORD i, count;
|
|
|
|
|
|
|
|
package->version = msi_suminfo_get_int32( si, PID_PAGECOUNT );
|
|
|
|
TRACE("version: %d\n", package->version);
|
|
|
|
|
|
|
|
template = msi_suminfo_dup_string( si, PID_TEMPLATE );
|
|
|
|
if (!template)
|
|
|
|
return ERROR_SUCCESS; /* native accepts missing template property */
|
|
|
|
|
|
|
|
TRACE("template: %s\n", debugstr_w(template));
|
|
|
|
|
|
|
|
p = strchrW( template, ';' );
|
|
|
|
if (!p)
|
|
|
|
{
|
|
|
|
WARN("invalid template string %s\n", debugstr_w(template));
|
|
|
|
msi_free( template );
|
|
|
|
return ERROR_PATCH_PACKAGE_INVALID;
|
|
|
|
}
|
|
|
|
*p = 0;
|
2013-04-03 21:58:03 +00:00
|
|
|
platform = template;
|
|
|
|
if ((q = strchrW( platform, ',' ))) *q = 0;
|
|
|
|
package->platform = parse_platform( platform );
|
|
|
|
while (package->platform == PLATFORM_UNKNOWN && q)
|
|
|
|
{
|
|
|
|
platform = q + 1;
|
|
|
|
if ((q = strchrW( platform, ',' ))) *q = 0;
|
|
|
|
package->platform = parse_platform( platform );
|
|
|
|
}
|
|
|
|
if (package->platform == PLATFORM_UNKNOWN)
|
2010-10-22 13:18:11 +00:00
|
|
|
{
|
|
|
|
WARN("unknown platform %s\n", debugstr_w(template));
|
|
|
|
msi_free( template );
|
|
|
|
return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
|
|
|
|
}
|
2011-03-20 08:47:41 +00:00
|
|
|
p++;
|
|
|
|
if (!*p)
|
|
|
|
{
|
|
|
|
msi_free( template );
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
2010-10-22 13:18:11 +00:00
|
|
|
count = 1;
|
2011-03-20 08:47:41 +00:00
|
|
|
for (q = p; (q = strchrW( q, ',' )); q++) count++;
|
2010-10-22 13:18:11 +00:00
|
|
|
|
|
|
|
package->langids = msi_alloc( count * sizeof(LANGID) );
|
|
|
|
if (!package->langids)
|
|
|
|
{
|
|
|
|
msi_free( template );
|
|
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (*p)
|
|
|
|
{
|
|
|
|
q = strchrW( p, ',' );
|
|
|
|
if (q) *q = 0;
|
|
|
|
package->langids[i] = atoiW( p );
|
|
|
|
if (!q) break;
|
|
|
|
p = q + 1;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
package->num_langids = i + 1;
|
|
|
|
|
|
|
|
msi_free( template );
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UINT validate_package( MSIPACKAGE *package )
|
|
|
|
{
|
|
|
|
UINT i;
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
if (package->platform == PLATFORM_INTEL64)
|
|
|
|
return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
|
2012-05-14 21:41:31 +00:00
|
|
|
#ifndef __arm__
|
|
|
|
if (package->platform == PLATFORM_ARM)
|
|
|
|
return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
|
|
|
|
#endif
|
2010-10-22 13:18:11 +00:00
|
|
|
if (package->platform == PLATFORM_X64)
|
|
|
|
{
|
|
|
|
if (!is_64bit && !is_wow64)
|
|
|
|
return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
|
|
|
|
if (package->version < 200)
|
|
|
|
return ERROR_INSTALL_PACKAGE_INVALID;
|
|
|
|
}
|
|
|
|
if (!package->num_langids)
|
|
|
|
{
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
for (i = 0; i < package->num_langids; i++)
|
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
LANGID langid = package->langids[i];
|
|
|
|
|
|
|
|
if (PRIMARYLANGID( langid ) == LANG_NEUTRAL)
|
|
|
|
{
|
|
|
|
langid = MAKELANGID( PRIMARYLANGID( GetSystemDefaultLangID() ), SUBLANGID( langid ) );
|
|
|
|
}
|
|
|
|
if (SUBLANGID( langid ) == SUBLANG_NEUTRAL)
|
|
|
|
{
|
|
|
|
langid = MAKELANGID( PRIMARYLANGID( langid ), SUBLANGID( GetSystemDefaultLangID() ) );
|
|
|
|
}
|
|
|
|
if (IsValidLocale( langid, LCID_INSTALLED ))
|
2010-10-22 13:18:11 +00:00
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
return ERROR_INSTALL_LANGUAGE_UNSUPPORTED;
|
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
int msi_track_tempfile( MSIPACKAGE *package, const WCHAR *path )
|
|
|
|
{
|
|
|
|
MSITEMPFILE *temp;
|
|
|
|
|
|
|
|
TRACE("%s\n", debugstr_w(path));
|
|
|
|
|
|
|
|
LIST_FOR_EACH_ENTRY( temp, &package->tempfiles, MSITEMPFILE, entry )
|
|
|
|
{
|
|
|
|
if (!strcmpW( path, temp->Path )) return 0;
|
|
|
|
}
|
|
|
|
if (!(temp = msi_alloc_zero( sizeof (MSITEMPFILE) ))) return -1;
|
|
|
|
list_add_head( &package->tempfiles, &temp->entry );
|
|
|
|
temp->Path = strdupW( path );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static WCHAR *get_product_code( MSIDATABASE *db )
|
|
|
|
{
|
|
|
|
static const WCHAR query[] = {
|
|
|
|
'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ',
|
|
|
|
'F','R','O','M',' ','`','P','r','o','p','e','r','t','y','`',' ',
|
|
|
|
'W','H','E','R','E',' ','`','P','r','o','p','e','r','t','y','`','=',
|
|
|
|
'\'','P','r','o','d','u','c','t','C','o','d','e','\'',0};
|
|
|
|
MSIQUERY *view;
|
|
|
|
MSIRECORD *rec;
|
|
|
|
WCHAR *ret = NULL;
|
|
|
|
|
|
|
|
if (MSI_DatabaseOpenViewW( db, query, &view ) != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (MSI_ViewExecute( view, 0 ) != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
MSI_ViewClose( view );
|
|
|
|
msiobj_release( &view->hdr );
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (MSI_ViewFetch( view, &rec ) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
ret = strdupW( MSI_RecordGetString( rec, 1 ) );
|
|
|
|
msiobj_release( &rec->hdr );
|
|
|
|
}
|
|
|
|
MSI_ViewClose( view );
|
|
|
|
msiobj_release( &view->hdr );
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UINT get_registered_local_package( const WCHAR *product, const WCHAR *package, WCHAR *localfile )
|
|
|
|
{
|
|
|
|
MSIINSTALLCONTEXT context;
|
|
|
|
HKEY product_key, props_key;
|
|
|
|
WCHAR *registered_package = NULL, unsquashed[GUID_SIZE];
|
|
|
|
UINT r;
|
|
|
|
|
|
|
|
r = msi_locate_product( product, &context );
|
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = MSIREG_OpenProductKey( product, NULL, context, &product_key, FALSE );
|
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
r = MSIREG_OpenInstallProps( product, context, NULL, &props_key, FALSE );
|
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
RegCloseKey( product_key );
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
r = ERROR_FUNCTION_FAILED;
|
|
|
|
registered_package = msi_reg_get_val_str( product_key, INSTALLPROPERTY_PACKAGECODEW );
|
|
|
|
if (!registered_package)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
unsquash_guid( registered_package, unsquashed );
|
|
|
|
if (!strcmpiW( package, unsquashed ))
|
|
|
|
{
|
|
|
|
WCHAR *filename = msi_reg_get_val_str( props_key, INSTALLPROPERTY_LOCALPACKAGEW );
|
2012-05-14 21:41:31 +00:00
|
|
|
if (!filename)
|
|
|
|
goto done;
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
strcpyW( localfile, filename );
|
|
|
|
msi_free( filename );
|
|
|
|
r = ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
msi_free( registered_package );
|
|
|
|
RegCloseKey( props_key );
|
|
|
|
RegCloseKey( product_key );
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
static WCHAR *get_package_code( MSIDATABASE *db )
|
|
|
|
{
|
|
|
|
WCHAR *ret;
|
|
|
|
MSISUMMARYINFO *si;
|
|
|
|
|
|
|
|
if (!(si = MSI_GetSummaryInformationW( db->storage, 0 )))
|
|
|
|
{
|
|
|
|
WARN("failed to load summary info\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
ret = msi_suminfo_dup_string( si, PID_REVNUMBER );
|
|
|
|
msiobj_release( &si->hdr );
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UINT get_local_package( const WCHAR *filename, WCHAR *localfile )
|
|
|
|
{
|
|
|
|
WCHAR *product_code, *package_code;
|
|
|
|
MSIDATABASE *db;
|
|
|
|
UINT r;
|
|
|
|
|
|
|
|
if ((r = MSI_OpenDatabaseW( filename, MSIDBOPEN_READONLY, &db )) != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
if (GetFileAttributesW( filename ) == INVALID_FILE_ATTRIBUTES)
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
if (!(product_code = get_product_code( db )))
|
|
|
|
{
|
|
|
|
msiobj_release( &db->hdr );
|
|
|
|
return ERROR_INSTALL_PACKAGE_INVALID;
|
|
|
|
}
|
|
|
|
if (!(package_code = get_package_code( db )))
|
|
|
|
{
|
|
|
|
msi_free( product_code );
|
|
|
|
msiobj_release( &db->hdr );
|
|
|
|
return ERROR_INSTALL_PACKAGE_INVALID;
|
|
|
|
}
|
|
|
|
r = get_registered_local_package( product_code, package_code, localfile );
|
|
|
|
msi_free( package_code );
|
|
|
|
msi_free( product_code );
|
|
|
|
msiobj_release( &db->hdr );
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2013-04-03 21:58:03 +00:00
|
|
|
UINT msi_set_original_database_property( MSIDATABASE *db, const WCHAR *package )
|
|
|
|
{
|
|
|
|
UINT r;
|
|
|
|
|
|
|
|
if (UrlIsW( package, URLIS_URL ))
|
|
|
|
r = msi_set_property( db, szOriginalDatabase, package, -1 );
|
|
|
|
else if (package[0] == '#')
|
|
|
|
r = msi_set_property( db, szOriginalDatabase, db->path, -1 );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DWORD len;
|
|
|
|
WCHAR *path;
|
|
|
|
|
|
|
|
if (!(len = GetFullPathNameW( package, 0, NULL, NULL ))) return GetLastError();
|
|
|
|
if (!(path = msi_alloc( len * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY;
|
|
|
|
len = GetFullPathNameW( package, len, path, NULL );
|
|
|
|
r = msi_set_property( db, szOriginalDatabase, path, len );
|
|
|
|
msi_free( path );
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
|
|
|
{
|
2010-05-29 08:55:43 +00:00
|
|
|
static const WCHAR dotmsi[] = {'.','m','s','i',0};
|
2012-01-21 17:19:12 +00:00
|
|
|
MSIDATABASE *db;
|
2006-02-17 00:04:10 +00:00
|
|
|
MSIPACKAGE *package;
|
|
|
|
MSIHANDLE handle;
|
2006-11-28 11:21:39 +00:00
|
|
|
LPWSTR ptr, base_url = NULL;
|
2006-02-17 00:04:10 +00:00
|
|
|
UINT r;
|
2012-01-21 17:19:12 +00:00
|
|
|
WCHAR localfile[MAX_PATH], cachefile[MAX_PATH];
|
2008-01-16 10:11:22 +00:00
|
|
|
LPCWSTR file = szPackage;
|
2010-05-29 08:55:43 +00:00
|
|
|
DWORD index = 0;
|
2010-10-22 13:18:11 +00:00
|
|
|
MSISUMMARYINFO *si;
|
2012-01-21 17:19:12 +00:00
|
|
|
BOOL delete_on_close = FALSE;
|
2006-10-22 20:23:59 +00:00
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
TRACE("%s %p\n", debugstr_w(szPackage), pPackage);
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
localfile[0] = 0;
|
2006-02-17 00:04:10 +00:00
|
|
|
if( szPackage[0] == '#' )
|
|
|
|
{
|
|
|
|
handle = atoiW(&szPackage[1]);
|
|
|
|
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
|
|
|
|
if( !db )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
|
|
|
IWineMsiRemoteDatabase *remote_database;
|
|
|
|
|
|
|
|
remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( handle );
|
|
|
|
if ( !remote_database )
|
|
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
|
|
|
|
IWineMsiRemoteDatabase_Release( remote_database );
|
|
|
|
WARN("MsiOpenPackage not allowed during a custom action!\n");
|
|
|
|
|
|
|
|
return ERROR_FUNCTION_FAILED;
|
|
|
|
}
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-08-01 23:12:11 +00:00
|
|
|
if ( UrlIsW( szPackage, URLIS_URL ) )
|
2006-11-28 11:21:39 +00:00
|
|
|
{
|
2009-12-22 09:28:03 +00:00
|
|
|
r = msi_download_file( szPackage, cachefile );
|
2012-01-21 17:19:12 +00:00
|
|
|
if (r != ERROR_SUCCESS)
|
2009-12-22 09:28:03 +00:00
|
|
|
return r;
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
file = cachefile;
|
2006-11-28 11:21:39 +00:00
|
|
|
|
|
|
|
base_url = strdupW( szPackage );
|
2012-01-21 17:19:12 +00:00
|
|
|
if (!base_url)
|
2006-11-28 11:21:39 +00:00
|
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
|
|
|
|
ptr = strrchrW( base_url, '/' );
|
|
|
|
if (ptr) *(ptr + 1) = '\0';
|
|
|
|
}
|
2012-01-21 17:19:12 +00:00
|
|
|
r = get_local_package( file, localfile );
|
|
|
|
if (r != ERROR_SUCCESS || GetFileAttributesW( localfile ) == INVALID_FILE_ATTRIBUTES)
|
2009-12-22 09:28:03 +00:00
|
|
|
{
|
2012-01-21 17:19:12 +00:00
|
|
|
r = msi_create_empty_local_file( localfile, dotmsi );
|
|
|
|
if (r != ERROR_SUCCESS)
|
2012-12-09 19:43:59 +00:00
|
|
|
{
|
|
|
|
msi_free ( base_url );
|
2009-12-22 09:28:03 +00:00
|
|
|
return r;
|
2012-12-09 19:43:59 +00:00
|
|
|
}
|
2009-12-22 09:28:03 +00:00
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
if (!CopyFileW( file, localfile, FALSE ))
|
|
|
|
{
|
|
|
|
r = GetLastError();
|
|
|
|
WARN("unable to copy package %s to %s (%u)\n", debugstr_w(file), debugstr_w(localfile), r);
|
|
|
|
DeleteFileW( localfile );
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_free ( base_url );
|
2012-01-21 17:19:12 +00:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
delete_on_close = TRUE;
|
2009-12-22 09:28:03 +00:00
|
|
|
}
|
2012-01-21 17:19:12 +00:00
|
|
|
TRACE("opening package %s\n", debugstr_w( localfile ));
|
|
|
|
r = MSI_OpenDatabaseW( localfile, MSIDBOPEN_TRANSACT, &db );
|
2009-10-25 11:06:09 +00:00
|
|
|
if (r != ERROR_SUCCESS)
|
2012-12-09 19:43:59 +00:00
|
|
|
{
|
|
|
|
msi_free ( base_url );
|
2009-10-25 11:06:09 +00:00
|
|
|
return r;
|
2012-12-09 19:43:59 +00:00
|
|
|
}
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
2006-11-28 11:21:39 +00:00
|
|
|
package = MSI_CreatePackage( db, base_url );
|
|
|
|
msi_free( base_url );
|
2006-02-17 00:04:10 +00:00
|
|
|
msiobj_release( &db->hdr );
|
2012-01-21 17:19:12 +00:00
|
|
|
if (!package) return ERROR_INSTALL_PACKAGE_INVALID;
|
|
|
|
package->localfile = strdupW( localfile );
|
|
|
|
package->delete_on_close = delete_on_close;
|
2008-01-16 10:11:22 +00:00
|
|
|
|
2010-10-22 13:18:11 +00:00
|
|
|
si = MSI_GetSummaryInformationW( db->storage, 0 );
|
|
|
|
if (!si)
|
|
|
|
{
|
2012-01-21 17:19:12 +00:00
|
|
|
WARN("failed to load summary info\n");
|
2010-10-22 13:18:11 +00:00
|
|
|
msiobj_release( &package->hdr );
|
|
|
|
return ERROR_INSTALL_PACKAGE_INVALID;
|
|
|
|
}
|
|
|
|
r = msi_parse_summary( si, package );
|
|
|
|
msiobj_release( &si->hdr );
|
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
WARN("failed to parse summary info %u\n", r);
|
|
|
|
msiobj_release( &package->hdr );
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
r = validate_package( package );
|
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
msiobj_release( &package->hdr );
|
|
|
|
return r;
|
|
|
|
}
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_set_property( package->db, szDatabase, db->path, -1 );
|
2010-05-29 08:55:43 +00:00
|
|
|
msi_set_context( package );
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
WCHAR patch_code[GUID_SIZE];
|
|
|
|
r = MsiEnumPatchesExW( package->ProductCode, NULL, package->Context,
|
|
|
|
MSIPATCHSTATE_APPLIED, index, patch_code, NULL, NULL, NULL, NULL );
|
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
break;
|
|
|
|
|
|
|
|
TRACE("found registered patch %s\n", debugstr_w(patch_code));
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
r = msi_apply_registered_patch( package, patch_code );
|
2010-05-29 08:55:43 +00:00
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
ERR("registered patch failed to apply %u\n", r);
|
2010-10-22 13:18:11 +00:00
|
|
|
msiobj_release( &package->hdr );
|
2010-05-29 08:55:43 +00:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
}
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
if (index)
|
|
|
|
{
|
|
|
|
msi_clone_properties( package );
|
2010-10-22 13:18:11 +00:00
|
|
|
msi_adjust_privilege_properties( package );
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
}
|
2013-04-03 21:58:03 +00:00
|
|
|
r = msi_set_original_database_property( package->db, szPackage );
|
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
msiobj_release( &package->hdr );
|
|
|
|
return r;
|
|
|
|
}
|
2011-03-20 08:47:41 +00:00
|
|
|
if (gszLogFile)
|
|
|
|
package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
|
|
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
2010-05-29 08:55:43 +00:00
|
|
|
*pPackage = package;
|
2006-02-17 00:04:10 +00:00
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
|
|
|
|
{
|
|
|
|
MSIPACKAGE *package = NULL;
|
|
|
|
UINT ret;
|
|
|
|
|
2006-10-22 20:23:59 +00:00
|
|
|
TRACE("%s %08x %p\n", debugstr_w(szPackage), dwOptions, phPackage );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
if( !szPackage || !phPackage )
|
2006-08-01 23:12:11 +00:00
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
if ( !*szPackage )
|
|
|
|
{
|
|
|
|
FIXME("Should create an empty database and package\n");
|
|
|
|
return ERROR_FUNCTION_FAILED;
|
|
|
|
}
|
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
if( dwOptions )
|
2006-10-22 20:23:59 +00:00
|
|
|
FIXME("dwOptions %08x not supported\n", dwOptions);
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
ret = MSI_OpenPackageW( szPackage, &package );
|
|
|
|
if( ret == ERROR_SUCCESS )
|
|
|
|
{
|
|
|
|
*phPackage = alloc_msihandle( &package->hdr );
|
2006-08-30 19:24:26 +00:00
|
|
|
if (! *phPackage)
|
|
|
|
ret = ERROR_NOT_ENOUGH_MEMORY;
|
2006-02-17 00:04:10 +00:00
|
|
|
msiobj_release( &package->hdr );
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
|
|
|
|
{
|
|
|
|
return MsiOpenPackageExW( szPackage, 0, phPackage );
|
|
|
|
}
|
|
|
|
|
|
|
|
UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
|
|
|
|
{
|
|
|
|
LPWSTR szwPack = NULL;
|
|
|
|
UINT ret;
|
|
|
|
|
|
|
|
if( szPackage )
|
|
|
|
{
|
|
|
|
szwPack = strdupAtoW( szPackage );
|
|
|
|
if( !szwPack )
|
|
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = MsiOpenPackageExW( szwPack, dwOptions, phPackage );
|
|
|
|
|
|
|
|
msi_free( szwPack );
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
|
|
|
|
{
|
|
|
|
return MsiOpenPackageExA( szPackage, 0, phPackage );
|
|
|
|
}
|
|
|
|
|
|
|
|
MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
|
|
|
|
{
|
|
|
|
MSIPACKAGE *package;
|
|
|
|
MSIHANDLE handle = 0;
|
2010-05-29 08:55:43 +00:00
|
|
|
IUnknown *remote_unk;
|
2008-01-16 10:11:22 +00:00
|
|
|
IWineMsiRemotePackage *remote_package;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2009-01-18 12:52:01 +00:00
|
|
|
TRACE("(%d)\n",hInstall);
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
|
|
|
|
if( package)
|
|
|
|
{
|
|
|
|
handle = alloc_msihandle( &package->db->hdr );
|
|
|
|
msiobj_release( &package->hdr );
|
|
|
|
}
|
2010-05-29 08:55:43 +00:00
|
|
|
else if ((remote_unk = msi_get_remote(hInstall)))
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2010-05-29 08:55:43 +00:00
|
|
|
if (IUnknown_QueryInterface(remote_unk, &IID_IWineMsiRemotePackage,
|
|
|
|
(LPVOID *)&remote_package) == S_OK)
|
|
|
|
{
|
|
|
|
IWineMsiRemotePackage_GetActiveDatabase(remote_package, &handle);
|
|
|
|
IWineMsiRemotePackage_Release(remote_package);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WARN("remote handle %d is not a package\n", hInstall);
|
|
|
|
}
|
|
|
|
IUnknown_Release(remote_unk);
|
2008-01-16 10:11:22 +00:00
|
|
|
}
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
return handle;
|
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record )
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
2012-05-14 21:41:31 +00:00
|
|
|
static const WCHAR szActionData[] = {'A','c','t','i','o','n','D','a','t','a',0};
|
|
|
|
static const WCHAR szSetProgress[] = {'S','e','t','P','r','o','g','r','e','s','s',0};
|
|
|
|
static const WCHAR szActionText[] = {'A','c','t','i','o','n','T','e','x','t',0};
|
|
|
|
MSIRECORD *uirow;
|
|
|
|
LPWSTR deformated, message;
|
2012-01-21 17:19:12 +00:00
|
|
|
DWORD i, len, total_len, log_type = 0;
|
|
|
|
INT rc = 0;
|
2006-02-17 00:04:10 +00:00
|
|
|
char *msg;
|
|
|
|
|
|
|
|
TRACE("%x\n", eMessageType);
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_FATALEXIT)
|
|
|
|
log_type |= INSTALLLOGMODE_FATALEXIT;
|
2006-02-17 00:04:10 +00:00
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ERROR)
|
|
|
|
log_type |= INSTALLLOGMODE_ERROR;
|
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_WARNING)
|
|
|
|
log_type |= INSTALLLOGMODE_WARNING;
|
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_USER)
|
|
|
|
log_type |= INSTALLLOGMODE_USER;
|
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_INFO)
|
|
|
|
log_type |= INSTALLLOGMODE_INFO;
|
2012-01-21 17:19:12 +00:00
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_RESOLVESOURCE)
|
|
|
|
log_type |= INSTALLLOGMODE_RESOLVESOURCE;
|
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_OUTOFDISKSPACE)
|
|
|
|
log_type |= INSTALLLOGMODE_OUTOFDISKSPACE;
|
2006-02-17 00:04:10 +00:00
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_COMMONDATA)
|
|
|
|
log_type |= INSTALLLOGMODE_COMMONDATA;
|
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONSTART)
|
|
|
|
log_type |= INSTALLLOGMODE_ACTIONSTART;
|
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONDATA)
|
|
|
|
log_type |= INSTALLLOGMODE_ACTIONDATA;
|
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_PROGRESS)
|
2012-01-21 17:19:12 +00:00
|
|
|
log_type |= INSTALLLOGMODE_PROGRESS;
|
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_INITIALIZE)
|
|
|
|
log_type |= INSTALLLOGMODE_INITIALIZE;
|
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_TERMINATE)
|
|
|
|
log_type |= INSTALLLOGMODE_TERMINATE;
|
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_SHOWDIALOG)
|
|
|
|
log_type |= INSTALLLOGMODE_SHOWDIALOG;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2006-08-01 23:12:11 +00:00
|
|
|
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONSTART)
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
2006-08-01 23:12:11 +00:00
|
|
|
static const WCHAR template_s[]=
|
|
|
|
{'A','c','t','i','o','n',' ','%','s',':',' ','%','s','.',' ',0};
|
2008-01-16 10:11:22 +00:00
|
|
|
static const WCHAR format[] =
|
2006-08-01 23:12:11 +00:00
|
|
|
{'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};
|
|
|
|
WCHAR timet[0x100];
|
|
|
|
LPCWSTR action_text, action;
|
|
|
|
LPWSTR deformatted = NULL;
|
|
|
|
|
|
|
|
GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
|
|
|
|
|
|
|
|
action = MSI_RecordGetString(record, 1);
|
|
|
|
action_text = MSI_RecordGetString(record, 2);
|
2006-08-30 19:24:26 +00:00
|
|
|
|
|
|
|
if (!action || !action_text)
|
|
|
|
return IDOK;
|
|
|
|
|
2006-08-01 23:12:11 +00:00
|
|
|
deformat_string(package, action_text, &deformatted);
|
|
|
|
|
|
|
|
len = strlenW(timet) + strlenW(action) + strlenW(template_s);
|
|
|
|
if (deformatted)
|
|
|
|
len += strlenW(deformatted);
|
|
|
|
message = msi_alloc(len*sizeof(WCHAR));
|
|
|
|
sprintfW(message, template_s, timet, action);
|
|
|
|
if (deformatted)
|
|
|
|
strcatW(message, deformatted);
|
|
|
|
msi_free(deformatted);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-21 17:19:12 +00:00
|
|
|
static const WCHAR format[] = {'%','u',':',' ',0};
|
|
|
|
UINT count = MSI_RecordGetFieldCount( record );
|
|
|
|
WCHAR *p;
|
|
|
|
|
|
|
|
total_len = 1;
|
|
|
|
for (i = 1; i <= count; i++)
|
|
|
|
{
|
|
|
|
len = 0;
|
|
|
|
MSI_RecordGetStringW( record, i, NULL, &len );
|
|
|
|
total_len += len + 13;
|
|
|
|
}
|
|
|
|
p = message = msi_alloc( total_len * sizeof(WCHAR) );
|
|
|
|
if (!p) return ERROR_OUTOFMEMORY;
|
|
|
|
|
|
|
|
for (i = 1; i <= count; i++)
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
2012-01-21 17:19:12 +00:00
|
|
|
if (count > 1)
|
2006-08-01 23:12:11 +00:00
|
|
|
{
|
2012-01-21 17:19:12 +00:00
|
|
|
len = sprintfW( p, format, i );
|
|
|
|
total_len -= len;
|
|
|
|
p += len;
|
|
|
|
}
|
|
|
|
len = total_len;
|
|
|
|
MSI_RecordGetStringW( record, i, p, &len );
|
|
|
|
total_len -= len;
|
|
|
|
p += len;
|
|
|
|
if (count > 1 && total_len)
|
|
|
|
{
|
|
|
|
*p++ = ' ';
|
|
|
|
total_len--;
|
2006-08-01 23:12:11 +00:00
|
|
|
}
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
2012-01-21 17:19:12 +00:00
|
|
|
p[0] = 0;
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
|
2009-11-16 01:13:42 +00:00
|
|
|
TRACE("%p %p %p %x %x %s\n", gUIHandlerA, gUIHandlerW, gUIHandlerRecord,
|
|
|
|
gUIFilter, log_type, debugstr_w(message));
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
/* convert it to ASCII */
|
2009-11-16 01:13:42 +00:00
|
|
|
len = WideCharToMultiByte( CP_ACP, 0, message, -1, NULL, 0, NULL, NULL );
|
2006-02-17 00:04:10 +00:00
|
|
|
msg = msi_alloc( len );
|
2009-11-16 01:13:42 +00:00
|
|
|
WideCharToMultiByte( CP_ACP, 0, message, -1, msg, len, NULL, NULL );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2009-11-16 01:13:42 +00:00
|
|
|
if (gUIHandlerW && (gUIFilter & log_type))
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
2009-11-16 01:13:42 +00:00
|
|
|
rc = gUIHandlerW( gUIContext, eMessageType, message );
|
|
|
|
}
|
|
|
|
else if (gUIHandlerA && (gUIFilter & log_type))
|
|
|
|
{
|
|
|
|
rc = gUIHandlerA( gUIContext, eMessageType, msg );
|
|
|
|
}
|
|
|
|
else if (gUIHandlerRecord && (gUIFilter & log_type))
|
|
|
|
{
|
|
|
|
MSIHANDLE rec = MsiCreateRecord( 1 );
|
|
|
|
MsiRecordSetStringW( rec, 0, message );
|
|
|
|
rc = gUIHandlerRecord( gUIContext, eMessageType, rec );
|
|
|
|
MsiCloseHandle( rec );
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
|
2011-03-20 08:47:41 +00:00
|
|
|
if (!rc && package->log_file != INVALID_HANDLE_VALUE &&
|
|
|
|
(eMessageType & 0xff000000) != INSTALLMESSAGE_PROGRESS)
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
DWORD written;
|
|
|
|
WriteFile( package->log_file, msg, len - 1, &written, NULL );
|
|
|
|
WriteFile( package->log_file, "\n", 1, &written, NULL );
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
msi_free( msg );
|
2009-11-16 01:13:42 +00:00
|
|
|
msi_free( message );
|
2006-08-01 23:12:11 +00:00
|
|
|
|
|
|
|
switch (eMessageType & 0xff000000)
|
|
|
|
{
|
|
|
|
case INSTALLMESSAGE_ACTIONDATA:
|
2012-05-14 21:41:31 +00:00
|
|
|
deformat_string(package, MSI_RecordGetString(record, 2), &deformated);
|
|
|
|
uirow = MSI_CreateRecord(1);
|
|
|
|
MSI_RecordSetStringW(uirow, 1, deformated);
|
|
|
|
msi_free(deformated);
|
|
|
|
|
2013-09-22 16:30:18 +00:00
|
|
|
msi_event_fire( package, szActionData, uirow );
|
2012-05-14 21:41:31 +00:00
|
|
|
msiobj_release(&uirow->hdr);
|
2012-08-13 16:17:18 +00:00
|
|
|
|
|
|
|
if (package->action_progress_increment)
|
|
|
|
{
|
|
|
|
uirow = MSI_CreateRecord(2);
|
|
|
|
MSI_RecordSetInteger(uirow, 1, 2);
|
|
|
|
MSI_RecordSetInteger(uirow, 2, package->action_progress_increment);
|
2013-09-22 16:30:18 +00:00
|
|
|
msi_event_fire( package, szSetProgress, uirow );
|
2012-08-13 16:17:18 +00:00
|
|
|
msiobj_release(&uirow->hdr);
|
|
|
|
}
|
2006-08-01 23:12:11 +00:00
|
|
|
break;
|
|
|
|
|
2012-05-14 21:41:31 +00:00
|
|
|
case INSTALLMESSAGE_ACTIONSTART:
|
|
|
|
deformat_string(package, MSI_RecordGetString(record, 2), &deformated);
|
2006-08-01 23:12:11 +00:00
|
|
|
uirow = MSI_CreateRecord(1);
|
|
|
|
MSI_RecordSetStringW(uirow, 1, deformated);
|
|
|
|
msi_free(deformated);
|
|
|
|
|
2013-09-22 16:30:18 +00:00
|
|
|
msi_event_fire( package, szActionText, uirow );
|
2006-08-01 23:12:11 +00:00
|
|
|
|
|
|
|
msiobj_release(&uirow->hdr);
|
|
|
|
break;
|
2012-05-14 21:41:31 +00:00
|
|
|
|
2006-08-01 23:12:11 +00:00
|
|
|
case INSTALLMESSAGE_PROGRESS:
|
2013-09-22 16:30:18 +00:00
|
|
|
msi_event_fire( package, szSetProgress, record );
|
2006-08-01 23:12:11 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
|
|
|
|
MSIHANDLE hRecord)
|
|
|
|
{
|
|
|
|
UINT ret = ERROR_INVALID_HANDLE;
|
|
|
|
MSIPACKAGE *package = NULL;
|
|
|
|
MSIRECORD *record = NULL;
|
|
|
|
|
|
|
|
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
|
|
|
|
if( !package )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
IWineMsiRemotePackage *remote_package;
|
|
|
|
|
|
|
|
remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
|
|
|
|
if (!remote_package)
|
|
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
|
|
|
|
hr = IWineMsiRemotePackage_ProcessMessage( remote_package, eMessageType, hRecord );
|
|
|
|
|
|
|
|
IWineMsiRemotePackage_Release( remote_package );
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
|
|
|
return HRESULT_CODE(hr);
|
|
|
|
|
|
|
|
return ERROR_FUNCTION_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
record = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );
|
|
|
|
if( !record )
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
ret = MSI_ProcessMessage( package, eMessageType, record );
|
|
|
|
|
|
|
|
out:
|
|
|
|
msiobj_release( &package->hdr );
|
|
|
|
if( record )
|
|
|
|
msiobj_release( &record->hdr );
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* property code */
|
2006-08-30 19:24:26 +00:00
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue )
|
|
|
|
{
|
|
|
|
LPWSTR szwName = NULL, szwValue = NULL;
|
|
|
|
UINT r = ERROR_OUTOFMEMORY;
|
|
|
|
|
|
|
|
szwName = strdupAtoW( szName );
|
|
|
|
if( szName && !szwName )
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
szwValue = strdupAtoW( szValue );
|
|
|
|
if( szValue && !szwValue )
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
r = MsiSetPropertyW( hInstall, szwName, szwValue);
|
|
|
|
|
|
|
|
end:
|
|
|
|
msi_free( szwName );
|
|
|
|
msi_free( szwValue );
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2010-05-29 08:55:43 +00:00
|
|
|
void msi_reset_folders( MSIPACKAGE *package, BOOL source )
|
2010-03-06 09:05:09 +00:00
|
|
|
{
|
|
|
|
MSIFOLDER *folder;
|
|
|
|
|
|
|
|
LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry )
|
|
|
|
{
|
|
|
|
if ( source )
|
|
|
|
{
|
|
|
|
msi_free( folder->ResolvedSource );
|
|
|
|
folder->ResolvedSource = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
msi_free( folder->ResolvedTarget );
|
|
|
|
folder->ResolvedTarget = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
UINT msi_set_property( MSIDATABASE *db, const WCHAR *name, const WCHAR *value, int len )
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
2012-01-21 17:19:12 +00:00
|
|
|
static const WCHAR insert_query[] = {
|
|
|
|
'I','N','S','E','R','T',' ','I','N','T','O',' ',
|
|
|
|
'`','_','P','r','o','p','e','r','t','y','`',' ',
|
|
|
|
'(','`','_','P','r','o','p','e','r','t','y','`',',','`','V','a','l','u','e','`',')',' ',
|
|
|
|
'V','A','L','U','E','S',' ','(','?',',','?',')',0};
|
|
|
|
static const WCHAR update_query[] = {
|
|
|
|
'U','P','D','A','T','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ',
|
|
|
|
'S','E','T',' ','`','V','a','l','u','e','`',' ','=',' ','?',' ','W','H','E','R','E',' ',
|
|
|
|
'`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
|
|
|
|
static const WCHAR delete_query[] = {
|
2008-01-16 10:11:22 +00:00
|
|
|
'D','E','L','E','T','E',' ','F','R','O','M',' ',
|
|
|
|
'`','_','P','r','o','p','e','r','t','y','`',' ','W','H','E','R','E',' ',
|
|
|
|
'`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
|
2012-01-21 17:19:12 +00:00
|
|
|
MSIQUERY *view;
|
|
|
|
MSIRECORD *row = NULL;
|
|
|
|
DWORD sz = 0;
|
|
|
|
WCHAR query[1024];
|
|
|
|
UINT rc;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
TRACE("%p %s %s %d\n", db, debugstr_w(name), debugstr_wn(value, len), len);
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
if (!name)
|
2006-02-17 00:04:10 +00:00
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
/* this one is weird... */
|
2012-12-09 19:43:59 +00:00
|
|
|
if (!name[0])
|
|
|
|
return value ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS;
|
|
|
|
|
|
|
|
if (value && len < 0) len = strlenW( value );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
rc = msi_get_property( db, name, 0, &sz );
|
|
|
|
if (!value || (!*value && !len))
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2012-12-09 19:43:59 +00:00
|
|
|
sprintfW( query, delete_query, name );
|
2008-01-16 10:11:22 +00:00
|
|
|
}
|
|
|
|
else if (rc == ERROR_MORE_DATA || rc == ERROR_SUCCESS)
|
|
|
|
{
|
2012-12-09 19:43:59 +00:00
|
|
|
sprintfW( query, update_query, name );
|
2008-01-16 10:11:22 +00:00
|
|
|
row = MSI_CreateRecord(1);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_record_set_string( row, 1, value, len );
|
2008-01-16 10:11:22 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-12-09 19:43:59 +00:00
|
|
|
strcpyW( query, insert_query );
|
2008-01-16 10:11:22 +00:00
|
|
|
row = MSI_CreateRecord(2);
|
2012-12-09 19:43:59 +00:00
|
|
|
msi_record_set_string( row, 1, name, -1 );
|
|
|
|
msi_record_set_string( row, 2, value, len );
|
2008-01-16 10:11:22 +00:00
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
rc = MSI_DatabaseOpenViewW(db, query, &view);
|
2008-01-16 10:11:22 +00:00
|
|
|
if (rc == ERROR_SUCCESS)
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
2008-01-16 10:11:22 +00:00
|
|
|
rc = MSI_ViewExecute(view, row);
|
|
|
|
MSI_ViewClose(view);
|
|
|
|
msiobj_release(&view->hdr);
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
2012-01-21 17:19:12 +00:00
|
|
|
if (row) msiobj_release(&row->hdr);
|
2008-01-16 10:11:22 +00:00
|
|
|
return rc;
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue)
|
|
|
|
{
|
|
|
|
MSIPACKAGE *package;
|
|
|
|
UINT ret;
|
|
|
|
|
|
|
|
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
|
|
|
|
if( !package )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
BSTR name = NULL, value = NULL;
|
|
|
|
IWineMsiRemotePackage *remote_package;
|
|
|
|
|
|
|
|
remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
|
|
|
|
if (!remote_package)
|
|
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
|
|
|
|
name = SysAllocString( szName );
|
|
|
|
value = SysAllocString( szValue );
|
|
|
|
if ((!name && szName) || (!value && szValue))
|
|
|
|
{
|
|
|
|
SysFreeString( name );
|
|
|
|
SysFreeString( value );
|
|
|
|
IWineMsiRemotePackage_Release( remote_package );
|
|
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
hr = IWineMsiRemotePackage_SetProperty( remote_package, name, value );
|
|
|
|
|
|
|
|
SysFreeString( name );
|
|
|
|
SysFreeString( value );
|
|
|
|
IWineMsiRemotePackage_Release( remote_package );
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
|
|
|
return HRESULT_CODE(hr);
|
|
|
|
|
|
|
|
return ERROR_FUNCTION_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
ret = msi_set_property( package->db, szName, szValue, -1 );
|
2012-01-21 17:19:12 +00:00
|
|
|
if (ret == ERROR_SUCCESS && !strcmpW( szName, szSourceDir ))
|
2010-05-29 08:55:43 +00:00
|
|
|
msi_reset_folders( package, TRUE );
|
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
msiobj_release( &package->hdr );
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-05-29 08:55:43 +00:00
|
|
|
static MSIRECORD *msi_get_property_row( MSIDATABASE *db, LPCWSTR name )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
|
|
|
static const WCHAR query[]= {
|
|
|
|
'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ',
|
2012-01-21 17:19:12 +00:00
|
|
|
'F','R','O','M',' ' ,'`','_','P','r','o','p','e','r','t','y','`',' ',
|
|
|
|
'W','H','E','R','E',' ' ,'`','_','P','r','o','p','e','r','t','y','`','=','?',0};
|
|
|
|
MSIRECORD *rec, *row = NULL;
|
|
|
|
MSIQUERY *view;
|
|
|
|
UINT r;
|
2008-01-16 10:11:22 +00:00
|
|
|
|
|
|
|
if (!name || !*name)
|
|
|
|
return NULL;
|
|
|
|
|
2009-05-20 12:59:23 +00:00
|
|
|
rec = MSI_CreateRecord(1);
|
|
|
|
if (!rec)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
MSI_RecordSetStringW(rec, 1, name);
|
|
|
|
|
2010-05-29 08:55:43 +00:00
|
|
|
r = MSI_DatabaseOpenViewW(db, query, &view);
|
2009-05-20 12:59:23 +00:00
|
|
|
if (r == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
MSI_ViewExecute(view, rec);
|
|
|
|
MSI_ViewFetch(view, &row);
|
|
|
|
MSI_ViewClose(view);
|
|
|
|
msiobj_release(&view->hdr);
|
|
|
|
}
|
|
|
|
msiobj_release(&rec->hdr);
|
|
|
|
return row;
|
2008-01-16 10:11:22 +00:00
|
|
|
}
|
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
/* internal function, not compatible with MsiGetPropertyW */
|
2010-05-29 08:55:43 +00:00
|
|
|
UINT msi_get_property( MSIDATABASE *db, LPCWSTR szName,
|
2008-01-16 10:11:22 +00:00
|
|
|
LPWSTR szValueBuf, LPDWORD pchValueBuf )
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
2008-01-16 10:11:22 +00:00
|
|
|
MSIRECORD *row;
|
|
|
|
UINT rc = ERROR_FUNCTION_FAILED;
|
|
|
|
|
2010-05-29 08:55:43 +00:00
|
|
|
row = msi_get_property_row( db, szName );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
if (*pchValueBuf > 0)
|
|
|
|
szValueBuf[0] = 0;
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
if (row)
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
2008-01-16 10:11:22 +00:00
|
|
|
rc = MSI_RecordGetStringW(row, 1, szValueBuf, pchValueBuf);
|
|
|
|
msiobj_release(&row->hdr);
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
if (rc == ERROR_SUCCESS)
|
2012-12-09 19:43:59 +00:00
|
|
|
TRACE("returning %s for property %s\n", debugstr_wn(szValueBuf, *pchValueBuf),
|
2008-01-16 10:11:22 +00:00
|
|
|
debugstr_w(szName));
|
|
|
|
else if (rc == ERROR_MORE_DATA)
|
|
|
|
TRACE("need %d sized buffer for %s\n", *pchValueBuf,
|
|
|
|
debugstr_w(szName));
|
2006-02-17 00:04:10 +00:00
|
|
|
else
|
|
|
|
{
|
2008-01-16 10:11:22 +00:00
|
|
|
*pchValueBuf = 0;
|
|
|
|
TRACE("property %s not found\n", debugstr_w(szName));
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
return rc;
|
2006-08-30 19:24:26 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 08:55:43 +00:00
|
|
|
LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop)
|
2006-08-30 19:24:26 +00:00
|
|
|
{
|
2008-01-16 10:11:22 +00:00
|
|
|
DWORD sz = 0;
|
|
|
|
LPWSTR str;
|
|
|
|
UINT r;
|
2006-08-30 19:24:26 +00:00
|
|
|
|
2010-05-29 08:55:43 +00:00
|
|
|
r = msi_get_property(db, prop, NULL, &sz);
|
2008-01-16 10:11:22 +00:00
|
|
|
if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
|
|
|
|
return NULL;
|
2006-08-30 19:24:26 +00:00
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
sz++;
|
|
|
|
str = msi_alloc(sz * sizeof(WCHAR));
|
2010-05-29 08:55:43 +00:00
|
|
|
r = msi_get_property(db, prop, str, &sz);
|
2008-01-16 10:11:22 +00:00
|
|
|
if (r != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
msi_free(str);
|
|
|
|
str = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return str;
|
2006-02-17 00:04:10 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 08:55:43 +00:00
|
|
|
int msi_get_property_int( MSIDATABASE *db, LPCWSTR prop, int def )
|
2006-08-30 19:24:26 +00:00
|
|
|
{
|
2010-05-29 08:55:43 +00:00
|
|
|
LPWSTR str = msi_dup_property( db, prop );
|
2008-01-16 10:11:22 +00:00
|
|
|
int val = str ? atoiW(str) : def;
|
|
|
|
msi_free(str);
|
|
|
|
return val;
|
2006-08-30 19:24:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name,
|
2008-01-16 10:11:22 +00:00
|
|
|
awstring *szValueBuf, LPDWORD pchValueBuf )
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
|
|
|
MSIPACKAGE *package;
|
2008-01-16 10:11:22 +00:00
|
|
|
MSIRECORD *row = NULL;
|
|
|
|
UINT r = ERROR_FUNCTION_FAILED;
|
2006-02-17 00:04:10 +00:00
|
|
|
LPCWSTR val = NULL;
|
2012-12-09 19:43:59 +00:00
|
|
|
DWORD len = 0;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2009-01-18 12:52:01 +00:00
|
|
|
TRACE("%u %s %p %p\n", handle, debugstr_w(name),
|
2006-02-17 00:04:10 +00:00
|
|
|
szValueBuf->str.w, pchValueBuf );
|
|
|
|
|
|
|
|
if (!name)
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE );
|
|
|
|
if (!package)
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
IWineMsiRemotePackage *remote_package;
|
|
|
|
LPWSTR value = NULL;
|
|
|
|
BSTR bname;
|
|
|
|
|
|
|
|
remote_package = (IWineMsiRemotePackage *)msi_get_remote( handle );
|
|
|
|
if (!remote_package)
|
|
|
|
return ERROR_INVALID_HANDLE;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
bname = SysAllocString( name );
|
|
|
|
if (!bname)
|
|
|
|
{
|
|
|
|
IWineMsiRemotePackage_Release( remote_package );
|
|
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
hr = IWineMsiRemotePackage_GetProperty( remote_package, bname, NULL, &len );
|
|
|
|
if (FAILED(hr))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
len++;
|
|
|
|
value = msi_alloc(len * sizeof(WCHAR));
|
|
|
|
if (!value)
|
|
|
|
{
|
|
|
|
r = ERROR_OUTOFMEMORY;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
hr = IWineMsiRemotePackage_GetProperty( remote_package, bname, value, &len );
|
2008-01-16 10:11:22 +00:00
|
|
|
if (FAILED(hr))
|
|
|
|
goto done;
|
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
r = msi_strcpy_to_awstring( value, len, szValueBuf, pchValueBuf );
|
2008-01-16 10:11:22 +00:00
|
|
|
|
|
|
|
/* Bug required by Adobe installers */
|
|
|
|
if (!szValueBuf->unicode && !szValueBuf->str.a)
|
|
|
|
*pchValueBuf *= sizeof(WCHAR);
|
|
|
|
|
|
|
|
done:
|
|
|
|
IWineMsiRemotePackage_Release(remote_package);
|
|
|
|
SysFreeString(bname);
|
|
|
|
msi_free(value);
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
|
|
|
return HRESULT_CODE(hr);
|
|
|
|
|
|
|
|
return ERROR_FUNCTION_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2010-05-29 08:55:43 +00:00
|
|
|
row = msi_get_property_row( package->db, name );
|
2008-01-16 10:11:22 +00:00
|
|
|
if (row)
|
2012-12-09 19:43:59 +00:00
|
|
|
val = msi_record_get_string( row, 1, (int *)&len );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
|
|
|
if (!val)
|
2009-10-25 11:06:09 +00:00
|
|
|
val = szEmpty;
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2012-12-09 19:43:59 +00:00
|
|
|
r = msi_strcpy_to_awstring( val, len, szValueBuf, pchValueBuf );
|
2006-02-17 00:04:10 +00:00
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
if (row)
|
|
|
|
msiobj_release( &row->hdr );
|
2006-02-17 00:04:10 +00:00
|
|
|
msiobj_release( &package->hdr );
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
UINT WINAPI MsiGetPropertyA( MSIHANDLE hInstall, LPCSTR szName,
|
2008-01-16 10:11:22 +00:00
|
|
|
LPSTR szValueBuf, LPDWORD pchValueBuf )
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
|
|
|
awstring val;
|
|
|
|
LPWSTR name;
|
|
|
|
UINT r;
|
|
|
|
|
|
|
|
val.unicode = FALSE;
|
|
|
|
val.str.a = szValueBuf;
|
|
|
|
|
|
|
|
name = strdupAtoW( szName );
|
|
|
|
if (szName && !name)
|
|
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
|
|
|
|
r = MSI_GetProperty( hInstall, name, &val, pchValueBuf );
|
|
|
|
msi_free( name );
|
|
|
|
return r;
|
|
|
|
}
|
2006-08-30 19:24:26 +00:00
|
|
|
|
2006-02-17 00:04:10 +00:00
|
|
|
UINT WINAPI MsiGetPropertyW( MSIHANDLE hInstall, LPCWSTR szName,
|
2008-01-16 10:11:22 +00:00
|
|
|
LPWSTR szValueBuf, LPDWORD pchValueBuf )
|
2006-02-17 00:04:10 +00:00
|
|
|
{
|
|
|
|
awstring val;
|
|
|
|
|
|
|
|
val.unicode = TRUE;
|
|
|
|
val.str.w = szValueBuf;
|
|
|
|
|
|
|
|
return MSI_GetProperty( hInstall, szName, &val, pchValueBuf );
|
|
|
|
}
|
2008-01-16 10:11:22 +00:00
|
|
|
|
|
|
|
typedef struct _msi_remote_package_impl {
|
2011-03-20 08:47:41 +00:00
|
|
|
IWineMsiRemotePackage IWineMsiRemotePackage_iface;
|
2008-01-16 10:11:22 +00:00
|
|
|
MSIHANDLE package;
|
|
|
|
LONG refs;
|
|
|
|
} msi_remote_package_impl;
|
|
|
|
|
2011-03-20 08:47:41 +00:00
|
|
|
static inline msi_remote_package_impl *impl_from_IWineMsiRemotePackage( IWineMsiRemotePackage *iface )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
return CONTAINING_RECORD(iface, msi_remote_package_impl, IWineMsiRemotePackage_iface);
|
2008-01-16 10:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI mrp_QueryInterface( IWineMsiRemotePackage *iface,
|
|
|
|
REFIID riid,LPVOID *ppobj)
|
|
|
|
{
|
|
|
|
if( IsEqualCLSID( riid, &IID_IUnknown ) ||
|
|
|
|
IsEqualCLSID( riid, &IID_IWineMsiRemotePackage ) )
|
|
|
|
{
|
2012-08-13 16:17:18 +00:00
|
|
|
IWineMsiRemotePackage_AddRef( iface );
|
2008-01-16 10:11:22 +00:00
|
|
|
*ppobj = iface;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI mrp_AddRef( IWineMsiRemotePackage *iface )
|
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2008-01-16 10:11:22 +00:00
|
|
|
|
|
|
|
return InterlockedIncrement( &This->refs );
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI mrp_Release( IWineMsiRemotePackage *iface )
|
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2008-01-16 10:11:22 +00:00
|
|
|
ULONG r;
|
|
|
|
|
|
|
|
r = InterlockedDecrement( &This->refs );
|
|
|
|
if (r == 0)
|
|
|
|
{
|
|
|
|
MsiCloseHandle( This->package );
|
|
|
|
msi_free( This );
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI mrp_SetMsiHandle( IWineMsiRemotePackage *iface, MSIHANDLE handle )
|
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2008-01-16 10:11:22 +00:00
|
|
|
This->package = handle;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_GetActiveDatabase( IWineMsiRemotePackage *iface, MSIHANDLE *handle )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2008-01-16 10:11:22 +00:00
|
|
|
IWineMsiRemoteDatabase *rdb = NULL;
|
|
|
|
HRESULT hr;
|
|
|
|
MSIHANDLE hdb;
|
|
|
|
|
|
|
|
hr = create_msi_remote_database( NULL, (LPVOID *)&rdb );
|
|
|
|
if (FAILED(hr) || !rdb)
|
|
|
|
{
|
|
|
|
ERR("Failed to create remote database\n");
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
hdb = MsiGetActiveDatabase(This->package);
|
|
|
|
|
|
|
|
hr = IWineMsiRemoteDatabase_SetMsiHandle( rdb, hdb );
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
ERR("Failed to set the database handle\n");
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
*handle = alloc_msi_remote_handle( (IUnknown *)rdb );
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
static HRESULT WINAPI mrp_GetProperty( IWineMsiRemotePackage *iface, BSTR property, BSTR value, DWORD *size )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2012-01-21 17:19:12 +00:00
|
|
|
UINT r = MsiGetPropertyW(This->package, property, value, size);
|
|
|
|
if (r != ERROR_SUCCESS) return HRESULT_FROM_WIN32(r);
|
2008-01-16 10:11:22 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_SetProperty( IWineMsiRemotePackage *iface, BSTR property, BSTR value )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2009-01-18 12:52:01 +00:00
|
|
|
UINT r = MsiSetPropertyW(This->package, property, value);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_ProcessMessage( IWineMsiRemotePackage *iface, INSTALLMESSAGE message, MSIHANDLE record )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2008-01-16 10:11:22 +00:00
|
|
|
UINT r = MsiProcessMessage(This->package, message, record);
|
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_DoAction( IWineMsiRemotePackage *iface, BSTR action )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2009-01-18 12:52:01 +00:00
|
|
|
UINT r = MsiDoActionW(This->package, action);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_Sequence( IWineMsiRemotePackage *iface, BSTR table, int sequence )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2009-01-18 12:52:01 +00:00
|
|
|
UINT r = MsiSequenceW(This->package, table, sequence);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
static HRESULT WINAPI mrp_GetTargetPath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value, DWORD *size )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2012-01-21 17:19:12 +00:00
|
|
|
UINT r = MsiGetTargetPathW(This->package, folder, value, size);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_SetTargetPath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value)
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2009-01-18 12:52:01 +00:00
|
|
|
UINT r = MsiSetTargetPathW(This->package, folder, value);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
static HRESULT WINAPI mrp_GetSourcePath( IWineMsiRemotePackage *iface, BSTR folder, BSTR value, DWORD *size )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2012-01-21 17:19:12 +00:00
|
|
|
UINT r = MsiGetSourcePathW(This->package, folder, value, size);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_GetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL *ret )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2008-01-16 10:11:22 +00:00
|
|
|
*ret = MsiGetMode(This->package, mode);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2010-03-01 12:01:30 +00:00
|
|
|
static HRESULT WINAPI mrp_SetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL state )
|
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2010-03-01 12:01:30 +00:00
|
|
|
UINT r = MsiSetMode(This->package, mode, state);
|
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_GetFeatureState( IWineMsiRemotePackage *iface, BSTR feature,
|
2008-01-16 10:11:22 +00:00
|
|
|
INSTALLSTATE *installed, INSTALLSTATE *action )
|
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2009-01-18 12:52:01 +00:00
|
|
|
UINT r = MsiGetFeatureStateW(This->package, feature, installed, action);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_SetFeatureState( IWineMsiRemotePackage *iface, BSTR feature, INSTALLSTATE state )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2009-01-18 12:52:01 +00:00
|
|
|
UINT r = MsiSetFeatureStateW(This->package, feature, state);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_GetComponentState( IWineMsiRemotePackage *iface, BSTR component,
|
2008-01-16 10:11:22 +00:00
|
|
|
INSTALLSTATE *installed, INSTALLSTATE *action )
|
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2009-01-18 12:52:01 +00:00
|
|
|
UINT r = MsiGetComponentStateW(This->package, component, installed, action);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_SetComponentState( IWineMsiRemotePackage *iface, BSTR component, INSTALLSTATE state )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2009-01-18 12:52:01 +00:00
|
|
|
UINT r = MsiSetComponentStateW(This->package, component, state);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_GetLanguage( IWineMsiRemotePackage *iface, LANGID *language )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2008-01-16 10:11:22 +00:00
|
|
|
*language = MsiGetLanguage(This->package);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_SetInstallLevel( IWineMsiRemotePackage *iface, int level )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2008-01-16 10:11:22 +00:00
|
|
|
UINT r = MsiSetInstallLevel(This->package, level);
|
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_FormatRecord( IWineMsiRemotePackage *iface, MSIHANDLE record,
|
2008-05-17 19:46:01 +00:00
|
|
|
BSTR *value)
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2008-05-17 19:46:01 +00:00
|
|
|
DWORD size = 0;
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2008-05-17 19:46:01 +00:00
|
|
|
UINT r = MsiFormatRecordW(This->package, record, NULL, &size);
|
|
|
|
if (r == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
*value = SysAllocStringLen(NULL, size);
|
|
|
|
if (!*value)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
size++;
|
|
|
|
r = MsiFormatRecordW(This->package, record, *value, &size);
|
|
|
|
}
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-04-04 13:43:40 +00:00
|
|
|
static HRESULT WINAPI mrp_EvaluateCondition( IWineMsiRemotePackage *iface, BSTR condition )
|
2008-01-16 10:11:22 +00:00
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2009-01-18 12:52:01 +00:00
|
|
|
UINT r = MsiEvaluateConditionW(This->package, condition);
|
2008-01-16 10:11:22 +00:00
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2009-11-16 01:13:42 +00:00
|
|
|
static HRESULT WINAPI mrp_GetFeatureCost( IWineMsiRemotePackage *iface, BSTR feature,
|
|
|
|
INT cost_tree, INSTALLSTATE state, INT *cost )
|
|
|
|
{
|
2011-03-20 08:47:41 +00:00
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
2009-11-16 01:13:42 +00:00
|
|
|
UINT r = MsiGetFeatureCostW(This->package, feature, cost_tree, state, cost);
|
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2012-01-21 17:19:12 +00:00
|
|
|
static HRESULT WINAPI mrp_EnumComponentCosts( IWineMsiRemotePackage *iface, BSTR component,
|
|
|
|
DWORD index, INSTALLSTATE state, BSTR drive,
|
|
|
|
DWORD *buflen, INT *cost, INT *temp )
|
|
|
|
{
|
|
|
|
msi_remote_package_impl* This = impl_from_IWineMsiRemotePackage( iface );
|
|
|
|
UINT r = MsiEnumComponentCostsW(This->package, component, index, state, drive, buflen, cost, temp);
|
|
|
|
return HRESULT_FROM_WIN32(r);
|
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl =
|
|
|
|
{
|
|
|
|
mrp_QueryInterface,
|
|
|
|
mrp_AddRef,
|
|
|
|
mrp_Release,
|
|
|
|
mrp_SetMsiHandle,
|
|
|
|
mrp_GetActiveDatabase,
|
|
|
|
mrp_GetProperty,
|
|
|
|
mrp_SetProperty,
|
|
|
|
mrp_ProcessMessage,
|
|
|
|
mrp_DoAction,
|
|
|
|
mrp_Sequence,
|
|
|
|
mrp_GetTargetPath,
|
|
|
|
mrp_SetTargetPath,
|
|
|
|
mrp_GetSourcePath,
|
|
|
|
mrp_GetMode,
|
2010-03-01 12:01:30 +00:00
|
|
|
mrp_SetMode,
|
2008-01-16 10:11:22 +00:00
|
|
|
mrp_GetFeatureState,
|
|
|
|
mrp_SetFeatureState,
|
|
|
|
mrp_GetComponentState,
|
|
|
|
mrp_SetComponentState,
|
|
|
|
mrp_GetLanguage,
|
|
|
|
mrp_SetInstallLevel,
|
|
|
|
mrp_FormatRecord,
|
|
|
|
mrp_EvaluateCondition,
|
2009-11-16 01:13:42 +00:00
|
|
|
mrp_GetFeatureCost,
|
2012-01-21 17:19:12 +00:00
|
|
|
mrp_EnumComponentCosts
|
2008-01-16 10:11:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
HRESULT create_msi_remote_package( IUnknown *pOuter, LPVOID *ppObj )
|
|
|
|
{
|
|
|
|
msi_remote_package_impl* This;
|
|
|
|
|
|
|
|
This = msi_alloc( sizeof *This );
|
|
|
|
if (!This)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
2011-03-20 08:47:41 +00:00
|
|
|
This->IWineMsiRemotePackage_iface.lpVtbl = &msi_remote_package_vtbl;
|
2008-01-16 10:11:22 +00:00
|
|
|
This->package = 0;
|
|
|
|
This->refs = 1;
|
|
|
|
|
|
|
|
*ppObj = This;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
UINT msi_package_add_info(MSIPACKAGE *package, DWORD context, DWORD options,
|
|
|
|
LPCWSTR property, LPWSTR value)
|
|
|
|
{
|
|
|
|
MSISOURCELISTINFO *info;
|
|
|
|
|
2011-03-20 08:47:41 +00:00
|
|
|
LIST_FOR_EACH_ENTRY( info, &package->sourcelist_info, MSISOURCELISTINFO, entry )
|
|
|
|
{
|
|
|
|
if (!strcmpW( info->value, value )) return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
info = msi_alloc(sizeof(MSISOURCELISTINFO));
|
|
|
|
if (!info)
|
|
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
|
|
|
|
info->context = context;
|
|
|
|
info->options = options;
|
|
|
|
info->property = property;
|
|
|
|
info->value = strdupW(value);
|
|
|
|
list_add_head(&package->sourcelist_info, &info->entry);
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
UINT msi_package_add_media_disk(MSIPACKAGE *package, DWORD context, DWORD options,
|
|
|
|
DWORD disk_id, LPWSTR volume_label, LPWSTR disk_prompt)
|
|
|
|
{
|
|
|
|
MSIMEDIADISK *disk;
|
|
|
|
|
2011-03-20 08:47:41 +00:00
|
|
|
LIST_FOR_EACH_ENTRY( disk, &package->sourcelist_media, MSIMEDIADISK, entry )
|
|
|
|
{
|
|
|
|
if (disk->disk_id == disk_id) return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2008-01-16 10:11:22 +00:00
|
|
|
disk = msi_alloc(sizeof(MSIMEDIADISK));
|
|
|
|
if (!disk)
|
|
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
|
|
|
|
disk->context = context;
|
|
|
|
disk->options = options;
|
|
|
|
disk->disk_id = disk_id;
|
|
|
|
disk->volume_label = strdupW(volume_label);
|
|
|
|
disk->disk_prompt = strdupW(disk_prompt);
|
|
|
|
list_add_head(&package->sourcelist_media, &disk->entry);
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|