📄 package.c
字号:
check = msi_dup_property( package, szCOMPANYNAME );
if (!check)
{
LPWSTR company = msi_reg_get_val_str( hkey, szRegisteredOrg );
MSI_SetPropertyW( package, szCOMPANYNAME, company );
msi_free( company );
}
msi_free( check );
CloseHandle( hkey );
}
static UINT msi_get_word_count( MSIPACKAGE *package )
{
UINT rc;
INT word_count;
MSIHANDLE suminfo;
MSIHANDLE hdb = alloc_msihandle( &package->db->hdr );
if (!hdb) {
ERR("Unable to allocate handle\n");
return 0;
}
rc = MsiGetSummaryInformationW( hdb, NULL, 0, &suminfo );
MsiCloseHandle(hdb);
if (rc != ERROR_SUCCESS)
{
ERR("Unable to open Summary Information\n");
return 0;
}
rc = MsiSummaryInfoGetPropertyW( suminfo, PID_WORDCOUNT, NULL,
&word_count, NULL, NULL, NULL );
if (rc != ERROR_SUCCESS)
{
ERR("Unable to query word count\n");
MsiCloseHandle(suminfo);
return 0;
}
MsiCloseHandle(suminfo);
return word_count;
}
MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPWSTR base_url )
{
static const WCHAR szLevel[] = { 'U','I','L','e','v','e','l',0 };
static const WCHAR szpi[] = {'%','i',0};
static const WCHAR szProductCode[] = {
'P','r','o','d','u','c','t','C','o','d','e',0};
MSIPACKAGE *package = NULL;
WCHAR uilevel[10];
int i;
TRACE("%p\n", db);
package = alloc_msiobject( MSIHANDLETYPE_PACKAGE, sizeof (MSIPACKAGE),
MSI_FreePackage );
if( package )
{
msiobj_addref( &db->hdr );
package->db = db;
list_init( &package->components );
list_init( &package->features );
list_init( &package->files );
list_init( &package->tempfiles );
list_init( &package->folders );
package->ActionFormat = NULL;
package->LastAction = NULL;
package->dialog = NULL;
package->next_dialog = NULL;
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 );
package->WordCount = msi_get_word_count( package );
package->PackagePath = strdupW( db->path );
package->BaseURL = strdupW( base_url );
/* OK, here is where we do a slew of things to the database to
* prep for all that is to come as a package */
for (i=0; i<PROPERTY_HASH_SIZE; i++)
list_init( &package->props[i] );
clone_properties( package );
set_installer_properties(package);
sprintfW(uilevel,szpi,gUILevel);
MSI_SetPropertyW(package, szLevel, uilevel);
package->ProductCode = msi_dup_property( package, szProductCode );
set_installed_prop( package );
}
return package;
}
/*
* copy_package_to_temp [internal]
*
* copy the msi file to a temp file to prevent locking a CD
* with a multi disc install
*
* FIXME: I think this is wrong, and instead of copying the package,
* we should read all the tables to memory, then open the
* database to read binary streams on demand.
*/
static LPCWSTR copy_package_to_temp( LPCWSTR szPackage, LPWSTR filename )
{
WCHAR path[MAX_PATH];
static const WCHAR szMSI[] = {'M','S','I',0};
GetTempPathW( MAX_PATH, path );
GetTempFileNameW( path, szMSI, 0, filename );
if( !CopyFileW( szPackage, filename, FALSE ) )
{
ERR("failed to copy package %s\n", debugstr_w(szPackage) );
return szPackage;
}
TRACE("Opening relocated package %s\n", debugstr_w( filename ));
return filename;
}
LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename )
{
LPINTERNET_CACHE_ENTRY_INFOW cache_entry;
DWORD size = 0;
HRESULT hr;
/* call will always fail, becase size is 0,
* but will return ERROR_FILE_NOT_FOUND first
* if the file doesn't exist
*/
GetUrlCacheEntryInfoW( szUrl, NULL, &size );
if ( GetLastError() != ERROR_FILE_NOT_FOUND )
{
cache_entry = HeapAlloc( GetProcessHeap(), 0, size );
if ( !GetUrlCacheEntryInfoW( szUrl, cache_entry, &size ) )
{
HeapFree( GetProcessHeap(), 0, cache_entry );
return szUrl;
}
lstrcpyW( filename, cache_entry->lpszLocalFileName );
HeapFree( GetProcessHeap(), 0, cache_entry );
return filename;
}
hr = URLDownloadToCacheFileW( NULL, szUrl, filename, MAX_PATH, 0, NULL );
if ( FAILED(hr) )
return szUrl;
return filename;
}
UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
{
MSIDATABASE *db = NULL;
MSIPACKAGE *package;
MSIHANDLE handle;
LPWSTR ptr, base_url = NULL;
UINT r;
static const WCHAR OriginalDatabase[] =
{'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
static const WCHAR Database[] = {'D','A','T','A','B','A','S','E',0};
TRACE("%s %p\n", debugstr_w(szPackage), pPackage);
if( szPackage[0] == '#' )
{
handle = atoiW(&szPackage[1]);
db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
if( !db )
return ERROR_INVALID_HANDLE;
}
else
{
WCHAR temppath[MAX_PATH];
LPCWSTR file;
if ( UrlIsW( szPackage, URLIS_URL ) )
{
file = msi_download_file( szPackage, temppath );
base_url = strdupW( szPackage );
if ( !base_url )
return ERROR_OUTOFMEMORY;
ptr = strrchrW( base_url, '/' );
if (ptr) *(ptr + 1) = '\0';
}
else
file = copy_package_to_temp( szPackage, temppath );
r = MSI_OpenDatabaseW( file, MSIDBOPEN_READONLY, &db );
if (file != szPackage)
DeleteFileW( file );
if( r != ERROR_SUCCESS )
{
if (GetLastError() == ERROR_FILE_NOT_FOUND)
msi_ui_error( 4, MB_OK | MB_ICONWARNING );
return r;
}
}
package = MSI_CreatePackage( db, base_url );
msi_free( base_url );
msiobj_release( &db->hdr );
if( !package )
return ERROR_FUNCTION_FAILED;
if( szPackage[0] != '#' )
{
MSI_SetPropertyW( package, OriginalDatabase, szPackage );
MSI_SetPropertyW( package, Database, szPackage );
}
else
{
MSI_SetPropertyW( package, OriginalDatabase, db->path );
MSI_SetPropertyW( package, Database, db->path );
}
*pPackage = package;
return ERROR_SUCCESS;
}
UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
{
MSIPACKAGE *package = NULL;
UINT ret;
TRACE("%s %08x %p\n", debugstr_w(szPackage), dwOptions, phPackage );
if( szPackage == NULL )
return ERROR_INVALID_PARAMETER;
if( dwOptions )
FIXME("dwOptions %08x not supported\n", dwOptions);
ret = MSI_OpenPackageW( szPackage, &package );
if( ret == ERROR_SUCCESS )
{
*phPackage = alloc_msihandle( &package->hdr );
if (! *phPackage)
ret = ERROR_NOT_ENOUGH_MEMORY;
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;
TRACE("(%ld)\n",hInstall);
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
if( package)
{
handle = alloc_msihandle( &package->db->hdr );
msiobj_release( &package->hdr );
}
return handle;
}
INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType,
MSIRECORD *record)
{
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};
DWORD log_type = 0;
LPWSTR message;
DWORD sz;
DWORD total_size = 0;
INT i;
INT rc;
char *msg;
int len;
TRACE("%x\n", eMessageType);
rc = 0;
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;
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;
/* just a guess */
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_PROGRESS)
log_type |= 0x800;
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONSTART)
{
static const WCHAR template_s[]=
{'A','c','t','i','o','n',' ','%','s',':',' ','%','s','.',' ',0};
static const WCHAR format[] =
{'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);
if (!action || !action_text)
return IDOK;
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
{
INT msg_field=1;
message = msi_alloc(1*sizeof (WCHAR));
message[0]=0;
msg_field = MSI_RecordGetFieldCount(record);
for (i = 1; i <= msg_field; i++)
{
LPWSTR tmp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -