|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: getobj.cxx
//
// Contents: Windows NT 3.5 GetObject functionality
//
// History:
//----------------------------------------------------------------------------
#include "winnt.hxx"
#pragma hdrstop
extern WCHAR * szWinNTPrefix;
//+---------------------------------------------------------------------------
// Function: GetObject
//
// Synopsis: Called by ResolvePathName to return an object
//
// Arguments: [LPWSTR szBuffer]
// [LPVOID *ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT GetObject( LPWSTR szBuffer, LPVOID *ppObject, CWinNTCredentials& Credentials ) { OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; CLexer Lexer(szBuffer); HRESULT hr;
memset(pObjectInfo, 0, sizeof(OBJECTINFO)); hr = Object(&Lexer, pObjectInfo); BAIL_IF_ERROR(hr);
hr = ValidateProvider(pObjectInfo); BAIL_IF_ERROR(hr);
switch (pObjectInfo->ObjectType) { case TOKEN_DOMAIN: hr = GetDomainObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_USER: hr = GetUserObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_COMPUTER: hr = GetComputerObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_PRINTER: hr = GetPrinterObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_SERVICE: hr = GetServiceObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_FILESERVICE: hr = GetFileServiceObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_GROUP: hr = GetGroupObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_LOCALGROUP: hr = E_ADS_BAD_PATHNAME; //hr = GetLocalGroupObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_GLOBALGROUP: hr = E_ADS_BAD_PATHNAME; //hr = GetGlobalGroupObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_FILESHARE: hr = GetFileShareObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_SCHEMA: hr = GetSchemaObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_CLASS: hr = GetClassObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_PROPERTY: hr = GetPropertyObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_SYNTAX: hr = GetSyntaxObject(pObjectInfo, ppObject, Credentials); break;
case TOKEN_WORKGROUP: hr = GetWorkGroupObject(pObjectInfo, ppObject, Credentials); break;
default: hr = HeuristicGetObject(pObjectInfo, ppObject, Credentials); break; }
cleanup:
FreeObjectInfo( &ObjectInfo, TRUE ); RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetDomainObject
//
// Synopsis: called by GetObject
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT GetNamespaceObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr;
hr = ValidateNamespaceObject( pObjectInfo ); BAIL_ON_FAILURE(hr);
// check if the call is from UMI
if(Credentials.GetFlags() & ADS_AUTH_RESERVED) { hr = CWinNTNamespace::CreateNamespace( L"ADs:", L"WinNT:", ADS_OBJECT_BOUND, IID_IUnknown, Credentials, ppObject ); } else { // came in through ADSI
hr = CoCreateInstance(CLSID_WinNTNamespace, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)ppObject ); }
error:
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetDomainObject
//
// Synopsis: called by GetObject
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT GetDomainObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr; IUnknown *pUnknown = NULL; IADs *pADs = NULL; NET_API_STATUS nasStatus; WCHAR szHostServerName[MAX_PATH]; WCHAR ADsParent[MAX_ADS_PATH]; WCHAR szSAMName[MAX_ADS_PATH];
szSAMName[0] = L'\0';
*ppObject = NULL;
if (pObjectInfo->NumComponents != 1) { RRETURN(E_ADS_INVALID_DOMAIN_OBJECT); }
//
// Verify that this object is really a domain
//
// We can try and ref the domain here but it will
// anyway end up in WinNTGetCachedDCName call in
// CWinNTCredentials::RefDomain, so there is no point in
// doing that
hr = WinNTGetCachedDCName( pObjectInfo->ComponentArray[0], szHostServerName, Credentials.GetFlags() ); BAIL_ON_FAILURE(hr);
if (szSAMName[0] != L'\0') { if (pObjectInfo->ComponentArray[0]) { FreeADsStr(pObjectInfo->ComponentArray[0]); }
pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName); if (!pObjectInfo) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); } }
hr = BuildParent( pObjectInfo, ADsParent ); BAIL_ON_FAILURE(hr);
hr = CWinNTDomain::CreateDomain( ADsParent, pObjectInfo->ComponentArray[0], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
error:
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetWorkgroupObject
//
// Synopsis: called by GetObject.
// Note: We really don't have a workgroup object. But we
// need to support a syntax such as @WinNT!workstation to
// allow for IADsContainer interface methods. There is
// no authentication that needs to done.
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 05-23-96 RamV Created.
//
//----------------------------------------------------------------------------
HRESULT GetWorkGroupObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
HRESULT hr; IUnknown *pUnknown = NULL; IADs *pADs = NULL; WCHAR ADsParent[MAX_ADS_PATH]; WCHAR szName[MAX_PATH];
*ppObject = NULL;
if (pObjectInfo->NumComponents != 1) { RRETURN(E_ADS_INVALID_DOMAIN_OBJECT); }
//
// any single component oleds path can be validated as a workgroup
//
hr = BuildParent( pObjectInfo, ADsParent ); BAIL_ON_FAILURE(hr);
hr = CWinNTDomain::CreateDomain( ADsParent, pObjectInfo->ComponentArray[0], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown );
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
error: RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetUserObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
// 8-8-96 ramv Modified.
//
//----------------------------------------------------------------------------
HRESULT GetUserObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szUserName = NULL; DWORD dwParentId = 0; WCHAR szComputerParent[MAX_PATH]; POBJECTINFO pUserObjectInfo = NULL;
hr = ValidateUserObject( pObjectInfo, &dwParentId, Credentials ); BAIL_ON_FAILURE(hr);
switch (pObjectInfo->NumComponents) { case 2: //
// could be user in computer or user in domain
//
if(dwParentId == WINNT_DOMAIN_ID){
szDomainName = pObjectInfo->ComponentArray[0]; szUserName = pObjectInfo->ComponentArray[1]; szServerName = NULL;
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
} else {
//
// user in a computer
//
hr = ConstructFullObjectInfo(pObjectInfo, &pUserObjectInfo, Credentials ); if (SUCCEEDED(hr)) {
hr = BuildParent(pUserObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pUserObjectInfo->ComponentArray[0]; szServerName = pUserObjectInfo->ComponentArray[1]; szUserName = pUserObjectInfo->ComponentArray[2];
} else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
// We alread know that the object is valid,
// So we should set appropriate values and proceed to
// create the object
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = NULL; szServerName = pObjectInfo->ComponentArray[0]; szUserName = pObjectInfo->ComponentArray[1];
}
}
break;
case 3: szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szUserName = pObjectInfo->ComponentArray[2];
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr); break; }
hr = CWinNTUser::CreateUser(ADsParent, dwParentId, szDomainName, szServerName, szUserName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
FreeObjectInfo(pUserObjectInfo); RRETURN(hr);
error:
if (pUnknown) { pUnknown->Release(); } *ppObject = NULL;
FreeObjectInfo(pUserObjectInfo); RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetUserObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 8-8-96 ramv Created.
//
//----------------------------------------------------------------------------
HRESULT GetUserObjectInDomain( LPWSTR pszHostServerName, POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szUserName = NULL; DWORD dwParentId = WINNT_DOMAIN_ID; LPUSER_INFO_20 lpUI = NULL; NET_API_STATUS nasStatus; BOOL fRefAdded = FALSE; LPUSER_INFO_0 lpUI_0 = NULL; DWORD dwLevelUsed = 20;
// At this point a \\ has been prepended to the host
// we need to get rid of it.
hr = Credentials.RefServer(pszHostServerName+2); if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
nasStatus = NetUserGetInfo(pszHostServerName, pObjectInfo->ComponentArray[1], 20, (LPBYTE *)&lpUI);
if (nasStatus == ERROR_ACCESS_DENIED) { // try and drop down to level 0 as that may work
dwLevelUsed = 0; nasStatus = NetUserGetInfo( pszHostServerName, pObjectInfo->ComponentArray[1], 0, (LPBYTE *)&lpUI_0 ); }
// deref if necessary, note no error recovery possible
if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; }
hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (dwLevelUsed == 20) { if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) { FreeADsStr(pObjectInfo->ComponentArray[1]); pObjectInfo->ComponentArray[1] = AllocADsStr(lpUI->usri20_name); }
if (!pObjectInfo->ComponentArray[1]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); }
// if it is not a level 20 call then we will just use
// whatever the user gave us
szDomainName = pObjectInfo->ComponentArray[0]; szUserName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
hr = CWinNTUser::CreateUser(ADsParent, dwParentId, szDomainName, szServerName, szUserName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
error: if (FAILED(hr) && pUnknown) { pUnknown->Release(); *ppObject = NULL; }
if (lpUI) NetApiBufferFree((LPBYTE)lpUI);
if (lpUI_0) { NetApiBufferFree((LPBYTE)lpUI_0); }
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetUserObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
// 8-8-96 ramv Modified.
//
//----------------------------------------------------------------------------
HRESULT GetUserObjectInComputer( LPWSTR pszHostServerName, // pdc name
POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szUserName = NULL; DWORD dwParentId = WINNT_COMPUTER_ID; WCHAR szComputerParent[MAX_PATH]; POBJECTINFO pUserObjectInfo = NULL; WCHAR lpszUncName[MAX_PATH]; NET_API_STATUS nasStatus; LPBYTE lpUI = NULL; BOOL fRefAdded = FALSE;
switch (pObjectInfo->NumComponents) { case 2: //
// could be user in computer
//
//
// first validate user
//
hr = Credentials.RefServer(pObjectInfo->ComponentArray[0]); if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName);
nasStatus = NetUserGetInfo(lpszUncName, pObjectInfo->ComponentArray[1], 20, &lpUI);
if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; }
hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[1] && ((LPUSER_INFO_20)lpUI)->usri20_name) {
FreeADsStr(pObjectInfo->ComponentArray[1]); pObjectInfo->ComponentArray[1] = AllocADsStr(((LPUSER_INFO_20)lpUI)->usri20_name); }
if (!pObjectInfo->ComponentArray[1]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
// This call will add the domain information to the
// objectInfo blob, so that the ComponentArray[2] is valid
hr = ConstructFullObjectInfo(pObjectInfo, &pUserObjectInfo, Credentials ); BAIL_ON_FAILURE(hr);
hr = BuildParent(pUserObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pUserObjectInfo->ComponentArray[0]; szServerName = pUserObjectInfo->ComponentArray[1]; szUserName = pUserObjectInfo->ComponentArray[2];
break;
case 3:
//
// ValidateComputerParent and validate user in computer
//
hr = ValidateComputerParent(pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], Credentials); BAIL_ON_FAILURE(hr);
hr = Credentials.RefServer(pObjectInfo->ComponentArray[1]); if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
MakeUncName(pObjectInfo->ComponentArray[1], lpszUncName);
nasStatus = NetUserGetInfo(lpszUncName, pObjectInfo->ComponentArray[2], 20, (LPBYTE *)&lpUI);
if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; }
hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[2] && ((LPUSER_INFO_20)lpUI)->usri20_name) {
FreeADsStr(pObjectInfo->ComponentArray[2]); pObjectInfo->ComponentArray[2] = AllocADsStr(((LPUSER_INFO_20)lpUI)->usri20_name); }
if (!pObjectInfo->ComponentArray[2]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szUserName = pObjectInfo->ComponentArray[2]; break; } hr = CWinNTUser::CreateUser(ADsParent, dwParentId, szDomainName, szServerName, szUserName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); error: if (FAILED(hr)) { if (pUnknown) { pUnknown->Release(); } *ppObject = NULL; } else { *ppObject = pUnknown; }
if (lpUI) { NetApiBufferFree(lpUI); }
FreeObjectInfo(pUserObjectInfo);
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetComputerObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT GetComputerObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr = S_OK; WCHAR ADsParent[MAX_ADS_PATH]; TCHAR szUncName[MAX_PATH]; NET_API_STATUS nasStatus; POBJECTINFO pComputerObjectInfo = NULL; BOOL fNoWksta = FALSE; WCHAR szCompName[MAX_PATH]; DWORD dwSize = MAX_PATH;
//
// The following function call merely checks to see if the domain is
// correct. If not, we can assume that the computer does not belong to
// a domain.
//
hr = ValidateComputerObject(pObjectInfo, Credentials);
if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) fNoWksta = TRUE; else BAIL_ON_FAILURE(hr);
// Normall we can expect that the workstation service will
// be started. This will not be the case for minimum installs
if (!fNoWksta) {
if(pObjectInfo->NumComponents == 1){
//
// we need to supply the workgroup name for this computer
// This is needed because EnumLocalGroups requires the
// workgroup name to function properly
//
hr = ConstructFullObjectInfo(pObjectInfo, &pComputerObjectInfo, Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pComputerObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
hr = CWinNTComputer::CreateComputer( ADsParent, pComputerObjectInfo->ComponentArray[0], pComputerObjectInfo->ComponentArray[1], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, ppObject );
} else if(pObjectInfo->NumComponents == 2) {
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
hr = CWinNTComputer::CreateComputer( ADsParent, pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, ppObject);
} } else {
// Else clause for if(!fWksta)
// This means that workstation services were not
// started, we need to verify that the host computer
// is the one they are interested in.
if ((pObjectInfo->NumComponents != 1) || (!GetComputerName(szCompName, &dwSize))) { // We cannot get the computer name so bail
BAIL_ON_FAILURE(hr); }
// Compare the names before we continue
#ifdef WIN95
if (_wcsicmp(szCompName, pObjectInfo->ComponentArray[0])) { #else
if (CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, szCompName, -1, pObjectInfo->ComponentArray[0], -1 ) != CSTR_EQUAL ) { #endif
// names do not match
BAIL_ON_FAILURE(hr); }
hr = CWinNTComputer::CreateComputer( L"WinNT:", NULL, pObjectInfo->ComponentArray[0], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, ppObject ); BAIL_ON_FAILURE(hr);
}
error:
if(pComputerObjectInfo){ FreeObjectInfo(pComputerObjectInfo); } RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetPrinterObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 01/03/96 Ramv Created.
//
//----------------------------------------------------------------------------
HRESULT GetPrinterObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR szADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szDomainName = NULL; LPWSTR szServerName = NULL; LPWSTR szPrinterName = NULL; DWORD dwParentId = 0; LPWSTR szComputerParent[MAX_PATH]; POBJECTINFO pPrinterObjectInfo = NULL;
if (!(pObjectInfo->NumComponents == 3 ||pObjectInfo->NumComponents == 2)){
RRETURN(E_ADS_BAD_PATHNAME); }
// check to see that the printer is a valid one
hr = ValidatePrinterObject(pObjectInfo, Credentials);
BAIL_ON_FAILURE(hr);
dwParentId = WINNT_COMPUTER_ID;
if(pObjectInfo->NumComponents == 3) {
hr = BuildParent(pObjectInfo, szADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szPrinterName= pObjectInfo->ComponentArray[2];
} else if (pObjectInfo->NumComponents == 2){
hr = ConstructFullObjectInfo(pObjectInfo, &pPrinterObjectInfo, Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pPrinterObjectInfo, szADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pPrinterObjectInfo->ComponentArray[0]; szServerName = pPrinterObjectInfo->ComponentArray[1]; szPrinterName= pPrinterObjectInfo->ComponentArray[2]; } hr = CWinNTPrintQueue::CreatePrintQueue( szADsParent, dwParentId, szDomainName, szServerName, szPrinterName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
FreeObjectInfo(pPrinterObjectInfo); RRETURN(hr);
error: if (pUnknown) { pUnknown->Release(); } *ppObject = NULL;
FreeObjectInfo(pPrinterObjectInfo); RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetServiceObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 01/03/96 Ramv Created.
//
//----------------------------------------------------------------------------
HRESULT GetServiceObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR szADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szDomainName = NULL; LPWSTR szServerName = NULL; LPWSTR szServiceName = NULL; DWORD dwParentId = 0; POBJECTINFO pServiceObjectInfo = NULL;
//
// check to see that the printer is in a valid server(computer) object
//
if(!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2)) { RRETURN(E_ADS_BAD_PATHNAME); }
hr = ValidateServiceObject(pObjectInfo, Credentials); BAIL_ON_FAILURE(hr);
dwParentId = WINNT_COMPUTER_ID;
if(pObjectInfo->NumComponents == 3) {
hr = BuildParent(pObjectInfo, szADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szServiceName= pObjectInfo->ComponentArray[2];
hr = CWinNTService::Create(szADsParent, szDomainName, szServerName, szServiceName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr);
} else if (pObjectInfo->NumComponents == 2) {
hr = ConstructFullObjectInfo(pObjectInfo, &pServiceObjectInfo, Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pServiceObjectInfo, szADsParent); BAIL_ON_FAILURE(hr);
szServerName = pServiceObjectInfo->ComponentArray[1]; szServiceName= pServiceObjectInfo->ComponentArray[2];
hr = CWinNTService::Create(szADsParent, pServiceObjectInfo->ComponentArray[0], szServerName, szServiceName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr);
}
*ppObject = pUnknown; if(pServiceObjectInfo){ FreeObjectInfo(pServiceObjectInfo); } RRETURN(hr);
error:
if(pServiceObjectInfo){ FreeObjectInfo(pServiceObjectInfo); } if (pUnknown) { pUnknown->Release(); } *ppObject = NULL;
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetFileServiceObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 01/15/96 Ramv Created.
//
//----------------------------------------------------------------------------
HRESULT GetFileServiceObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR szADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szDomainName = NULL; LPWSTR szServerName = NULL; LPWSTR szFileServiceName = NULL; DWORD dwParentId = 0; POBJECTINFO pFileServiceObjectInfo = NULL; //
// check to see that the service is in a valid server(computer) object
//
if (!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2)) RRETURN(E_ADS_BAD_PATHNAME);
hr = ValidateFileServiceObject(pObjectInfo, Credentials); BAIL_ON_FAILURE(hr);
if (pObjectInfo->NumComponents == 3){ szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szFileServiceName= pObjectInfo->ComponentArray[2];
hr = BuildParent(pObjectInfo, szADsParent); BAIL_ON_FAILURE(hr);
}
if (pObjectInfo->NumComponents == 2){
hr = ConstructFullObjectInfo(pObjectInfo, &pFileServiceObjectInfo, Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pFileServiceObjectInfo, szADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pFileServiceObjectInfo->ComponentArray[0]; szServerName = pFileServiceObjectInfo->ComponentArray[1]; szFileServiceName= pFileServiceObjectInfo->ComponentArray[2]; }
dwParentId = WINNT_COMPUTER_ID;
if(_tcsicmp(szFileServiceName,TEXT("LanmanServer")) == 0) { hr = CWinNTFileService::CreateFileService(szADsParent, dwParentId, szDomainName, szServerName, szFileServiceName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr);
} else if(_tcsicmp(szFileServiceName,TEXT("FPNW")) == 0) {
hr = CFPNWFileService::CreateFileService(szADsParent, dwParentId, szDomainName, szServerName, szFileServiceName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr); }
*ppObject = pUnknown;
if(pFileServiceObjectInfo){ FreeObjectInfo(pFileServiceObjectInfo); }
RRETURN(hr);
error:
if(pFileServiceObjectInfo){ FreeObjectInfo(pFileServiceObjectInfo); }
if (pUnknown) { pUnknown->Release(); } *ppObject = NULL;
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetFileShareObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 01/15/96 Ramv Created.
//
//----------------------------------------------------------------------------
HRESULT GetFileShareObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR szADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPTSTR szDomainName = NULL; LPTSTR szServerName = NULL; LPTSTR szFileServiceName = NULL; LPTSTR szFileShareName = NULL; DWORD dwParentId = 0; POBJECTINFO pFileShareObjectInfo = NULL; WCHAR lpszUncName[MAX_PATH]; BOOL fRefAdded = FALSE;
//
// check to see that the share is in a valid fileservice
//
if (!(pObjectInfo->NumComponents == 4 || pObjectInfo->NumComponents == 3)) { RRETURN(E_ADS_BAD_PATHNAME); }
// The server is ref'ed in this routine.
hr = ValidateFileShareObject(pObjectInfo, Credentials); BAIL_ON_FAILURE(hr);
dwParentId = WINNT_SERVICE_ID;
if(pObjectInfo->NumComponents == 4){
hr = BuildParent(pObjectInfo, szADsParent); BAIL_ON_FAILURE(hr);
szServerName = pObjectInfo->ComponentArray[1]; szFileServiceName= pObjectInfo->ComponentArray[2]; szFileShareName = pObjectInfo ->ComponentArray[3];
} else if (pObjectInfo->NumComponents == 3){
hr = ConstructFullObjectInfo(pObjectInfo, &pFileShareObjectInfo, Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pFileShareObjectInfo, szADsParent); BAIL_ON_FAILURE(hr);
szServerName = pObjectInfo->ComponentArray[0]; szFileServiceName= pObjectInfo->ComponentArray[1]; szFileShareName = pObjectInfo ->ComponentArray[2]; }
if(_tcsicmp(szFileServiceName,TEXT("LanmanServer")) == 0){
hr = CWinNTFileShare::Create(szADsParent, szServerName, szFileServiceName, szFileShareName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr); } else { //
// we have validated it already, it *has* to be an FPNW server
//
hr = CFPNWFileShare::Create(szADsParent, szServerName, szFileServiceName, szFileShareName, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown); BAIL_ON_FAILURE(hr); }
*ppObject = pUnknown;
if(pFileShareObjectInfo){ FreeObjectInfo(pFileShareObjectInfo); }
RRETURN(hr);
error: if (pUnknown) { pUnknown->Release(); }
if(pFileShareObjectInfo){ FreeObjectInfo(pFileShareObjectInfo); }
*ppObject = NULL;
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetGroupObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT GetGroupObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szGroupName = NULL; DWORD dwParentId = 0; ULONG uGroupType = 0; POBJECTINFO pGroupObjectInfo = NULL;
hr = ValidateGroupObject( pObjectInfo, &uGroupType, &dwParentId, Credentials ); BAIL_ON_FAILURE(hr);
switch (pObjectInfo->NumComponents) { case 2: //
// could be group in computer or group in domain
//
if(dwParentId == WINNT_DOMAIN_ID){
szDomainName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
} else {
//
// group in a computer
//
hr = ConstructFullObjectInfo(pObjectInfo, &pGroupObjectInfo, Credentials );
if (SUCCEEDED(hr)) { hr = BuildParent(pGroupObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pGroupObjectInfo->ComponentArray[0]; szServerName = pGroupObjectInfo->ComponentArray[1]; szGroupName = pGroupObjectInfo->ComponentArray[2];
} else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) { //
// We will build the info without the parent
//
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = NULL; szServerName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1];
}
BAIL_ON_FAILURE(hr);
}
break;
case 3:
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szGroupName = pObjectInfo->ComponentArray[2]; break;
}
hr = CWinNTGroup::CreateGroup( ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown );
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); }
RRETURN(hr);
error: if (pUnknown) { pUnknown->Release(); }
if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); }
*ppObject = NULL;
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetGroupObjectInComputer
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 ramv Created.
//
//----------------------------------------------------------------------------
HRESULT GetGroupObjectInComputer( LPWSTR pszHostServerName, // pdc name
POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials) {
LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szGroupName = NULL; DWORD dwParentId = WINNT_COMPUTER_ID; ULONG uGroupType = 0; POBJECTINFO pGroupObjectInfo = NULL; WCHAR lpszUncName[MAX_PATH];
switch (pObjectInfo->NumComponents) { case 2: //
// group in a computer
//
MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName);
hr = ValidateGlobalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[1]), Credentials );
if (SUCCEEDED(hr)) { uGroupType = WINNT_GROUP_GLOBAL;
}else{ hr = ValidateLocalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[1]), Credentials );
BAIL_ON_FAILURE(hr); uGroupType = WINNT_GROUP_LOCAL; }
hr = ConstructFullObjectInfo(pObjectInfo, &pGroupObjectInfo, Credentials ); BAIL_ON_FAILURE(hr);
hr = BuildParent(pGroupObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pGroupObjectInfo->ComponentArray[0]; szServerName = pGroupObjectInfo->ComponentArray[1]; szGroupName = pGroupObjectInfo->ComponentArray[2];
break;
case 3:
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 (SUCCEEDED(hr)) { uGroupType = WINNT_GROUP_GLOBAL; } else { hr = ValidateLocalGroupObject( lpszUncName, &(pObjectInfo->ComponentArray[2]), Credentials );
BAIL_ON_FAILURE(hr); uGroupType = WINNT_GROUP_LOCAL; }
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szGroupName = pObjectInfo->ComponentArray[2]; break; }
if (uGroupType == WINNT_GROUP_LOCAL) {
hr = CWinNTGroup::CreateGroup(ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown );
}else {
hr = CWinNTGroup::CreateGroup(ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown );
}
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); }
RRETURN(hr);
error: if (pUnknown) { pUnknown->Release(); }
if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); }
*ppObject = NULL;
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetGroupObjectInDomain
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 8-8-96 Ramv Created.
//
//----------------------------------------------------------------------------
HRESULT GetGroupObjectInDomain( LPWSTR pszHostServerName, POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szGroupName = NULL; DWORD dwParentId = WINNT_DOMAIN_ID; ULONG uGroupType = 0; BOOL fRefAdded = FALSE;
// At this point the host server name has a \\ prepended
// so we need to get rid of it.
hr = Credentials.RefServer(pszHostServerName+2); if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
hr = ValidateGlobalGroupObject( pszHostServerName, &(pObjectInfo->ComponentArray[1]), Credentials );
if (FAILED(hr)) { hr = ValidateLocalGroupObject( pszHostServerName, &(pObjectInfo->ComponentArray[1]), Credentials );
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; }
BAIL_ON_FAILURE(hr); uGroupType = WINNT_GROUP_LOCAL; }else {
uGroupType = WINNT_GROUP_GLOBAL; }
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; }
szDomainName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
if (uGroupType==WINNT_GROUP_LOCAL) {
hr = CWinNTGroup::CreateGroup( ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); } else {
hr = CWinNTGroup::CreateGroup(ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); } BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error: if (pUnknown) { pUnknown->Release(); }
*ppObject = NULL;
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetSchemaObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 1-17-96 yihsins Created.
//
//----------------------------------------------------------------------------
HRESULT GetSchemaObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK;
if (pObjectInfo->NumComponents != 2) RRETURN(E_ADS_BAD_PATHNAME);
if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 ) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); }
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
hr = CWinNTSchema::CreateSchema( ADsParent, pObjectInfo->ComponentArray[1], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error: if (pUnknown) pUnknown->Release();
*ppObject = NULL; RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetClassObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 1-17-96 yihsins Created.
//
//----------------------------------------------------------------------------
HRESULT GetClassObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; DWORD i;
if (pObjectInfo->NumComponents != 3) RRETURN(E_ADS_BAD_PATHNAME);
if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 ) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); }
//
// Look for the given class name
//
for ( i = 0; i < g_cWinNTClasses; i++ ) { if ( _wcsicmp( g_aWinNTClasses[i].bstrName, pObjectInfo->ComponentArray[2] ) == 0 ) break; }
if ( i == g_cWinNTClasses ) { // Class name not found, return error
hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); }
//
// Class name found, create and return the object
//
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
hr = CWinNTClass::CreateClass( ADsParent, &g_aWinNTClasses[i], ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error: if (pUnknown) pUnknown->Release();
*ppObject = NULL; RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetSyntaxObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 1-17-96 yihsins Created.
//
//----------------------------------------------------------------------------
HRESULT GetSyntaxObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; DWORD i;
if (pObjectInfo->NumComponents != 3) RRETURN(E_ADS_BAD_PATHNAME);
if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 ) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); }
//
// Look for the given syntax name
//
for ( i = 0; i < g_cWinNTSyntax; i++ ) { if ( _wcsicmp( g_aWinNTSyntax[i].bstrName, pObjectInfo->ComponentArray[2] ) == 0 ) break; }
if ( i == g_cWinNTSyntax ) { // Syntax name not found, return error
hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); }
//
// Syntax name found, create and return the object
//
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
hr = CWinNTSyntax::CreateSyntax( ADsParent, &(g_aWinNTSyntax[i]), ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error: if (pUnknown) pUnknown->Release();
*ppObject = NULL; RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetPropertyObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 1-17-96 yihsins Created.
//
//----------------------------------------------------------------------------
HRESULT GetPropertyObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; WCHAR ADsGrandParent[MAX_ADS_PATH]; HRESULT hr = S_OK; DWORD nClass, nProp;
if (pObjectInfo->NumComponents != 3) RRETURN(E_ADS_BAD_PATHNAME);
if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 ) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); }
//
// We found the specified functional set, now see if we can locate
// the given property name
//
for ( nProp = 0; nProp < g_cWinNTProperties; nProp++ ) { if ( _wcsicmp(g_aWinNTProperties[nProp].szPropertyName, pObjectInfo->ComponentArray[2] ) == 0 ) break; }
if ( nProp == g_cWinNTProperties ) { // Return error because the given property name is not found
hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); }
//
// Property name is found, so create and return the object
//
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
hr = CWinNTProperty::CreateProperty( ADsParent, &(g_aWinNTProperties[nProp]), ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error: if (pUnknown) pUnknown->Release();
*ppObject = NULL; RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT HeuristicGetObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr = S_OK; WCHAR szHostServerName[MAX_PATH]; DWORD dwElementType; WCHAR szName[MAX_PATH]; WCHAR szSAMName[MAX_ADS_PATH]; WCHAR lpszUncName[MAX_PATH];
szSAMName[0] = L'\0'; //
// Case 0: Zero components - must be a namespace object
//
if (pObjectInfo->NumComponents == 0) { RRETURN(GetNamespaceObject(pObjectInfo, ppObject, Credentials)); }
//
// Case 1: Single component - must be a domain object or
// computer object
//
if (pObjectInfo->NumComponents == 1) {
//
// hr = WinNTGetCachedObject(type, hit/miss, pdcname/domain name)
//
// if (succeeded...
// switch(type) .... call the appropriate
// GetDomain or GetWorkGroup or GetComputer
//
hr = WinNTGetCachedName( pObjectInfo->ComponentArray[0], &dwElementType, szHostServerName, szSAMName, Credentials );
BAIL_IF_ERROR(hr);
// update the name to the one on SAM
if (szSAMName[0] != L'\0') { FreeADsStr(pObjectInfo->ComponentArray[0]); pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName); }
if (!pObjectInfo->ComponentArray[0]) { BAIL_IF_ERROR(hr = E_OUTOFMEMORY); }
switch(dwElementType) {
case DOMAIN_ENTRY_TYPE: hr = GetDomainObject(pObjectInfo, ppObject, Credentials); break;
case COMPUTER_ENTRY_TYPE: hr = GetComputerObject(pObjectInfo, ppObject, Credentials); break;
default: hr = GetWorkGroupObject(pObjectInfo, ppObject, Credentials); break;
} goto cleanup;
}
//
// Case 2: Two components - could be user, group, computer,
// or any one of the computer's sub-objects.
//
if (pObjectInfo->NumComponents == 2) {
hr = GetSchemaObject(pObjectInfo, ppObject, Credentials);
if(SUCCEEDED(hr)){ goto cleanup; } if(FAILED(hr)) { //
// try doing a WinNTGetCachedDCName first
// and if it goes through, then we have objects such as
// user,group,computer in domain, otherwise it is the
// computer case or workgroup case
//
// WinNtGetCachedObject will directly tell us to proceed or
// not
hr = WinNTGetCachedName(pObjectInfo->ComponentArray[0], &dwElementType, szHostServerName, szSAMName, Credentials );
BAIL_IF_ERROR(hr);
// Again we do not have to worry about the case of the
// object name, it is handled by the GetObject calls
switch(dwElementType) {
case DOMAIN_ENTRY_TYPE:
hr = GetUserObjectInDomain(szHostServerName, pObjectInfo, ppObject, Credentials);
if (FAILED(hr)) { hr = GetGroupObjectInDomain(szHostServerName, pObjectInfo, ppObject, Credentials); }
if (FAILED(hr)) { hr = GetComputerObject(pObjectInfo, ppObject, Credentials); }
goto cleanup;
case COMPUTER_ENTRY_TYPE:
hr = GetPrinterObject(pObjectInfo, ppObject, Credentials); if (FAILED(hr)) { hr = GetFileServiceObject( pObjectInfo, ppObject, Credentials ); } if (FAILED(hr)) { hr = GetServiceObject(pObjectInfo, ppObject, Credentials); } if(FAILED(hr)){ hr = GetUserObjectInComputer( pObjectInfo->ComponentArray[0], pObjectInfo, ppObject, Credentials ); } if (FAILED(hr)) { hr = GetGroupObjectInComputer( pObjectInfo->ComponentArray[0], pObjectInfo, ppObject, Credentials ); } goto cleanup;
case WORKGROUP_ENTRY_TYPE:
hr = GetComputerObject(pObjectInfo, ppObject, Credentials); if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) { // In this case I want to mask the error
// as it means it could not find the object
hr = E_ADS_UNKNOWN_OBJECT; } } goto cleanup;
default: hr = E_ADS_UNKNOWN_OBJECT; goto cleanup;
}
} } /* NumComponents == 2 */
//
// Case 3: Three components - could be user, group, printer, fileservice
// or service or fileshare for computer in a workgroup environment.
//
if (pObjectInfo->NumComponents == 3) {
if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) == 0 ){ hr = GetClassObject(pObjectInfo, ppObject, Credentials);
if (FAILED(hr)) {
hr = GetPropertyObject(pObjectInfo, ppObject, Credentials); }
if (FAILED(hr)) { hr = GetSyntaxObject(pObjectInfo, ppObject, Credentials); } } else{ hr = GetUserObjectInComputer(pObjectInfo->ComponentArray[1], pObjectInfo, ppObject, Credentials);
if (FAILED(hr)) { hr = GetGroupObjectInComputer(pObjectInfo->ComponentArray[1], pObjectInfo, ppObject, Credentials); }
if(FAILED(hr)){ hr = GetPrinterObject(pObjectInfo, ppObject, Credentials); }
if (FAILED(hr)) { hr = GetFileServiceObject(pObjectInfo, ppObject, Credentials); }
if (FAILED(hr)) { hr = GetServiceObject(pObjectInfo, ppObject, Credentials); }
if (FAILED(hr)) { hr = GetFileShareObject(pObjectInfo, ppObject, Credentials); }
} if(FAILED(hr) ){ RRETURN(hr); } else{ RRETURN(S_OK); } }
if (pObjectInfo->NumComponents == 4) {
hr = GetFileShareObject(pObjectInfo, ppObject, Credentials);
if(FAILED(hr)){ RRETURN(hr); } else{ RRETURN(S_OK); }
} RRETURN (E_ADS_UNKNOWN_OBJECT);
cleanup:
if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
//
// There is a very good chance that this is a case
// where they are trying to work on the local machine
// when there are no workstation services. Note that this
// means that a fully qualified name was not given.
//
hr = HeuristicGetObjectNoWksta( pObjectInfo, ppObject, Credentials );
}
//
// Propagate the error code which we have rather than
// mask it and return information of little value
//
if (FAILED(hr)) {
// the error code NERR_BadTransactConfig means that the
// object did not exist, we want to mask just that ecode
if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) { hr = E_ADS_UNKNOWN_OBJECT; }
RRETURN(hr);
} else { RRETURN(S_OK); } }
//+---------------------------------------------------------------------------
// Function: HeuristicGetObjectNoWksta
//
// Synopsis: Tries to locate the object on local machine when there are no
// workstation services. This will happen in a minimum install of NT.
//
// Arguments: POBJECTINFO -> data about object being located.
// LPVOID -> Object to be returned in this arg.
// Credentials -> Credentials blob.
//
// Returns: Either S_OK or HR_From_Win32(NERR_WkstaNotStarted)
//
// Modifies:
//
// History: 08-03-98 AjayR Created.
//
//----------------------------------------------------------------------------
HRESULT HeuristicGetObjectNoWksta( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) { HRESULT hr = S_OK; HRESULT hrNoWksta = HRESULT_FROM_WIN32(NERR_WkstaNotStarted); WCHAR szHostServerName[MAX_PATH]; DWORD dwElementType; WCHAR szName[MAX_PATH]; WCHAR szSAMName[MAX_ADS_PATH]; WCHAR lpszUncName[MAX_PATH];
szSAMName[0] = L'\0';
//
// Case 0: Zero components - Should no be hit here.
//
if (pObjectInfo->NumComponents == 0) { RRETURN(hrNoWksta); }
//
// Case 1: Single component - Can only be a computer object
//
if (pObjectInfo->NumComponents == 1) {
hr = GetComputerObject(pObjectInfo, ppObject, Credentials); goto cleanup;
}
//
// Case 2: Two components - could be user or group for now.
// Other possible objects - TBD.
//
if (pObjectInfo->NumComponents == 2) {
hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
if (FAILED(hr)) { hr = GetFileServiceObject( pObjectInfo, ppObject, Credentials ); }
if (FAILED(hr)) { hr = GetServiceObject(pObjectInfo, ppObject, Credentials); }
if(FAILED(hr)){ hr = GetUserObject( pObjectInfo, ppObject, Credentials ); } if (FAILED(hr)) { hr = GetLocalGroupObject( pObjectInfo, ppObject, Credentials ); } goto cleanup;
} /* NumComponents == 2 */
//
// Case 3 or more : Three or more components - not possible
//
if (pObjectInfo->NumComponents > 2) {
RRETURN(hrNoWksta);
}
RRETURN (E_ADS_UNKNOWN_OBJECT);
cleanup: //
// Propagate the error code which we have rather than
// mask it and return information of little value
//
if (FAILED(hr)) { // the error code NERR_BadTransactConfig means that the
// object did not exist, we want to mask just that ecode
if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) { hr = E_ADS_UNKNOWN_OBJECT; }
RRETURN(hr);
} else { RRETURN(S_OK); } }
HRESULT BuildParent( POBJECTINFO pObjectInfo, LPWSTR szBuffer ) { DWORD i = 0; DWORD dwLen = 0;
if (!pObjectInfo->ProviderName) { RRETURN(E_ADS_BAD_PATHNAME); }
wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
if (pObjectInfo->NumComponents - 1) {
dwLen = wcslen(pObjectInfo->ProviderName) + 3 + wcslen(pObjectInfo->DisplayComponentArray[0]); if(dwLen >= MAX_ADS_PATH) { RRETURN(E_ADS_BAD_PATHNAME); }
wcscat(szBuffer, L"//"); wcscat(szBuffer, pObjectInfo->DisplayComponentArray[0]);
for (i = 1; i < (pObjectInfo->NumComponents - 1); i++) { dwLen += (1 + wcslen(pObjectInfo->DisplayComponentArray[i])); if(dwLen >= MAX_ADS_PATH) { RRETURN(E_ADS_BAD_PATHNAME); }
wcscat(szBuffer, L"/"); wcscat(szBuffer, pObjectInfo->DisplayComponentArray[i]); } } RRETURN(S_OK); }
HRESULT BuildGrandParent( POBJECTINFO pObjectInfo, LPWSTR szBuffer ) { DWORD i = 0;
if (!pObjectInfo->ProviderName) { RRETURN(E_ADS_BAD_PATHNAME); }
wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
if (pObjectInfo->NumComponents - 2) {
wcscat(szBuffer, L"//"); wcscat(szBuffer, pObjectInfo->ComponentArray[0]);
for (i = 1; i < (pObjectInfo->NumComponents - 2); i++) { wcscat(szBuffer, L"/"); wcscat(szBuffer, pObjectInfo->ComponentArray[i]); } }
RRETURN(S_OK); }
HRESULT BuildADsPath( POBJECTINFO pObjectInfo, LPWSTR szBuffer ) { DWORD i = 0;
if (!pObjectInfo->ProviderName) { RRETURN(E_ADS_BAD_PATHNAME); }
wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
if (pObjectInfo->NumComponents) {
wcscat(szBuffer, L"//"); wcscat(szBuffer, pObjectInfo->DisplayComponentArray[0]);
for (i = 1; i < (pObjectInfo->NumComponents); i++) { wcscat(szBuffer, L"/"); wcscat(szBuffer, pObjectInfo->DisplayComponentArray[i]); } } RRETURN(S_OK); }
HRESULT ValidateUserObject( POBJECTINFO pObjectInfo, PDWORD pdwParentId, CWinNTCredentials& Credentials ) { WCHAR szHostServerName[MAX_PATH]; LPUSER_INFO_20 lpUI = NULL; HRESULT hr; WCHAR lpszUncName[MAX_PATH]; NET_API_STATUS nasStatus; WCHAR szSAMName[MAX_PATH]; BOOL fRefAdded = FALSE; LPUSER_INFO_0 lpUI_0 = NULL; DWORD dwLevelUsed = 20; WCHAR szCompName[MAX_PATH]; DWORD dwSize = MAX_PATH;
szSAMName[0] = L'\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)){
// Need to ref the server, note that RefServer
// checks if the credentials are non null
// We are not concerned about any error as we may
// still succeed with default credentials.
// The +2 is to skip the \\ at the head.
hr = Credentials.RefServer(szHostServerName+2); if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
nasStatus = NetUserGetInfo(szHostServerName, pObjectInfo->ComponentArray[1], 20, (LPBYTE *)&lpUI); //
// This code is here because Level 20 reads the flags
// and if you accessed WinNT://ntdev/foo with Redmond\foo
// credentials, it will fail. This allow a bind but the
// GetInfo will fail.
//
if (nasStatus == ERROR_ACCESS_DENIED) { // try and drop down to level 0 as that may work
dwLevelUsed = 0; nasStatus = NetUserGetInfo( szHostServerName, pObjectInfo->ComponentArray[1], 0, (LPBYTE *)&lpUI_0 ); }
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; }
hr = HRESULT_FROM_WIN32(nasStatus);
BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (dwLevelUsed == 20 ) { if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) { FreeADsStr(pObjectInfo->ComponentArray[1]); pObjectInfo->ComponentArray[1] = AllocADsStr(lpUI->usri20_name); }
if (!pObjectInfo->ComponentArray[1]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); }
*pdwParentId = WINNT_DOMAIN_ID; }
//
// 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 );
if (SUCCEEDED(hr)) {
// Need to ref the server on which the object lives
// Note that RefServer checks if Credentials are null.
// Again, we are not concerned about any errors as we
// will drop down to default credentials automatically.
hr = Credentials.RefServer(pObjectInfo->ComponentArray[0]); if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName);
nasStatus = NetUserGetInfo(lpszUncName, pObjectInfo->ComponentArray[1], 20, (LPBYTE *)&lpUI);
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) { FreeADsStr(pObjectInfo->ComponentArray[1]); pObjectInfo->ComponentArray[1] = AllocADsStr(lpUI->usri20_name); }
if (!pObjectInfo->ComponentArray[1]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
*pdwParentId = WINNT_COMPUTER_ID; } else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
//
// Need to see if the problem was not workstation
// services in which case we need to still try and
// locate user if the comptuer name matches.
//
if (!GetComputerName(szCompName, &dwSize)) { //
// We could not get the computer name so bail
//
BAIL_ON_FAILURE(hr); }
//
// Test the name before continuing.
//
#ifdef WIN95
if (_wcsicmp(szCompName, pObjectInfo->ComponentArray[0])) { #else
if (CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, szCompName, -1, pObjectInfo->ComponentArray[0], -1 ) != CSTR_EQUAL ) { #endif
// names do not match
BAIL_ON_FAILURE(hr); }
//
// Valid computer name, so we can try and check for user
//
MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName);
nasStatus = NetUserGetInfo( lpszUncName, pObjectInfo->ComponentArray[1], 20, (LPBYTE *)&lpUI );
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(nasStatus));
*pdwParentId = WINNT_COMPUTER_ID;
} }
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);
// Again we need to ref the server
hr = Credentials.RefServer(pObjectInfo->ComponentArray[1]); if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
MakeUncName(pObjectInfo->ComponentArray[1], lpszUncName);
nasStatus = NetUserGetInfo(lpszUncName, pObjectInfo->ComponentArray[2], 20, (LPBYTE *)&lpUI);
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[2] && lpUI->usri20_name) { FreeADsStr(pObjectInfo->ComponentArray[2]); pObjectInfo->ComponentArray[2] = AllocADsStr(lpUI->usri20_name); }
if (!pObjectInfo->ComponentArray[2]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
*pdwParentId = WINNT_COMPUTER_ID; break;
default: RRETURN(E_ADS_BAD_PATHNAME); }
error: if (lpUI) { NetApiBufferFree((LPBYTE)lpUI); }
if (lpUI_0) { NetApiBufferFree((LPBYTE)lpUI_0); }
RRETURN(hr);
}
HRESULT ValidateComputerParent( LPWSTR pszDomainName, LPWSTR pszComputerName, CWinNTCredentials& Credentials )
{ HRESULT hr; NET_API_STATUS nasStatus; WCHAR szName[MAX_PATH]; WCHAR szSAMName[MAX_PATH]; WCHAR szCompName[MAX_PATH]; DWORD dwSize = MAX_PATH;
szSAMName[0] = L'\0';
hr = WinNTGetCachedComputerName( pszComputerName, szName, szSAMName, Credentials );
if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
//
// We want to see if the computer being validated is
// the current host.
//
if (!GetComputerName(szCompName, &dwSize) #ifdef WIN95
|| (_wcsicmp(szCompName, pszComputerName)) #else
|| (CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, szCompName, -1, pszComputerName, -1 ) != CSTR_EQUAL ) #endif
) BAIL_ON_FAILURE(hr);
hr = S_OK;
} BAIL_ON_FAILURE(hr);
if(pszDomainName == NULL){ //
// we are dealing with a case where we aren't supplied the
// computer's parent. Just validate the computer
//
hr = S_OK; goto error;
} else {
#ifdef WIN95
//
// No NetpNameCompare for Win9x
//
if (!_wcsicmp(pszDomainName, szName)) { #else
if ((CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, pszDomainName, -1, szName, -1 ) == CSTR_EQUAL ) || (NetpNameCompare( NULL, pszDomainName, szName, NAMETYPE_DOMAIN, 0 ) == 0 ) ) { #endif
hr = S_OK; }else { hr = E_ADS_BAD_PATHNAME; } }
error: RRETURN(hr); }
// Overloaded ValidateComputerParent function.
// This is used when the case of pszComputerName on the SAM
// databsae is needed.
HRESULT ValidateComputerParent( LPWSTR pszDomainName, LPWSTR pszComputerName, LPWSTR pszSAMName, CWinNTCredentials& Credentials )
{ HRESULT hr; NET_API_STATUS nasStatus; WCHAR szName[MAX_PATH]; WCHAR szSAMName[MAX_PATH];
szSAMName[0] = L'\0';
hr = WinNTGetCachedComputerName( pszComputerName, szName, szSAMName, Credentials );
BAIL_ON_FAILURE(hr);
if (szSAMName[0] != L'\0') { wcscpy(pszSAMName, szSAMName); }
if(pszDomainName == NULL){ //
// we are dealing with a case where we aren't supplied the
// computer's parent. Just validate the computer
//
hr = S_OK; goto error;
} else {
#ifdef WIN95
//
// No NetpNameCompare for Win9x
//
if (!_wcsicmp(pszDomainName, szName)) { #else
if ((CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, pszDomainName, -1, szName, -1 ) == CSTR_EQUAL ) || (NetpNameCompare( NULL, pszDomainName, szName, NAMETYPE_DOMAIN, 0 ) == 0 ) ) { #endif
hr = S_OK; }else {
hr = E_FAIL; } }
error: RRETURN(hr); }
HRESULT ValidateGroupObject( POBJECTINFO pObjectInfo, PULONG puGroupType, PDWORD pdwParentId, CWinNTCredentials& Credentials ) { WCHAR szHostServerName[MAX_PATH]; LPGROUP_INFO_0 lpGI = NULL; HRESULT hr; WCHAR lpszUncName[MAX_PATH]; NET_API_STATUS nasStatus; ULONG uGroupType = 0L; WCHAR szSAMName[MAX_PATH];
szSAMName[0] = L'\0';
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
//
*pdwParentId = WINNT_DOMAIN_ID;
hr = ValidateGlobalGroupObject( szHostServerName, &(pObjectInfo->ComponentArray[1]), Credentials );
if (FAILED(hr)) { hr = ValidateLocalGroupObject( szHostServerName, &(pObjectInfo->ComponentArray[1]), Credentials );
if(SUCCEEDED(hr)){ uGroupType = WINNT_GROUP_LOCAL; }
}else{ uGroupType = WINNT_GROUP_GLOBAL; } }
if(FAILED(hr)){ //
// potentially a group in a computer
//
hr = ValidateComputerParent(NULL, pObjectInfo->ComponentArray[0], Credentials); BAIL_ON_FAILURE(hr);
//
// group in a computer
//
*pdwParentId = WINNT_COMPUTER_ID;
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); uGroupType = WINNT_GROUP_LOCAL;
}else{ uGroupType = WINNT_GROUP_GLOBAL; } } break;
case 3:
//
// if there are 3 components then we must have parentid
// WINNT_COMPUTER_ID
//
*pdwParentId = 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); uGroupType = WINNT_GROUP_LOCAL;
}else{ uGroupType = WINNT_GROUP_GLOBAL; } break;
default: RRETURN(E_ADS_BAD_PATHNAME); }
error: if (lpGI) { NetApiBufferFree((LPBYTE)lpGI); }
*puGroupType = uGroupType; RRETURN(hr);
}
HRESULT ValidatePrinterObject( POBJECTINFO pObjectInfo, CWinNTCredentials& Credentials ) { LPTSTR szDomainName = NULL; LPTSTR szServerName = NULL; LPTSTR szPrinterName = NULL; WCHAR szPrintObjectName[MAX_PATH]; HRESULT hr = E_ADS_UNKNOWN_OBJECT; BOOL fStatus = FALSE; HANDLE hPrinter = NULL; PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_USE};
if (!(pObjectInfo->NumComponents == 3 ||pObjectInfo->NumComponents == 2)){
RRETURN(E_ADS_BAD_PATHNAME); }
if(pObjectInfo->NumComponents == 3){ //
// printer in domain\computer or workgroup\computer
//
szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szPrinterName = pObjectInfo->ComponentArray[2];
hr = ValidateComputerParent(szDomainName, szServerName, Credentials); BAIL_IF_ERROR(hr);
} else if ( pObjectInfo-> NumComponents == 2 ){
szServerName = pObjectInfo->ComponentArray[0]; szPrinterName = pObjectInfo->ComponentArray[1]; }
MakeUncName(szServerName, szPrintObjectName); wcscat(szPrintObjectName, TEXT("\\")); wcscat(szPrintObjectName, szPrinterName);
//
// validate the printer in computer now
//
fStatus = OpenPrinter(szPrintObjectName, &hPrinter, &PrinterDefaults);
if(!fStatus){ hr = HRESULT_FROM_WIN32(GetLastError()); } else { hr = S_OK; }
cleanup: if(hPrinter){ ClosePrinter(hPrinter); } RRETURN(hr);
}
HRESULT ValidateServiceObject( POBJECTINFO pObjectInfo, CWinNTCredentials& Credentials ) { LPTSTR szDomainName = NULL; LPTSTR szServerName = NULL; LPTSTR szServiceName = NULL; SC_HANDLE schSCMHandle=NULL; SC_HANDLE schServiceHandle=NULL; HRESULT hr = S_OK; BOOLEAN fRefAdded = FALSE;
if(!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2)) { RRETURN(E_ADS_BAD_PATHNAME); }
if(pObjectInfo->NumComponents == 3){
szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szServiceName = pObjectInfo->ComponentArray[2];
//
// First check to see if the computer is in the right domain
//
hr = ValidateComputerParent( szDomainName, szServerName, Credentials ); BAIL_ON_FAILURE(hr);
} else if (pObjectInfo->NumComponents == 2){ szServerName = pObjectInfo->ComponentArray[0]; szServiceName = pObjectInfo->ComponentArray[1]; }
//
// check to see if the service is valid by opening the active services
// database on the server
//
hr = Credentials.RefServer(szServerName);
if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
//
// Open the Service Control Manager.
//
schSCMHandle = OpenSCManager(szServerName, NULL, GENERIC_READ);
if (schSCMHandle == NULL) { hr = HRESULT_FROM_WIN32(GetLastError()); goto error; }
//
// Need to ref the server before opening the service
//
//
// try to open the service
//
schServiceHandle = OpenService(schSCMHandle, szServiceName, GENERIC_READ);
if(schServiceHandle == NULL) {
CloseServiceHandle(schSCMHandle); schSCMHandle = NULL; hr = HRESULT_FROM_WIN32(GetLastError()); goto error; }
CloseServiceHandle(schServiceHandle); CloseServiceHandle(schSCMHandle);
error:
if (fRefAdded) { Credentials.DeRefServer(); fRefAdded = FALSE; } RRETURN(hr); }
HRESULT GetPrinterFromPath(LPTSTR *pszPrinter, LPWSTR szPathName) { //
// If passed an empty string, it returns an empty string
//
LPTSTR szRetval;
*pszPrinter = NULL; szRetval = szPathName;
ADsAssert(szPathName);
while(!(*szRetval==L'\0' || *szRetval==L'\\')){ szRetval++; }
if(*szRetval != L'\\'){ RRETURN(E_FAIL); } szRetval++; *pszPrinter = szRetval; RRETURN(S_OK); }
HRESULT ValidateComputerObject( POBJECTINFO pObjectInfo, CWinNTCredentials& Credentials) { HRESULT hr; WCHAR szSAMName[MAX_PATH];
szSAMName[0] = L'\0';
if(!(pObjectInfo->NumComponents == 2 || pObjectInfo->NumComponents == 1)){
RRETURN(E_ADS_UNKNOWN_OBJECT); }
if(pObjectInfo->NumComponents == 2){
hr = ValidateComputerParent( pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], szSAMName, Credentials ); BAIL_ON_FAILURE(hr);
if (szSAMName[0] != L'\0') { FreeADsStr(pObjectInfo->ComponentArray[1]); pObjectInfo->ComponentArray[1] = AllocADsStr(szSAMName); if (!pObjectInfo->ComponentArray[1]) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); } }
} else {
hr = ValidateComputerParent( NULL, pObjectInfo->ComponentArray[0], szSAMName, Credentials ); BAIL_ON_FAILURE(hr);
if (szSAMName[0] != L'\0') { FreeADsStr(pObjectInfo->ComponentArray[0]); pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName); if (!pObjectInfo->ComponentArray[0]) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); } }
}
error: RRETURN(hr);
}
HRESULT ValidateFileServiceObject( POBJECTINFO pObjectInfo, CWinNTCredentials& Credentials ) {
HRESULT hr = S_OK;
//
// check to see if it is a valid service
//
if(!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2)) { RRETURN(E_ADS_BAD_PATHNAME); }
hr = ValidateServiceObject(pObjectInfo, Credentials);
if(FAILED(hr)) RRETURN(hr);
//
// check to see if it is the LanmanServer or FPNW service
//
if (pObjectInfo->NumComponents ==3){
if(!(_wcsicmp(pObjectInfo->ComponentArray[2], TEXT("LanmanServer"))== 0 || _wcsicmp(pObjectInfo->ComponentArray[2],TEXT("FPNW"))==0)){ RRETURN(E_ADS_BAD_PATHNAME); }
}else if(pObjectInfo->NumComponents == 2) {
if(!(_wcsicmp(pObjectInfo->ComponentArray[1], TEXT("LanmanServer"))== 0 || _wcsicmp(pObjectInfo->ComponentArray[1],TEXT("FPNW"))==0)){
RRETURN(E_ADS_BAD_PATHNAME); } }
RRETURN(hr); }
HRESULT ValidateFileShareObject( POBJECTINFO pObjectInfo, CWinNTCredentials& Credentials ) {
NET_API_STATUS nasStatus; LPSHARE_INFO_1 lpShareInfo1 = NULL; PNWVOLUMEINFO pVolumeInfo = NULL; LPTSTR pszDomainName = NULL; LPTSTR pszServerName = NULL; LPTSTR pszShareName = NULL; LPTSTR pszServerType = NULL; HRESULT hr = S_OK; DWORD dwSharePos = 3; BOOL fRefAdded = FALSE; //
// check to see if it is a valid file share
//
if (pObjectInfo->NumComponents == 4 ){ pszDomainName = pObjectInfo->ComponentArray[0]; pszServerName = pObjectInfo->ComponentArray[1]; pszServerType = pObjectInfo->ComponentArray[2]; pszShareName = pObjectInfo->ComponentArray[3]; dwSharePos = 3;
hr = ValidateComputerParent(pszDomainName, pszServerName, Credentials); BAIL_ON_FAILURE(hr);
} else if (pObjectInfo->NumComponents == 3 ){ pszServerName = pObjectInfo->ComponentArray[0]; pszServerType = pObjectInfo->ComponentArray[1]; pszShareName = pObjectInfo->ComponentArray[2]; dwSharePos = 2; } else { hr = E_ADS_UNKNOWN_OBJECT; goto error; }
if(_tcsicmp(pszServerType,TEXT("LanmanServer")) == 0){
// Need to ref this server before we do the NetShareGetInfo
// so that we can authenticate against the server.
hr = Credentials.RefServer(pszServerName); if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
nasStatus = NetShareGetInfo(pszServerName, pszShareName, 1, (LPBYTE*)&lpShareInfo1);
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) { hr = Credentials.DeRefServer(); fRefAdded = FALSE; }
if(nasStatus != NERR_Success){ hr = HRESULT_FROM_WIN32(nasStatus); goto error; } else { // Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[dwSharePos] && lpShareInfo1->shi1_netname) {
FreeADsStr(pObjectInfo->ComponentArray[dwSharePos]); pObjectInfo->ComponentArray[dwSharePos] = AllocADsStr(lpShareInfo1->shi1_netname); }
if (!pObjectInfo->ComponentArray[dwSharePos]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
hr = S_OK; goto error; } } else if(_tcsicmp(pszServerType,TEXT("FPNW")) == 0){
hr = Credentials.RefServer(pszServerName); if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
nasStatus = ADsNwVolumeGetInfo(pszServerName, pszShareName, 1, &pVolumeInfo);
// need to deref, nothing we can do if deref fails
if (fRefAdded) { hr = Credentials.DeRefServer(); fRefAdded = FALSE; }
if(nasStatus != NERR_Success){ hr = HRESULT_FROM_WIN32(nasStatus); goto error; } else{ // Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[dwSharePos] && pVolumeInfo->lpPath) {
FreeADsStr(pObjectInfo->ComponentArray[dwSharePos]); pObjectInfo->ComponentArray[dwSharePos] = AllocADsStr(pVolumeInfo->lpPath); }
if (!pObjectInfo->ComponentArray[dwSharePos]) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
hr = S_OK; goto error; } } else { hr = E_ADS_UNKNOWN_OBJECT ; }
error: if(pVolumeInfo){ ADsNwApiBufferFree(pVolumeInfo); }
if(lpShareInfo1){ NetApiBufferFree(lpShareInfo1); }
RRETURN(hr); }
HRESULT ValidateNamespaceObject( POBJECTINFO pObjectInfo ) { if (!_wcsicmp(pObjectInfo->ProviderName, szProviderName)) { RRETURN(S_OK); } RRETURN(E_FAIL); }
HRESULT ValidateLocalGroupObject( LPWSTR szServerName, LPWSTR *pszGroupName, CWinNTCredentials& Credentials )
{ NET_API_STATUS nasStatus; LPLOCALGROUP_INFO_1 lpGI = NULL; HRESULT hr = S_OK; BOOL fRefAdded = FALSE;
// At this point the host server name has a \\ prepended
// so we need to get rid of it.
hr = Credentials.RefServer(szServerName+2);
if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
nasStatus = NetLocalGroupGetInfo( szServerName, *pszGroupName, 1, (LPBYTE*)(&lpGI) );
//
// if a ref has been added we need to delete if before
// checking the error status.
//
if (fRefAdded) { hr = Credentials.DeRefServer(); // even if we fail, we have no recovery path
fRefAdded = FALSE; }
hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if ((*pszGroupName) && lpGI->lgrpi1_name) { FreeADsStr(*pszGroupName); *pszGroupName = AllocADsStr(lpGI->lgrpi1_name); }
if (!(*pszGroupName)) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
error:
if (lpGI) { NetApiBufferFree(lpGI); }
RRETURN(hr); }
HRESULT ValidateGlobalGroupObject( LPWSTR szServerName, LPWSTR *pszGroupName, CWinNTCredentials& Credentials )
{ NET_API_STATUS nasStatus; LPGROUP_INFO_1 lpGI = NULL; HRESULT hr = S_OK; BOOL fRefAdded = FALSE;
// At this point the host server name has a \\ prepended
// so we need to get rid of it.
hr = Credentials.RefServer(szServerName+2);
if (SUCCEEDED(hr)) { fRefAdded = TRUE; }
nasStatus = NetGroupGetInfo( szServerName, *pszGroupName, 1, (LPBYTE*)(&lpGI) );
//
// if a ref has been added we need to delete if before
// checking the error status.
//
if (fRefAdded) { hr = Credentials.DeRefServer(); // even if we fail, we have no recovery path
fRefAdded = FALSE; }
hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if ((*pszGroupName) && lpGI->grpi1_name) { FreeADsStr(*pszGroupName); *pszGroupName = AllocADsStr(lpGI->grpi1_name); }
if (!(*pszGroupName)) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
error:
if (lpGI) { NetApiBufferFree(lpGI); }
RRETURN(hr); }
HRESULT GetComputerParent( LPTSTR pszComputerName, LPTSTR *ppszComputerParentName, CWinNTCredentials& Credentials )
{ //
// This function returns the computer parent irrespective of whether
// the computer belongs to a domain or to a workgroup
//
HRESULT hr = S_OK; LPTSTR pszComputerParentName = NULL; WCHAR szDomainName[MAX_PATH]; WCHAR szSAMName[MAX_PATH];
szSAMName[0] = L'\0';
hr = WinNTGetCachedComputerName(pszComputerName, szDomainName, szSAMName, Credentials );
BAIL_ON_FAILURE(hr);
pszComputerParentName = AllocADsStr(szDomainName);
if(!pszComputerParentName){ hr = E_OUTOFMEMORY; } *ppszComputerParentName = pszComputerParentName;
error: RRETURN(hr); }
HRESULT ConstructFullObjectInfo( POBJECTINFO pObjectInfo, POBJECTINFO *ppFullObjectInfo, CWinNTCredentials& Credentials ) {
//
// used in the case where the domain name is not specified.
// Here the assumption is that an objectinfo structure with
// domain name not filled in is passed down. We create a new
// object info structure with the domain/workgroup name filled
// in
HRESULT hr = S_OK; POBJECTINFO pTempObjectInfo = NULL; DWORD i; LPWSTR pszComputerParent = NULL;
pTempObjectInfo = (POBJECTINFO)AllocADsMem(sizeof(OBJECTINFO));
if (!pTempObjectInfo) { RRETURN(hr = E_OUTOFMEMORY); }
memset(pTempObjectInfo, 0, sizeof(OBJECTINFO));
if(!pObjectInfo){ RRETURN(E_OUTOFMEMORY); }
pTempObjectInfo->ProviderName = AllocADsStr(pObjectInfo->ProviderName); if(!pTempObjectInfo->ProviderName){ hr = E_OUTOFMEMORY; goto error; } pTempObjectInfo->ObjectType = pObjectInfo->ObjectType; pTempObjectInfo->NumComponents = pObjectInfo->NumComponents +1;
for(i=0; i<MAXCOMPONENTS-1; i++){ if(pObjectInfo->ComponentArray[i]) { pTempObjectInfo->ComponentArray[i+1] = AllocADsStr(pObjectInfo->ComponentArray[i]);
if(!pTempObjectInfo->ComponentArray[i+1]){ hr = E_OUTOFMEMORY; goto error; } } if(pObjectInfo->DisplayComponentArray[i]) { pTempObjectInfo->DisplayComponentArray[i+1] = AllocADsStr(pObjectInfo->DisplayComponentArray[i]);
if(!pTempObjectInfo->DisplayComponentArray[i+1]){ hr = E_OUTOFMEMORY; goto error; } } }
hr = GetComputerParent(pObjectInfo->ComponentArray[0], &(pTempObjectInfo->ComponentArray[0]), Credentials );
BAIL_ON_FAILURE(hr);
hr = GetDisplayName(pTempObjectInfo->ComponentArray[0], &(pTempObjectInfo->DisplayComponentArray[0]) );
*ppFullObjectInfo = pTempObjectInfo ;
RRETURN(S_OK);
error:
FreeObjectInfo( pTempObjectInfo ); *ppFullObjectInfo = NULL; RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetGroupObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT GetLocalGroupObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szGroupName = NULL; DWORD dwParentId = 0; ULONG uGroupType = 0; POBJECTINFO pGroupObjectInfo = NULL;
hr = ValidateGroupObject( pObjectInfo, &uGroupType, &dwParentId, Credentials ); BAIL_ON_FAILURE(hr);
if (uGroupType != WINNT_GROUP_LOCAL) { hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr);
}
switch (pObjectInfo->NumComponents) { case 2: //
// could be group in computer or group in domain
//
if(dwParentId == WINNT_DOMAIN_ID){
szDomainName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
} else {
//
// group in a computer
//
hr = ConstructFullObjectInfo(pObjectInfo, &pGroupObjectInfo, Credentials );
if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
//
// Case when there are no workstation services.
//
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
szDomainName = NULL; szServerName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1];
} else {
BAIL_ON_FAILURE(hr);
hr = BuildParent(pGroupObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pGroupObjectInfo->ComponentArray[0]; szServerName = pGroupObjectInfo->ComponentArray[1]; szGroupName = pGroupObjectInfo->ComponentArray[2];
} }
break;
case 3:
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szGroupName = pObjectInfo->ComponentArray[2]; break;
} hr = CWinNTGroup::CreateGroup(ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); }
RRETURN(hr);
error: if (pUnknown) { pUnknown->Release(); }
if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); }
*ppObject = NULL;
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: GetGroupObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT GetGlobalGroupObject( POBJECTINFO pObjectInfo, LPVOID * ppObject, CWinNTCredentials& Credentials ) {
LPUNKNOWN pUnknown = NULL; WCHAR ADsParent[MAX_ADS_PATH]; HRESULT hr = S_OK; LPWSTR szServerName = NULL; LPWSTR szDomainName = NULL; LPWSTR szGroupName = NULL; DWORD dwParentId = 0; ULONG uGroupType = 0; POBJECTINFO pGroupObjectInfo = NULL;
hr = ValidateGroupObject( pObjectInfo, &uGroupType, &dwParentId, Credentials ); BAIL_ON_FAILURE(hr);
if (uGroupType != WINNT_GROUP_GLOBAL) {
hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); }
switch (pObjectInfo->NumComponents) { case 2: //
// could be group in computer or group in domain
//
if(dwParentId == WINNT_DOMAIN_ID){
szDomainName = pObjectInfo->ComponentArray[0]; szGroupName = pObjectInfo->ComponentArray[1]; szServerName = NULL; hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
} else {
//
// group in a computer
//
hr = ConstructFullObjectInfo(pObjectInfo, &pGroupObjectInfo, Credentials ); BAIL_ON_FAILURE(hr);
hr = BuildParent(pGroupObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pGroupObjectInfo->ComponentArray[0]; szServerName = pGroupObjectInfo->ComponentArray[1]; szGroupName = pGroupObjectInfo->ComponentArray[2];
} break;
case 3:
hr = BuildParent(pObjectInfo, ADsParent); BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0]; szServerName = pObjectInfo->ComponentArray[1]; szGroupName = pObjectInfo->ComponentArray[2]; break;
} hr = CWinNTGroup::CreateGroup(ADsParent, dwParentId, szDomainName, szServerName, szGroupName, uGroupType, ADS_OBJECT_BOUND, IID_IUnknown, Credentials, (void **)&pUnknown ); BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); }
RRETURN(hr);
error: if (pUnknown) { pUnknown->Release(); }
if(pGroupObjectInfo){ FreeObjectInfo(pGroupObjectInfo); }
*ppObject = NULL;
RRETURN(hr); }
|