|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996
//
// File: cenumcom.cxx
//
// Contents: Windows NT 4.0 Enumeration code for computer container
//
// CWinNTComputerEnum::CWinNTComputerEnum()
// CWinNTComputerEnum::CWinNTComputerEnum
// CWinNTComputerEnum::EnumObjects
// CWinNTComputerEnum::EnumObjects
//
// History:
//----------------------------------------------------------------------------
#include "winnt.hxx"
#pragma hdrstop
#if DBG
DECLARE_INFOLEVEL(EnumComp); DECLARE_DEBUG(EnumComp); #define EnumCompDebugOut(x) EnumCompInlineDebugOut x
#endif
//+---------------------------------------------------------------------------
//
// Function: CWinNTEnumVariant::Create
//
// Synopsis:
//
// Arguments: [pCollection]
// [ppEnumVariant]
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT CWinNTComputerEnum::Create( CWinNTComputerEnum FAR* FAR* ppenumvariant, BSTR ADsPath, BSTR DomainName, BSTR ComputerName, VARIANT var, CWinNTCredentials& Credentials ) { HRESULT hr = NOERROR; CWinNTComputerEnum FAR* penumvariant = NULL;
*ppenumvariant = NULL;
penumvariant = new CWinNTComputerEnum();
if (!penumvariant) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
hr = ADsAllocString( ADsPath, &penumvariant->_ADsPath); BAIL_ON_FAILURE(hr);
hr = ADsAllocString( DomainName, &penumvariant->_DomainName); BAIL_ON_FAILURE(hr);
hr = ADsAllocString( ComputerName, &penumvariant->_ComputerName); BAIL_ON_FAILURE(hr);
hr = ObjectTypeList::CreateObjectTypeList( var, &penumvariant->_pObjList ); BAIL_ON_FAILURE(hr);
penumvariant->_Credentials = Credentials; hr = penumvariant->_Credentials.RefServer(ComputerName); BAIL_ON_FAILURE(hr);
*ppenumvariant = penumvariant;
RRETURN(hr);
error: delete penumvariant;
RRETURN_EXP_IF_ERR(hr); }
CWinNTComputerEnum::CWinNTComputerEnum(): _ComputerName(NULL), _DomainName(NULL), _ADsPath(NULL) { _pObjList = NULL; _pBuffer = NULL; _bNoMore = 0; _dwObjectReturned = 0; _dwObjectCurrentEntry = 0; _dwObjectTotal = 0;
_hLGroupComputer = NULL; _hGGroupComputer = NULL; _dwGroupArrayIndex = 0;
_pPrinterBuffer = NULL; _dwPrinterObjectReturned = 0; _dwPrinterObjectCurrentEntry = 0; _dwPrinterObjectTotal = 0; _fPrinterNoMore = 0;
_pServiceBuffer = NULL; _dwServiceObjectReturned = 0; _dwServiceObjectCurrentEntry = 0; _dwServiceObjectTotal = 0; _fServiceNoMore = 0; _dwIndex = 0;
}
CWinNTComputerEnum::CWinNTComputerEnum(ObjectTypeList ObjList): _ComputerName(NULL), _DomainName(NULL), _ADsPath(NULL) { _pObjList = NULL; _pBuffer = NULL; _bNoMore = 0; _dwObjectReturned = 0; _dwObjectTotal = 0; _dwObjectCurrentEntry = 0;
_hLGroupComputer = NULL; _hGGroupComputer = NULL; _dwGroupArrayIndex = 0;
_pPrinterBuffer = NULL; _dwPrinterObjectReturned = 0; _dwPrinterObjectCurrentEntry = 0; _dwPrinterObjectTotal = 0; _fPrinterNoMore = FALSE;
_pServiceBuffer = NULL; _dwServiceObjectReturned = 0; _dwServiceObjectCurrentEntry = 0; _dwServiceObjectTotal = 0; _fServiceNoMore = FALSE; _dwIndex = 0;
}
CWinNTComputerEnum::~CWinNTComputerEnum() { if (_pServiceBuffer) { FreeADsMem(_pServiceBuffer); }
if(_pPrinterBuffer){ FreeADsMem(_pPrinterBuffer); }
if (_hLGroupComputer) {
WinNTCloseComputer(_hLGroupComputer);
}
if (_hGGroupComputer) {
WinNTCloseComputer(_hGGroupComputer); }
if (_ComputerName) { ADsFreeString(_ComputerName); }
if (_ADsPath) { ADsFreeString(_ADsPath); }
if (_DomainName) { ADsFreeString(_DomainName); }
if (_pObjList) {
delete _pObjList; }
}
HRESULT CWinNTComputerEnum::EnumObjects( DWORD ObjectType, ULONG cElements, VARIANT FAR * pvar, ULONG FAR * pcElementFetched ) {
HRESULT hr = S_OK ; DWORD cElementLocal = 0; DWORD cElementGlobal = 0;
switch (ObjectType) {
case WINNT_GROUP_ID:
//
// for backward compatabillity, "group" includes "local group" and
// "global group" during enumeration
//
//
// enum local groups first
//
hr = EnumGroupObjects(WINNT_GROUP_LOCAL, cElements, pvar, &cElementLocal );
if (hr == S_FALSE) {
//
// enum global groups after all local groups have been enumerated
//
hr = EnumGroupObjects(WINNT_GROUP_GLOBAL, cElements-cElementLocal, pvar+cElementLocal, &cElementGlobal ); }
//
// increment instead of assingn: consistent with other switch cases
//
(*pcElementFetched) += (cElementGlobal+cElementLocal);
break;
case WINNT_LOCALGROUP_ID: hr = EnumGroupObjects(WINNT_GROUP_LOCAL, cElements, pvar, pcElementFetched); break;
case WINNT_GLOBALGROUP_ID: hr = EnumGroupObjects(WINNT_GROUP_GLOBAL, cElements, pvar, pcElementFetched); break;
case WINNT_USER_ID: hr = EnumUsers(cElements, pvar, pcElementFetched); break; case WINNT_PRINTER_ID: hr = EnumPrintQueues(cElements, pvar, pcElementFetched); break; case WINNT_SERVICE_ID: hr = EnumServices(cElements, pvar, pcElementFetched); break; default: hr = S_FALSE; } RRETURN_EXP_IF_ERR(hr); }
HRESULT CWinNTComputerEnum::EnumObjects( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { DWORD i; ULONG cRequested = 0; ULONG cFetchedByPath = 0; ULONG cTotalFetched = 0; VARIANT FAR* pPathvar = pvar; HRESULT hr = S_FALSE; DWORD ObjectType;
for (i = 0; i < cElements; i++) { VariantInit(&pvar[i]); } cRequested = cElements;
while (SUCCEEDED(_pObjList->GetCurrentObject(&ObjectType)) && ((hr = EnumObjects(ObjectType, cRequested, pPathvar, &cFetchedByPath)) == S_FALSE )) { pPathvar += cFetchedByPath; cRequested -= cFetchedByPath; cTotalFetched += cFetchedByPath;
cFetchedByPath = 0;
if (FAILED(_pObjList->Next())){ if (pcElementFetched) *pcElementFetched = cTotalFetched; return(ResultFromScode(S_FALSE)); }
}
if (pcElementFetched) { *pcElementFetched = cTotalFetched + cFetchedByPath; }
RRETURN_EXP_IF_ERR(hr); }
HRESULT CWinNTComputerEnum::EnumUsers(ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched) { HRESULT hr = S_OK ; IDispatch *pDispatch = NULL; DWORD i = 0;
while (i < cElements) {
hr = GetUserObject(&pDispatch); if (hr == S_FALSE) { break; }
VariantInit(&pvar[i]); pvar[i].vt = VT_DISPATCH; pvar[i].pdispVal = pDispatch; (*pcElementFetched)++; i++; } return(hr); }
HRESULT CWinNTComputerEnum::GetUserObject(IDispatch ** ppDispatch) { HRESULT hr = S_OK; NTSTATUS Status; PNET_DISPLAY_USER pUserInfo1 = NULL; NET_API_STATUS nasStatus = 0; DWORD dwResumeHandle = 0; WCHAR szBuffer[MAX_PATH];
if (!_pBuffer || (_dwObjectCurrentEntry == _dwObjectReturned)) {
if (_pBuffer) { NetApiBufferFree(_pBuffer); _pBuffer = NULL; }
_dwObjectCurrentEntry = 0; _dwObjectReturned = 0;
wcscpy(szBuffer, L"\\\\"); wcscat(szBuffer, _ComputerName);
nasStatus = NetQueryDisplayInformation( szBuffer, 1, _dwIndex, 1024, MAX_PREFERRED_LENGTH, &_dwObjectReturned, (PVOID *)&_pBuffer ); //
// The following if clause is to handle real errors; anything
// other than ERROR_SUCCESS and ERROR_MORE_DATA
//
if ((nasStatus != ERROR_SUCCESS) && (nasStatus != ERROR_MORE_DATA)) { RRETURN(S_FALSE); }
//
// This one is to handle the termination case - Call completed
// successfully but there is no data to retrieve _pBuffer = NULL
//
if (!_pBuffer) { RRETURN(S_FALSE); }
_dwIndex = ((PNET_DISPLAY_USER)_pBuffer + _dwObjectReturned -1)->usri1_next_index;
}
//
// Now send back the current ovbject
//
pUserInfo1 = (PNET_DISPLAY_USER)_pBuffer; pUserInfo1 += _dwObjectCurrentEntry;
hr = CWinNTUser::CreateUser( _ADsPath, WINNT_COMPUTER_ID, NULL, _ComputerName, pUserInfo1->usri1_name, ADS_OBJECT_BOUND, &(pUserInfo1->usri1_flags), pUserInfo1->usri1_full_name, pUserInfo1->usri1_comment, NULL, IID_IDispatch, _Credentials, (void **)ppDispatch ); BAIL_IF_ERROR(hr); _dwObjectCurrentEntry++;
RRETURN(S_OK);
cleanup: *ppDispatch = NULL; RRETURN(S_FALSE); }
HRESULT CWinNTComputerEnum::EnumPrintQueues( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched )
{ HRESULT hr = S_OK ; IDispatch *pDispatch = NULL; DWORD i = 0;
while (i < cElements) {
hr = GetPrinterObject(&pDispatch); if (hr != S_OK) { break; }
VariantInit(&pvar[i]); pvar[i].vt = VT_DISPATCH; pvar[i].pdispVal = pDispatch; (*pcElementFetched)++; i++; } return(hr); }
HRESULT CWinNTComputerEnum::GetPrinterObject(IDispatch **ppDispatch) { HRESULT hr = S_OK; NTSTATUS Status; NET_API_STATUS nasStatus = NERR_Success; DWORD dwBytesNeeded = 0; DWORD dwBufLen = 0; WCHAR szPrintObjectName[MAX_PATH]; BOOL fStatus; DWORD dwLastError; LPBYTE pMem = NULL; PRINTER_INFO_2 * pPrinterInfo2 = NULL; WCHAR szDomainName[MAX_PATH];
if(!_pPrinterBuffer || (_dwPrinterObjectCurrentEntry == _dwPrinterObjectReturned)){
if (_pPrinterBuffer) {
FreeADsMem(_pPrinterBuffer); _pPrinterBuffer = NULL;
}
if (_fPrinterNoMore) { *ppDispatch = NULL; return(S_FALSE); }
_dwPrinterObjectCurrentEntry = 0; _dwPrinterObjectReturned = 0;
wcscpy(szPrintObjectName, TEXT("\\\\")); wcscat(szPrintObjectName, _ComputerName);
fStatus = WinNTEnumPrinters( PRINTER_ENUM_NAME| PRINTER_ENUM_SHARED, szPrintObjectName, 2, (LPBYTE *)&_pPrinterBuffer, &_dwPrinterObjectReturned );
if (!fStatus || !_dwPrinterObjectReturned) {
_fPrinterNoMore = TRUE; RRETURN(S_FALSE); }
}
pPrinterInfo2 = (PRINTER_INFO_2 *)_pPrinterBuffer; pPrinterInfo2 += _dwPrinterObjectCurrentEntry;
hr = CWinNTPrintQueue::CreatePrintQueue( _ADsPath, WINNT_COMPUTER_ID, szDomainName, _ComputerName, pPrinterInfo2->pShareName, ADS_OBJECT_BOUND, IID_IDispatch, _Credentials, (void **)ppDispatch );
BAIL_IF_ERROR(hr);
_dwPrinterObjectCurrentEntry++;
if(_dwPrinterObjectCurrentEntry == _dwPrinterObjectReturned){ _fPrinterNoMore = TRUE; }
cleanup: if(FAILED(hr)){ *ppDispatch = NULL; #if DBG
EnumCompDebugOut((DEB_TRACE, "hr Failed with value: %ld \n", hr ));
#endif
hr = S_FALSE; // something else may have failed!
} RRETURN_EXP_IF_ERR(hr); }
HRESULT CWinNTComputerEnum::EnumServices( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched )
{ HRESULT hr = S_OK ; IDispatch *pDispatch = NULL; DWORD i = 0;
while (i < cElements) {
hr = GetServiceObject(&pDispatch); if (hr != S_OK) { break; }
VariantInit(&pvar[i]); pvar[i].vt = VT_DISPATCH; pvar[i].pdispVal = pDispatch; (*pcElementFetched)++; i++; } RRETURN(hr);
}
HRESULT CWinNTComputerEnum::GetServiceObject(IDispatch **ppDispatch) {
HRESULT hr = S_OK; LPBYTE pMem = NULL; DWORD dwBytesNeeded = 0; NET_API_STATUS nasStatus = NERR_Success; WCHAR szBuffer[MAX_PATH]; ENUM_SERVICE_STATUS *pqssBuf; WCHAR szDomainName[MAX_PATH];
if(!_pServiceBuffer || (_fServiceNoMore == TRUE )){
if(_pServiceBuffer){ FreeADsMem(_pServiceBuffer); _pServiceBuffer = NULL; }
if (_fServiceNoMore == TRUE) { *ppDispatch = NULL; return(S_FALSE); }
_dwServiceObjectCurrentEntry = 0; _dwServiceObjectReturned = 0;
hr = WinNTEnumServices( _ComputerName, &_dwServiceObjectReturned, &_pServiceBuffer );
BAIL_IF_ERROR(hr);
if(hr == S_FALSE){ _fServiceNoMore = TRUE; *ppDispatch = NULL; goto cleanup; }
}
hr = GetDomainFromPath(_ADsPath, szDomainName); BAIL_IF_ERROR(hr);
pqssBuf = (ENUM_SERVICE_STATUS *)_pServiceBuffer; pqssBuf += _dwServiceObjectCurrentEntry;
hr = CWinNTService::Create(_ADsPath, szDomainName, _ComputerName, pqssBuf->lpServiceName, ADS_OBJECT_BOUND, IID_IDispatch, _Credentials, (void **)ppDispatch);
BAIL_IF_ERROR(hr);
_dwServiceObjectCurrentEntry++;
if(_dwServiceObjectCurrentEntry == _dwServiceObjectReturned){ _fServiceNoMore = TRUE; }
cleanup: if(FAILED(hr)){ #if DBG
EnumCompDebugOut((DEB_TRACE, "hr Failed with value: %ld \n", hr ));
#endif
hr = S_FALSE; } RRETURN(hr); }
//+---------------------------------------------------------------------------
//
// Function: CWinNTComputerEnum::Next
//
// Synopsis: Returns cElements number of requested ADs objects in the
// array supplied in pvar.
//
// Arguments: [cElements] -- The number of elements requested by client
// [pvar] -- ptr to array of VARIANTs to for return objects
// [pcElementFetched] -- if non-NULL, then number of elements
// -- actually returned is placed here
//
// Returns: HRESULT -- S_OK if number of elements requested are returned
// -- S_FALSE if number of elements is < requested
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
STDMETHODIMP CWinNTComputerEnum::Next(ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched) { ULONG cElementFetched = 0; HRESULT hr = S_OK;
hr = EnumObjects(cElements, pvar, &cElementFetched );
if (pcElementFetched) { *pcElementFetched = cElementFetched; } RRETURN_EXP_IF_ERR(hr); }
HRESULT CWinNTComputerEnum::GetGlobalGroupObject( IDispatch ** ppDispatch ) { HRESULT hr = S_OK; LPWINNT_GROUP pWinNTGrp = NULL; LPBYTE pBuffer = NULL; DWORD dwReturned = 0; BOOL dwRet = 0;
if (!_hGGroupComputer) { dwRet = WinNTComputerOpen( _DomainName, _ComputerName, WINNT_COMPUTER_ID, &_hGGroupComputer ); if (!dwRet) { goto error; } }
dwRet = WinNTEnumGlobalGroups( _hGGroupComputer, 1, &pBuffer, &dwReturned ); if (!dwRet) { goto error; }
pWinNTGrp = (LPWINNT_GROUP)pBuffer;
hr = CWinNTGroup::CreateGroup( pWinNTGrp->Parent, WINNT_COMPUTER_ID, pWinNTGrp->Domain, pWinNTGrp->Computer, pWinNTGrp->Name, WINNT_GROUP_GLOBAL, ADS_OBJECT_BOUND, IID_IDispatch, _Credentials, (void **)ppDispatch ); BAIL_ON_FAILURE(hr);
hr = S_OK;
cleanup:
if (pBuffer) {
FreeADsMem(pBuffer); }
RRETURN(hr);
error: *ppDispatch = NULL;
hr = S_FALSE;
goto cleanup; }
HRESULT CWinNTComputerEnum::GetLocalGroupObject( IDispatch ** ppDispatch ) { HRESULT hr = S_OK; LPWINNT_GROUP pWinNTGrp = NULL; LPBYTE pBuffer = NULL; DWORD dwReturned = 0; BOOL dwRet = 0;
if (!_hLGroupComputer) { dwRet = WinNTComputerOpen( _DomainName, _ComputerName, WINNT_COMPUTER_ID, &_hLGroupComputer ); if (!dwRet) { goto error; } }
dwRet = WinNTEnumLocalGroups( _hLGroupComputer, 1, &pBuffer, &dwReturned ); if (!dwRet) { goto error; }
pWinNTGrp = (LPWINNT_GROUP)pBuffer;
hr = CWinNTGroup::CreateGroup( pWinNTGrp->Parent, WINNT_COMPUTER_ID, pWinNTGrp->Domain, pWinNTGrp->Computer, pWinNTGrp->Name, WINNT_GROUP_LOCAL, ADS_OBJECT_BOUND, IID_IDispatch, _Credentials, (void **)ppDispatch );
BAIL_ON_FAILURE(hr);
hr = S_OK;
cleanup:
if (pBuffer) { FreeADsMem(pBuffer);
}
RRETURN(hr);
error: *ppDispatch = NULL;
//
// We missed a member so return E_FAIL if that was the error
// as we would still like to get at the other groups
//
if (hr != E_FAIL) { hr = S_FALSE; }
goto cleanup; }
HRESULT CWinNTComputerEnum::EnumGroupObjects( DWORD ObjectType, ULONG cElements, VARIANT FAR * pvar, ULONG FAR * pcElementFetched ) { HRESULT hr = S_OK ;
switch (ObjectType) {
case WINNT_GROUP_GLOBAL: hr = EnumGlobalGroups(cElements, pvar, pcElementFetched); break;
case WINNT_GROUP_LOCAL: hr = EnumLocalGroups(cElements, pvar, pcElementFetched); break;
default: hr = S_FALSE; } RRETURN(hr); }
extern ULONG GroupTypeArray[];
HRESULT CWinNTComputerEnum::EnumGroups( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { DWORD i; ULONG cRequested = 0; ULONG cFetchedByPath = 0; ULONG cTotalFetched = 0; VARIANT FAR* pPathvar = pvar; HRESULT hr = S_OK; DWORD ObjectType;
for (i = 0; i < cElements; i++) { VariantInit(&pvar[i]); } cRequested = cElements;
while ((GroupTypeArray[_dwGroupArrayIndex] != (ULONG)-1) && ((hr = EnumGroupObjects( GroupTypeArray[_dwGroupArrayIndex], cRequested, pPathvar, &cFetchedByPath)) == S_FALSE )) {
pPathvar += cFetchedByPath; cRequested -= cFetchedByPath; cTotalFetched += cFetchedByPath;
cFetchedByPath = 0;
if (GroupTypeArray[_dwGroupArrayIndex++] == (ULONG)-1){ if (pcElementFetched) *pcElementFetched = cTotalFetched; RRETURN(S_FALSE); }
}
if (pcElementFetched) { *pcElementFetched = cTotalFetched + cFetchedByPath; }
RRETURN(hr); }
HRESULT CWinNTComputerEnum::EnumGlobalGroups( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { HRESULT hr = S_OK ; IDispatch *pDispatch = NULL; DWORD i = 0;
while (i < cElements) {
hr = GetGlobalGroupObject(&pDispatch); if (hr == S_FALSE) { break; }
VariantInit(&pvar[i]); pvar[i].vt = VT_DISPATCH; pvar[i].pdispVal = pDispatch; (*pcElementFetched)++; i++; } return(hr); }
HRESULT CWinNTComputerEnum::EnumLocalGroups( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { HRESULT hr = S_OK ; IDispatch *pDispatch = NULL; DWORD i = 0;
while (i < cElements) {
//
// Need to set it here in case we are getting multiple elements
//
hr = E_FAIL;
//
// We use a while loop in case a get of one of the objects fails
// because it has a long pathname or otherwise
//
while (hr == E_FAIL) { hr = GetLocalGroupObject(&pDispatch); } if (hr == S_FALSE) { break; }
VariantInit(&pvar[i]); pvar[i].vt = VT_DISPATCH; pvar[i].pdispVal = pDispatch; (*pcElementFetched)++; i++; } return(hr); }
|