427 lines
12 KiB
C++
427 lines
12 KiB
C++
|
// test harness for WMI GPO subsubsystem
|
||
|
// hardcoded for the hhancedom domain in microsoft.com
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <initguid.h>
|
||
|
#include <prsht.h>
|
||
|
#include <wbemidl.h>
|
||
|
#include <gpedit.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#define LINK_TARGET L"LDAP://DC=EssCool,DC=com"
|
||
|
#define DOMAIN_NAME L"LDAP://DC=EssCool,DC=com"
|
||
|
|
||
|
// {AAEAE720-0328-4763-8ECB-23422EDE2DB5}
|
||
|
const CLSID CLSID_CSE =
|
||
|
{ 0xaaeae720, 0x328, 0x4763, { 0x8e, 0xcb, 0x23, 0x42, 0x2e, 0xde, 0x2d, 0xb5 } };
|
||
|
|
||
|
// TODO: attempt to create namespace if not available.
|
||
|
HRESULT GetNamespace(BSTR namespaceName, IWbemServices*& pNamespace)
|
||
|
{
|
||
|
HRESULT hr = WBEM_E_FAILED;
|
||
|
|
||
|
IWbemLocator* pLoc = NULL;
|
||
|
|
||
|
if (FAILED(hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*) &pLoc)))
|
||
|
printf("Could not create wbem locator (0x%08X)\n", hr);
|
||
|
else
|
||
|
{
|
||
|
if (SUCCEEDED(hr = pLoc->ConnectServer(namespaceName, NULL,NULL, 0,0,0,0,&pNamespace)))
|
||
|
printf("Retrieved %S namespace\n", namespaceName);
|
||
|
else
|
||
|
printf("ConnectServer(%s) failed (0x%08X)\n", namespaceName, hr);
|
||
|
|
||
|
pLoc->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT GetPolicyNamespace(IWbemServices*& pPolicyNamespace)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
BSTR bstr = SysAllocString(L"\\\\.\\ROOT\\POLICY");
|
||
|
if (bstr)
|
||
|
{
|
||
|
hr = GetNamespace(bstr, pPolicyNamespace);
|
||
|
SysFreeString(bstr);
|
||
|
}
|
||
|
else
|
||
|
hr = WBEM_E_OUT_OF_MEMORY;
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
printf("Failed to retrieve policy namespace (0x%08X)\n", hr);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT DeleteGPO(WCHAR *name)
|
||
|
{
|
||
|
LPGROUPPOLICYOBJECT pGPO = NULL;
|
||
|
HRESULT hr;
|
||
|
|
||
|
if (SUCCEEDED(hr = DeleteGPOLink(name,LINK_TARGET)))
|
||
|
printf("deleted link\n");
|
||
|
else
|
||
|
printf("DeleteGPOLink failed with 0x%x.\n", hr);
|
||
|
|
||
|
|
||
|
if (FAILED(hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL,
|
||
|
CLSCTX_SERVER, IID_IGroupPolicyObject,
|
||
|
(void **)&pGPO)))
|
||
|
printf("CoCreateInstance failed with 0x%x.\n", hr);
|
||
|
else
|
||
|
{
|
||
|
if (FAILED(hr = pGPO->OpenDSGPO(name, 0)))
|
||
|
printf("OpenDSGPO failed with 0x%x.\n", hr);
|
||
|
else
|
||
|
if (FAILED(hr = pGPO->Delete()))
|
||
|
printf("Delete failed with 0x%x.\n", hr);
|
||
|
else
|
||
|
printf("Deleted %S\n", name);
|
||
|
|
||
|
pGPO->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// communicate with the Group Policy Infrastructure which will
|
||
|
// create a GPO object & return to us the path of the container
|
||
|
// into which we should write our object
|
||
|
HRESULT CreateGPO(const WCHAR* name, WCHAR* domain, WCHAR* szPath)
|
||
|
{
|
||
|
LPGROUPPOLICYOBJECT pGPO = NULL;
|
||
|
HRESULT hr;
|
||
|
|
||
|
if (FAILED(hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL,
|
||
|
CLSCTX_SERVER, IID_IGroupPolicyObject,
|
||
|
(void **)&pGPO)))
|
||
|
printf("CoCreateInstance failed with 0x%x.\n", hr);
|
||
|
else
|
||
|
{
|
||
|
if (FAILED(hr = pGPO->New(domain, (WCHAR*)name, 0)))
|
||
|
printf("New failed with 0x%x.\n", hr);
|
||
|
else
|
||
|
if (FAILED(hr= pGPO->GetDSPath(GPO_SECTION_MACHINE, szPath, MAX_PATH)))
|
||
|
printf("GetDSPath failed with 0x%x.\n", hr);
|
||
|
else
|
||
|
{
|
||
|
printf("\nGPO machine path: %S\n\n", szPath);
|
||
|
// pGPO->GetDSPath(GPO_SECTION_USER, szPath, MAX_PATH);
|
||
|
// printf("GPO user path: %S\n\n", szPath);
|
||
|
|
||
|
WCHAR rootPath[MAX_PATH];
|
||
|
|
||
|
if (FAILED(hr = pGPO->GetPath(rootPath, MAX_PATH)))
|
||
|
printf("GetPath failed with 0x%x.\n", hr);
|
||
|
else
|
||
|
{
|
||
|
printf("GPO root path: %S\n\n", rootPath);
|
||
|
|
||
|
if (FAILED(hr = CreateGPOLink(rootPath, domain, FALSE)))
|
||
|
printf("CreateGPOLink failed with 0x%x.\n", hr);
|
||
|
else
|
||
|
if (FAILED(hr = pGPO->Save(TRUE, TRUE, (struct _GUID *)&CLSID_CSE, (struct _GUID *)&CLSID_CSE) ))
|
||
|
printf("Save failed with 0x%x.\n", hr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pGPO->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT PutRangeParams(IWbemServices* pPolicyNamespace, IWbemClassObject* pTemplate)
|
||
|
{
|
||
|
HRESULT hr = WBEM_S_NO_ERROR;
|
||
|
|
||
|
SAFEARRAYBOUND
|
||
|
arrayBounds;
|
||
|
|
||
|
arrayBounds.lLbound = 0;
|
||
|
arrayBounds.cElements = 1;
|
||
|
|
||
|
SAFEARRAY* psa = SafeArrayCreate(VT_UNKNOWN, 1, &arrayBounds);
|
||
|
if (!psa)
|
||
|
{
|
||
|
printf("Failed to create safe array\n");
|
||
|
return WBEM_E_OUT_OF_MEMORY;
|
||
|
}
|
||
|
|
||
|
IWbemClassObject* pClass = NULL;
|
||
|
BSTR bustard = SysAllocString(L"MSFT_SintRangeParam");
|
||
|
if (SUCCEEDED(hr = pPolicyNamespace->GetObject(bustard, 0, NULL, &pClass, NULL)))
|
||
|
{
|
||
|
IWbemClassObject* pRange = NULL;
|
||
|
if (FAILED(hr = pClass->SpawnInstance(0, &pRange)))
|
||
|
{
|
||
|
printf("pClass->SpawnInstance failed, 0x%08X\n", hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
VARIANT v;
|
||
|
VariantInit(&v);
|
||
|
v.vt = VT_BSTR;
|
||
|
v.bstrVal = SysAllocString(L"ID");
|
||
|
|
||
|
pRange->Put(L"PropertyName",0,&v,NULL);
|
||
|
VariantClear(&v);
|
||
|
|
||
|
v.vt = VT_BSTR;
|
||
|
v.bstrVal = SysAllocString(L"SINT32");
|
||
|
pRange->Put(L"TargetClass",0,&v,NULL);
|
||
|
VariantClear(&v);
|
||
|
|
||
|
v.vt = VT_I4;
|
||
|
v.lVal = 5;
|
||
|
pRange->Put(L"Default",0,&v,NULL);
|
||
|
VariantClear(&v);
|
||
|
|
||
|
v.vt = VT_I4;
|
||
|
v.lVal = CIM_SINT32;
|
||
|
pRange->Put(L"TargetType",0,&v,NULL);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
v.vt = VT_UNKNOWN | VT_ARRAY;
|
||
|
v.parray = psa;
|
||
|
long index = 0;
|
||
|
SafeArrayPutElement(psa, &index, pRange);
|
||
|
|
||
|
hr = pTemplate->Put(L"RangeSettings", 0, &v, NULL);
|
||
|
|
||
|
pRange->Release();
|
||
|
pClass->Release();
|
||
|
}
|
||
|
else
|
||
|
printf("Failed to retrieve MSFT_SintRangeParam, 0x%08X\n", hr);
|
||
|
|
||
|
printf("PutRangeParams returning 0x%08X\n", hr);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
// create template based on object
|
||
|
// write it to ds, return key string
|
||
|
HRESULT CreatePolicyTemplate(IWbemServices* pPolicyNamespace, WCHAR* keyString)
|
||
|
{
|
||
|
HRESULT hr = WBEM_E_FAILED;
|
||
|
IWbemClassObject* pTemplateTemplate = NULL;
|
||
|
BSTR bstr = SysAllocString(L"MSFT_MergeablePolicyTemplate");
|
||
|
|
||
|
if (FAILED(hr = pPolicyNamespace->GetObject(bstr,0,NULL,&pTemplateTemplate,NULL)))
|
||
|
printf("GetObject on MSFT_MergeablePolicyTemplate failed 0x%08X\n", hr);
|
||
|
else
|
||
|
{
|
||
|
printf("Retrieved MSFT_MergeablePolicyTemplate\n");
|
||
|
|
||
|
IWbemClassObject* pTemplate = NULL;
|
||
|
if (FAILED(hr = pTemplateTemplate->SpawnInstance(0, &pTemplate)))
|
||
|
printf("SpawnInstance on MSFT_MergeablePolicyTemplate failed 0x%08X\n", hr);
|
||
|
else
|
||
|
{
|
||
|
printf("SpawnInstance on MSFT_MergeablePolicyTemplate Succeeded\n");
|
||
|
|
||
|
VARIANT v;
|
||
|
VariantInit(&v);
|
||
|
v.vt = VT_BSTR;
|
||
|
GUID guid;
|
||
|
|
||
|
CoCreateGuid(&guid);
|
||
|
WCHAR guidStr[128];
|
||
|
|
||
|
StringFromGUID2(guid, guidStr, 128);
|
||
|
|
||
|
v.bstrVal = SysAllocString(guidStr);
|
||
|
pTemplate->Put(L"ID", 0, &v, NULL);
|
||
|
SysFreeString(v.bstrVal);
|
||
|
|
||
|
v.bstrVal = SysAllocString(L"LOCAL");
|
||
|
pTemplate->Put(L"DsContext", 0, &v, NULL);
|
||
|
SysFreeString(v.bstrVal);
|
||
|
|
||
|
v.bstrVal = SysAllocString(L"root\\policy");
|
||
|
pTemplate->Put(L"TargetNamespace", 0, &v, NULL);
|
||
|
SysFreeString(v.bstrVal);
|
||
|
|
||
|
v.bstrVal = SysAllocString(L"ModemSetting");
|
||
|
pTemplate->Put(L"TargetClass", 0, &v, NULL);
|
||
|
SysFreeString(v.bstrVal);
|
||
|
|
||
|
v.bstrVal = SysAllocString(L"Description");
|
||
|
pTemplate->Put(L"Description", 0, &v, NULL);
|
||
|
SysFreeString(v.bstrVal);
|
||
|
|
||
|
v.bstrVal = SysAllocString(L"ModemSetting.id=5");
|
||
|
pTemplate->Put(L"TargetPath", 0, &v, NULL);
|
||
|
SysFreeString(v.bstrVal);
|
||
|
|
||
|
v.bstrVal = SysAllocString(L"None whatsoever");
|
||
|
pTemplate->Put(L"SourceOrganization", 0, &v, NULL);
|
||
|
SysFreeString(v.bstrVal);
|
||
|
|
||
|
v.bstrVal = SysAllocString(L"20000101000000.000000-480");
|
||
|
pTemplate->Put(L"ChangeDate", 0, &v, NULL);
|
||
|
pTemplate->Put(L"CreationDate", 0, &v, NULL);
|
||
|
SysFreeString(v.bstrVal);
|
||
|
|
||
|
v.bstrVal = SysAllocString(L"Joe Bob");
|
||
|
pTemplate->Put(L"Name", 0, &v, NULL);
|
||
|
SysFreeString(v.bstrVal);
|
||
|
|
||
|
v.bstrVal = SysAllocString(L"Joe Jack");
|
||
|
pTemplate->Put(L"Author", 0, &v, NULL);
|
||
|
SysFreeString(v.bstrVal);
|
||
|
|
||
|
hr = PutRangeParams(pPolicyNamespace, pTemplate);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
pTemplate->Get(L"__RELPATH", 0, &v, NULL, NULL);
|
||
|
wcscpy(keyString, v.bstrVal);
|
||
|
VariantClear(&v);
|
||
|
|
||
|
if (SUCCEEDED(hr = pPolicyNamespace->PutInstance(pTemplate, WBEM_FLAG_USE_AMENDED_QUALIFIERS | WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL)))
|
||
|
printf("Successfully put %S\n", keyString);
|
||
|
else
|
||
|
printf("PutInstance on MSFT_MergeablePolicyTemplate failed 0x%08X\n", hr);
|
||
|
}
|
||
|
|
||
|
pTemplate->Release();
|
||
|
}
|
||
|
|
||
|
pTemplateTemplate->Release();
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// write WMIGPO object to DS
|
||
|
// to path specified in szPath
|
||
|
// containing keystring
|
||
|
HRESULT WriteWMIGPO(IWbemServices* pPolicyNamespace, const WCHAR* szPath, const WCHAR* keyString)
|
||
|
{
|
||
|
HRESULT hr = WBEM_E_FAILED;
|
||
|
IWbemClassObject* pWmiGpoClass = NULL;
|
||
|
BSTR bstr = SysAllocString(L"MSFT_WMIGPO");
|
||
|
|
||
|
if (FAILED(hr = pPolicyNamespace->GetObject(bstr,WBEM_FLAG_USE_AMENDED_QUALIFIERS,NULL,&pWmiGpoClass,NULL)))
|
||
|
printf("GetObject on MSFT_WMIGPO failed 0x%08X\n", hr);
|
||
|
else
|
||
|
{
|
||
|
IWbemClassObject* pWmiGpo = NULL;
|
||
|
if (FAILED(hr = pWmiGpoClass->SpawnInstance(0, &pWmiGpo)))
|
||
|
printf("SpawnInstance on MSFT_WMIGPO failed 0x%08X\n", hr);
|
||
|
else
|
||
|
{
|
||
|
VARIANT v;
|
||
|
VariantInit(&v);
|
||
|
v.vt = VT_BSTR;
|
||
|
|
||
|
v.bstrVal = SysAllocString(szPath);
|
||
|
pWmiGpo->Put(L"DsPath", 0, &v, NULL);
|
||
|
|
||
|
VariantClear(&v);
|
||
|
v.vt = VT_BSTR | VT_ARRAY;
|
||
|
|
||
|
SAFEARRAYBOUND
|
||
|
arrayBounds;
|
||
|
SAFEARRAY* pArray = NULL;
|
||
|
|
||
|
arrayBounds.lLbound = 0;
|
||
|
arrayBounds.cElements = 1;
|
||
|
|
||
|
long index = 0;
|
||
|
pArray = SafeArrayCreate(VT_BSTR, 1, &arrayBounds);
|
||
|
SafeArrayPutElement(pArray, &index, SysAllocString(keyString));
|
||
|
v.parray = pArray;
|
||
|
|
||
|
pWmiGpo->Put(L"PolicyTemplate", 0, &v, NULL);
|
||
|
SafeArrayDestroy(pArray);
|
||
|
|
||
|
|
||
|
if (SUCCEEDED(hr = pPolicyNamespace->PutInstance(pWmiGpo, WBEM_FLAG_USE_AMENDED_QUALIFIERS | WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL)))
|
||
|
printf("Successfully put MSFT_WMIGPO\n");
|
||
|
else
|
||
|
printf("PutInstance on MSFT_WMIGPO failed 0x%08X\n", hr);
|
||
|
|
||
|
pWmiGpo->Release();
|
||
|
}
|
||
|
|
||
|
pWmiGpoClass->Release();
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstr);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
int __cdecl wmain(int argc, WCHAR *argv[])
|
||
|
{
|
||
|
CoInitialize(NULL);
|
||
|
|
||
|
CoInitializeSecurity (NULL, -1, NULL, NULL,
|
||
|
RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IMPERSONATE, NULL,
|
||
|
EOAC_NONE, NULL);
|
||
|
|
||
|
/**********************
|
||
|
|
||
|
// create deleter with this...
|
||
|
if (argc==2)
|
||
|
DeleteGPO(argv[1]);
|
||
|
else
|
||
|
printf("one and only one argument, please - that's the path to the root of the gpo\n");
|
||
|
******************/
|
||
|
|
||
|
WCHAR szPath[MAX_PATH];
|
||
|
IWbemServices* pPolicyNamespace = NULL;
|
||
|
|
||
|
if (argc==3)
|
||
|
{
|
||
|
if (SUCCEEDED(GetPolicyNamespace(pPolicyNamespace))
|
||
|
&&
|
||
|
SUCCEEDED(CreateGPO(L"WMI Test Policy", argv[1], szPath)))
|
||
|
WriteWMIGPO(pPolicyNamespace, szPath, argv[2]);
|
||
|
|
||
|
if (pPolicyNamespace)
|
||
|
pPolicyNamespace->Release();
|
||
|
}
|
||
|
else if (argc==4)
|
||
|
{
|
||
|
if (SUCCEEDED(GetPolicyNamespace(pPolicyNamespace))
|
||
|
&&
|
||
|
SUCCEEDED(CreateGPO(argv[3], argv[1], szPath)))
|
||
|
WriteWMIGPO(pPolicyNamespace, szPath, argv[2]);
|
||
|
|
||
|
if (pPolicyNamespace)
|
||
|
pPolicyNamespace->Release();
|
||
|
}
|
||
|
else
|
||
|
printf("\nUSAGE:\n\n Loader [domain path] [Policy Template Path] <optional policy name>\n\nEXAMPLE (line breaks to improve readability):\n\n Loader LDAP://DC=EssCool,DC=com\n MSFT_MergeablePolicyTemplate.DsContext=\\\"LOCAL\\\",ID=\\\"{BA34...3471}\\\"\n MyPolicy\n");
|
||
|
|
||
|
|
||
|
|
||
|
/*********************
|
||
|
hard coded version
|
||
|
WCHAR keyString[MAX_PATH];
|
||
|
if (SUCCEEDED(GetPolicyNamespace(pPolicyNamespace))
|
||
|
&&
|
||
|
SUCCEEDED(CreatePolicyTemplate(pPolicyNamespace, keyString))
|
||
|
&&
|
||
|
SUCCEEDED(CreateGPO(L"fribbert", szPath))
|
||
|
)
|
||
|
WriteWMIGPO(pPolicyNamespace, szPath, keyString);
|
||
|
|
||
|
if (pPolicyNamespace)
|
||
|
pPolicyNamespace->Release();
|
||
|
*************************/
|
||
|
|
||
|
CoUninitialize();
|
||
|
|
||
|
return 0;
|
||
|
}
|