You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
997 lines
28 KiB
997 lines
28 KiB
//***************************************************************************
|
|
|
|
//
|
|
|
|
// MSIProv.CPP
|
|
|
|
//
|
|
|
|
// Module: WBEM Instance provider for MSI
|
|
|
|
//
|
|
|
|
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
|
|
//
|
|
//***************************************************************************
|
|
|
|
#include "precomp.h"
|
|
#include <wbemcli_i.c>
|
|
#include <wbemprov_i.c>
|
|
#include "requestobject.h"
|
|
//#define _MT
|
|
#include <process.h>
|
|
#include <Polarity.h>
|
|
|
|
#include <tchar.h>
|
|
|
|
CRITICAL_SECTION g_msi_prov_cs;
|
|
|
|
WCHAR *g_wcpLoggingDir = NULL;
|
|
|
|
bool g_bMsiPresent = true;
|
|
bool g_bMsiLoaded = false;
|
|
|
|
CHeap_Exception CMSIProv::m_he(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
|
|
LPFNMSIVIEWFETCH g_fpMsiViewFetch = NULL;
|
|
LPFNMSIRECORDGETSTRINGW g_fpMsiRecordGetStringW = NULL;
|
|
LPFNMSICLOSEHANDLE g_fpMsiCloseHandle = NULL;
|
|
LPFNMSIDATABASEOPENVIEWW g_fpMsiDatabaseOpenViewW = NULL;
|
|
LPFNMSIVIEWEXECUTE g_fpMsiViewExecute = NULL;
|
|
LPFNMSIGETACTIVEDATABASE g_fpMsiGetActiveDatabase = NULL;
|
|
LPFNMSIGETCOMPONENTPATHW g_fpMsiGetComponentPathW = NULL;
|
|
LPFNMSIGETCOMPONENTSTATEW g_fpMsiGetComponentStateW = NULL;
|
|
LPFNMSIOPENPRODUCTW g_fpMsiOpenProductW = NULL;
|
|
LPFNMSIOPENPACKAGEW g_fpMsiOpenPackageW = NULL;
|
|
LPFNMSIDATABASEISTABLEPERSITENTW g_fpMsiDatabaseIsTablePersistentW = NULL;
|
|
LPFNMSISETINTERNALUI g_fpMsiSetInternalUI = NULL;
|
|
LPFNMSISETEXTERNALUIW g_fpMsiSetExternalUIW = NULL;
|
|
LPFNMSIENABLELOGW g_fpMsiEnableLogW = NULL;
|
|
LPFNMSIGETPRODUCTPROPERTYW g_fpMsiGetProductPropertyW = NULL;
|
|
LPFNMSIQUERYPRODUCTSTATEW g_fpMsiQueryProductStateW = NULL;
|
|
LPFNMSIINSTALLPRODUCTW g_fpMsiInstallProductW = NULL;
|
|
LPFNMSICONFIGUREPRODUCTW g_fpMsiConfigureProductW = NULL;
|
|
LPFNMSIREINSTALLPRODUCTW g_fpMsiReinstallProductW = NULL;
|
|
LPFNMSIAPPLYPATCHW g_fpMsiApplyPatchW = NULL;
|
|
LPFNMSIRECORDGETINTEGER g_fpMsiRecordGetInteger = NULL;
|
|
LPFNMSIENUMFEATURESW g_fpMsiEnumFeaturesW = NULL;
|
|
LPFNMSIGETPRODUCTINFOW g_fpMsiGetProductInfoW = NULL;
|
|
LPFNMSIQUERYFEATURESTATEW g_fpMsiQueryFeatureStateW = NULL;
|
|
LPFNMSIGETFEATUREUSAGEW g_fpMsiGetFeatureUsageW = NULL;
|
|
LPFNMSIGETFEATUREINFOW g_fpMsiGetFeatureInfoW = NULL;
|
|
LPFNMSICONFIGUREFEATUREW g_fpMsiConfigureFeatureW = NULL;
|
|
LPFNMSIREINSTALLFEATUREW g_fpMsiReinstallFeatureW = NULL;
|
|
LPFNMSIENUMPRODUCTSW g_fpMsiEnumProductsW = NULL;
|
|
LPFNMSIGETDATABASESTATE g_fpMsiGetDatabaseState = NULL;
|
|
LPFNMSIRECORDSETSTRINGW g_fpMsiRecordSetStringW = NULL;
|
|
LPFNMSIDATABASECOMMIT g_fpMsiDatabaseCommit = NULL;
|
|
LPFNMSIENUMCOMPONENTSW g_fpMsiEnumComponentsW = NULL;
|
|
LPFNMSIVIEWCLOSE g_fpMsiViewClose = NULL;
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CMSIProv::CMSIProv
|
|
// CMSIProv::~CMSIProv
|
|
//
|
|
//***************************************************************************
|
|
|
|
CMSIProv::CMSIProv(BSTR ObjectPath, BSTR User, BSTR Password, IWbemContext * pCtx)
|
|
{
|
|
m_pNamespace = NULL;
|
|
m_cRef = 0;
|
|
|
|
InterlockedIncrement(&g_cObj);
|
|
|
|
return;
|
|
}
|
|
|
|
CMSIProv::~CMSIProv(void)
|
|
{
|
|
if(m_pNamespace) m_pNamespace->Release();
|
|
|
|
InterlockedDecrement(&g_cObj) ;
|
|
|
|
return;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CMSIProv::QueryInterface
|
|
// CMSIProv::AddRef
|
|
// CMSIProv::Release
|
|
//
|
|
// Purpose: IUnknown members for CMSIProv object.
|
|
//***************************************************************************
|
|
|
|
|
|
STDMETHODIMP CMSIProv::QueryInterface(REFIID riid, PPVOID ppv)
|
|
{
|
|
*ppv=NULL;
|
|
|
|
// Since we have dual inheritance, it is necessary to cast the return type
|
|
|
|
if(riid == IID_IWbemServices)
|
|
*ppv = (IWbemServices*)this;
|
|
|
|
if(IID_IUnknown == riid || riid == IID_IWbemProviderInit)
|
|
*ppv = (IWbemProviderInit*)this;
|
|
|
|
|
|
if(NULL!=*ppv){
|
|
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
else return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(ULONG) CMSIProv::AddRef(void)
|
|
{
|
|
return ++m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CMSIProv::Release(void)
|
|
{
|
|
ULONG nNewCount = InterlockedDecrement((long *)&m_cRef);
|
|
|
|
if(0L == nNewCount){
|
|
|
|
delete this;
|
|
}
|
|
|
|
return nNewCount;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* *
|
|
* CMSIProv::Initialize *
|
|
* *
|
|
* Purpose: This is the implementation of IWbemProviderInit. The method *
|
|
* is need to initialize with CIMOM. *
|
|
* *
|
|
***********************************************************************/
|
|
|
|
STDMETHODIMP CMSIProv::Initialize(LPWSTR pszUser, LONG lFlags,
|
|
LPWSTR pszNamespace, LPWSTR pszLocale,
|
|
IWbemServices *pNamespace,
|
|
IWbemContext *pCtx,
|
|
IWbemProviderInitSink *pInitSink)
|
|
{
|
|
try{
|
|
|
|
if(pNamespace){
|
|
m_pNamespace = pNamespace;
|
|
m_pNamespace->AddRef();
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
CheckForMsiDll();
|
|
|
|
#ifdef _PRIVATE_DEBUG
|
|
|
|
//get the working directory for the log file
|
|
HKEY hkeyLocalMachine;
|
|
LONG lResult;
|
|
|
|
if((lResult = RegConnectRegistryW(NULL, HKEY_LOCAL_MACHINE, &hkeyLocalMachine)) == ERROR_SUCCESS)
|
|
{
|
|
HKEY hkeyHmomCwd;
|
|
|
|
if( (lResult = RegOpenKeyExW ( hkeyLocalMachine,
|
|
L"SOFTWARE\\Microsoft\\WBEM\\CIMOM",
|
|
0,
|
|
KEY_READ | KEY_QUERY_VALUE,
|
|
&hkeyHmomCwd
|
|
)
|
|
) == ERROR_SUCCESS)
|
|
{
|
|
|
|
unsigned long lcbValue = 0L;
|
|
unsigned long lType = 0L;
|
|
|
|
lResult = RegQueryValueExW ( hkeyHmomCwd,
|
|
L"Logging Directory",
|
|
NULL,
|
|
&lType,
|
|
NULL,
|
|
&lcbValue
|
|
);
|
|
|
|
if ( lResult == ERROR_MORE_DATA )
|
|
{
|
|
try
|
|
{
|
|
if ( ( g_wcpLoggingDir = new WCHAR [ lcbValue/sizeof ( WCHAR ) + wcslen ( L"\\msiprov.log" ) + 1 ] ) != NULL )
|
|
{
|
|
lResult = RegQueryValueExW ( hkeyHmomCwd,
|
|
L"Logging Directory",
|
|
NULL,
|
|
&lType,
|
|
g_wcpLoggingDir,
|
|
&lcbValue
|
|
);
|
|
|
|
if ( lResult == ERROR_SUCCESS )
|
|
{
|
|
wcscat(g_wcpLoggingDir, L"\\msiprov.log");
|
|
}
|
|
else
|
|
{
|
|
if ( g_wcpLoggingDir );
|
|
{
|
|
delete [] g_wcpLoggingDir;
|
|
g_wcpLoggingDir = NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw m_he;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( g_wcpLoggingDir );
|
|
{
|
|
delete [] g_wcpLoggingDir;
|
|
g_wcpLoggingDir = NULL;
|
|
}
|
|
|
|
RegCloseKey(hkeyHmomCwd);
|
|
RegCloseKey(hkeyLocalMachine);
|
|
|
|
throw;
|
|
}
|
|
|
|
RegCloseKey(hkeyHmomCwd);
|
|
RegCloseKey(hkeyLocalMachine);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RegCloseKey(hkeyLocalMachine);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
//Register usage information with MSI
|
|
/* WCHAR wcProduct[39];
|
|
WCHAR wcFeature[BUFF_SIZE];
|
|
WCHAR wcParent[BUFF_SIZE];
|
|
int iPass = -1;
|
|
|
|
MsiGetProductCodeW(L"{E705C42D-35ED-11D2-BFB7-00A0C9954921}", wcProduct);
|
|
|
|
while(MsiEnumFeaturesW(wcProduct, ++iPass, wcFeature, wcParent) != ERROR_NO_MORE_ITEMS){
|
|
|
|
if(wcscmp(wcFeature, L"Provider") == 0){
|
|
|
|
MsiUseFeatureW(wcProduct, wcFeature);
|
|
break;
|
|
}
|
|
}
|
|
*/
|
|
|
|
}catch(...){
|
|
|
|
//Let CIMOM know there was problem
|
|
pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
//Let CIMOM know you are initialized
|
|
pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CMSIProv::CreateInstanceEnumAsync
|
|
//
|
|
// Purpose: Asynchronously enumerates the instances.
|
|
//
|
|
//***************************************************************************
|
|
SCODE CMSIProv::CreateInstanceEnumAsync(const BSTR RefStr, long lFlags, IWbemContext *pCtx,
|
|
IWbemObjectSink FAR* pHandler)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CRequestObject *pRObj = NULL;
|
|
|
|
try
|
|
{
|
|
if(CheckForMsiDll())
|
|
{
|
|
// Do a check of arguments and make sure we have pointer to Namespace
|
|
if(RefStr == NULL || pHandler == NULL)
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(SUCCEEDED(hr = CheckImpersonationLevel()))
|
|
{
|
|
g_fpMsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
//Create the RequestObject
|
|
if ( ( pRObj = new CRequestObject() ) == NULL )
|
|
{
|
|
throw m_he;
|
|
}
|
|
|
|
pRObj->Initialize(m_pNamespace);
|
|
|
|
//Get package list
|
|
hr = pRObj->InitializeList(true);
|
|
if SUCCEEDED ( hr )
|
|
{
|
|
if ( hr != WBEM_S_NO_MORE_DATA )
|
|
{
|
|
//Get the requested object(s)
|
|
hr = pRObj->CreateObjectEnum(RefStr, pHandler, pCtx);
|
|
}
|
|
else
|
|
{
|
|
//return empty and success
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
|
|
// Set status
|
|
pHandler->SetStatus(0, hr, NULL, NULL);
|
|
|
|
}
|
|
catch(CHeap_Exception e_HE)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
pHandler->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
catch(HRESULT e_hr)
|
|
{
|
|
hr = e_hr;
|
|
pHandler->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = WBEM_E_CRITICAL_ERROR;
|
|
pHandler->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
|
|
#ifdef _PRIVATE_DEBUG
|
|
if(!HeapValidate(GetProcessHeap(),NULL , NULL)) DebugBreak();
|
|
#endif
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CMSIProv::GetObjectAsync
|
|
//
|
|
// Purpose: Creates an instance given a particular path value.
|
|
//
|
|
//***************************************************************************
|
|
SCODE CMSIProv::GetObjectAsync(const BSTR ObjectPath, long lFlags,IWbemContext *pCtx,
|
|
IWbemObjectSink FAR* pHandler)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CRequestObject *pRObj = NULL;
|
|
|
|
try
|
|
{
|
|
if(CheckForMsiDll())
|
|
{
|
|
// Do a check of arguments and make sure we have pointer to Namespace
|
|
if(ObjectPath == NULL || pHandler == NULL )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(SUCCEEDED(hr = CheckImpersonationLevel()))
|
|
{
|
|
g_fpMsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
//Create the RequestObject
|
|
if ( ( pRObj = new CRequestObject() ) == NULL )
|
|
{
|
|
throw m_he;
|
|
}
|
|
|
|
pRObj->Initialize(m_pNamespace);
|
|
|
|
//Get package list
|
|
hr = pRObj->InitializeList(true);
|
|
if SUCCEEDED ( hr )
|
|
{
|
|
if ( hr != WBEM_S_NO_MORE_DATA )
|
|
{
|
|
//Get the requested object
|
|
hr = pRObj->CreateObject(ObjectPath, pHandler, pCtx);
|
|
}
|
|
else
|
|
{
|
|
//return empty and success
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
|
|
// Set Status
|
|
pHandler->SetStatus(0, hr , NULL, NULL);
|
|
|
|
}
|
|
catch(CHeap_Exception e_HE)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
pHandler->SetStatus(0, hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
catch(HRESULT e_hr)
|
|
{
|
|
hr = e_hr;
|
|
pHandler->SetStatus(0, hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = WBEM_E_CRITICAL_ERROR;
|
|
pHandler->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
|
|
#ifdef _PRIVATE_DEBUG
|
|
if(!HeapValidate(GetProcessHeap(),NULL , NULL)) DebugBreak();
|
|
#endif
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CMSIProv::PutInstanceAsync
|
|
//
|
|
// Purpose: Writes an instance to the WBEM Repsoitory.
|
|
//
|
|
//***************************************************************************
|
|
SCODE CMSIProv::PutInstanceAsync(IWbemClassObject FAR *pInst, long lFlags, IWbemContext *pCtx,
|
|
IWbemObjectSink FAR *pResponseHandler)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CRequestObject *pRObj = NULL;
|
|
|
|
try
|
|
{
|
|
if(CheckForMsiDll())
|
|
{
|
|
// Do a check of arguments and make sure we have pointer to Namespace
|
|
// Do a check of arguments and make sure we have pointer to Namespace
|
|
if(pInst == NULL || pResponseHandler == NULL )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(SUCCEEDED(hr = CheckImpersonationLevel()))
|
|
{
|
|
g_fpMsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
//Create the RequestObject
|
|
if ( ( pRObj = new CRequestObject() ) == NULL )
|
|
{
|
|
throw m_he;
|
|
}
|
|
|
|
pRObj->Initialize(m_pNamespace);
|
|
|
|
//Get package list
|
|
hr = pRObj->InitializeList(true);
|
|
if SUCCEEDED ( hr )
|
|
{
|
|
if ( hr != WBEM_S_NO_MORE_DATA )
|
|
{
|
|
//Put the object
|
|
hr = pRObj->PutObject(pInst, pResponseHandler, pCtx);
|
|
}
|
|
else
|
|
{
|
|
//return empty and success
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_NOT_AVAILABLE;
|
|
}
|
|
|
|
// Set Status
|
|
pResponseHandler->SetStatus(0 ,hr , NULL, NULL);
|
|
}
|
|
catch(CHeap_Exception e_HE)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
pResponseHandler->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
catch(HRESULT e_hr)
|
|
{
|
|
hr = e_hr;
|
|
pResponseHandler->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = WBEM_E_CRITICAL_ERROR;
|
|
pResponseHandler->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
|
|
#ifdef _PRIVATE_DEBUG
|
|
if(!HeapValidate(GetProcessHeap(),NULL , NULL)) DebugBreak();
|
|
#endif
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CMSIProv::ExecMethodAsync
|
|
//
|
|
// Purpose: Executes a method on an MSI class or instance.
|
|
//
|
|
//***************************************************************************
|
|
SCODE CMSIProv::ExecMethodAsync(const BSTR ObjectPath, const BSTR Method, long lFlags,
|
|
IWbemContext *pCtx, IWbemClassObject *pInParams,
|
|
IWbemObjectSink *pResponse)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CRequestObject *pRObj = NULL;
|
|
|
|
try{
|
|
|
|
if(CheckForMsiDll()){
|
|
|
|
// Do a check of arguments and make sure we have pointer to Namespace
|
|
if(ObjectPath == NULL || Method == NULL || pResponse == NULL )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(SUCCEEDED(hr = CheckImpersonationLevel())){
|
|
|
|
g_fpMsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
//Create the RequestObject
|
|
pRObj = new CRequestObject();
|
|
if(!pRObj) throw m_he;
|
|
|
|
pRObj->Initialize(m_pNamespace);
|
|
|
|
//Don't get package list
|
|
if(SUCCEEDED(hr = pRObj->InitializeList(false))){
|
|
|
|
//Execute the method
|
|
hr = pRObj->ExecMethod(ObjectPath, Method, pInParams, pResponse, pCtx);
|
|
}
|
|
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
|
|
}else{
|
|
|
|
hr = WBEM_E_NOT_AVAILABLE;
|
|
}
|
|
|
|
// Set Status
|
|
pResponse->SetStatus(WBEM_STATUS_COMPLETE ,hr , NULL, NULL);
|
|
|
|
}catch(CHeap_Exception e_HE){
|
|
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
pResponse->SetStatus(WBEM_STATUS_COMPLETE , hr, NULL, NULL);
|
|
|
|
if(pRObj){
|
|
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
|
|
}catch(HRESULT e_hr){
|
|
hr = e_hr;
|
|
|
|
pResponse->SetStatus(WBEM_STATUS_COMPLETE , hr, NULL, NULL);
|
|
|
|
if(pRObj){
|
|
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
|
|
}catch(...){
|
|
|
|
hr = WBEM_E_CRITICAL_ERROR;
|
|
|
|
pResponse->SetStatus(WBEM_STATUS_COMPLETE , hr, NULL, NULL);
|
|
|
|
if(pRObj){
|
|
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
|
|
#ifdef _PRIVATE_DEBUG
|
|
if(!HeapValidate(GetProcessHeap(),NULL , NULL)) DebugBreak();
|
|
#endif
|
|
|
|
return hr;
|
|
}
|
|
|
|
SCODE CMSIProv::DeleteInstanceAsync(const BSTR ObjectPath, long lFlags, IWbemContext *pCtx,
|
|
IWbemObjectSink *pResponse)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CRequestObject *pRObj = NULL;
|
|
|
|
try{
|
|
if(CheckForMsiDll()){
|
|
|
|
// Do a check of arguments and make sure we have pointer to Namespace
|
|
if(ObjectPath == NULL || pResponse == NULL )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(SUCCEEDED(hr = CheckImpersonationLevel())){
|
|
|
|
g_fpMsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
//Create the RequestObject
|
|
pRObj = new CRequestObject();
|
|
if(!pRObj) throw m_he;
|
|
|
|
pRObj->Initialize(m_pNamespace);
|
|
|
|
//Don't get package list
|
|
if(SUCCEEDED(hr = pRObj->InitializeList(false))){
|
|
|
|
//Delete the requested object
|
|
hr = pRObj->DeleteObject(ObjectPath, pResponse, pCtx);
|
|
}
|
|
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
|
|
}else{
|
|
|
|
hr = WBEM_E_NOT_AVAILABLE;
|
|
}
|
|
|
|
// Set Status
|
|
pResponse->SetStatus(0 ,hr , NULL, NULL);
|
|
|
|
}catch(CHeap_Exception e_HE){
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
pResponse->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj){
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
|
|
}catch(HRESULT e_hr){
|
|
hr = e_hr;
|
|
|
|
pResponse->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj){
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
|
|
}catch(...){
|
|
hr = WBEM_E_CRITICAL_ERROR;
|
|
|
|
pResponse->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj){
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
|
|
#ifdef _PRIVATE_DEBUG
|
|
if(!HeapValidate(GetProcessHeap(),NULL , NULL)) DebugBreak();
|
|
#endif
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CMSIProv::ExecQueryAsync(const BSTR QueryLanguage, const BSTR Query, long lFlags,
|
|
IWbemContext __RPC_FAR *pCtx, IWbemObjectSink __RPC_FAR *pResponseHandler)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
#ifdef _EXEC_QUERY_SUPPORT
|
|
CRequestObject *pRObj = NULL;
|
|
CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
|
|
|
|
try
|
|
{
|
|
if(CheckForMsiDll())
|
|
{
|
|
// Do a check of arguments and make sure we have pointer to Namespace
|
|
if(0 != _wcsicmp(QueryLanguage, L"WQL") || Query == NULL || pResponseHandler == NULL )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(SUCCEEDED(hr = CheckImpersonationLevel()))
|
|
{
|
|
g_fpMsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
|
|
|
|
//Create the RequestObject
|
|
if ( ( pRObj = new CRequestObject() ) == NULL )
|
|
{
|
|
throw he;
|
|
}
|
|
|
|
pRObj->Initialize(m_pNamespace);
|
|
|
|
//Get package list
|
|
hr = pRObj->InitializeList(true);
|
|
if SUCCEEDED ( hr )
|
|
{
|
|
if ( hr != WBEM_S_NO_MORE_DATA )
|
|
{
|
|
//Get the requested object(s)
|
|
hr = pRObj->ExecQuery(Query, pResponseHandler, pCtx);
|
|
}
|
|
else
|
|
{
|
|
//return empty and success
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
|
|
// Set Status
|
|
pResponseHandler->SetStatus(0 ,hr , NULL, NULL);
|
|
|
|
}
|
|
catch(CHeap_Exception e_HE)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
pResponseHandler->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
catch(HRESULT e_hr)
|
|
{
|
|
hr = e_hr;
|
|
pResponseHandler->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = WBEM_E_CRITICAL_ERROR;
|
|
pResponseHandler->SetStatus(0 , hr, NULL, NULL);
|
|
|
|
if(pRObj)
|
|
{
|
|
pRObj->Cleanup();
|
|
delete pRObj;
|
|
}
|
|
}
|
|
|
|
#else //_EXEC_QUERY_SUPPORT
|
|
hr = WBEM_E_NOT_SUPPORTED;
|
|
#endif
|
|
|
|
#ifdef _PRIVATE_DEBUG
|
|
if(!HeapValidate(GetProcessHeap(),NULL , NULL)) DebugBreak();
|
|
#endif //_PRIVATE_DEBUG
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//Ensure msi.dll and functions are loaded if present on system
|
|
bool CMSIProv::CheckForMsiDll()
|
|
{
|
|
EnterCriticalSection(&g_msi_prov_cs);
|
|
|
|
if(!g_bMsiLoaded){
|
|
|
|
HINSTANCE hiMsiDll = LoadLibraryW(L"msi.dll");
|
|
|
|
if(!hiMsiDll){
|
|
|
|
hiMsiDll = LoadLibrary(_T("msi.dll"));
|
|
|
|
if(!hiMsiDll){
|
|
|
|
TCHAR cBuf[MAX_PATH + 1];
|
|
|
|
if (0 != GetSystemDirectory(cBuf, MAX_PATH/*Number of TCHARs*/)){
|
|
|
|
_tcscat(cBuf, _T("\\msi.dll"));
|
|
hiMsiDll = LoadLibrary(cBuf);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(hiMsiDll){
|
|
|
|
//Load the function pointers
|
|
g_fpMsiViewFetch = (LPFNMSIVIEWFETCH)GetProcAddress(hiMsiDll, "MsiViewFetch");
|
|
g_fpMsiRecordGetStringW = (LPFNMSIRECORDGETSTRINGW)GetProcAddress(hiMsiDll, "MsiRecordGetStringW");
|
|
g_fpMsiCloseHandle = (LPFNMSICLOSEHANDLE)GetProcAddress(hiMsiDll, "MsiCloseHandle");
|
|
g_fpMsiDatabaseOpenViewW = (LPFNMSIDATABASEOPENVIEWW)GetProcAddress(hiMsiDll, "MsiDatabaseOpenViewW");
|
|
g_fpMsiViewExecute = (LPFNMSIVIEWEXECUTE)GetProcAddress(hiMsiDll, "MsiViewExecute");
|
|
g_fpMsiGetActiveDatabase = (LPFNMSIGETACTIVEDATABASE)GetProcAddress(hiMsiDll, "MsiGetActiveDatabase");
|
|
g_fpMsiGetComponentPathW = (LPFNMSIGETCOMPONENTPATHW)GetProcAddress(hiMsiDll, "MsiGetComponentPathW");
|
|
g_fpMsiGetComponentStateW = (LPFNMSIGETCOMPONENTSTATEW)GetProcAddress(hiMsiDll, "MsiGetComponentStateW");
|
|
g_fpMsiOpenProductW = (LPFNMSIOPENPRODUCTW)GetProcAddress(hiMsiDll, "MsiOpenProductW");
|
|
g_fpMsiOpenPackageW = (LPFNMSIOPENPACKAGEW)GetProcAddress(hiMsiDll, "MsiOpenPackageW");
|
|
g_fpMsiDatabaseIsTablePersistentW = (LPFNMSIDATABASEISTABLEPERSITENTW)GetProcAddress(hiMsiDll, "MsiDatabaseIsTablePersistentW");
|
|
g_fpMsiSetInternalUI = (LPFNMSISETINTERNALUI)GetProcAddress(hiMsiDll, "MsiSetInternalUI");
|
|
g_fpMsiSetExternalUIW = (LPFNMSISETEXTERNALUIW)GetProcAddress(hiMsiDll, "MsiSetExternalUIW");
|
|
g_fpMsiEnableLogW = (LPFNMSIENABLELOGW)GetProcAddress(hiMsiDll, "MsiEnableLogW");
|
|
g_fpMsiGetProductPropertyW = (LPFNMSIGETPRODUCTPROPERTYW)GetProcAddress(hiMsiDll, "MsiGetProductPropertyW");
|
|
g_fpMsiQueryProductStateW = (LPFNMSIQUERYPRODUCTSTATEW)GetProcAddress(hiMsiDll, "MsiQueryProductStateW");
|
|
g_fpMsiInstallProductW = (LPFNMSIINSTALLPRODUCTW)GetProcAddress(hiMsiDll, "MsiInstallProductW");
|
|
g_fpMsiConfigureProductW = (LPFNMSICONFIGUREPRODUCTW)GetProcAddress(hiMsiDll, "MsiConfigureProductW");
|
|
g_fpMsiReinstallProductW = (LPFNMSIREINSTALLPRODUCTW)GetProcAddress(hiMsiDll, "MsiReinstallProductW");
|
|
g_fpMsiApplyPatchW = (LPFNMSIAPPLYPATCHW)GetProcAddress(hiMsiDll, "MsiApplyPatchW");
|
|
g_fpMsiRecordGetInteger = (LPFNMSIRECORDGETINTEGER)GetProcAddress(hiMsiDll, "MsiRecordGetInteger");
|
|
g_fpMsiEnumFeaturesW = (LPFNMSIENUMFEATURESW)GetProcAddress(hiMsiDll, "MsiEnumFeaturesW");
|
|
g_fpMsiGetProductInfoW = (LPFNMSIGETPRODUCTINFOW)GetProcAddress(hiMsiDll, "MsiGetProductInfoW");
|
|
g_fpMsiQueryFeatureStateW = (LPFNMSIQUERYFEATURESTATEW)GetProcAddress(hiMsiDll, "MsiQueryFeatureStateW");
|
|
g_fpMsiGetFeatureUsageW = (LPFNMSIGETFEATUREUSAGEW)GetProcAddress(hiMsiDll, "MsiGetFeatureUsageW");
|
|
g_fpMsiGetFeatureInfoW = (LPFNMSIGETFEATUREINFOW)GetProcAddress(hiMsiDll, "MsiGetFeatureInfoW");
|
|
g_fpMsiConfigureFeatureW = (LPFNMSICONFIGUREFEATUREW)GetProcAddress(hiMsiDll, "MsiConfigureFeatureW");
|
|
g_fpMsiReinstallFeatureW = (LPFNMSIREINSTALLFEATUREW)GetProcAddress(hiMsiDll, "MsiReinstallFeatureW");
|
|
g_fpMsiEnumProductsW = (LPFNMSIENUMPRODUCTSW)GetProcAddress(hiMsiDll, "MsiEnumProductsW");
|
|
g_fpMsiGetDatabaseState = (LPFNMSIGETDATABASESTATE)GetProcAddress(hiMsiDll, "MsiGetDatabaseState");
|
|
g_fpMsiRecordSetStringW = (LPFNMSIRECORDSETSTRINGW)GetProcAddress(hiMsiDll, "MsiRecordSetStringW");
|
|
g_fpMsiDatabaseCommit = (LPFNMSIDATABASECOMMIT)GetProcAddress(hiMsiDll, "MsiDatabaseCommit");
|
|
g_fpMsiEnumComponentsW = (LPFNMSIENUMCOMPONENTSW)GetProcAddress(hiMsiDll, "MsiEnumComponentsW");
|
|
g_fpMsiViewClose = (LPFNMSIVIEWCLOSE)GetProcAddress(hiMsiDll, "MsiViewClose");
|
|
|
|
// Did we get all the pointers we need?
|
|
if(g_fpMsiViewFetch && g_fpMsiRecordGetStringW && g_fpMsiCloseHandle &&
|
|
g_fpMsiDatabaseOpenViewW && g_fpMsiViewExecute && g_fpMsiGetActiveDatabase &&
|
|
g_fpMsiGetComponentPathW && g_fpMsiGetComponentStateW && g_fpMsiOpenProductW &&
|
|
g_fpMsiOpenPackageW && g_fpMsiDatabaseIsTablePersistentW && g_fpMsiSetInternalUI &&
|
|
g_fpMsiSetExternalUIW && g_fpMsiEnableLogW && g_fpMsiGetProductPropertyW &&
|
|
g_fpMsiQueryProductStateW && g_fpMsiInstallProductW && g_fpMsiConfigureProductW &&
|
|
g_fpMsiReinstallProductW && g_fpMsiApplyPatchW && g_fpMsiRecordGetInteger &&
|
|
g_fpMsiEnumFeaturesW && g_fpMsiGetProductInfoW && g_fpMsiQueryFeatureStateW &&
|
|
g_fpMsiGetFeatureUsageW && g_fpMsiGetFeatureInfoW && g_fpMsiConfigureFeatureW &&
|
|
g_fpMsiReinstallFeatureW && g_fpMsiEnumProductsW && g_fpMsiGetDatabaseState &&
|
|
g_fpMsiRecordSetStringW && g_fpMsiDatabaseCommit && g_fpMsiEnumComponentsW &&
|
|
g_fpMsiViewClose){
|
|
|
|
g_bMsiLoaded = true;
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
g_bMsiPresent = false;
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&g_msi_prov_cs);
|
|
|
|
return g_bMsiLoaded;
|
|
}
|
|
|
|
bool UnloadMsiDll()
|
|
{
|
|
bool bRetVal = true;
|
|
|
|
EnterCriticalSection(&g_msi_prov_cs);
|
|
|
|
if(g_bMsiLoaded){
|
|
|
|
if(FreeLibrary(GetModuleHandle(L"msi.dll"))){
|
|
|
|
g_bMsiLoaded = false;
|
|
bRetVal = true;
|
|
|
|
}else bRetVal = false;
|
|
|
|
}
|
|
|
|
LeaveCriticalSection(&g_msi_prov_cs);
|
|
|
|
return bRetVal;
|
|
}
|