|
|
// Utils.cpp: implementation of the CGenericClass class.
//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
//////////////////////////////////////////////////////////////////////
#include "precomp.h"
char * WcharToTchar(WCHAR * wcPtr, char * tcTmp) { WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, wcPtr, (-1), tcTmp, BUFF_SIZE, NULL, NULL); return tcTmp; }
WCHAR * TcharToWchar(char * tcPtr, WCHAR * wcTmp) { MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, tcPtr, (-1), wcTmp, BUFF_SIZE); return wcTmp; }
WCHAR * TcharToWchar(const char * tcPtr, WCHAR * wcTmp) { MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, tcPtr, (-1), wcTmp, BUFF_SIZE); return wcTmp; }
HRESULT ConvertError(UINT uiStatus) { switch(uiStatus){
case ERROR_INSTALL_ALREADY_RUNNING: return WBEM_E_ACCESS_DENIED;
case ERROR_ACCESS_DENIED: return WBEM_E_PRIVILEGE_NOT_HELD;
case E_OUTOFMEMORY: throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); return WBEM_E_OUT_OF_MEMORY;
default: return WBEM_E_FAILED; } }
WCHAR * EscapeStringW(WCHAR * wcIn, WCHAR * wcOut) { wcOut [ 0 ] = 0;
DWORD dwLenghtIn = 0L; dwLenghtIn = lstrlenW ( wcIn );
WCHAR wcTmp[BUFF_SIZE] = { L'\0' }; wcscpy(wcTmp, wcIn); WCHAR * wcp = wcTmp;
DWORD dwNumber = 0L;
while ( *wcp ) { if ( *wcp == L'\\' || *wcp == L'\"' ) { dwNumber++; }
wcp++; }
if ( BUFF_SIZE > ( dwLenghtIn + dwNumber * 2 ) ) { wcp = wcTmp;
while ( *wcp ) { switch ( *wcp ) { case L'\\': *wcp = NULL; wcscpy(wcOut, wcTmp); wcscat(wcOut, L"\\\\"); wcscat(wcOut, (wcp + 1)); wcscpy(wcTmp, wcOut); wcp++; break;
case L'\"': *wcp = NULL; wcscpy(wcOut, wcTmp); wcscat(wcOut, L"\\\""); wcscat(wcOut, (wcp + 1)); wcscpy(wcTmp, wcOut); wcp++; break;
default: break; }
wcp++; } }
return wcOut; }
void SoftwareElementState(INSTALLSTATE piInstalled, int *iState) { switch(piInstalled){
case INSTALLSTATE_ABSENT: *iState = 0; break; case INSTALLSTATE_BADCONFIG: *iState = 0; break; case INSTALLSTATE_INVALIDARG: *iState = 0; break; case INSTALLSTATE_LOCAL: *iState = 2; break; case INSTALLSTATE_SOURCE: *iState = 1; break; case INSTALLSTATE_SOURCEABSENT: *iState = 0; break; case INSTALLSTATE_UNKNOWN: *iState = 0; break; default: *iState = 0; } }
// string am getting is BUF_SIZE ( statically allocated )
bool CreateProductString(WCHAR *wcProductCode, WCHAR *wcProductPath) { DWORD dwBufSize; WCHAR wcBuf[BUFF_SIZE]; #if !defined(_UNICODE)
WCHAR wcTmp[BUFF_SIZE]; #endif
bool bResult = false;
// safe operation
wcscpy(wcProductPath, L"Win32_Product.IdentifyingNumber=\"");
if ( wcslen ( wcProductPath ) + wcslen ( L"\",Name=\"" )
< BUFF_SIZE ) { wcscat(wcProductPath, wcProductCode); wcscat(wcProductPath, L"\",Name=\"");
dwBufSize = BUFF_SIZE; #if defined(_UNICODE)
if(g_fpMsiGetProductInfoW(wcProductCode, INSTALLPROPERTY_PRODUCTNAME, #else
if(g_fpMsiGetProductInfoW(wcProductCode, TcharToWchar(INSTALLPROPERTY_PRODUCTNAME, wcTmp), #endif
wcBuf, &dwBufSize) == ERROR_SUCCESS) {
if ( wcslen (wcProductPath) + wcslen (wcBuf) + wcslen (L"\",Version=\"")
< BUFF_SIZE ) { wcscat(wcProductPath, wcBuf); wcscat(wcProductPath, L"\",Version=\"");
dwBufSize = BUFF_SIZE; #if defined(_UNICODE)
if(g_fpMsiGetProductInfoW(wcProductCode, INSTALLPROPERTY_VERSIONSTRING, #else
if(g_fpMsiGetProductInfoW(wcProductCode, TcharToWchar(INSTALLPROPERTY_VERSIONSTRING, wcTmp), #endif
wcBuf, &dwBufSize) == ERROR_SUCCESS) { if ( wcslen (wcProductPath) + wcslen (wcBuf) + 1
< BUFF_SIZE ) { wcscat(wcProductPath, wcBuf); wcscat(wcProductPath, L"\""); bResult = true; } } else { dwBufSize = BUFF_SIZE; if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode, #if defined(_UNICODE)
INSTALLPROPERTY_VERSION, wcBuf, &dwBufSize)) {
#else
TcharToWchar(INSTALLPROPERTY_VERSION, wcTmp), wcBuf, &dwBufSize)) { #endif
if ( wcslen (wcProductPath) + wcslen (wcBuf) + 1
< BUFF_SIZE ) { wcscat(wcProductPath, wcBuf); wcscat(wcProductPath, L"\""); bResult = true; } } } } } }
return bResult; }
DWORD CreateSoftwareElementString ( MSIHANDLE hDatabase, WCHAR *wcComponent, WCHAR *wcProductCode, WCHAR *wcPath, DWORD * dwPath ) { DWORD dwResult = static_cast < DWORD > ( E_INVALIDARG ); DWORD dwResultHelp = static_cast < DWORD > ( S_FALSE );
#if !defined(_UNICODE)
WCHAR wcTmp[BUFF_SIZE]; #endif
if ( wcComponent != NULL && wcComponent [ 0 ] != 0 ) { MSIHANDLE hView = NULL; MSIHANDLE hRecord = NULL;
DWORD dwBufSize = BUFF_SIZE;
LPWSTR wcBuf = NULL; LPWSTR wcID = NULL; LPWSTR wcQuery = NULL;
int iState = 0L;
DWORD dwPathSize = 0; dwPathSize = * dwPath;
DWORD dwUsed = 1; // last null
try { if ( ( wcBuf = new WCHAR [ dwBufSize ] ) == NULL ) { throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); } if ( ( wcID = new WCHAR [ dwBufSize ] ) == NULL ) { throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); }
LPCWSTR wszQuery = L"select distinct `ComponentId` from Component where `Component`=\'";
DWORD dwQuery = 0L; dwQuery = lstrlenW ( wszQuery ) + lstrlenW ( wcComponent ) + 1 + 1;
if ( ( wcQuery = new WCHAR [ dwQuery ] ) == NULL ) { throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); }
wcscpy ( wcQuery, wszQuery ); wcscat ( wcQuery, wcComponent ); wcscat ( wcQuery, L"\'" );
if ( ( dwResult = g_fpMsiDatabaseOpenViewW ( hDatabase, wcQuery, &hView ) ) == ERROR_SUCCESS ) { if ( g_fpMsiViewExecute ( hView, 0 ) == ERROR_SUCCESS ) { if ( g_fpMsiViewFetch ( hView, &hRecord ) != ERROR_NO_MORE_ITEMS ) { dwBufSize = BUFF_SIZE;
BOOL bContinue = TRUE; DWORD dwContinue= 2; do { if ( ( dwResult = g_fpMsiRecordGetStringW ( hRecord, 1, wcID, &dwBufSize ) ) == ERROR_MORE_DATA ) { delete [] wcID; wcID = NULL;
if ( ( wcID = new WCHAR [ dwBufSize ] ) == NULL ) { throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); } } else { bContinue = FALSE; } } while ( bContinue && dwContinue-- );
if ( dwResult == ERROR_MORE_DATA ) { dwResult = static_cast < DWORD > ( E_FAIL ); }
if ( dwResult == ERROR_SUCCESS && wcProductCode != NULL && wcProductCode [ 0 ] != 0 ) { //Check to make sure it's on the system
if ( ValidateComponentID ( wcID, wcProductCode ) ) { dwUsed = dwUsed + lstrlenW ( L"Win32_SoftwareElement.Name=\"" ) + lstrlenW ( wcComponent ) + lstrlenW ( L"\",SoftwareElementID=\"" ) + lstrlenW ( wcID ) + lstrlenW ( L"\",SoftwareElementState=" );
if ( dwUsed > dwPathSize ) { dwResultHelp = ERROR_MORE_DATA; } else { wcscpy(wcPath, L"Win32_SoftwareElement.Name=\""); wcscat(wcPath, wcComponent); wcscat(wcPath, L"\",SoftwareElementID=\""); wcscat(wcPath, wcID); wcscat(wcPath, L"\",SoftwareElementState="); }
SoftwareElementState ( g_fpMsiGetComponentPathW ( wcProductCode, wcID, NULL, NULL ), &iState );
_itow(iState, wcBuf, 10);
dwUsed = dwUsed + lstrlenW ( wcBuf ) + lstrlenW ( L"\",SoftwareElementState=\"" );
if ( dwUsed > dwPathSize ) { dwResultHelp = ERROR_MORE_DATA; } else { wcscat(wcPath, wcBuf); wcscat(wcPath, L",TargetOperatingSystem="); }
_itow(GetOS(), wcBuf, 10);
dwUsed = dwUsed + lstrlenW ( wcBuf ) + lstrlenW ( L"\",SoftwareElementState=\"" );
if ( dwUsed > dwPathSize ) { dwResultHelp = ERROR_MORE_DATA; } else { wcscat(wcPath, wcBuf); wcscat(wcPath, L",Version=\""); }
dwBufSize = BUFF_SIZE; wcBuf [0] = 0;
bContinue = TRUE; dwContinue = 2;
do { if ( ( dwResult = g_fpMsiGetProductInfoW ( wcProductCode, #ifdef _UNICODE
INSTALLPROPERTY_VERSIONSTRING, #else _UNICODE
TcharToWchar(INSTALLPROPERTY_VERSIONSTRING, wcTmp), #endif _UNICODE
wcBuf, &dwBufSize ) ) == ERROR_MORE_DATA ) { delete [] wcBuf; wcBuf = NULL;
if ( ( wcBuf = new WCHAR [ dwBufSize + 1 ] ) == NULL ) { throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); }
dwBufSize = dwBufSize + 1; } else { bContinue = FALSE; } } while ( bContinue && dwContinue-- );
if ( dwResult == ERROR_MORE_DATA ) { dwResult = static_cast < DWORD > ( E_FAIL ); }
if ( dwResult == ERROR_SUCCESS ) { dwUsed = dwUsed + lstrlenW ( wcBuf ) + lstrlenW ( L"\"" );
if ( dwUsed > dwPathSize ) { dwResultHelp = ERROR_MORE_DATA; } else { wcscat(wcPath, wcBuf); wcscat(wcPath, L"\"");
dwResult = ERROR_SUCCESS; } } } else { dwResult = static_cast < DWORD > ( E_FAIL ); } } } } } else { if ( dwResult == E_OUTOFMEMORY ) { throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); } } } catch ( ... ) { if ( wcBuf ) { delete [] wcBuf; wcBuf = NULL; }
if ( wcID ) { delete [] wcID; wcID = NULL; }
if ( wcQuery ) { delete [] wcQuery; wcQuery = NULL; }
throw; }
if ( wcBuf ) { delete [] wcBuf; wcBuf = NULL; }
if ( wcID ) { delete [] wcID; wcID = NULL; }
if ( wcQuery ) { delete [] wcQuery; wcQuery = NULL; }
g_fpMsiCloseHandle(hRecord);
g_fpMsiViewClose(hView); g_fpMsiCloseHandle(hView);
if ( dwResult == ERROR_SUCCESS && dwResultHelp == ERROR_MORE_DATA ) { ( * dwPath ) = ( * dwPath ) + ( dwUsed - dwPathSize ); wcPath [ 0 ] = 0;
dwResult = dwResultHelp; } }
return dwResult; }
// string am getting is BUF_SIZE ( statically allocated )
bool CreateSoftwareFeatureString(WCHAR *wcName, WCHAR *wcProductCode, WCHAR * wcString, bool bValidate) { bool bResult = false; DWORD dwBufSize; WCHAR wcBuf[BUFF_SIZE]; #if !defined(_UNICODE)
WCHAR wcTmp[BUFF_SIZE]; #endif
if((bValidate) && (!ValidateFeatureName(wcName, wcProductCode))) return bResult;
// safe operation
wcscpy(wcString, L"Win32_SoftwareFeature.IdentifyingNumber=\"");
if ( wcslen ( wcString ) + wcslen ( L"\",Name=\"" ) + wcslen ( wcName ) + wcslen ( L"\",ProductName=\"" )
< BUFF_SIZE ) { wcscat(wcString, wcProductCode); wcscat(wcString, L"\",Name=\""); wcscat(wcString, wcName); wcscat(wcString, L"\",ProductName=\"");
dwBufSize = BUFF_SIZE; if(g_fpMsiGetProductInfoW(wcProductCode, #if defined(_UNICODE)
INSTALLPROPERTY_PRODUCTNAME, #else
TcharToWchar(INSTALLPROPERTY_PRODUCTNAME, wcTmp), #endif
wcBuf, &dwBufSize) == ERROR_SUCCESS) { if ( wcslen (wcString) + wcslen (wcBuf) + wcslen (L"\",Version=\"")
< BUFF_SIZE ) { wcscat(wcString, wcBuf); wcscat(wcString, L"\",Version=\"");
dwBufSize = BUFF_SIZE; if(g_fpMsiGetProductInfoW(wcProductCode, #if defined(_UNICODE)
INSTALLPROPERTY_VERSIONSTRING, #else
TcharToWchar(INSTALLPROPERTY_VERSIONSTRING, wcTmp), #endif
wcBuf, &dwBufSize) == ERROR_SUCCESS) { if ( wcslen (wcString) + wcslen (wcBuf) + 1
< BUFF_SIZE ) { wcscat(wcString, wcBuf); wcscat(wcString, L"\""); bResult = true; } } else { dwBufSize = BUFF_SIZE; if(ERROR_SUCCESS == g_fpMsiGetProductInfoW(wcProductCode, #if defined(_UNICODE)
INSTALLPROPERTY_VERSION #else
TcharToWchar(INSTALLPROPERTY_VERSION, wcTmp) #endif
, wcBuf, &dwBufSize)) { if ( wcslen (wcString) + wcslen (wcBuf) + 1
< BUFF_SIZE ) { wcscat(wcString, wcBuf); wcscat(wcString, L"\""); bResult = true; } } } } } }
return bResult; }
// simple helper to ask the age old question
// of what OS are we running on, anyway?
bool AreWeOnNT() { OSVERSIONINFO osversion; osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osversion);
return (osversion.dwPlatformId == VER_PLATFORM_WIN32_NT); }
int GetOS() { OSVERSIONINFO osversion; int iOS = 19; osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osversion);
if(osversion.dwPlatformId == VER_PLATFORM_WIN32s) iOS = 16; else if(osversion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS){
if(osversion.dwMinorVersion == 0) iOS = 17; else iOS = 18; }
return iOS; }
bool IsNT4() { OSVERSIONINFO osversion; int iOS = 19; osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osversion);
return osversion.dwMajorVersion == 4; }
bool IsNT5() { OSVERSIONINFO osversion; int iOS = 19; osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osversion);
return osversion.dwMajorVersion == 5; }
// checks impersonation level
// impersonates client if allowed
HRESULT CheckImpersonationLevel() { HRESULT hr = WBEM_E_ACCESS_DENIED;
if(AreWeOnNT()){
if(SUCCEEDED(CoImpersonateClient())){
// Now, let's check the impersonation level. First, get the thread token
HANDLE hThreadTok; DWORD dwImp, dwBytesReturned;
if(!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hThreadTok )){
DWORD dwLastError = GetLastError();
if (dwLastError == ERROR_NO_TOKEN){
// If the CoImpersonate works, but the OpenThreadToken fails due to ERROR_NO_TOKEN, we
// are running under the process token (either local system, or if we are running
// with /exe, the rights of the logged in user). In either case, impersonation rights
// don't apply. We have the full rights of that user.
hr = WBEM_S_NO_ERROR; }else{ // If we failed to get the thread token for any other reason, an error.
hr = WBEM_E_ACCESS_DENIED; }
}else{
if(GetTokenInformation(hThreadTok, TokenImpersonationLevel, &dwImp, sizeof(DWORD), &dwBytesReturned)){
// Is the impersonation level Impersonate?
if (dwImp >= SecurityImpersonation) hr = WBEM_S_NO_ERROR; else hr = WBEM_E_ACCESS_DENIED;
}else hr = WBEM_E_FAILED;
CloseHandle(hThreadTok); }
if (FAILED(hr)) { CoRevertToSelf(); } }
}else // let win9X in...
hr = WBEM_S_NO_ERROR;
return hr; }
bool ValidateComponentID(WCHAR *wcID, WCHAR *wcProductCode) { int i = 0;
WCHAR * wcBuf = (WCHAR *)malloc(BUFF_SIZE * sizeof(WCHAR)); if(!wcBuf) { throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); }
DWORD dwBufSize; UINT uiStatus; INSTALLSTATE isInstalled; bool bRetVal = false;
dwBufSize = BUFF_SIZE; isInstalled = g_fpMsiGetComponentPathW(wcProductCode, wcID, wcBuf, &dwBufSize);
// this lines are added for backward compatability ( ! INSTALLSTATE_NOTUSED )
if( isInstalled == INSTALLSTATE_LOCAL || isInstalled == INSTALLSTATE_SOURCE || isInstalled == INSTALLSTATE_SOURCEABSENT || isInstalled == INSTALLSTATE_UNKNOWN || isInstalled == INSTALLSTATE_ABSENT ) { bRetVal = true; }
free((void *)wcBuf);
return bRetVal; }
bool ValidateComponentName ( MSIHANDLE hDatabase, WCHAR *wcProductCode, WCHAR *wcName ) { bool bResult = false;
if ( wcName != NULL ) { MSIHANDLE hView = NULL; MSIHANDLE hRecord = NULL;
LPWSTR wcQuery = NULL; LPWSTR wcBuf = NULL;
LPCWSTR wszQuery = L"select distinct `ComponentId` from Component where `Component`=\'";
DWORD dwBuf = BUFF_SIZE; DWORD dwQuery = 0L; dwQuery = wcslen ( wszQuery ) + wcslen ( wcName ) + 1 + 1;
if ( ( wcQuery = new WCHAR [ dwQuery ] ) == NULL ) { throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); }
try { wcscpy ( wcQuery, wszQuery ); wcscat ( wcQuery, wcName ); wcscat ( wcQuery, L"\'" ); } catch ( ... ) { delete [] wcQuery; wcQuery = NULL;
throw; }
try { if ( ( wcBuf = new WCHAR [ dwBuf ] ) == NULL ) { throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); } } catch ( ... ) { delete [] wcQuery; wcQuery = NULL;
throw; }
HRESULT hRes = S_OK;
if ( ERROR_SUCCESS == ( hRes = g_fpMsiDatabaseOpenViewW ( hDatabase, wcQuery, &hView ) ) ) { if ( ERROR_SUCCESS == g_fpMsiViewExecute ( hView, 0 ) ) { if ( ERROR_NO_MORE_ITEMS != ( hRes = g_fpMsiViewFetch ( hView, &hRecord ) ) ) { if ( E_OUTOFMEMORY == hRes ) { g_fpMsiCloseHandle(hRecord);
g_fpMsiViewClose(hView); g_fpMsiCloseHandle(hView);
delete [] wcBuf; delete [] wcQuery;
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); }
if ( ERROR_SUCCESS == g_fpMsiRecordGetStringW ( hRecord, 1, wcBuf, &dwBuf ) ) { //Check to make sure it's on the system
bResult = ValidateComponentID ( wcBuf, wcProductCode ); }
g_fpMsiCloseHandle(hRecord); } }
g_fpMsiViewClose(hView); g_fpMsiCloseHandle(hView);
} else { if ( E_OUTOFMEMORY == hRes ) { delete [] wcBuf; delete [] wcQuery;
throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); } }
delete [] wcBuf; delete [] wcQuery; }
return bResult; }
bool ValidateFeatureName(WCHAR *wcName, WCHAR *wcProduct) { int i = 0; bool bRetVal = false; WCHAR * wcBuf = (WCHAR *)malloc(BUFF_SIZE * sizeof(WCHAR)); if(!wcBuf) { wcBuf = NULL; throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); }
WCHAR * wcParent = (WCHAR *)malloc(BUFF_SIZE * sizeof(WCHAR)); if(!wcParent) { free ( wcBuf ); throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR); }
UINT uiStatus;
while((uiStatus = g_fpMsiEnumFeaturesW(wcProduct, i++, wcBuf, wcParent)) != ERROR_NO_MORE_ITEMS){
if(uiStatus != S_OK){ bRetVal = false; break; }
if(wcscmp(wcName, wcBuf) == 0){ bRetVal = true; break; } }
free((void *)wcBuf); free((void *)wcParent);
return bRetVal; }
bool SafeLeaveCriticalSection(CRITICAL_SECTION *pcs) { void * vpOwner = pcs->OwningThread; DWORD dwOwner = PtrToUlong(vpOwner);
if((pcs->LockCount > -1) && (dwOwner == GetCurrentThreadId())) LeaveCriticalSection(pcs);
return true; }
|