windows-nt/Source/XPSP1/NT/inetsrv/iis/admin/adsi/adsiis/getobj.cxx
2020-09-26 16:20:57 +08:00

1214 lines
27 KiB
C++

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1997
//
// File: getobj.cxx
//
// Contents: ADSI GetObject functionality
//
// History: 25-Feb-97 SophiaC Created.
// 25-Jun-97 MagnusH Added private extension mechanism
//
//----------------------------------------------------------------------------
#include "iis.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]
// [BOOL bNamespaceRelative]
//
// Returns: HRESULT
//
// Modifies: *ppObject
//
//----------------------------------------------------------------------------
HRESULT
RelativeGetObject(
BSTR ADsPath,
BSTR ClassName,
BSTR RelativeName,
CCredentials& Credentials,
IDispatch * FAR* ppObject,
BOOL bNamespaceRelative
)
{
HRESULT hr = S_OK;
LPWSTR pszBuffer = NULL;
DWORD dwLen;
*ppObject = NULL;
if (!RelativeName || !*RelativeName) {
RRETURN(E_ADS_UNKNOWN_OBJECT);
}
dwLen = wcslen(ADsPath) + wcslen(RelativeName) + wcslen(ClassName) + 4;
pszBuffer = (LPWSTR)AllocADsMem(dwLen*sizeof(WCHAR));
if (!pszBuffer) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
wcscpy(pszBuffer, ADsPath);
if (bNamespaceRelative)
wcscat(pszBuffer, L"//");
else
wcscat(pszBuffer, L"/");
wcscat(pszBuffer, RelativeName);
if (ClassName && *ClassName) {
wcscat(pszBuffer,L",");
wcscat(pszBuffer, ClassName);
}
hr = ::GetObject(
pszBuffer,
Credentials,
(LPVOID *)ppObject
);
BAIL_ON_FAILURE(hr);
error:
if (pszBuffer) {
FreeADsMem(pszBuffer);
}
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetObject
//
// Synopsis: Called by ResolvePathName to return an object
//
// Arguments: [LPWSTR szBuffer]
// [LPVOID *ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
//----------------------------------------------------------------------------
HRESULT
GetObject(
LPWSTR szBuffer,
CCredentials& Credentials,
LPVOID * ppObject
)
{
HRESULT hr;
DWORD dwStatus = NO_ERROR;
WCHAR szCommonName[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
LPWSTR pszParent = NULL;
IMSAdminBase * pAdminBase = NULL;
METADATA_HANDLE hObjHandle = NULL;
METADATA_RECORD mdrData;
LPWSTR pszIISPathName = NULL;
WCHAR DataBuf[MAX_PATH];
DWORD dwReqdBufferLen;
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = &ObjectInfo;
CLexer Lexer(szBuffer);
IIsSchema *pSchema = NULL;
IADs * pADs = NULL;
//
// Parse the pathname
//
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 @IIS!
//
hr = InitServerInfo(pObjectInfo->TreeName, &pAdminBase, &pSchema);
BAIL_ON_FAILURE(hr);
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,
pSchema,
ppObject
);
BAIL_ON_FAILURE(hr);
break;
case TOKEN_CLASS:
hr = GetClassObject(
pObjectInfo,
pSchema,
ppObject
);
BAIL_ON_FAILURE(hr);
break;
case TOKEN_PROPERTY:
hr = GetPropertyObject(
pObjectInfo,
pSchema,
ppObject
);
BAIL_ON_FAILURE(hr);
break;
case TOKEN_SYNTAX:
hr = GetSyntaxObject(
pObjectInfo,
ppObject
);
BAIL_ON_FAILURE(hr);
break;
default:
pszIISPathName = AllocADsStr(szBuffer);
if (!pszIISPathName) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
*pszIISPathName = L'\0';
hr = BuildIISPathFromADsPath(
pObjectInfo,
pszIISPathName
);
BAIL_ON_FAILURE(hr);
hr = OpenAdminBaseKey(
pObjectInfo->TreeName,
(LPWSTR)pszIISPathName,
METADATA_PERMISSION_READ,
&pAdminBase,
&hObjHandle
);
BAIL_ON_FAILURE(hr);
//
// Find out Class Name
//
mdrData.dwMDIdentifier = MD_KEY_TYPE;
mdrData.dwMDDataType = STRING_METADATA;
mdrData.dwMDUserType = ALL_METADATA;
mdrData.dwMDAttributes = METADATA_INHERIT;
mdrData.dwMDDataLen = MAX_PATH;
mdrData.pbMDData = (PBYTE)DataBuf;
hr = pAdminBase->GetData(
hObjHandle,
L"",
&mdrData,
&dwReqdBufferLen
);
if (FAILED(hr)) {
if (hr == MD_ERROR_DATA_NOT_FOUND) {
memcpy((LPWSTR)DataBuf, DEFAULT_SCHEMA_CLASS_W,
SIZEOF_DEFAULT_CLASS_W);
if (pObjectInfo->ClassName[0] != L'\0' &&
_wcsicmp((LPWSTR)pObjectInfo->ClassName, DataBuf)) {
hr = E_ADS_BAD_PARAMETER;
BAIL_ON_FAILURE(hr);
}
}
else {
BAIL_ON_FAILURE(hr);
}
}
else {
if (pObjectInfo->ClassName[0] != L'\0' &&
_wcsicmp((LPWSTR)pObjectInfo->ClassName, DataBuf)) {
hr = E_ADS_BAD_PARAMETER;
BAIL_ON_FAILURE(hr);
}
hr = pSchema->ValidateClassName((LPWSTR)DataBuf);
if (hr == E_ADS_SCHEMA_VIOLATION) {
memcpy((LPWSTR)DataBuf, DEFAULT_SCHEMA_CLASS_W,
SIZEOF_DEFAULT_CLASS_W);
}
}
//
// Close the handle now
//
if (hObjHandle) {
CloseAdminBaseKey(pAdminBase, hObjHandle);
hObjHandle = NULL;
}
pszParent = AllocADsStr(szBuffer);
if (!pszParent) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
*pszParent = L'\0';
hr = BuildADsParentPath(
szBuffer,
pszParent,
szCommonName
);
BAIL_ON_FAILURE(hr);
hr = CIISGenObject::CreateGenericObject(
pszParent,
szCommonName,
(LPWSTR)DataBuf,
Credentials,
ADS_OBJECT_BOUND,
IID_IDispatch,
(void **)&pADs
);
BAIL_ON_FAILURE(hr);
hr = pADs->QueryInterface(
IID_IDispatch,
ppObject
);
BAIL_ON_FAILURE(hr);
}
error:
if (pAdminBase && hObjHandle) {
CloseAdminBaseKey(pAdminBase, hObjHandle);
}
if (pADs) {
pADs->Release();
}
if (pszIISPathName) {
FreeADsStr(pszIISPathName);
}
if (pszParent) {
FreeADsStr(pszParent);
}
FreeObjectInfo( &ObjectInfo );
RRETURN(hr);
}
HRESULT
BuildIISPathFromADsPath(
LPWSTR szADsPathName,
LPWSTR * pszIISPathName
)
{
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = &ObjectInfo;
CLexer Lexer(szADsPathName);
DWORD i = 0;
HRESULT hr;
LPWSTR szIISPathName = NULL;
*pszIISPathName = NULL;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = ADsObject(&Lexer, pObjectInfo);
BAIL_ON_FAILURE(hr);
szIISPathName = AllocADsStr(szADsPathName);
if (!szIISPathName) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
*szIISPathName = L'\0';
hr = BuildIISPathFromADsPath(pObjectInfo, szIISPathName);
BAIL_ON_FAILURE(hr);
*pszIISPathName = szIISPathName;
error:
FreeObjectInfo( &ObjectInfo );
RRETURN(hr);
}
HRESULT
BuildIISPathFromADsPath(
POBJECTINFO pObjectInfo,
LPWSTR pszIISPathName
)
{
DWORD dwNumComponents = 0;
DWORD i = 0;
dwNumComponents = pObjectInfo->NumComponents;
//
// wcscat "LM" to IIS Metabase path
//
wcscat(pszIISPathName, L"/LM/");
if (dwNumComponents) {
for (i = 0; i < dwNumComponents; i++) {
wcscat(pszIISPathName, pObjectInfo->ComponentArray[i].szComponent);
if( i < dwNumComponents -1 ) {
wcscat(pszIISPathName,L"/");
}
}
}
RRETURN(S_OK);
}
HRESULT
BuildADsParentPath(
LPWSTR szBuffer,
LPWSTR szParent,
LPWSTR szCommonName
)
{
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = &ObjectInfo;
CLexer Lexer(szBuffer);
DWORD i = 0;
DWORD dwNumComponents = 0;
HRESULT hr;
LPWSTR pszComponent = NULL, pszValue = NULL;
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
//
wsprintf(szParent,L"ADs:");
hr = S_OK;
} 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 @IIS! object
wsprintf(szParent, L"%s:", pObjectInfo->ProviderName);
//
// And the common name is the TreeName
//
wsprintf(szCommonName,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(
szParent, L"%s://%s",
pObjectInfo->ProviderName,
pObjectInfo->TreeName
);
for (i = 0; i < dwNumComponents - 1; i++) {
wcscat(szParent, L"/");
pszComponent = pObjectInfo->ComponentArray[i].szComponent;
pszValue = pObjectInfo->ComponentArray[i].szValue;
if (pszComponent && pszValue) {
wcscat(
szParent,
pObjectInfo->ComponentArray[i].szComponent
);
wcscat(szParent,L"=");
wcscat(
szParent,
pObjectInfo->ComponentArray[i].szValue
);
}else if (pszComponent){
wcscat(
szParent,
pObjectInfo->ComponentArray[i].szComponent
);
}else {
//
// Error - we should never hit this case!!
//
}
}
//
// And the common name is the last component
//
pszComponent = pObjectInfo->ComponentArray[dwNumComponents - 1].szComponent;
pszValue = pObjectInfo->ComponentArray[dwNumComponents - 1].szValue;
if (pszComponent && pszValue) {
wsprintf(szCommonName, L"%s=%s",pszComponent, pszValue);
}else if (pszComponent){
wsprintf(szCommonName, L"%s", pszComponent);
}else {
//
// Error - we should never hit this case!!
//
}
}
error:
FreeObjectInfo( &ObjectInfo );
RRETURN(hr);
}
HRESULT
BuildADsParentPath(
POBJECTINFO pObjectInfo,
LPWSTR szParent,
LPWSTR szCommonName
)
{
DWORD i = 0;
DWORD dwNumComponents = 0;
HRESULT hr;
LPWSTR pszComponent = NULL, pszValue = NULL;
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
//
wsprintf(szParent,L"ADs:");
RRETURN(S_OK);
} 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 @IIS! 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->TreeName);
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->TreeName
);
for (i = 0; i < dwNumComponents - 1; i++) {
wcscat(szParent, L"/");
pszComponent = pObjectInfo->ComponentArray[i].szComponent;
pszValue = pObjectInfo->ComponentArray[i].szValue;
if (pszComponent && pszValue) {
wcscat(
szParent,
pObjectInfo->ComponentArray[i].szComponent
);
wcscat(szParent,L"=");
wcscat(
szParent,
pObjectInfo->ComponentArray[i].szValue
);
}else if (pszComponent){
wcscat(
szParent,
pObjectInfo->ComponentArray[i].szComponent
);
}else {
//
// Error - we should never hit this case!!
//
}
}
//
// And the common name is the last component
//
pszComponent = pObjectInfo->ComponentArray[dwNumComponents - 1].szComponent;
pszValue = pObjectInfo->ComponentArray[dwNumComponents - 1].szValue;
if (pszComponent && pszValue) {
wsprintf(szCommonName, L"%s=%s",pszComponent, pszValue);
}else if (pszComponent){
wsprintf(szCommonName, L"%s", pszComponent);
}else {
//
// Error - we should never hit this case!!
//
}
}
RRETURN(S_OK);
}
VOID
FreeObjectInfo(
POBJECTINFO pObjectInfo
)
{
if ( !pObjectInfo )
return;
FreeADsStr( pObjectInfo->ProviderName );
FreeADsStr( pObjectInfo->TreeName );
for ( DWORD i = 0; i < pObjectInfo->NumComponents; i++ ) {
if (pObjectInfo->ComponentArray[i].szComponent) {
FreeADsStr( pObjectInfo->ComponentArray[i].szComponent );
}
if (pObjectInfo->ComponentArray[i].szValue) {
FreeADsStr( pObjectInfo->ComponentArray[i].szValue );
}
}
if (pObjectInfo->ComponentArray) {
FreeADsMem(pObjectInfo->ComponentArray);
}
// We don't need to free pObjectInfo since the object is always a static
// variable on the stack.
}
//+---------------------------------------------------------------------------
// Function: GetNamespaceObject
//
// Synopsis: called by GetObject
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
//----------------------------------------------------------------------------
HRESULT
GetNamespaceObject(
POBJECTINFO pObjectInfo,
CCredentials& Credentials,
LPVOID * ppObject
)
{
HRESULT hr;
hr = ValidateNamespaceObject(
pObjectInfo
);
BAIL_ON_FAILURE(hr);
hr = CIISNamespace::CreateNamespace(
L"ADs:",
L"IIS:",
Credentials,
ADS_OBJECT_BOUND,
IID_IUnknown,
ppObject
);
error:
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetSchemaObject
//
// Synopsis: called by GetObject
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
//----------------------------------------------------------------------------
HRESULT
GetSchemaObject(
POBJECTINFO pObjectInfo,
IIsSchema *pSchemaCache,
LPVOID * ppObject
)
{
HRESULT hr = S_OK;
DWORD dwObjectType = 0;
hr = ValidateSchemaObject(
pObjectInfo,
&dwObjectType
);
BAIL_ON_FAILURE(hr);
//
// Note: The "error:" tag is at the end of the switch statement,
// so we can simply break out.
//
switch (dwObjectType) {
case IIS_SCHEMA_ID:
hr = GetIntSchemaObject(
pObjectInfo,
ppObject
);
break;
case IIS_CLASSPROP_ID:
hr = GetClassObject(
pObjectInfo,
pSchemaCache,
ppObject
);
if (FAILED(hr)) {
hr = GetPropertyObject(
pObjectInfo,
pSchemaCache,
ppObject
);
if (FAILED(hr)) {
hr = GetSyntaxObject(
pObjectInfo,
ppObject
);
}
if (FAILED(hr)) {
hr = E_ADS_UNKNOWN_OBJECT;
}
}
break;
default:
hr = E_ADS_UNKNOWN_OBJECT;
break;
}
error:
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetSchemaObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
//----------------------------------------------------------------------------
HRESULT
GetIntSchemaObject(
POBJECTINFO pObjInfo,
LPVOID * ppObject
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
WCHAR ADsName[MAX_PATH];
HRESULT hr = S_OK;
if (pObjInfo->NumComponents != 1)
RRETURN(E_ADS_BAD_PATHNAME);
if ( _wcsicmp( pObjInfo->ComponentArray[0].szComponent, SCHEMA_NAME ) != 0 )
{
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
hr = BuildADsParentPath(pObjInfo, ADsParent, ADsName);
BAIL_ON_FAILURE(hr);
hr = CIISSchema::CreateSchema( pObjInfo->TreeName,
ADsParent,
pObjInfo->ComponentArray[0].szComponent,
ADS_OBJECT_BOUND,
IID_IUnknown,
(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:
//
//----------------------------------------------------------------------------
HRESULT
GetClassObject(
POBJECTINFO pObjInfo,
IIsSchema *pSchemaCache,
LPVOID * ppObject
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
WCHAR ADsName[MAX_PATH];
HRESULT hr = S_OK;
DWORD i;
DWORD dwNumComponents = pObjInfo->NumComponents;
if ( dwNumComponents != 2 && dwNumComponents != 3)
RRETURN(E_ADS_BAD_PATHNAME);
if ( (dwNumComponents == 2 &&
_wcsicmp( pObjInfo->ComponentArray[0].szComponent, SCHEMA_NAME ) != 0 ) ||
(dwNumComponents == 3 &&
_wcsicmp( pObjInfo->ComponentArray[0].szComponent, CLASS_CLASS_NAME ) != 0 ))
{
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
//
// Validate the given class name
//
hr = pSchemaCache->ValidateClassName(
pObjInfo->ComponentArray[dwNumComponents-1].szComponent);
BAIL_ON_FAILURE(hr);
//
// Class name found, create and return the object
//
hr = BuildADsParentPath(pObjInfo, ADsParent, ADsName);
BAIL_ON_FAILURE(hr);
hr = CIISClass::CreateClass( ADsParent,
pObjInfo->ComponentArray[dwNumComponents-1].szComponent,
ADS_OBJECT_BOUND,
IID_IUnknown,
(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:
//
//----------------------------------------------------------------------------
HRESULT
GetSyntaxObject(
POBJECTINFO pObjInfo,
LPVOID * ppObject
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
WCHAR ADsName[MAX_PATH];
HRESULT hr = S_OK;
DWORD i;
DWORD dwNumComponents = pObjInfo->NumComponents;
if (dwNumComponents != 2 && dwNumComponents != 3)
RRETURN(E_ADS_BAD_PATHNAME);
if ( (dwNumComponents == 2 &&
_wcsicmp( pObjInfo->ComponentArray[0].szComponent, SCHEMA_NAME ) != 0 ) ||
(dwNumComponents == 3 &&
_wcsicmp( pObjInfo->ComponentArray[0].szComponent, SYNTAX_CLASS_NAME ) != 0 ))
{
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
//
// Look for the given syntax name
//
for ( i = 0; i < g_cIISSyntax; i++ )
{
if ( _wcsicmp( g_aIISSyntax[i].bstrName,
pObjInfo->ComponentArray[dwNumComponents-1].szComponent ) == 0 )
break;
}
if ( i == g_cIISSyntax )
{
// Syntax name not found, return error
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
//
// Syntax name found, create and return the object
//
hr = BuildADsParentPath(pObjInfo, ADsParent, ADsName);
BAIL_ON_FAILURE(hr);
hr = CIISSyntax::CreateSyntax( ADsParent,
&(g_aIISSyntax[i]),
ADS_OBJECT_BOUND,
IID_IUnknown,
(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:
//
//----------------------------------------------------------------------------
HRESULT
GetPropertyObject(
POBJECTINFO pObjInfo,
IIsSchema *pSchemaCache,
LPVOID * ppObject
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
WCHAR ADsName[MAX_PATH];
HRESULT hr = S_OK;
DWORD i;
DWORD dwNumComponents = pObjInfo->NumComponents;
if (dwNumComponents != 2 && dwNumComponents != 3)
RRETURN(E_ADS_BAD_PATHNAME);
if ( (dwNumComponents == 2 &&
_wcsicmp( pObjInfo->ComponentArray[0].szComponent, SCHEMA_NAME ) != 0 ) ||
(dwNumComponents == 3 &&
_wcsicmp( pObjInfo->ComponentArray[0].szComponent, PROPERTY_CLASS_NAME ) != 0 ))
{
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
//
// Validate the given property name
//
hr = pSchemaCache->ValidatePropertyName(
pObjInfo->ComponentArray[dwNumComponents-1].szComponent);
BAIL_ON_FAILURE(hr);
//
// Property name is found, so create and return the object
//
hr = BuildADsParentPath(pObjInfo, ADsParent, ADsName);
BAIL_ON_FAILURE(hr);
hr = CIISProperty::CreateProperty(
ADsParent,
pObjInfo->ComponentArray[dwNumComponents-1].szComponent,
ADS_OBJECT_BOUND,
IID_IUnknown,
(void **)&pUnknown );
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error:
if (pUnknown)
pUnknown->Release();
*ppObject = NULL;
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);
}
HRESULT
ValidateObjectType(
POBJECTINFO pObjectInfo
)
{
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;
}
else if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"class")) {
pObjectInfo->ObjectType = TOKEN_CLASS;
}
else if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"property")) {
pObjectInfo->ObjectType = TOKEN_PROPERTY;
}
else if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"syntax")) {
pObjectInfo->ObjectType = TOKEN_SYNTAX;
}
}
RRETURN(S_OK);
}
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 = IIS_SCHEMA_ID;
RRETURN(S_OK);
}
break;
case 2:
*pdwObjectType = IIS_CLASSPROP_ID;
RRETURN(S_OK);
default:
break;
}
RRETURN(E_FAIL);
}