929 lines
23 KiB
C++
929 lines
23 KiB
C++
/*++
|
|
|
|
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>
|
|
enum StringType{SIMPLE, EXPANDED};
|
|
|
|
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)
|
|
{
|
|
pOut = new TCHAR[wcslen(var.bstrVal) + 1];
|
|
if(pOut)
|
|
wcscpy(pOut, 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;
|
|
|
|
// 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)
|
|
{
|
|
RegCloseKey(hKey);
|
|
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)
|
|
{
|
|
|
|
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);
|
|
RegCloseKey(hKey);
|
|
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;
|
|
|
|
// 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)
|
|
{
|
|
RegCloseKey(hKey);
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
SAFEARRAY FAR* psaTypes = MySafeArrayCreate(dwNumValues, VT_I4);
|
|
if(psaTypes == NULL)
|
|
{
|
|
SafeArrayDestroy(psaNames);
|
|
RegCloseKey(hKey);
|
|
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)
|
|
{
|
|
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);
|
|
RegCloseKey(hKey);
|
|
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;
|
|
if(var.vt != (VT_ARRAY | VT_BSTR))
|
|
{
|
|
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)
|
|
{
|
|
VariantClear(&var);
|
|
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;
|
|
if(S_OK == SafeArrayGetElement(psa, &lTry, &bstr))
|
|
{
|
|
lSize += SysStringLen(bstr) + 1;
|
|
SysFreeString(bstr);
|
|
}
|
|
}
|
|
|
|
WCHAR * pMulti = new WCHAR [lSize];
|
|
if(pMulti == NULL)
|
|
{
|
|
VariantClear(&var);
|
|
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))
|
|
{
|
|
wcscpy(pNext, bstr);
|
|
pNext += SysStringLen(bstr) + 1;
|
|
SysFreeString(bstr);
|
|
}
|
|
}
|
|
VariantClear(&var);
|
|
|
|
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;
|
|
for(pNext = pMulti; *pNext; 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;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SCODE LoadProfile
|
|
//
|
|
// Purpose: Sets up all the arguments needed for calling LoadUserProfile
|
|
//
|
|
// Return: error code or 0 if OK.
|
|
//
|
|
//***************************************************************************
|
|
|
|
SCODE LoadProfile(HANDLE & hToken,HKEY & hRoot)
|
|
{
|
|
PROFILEINFO pi;
|
|
memset((void *)&pi, 0, sizeof(pi));
|
|
pi.dwSize = sizeof(pi);
|
|
SCODE sc;
|
|
|
|
BOOL bRes;
|
|
bRes = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE,
|
|
TRUE, &hToken);
|
|
if(!bRes)
|
|
return WBEM_E_FAILED;
|
|
|
|
TCHAR cUsername[MAX_PATH];
|
|
cUsername[0] = 0;
|
|
DWORD dwSize = MAX_PATH;
|
|
GetUserName(cUsername, &dwSize);
|
|
pi.lpUserName = cUsername;
|
|
pi.dwFlags = 1;
|
|
WbemCoRevertToSelf();
|
|
BOOL bRet = LoadUserProfile(hToken, &pi);
|
|
if(bRet == 0)
|
|
{
|
|
hRoot = NULL;
|
|
sc = WbemCoImpersonateClient();
|
|
return WBEM_E_FAILED;
|
|
}
|
|
else
|
|
hRoot = (HKEY)pi.hProfile;
|
|
sc = WbemCoImpersonateClient();
|
|
if(FAILED(sc))
|
|
{
|
|
UnloadUserProfile(hToken, hRoot);
|
|
hRoot = NULL;
|
|
}
|
|
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;
|
|
|
|
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;
|
|
|
|
|
|
HANDLE hToken = INVALID_HANDLE_VALUE;
|
|
CCloseMe cm(hToken);
|
|
|
|
if(bUsingHKCU)
|
|
sc = LoadProfile(hToken, hRoot);
|
|
|
|
if(sc != S_OK)
|
|
return sc;
|
|
|
|
if(!_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(!_wcsicmp(MethodName, L"DeleteKey"))
|
|
{
|
|
if(lstrlen(pcSubKey) < 1)
|
|
sc = WBEM_E_INVALID_PARAMETER;
|
|
else
|
|
lRet = RegDeleteKey(hRoot, pcSubKey);
|
|
}
|
|
else if(!_wcsicmp(MethodName, L"DeleteValue"))
|
|
{
|
|
HKEY hKey;
|
|
lRet = RegOpenKey(hRoot, pcSubKey, &hKey);
|
|
if(lRet == ERROR_SUCCESS)
|
|
{
|
|
lRet = RegDeleteValue(hKey, pcValueName);
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
else if(!_wcsicmp(MethodName, L"EnumKey"))
|
|
{
|
|
lRet = EnumKey(hRoot, pcSubKey, pOutParams);
|
|
}
|
|
else if(!_wcsicmp(MethodName, L"EnumValues"))
|
|
{
|
|
lRet = EnumValue(hRoot, pcSubKey, pOutParams);
|
|
}
|
|
else if(!_wcsicmp(MethodName, L"GetStringValue") ||
|
|
!_wcsicmp(MethodName, L"GetExpandedStringValue"))
|
|
{
|
|
lRet = GetStr(hRoot, pcSubKey, pcValueName, pOutParams);
|
|
}
|
|
else if(!_wcsicmp(MethodName, L"SetMultiStringValue"))
|
|
{
|
|
lRet = SetMultiStrValue(hRoot,pcSubKey,pcValueName,pInParams);
|
|
}
|
|
else if(!_wcsicmp(MethodName, L"GetMultiStringValue"))
|
|
{
|
|
lRet = GetMultiStrValue(hRoot,pcSubKey,pcValueName,pOutParams);
|
|
}
|
|
else if(!_wcsicmp(MethodName, L"SetExpandedStringValue"))
|
|
{
|
|
lRet = SetStringValue(hRoot, pcSubKey, pcValueName, pInParams, EXPANDED);
|
|
}
|
|
else if(!_wcsicmp(MethodName, L"SetStringValue"))
|
|
{
|
|
lRet = SetStringValue(hRoot, pcSubKey, pcValueName, pInParams, SIMPLE);
|
|
}
|
|
else if(!_wcsicmp(MethodName, L"SetBinaryValue"))
|
|
{
|
|
lRet = SetBinaryValue(hRoot, pcSubKey, pcValueName, pInParams);
|
|
}
|
|
else if(!_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(!_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(!_wcsicmp(MethodName, L"GetBinaryValue"))
|
|
{
|
|
lRet = GetBinaryValue(hRoot,pcSubKey,pcValueName,pOutParams);
|
|
}
|
|
else if(!_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();
|
|
UnloadUserProfile(hToken, hRoot);
|
|
}
|
|
|
|
// 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);
|
|
}
|