|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: oleds.odl
//
// Contents: Top level odl file for the ADs project
//
// History: 11-1-95 krishnag Created.
//
//----------------------------------------------------------------------------
#include "winnt.hxx"
#pragma hdrstop
// Class CWinNTComputer
DEFINE_IDispatch_ExtMgr_Implementation(CWinNTComputer) DEFINE_IADsExtension_ExtMgr_Implementation(CWinNTComputer) DEFINE_IADs_TempImplementation(CWinNTComputer) DEFINE_IADs_PutGetImplementation(CWinNTComputer, ComputerClass,gdwComputerTableSize) DEFINE_IADsPropertyList_Implementation(CWinNTComputer,ComputerClass,gdwComputerTableSize)
CWinNTComputer::CWinNTComputer(): _pDispMgr(NULL), _pExtMgr(NULL), _pPropertyCache(NULL), _DomainName(NULL), _fCredentialsBound(FALSE), _hrBindingResult(S_OK), _fNoWKSTA(FALSE) { VariantInit(&_vFilter); }
HRESULT CWinNTComputer::CreateComputer( BSTR Parent, BSTR DomainName, BSTR ComputerName, DWORD dwObjectState, REFIID riid, CWinNTCredentials& Credentials, void **ppvObj ) { CWinNTComputer FAR * pComputer = NULL; HRESULT hr = S_OK;
hr = AllocateComputerObject(&pComputer); BAIL_ON_FAILURE(hr);
ADsAssert(pComputer->_pDispMgr);
hr = pComputer->InitializeCoreObject( Parent, ComputerName, COMPUTER_CLASS_NAME, COMPUTER_SCHEMA_NAME, CLSID_WinNTComputer, dwObjectState ); BAIL_ON_FAILURE(hr);
hr = ADsAllocString( DomainName, &pComputer->_DomainName); BAIL_ON_FAILURE(hr);
if (DomainName == NULL) { pComputer->_fNoWKSTA = TRUE; }
//
// The computer is a special case for using credentials. If it is
// created from a Domain object, the credentials will have the server
// name of the Domain's DC. So when we go to RefServer the computer
// object, it has a different machine name, which should ordinarily fail.
// We obviously don't want that, so we tell RefServer to allow a change
// of server names.
//
// We also don't want to try to bind to each computer in a domain, since
// most computers won't actually be examined in detail. So we don't
// RefServer until we perform an operation on this object.
//
pComputer->_Credentials = Credentials;
//
// Load ext mgr and extensions
//
hr = ADSILoadExtensionManager( COMPUTER_CLASS_NAME, (IADsComputer *) pComputer, pComputer->_pDispMgr, Credentials, &pComputer->_pExtMgr ); BAIL_ON_FAILURE(hr);
ADsAssert(pComputer->_pExtMgr);
// check if the call is from UMI
if(Credentials.GetFlags() & ADS_AUTH_RESERVED) { //
// we do not pass riid to InitUmiObject below. This is because UMI object
// does not support IDispatch. There are several places in ADSI code where
// riid passed into this function is defaulted to IID_IDispatch -
// IADsContainer::Create for example. To handle these cases, we always
// request IID_IUnknown from the UMI object. Subsequent code within UMI
// will QI for the appropriate interface.
//
if(2 == pComputer->_dwNumComponents) { pComputer->_CompClasses[0] = L"Domain"; pComputer->_CompClasses[1] = L"Computer"; } else if(1 == pComputer->_dwNumComponents) { pComputer->_CompClasses[0] = L"Computer"; } else BAIL_ON_FAILURE(hr = UMI_E_FAIL);
hr = pComputer->InitUmiObject( pComputer->_Credentials, ComputerClass, gdwComputerTableSize, pComputer->_pPropertyCache, (IUnknown *)(INonDelegatingUnknown *) pComputer, pComputer->_pExtMgr, IID_IUnknown, ppvObj ); BAIL_ON_FAILURE(hr);
//
// UMI object was created and the interface was obtained successfully.
// UMI object now has a reference to the inner unknown of IADs, since
// the call to Release() below is not going to be made in this case.
//
RRETURN(hr); }
hr = pComputer->QueryInterface(riid, ppvObj); BAIL_ON_FAILURE(hr);
pComputer->Release();
RRETURN(hr);
error:
delete pComputer; RRETURN_EXP_IF_ERR(hr); }
CWinNTComputer::~CWinNTComputer( ) { VariantClear(&_vFilter);
if (_DomainName) { ADsFreeString(_DomainName); }
delete _pExtMgr; // created last, destroyed first
delete _pDispMgr;
delete _pPropertyCache; }
//----------------------------------------------------------------------------
// Function: QueryInterface
//
// Synopsis: If this object is aggregated within another object, then
// all calls will delegate to the outer object. Otherwise, the
// non-delegating QI is called
//
// Arguments:
//
// iid interface requested
// ppInterface Returns pointer to interface requested. NULL if interface
// is not supported.
//
// Returns: S_OK on success. Error code otherwise.
//
// Modifies: *ppInterface to return interface pointer
//
//----------------------------------------------------------------------------
STDMETHODIMP CWinNTComputer::QueryInterface( REFIID iid, LPVOID *ppInterface ) { if(_pUnkOuter != NULL) RRETURN(_pUnkOuter->QueryInterface( iid, ppInterface ));
RRETURN(NonDelegatingQueryInterface( iid, ppInterface )); }
//----------------------------------------------------------------------------
// Function: AddRef
//
// Synopsis: IUnknown::AddRef. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating AddRef is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWinNTComputer::AddRef(void) { if(_pUnkOuter != NULL) RRETURN(_pUnkOuter->AddRef());
RRETURN(NonDelegatingAddRef()); }
//----------------------------------------------------------------------------
// Function: Release
//
// Synopsis: IUnknown::Release. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating Release is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWinNTComputer::Release(void) { if(_pUnkOuter != NULL) RRETURN(_pUnkOuter->Release());
RRETURN(NonDelegatingRelease()); }
//----------------------------------------------------------------------------
STDMETHODIMP CWinNTComputer::NonDelegatingQueryInterface( REFIID iid, LPVOID FAR* ppv ) { HRESULT hr = S_OK;
if (ppv == NULL) { RRETURN(E_POINTER); }
if (IsEqualIID(iid, IID_IUnknown)) { *ppv = (IADsComputer FAR *) this; } else if (IsEqualIID(iid, IID_IADsComputer)) { *ppv = (IADsComputer FAR *) this; } else if (IsEqualIID(iid, IID_IADsComputerOperations)) { *ppv = (IADsComputerOperations FAR *) this; } else if (IsEqualIID(iid, IID_IADsContainer)) { *ppv = (IADsContainer FAR *) this; } else if (IsEqualIID(iid, IID_IADsPropertyList)) { *ppv = (IADsPropertyList FAR *) this; } else if (IsEqualIID(iid, IID_IADs)) { *ppv = (IADsComputer FAR *) this; } else if (IsEqualIID(iid, IID_IDispatch)) { *ppv = (IADsComputer FAR *) this; } else if (IsEqualIID(iid, IID_ISupportErrorInfo)) { *ppv = (ISupportErrorInfo FAR *) this; } else if( (_pDispatch != NULL) && IsEqualIID(iid, IID_IADsExtension) ) { *ppv = (IADsExtension *) this; } else if (_pExtMgr) { RRETURN( _pExtMgr->QueryInterface(iid, ppv)); } else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return NOERROR; }
HRESULT CWinNTComputer::InterfaceSupportsErrorInfo( THIS_ REFIID riid ) { if (IsEqualIID(riid, IID_IADs) || IsEqualIID(riid, IID_IADsComputer) || IsEqualIID(riid, IID_IADsComputerOperations) || IsEqualIID(riid, IID_IADsContainer) || IsEqualIID(riid, IID_IADsPropertyList)) { RRETURN(S_OK); } else { RRETURN(S_FALSE); } }
HRESULT CWinNTComputer::RefCredentials() { if (!_fCredentialsBound) { //
// Only try it once, regardless of whether we succeed.
//
_fCredentialsBound = TRUE;
//
// Also let us rebind to a different server (the TRUE flag).
//
_hrBindingResult = _Credentials.RefServer(_Name, TRUE); }
//
// We also want to return the same value on each call; if we failed to
// bind, this object shouldn't be allowed to do anything.
//
RRETURN_EXP_IF_ERR(_hrBindingResult); }
/* IADs methods */
STDMETHODIMP CWinNTComputer::SetInfo(THIS) { HRESULT hr = S_OK; NET_API_STATUS nasStatus; WCHAR szHostServerName[MAX_PATH];
// We should ref the credentials only if the computer exists
// otherwise the call will fail.
if (GetObjectState() != ADS_OBJECT_UNBOUND) { BAIL_ON_FAILURE(hr = RefCredentials()); }
if (GetObjectState() == ADS_OBJECT_UNBOUND) {
hr = WinNTGetCachedDCName( _DomainName, szHostServerName, _Credentials.GetFlags() ); BAIL_ON_FAILURE(hr);
hr = WinNTCreateComputer( (szHostServerName + 2), _Name ); BAIL_ON_FAILURE(hr);
SetObjectState(ADS_OBJECT_BOUND);
}else {
RRETURN_EXP_IF_ERR(E_NOTIMPL); }
if(SUCCEEDED(hr)) _pPropertyCache->ClearModifiedFlags();
error:
RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CWinNTComputer::GetInfo(THIS) {
_pPropertyCache->flushpropcache();
RRETURN(GetInfo(4, TRUE)); }
STDMETHODIMP CWinNTComputer::ImplicitGetInfo(THIS) { RRETURN(GetInfo(4, FALSE)); }
/* IADsContainer methods */
STDMETHODIMP CWinNTComputer::get_Count(long FAR* retval) { RRETURN_EXP_IF_ERR(E_NOTIMPL); }
STDMETHODIMP CWinNTComputer::get_Filter(THIS_ VARIANT FAR* pVar) { HRESULT hr; VariantInit(pVar); hr = VariantCopy(pVar, &_vFilter); RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CWinNTComputer::put_Filter(THIS_ VARIANT Var) { HRESULT hr; hr = VariantCopy(&_vFilter, &Var); RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CWinNTComputer::put_Hints(THIS_ VARIANT Var) { RRETURN_EXP_IF_ERR( E_NOTIMPL); }
STDMETHODIMP CWinNTComputer::get_Hints(THIS_ VARIANT FAR* pVar) { RRETURN_EXP_IF_ERR(E_NOTIMPL); }
STDMETHODIMP CWinNTComputer::GetObject( THIS_ BSTR ClassName, BSTR RelativeName, IDispatch * FAR* ppObject ) { WCHAR szBuffer[MAX_PATH]; DWORD dwLength = 0; HRESULT hr = S_OK;
if (!RelativeName || !*RelativeName) { RRETURN_EXP_IF_ERR(E_ADS_UNKNOWN_OBJECT); }
// Make sure we have proper credentials.
BAIL_ON_FAILURE(hr = RefCredentials());
//
// Length of ADsPath, the relative name and
// +2 for / and \0
//
dwLength = wcslen(_ADsPath) + wcslen(RelativeName) + 2; if ( dwLength > MAX_PATH) { RRETURN(hr = E_ADS_BAD_PARAMETER); }
wcscpy(szBuffer, _ADsPath);
wcscat(szBuffer, L"/"); wcscat(szBuffer, RelativeName);
if (ClassName) { //
// +1 for the ",".
//
dwLength += wcslen(ClassName) + 1; //
// See if this will cause a buffer overflow.
//
if (dwLength > MAX_PATH) { BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER); }
wcscat(szBuffer,L","); wcscat(szBuffer, ClassName); }
hr = ::GetObject( szBuffer, (LPVOID *)ppObject, _Credentials ); BAIL_ON_FAILURE(hr);
error:
RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CWinNTComputer::get__NewEnum(THIS_ IUnknown * FAR* retval) { HRESULT hr; IUnknown FAR* punkEnum=NULL; IEnumVARIANT * penum = NULL;
*retval = NULL;
// Make sure we have proper credentials.
BAIL_ON_FAILURE(hr = RefCredentials());
hr = CWinNTComputerEnum::Create( (CWinNTComputerEnum **)&penum, _ADsPath, _DomainName, _Name, _vFilter, _Credentials ); BAIL_ON_FAILURE(hr);
hr = penum->QueryInterface( IID_IUnknown, (VOID FAR* FAR*)retval ); BAIL_ON_FAILURE(hr);
if (penum) { penum->Release(); }
RRETURN(NOERROR);
error:
if (penum) { delete penum; }
RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CWinNTComputer::Create( THIS_ BSTR ClassName, BSTR RelativeName, IDispatch * FAR* ppObject ) { ULONG ObjectType = 0; HRESULT hr; POBJECTINFO pObjectInfo = NULL;
// Make sure we have proper credentials.
BAIL_ON_FAILURE(hr = RefCredentials());
hr = GetObjectType(gpFilters, gdwMaxFilters, ClassName, (PDWORD)&ObjectType ); BAIL_ON_FAILURE(hr);
hr = BuildObjectInfo(_ADsPath, RelativeName, &pObjectInfo ); BAIL_ON_FAILURE(hr);
switch (ObjectType) {
case WINNT_USER_ID:
hr = CWinNTUser::CreateUser(_ADsPath, WINNT_COMPUTER_ID, _DomainName, _Name, RelativeName, ADS_OBJECT_UNBOUND, IID_IDispatch, _Credentials, (void **)ppObject ); break;
case WINNT_PRINTER_ID: hr = CWinNTPrintQueue::CreatePrintQueue(_ADsPath, WINNT_COMPUTER_ID, pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], RelativeName, ADS_OBJECT_UNBOUND, IID_IDispatch, _Credentials, (void**)ppObject ); break;
//
// default "group" to local group in computer container for backward
// compatiblity
//
case WINNT_GROUP_ID: hr = CWinNTGroup::CreateGroup( _ADsPath, WINNT_COMPUTER_ID, _DomainName, _Name, RelativeName, WINNT_GROUP_LOCAL, ADS_OBJECT_UNBOUND, IID_IDispatch, _Credentials, (void **)ppObject ); break;
case WINNT_SERVICE_ID: hr = CWinNTService::Create(_ADsPath, pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], RelativeName, ADS_OBJECT_UNBOUND, IID_IDispatch, _Credentials, (void**)ppObject );
break;
default:
hr = E_ADS_UNKNOWN_OBJECT; break; }
BAIL_ON_FAILURE(hr);
error:
if (pObjectInfo) { FreeObjectInfo(pObjectInfo); }
RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CWinNTComputer::Delete( BSTR bstrClassName, BSTR bstrSourceName ) { ULONG ObjectType = 0; POBJECTINFO pObjectInfo = NULL; BOOL fStatus = FALSE; HRESULT hr = S_OK; WCHAR szUncServerName[MAX_PATH];
// Check if the input parameters are valid
if (bstrClassName == NULL || bstrSourceName == NULL) { BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER); }
// Make sure we have proper credentials.
BAIL_ON_FAILURE(hr = RefCredentials());
hr = GetObjectType(gpFilters, gdwMaxFilters, bstrClassName, (PDWORD)&ObjectType );
BAIL_ON_FAILURE(hr);
hr = BuildObjectInfo( _ADsPath, bstrSourceName, &pObjectInfo );
BAIL_ON_FAILURE(hr);
switch (ObjectType) {
case WINNT_USER_ID:
hr = WinNTDeleteUser(pObjectInfo, _Credentials);
// This might be the case where the user is on the local
// machine and there workstation is not available
if (FAILED(hr) && _fNoWKSTA) { // We need to go ahead and whack this user
hr = WinNTDeleteUser( pObjectInfo->ComponentArray[0], bstrSourceName ); }
break;
case WINNT_GROUP_ID:
//
// for backward compatability: allow user to delete by classname "group"
//
hr = WinNTDeleteGroup(pObjectInfo, WINNT_GROUP_EITHER, _Credentials);
if (FAILED(hr) && _fNoWKSTA) { //
// We need to whack this group.
//
hr = WinNTDeleteLocalGroup( pObjectInfo->ComponentArray[0], bstrSourceName ); } break;
//
// Global Group and LocalGroup ID's will now goto default
//
case WINNT_PRINTER_ID:
hr = WinNTDeletePrinter(pObjectInfo); break;
case WINNT_SERVICE_ID:
hr = WinNTDeleteService(pObjectInfo); break;
default:
hr = E_ADS_UNKNOWN_OBJECT; break; }
BAIL_ON_FAILURE(hr);
error:
if (pObjectInfo) { FreeObjectInfo(pObjectInfo); } RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CWinNTComputer::CopyHere( THIS_ BSTR SourceName, BSTR NewName, IDispatch * FAR* ppObject ) { RRETURN_EXP_IF_ERR(E_NOTIMPL); }
/* IADsComputer methods */
HRESULT CWinNTComputer::AllocateComputerObject( CWinNTComputer ** ppComputer ) { CWinNTComputer FAR * pComputer = NULL; CPropertyCache FAR * pPropertyCache = NULL; CAggregatorDispMgr FAR * pDispMgr = NULL; HRESULT hr = S_OK;
pComputer = new CWinNTComputer(); if (pComputer == NULL) { hr = E_OUTOFMEMORY; } BAIL_ON_FAILURE(hr);
pDispMgr = new CAggregatorDispMgr; if (pDispMgr == NULL) { hr = E_OUTOFMEMORY; } BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr, LIBID_ADs, IID_IADsComputer, (IADsComputer *)pComputer, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr, LIBID_ADs, IID_IADsComputerOperations, (IADsComputerOperations *)pComputer, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr, LIBID_ADs, IID_IADsContainer, (IADsContainer *)pComputer, DISPID_NEWENUM ); BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr, LIBID_ADs, IID_IADsPropertyList, (IADsPropertyList *)pComputer, DISPID_VALUE ); BAIL_ON_FAILURE(hr);
hr = CPropertyCache::createpropertycache( ComputerClass, gdwComputerTableSize, (CCoreADsObject *)pComputer, &pPropertyCache ); BAIL_ON_FAILURE(hr);
pDispMgr->RegisterPropertyCache( pPropertyCache );
pComputer->_pPropertyCache = pPropertyCache; pComputer->_pDispMgr = pDispMgr; *ppComputer = pComputer;
RRETURN(hr);
error:
delete pPropertyCache; delete pDispMgr; delete pComputer;
RRETURN(hr);
}
WCHAR *szCurrentVersion = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"; WCHAR *szHardwareInfo = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
STDMETHODIMP CWinNTComputer::GetInfo( THIS_ DWORD dwApiLevel, BOOL fExplicit ) {
COMP_INFO_4 CompInfo4; PCOMP_INFO_4 pCompInfo4 = &CompInfo4; DWORD dwRet = 0; HKEY hKey = NULL; HKEY hCurrentKey = NULL; HKEY hHardwareKey = NULL; DWORD cbData = 0; HRESULT hr = S_OK; WCHAR lpszServerName[MAX_PATH]; NET_API_STATUS nasStatus; LPSERVER_INFO_101 lpServerInfo =NULL; WCHAR szMajorVersion[20]; WCHAR szMinorVersion[20];
// Make sure we have proper credentials.
BAIL_ON_FAILURE(hr = RefCredentials());
memset(pCompInfo4, 0, sizeof(COMP_INFO_4)); switch (dwApiLevel) { case 4:
hr = MakeUncName(_Name, lpszServerName); BAIL_ON_FAILURE(hr);
dwRet = RegConnectRegistry( lpszServerName, HKEY_LOCAL_MACHINE, &hKey ); if (dwRet !=ERROR_SUCCESS) { hr = HRESULT_FROM_WIN32(dwRet); BAIL_ON_FAILURE(hr); }
dwRet = RegOpenKeyEx( hKey, szCurrentVersion, 0, KEY_READ, &hCurrentKey );
if (dwRet != ERROR_SUCCESS) { hr = HRESULT_FROM_WIN32(dwRet); BAIL_ON_FAILURE(hr); }
wcscpy(pCompInfo4->szOS, L"Windows NT");
nasStatus = NetServerGetInfo(lpszServerName, 101, (LPBYTE *)&lpServerInfo );
hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
_itow( lpServerInfo->sv101_version_major, szMajorVersion, 10 );
_itow( lpServerInfo->sv101_version_minor, szMinorVersion, 10 );
wcscpy( pCompInfo4->szOSVersion, szMajorVersion );
wcscat( pCompInfo4->szOSVersion, L"." );
wcscat( pCompInfo4->szOSVersion, szMinorVersion );
cbData = sizeof(pCompInfo4->szOwner); dwRet = RegQueryValueEx( hCurrentKey, L"RegisteredOwner", NULL, NULL, (LPBYTE)pCompInfo4->szOwner, &cbData );
cbData = sizeof(pCompInfo4->szDivision), dwRet = RegQueryValueEx( hCurrentKey, L"RegisteredOrganization", NULL, NULL, (LPBYTE)pCompInfo4->szDivision, &cbData );
cbData = sizeof(pCompInfo4->szProcessorCount), dwRet = RegQueryValueEx( hCurrentKey, L"CurrentType", NULL, NULL, (LPBYTE)pCompInfo4->szProcessorCount, &cbData );
dwRet = RegOpenKeyEx( hKey, szHardwareInfo, 0, KEY_READ, &hHardwareKey ); if (dwRet != ERROR_SUCCESS) { hr = HRESULT_FROM_WIN32(dwRet); BAIL_ON_FAILURE(hr); }
cbData = sizeof(pCompInfo4->szProcessor), dwRet = RegQueryValueEx( hHardwareKey, L"Identifier", NULL, NULL, (LPBYTE)pCompInfo4->szProcessor, &cbData );
hr = UnMarshall_Level4(fExplicit, pCompInfo4);
error: if(lpServerInfo) { NetApiBufferFree(lpServerInfo); }
if (hCurrentKey) { RegCloseKey(hCurrentKey); }
if (hHardwareKey) { RegCloseKey(hHardwareKey); }
if (hKey) { RegCloseKey(hKey); }
RRETURN_EXP_IF_ERR(hr);
default: RRETURN_EXP_IF_ERR(E_FAIL); }
}
HRESULT CWinNTComputer::UnMarshall_Level4( BOOL fExplicit, LPCOMP_INFO_4 pCompInfo4 ) { HRESULT hr = S_OK;
hr = SetLPTSTRPropertyInCache( _pPropertyCache, TEXT("OperatingSystem"), pCompInfo4->szOS, fExplicit );
hr = SetLPTSTRPropertyInCache( _pPropertyCache, TEXT("OperatingSystemVersion"), pCompInfo4->szOSVersion, fExplicit );
hr = SetLPTSTRPropertyInCache( _pPropertyCache, TEXT("Owner"), pCompInfo4->szOwner, fExplicit );
hr = SetLPTSTRPropertyInCache( _pPropertyCache, TEXT("Division"), pCompInfo4->szDivision, fExplicit );
hr = SetLPTSTRPropertyInCache( _pPropertyCache, TEXT("ProcessorCount"), pCompInfo4->szProcessorCount, fExplicit );
hr = SetLPTSTRPropertyInCache( _pPropertyCache, TEXT("Processor"), pCompInfo4->szProcessor, fExplicit );
hr = SetLPTSTRPropertyInCache( _pPropertyCache, TEXT("Name"), _Name, fExplicit );
RRETURN(S_OK); }
STDMETHODIMP CWinNTComputer::Status( IDispatch * FAR * ppObject ) { RRETURN_EXP_IF_ERR(E_NOTIMPL); }
STDMETHODIMP CWinNTComputer::Shutdown( VARIANT_BOOL bReboot ) { RRETURN_EXP_IF_ERR(E_NOTIMPL); }
HRESULT RenameUserObject( POBJECTINFO pObjectInfo, LPWSTR szNewName, CWinNTCredentials& Credentials ) { WCHAR szHostServerName[MAX_PATH]; LPUSER_INFO_0 lpUI = NULL; HRESULT hr; WCHAR lpszUncName[MAX_PATH]; NET_API_STATUS nasStatus; DWORD dwParam = 0; USER_INFO_0 userinfo; memset(&userinfo, 0, sizeof(USER_INFO_0));
switch (pObjectInfo->NumComponents) { case 2:
//
// if 2 components then either it is user in computer
// or user in domain.
hr = WinNTGetCachedDCName( pObjectInfo->ComponentArray[0], szHostServerName, Credentials.GetFlags() );
if(SUCCEEDED(hr)){
nasStatus = NetUserGetInfo(szHostServerName, pObjectInfo->ComponentArray[1], 1, (LPBYTE *)&lpUI);
hr = HRESULT_FROM_WIN32(nasStatus);
userinfo.usri0_name = szNewName; nasStatus = NetUserSetInfo(szHostServerName, pObjectInfo->ComponentArray[1], 0, (LPBYTE)&userinfo, &dwParam); hr = HRESULT_FROM_WIN32(nasStatus); }
//
// if we are here with hr != S_OK it could be that we have
// user in a computer.
//
if(FAILED(hr)){ hr = ValidateComputerParent( NULL, pObjectInfo->ComponentArray[0], Credentials );
BAIL_ON_FAILURE(hr);
MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName);
nasStatus = NetUserGetInfo(lpszUncName, pObjectInfo->ComponentArray[1], 0, (LPBYTE *)&lpUI);
hr = HRESULT_FROM_WIN32(nasStatus);
userinfo.usri0_name = szNewName; nasStatus = NetUserSetInfo(lpszUncName, pObjectInfo->ComponentArray[1], 0, (LPBYTE)&userinfo, &dwParam); hr = HRESULT_FROM_WIN32(nasStatus);
}
BAIL_ON_FAILURE(hr);
break;
case 3:
//
// user in domain\computer or user in workgroup\computer
//
hr = ValidateComputerParent(pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], Credentials); BAIL_ON_FAILURE(hr);
MakeUncName(pObjectInfo->ComponentArray[1], lpszUncName);
nasStatus = NetUserGetInfo(lpszUncName, pObjectInfo->ComponentArray[2], 0, (LPBYTE *)&lpUI);
hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
userinfo.usri0_name = szNewName; nasStatus = NetUserSetInfo(lpszUncName, pObjectInfo->ComponentArray[2], 0, (LPBYTE)&userinfo, &dwParam); hr = HRESULT_FROM_WIN32(nasStatus); break;
default: RRETURN(E_ADS_BAD_PATHNAME); }
error: if (lpUI) { NetApiBufferFree((LPBYTE)lpUI); }
RRETURN(hr);
}
HRESULT RenameGroupObject( POBJECTINFO pObjectInfo, LPWSTR szNewName, CWinNTCredentials& Credentials ) { WCHAR szHostServerName[MAX_PATH]; LPGROUP_INFO_0 lpGI = NULL; HRESULT hr; WCHAR lpszUncName[MAX_PATH]; NET_API_STATUS nasStatus; GROUP_INFO_0 groupinfo; memset(&groupinfo, 0, sizeof(GROUP_INFO_0)); groupinfo.grpi0_name = szNewName; DWORD dwParam;
switch (pObjectInfo->NumComponents) { case 2: //
// if 2 components then either it is a group in computer
// or group in domain.
//
hr = WinNTGetCachedDCName( pObjectInfo->ComponentArray[0], szHostServerName, Credentials.GetFlags() );
if(SUCCEEDED(hr)){ //
// must be a group in a domain
//
hr = ValidateGlobalGroupObject( szHostServerName, &(pObjectInfo->ComponentArray[1]), Credentials );
if (FAILED(hr)) { hr = ValidateLocalGroupObject( szHostServerName, &(pObjectInfo->ComponentArray[1]), Credentials );
if(SUCCEEDED(hr)){ nasStatus = NetLocalGroupSetInfo(szHostServerName, pObjectInfo->ComponentArray[1], 0, (LPBYTE)&groupinfo, &dwParam); hr = HRESULT_FROM_WIN32(nasStatus); }
}else{ nasStatus = NetGroupSetInfo(szHostServerName, pObjectInfo->ComponentArray[1], 0, (LPBYTE)&groupinfo, &dwParam); hr = HRESULT_FROM_WIN32(nasStatus); } }
if(FAILED(hr)){ //
// potentially a group in a computer
//
hr = ValidateComputerParent(NULL, pObjectInfo->ComponentArray[0], Credentials); BAIL_ON_FAILURE(hr);
//
// group in a computer
//
MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName);
hr = ValidateGlobalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[1]), Credentials );
if (FAILED(hr)) {
hr = ValidateLocalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[1]), Credentials );
BAIL_ON_FAILURE(hr); nasStatus = NetLocalGroupSetInfo(lpszUncName, pObjectInfo->ComponentArray[1], 0, (LPBYTE)&groupinfo, &dwParam); hr = HRESULT_FROM_WIN32(nasStatus);
}else{ nasStatus = NetGroupSetInfo(lpszUncName, pObjectInfo->ComponentArray[1], 0, (LPBYTE)&groupinfo, &dwParam); hr = HRESULT_FROM_WIN32(nasStatus); } } break;
case 3:
//
// if there are 3 components then we must have parentid
// WINNT_COMPUTER_ID
//
hr = ValidateComputerParent(pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], Credentials);
BAIL_ON_FAILURE(hr);
MakeUncName( pObjectInfo->ComponentArray[1], lpszUncName );
hr = ValidateGlobalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[2]), Credentials );
if (FAILED(hr)) {
hr = ValidateLocalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[2]), Credentials );
BAIL_ON_FAILURE(hr); nasStatus = NetLocalGroupSetInfo(lpszUncName, pObjectInfo->ComponentArray[2], 0, (LPBYTE)&groupinfo, &dwParam); hr = HRESULT_FROM_WIN32(nasStatus);
}else{ nasStatus = NetGroupSetInfo(lpszUncName, pObjectInfo->ComponentArray[2], 0, (LPBYTE)&groupinfo, &dwParam); hr = HRESULT_FROM_WIN32(nasStatus); } break;
default: RRETURN(E_ADS_BAD_PATHNAME); }
error: if (lpGI) { NetApiBufferFree((LPBYTE)lpGI); }
RRETURN(hr);
}
HRESULT CompareBasePath(POBJECTINFO pObjectInfo, POBJECTINFO pObjectInfoParent) { HRESULT hr = S_OK; DWORD i;
if (wcscmp(pObjectInfo->ProviderName, pObjectInfoParent->ProviderName) != 0) { hr = E_FAIL; BAIL_ON_FAILURE(hr); }
if (pObjectInfo->NumComponents != pObjectInfoParent->NumComponents+1) { hr = E_FAIL; BAIL_ON_FAILURE(hr); }
for (i=0;i<pObjectInfoParent->NumComponents;i++) { if (wcscmp(pObjectInfo->ComponentArray[i], pObjectInfoParent->ComponentArray[i]) != 0) { hr = E_FAIL; BAIL_ON_FAILURE(hr); } }
error: return hr; }
HRESULT MoveUserGroupObject( THIS_ BSTR SourceName, BSTR NewName, BSTR bstrParentADsPath, CWinNTCredentials& Credentials, IDispatch * FAR* ppObject ) { HRESULT hr = S_OK; POBJECTINFO pObjectInfo = NULL; POBJECTINFO pObjectInfoParent = NULL;
if ((!SourceName || *SourceName == NULL) || (!NewName || *NewName == NULL)) { hr = E_ADS_BAD_PARAMETER; BAIL_IF_ERROR(hr); }
hr = BuildObjectInfo( SourceName, &pObjectInfo ); BAIL_IF_ERROR(hr);
hr = BuildObjectInfo( bstrParentADsPath, &pObjectInfoParent ); BAIL_IF_ERROR(hr);
hr = CompareBasePath(pObjectInfo, pObjectInfoParent); BAIL_IF_ERROR(hr);
hr = ValidateProvider(pObjectInfo); BAIL_IF_ERROR(hr);
// check if the call is from UMI. If so, the old path will have a class
// specified in it. Try to rename the object of that class, as opposed
// to trying to trying to rename a user first and then rename a group.
if(Credentials.GetFlags() & ADS_AUTH_RESERVED) { if(pObjectInfo->ObjectType == TOKEN_USER) { hr = RenameUserObject( pObjectInfo, NewName, Credentials ); } else if(pObjectInfo->ObjectType == TOKEN_GROUP) { hr = RenameGroupObject( pObjectInfo, NewName, Credentials ); } else hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); } else { hr = RenameUserObject( pObjectInfo, NewName, Credentials ); if (FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_BAD_USERNAME) && hr != HRESULT_FROM_WIN32(NERR_UserExists) && hr != HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) ) {
hr = RenameGroupObject( pObjectInfo, NewName, Credentials );
if (hr == HRESULT_FROM_WIN32(NERR_GroupNotFound)) { //
// The object to move wasn't a group or user
//
hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); } } } // else
BAIL_ON_FAILURE(hr);
if (pObjectInfo) { FreeObjectInfo(pObjectInfo); }
hr = BuildObjectInfo( bstrParentADsPath, NewName, &pObjectInfo ); BAIL_IF_ERROR(hr);
hr = HeuristicGetObject( pObjectInfo, (void**)ppObject, Credentials); BAIL_IF_ERROR(hr);
cleanup: error: if (pObjectInfo) { FreeObjectInfo(pObjectInfo); } if (pObjectInfoParent) { FreeObjectInfo(pObjectInfoParent); } return hr; }
STDMETHODIMP CWinNTComputer::MoveHere( THIS_ BSTR SourceName, BSTR NewName, IDispatch * FAR* ppObject ) { return MoveUserGroupObject(SourceName, NewName, _ADsPath, _Credentials, ppObject); }
|