📄 msi.c
字号:
/*
* Implementation of the Microsoft Installer (msi.dll)
*
* Copyright 2002,2003,2004,2005 Mike McCormack 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
*/
#include <stdarg.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "stdio.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "shlwapi.h"
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "msipriv.h"
#include "wincrypt.h"
#include "winver.h"
#include "winuser.h"
#include "shlobj.h"
#include "shobjidl.h"
#include "objidl.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
{
UINT r;
LPWSTR szwProd = NULL;
TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
if( szProduct )
{
szwProd = strdupAtoW( szProduct );
if( !szwProd )
return ERROR_OUTOFMEMORY;
}
r = MsiOpenProductW( szwProd, phProduct );
msi_free( szwProd );
return r;
}
static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
{
LPWSTR path = NULL;
UINT r;
HKEY hKeyProduct = NULL;
DWORD count, type;
TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
if( r != ERROR_SUCCESS )
{
r = ERROR_UNKNOWN_PRODUCT;
goto end;
}
/* find the size of the path */
type = count = 0;
r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
NULL, &type, NULL, &count );
if( r != ERROR_SUCCESS )
{
r = ERROR_UNKNOWN_PRODUCT;
goto end;
}
/* now alloc and fetch the path of the database to open */
path = msi_alloc( count );
if( !path )
goto end;
r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
NULL, &type, (LPBYTE) path, &count );
if( r != ERROR_SUCCESS )
{
r = ERROR_UNKNOWN_PRODUCT;
goto end;
}
r = MSI_OpenPackageW( path, ppackage );
end:
msi_free( path );
if( hKeyProduct )
RegCloseKey( hKeyProduct );
return r;
}
UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
{
MSIPACKAGE *package = NULL;
UINT r;
r = MSI_OpenProductW( szProduct, &package );
if( r == ERROR_SUCCESS )
{
*phProduct = alloc_msihandle( &package->hdr );
if (! *phProduct)
r = ERROR_NOT_ENOUGH_MEMORY;
msiobj_release( &package->hdr );
}
return r;
}
UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
LPCSTR szTransforms, LANGID lgidLanguage)
{
FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
LPCWSTR szTransforms, LANGID lgidLanguage)
{
FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
{
FIXME("%s %s %s %08x %08x %08x\n", debugstr_a(szPackagePath),
debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
lgidLanguage, dwPlatform, dwOptions);
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
{
FIXME("%s %s %s %08x %08x %08x\n", debugstr_w(szPackagePath),
debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
lgidLanguage, dwPlatform, dwOptions);
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
{
LPWSTR szwPath = NULL, szwCommand = NULL;
UINT r = ERROR_OUTOFMEMORY;
TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
if( szPackagePath )
{
szwPath = strdupAtoW( szPackagePath );
if( !szwPath )
goto end;
}
if( szCommandLine )
{
szwCommand = strdupAtoW( szCommandLine );
if( !szwCommand )
goto end;
}
r = MsiInstallProductW( szwPath, szwCommand );
end:
msi_free( szwPath );
msi_free( szwCommand );
return r;
}
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
{
MSIPACKAGE *package = NULL;
UINT r;
TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
r = MSI_OpenPackageW( szPackagePath, &package );
if (r == ERROR_SUCCESS)
{
r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
msiobj_release( &package->hdr );
}
return r;
}
UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
{
FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
{
FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
INSTALLTYPE eInstallType, LPCSTR szCommandLine)
{
FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
eInstallType, debugstr_a(szCommandLine));
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
{
FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
eInstallType, debugstr_w(szCommandLine));
return ERROR_CALL_NOT_IMPLEMENTED;
}
UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
{
MSIPACKAGE* package = NULL;
UINT r;
DWORD sz;
WCHAR sourcepath[MAX_PATH];
WCHAR filename[MAX_PATH];
static const WCHAR szInstalled[] = {
' ','I','n','s','t','a','l','l','e','d','=','1',0};
LPWSTR commandline;
TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
debugstr_w(szCommandLine));
if (eInstallState != INSTALLSTATE_LOCAL &&
eInstallState != INSTALLSTATE_DEFAULT)
{
FIXME("Not implemented for anything other than local installs\n");
return ERROR_CALL_NOT_IMPLEMENTED;
}
sz = sizeof(sourcepath);
MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
&sz);
sz = sizeof(filename);
MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
lstrcatW(sourcepath,filename);
/*
* ok 1, we need to find the msi file for this product.
* 2, find the source dir for the files
* 3, do the configure/install.
* 4, cleanupany runonce entry.
*/
r = MSI_OpenProductW( szProduct, &package );
if (r != ERROR_SUCCESS)
return r;
sz = lstrlenW(szInstalled) + 1;
if (szCommandLine)
sz += lstrlenW(szCommandLine);
commandline = msi_alloc(sz * sizeof(WCHAR));
if (!commandline )
{
r = ERROR_OUTOFMEMORY;
goto end;
}
commandline[0] = 0;
if (szCommandLine)
lstrcpyW(commandline,szCommandLine);
if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
lstrcatW(commandline,szInstalled);
r = MSI_InstallPackage( package, sourcepath, commandline );
msi_free(commandline);
end:
msiobj_release( &package->hdr );
return r;
}
UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
INSTALLSTATE eInstallState, LPCSTR szCommandLine)
{
LPWSTR szwProduct = NULL;
LPWSTR szwCommandLine = NULL;
UINT r = ERROR_OUTOFMEMORY;
if( szProduct )
{
szwProduct = strdupAtoW( szProduct );
if( !szwProduct )
goto end;
}
if( szCommandLine)
{
szwCommandLine = strdupAtoW( szCommandLine );
if( !szwCommandLine)
goto end;
}
r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
szwCommandLine );
end:
msi_free( szwProduct );
msi_free( szwCommandLine);
return r;
}
UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
INSTALLSTATE eInstallState)
{
LPWSTR szwProduct = NULL;
UINT r;
TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
if( szProduct )
{
szwProduct = strdupAtoW( szProduct );
if( !szwProduct )
return ERROR_OUTOFMEMORY;
}
r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
msi_free( szwProduct );
return r;
}
UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
INSTALLSTATE eInstallState)
{
return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
}
UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
{
LPWSTR szwComponent = NULL;
UINT r;
WCHAR szwBuffer[GUID_SIZE];
TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
if( szComponent )
{
szwComponent = strdupAtoW( szComponent );
if( !szwComponent )
return ERROR_OUTOFMEMORY;
}
r = MsiGetProductCodeW( szwComponent, szwBuffer );
if( ERROR_SUCCESS == r )
WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
msi_free( szwComponent );
return r;
}
UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
{
UINT rc;
HKEY hkey;
WCHAR szSquished[GUID_SIZE];
DWORD sz = GUID_SIZE;
static const WCHAR szPermKey[] =
{ '0','0','0','0','0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',0};
TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
if (NULL == szComponent)
return ERROR_INVALID_PARAMETER;
rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
if (rc != ERROR_SUCCESS)
return ERROR_UNKNOWN_COMPONENT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -