|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: getobj.cxx
//
// Contents: Windows NT 3.5 GetObject functionality
//
// History:
//----------------------------------------------------------------------------
#include "nds.hxx"
#pragma hdrstop
extern LPWSTR szProviderName;
//+---------------------------------------------------------------------------
// Function: RelativeGetObject
//
// Synopsis: Gets object relative to given Active Directory path.
//
// Arguments: [BSTR ADsPath]
// [BSTR ClassName]
// [BSTR RelativeName]
// [IUnknown** ppObject]
// [BOOT bNamespaceRelative]
//
// Returns: HRESULT
//
// Modifies: *ppObject
//
// History: 08-02-96 t-danal Created as such.
//
//----------------------------------------------------------------------------
HRESULT RelativeGetObject( BSTR ADsPath, BSTR ClassName, BSTR RelativeName, CCredentials& Credentials, IDispatch * FAR* ppObject, BOOL bNamespaceRelative ) { WCHAR szBuffer[MAX_PATH]; ULONG cchBuffer = 0; HRESULT hr = S_OK;
*ppObject = NULL;
if (!RelativeName || !*RelativeName) { RRETURN(E_ADS_UNKNOWN_OBJECT); }
cchBuffer += wcslen(ADsPath); cchBuffer += (bNamespaceRelative ? 2 : 1); cchBuffer += wcslen(RelativeName); cchBuffer += ((ClassName && *ClassName) ? (1 + wcslen(ClassName)) : 0);
if (cchBuffer >= MAX_PATH) { RRETURN(E_OUTOFMEMORY); }
memset(szBuffer, 0, sizeof(szBuffer)); wcscpy(szBuffer, ADsPath);
if (bNamespaceRelative) wcscat(szBuffer, L"//"); else wcscat(szBuffer, L"/"); wcscat(szBuffer, RelativeName);
if (ClassName && *ClassName) { wcscat(szBuffer,L","); wcscat(szBuffer, ClassName); }
hr = ::GetObject( szBuffer, Credentials, (LPVOID *)ppObject ); BAIL_ON_FAILURE(hr);
error: RRETURN(hr); }
//+---------------------------------------------------------------------------
// 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, CCredentials& Credentials, LPVOID * ppObject ) { HRESULT hr; DWORD dwStatus = NO_ERROR; DWORD dwNumberEntries = 0; DWORD dwModificationTime = 0; WCHAR szObjectClassName[MAX_PATH]; WCHAR szObjectFullName[MAX_PATH];
LPWSTR pszNDSPath = NULL;
WCHAR szParent[MAX_PATH]; WCHAR szCommonName[MAX_PATH]; HANDLE hObject = NULL;
OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; CLexer Lexer(szBuffer);
IADs * pADs = NULL;
memset(pObjectInfo, 0, sizeof(OBJECTINFO)); hr = ADsObject(&Lexer, pObjectInfo); BAIL_ON_FAILURE(hr);
//
// Validate that this ADs pathname is to be processed by
// us - as in the provider name is @NDS!
//
hr = ValidateProvider(pObjectInfo); BAIL_ON_FAILURE(hr);
hr = ValidateObjectType(pObjectInfo);
switch (pObjectInfo->ObjectType) {
case TOKEN_NAMESPACE: //
// This means that this is a namespace object;
// instantiate the namespace object
//
hr = GetNamespaceObject( pObjectInfo, Credentials, ppObject ); BAIL_ON_FAILURE(hr);
break;
case TOKEN_SCHEMA:
hr = GetSchemaObject( pObjectInfo, Credentials, ppObject ); BAIL_ON_FAILURE(hr);
break;
default: hr = BuildNDSPathFromADsPath( szBuffer, &pszNDSPath ); BAIL_ON_FAILURE(hr);
dwStatus = ADsNwNdsOpenObject( pszNDSPath, Credentials, &hObject, szObjectFullName, szObjectClassName, &dwModificationTime, &dwNumberEntries );
CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
hr = BuildADsParentPath( szBuffer, szParent, szCommonName ); BAIL_ON_FAILURE(hr);
hr = CNDSGenObject::CreateGenericObject( szParent, szCommonName, szObjectClassName, Credentials, ADS_OBJECT_BOUND, IID_IADs, (void **)&pADs ); BAIL_ON_FAILURE(hr);
//
// InstantiateDerivedObject should add-ref this pointer for us.
//
hr = InstantiateDerivedObject( pADs, Credentials, IID_IUnknown, (void **)ppObject );
if (FAILED(hr)) { hr = pADs->QueryInterface( IID_IUnknown, ppObject ); BAIL_ON_FAILURE(hr);
} break;
}
error: if (hObject) { NwNdsCloseObject(hObject); } if (pszNDSPath) {
FreeADsStr(pszNDSPath); }
if (pADs) { pADs->Release(); }
FreeObjectInfo( &ObjectInfo );
RRETURN(hr); }
HRESULT BuildADsPathFromNDSPath( LPWSTR szNDSTreeName, LPWSTR szNDSDNName, LPWSTR szADsPathName ) { PKEYDATA pKeyData = NULL; DWORD dwCount = 0; DWORD i = 0; LPWSTR pszDisplayTreeName = NULL; LPWSTR pszDisplayDNName = NULL; HRESULT hr = S_OK;
if (!szNDSTreeName || !szNDSDNName) { RRETURN(E_FAIL); }
hr = GetDisplayName( szNDSTreeName, &pszDisplayTreeName ); BAIL_ON_FAILURE(hr);
wsprintf(szADsPathName,L"%s:%s", szProviderName, szNDSTreeName);
hr = GetDisplayName( szNDSDNName, &pszDisplayDNName ); BAIL_ON_FAILURE(hr);
pKeyData = CreateTokenList( pszDisplayDNName, L'.' );
if (pKeyData) {
dwCount = pKeyData->cTokens; for (i = 0; i < dwCount; i++) { wcscat(szADsPathName, L"/"); wcscat(szADsPathName, pKeyData->pTokens[dwCount - 1 - i]); } }
if (pKeyData) { FreeADsMem(pKeyData); }
error:
if (pszDisplayTreeName) { FreeADsMem(pszDisplayTreeName); }
if (pszDisplayDNName) { FreeADsMem(pszDisplayDNName); }
RRETURN(hr); }
HRESULT BuildNDSPathFromADsPath( LPWSTR szADsPathName, LPWSTR * pszNDSPathName ) { OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; CLexer Lexer(szADsPathName); DWORD i = 0; DWORD dwNumComponents = 0; HRESULT hr; LPWSTR szNDSPathName = NULL;
*pszNDSPathName = NULL;
memset(pObjectInfo, 0, sizeof(OBJECTINFO)); hr = ADsObject(&Lexer, pObjectInfo); BAIL_ON_FAILURE(hr);
dwNumComponents = pObjectInfo->NumComponents;
szNDSPathName = AllocADsStr(szADsPathName); if (!szNDSPathName) {
hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
wcscpy(szNDSPathName, L"\\\\"); wcscat(szNDSPathName, pObjectInfo->TreeName);
if (dwNumComponents) {
wcscat(szNDSPathName, L"\\");
for (i = dwNumComponents; i > 0; i--) {
AppendComponent( szNDSPathName, &(pObjectInfo->ComponentArray[i-1]) );
if ((i - 1) > 0){ wcscat(szNDSPathName, L"."); } }
}
*pszNDSPathName = szNDSPathName;
error:
FreeObjectInfo( &ObjectInfo );
RRETURN(hr);
}
HRESULT AppendComponent( LPWSTR szNDSPathName, PCOMPONENT pComponent ) { if (pComponent->szComponent && pComponent->szValue) { wcscat(szNDSPathName, pComponent->szComponent); wcscat(szNDSPathName,L"="); wcscat(szNDSPathName, pComponent->szValue);
}else if (pComponent->szComponent && !pComponent->szValue) { wcscat(szNDSPathName, pComponent->szComponent); }else { //
// we should never hit this case
//
}
RRETURN(S_OK); }
HRESULT BuildADsParentPath( LPWSTR szBuffer, LPWSTR szParent, LPWSTR szCommonName ) { OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; CLexer Lexer(szBuffer); HRESULT hr = S_OK;
memset(pObjectInfo, 0, sizeof(OBJECTINFO)); hr = ADsObject(&Lexer, pObjectInfo); BAIL_ON_FAILURE(hr);
hr = BuildADsParentPath( pObjectInfo, szParent, szCommonName );
error:
FreeObjectInfo( &ObjectInfo ); RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetNamespaceObject
//
// Synopsis: called by GetObject
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT GetNamespaceObject( POBJECTINFO pObjectInfo, CCredentials& Credentials, LPVOID * ppObject ) { HRESULT hr;
hr = ValidateNamespaceObject( pObjectInfo ); BAIL_ON_FAILURE(hr);
hr = CNDSNamespace::CreateNamespace( L"ADs:", L"NDS:", Credentials, ADS_OBJECT_BOUND, IID_IUnknown, ppObject );
error:
RRETURN(hr); }
HRESULT ValidateNamespaceObject( POBJECTINFO pObjectInfo ) { if (!_wcsicmp(pObjectInfo->ProviderName, szProviderName)) { RRETURN(S_OK); } RRETURN(E_FAIL); }
HRESULT ValidateProvider( POBJECTINFO pObjectInfo ) {
//
// The provider name is case-sensitive. This is a restriction that OLE
// has put on us.
//
if (!(wcscmp(pObjectInfo->ProviderName, szProviderName))) { RRETURN(S_OK); } RRETURN(E_FAIL); }
//+---------------------------------------------------------------------------
// Function: GetSchemaObject
//
// Synopsis: called by GetObject
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT GetSchemaObject( POBJECTINFO pObjectInfo, CCredentials& Credentials, LPVOID * ppObject ) { HRESULT hr = S_OK; WCHAR szParent[MAX_PATH]; WCHAR szCommonName[MAX_PATH]; WCHAR szNDSPathName[MAX_PATH]; DWORD dwObjectType = 0; DWORD dwStatus; HANDLE hTree = NULL;
hr = ValidateSchemaObject( pObjectInfo, &dwObjectType ); BAIL_ON_FAILURE(hr);
hr = BuildADsParentPath( pObjectInfo, szParent, szCommonName ); BAIL_ON_FAILURE(hr);
switch(dwObjectType) { case NDS_CLASS_ID: case NDS_PROPERTY_ID: case NDS_CLASSPROP_ID: wcscpy(szNDSPathName, L"\\\\"); wcscat(szNDSPathName, pObjectInfo->TreeName); dwStatus = ADsNwNdsOpenObject( szNDSPathName, Credentials, &hTree, NULL, NULL, NULL, NULL );
CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr); break;
default: break; }
//
// Note: The "error:" tag is at the end of the switch statement,
// so we can simply break out.
//
switch (dwObjectType) { case NDS_SCHEMA_ID: hr = CNDSSchema::CreateSchema( szParent, szCommonName, Credentials, ADS_OBJECT_BOUND, IID_IUnknown, ppObject ); break;
case NDS_CLASSPROP_ID: hr = CNDSClass::CreateClass( szParent, szCommonName, hTree, Credentials, ADS_OBJECT_BOUND, IID_IUnknown, ppObject ); if (FAILED(hr)) {
hr = CNDSProperty::CreateProperty( szParent, szCommonName, hTree, Credentials, ADS_OBJECT_BOUND, IID_IUnknown, ppObject ); BAIL_ON_FAILURE(hr);
} break;
case NDS_CLASS_ID: hr = CNDSClass::CreateClass( szParent, szCommonName, hTree, Credentials, ADS_OBJECT_BOUND, IID_IUnknown, ppObject ); break;
case NDS_PROPERTY_ID: hr = CNDSProperty::CreateProperty( szParent, szCommonName, hTree, Credentials, ADS_OBJECT_BOUND, IID_IUnknown, ppObject ); break;
default: hr = E_ADS_UNKNOWN_OBJECT; break; }
error: if (hTree) { NwNdsCloseObject(hTree); } RRETURN(hr); }
HRESULT ValidateSchemaObject( POBJECTINFO pObjectInfo, PDWORD pdwObjectType ) { DWORD dwNumComponents = 0;
dwNumComponents = pObjectInfo->NumComponents;
switch (dwNumComponents) {
case 1: if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent, L"schema")) { *pdwObjectType = NDS_SCHEMA_ID; RRETURN(S_OK); } break;
case 2: if (pObjectInfo->ClassName) { if (!_wcsicmp(pObjectInfo->ClassName, L"Property")) { *pdwObjectType = NDS_PROPERTY_ID; } else { *pdwObjectType = NDS_CLASS_ID; } } else { *pdwObjectType = NDS_CLASSPROP_ID; } RRETURN(S_OK);
/* if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent, L"schema")) {
*pdwObjectType = NDS_CLASS_ID; RRETURN(S_OK); } break;
case 3: if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,SCHEMA_NAME)) { *pdwObjectType = NDS_PROPERTY_ID; RRETURN(S_OK); } break; */
default: break;
}
RRETURN(E_FAIL); }
HRESULT BuildADsParentPath( POBJECTINFO pObjectInfo, LPWSTR szParent, LPWSTR szCommonName ) { DWORD i = 0; DWORD dwNumComponents = 0; HRESULT hr;
dwNumComponents = pObjectInfo->NumComponents;
if (!dwNumComponents && !pObjectInfo->DisplayTreeName) { //
// There are no CNs in this pathname and
// no tree name specified. This is the
// namespace object - its parent is the
// @ADs! object
//
wsprintf(szParent,L"ADs:");
RRETURN(S_OK);
} else if (!dwNumComponents && pObjectInfo->DisplayTreeName) { //
// There are no CNs in this pathname and a tree
// name has been specified. This is the root
// object - its parent is the @NDS! object
wsprintf(szParent, L"%s:", pObjectInfo->ProviderName);
//
// And the common name is the TreeName. Remember the
// "//" will be added on when we reconstruct the full
// pathname
//
wsprintf(szCommonName,L"%s", pObjectInfo->DisplayTreeName);
RRETURN(S_OK);
}else { //
// There are one or more CNs, a tree name has been
// specified. In the worst case the parent is the
// root object. In the best case a long CN.
//
wsprintf( szParent, L"%s://%s", pObjectInfo->ProviderName, pObjectInfo->DisplayTreeName );
for (i = 0; i < dwNumComponents - 1; i++) {
wcscat(szParent, L"/");
AppendComponent(szParent, &(pObjectInfo->DisplayComponentArray[i]));
}
//
// And the common name is the last component
//
szCommonName[0] = '\0'; AppendComponent(szCommonName, &(pObjectInfo->DisplayComponentArray[dwNumComponents-1])); }
RRETURN(S_OK); }
HRESULT ValidateObjectType( POBJECTINFO pObjectInfo ) {
pObjectInfo->ObjectType = TOKEN_NDSOBJECT;
if (pObjectInfo->ProviderName && !pObjectInfo->TreeName && !pObjectInfo->NumComponents) { pObjectInfo->ObjectType = TOKEN_NAMESPACE; }else if (pObjectInfo->ProviderName && pObjectInfo->TreeName && pObjectInfo->NumComponents) {
if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"schema")) { pObjectInfo->ObjectType = TOKEN_SCHEMA; }
}
RRETURN(S_OK); }
HRESULT BuildNDSTreeNameFromADsPath( LPWSTR szBuffer, LPWSTR szNDSTreeName ) { OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; CLexer Lexer(szBuffer); DWORD dwNumComponents = 0; HRESULT hr;
memset(pObjectInfo, 0, sizeof(OBJECTINFO)); hr = ADsObject(&Lexer, pObjectInfo); BAIL_ON_FAILURE(hr);
dwNumComponents = pObjectInfo->NumComponents;
if (!dwNumComponents && !pObjectInfo->TreeName) { //
// There are no CNs in this pathname and
// no tree name specified. This is the
// namespace object - its parent is the
// @ADs! object
//
hr = E_FAIL;
} else if (!dwNumComponents && pObjectInfo->TreeName) { //
// There are no CNs in this pathname and a tree
// name has been specified. This is the root
// object - its parent is the @NDS! object
wsprintf(szNDSTreeName,L"\\\\%s", pObjectInfo->TreeName);
hr = S_OK;
}else { //
// There are one or more CNs, a tree name has been
// specified. In the worst case the parent is the
// root object. In the best case a long CN.
//
wsprintf(szNDSTreeName,L"\\\\%s", pObjectInfo->TreeName);
hr = S_OK; }
error:
FreeObjectInfo( &ObjectInfo ); RRETURN(hr);
}
HRESULT BuildNDSPathFromADsPath( LPWSTR szADsPathName, LPWSTR szNDSTreeName, LPWSTR szNDSPathName ) { OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; CLexer Lexer(szADsPathName); DWORD i = 0; DWORD dwNumComponents = 0; HRESULT hr;
memset(pObjectInfo, 0, sizeof(OBJECTINFO)); hr = ADsObject(&Lexer, pObjectInfo); BAIL_ON_FAILURE(hr);
dwNumComponents = pObjectInfo->NumComponents;
wcscpy(szNDSTreeName, L"\\\\"); wcscat(szNDSTreeName, pObjectInfo->TreeName);
*szNDSPathName = L'\0';
if (dwNumComponents) {
for (i = dwNumComponents; i > 0; i--) {
AppendComponent( szNDSPathName, &(pObjectInfo->ComponentArray[i-1]) );
if ((i - 1) > 0){ wcscat(szNDSPathName, L"."); } }
}
error:
FreeObjectInfo( &ObjectInfo ); RRETURN(hr); }
VOID FreeObjectInfo( POBJECTINFO pObjectInfo ) { if ( !pObjectInfo ) return;
FreeADsStr( pObjectInfo->ProviderName ); FreeADsStr( pObjectInfo->TreeName ); FreeADsStr( pObjectInfo->DisplayTreeName ); FreeADsStr( pObjectInfo->ClassName); for ( DWORD i = 0; i < pObjectInfo->NumComponents; i++ ) { FreeADsStr( pObjectInfo->ComponentArray[i].szComponent ); FreeADsStr( pObjectInfo->ComponentArray[i].szValue ); FreeADsStr( pObjectInfo->DisplayComponentArray[i].szComponent ); FreeADsStr( pObjectInfo->DisplayComponentArray[i].szValue ); }
// We don't need to free pObjectInfo since the object is always a static
// variable on the stack.
}
HRESULT GetDisplayName( LPWSTR szName, LPWSTR *ppszDisplayName ) {
HRESULT hr = S_OK; DWORD len = 0; LPWSTR pch = szName; LPWSTR pszDisplayCh = NULL, pszDisplay = NULL; BOOL fQuotingOn = FALSE;
if (!ppszDisplayName ) { RRETURN (E_INVALIDARG); }
*ppszDisplayName = NULL;
if (!szName) { RRETURN (S_OK); }
pch = szName; fQuotingOn = FALSE;
for (len=0; *pch; pch++, len++) { if ((!(pch > szName && *(pch-1) == '\\')) && (*pch == L'"') ) { fQuotingOn = ~fQuotingOn; } else if (!fQuotingOn && (!(pch > szName && *(pch-1) == '\\')) && (*pch == L'/' || *pch == L'<' || *pch == L'>') ) { len++; } }
pszDisplay = (LPWSTR) AllocADsMem((len+1) * sizeof(WCHAR));
if (!pszDisplay) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); }
pch = szName; pszDisplayCh = pszDisplay; fQuotingOn = FALSE;
for (; *pch; pch++, pszDisplayCh++) { if ((!(pch > szName && *(pch-1) == '\\')) && (*pch == L'"') ) { fQuotingOn = ~fQuotingOn; } else if (!fQuotingOn && (!(pch > szName && *(pch-1) == '\\')) && (*pch == L'/' || *pch == L'<' || *pch == L'>') ) { *pszDisplayCh++ = L'\\'; } *pszDisplayCh = *pch; }
*pszDisplayCh = L'\0';
*ppszDisplayName = pszDisplay;
error:
RRETURN(hr);
}
|