📄 package.c
字号:
/*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "shlwapi.h"
#include "wingdi.h"
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "objidl.h"
#include "wincrypt.h"
#include "winuser.h"
#include "wininet.h"
#include "urlmon.h"
#include "shlobj.h"
#include "wine/unicode.h"
#include "objbase.h"
#include "msidefs.h"
#include "msipriv.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
static void msi_free_properties( MSIPACKAGE *package );
static void MSI_FreePackage( MSIOBJECTHDR *arg)
{
MSIPACKAGE *package= (MSIPACKAGE*) arg;
if( package->dialog )
msi_dialog_destroy( package->dialog );
ACTION_free_package_structures(package);
msi_free_properties( package );
msiobj_release( &package->db->hdr );
}
static UINT clone_properties( MSIPACKAGE *package )
{
MSIQUERY * view = NULL;
UINT rc;
static const WCHAR Query[] = {
'S','E','L','E','C','T',' ','*',' ',
'F','R','O','M',' ','`','P','r','o','p','e','r','t','y','`',0};
/* clone the existing properties */
rc = MSI_DatabaseOpenViewW( package->db, Query, &view );
if (rc != ERROR_SUCCESS)
return rc;
rc = MSI_ViewExecute(view, 0);
if (rc != ERROR_SUCCESS)
{
MSI_ViewClose(view);
msiobj_release(&view->hdr);
return rc;
}
while (1)
{
MSIRECORD * row;
LPCWSTR name, value;
rc = MSI_ViewFetch(view,&row);
if (rc != ERROR_SUCCESS)
break;
name = MSI_RecordGetString( row, 1 );
value = MSI_RecordGetString( row, 2 );
MSI_SetPropertyW( package, name, value );
msiobj_release( &row->hdr );
}
MSI_ViewClose(view);
msiobj_release(&view->hdr);
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 )
{
static const WCHAR szInstalled[] = {
'I','n','s','t','a','l','l','e','d',0 };
WCHAR val[2] = { '1', 0 };
HKEY hkey = 0;
UINT r;
r = MSIREG_OpenUninstallKey( package->ProductCode, &hkey, FALSE );
if (r == ERROR_SUCCESS)
{
RegCloseKey( hkey );
MSI_SetPropertyW( package, szInstalled, val );
}
return r;
}
/*
* There are a whole slew of these we need to set
*
*
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/properties.asp
*/
static VOID set_installer_properties(MSIPACKAGE *package)
{
WCHAR pth[MAX_PATH];
WCHAR *ptr;
OSVERSIONINFOA OSVersion;
MEMORYSTATUSEX msex;
DWORD verval;
WCHAR verstr[10], bufstr[20];
HDC dc;
LPWSTR check;
HKEY hkey;
LONG res;
static const WCHAR cszbs[]={'\\',0};
static const WCHAR CFF[] =
{'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0};
static const WCHAR PFF[] =
{'P','r','o','g','r','a','m','F','i','l','e','s','F','o','l','d','e','r',0};
static const WCHAR CADF[] =
{'C','o','m','m','o','n','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
static const WCHAR FaF[] =
{'F','a','v','o','r','i','t','e','s','F','o','l','d','e','r',0};
static const WCHAR FoF[] =
{'F','o','n','t','s','F','o','l','d','e','r',0};
static const WCHAR SendTF[] =
{'S','e','n','d','T','o','F','o','l','d','e','r',0};
static const WCHAR SMF[] =
{'S','t','a','r','t','M','e','n','u','F','o','l','d','e','r',0};
static const WCHAR StF[] =
{'S','t','a','r','t','u','p','F','o','l','d','e','r',0};
static const WCHAR TemplF[] =
{'T','e','m','p','l','a','t','e','F','o','l','d','e','r',0};
static const WCHAR DF[] =
{'D','e','s','k','t','o','p','F','o','l','d','e','r',0};
static const WCHAR PMF[] =
{'P','r','o','g','r','a','m','M','e','n','u','F','o','l','d','e','r',0};
static const WCHAR ATF[] =
{'A','d','m','i','n','T','o','o','l','s','F','o','l','d','e','r',0};
static const WCHAR ADF[] =
{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
static const WCHAR SF[] =
{'S','y','s','t','e','m','F','o','l','d','e','r',0};
static const WCHAR SF16[] =
{'S','y','s','t','e','m','1','6','F','o','l','d','e','r',0};
static const WCHAR LADF[] =
{'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
static const WCHAR MPF[] =
{'M','y','P','i','c','t','u','r','e','s','F','o','l','d','e','r',0};
static const WCHAR PF[] =
{'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
static const WCHAR WF[] =
{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
static const WCHAR WV[] =
{'W','i','n','d','o','w','s','V','o','l','u','m','e',0};
static const WCHAR TF[]=
{'T','e','m','p','F','o','l','d','e','r',0};
static const WCHAR szAdminUser[] =
{'A','d','m','i','n','U','s','e','r',0};
static const WCHAR szPriv[] =
{'P','r','i','v','i','l','e','g','e','d',0};
static const WCHAR szOne[] =
{'1',0};
static const WCHAR v9x[] = { 'V','e','r','s','i','o','n','9','X',0 };
static const WCHAR vNT[] = { 'V','e','r','s','i','o','n','N','T',0 };
static const WCHAR szFormat[] = {'%','l','i',0};
static const WCHAR szWinBuild[] =
{'W','i','n','d','o','w','s','B','u','i','l','d', 0 };
static const WCHAR szSPL[] =
{'S','e','r','v','i','c','e','P','a','c','k','L','e','v','e','l',0 };
static const WCHAR szSix[] = {'6',0 };
static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 };
static const WCHAR szPhysicalMemory[] = { 'P','h','y','s','i','c','a','l','M','e','m','o','r','y',0 };
static const WCHAR szFormat2[] = {'%','l','i','.','%','l','i',0};
/* Screen properties */
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};
static const WCHAR szScreenFormat[] = {'%','d',0};
static const WCHAR szIntel[] = { 'I','n','t','e','l',0 };
static const WCHAR szAllUsers[] = { 'A','L','L','U','S','E','R','S',0 };
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};
static const WCHAR szRegisteredOrg[] = {
'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};
SYSTEM_INFO sys_info;
/*
* Other things that probably should be set:
*
* SystemLanguageID ComputerName UserLanguageID LogonUser VirtualMemory
* Intel ShellAdvSupport DefaultUIFont VersionDatabase PackagecodeChanging
* ProductState CaptionHeight BorderTop BorderSide TextHeight
* RedirectedDllSupport Time Date Privileged
*/
SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES_COMMON,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, CFF, pth);
SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, PFF, pth);
SHGetFolderPathW(NULL,CSIDL_COMMON_APPDATA,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, CADF, pth);
SHGetFolderPathW(NULL,CSIDL_FAVORITES,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, FaF, pth);
SHGetFolderPathW(NULL,CSIDL_FONTS,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, FoF, pth);
SHGetFolderPathW(NULL,CSIDL_SENDTO,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, SendTF, pth);
SHGetFolderPathW(NULL,CSIDL_STARTMENU,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, SMF, pth);
SHGetFolderPathW(NULL,CSIDL_STARTUP,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, StF, pth);
SHGetFolderPathW(NULL,CSIDL_TEMPLATES,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, TemplF, pth);
SHGetFolderPathW(NULL,CSIDL_DESKTOP,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, DF, pth);
SHGetFolderPathW(NULL,CSIDL_PROGRAMS,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, PMF, pth);
SHGetFolderPathW(NULL,CSIDL_ADMINTOOLS,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, ATF, pth);
SHGetFolderPathW(NULL,CSIDL_APPDATA,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, ADF, pth);
SHGetFolderPathW(NULL,CSIDL_SYSTEM,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, SF, pth);
MSI_SetPropertyW(package, SF16, pth);
SHGetFolderPathW(NULL,CSIDL_LOCAL_APPDATA,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, LADF, pth);
SHGetFolderPathW(NULL,CSIDL_MYPICTURES,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, MPF, pth);
SHGetFolderPathW(NULL,CSIDL_PERSONAL,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, PF, pth);
SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth);
strcatW(pth,cszbs);
MSI_SetPropertyW(package, WF, pth);
/* Physical Memory is specified in MB. Using total amount. */
msex.dwLength = sizeof(msex);
GlobalMemoryStatusEx( &msex );
sprintfW( bufstr, szScreenFormat, (int)(msex.ullTotalPhys/1024/1024));
MSI_SetPropertyW(package, szPhysicalMemory, bufstr);
SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth);
ptr = strchrW(pth,'\\');
if (ptr)
*(ptr+1) = 0;
MSI_SetPropertyW(package, WV, pth);
GetTempPathW(MAX_PATH,pth);
MSI_SetPropertyW(package, TF, pth);
/* in a wine environment the user is always admin and privileged */
MSI_SetPropertyW(package,szAdminUser,szOne);
MSI_SetPropertyW(package,szPriv,szOne);
MSI_SetPropertyW(package, szAllUsers, szOne);
/* set the os things */
OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
GetVersionExA(&OSVersion);
verval = OSVersion.dwMinorVersion+OSVersion.dwMajorVersion*100;
sprintfW(verstr,szFormat,verval);
switch (OSVersion.dwPlatformId)
{
case VER_PLATFORM_WIN32_WINDOWS:
MSI_SetPropertyW(package,v9x,verstr);
break;
case VER_PLATFORM_WIN32_NT:
MSI_SetPropertyW(package,vNT,verstr);
break;
}
sprintfW(verstr,szFormat,OSVersion.dwBuildNumber);
MSI_SetPropertyW(package,szWinBuild,verstr);
/* just fudge this */
MSI_SetPropertyW(package,szSPL,szSix);
sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
MSI_SetPropertyW( package, szVersionMsi, bufstr );
GetSystemInfo( &sys_info );
if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
{
sprintfW( bufstr, szScreenFormat, sys_info.wProcessorLevel );
MSI_SetPropertyW( package, szIntel, bufstr );
}
/* Screen properties. */
dc = GetDC(0);
sprintfW( bufstr, szScreenFormat, GetDeviceCaps( dc, HORZRES ) );
MSI_SetPropertyW( package, szScreenX, bufstr );
sprintfW( bufstr, szScreenFormat, GetDeviceCaps( dc, VERTRES ));
MSI_SetPropertyW( package, szScreenY, bufstr );
sprintfW( bufstr, szScreenFormat, GetDeviceCaps( dc, BITSPIXEL ));
MSI_SetPropertyW( package, szColorBits, bufstr );
ReleaseDC(0, dc);
/* USERNAME and COMPANYNAME */
res = RegOpenKeyW( HKEY_LOCAL_MACHINE, szCurrentVersion, &hkey );
if (res != ERROR_SUCCESS)
return;
check = msi_dup_property( package, szUSERNAME );
if (!check)
{
LPWSTR user = msi_reg_get_val_str( hkey, szRegisteredUser );
MSI_SetPropertyW( package, szUSERNAME, user );
msi_free( user );
}
msi_free( check );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -