msi.c
来自「一个类似windows」· C语言 代码 · 共 2,039 行 · 第 1/4 页
C
2,039 行
LPWSTR path = NULL;
DWORD sz, type;
TRACE("%s %s %p %p\n", debugstr_w(szProduct),
debugstr_w(szComponent), lpPathBuf, pcchBuf);
if( !szComponent )
return INSTALLSTATE_INVALIDARG;
if( lpPathBuf && !pcchBuf )
return INSTALLSTATE_INVALIDARG;
squash_guid(szProduct,squished_pc);
rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
if( rc != ERROR_SUCCESS )
goto end;
RegCloseKey(hkey);
rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
if( rc != ERROR_SUCCESS )
goto end;
sz = 0;
type = 0;
rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );
if( rc != ERROR_SUCCESS )
goto end;
if( type != REG_SZ )
goto end;
sz += sizeof(WCHAR);
path = msi_alloc( sz );
if( !path )
goto end;
rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );
if( rc != ERROR_SUCCESS )
goto end;
TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
debugstr_w(szProduct), debugstr_w(path));
if (path[0]=='0')
{
FIXME("Registry entry.. check entry\n");
rrc = INSTALLSTATE_LOCAL;
}
else
{
/* PROBABLY a file */
if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )
rrc = INSTALLSTATE_LOCAL;
else
rrc = INSTALLSTATE_ABSENT;
}
if( pcchBuf )
{
sz = sz / sizeof(WCHAR);
if( *pcchBuf >= sz )
lstrcpyW( lpPathBuf, path );
*pcchBuf = sz;
}
end:
msi_free(path );
RegCloseKey(hkey);
return rrc;
}
/******************************************************************
* MsiQueryFeatureStateA [MSI.@]
*/
INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
{
LPWSTR szwProduct = NULL, szwFeature= NULL;
INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
szwProduct = strdupAtoW( szProduct );
if ( szProduct && !szwProduct )
goto end;
szwFeature = strdupAtoW( szFeature );
if ( szFeature && !szwFeature )
goto end;
rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
end:
msi_free( szwProduct);
msi_free( szwFeature);
return rc;
}
/******************************************************************
* MsiQueryFeatureStateW [MSI.@]
*
* This does not verify that the Feature is functional. So i am only going to
* check the existence of the key in the registry. This should tell me if it is
* installed.
*/
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
{
WCHAR squishProduct[GUID_SIZE];
UINT rc;
DWORD sz = 0;
HKEY hkey;
TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
if (!szProduct || !szFeature)
return INSTALLSTATE_INVALIDARG;
if (!squash_guid( szProduct, squishProduct ))
return INSTALLSTATE_INVALIDARG;
rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
if (rc != ERROR_SUCCESS)
return INSTALLSTATE_UNKNOWN;
rc = RegQueryValueExW( hkey, szFeature, NULL, NULL, NULL, &sz);
RegCloseKey(hkey);
if (rc == ERROR_SUCCESS)
return INSTALLSTATE_LOCAL;
return INSTALLSTATE_UNKNOWN;
}
/******************************************************************
* MsiGetFileVersionA [MSI.@]
*/
UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
{
LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
UINT ret = ERROR_OUTOFMEMORY;
if( szFilePath )
{
szwFilePath = strdupAtoW( szFilePath );
if( !szwFilePath )
goto end;
}
if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
{
lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
if( !lpwVersionBuff )
goto end;
}
if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
{
lpwLangBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
if( !lpwLangBuff )
goto end;
}
ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
lpwLangBuff, pcchLangBuf);
if( lpwVersionBuff )
WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
lpVersionBuf, *pcchVersionBuf, NULL, NULL);
if( lpwLangBuff )
WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
lpLangBuf, *pcchLangBuf, NULL, NULL);
end:
msi_free(szwFilePath);
msi_free(lpwVersionBuff);
msi_free(lpwLangBuff);
return ret;
}
/******************************************************************
* MsiGetFileVersionW [MSI.@]
*/
UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
{
static WCHAR szVersionResource[] = {'\\',0};
static const WCHAR szVersionFormat[] = {
'%','d','.','%','d','.','%','d','.','%','d',0};
static const WCHAR szLangFormat[] = {'%','d',0};
UINT ret = 0;
DWORD dwVerLen;
LPVOID lpVer = NULL;
VS_FIXEDFILEINFO *ffi;
UINT puLen;
WCHAR tmp[32];
TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
if( !dwVerLen )
return GetLastError();
lpVer = msi_alloc(dwVerLen);
if( !lpVer )
{
ret = ERROR_OUTOFMEMORY;
goto end;
}
if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
{
ret = GetLastError();
goto end;
}
if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
{
if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
(puLen > 0) )
{
wsprintfW(tmp, szVersionFormat,
HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
*pcchVersionBuf = lstrlenW(lpVersionBuf);
}
else
{
*lpVersionBuf = 0;
*pcchVersionBuf = 0;
}
}
if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
{
DWORD lang = GetUserDefaultLangID();
FIXME("Retrieve language from file\n");
wsprintfW(tmp, szLangFormat, lang);
lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
*pcchLangBuf = lstrlenW(lpLangBuf);
}
end:
msi_free(lpVer);
return ret;
}
/******************************************************************
* DllMain
*/
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
msi_hInstance = hinstDLL;
DisableThreadLibraryCalls(hinstDLL);
msi_dialog_register_class();
break;
case DLL_PROCESS_DETACH:
msi_dialog_unregister_class();
/* FIXME: Cleanup */
break;
}
return TRUE;
}
typedef struct tagIClassFactoryImpl
{
const IClassFactoryVtbl *lpVtbl;
} IClassFactoryImpl;
static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid,LPVOID *ppobj)
{
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
return E_NOINTERFACE;
}
static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
{
LockModule();
return 2;
}
static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
{
UnlockModule();
return 1;
}
static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
{
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
return E_FAIL;
}
static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
{
TRACE("(%p)->(%d)\n", iface, dolock);
if(dolock)
LockModule();
else
UnlockModule();
return S_OK;
}
static const IClassFactoryVtbl MsiCF_Vtbl =
{
MsiCF_QueryInterface,
MsiCF_AddRef,
MsiCF_Release,
MsiCF_CreateInstance,
MsiCF_LockServer
};
static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
/******************************************************************
* DllGetClassObject [MSI.@]
*/
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
{
*ppv = (LPVOID) &Msi_CF;
return S_OK;
}
return CLASS_E_CLASSNOTAVAILABLE;
}
/******************************************************************
* DllGetVersion [MSI.@]
*/
HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi)
{
TRACE("%p\n",pdvi);
if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
return E_INVALIDARG;
pdvi->dwMajorVersion = MSI_MAJORVERSION;
pdvi->dwMinorVersion = MSI_MINORVERSION;
pdvi->dwBuildNumber = MSI_BUILDNUMBER;
pdvi->dwPlatformID = 1;
return S_OK;
}
/******************************************************************
* DllCanUnloadNow [MSI.@]
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
return dll_count == 0 ? S_OK : S_FALSE;
}
/***********************************************************************
* MsiGetFeatureUsageW [MSI.@]
*/
UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
DWORD* pdwUseCount, WORD* pwDateUsed )
{
FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
pdwUseCount, pwDateUsed);
return ERROR_CALL_NOT_IMPLEMENTED;
}
/***********************************************************************
* MsiGetFeatureUsageA [MSI.@]
*/
UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
DWORD* pdwUseCount, WORD* pwDateUsed )
{
LPWSTR prod = NULL, feat = NULL;
UINT ret = ERROR_OUTOFMEMORY;
TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
pdwUseCount, pwDateUsed);
prod = strdupAtoW( szProduct );
if (szProduct && !prod)
goto end;
feat = strdupAtoW( szFeature );
if (szFeature && !feat)
goto end;
ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
end:
msi_free( prod );
msi_free( feat );
return ret;
}
/***********************************************************************
* MsiUseFeatureExW [MSI.@]
*/
INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
DWORD dwInstallMode, DWORD dwReserved )
{
INSTALLSTATE state;
TRACE("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
dwInstallMode, dwReserved);
state = MsiQueryFeatureStateW( szProduct, szFeature );
if (dwReserved)
return INSTALLSTATE_INVALIDARG;
if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
{
FIXME("mark product %s feature %s as used\n",
debugstr_w(szProduct), debugstr_w(szFeature) );
}
return state;
}
/***********************************************************************
* MsiUseFeatureExA [MSI.@]
*/
INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
DWORD dwInstallMode, DWORD dwReserved )
{
INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
LPWSTR prod = NULL, feat = NULL;
TRACE("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
dwInstallMode, dwReserved);
prod = strdupAtoW( szProduct );
if (szProduct && !prod)
goto end;
feat = strdupAtoW( szFeature );
if (szFeature && !feat)
goto end;
ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
end:
msi_free( prod );
msi_free( feat );
return ret;
}
INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
{
FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
return INSTALLSTATE_LOCAL;
}
INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
{
INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
LPWSTR prod = NULL, feat = NULL;
TRACE("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature) );
prod = strdupAtoW( szProduct );
if (szProduct && !prod)
goto end;
feat = strdupAtoW( szFeature );
if (szFeature && !feat)
goto end;
ret = MsiUseFeatureW( prod, feat );
end:
msi_free( prod );
msi_free( feat );
return ret;
}
/***********************************************************************
* MsiProvideQualifiedComponentExW [MSI.@]
*/
UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
DWORD* pcchPathBuf)
{
HKEY hkey;
UINT rc;
LPWSTR info;
DWORD sz;
WCHAR product[MAX_FEATURE_CHARS+1];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?