The following seems to work OK supposing I'm logged on as domain user (or that I inpersonalize one). I'm still interested if it is possible to get the same using NetLocalGroupGetMembers or something else from LM.h
#include <string>
#include <iads.h>
#include <adshlp.h>
#pragma comment (lib,"Activeds.lib")
#pragma comment (lib,"ADSIid.lib")
void WalkGroup(int level,LPCTSTR objectName);
HRESULT EnumMembers(int level,IADsMembers *pMembers)
{
IUnknown *pUnk;
HRESULT hr;
hr = pMembers->get__NewEnum(&pUnk);
if(FAILED(hr))
{
KINFO(TEXT("Cannot get enum object\r\n"));
goto Cleanup;
}
IEnumVARIANT *pEnum;
hr = pUnk->QueryInterface(IID_IEnumVARIANT,(void**)&pEnum);
if(FAILED(hr))
{
KINFO(TEXT("Cannot get enum variant\r\n"));
goto Cleanup;
}
VARIANT var;
IADs *pADs;
ULONG lFetch;
IDispatch *pDisp;
VariantInit(&var);
hr = pEnum->Next(1, &var, &lFetch);
if(FAILED(hr))
{
KINFO(TEXT("Cannot get next member\r\n"));
goto Cleanup;
}
while(hr == S_OK)
{
if (lFetch == 1)
{
BSTR bstrName=NULL;
BSTR bstrClass=NULL;
BSTR bstrPath=NULL;
pDisp = V_DISPATCH(&var);
pDisp->QueryInterface(IID_IADs, (void**)&pADs);
pADs->get_Name(&bstrName);
pADs->get_Class(&bstrClass);
pADs->get_ADsPath(&bstrPath);
KINFO(TEXT("%d %s %s %s\n"),level,bstrClass, bstrName, bstrPath);
if(!_tcscmp(bstrClass,TEXT("Group")))
{
WalkGroup(level+1,bstrPath);
}
SysFreeString(bstrName);
SysFreeString(bstrClass);
SysFreeString(bstrPath);
}
VariantClear(&var);
pDisp=NULL;
hr = pEnum->Next(1, &var, &lFetch);
if(FAILED(hr))
{
KINFO(TEXT("Cannot get next member\r\n"));
goto Cleanup;
}
};
Cleanup:
if(pADs) pADs->Release();
if(pDisp) pDisp->Release();
if(pUnk) pUnk->Release();
if(pEnum) pEnum->Release();
VariantClear(&var);
return hr;
}
void WalkGroup(int level,LPCTSTR objectName)
{
HRESULT hr;
IADsGroup *pGroup=NULL;
IADsMembers *pMembers=NULL;
hr = ADsGetObject(objectName,IID_IADsGroup,(void**)&pGroup);
if(FAILED(hr))
{
KINFO(TEXT("Cannot get object %s. Priviledges? Domain?\r\n"),objectName);
goto Cleanup;
}
hr = pGroup->Members(&pMembers);
if(FAILED(hr))
{
KINFO(TEXT("Cannot get members\r\n"));
goto Cleanup;
}
EnumMembers(level,pMembers);
Cleanup:
if(pMembers)
pMembers->Release();
if(pGroup)
pGroup->Release();
}
int wmain(int argc, wchar_t *argv[], wchar_t *envp[])
{
CoInitialize(NULL);
TCHAR computerName[MAX_COMPUTERNAME_LENGTH + 1];
TCHAR objectName[MAX_COMPUTERNAME_LENGTH + 256];
DWORD computerNameSize=MAX_COMPUTERNAME_LENGTH + 1;
GetComputerName(computerName,&computerNameSize);
swprintf_s( objectName,MAX_COMPUTERNAME_LENGTH + 256,_T("WinNT://%s/Administrators"),computerName);
WalkGroup(0,objectName);
CoUninitialize();
return (0);
}
</adshlp.h></iads.h></string>