📄 msi.c
字号:
rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
{
sz = GUID_SIZE;
rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
}
RegCloseKey(hkey);
if (rc != ERROR_SUCCESS)
return ERROR_INSTALL_FAILURE;
unsquash_guid(szSquished, szBuffer);
return ERROR_SUCCESS;
}
static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
awstring *szValue, DWORD *pcchValueBuf)
{
UINT r;
HKEY hkey;
LPWSTR val = NULL;
TRACE("%s %s %p %p\n", debugstr_w(szProduct),
debugstr_w(szAttribute), szValue, pcchValueBuf);
/*
* FIXME: Values seem scattered/duplicated in the registry. Is there a system?
*/
if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
return ERROR_INVALID_PARAMETER;
/* check for special properties */
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
{
LPWSTR regval;
WCHAR packagecode[35];
r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
regval = msi_reg_get_val_str( hkey, szAttribute );
if (regval)
{
if (unsquash_guid(regval, packagecode))
val = strdupW(packagecode);
msi_free(regval);
}
RegCloseKey(hkey);
}
else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
{
static const WCHAR one[] = { '1',0 };
/*
* FIXME: should be in the Product key (user or system?)
* but isn't written yet...
*/
val = strdupW( one );
}
else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW))
{
static const WCHAR fmt[] = { '%','u',0 };
WCHAR szVal[16];
DWORD regval;
r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
if (msi_reg_get_val_dword( hkey, szAttribute, ®val))
{
sprintfW(szVal, fmt, regval);
val = strdupW( szVal );
}
RegCloseKey(hkey);
}
else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW))
{
r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
val = msi_reg_get_val_str( hkey, szAttribute );
RegCloseKey(hkey);
}
else
{
static const WCHAR szDisplayVersion[] = {
'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0 };
FIXME("%s\n", debugstr_w(szAttribute));
/* FIXME: some attribute values not tested... */
if (!lstrcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ))
szAttribute = szDisplayVersion;
r = MSIREG_OpenUninstallKey( szProduct, &hkey, FALSE );
if (r != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
val = msi_reg_get_val_str( hkey, szAttribute );
RegCloseKey(hkey);
}
TRACE("returning %s\n", debugstr_w(val));
if (!val)
return ERROR_UNKNOWN_PROPERTY;
r = msi_strcpy_to_awstring( val, szValue, pcchValueBuf );
msi_free(val);
return r;
}
UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
LPSTR szBuffer, DWORD *pcchValueBuf)
{
LPWSTR szwProduct, szwAttribute = NULL;
UINT r = ERROR_OUTOFMEMORY;
awstring buffer;
TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
szBuffer, pcchValueBuf);
szwProduct = strdupAtoW( szProduct );
if( szProduct && !szwProduct )
goto end;
szwAttribute = strdupAtoW( szAttribute );
if( szAttribute && !szwAttribute )
goto end;
buffer.unicode = FALSE;
buffer.str.a = szBuffer;
r = MSI_GetProductInfo( szwProduct, szwAttribute,
&buffer, pcchValueBuf );
end:
msi_free( szwProduct );
msi_free( szwAttribute );
return r;
}
UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
LPWSTR szBuffer, DWORD *pcchValueBuf)
{
awstring buffer;
TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
szBuffer, pcchValueBuf);
buffer.unicode = TRUE;
buffer.str.w = szBuffer;
return MSI_GetProductInfo( szProduct, szAttribute,
&buffer, pcchValueBuf );
}
UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
{
LPWSTR szwLogFile = NULL;
UINT r;
TRACE("%08x %s %08x\n", dwLogMode, debugstr_a(szLogFile), attributes);
if( szLogFile )
{
szwLogFile = strdupAtoW( szLogFile );
if( !szwLogFile )
return ERROR_OUTOFMEMORY;
}
r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
msi_free( szwLogFile );
return r;
}
UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
{
HANDLE file = INVALID_HANDLE_VALUE;
TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
if (szLogFile)
{
lstrcpyW(gszLogFile,szLogFile);
if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
DeleteFileW(szLogFile);
file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (file != INVALID_HANDLE_VALUE)
CloseHandle(file);
else
ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
}
else
gszLogFile[0] = '\0';
return ERROR_SUCCESS;
}
INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
{
LPWSTR szwProduct = NULL;
INSTALLSTATE r;
if( szProduct )
{
szwProduct = strdupAtoW( szProduct );
if( !szwProduct )
return ERROR_OUTOFMEMORY;
}
r = MsiQueryProductStateW( szwProduct );
msi_free( szwProduct );
return r;
}
INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
{
UINT rc;
INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
HKEY hkey = 0;
static const WCHAR szWindowsInstaller[] = {
'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
DWORD sz;
TRACE("%s\n", debugstr_w(szProduct));
if (!szProduct)
return INSTALLSTATE_INVALIDARG;
rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
if (rc != ERROR_SUCCESS)
goto end;
RegCloseKey(hkey);
rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
if (rc != ERROR_SUCCESS)
goto end;
sz = sizeof(rrc);
rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
if (rc != ERROR_SUCCESS)
goto end;
switch (rrc)
{
case 1:
/* default */
rrc = INSTALLSTATE_DEFAULT;
break;
default:
FIXME("Unknown install state read from registry (%i)\n",rrc);
rrc = INSTALLSTATE_UNKNOWN;
break;
}
end:
RegCloseKey(hkey);
return rrc;
}
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
{
INSTALLUILEVEL old = gUILevel;
HWND oldwnd = gUIhwnd;
TRACE("%08x %p\n", dwUILevel, phWnd);
gUILevel = dwUILevel;
if (phWnd)
{
gUIhwnd = *phWnd;
*phWnd = oldwnd;
}
return old;
}
INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
DWORD dwMessageFilter, LPVOID pvContext)
{
INSTALLUI_HANDLERA prev = gUIHandlerA;
TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
gUIHandlerA = puiHandler;
gUIFilter = dwMessageFilter;
gUIContext = pvContext;
return prev;
}
INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
DWORD dwMessageFilter, LPVOID pvContext)
{
INSTALLUI_HANDLERW prev = gUIHandlerW;
TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
gUIHandlerW = puiHandler;
gUIFilter = dwMessageFilter;
gUIContext = pvContext;
return prev;
}
/******************************************************************
* MsiLoadStringW [MSI.@]
*
* Loads a string from MSI's string resources.
*
* PARAMS
*
* handle [I] only -1 is handled currently
* id [I] id of the string to be loaded
* lpBuffer [O] buffer for the string to be written to
* nBufferMax [I] maximum size of the buffer in characters
* lang [I] the preferred language for the string
*
* RETURNS
*
* If successful, this function returns the language id of the string loaded
* If the function fails, the function returns zero.
*
* NOTES
*
* The type of the first parameter is unknown. LoadString's prototype
* suggests that it might be a module handle. I have made it an MSI handle
* for starters, as -1 is an invalid MSI handle, but not an invalid module
* handle. Maybe strings can be stored in an MSI database somehow.
*/
LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
int nBufferMax, LANGID lang )
{
HRSRC hres;
HGLOBAL hResData;
LPWSTR p;
DWORD i, len;
TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
if( handle != -1 )
FIXME("don't know how to deal with handle = %08lx\n", handle);
if( !lang )
lang = GetUserDefaultLangID();
hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
(LPWSTR)1, lang );
if( !hres )
return 0;
hResData = LoadResource( msi_hInstance, hres );
if( !hResData )
return 0;
p = LockResource( hResData );
if( !p )
return 0;
for (i = 0; i < (id&0xf); i++)
p += *p + 1;
len = *p;
if( nBufferMax <= len )
return 0;
memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
lpBuffer[ len ] = 0;
TRACE("found -> %s\n", debugstr_w(lpBuffer));
return lang;
}
LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
int nBufferMax, LANGID lang )
{
LPWSTR bufW;
LANGID r;
DWORD len;
bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
if( r )
{
len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
if( len <= nBufferMax )
WideCharToMultiByte( CP_ACP, 0, bufW, -1,
lpBuffer, nBufferMax, NULL, NULL );
else
r = 0;
}
msi_free(bufW);
return r;
}
INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
DWORD *pcchBuf)
{
char szProduct[GUID_SIZE];
TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
return INSTALLSTATE_UNKNOWN;
return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -