windows-nt/Source/XPSP1/NT/admin/wmi/wbem/policman/loader/loader.cpp
2020-09-26 16:20:57 +08:00

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;
}