|
|
/*++
Copyright (C) 1998-2001 Microsoft Corporation
Module Name:
REGMETHODS.CPP
Abstract:
Purpose: Implements the registry provider methods.
History:
--*/
#include "precomp.h"
#include "perfprov.h"
#include "cvariant.h"
#include "provreg.h"
#include "reg.h"
#include "genutils.h"
#include <cominit.h>
#include <arrtempl.h>
#include <userenv.h>
#include <lmcons.h>
enum StringType{SIMPLE, EXPANDED};
AutoProfile::AutoProfile() : m_bLoaded(FALSE), m_hToken(NULL), m_hRoot(NULL) { } AutoProfile::~AutoProfile() { if(m_bLoaded) { UnloadUserProfile(m_hToken, m_hRoot); } if(m_hToken != NULL) CloseHandle(m_hToken); }
HRESULT AutoProfile::LoadProfile(HKEY & hRoot) { PROFILEINFO pi; HRESULT hr; // If the profile is already loaded, there is no need to do it
DWORD dwFlags, dwLastError; if(GetProfileType(&dwFlags)) { hRoot = HKEY_CURRENT_USER; return S_OK; } memset((void *)&pi, 0, sizeof(pi)); pi.dwSize = sizeof(pi);
BOOL bRes; bRes = OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &m_hToken); if(!bRes) return WBEM_E_FAILED; TCHAR cUsername[UNLEN + 1]; cUsername[0] = 0; DWORD dwSize = UNLEN + 1; BOOL bRet = GetUserName(cUsername, &dwSize); if(!bRet) return WBEM_E_FAILED; pi.lpUserName = cUsername; pi.dwFlags = 1; CoRevertToSelf(); bRet = LoadUserProfile(m_hToken, &pi); if(bRet == 0) { hRoot = NULL; dwLastError = GetLastError(); HRESULT hr2 = CoImpersonateClient(); if(FAILED(hr2)) ERRORTRACE((LOG_STDPROV, "Registry event provider unable " "to CoImpersonateClient hr2= 0x%x.\n", hr2)); if(dwLastError == ERROR_ACCESS_DENIED ||dwLastError == ERROR_PRIVILEGE_NOT_HELD) hr = WBEM_E_ACCESS_DENIED; else hr = WBEM_E_FAILED; } else { hr = CoImpersonateClient(); m_bLoaded = TRUE; m_hRoot = (HKEY)pi.hProfile; hRoot = (HKEY)pi.hProfile; } return hr; } void CopyOrConvert(TCHAR * pTo, WCHAR * pFrom, int iLen) { #ifdef UNICODE
wcsncpy(pTo, pFrom,iLen); #else
wcstombs(pTo, pFrom, iLen); #endif
pTo[iLen-1] = 0; return; } BSTR GetBSTR(TCHAR * pIn) { #ifdef UNICODE
return SysAllocString(pIn); #else
int iBuffLen = lstrlen(pIn)+1; WCHAR * pTemp = new WCHAR[iBuffLen]; if(pTemp == NULL) return NULL; mbstowcs(pTemp, pIn, iBuffLen); BSTR bRet = SysAllocString(pTemp); delete []pTemp; return bRet; #endif
}
BOOL IsTypeMismatch(Registry & reg, TCHAR * pValueName, DWORD dwExpectedType) { DWORD dwType; long lRet = reg.GetType(pValueName, &dwType); if(lRet == ERROR_SUCCESS && dwExpectedType != dwType) return TRUE; else return FALSE; }
//***************************************************************************
//
// HRESULT SetStatusAndReturnOK;
//
// Purpose: Sets the status code in the sink.
//
//***************************************************************************
HRESULT SetStatusAndReturnOK(SCODE sc, IWbemObjectSink* pSink) { pSink->SetStatus(0,sc, NULL, NULL); return S_OK; }
//***************************************************************************
//
// SAFEARRAY FAR* MySafeArrayCreate
//
// Purpose: Creates a safearray.
//
// Return: pointer to safearray, NULL if error.
//
//***************************************************************************
SAFEARRAY FAR* MySafeArrayCreate(long lNumElement, VARTYPE vt) {
SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; rgsabound[0].cElements = lNumElement; return SafeArrayCreate( vt, 1 , rgsabound ); }
//***************************************************************************
//
// bool GetInArgString
//
// Purpose: Reads a string argument from the input object and puts it into
// a value allocated by the caller.
//
// Return: true if OK.
//
//***************************************************************************
TCHAR * GetInArgString(IWbemClassObject* pInParams, WCHAR * pwcName) { TCHAR * pOut = NULL; if(pInParams == NULL || pwcName == NULL) return NULL; VARIANT var; VariantInit(&var); SCODE sc = pInParams->Get(pwcName, 0, &var, NULL, NULL); if(sc == S_OK && var.vt == VT_BSTR) { DWORD dwLen = wcslen(var.bstrVal) + 1; pOut = new TCHAR[dwLen]; if(pOut) StringCchCopyW(pOut, dwLen, var.bstrVal); } VariantClear(&var); return pOut; }
//***************************************************************************
//
// SCODE EnumKey
//
// Purpose: Enumerate the subkeys and loads them into the output arguments.
//
// Return: error code or 0 if OK.
//
//***************************************************************************
SCODE EnumKey(HKEY hRoot, TCHAR * cSubKey, IWbemClassObject* pOutParams) { SCODE sc; DWORD dwNumSubKeys, dwMaxSubKeyLen, dwNumValues, dwMaxValueNameLen; TCHAR * pcTemp = NULL; // Open the key
HKEY hKey; long lRet = RegOpenKeyEx(hRoot, cSubKey, 0, KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE , &hKey); if(lRet != ERROR_SUCCESS) return lRet; CRegCloseMe cm(hKey); // Count the number of keys and the max size
lRet = RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwNumSubKeys, // number of subkeys
&dwMaxSubKeyLen, // longest subkey name
NULL, &dwNumValues, // number of value entries
&dwMaxValueNameLen, // longest value name
NULL, NULL, NULL);
if(lRet != ERROR_SUCCESS || dwMaxSubKeyLen == 0) return lRet;
pcTemp = new TCHAR[dwMaxSubKeyLen+1]; if(pcTemp == NULL) return WBEM_E_OUT_OF_MEMORY;
CVectorDeleteMe<TCHAR> dm(pcTemp);
// Create the safe array for returning the data
SAFEARRAY FAR* psa = MySafeArrayCreate(dwNumSubKeys, VT_BSTR); if(psa == NULL) { return WBEM_E_OUT_OF_MEMORY; }
// Put each value name into the array
for(long lTry = 0; lTry < dwNumSubKeys; lTry++) { lRet = RegEnumKey(hKey, lTry, pcTemp, dwMaxSubKeyLen+1); if(lRet == ERROR_SUCCESS) { pcTemp[dwMaxSubKeyLen] = 0; BSTR bstr = GetBSTR(pcTemp); if(bstr) { sc = SafeArrayPutElement(psa, &lTry, bstr); SysFreeString(bstr); if(FAILED(sc)) { SafeArrayDestroy(psa); return sc; } } } }
// Write the data back!
VARIANT var; var.vt = VT_BSTR | VT_ARRAY; var.parray = psa; sc = pOutParams->Put( L"sNames", 0, &var, 0); VariantClear(&var); return sc; }
//***************************************************************************
//
// SCODE EnumValue
//
// Purpose: Enumerates the value names and types and puts the results into
// the output object.
//
// Return: error code or 0 if OK.
//
//***************************************************************************
SCODE EnumValue(HKEY hRoot, TCHAR * cSubKey, IWbemClassObject* pOutParams) { SCODE sc1, sc2; DWORD dwNumSubKeys, dwMaxSubKeyLen, dwNumValues, dwMaxValueNameLen; TCHAR * pcTemp = NULL; DWORD dwType, dwSize;
// Open the registry key
HKEY hKey; long lRet = RegOpenKeyEx((HKEY)hRoot, cSubKey, 0, KEY_QUERY_VALUE, &hKey); if(lRet != ERROR_SUCCESS) return lRet; CRegCloseMe cm(hKey);
// Count the number of values and the max size
lRet = RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwNumSubKeys, // number of subkeys
&dwMaxSubKeyLen, // longest subkey name
NULL, &dwNumValues, // number of value entries
&dwMaxValueNameLen, // longest value name
NULL, NULL, NULL);
if(lRet != ERROR_SUCCESS || dwMaxValueNameLen == 0) return lRet;
pcTemp = new TCHAR[dwMaxValueNameLen+1]; if(pcTemp == NULL) return WBEM_E_OUT_OF_MEMORY;
CVectorDeleteMe<TCHAR> dm(pcTemp); // Create safe arrays for the data names and types
SAFEARRAY FAR* psaNames = MySafeArrayCreate(dwNumValues, VT_BSTR); if(psaNames == NULL) { return WBEM_E_OUT_OF_MEMORY; } SAFEARRAY FAR* psaTypes = MySafeArrayCreate(dwNumValues, VT_I4); if(psaTypes == NULL) { SafeArrayDestroy(psaNames); return WBEM_E_OUT_OF_MEMORY; }
// Fill in the arrays
for(long lTry = 0; lTry < dwNumValues; lTry++) { dwSize = dwMaxValueNameLen+1; lRet = RegEnumValue(hKey, lTry, pcTemp, &dwSize, 0, &dwType, NULL, 0); if(lRet == ERROR_SUCCESS) { pcTemp[dwMaxValueNameLen] = 0; BSTR bstr = GetBSTR(pcTemp); if(bstr) { sc1 = SafeArrayPutElement(psaNames, &lTry, bstr); sc2 = SafeArrayPutElement(psaTypes, &lTry, &dwType); SysFreeString(bstr); if(FAILED(sc1) || FAILED(sc2)) { SafeArrayDestroy(psaNames); SafeArrayDestroy(psaTypes); return WBEM_E_OUT_OF_MEMORY; } } } }
// Put the arrays containing the value names and types into the output object
VARIANT var; var.vt = VT_BSTR | VT_ARRAY; var.parray = psaNames; pOutParams->Put( L"sNames", 0, &var, 0); VariantClear(&var);
var.vt = VT_I4 | VT_ARRAY; var.parray = psaTypes; SCODE sc = pOutParams->Put( L"Types", 0, &var, 0); VariantClear(&var); return sc; }
//***************************************************************************
//
// SCODE GetStr
//
// Purpose: Reads a string and puts it into the output argument. Note that
// this works with either normal strings or expanded registry strings.
//
// Return: error code or 0 if OK.
//
//***************************************************************************
SCODE GetStr(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pOutParams) { Registry reg(hRoot, KEY_QUERY_VALUE, (TCHAR *)cSubKey); long lRet = reg.GetLastError(); if(lRet != ERROR_SUCCESS) return lRet;
// Get the string
TCHAR * pcValue; lRet = reg.GetStr(cValueName, &pcValue); if(lRet != ERROR_SUCCESS) { DWORD dwType; long lRet2 = reg.GetType(cValueName, &dwType); if(lRet2 == ERROR_SUCCESS && dwType != REG_SZ && dwType != REG_EXPAND_SZ) return WBEM_E_TYPE_MISMATCH; return lRet; } CDeleteMe<TCHAR> dm(pcValue);
VARIANT var; var.bstrVal = GetBSTR(pcValue); var.vt = VT_BSTR; if(var.bstrVal == NULL) return WBEM_E_OUT_OF_MEMORY;
lRet = pOutParams->Put( L"sValue", 0, &var, 0); VariantClear(&var); return lRet; }
//***************************************************************************
//
// SCODE SetMultiStrValue
//
// Purpose: Writes multi string values to the registry.
//
// Return: error code or 0 if OK.
//
//***************************************************************************
SCODE SetMultiStrValue(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pInParams) { SCODE sc; Registry reg(hRoot, KEY_SET_VALUE, (TCHAR *)cSubKey); if(reg.GetLastError() != 0) return reg.GetLastError();
VARIANT var; VariantInit(&var);
sc = pInParams->Get(L"sValue", 0, &var, NULL, NULL); if(sc != S_OK) return sc;
CClearMe cm(&var); if(var.vt != (VT_ARRAY | VT_BSTR)) { return WBEM_E_INVALID_PARAMETER; }
SAFEARRAY * psa = var.parray; long lLbound, lUbound; sc = SafeArrayGetLBound(psa, 1, &lLbound ); sc |= SafeArrayGetUBound(psa, 1, &lUbound ); if(sc != S_OK) { return WBEM_E_INVALID_PARAMETER; }
long lNumElements = lUbound - lLbound + 1;
// Calculate the necessary size
long lSize = 1, lTry;
for(lTry = lLbound; lTry <= lUbound; lTry++) { BSTR bstr = NULL; if(S_OK == SafeArrayGetElement(psa, &lTry, &bstr) && bstr) { lSize += SysStringLen(bstr) + 1; SysFreeString(bstr); } else { return WBEM_E_INVALID_PARAMETER; } }
WCHAR * pMulti = new WCHAR [lSize]; if(pMulti == NULL) { return WBEM_E_OUT_OF_MEMORY; }
memset(pMulti, 0, lSize * sizeof(WCHAR)); WCHAR * pNext = pMulti;
// Do the conversion;
for(lTry = lLbound; lTry <= lUbound; lTry++) { BSTR bstr; if(S_OK == SafeArrayGetElement(psa, &lTry, &bstr)) { StringCchCopyW(pNext, lSize - (pNext - pMulti), bstr); pNext += SysStringLen(bstr) + 1; SysFreeString(bstr); } }
long lRet; lRet = reg.SetMultiStr(cValueName, pMulti, lSize * sizeof(WCHAR)); delete [] pMulti; return lRet; }
//***************************************************************************
//
// SCODE GetMultiStrValue
//
// Purpose: Reads multi strings from the registry.
//
// Return: error code or 0 if OK.
//
//***************************************************************************
SCODE GetMultiStrValue(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pOutParams) { SCODE sc; Registry reg(hRoot, KEY_QUERY_VALUE, (TCHAR *)cSubKey); if(reg.GetLastError() != 0) return reg.GetLastError();
DWORD dwSize = 0; TCHAR * pMulti = reg.GetMultiStr(cValueName, dwSize); if(pMulti == NULL) return reg.GetLastError();
CVectorDeleteMe<TCHAR> dm(pMulti); // count the number of strings
long lNumString = 0; TCHAR * pNext; DWORD dwNumChar = dwSize / sizeof(WCHAR); WCHAR * pFinalNull = pMulti + dwNumChar - 1; for(pNext = pMulti; pNext < pFinalNull; pNext += lstrlen(pNext) + 1) lNumString++;
// create the bstr array
SAFEARRAY FAR* psa = MySafeArrayCreate(lNumString, VT_BSTR); if(psa == NULL) { return WBEM_E_OUT_OF_MEMORY; } pNext = pMulti; for(long lTry = 0; lTry < lNumString; lTry++, pNext += lstrlen(pNext) + 1) { int iLen = lstrlen(pNext) + 1; BSTR bstr = GetBSTR(pNext); if(bstr) { sc = SafeArrayPutElement(psa, &lTry, bstr); SysFreeString(bstr); if(FAILED(sc)) { SafeArrayDestroy(psa); return sc; } } }
// put the data
VARIANT var; var.vt = VT_BSTR | VT_ARRAY; var.parray = psa; sc = pOutParams->Put( L"sValue", 0, &var, 0); VariantClear(&var); return sc; }
//***************************************************************************
//
// SCODE SetStringValue
//
// Purpose: Writes strings to the registry. These strings may
// contain environment strings.
//
// Return: error code or 0 if OK.
//
//***************************************************************************
SCODE SetStringValue(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pInParams, StringType st) { Registry reg(hRoot, KEY_SET_VALUE, (TCHAR *)cSubKey); long lRet = reg.GetLastError(); if(lRet != ERROR_SUCCESS) return lRet;
VARIANT var; VariantInit(&var);
SCODE sc = pInParams->Get(L"sValue", 0, &var, NULL, NULL); if(sc != S_OK) return sc; if(var.vt != VT_BSTR) { VariantClear(&var); return WBEM_E_INVALID_PARAMETER; } int iLen = 2*wcslen(var.bstrVal) + 2; TCHAR * pValue = new TCHAR[iLen]; if(pValue) { CopyOrConvert(pValue, var.bstrVal, iLen); if(st == SIMPLE) sc = reg.SetStr(cValueName, pValue); else sc = reg.SetExpandStr(cValueName, pValue); delete [] pValue; } else sc = WBEM_E_OUT_OF_MEMORY; VariantClear(&var); return sc; }
//***************************************************************************
//
// SCODE SetBinaryValue
//
// Purpose: Writes binary data to the registry.
//
// Return: error code or 0 if OK.
//
//***************************************************************************
SCODE SetBinaryValue(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pInParams) { Registry reg(hRoot, KEY_SET_VALUE, (TCHAR *)cSubKey); if(reg.GetLastError() != 0) return reg.GetLastError();
VARIANT var; VariantInit(&var);
SCODE sc = pInParams->Get(L"uValue", 0, &var, NULL, NULL); if(sc != S_OK) return sc;
if(var.vt != (VT_ARRAY | VT_UI1) || var.parray == NULL) { VariantClear(&var); return WBEM_E_INVALID_PARAMETER; }
SAFEARRAY * psa = var.parray; long lLbound, lUbound; sc = SafeArrayGetLBound(psa, 1, &lLbound ); sc |= SafeArrayGetUBound(psa, 1, &lUbound ); if(sc == S_OK) { byte * pData; sc = SafeArrayAccessData(psa, (void HUGEP* FAR*)&pData); if(sc == S_OK) { sc = reg.SetBinary(cValueName, pData, DWORD(lUbound - lLbound + 1)); } } VariantClear(&var); return sc;
}
//***************************************************************************
//
// SCODE GetBinaryValue
//
// Purpose: Reads binary data from the registry.
//
// Return: error code or 0 if OK.
//
//***************************************************************************
SCODE GetBinaryValue(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pOutParams) { Registry reg(hRoot, KEY_QUERY_VALUE, (TCHAR *)cSubKey); if(reg.GetLastError() != 0) return reg.GetLastError();
SCODE sc; DWORD dwSize; byte * pRegData; long lRet = reg.GetBinary(cValueName, &pRegData, &dwSize); if(lRet != ERROR_SUCCESS || pRegData == NULL) { if(IsTypeMismatch(reg, cValueName, REG_BINARY)) return WBEM_E_TYPE_MISMATCH; else return lRet; }
SAFEARRAY FAR* psa = MySafeArrayCreate(dwSize, VT_UI1); if(psa) { TCHAR * pData = NULL; sc = SafeArrayAccessData(psa, (void HUGEP* FAR*)&pData); if(sc == S_OK) { memcpy(pData, pRegData, dwSize); SafeArrayUnaccessData(psa); VARIANT var; var.vt = VT_UI1|VT_ARRAY; var.parray = psa; sc = pOutParams->Put(L"uValue" , 0, &var, 0); VariantClear(&var); } } else sc = WBEM_E_OUT_OF_MEMORY; delete [] pRegData; return sc; }
/************************************************************************
* * *CMethodPro::ExecMethodAsync * * * *Purpose: This is the Async function implementation. * * * ************************************************************************/
SCODE CImpReg::MethodAsync(const BSTR ObjectPath, const BSTR MethodName, long lFlags, IWbemContext* pCtx, IWbemClassObject* pInParams, IWbemObjectSink* pSink) { HRESULT hr; IWbemClassObject * pClass = NULL; IWbemClassObject * pOutClass = NULL; IWbemClassObject* pOutParams = NULL; TCHAR * pcValueName = NULL; TCHAR * pcSubKey = NULL; long lRet = 0; AutoProfile ap;
if(ObjectPath == NULL || MethodName == NULL || pInParams == NULL || pSink == NULL) return WBEM_E_INVALID_PARAMETER;
// Kevin needs a way to tell if something is write
// Get the class object, this is hard coded and matches the class
// in the MOF. Then create the output argument
hr = m_pGateway->GetObject(L"StdRegProv", 0, pCtx, &pClass, NULL); if(hr == S_OK) { hr = pClass->GetMethod(MethodName, 0, NULL, &pOutClass); if(hr == S_OK) { hr = pOutClass->SpawnInstance(0, &pOutParams); pOutClass->Release(); } pClass->Release(); } if(hr != S_OK) return SetStatusAndReturnOK(hr, pSink);
CReleaseMe rm0(pOutParams); // Get the root key and subkeys
VARIANT var; VariantInit(&var); // Get the input argument
hr = pInParams->Get(L"hDefKey", 0, &var, NULL, NULL); if(hr != S_OK) return SetStatusAndReturnOK(hr, pSink); #ifdef _WIN64
HKEY hRoot = (HKEY)IntToPtr(var.lVal); #else
HKEY hRoot = (HKEY)var.lVal; #endif
pcSubKey = GetInArgString(pInParams, L"sSubKeyName"); if(pcSubKey == NULL) return SetStatusAndReturnOK(WBEM_E_INVALID_PARAMETER, pSink); CVectorDeleteMe<TCHAR> dm1(pcSubKey);
// This may or may not work since the value name isnt required
pcValueName = GetInArgString(pInParams, L"sValueName"); CVectorDeleteMe<TCHAR> dm2(pcValueName);
SCODE sc = S_OK;
// Impersonate if using NT
if(IsNT() && IsDcomEnabled()) { sc = WbemCoImpersonateClient(); if(sc != S_OK) return sc; }
// If we are using HKCU, the hive may need to be loaded
bool bUsingHKCU = IsNT() && hRoot == HKEY_CURRENT_USER;
if(bUsingHKCU) sc = ap.LoadProfile(hRoot);
if(sc != S_OK) return sc;
if(!wbem_wcsicmp(MethodName, L"CreateKey")) { HKEY hKey; if(lstrlen(pcSubKey) < 1) sc = WBEM_E_INVALID_PARAMETER; else { lRet = RegCreateKey(hRoot, pcSubKey, &hKey); if(lRet == ERROR_SUCCESS) RegCloseKey(hKey); } } else if(!wbem_wcsicmp(MethodName, L"DeleteKey")) { if(lstrlen(pcSubKey) < 1) sc = WBEM_E_INVALID_PARAMETER; else lRet = RegDeleteKey(hRoot, pcSubKey); } else if(!wbem_wcsicmp(MethodName, L"DeleteValue")) { HKEY hKey; lRet = RegOpenKey(hRoot, pcSubKey, &hKey); if(lRet == ERROR_SUCCESS) { lRet = RegDeleteValue(hKey, pcValueName); RegCloseKey(hKey); } } else if(!wbem_wcsicmp(MethodName, L"EnumKey")) { lRet = EnumKey(hRoot, pcSubKey, pOutParams); } else if(!wbem_wcsicmp(MethodName, L"EnumValues")) { lRet = EnumValue(hRoot, pcSubKey, pOutParams); } else if(!wbem_wcsicmp(MethodName, L"GetStringValue") || !wbem_wcsicmp(MethodName, L"GetExpandedStringValue")) { lRet = GetStr(hRoot, pcSubKey, pcValueName, pOutParams); } else if(!wbem_wcsicmp(MethodName, L"SetMultiStringValue")) { lRet = SetMultiStrValue(hRoot,pcSubKey,pcValueName,pInParams); } else if(!wbem_wcsicmp(MethodName, L"GetMultiStringValue")) { lRet = GetMultiStrValue(hRoot,pcSubKey,pcValueName,pOutParams); } else if(!wbem_wcsicmp(MethodName, L"SetExpandedStringValue")) { lRet = SetStringValue(hRoot, pcSubKey, pcValueName, pInParams, EXPANDED); } else if(!wbem_wcsicmp(MethodName, L"SetStringValue")) { lRet = SetStringValue(hRoot, pcSubKey, pcValueName, pInParams, SIMPLE); } else if(!wbem_wcsicmp(MethodName, L"SetBinaryValue")) { lRet = SetBinaryValue(hRoot, pcSubKey, pcValueName, pInParams); } else if(!wbem_wcsicmp(MethodName, L"SetDWORDValue")) { lRet = pInParams->Get(L"uValue", 0, &var, NULL, NULL); if(lRet == S_OK) { DWORD dwValue = var.lVal; Registry reg(hRoot, KEY_SET_VALUE, (TCHAR *)pcSubKey); lRet = reg.GetLastError(); if(lRet ==0) lRet = reg.SetDWORD(pcValueName, dwValue); } } else if(!wbem_wcsicmp(MethodName, L"GetDWORDValue")) { // Get the value name
Registry reg(hRoot, KEY_QUERY_VALUE, (TCHAR *)pcSubKey); lRet = reg.GetLastError(); if(lRet == 0) lRet = reg.GetDWORD(pcValueName, (DWORD *)&var.lVal); if(lRet == ERROR_SUCCESS) { var.vt = VT_I4; lRet = pOutParams->Put( L"uValue", 0, &var, 0); } else if(IsTypeMismatch(reg, pcValueName, REG_DWORD)) lRet = WBEM_E_TYPE_MISMATCH; } else if(!wbem_wcsicmp(MethodName, L"GetBinaryValue")) { lRet = GetBinaryValue(hRoot,pcSubKey,pcValueName,pOutParams); } else if(!wbem_wcsicmp(MethodName, L"CheckAccess")) { lRet = pInParams->Get(L"uRequired", 0, &var, NULL, NULL); if(lRet == S_OK) { BOOL bSuccess = FALSE; DWORD dwValue = var.lVal; HKEY hKey; lRet = RegOpenKeyEx(hRoot, pcSubKey, 0, dwValue, &hKey); if(lRet == ERROR_SUCCESS) { RegCloseKey(hKey); bSuccess = TRUE; } var.vt = VT_BOOL; var.boolVal = (bSuccess) ? VARIANT_TRUE : VARIANT_FALSE; pOutParams->Put( L"bGranted", 0, &var, 0); } } else sc = WBEM_E_INVALID_METHOD;
if(bUsingHKCU) { WbemCoRevertToSelf(); } // Set the return value
if(sc == S_OK) { BSTR retValName = SysAllocString(L"ReturnValue"); if(retValName) { var.vt = VT_I4; var.lVal = lRet; pOutParams->Put(retValName , 0, &var, 0); SysFreeString(retValName); } hr = pSink->Indicate(1, &pOutParams); }
return SetStatusAndReturnOK(sc, pSink); }
|