home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
msdn_vcb
/
samples
/
vc98
/
sdk
/
netds
/
adsi
/
sampprov
/
getobj.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-29
|
21KB
|
931 lines
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
GetObj.cpp
Abstract:
Sample Provider GetObject functionality
Author:
Environment:
User mode
Revision History :
--*/
#include "adssmp.h"
#pragma hdrstop
//+---------------------------------------------------------------------------
// Function: RelativeGetObject
//
// Synopsis: Gets object relative to given OLE DS path.
//
// Arguments: [BSTR ADsPath]
// [BSTR ClassName]
// [BSTR RelativeName]
// [IUnknown** ppObject]
// [BOOT bNamespaceRelative]
//
// Returns: HRESULT
//
// Modifies: *ppObject
//
//----------------------------------------------------------------------------
HRESULT
RelativeGetObject(
BSTR ADsPath,
BSTR ClassName,
BSTR RelativeName,
IDispatch* FAR* ppObject,
BOOL bNamespaceRelative
)
{
WCHAR szBuffer[MAX_PATH];
HRESULT hr = S_OK;
*ppObject = NULL;
if (!RelativeName || !*RelativeName) {
RRETURN(E_ADS_UNKNOWN_OBJECT);
}
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,
(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
//
//----------------------------------------------------------------------------
HRESULT
GetObject(
LPWSTR szBuffer,
LPVOID * ppObject
)
{
HRESULT hr;
DWORD dwStatus = NO_ERROR;
DWORD dwNumberEntries = 0;
DWORD dwModificationTime = 0;
WCHAR szObjectClassName[MAX_PATH];
WCHAR szDSPath[MAX_PATH];
WCHAR szParent[MAX_PATH];
WCHAR szCommonName[MAX_PATH];
HANDLE hObject = NULL;
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = &ObjectInfo;
CLexer Lexer(szBuffer);
IADs * pADs = NULL;
szObjectClassName[0]=L'\0';
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 @Sample!
//
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,
ppObject
);
BAIL_ON_FAILURE(hr);
break;
case TOKEN_SCHEMA:
hr = GetSchemaObject(
pObjectInfo,
ppObject
);
BAIL_ON_FAILURE(hr);
break;
default:
hr = BuildDSPathFromADsPath(
szBuffer,
szDSPath
);
BAIL_ON_FAILURE(hr);
hr = SampleDSOpenObject(
szDSPath,
&hObject,
szObjectClassName,
REG_DS);
BAIL_ON_FAILURE(hr);
hr = BuildADsParentPath(
szBuffer,
szParent,
szCommonName
);
BAIL_ON_FAILURE(hr);
hr = CSampleDSGenObject::CreateGenericObject(
szParent,
szCommonName,
szObjectClassName,
ADS_OBJECT_BOUND,
IID_IUnknown,
(void**)ppObject
);
BAIL_ON_FAILURE(hr);
break;
}
error:
if (pADs) {
pADs->Release();
}
if (hObject) {
SampleDSCloseObject(hObject);
}
RRETURN(hr);
}
HRESULT
BuildADsPathFromDSPath(
LPWSTR szDSRootRDN,
LPWSTR szDSDNName,
LPWSTR szADsPathName
)
{
PKEYDATA pKeyData = NULL;
DWORD dwCount = 0;
DWORD i = 0;
if (!szDSRootRDN || !szDSDNName) {
RRETURN(E_FAIL);
}
wsprintf(szADsPathName,L"%s:%s", g_szProviderName, szDSRootRDN);
pKeyData = CreateTokenList(
szDSDNName,
L'.'
);
if (pKeyData) {
dwCount = pKeyData->cTokens;
for (i = 0; i < dwCount; i++) {
wcscat(szADsPathName, L"/");
wcscat(szADsPathName, pKeyData->pTokens[dwCount - 1 - i]);
}
}
if (pKeyData) {
FreeProvMem(pKeyData);
}
RRETURN(S_OK);
}
HRESULT
BuildDSTreeNameFromADsPath(
LPWSTR szBuffer,
LPWSTR szSampleDSTreeName
)
{
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->RootRDN) {
//
// 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->RootRDN) {
//
// There are no CNs in this pathname and a tree
// name has been specified. This is the root
// object - its parent is the @SampleDS! object
wsprintf(szSampleDSTreeName,L"\\\\%s", pObjectInfo->RootRDN);
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(szSampleDSTreeName,L"\\\\%s", pObjectInfo->RootRDN);
hr = S_OK;
}
error:
RRETURN(hr);
}
HRESULT
BuildDSPathFromADsPath(
LPWSTR szADsPathName,
LPWSTR szDSPathName
)
{
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(szDSPathName, L"\\");
wcscat(szDSPathName, pObjectInfo->RootRDN);
for (i = 0; i < dwNumComponents; i++) {
wcscat(szDSPathName, L"\\");
wcscat(szDSPathName, pObjectInfo->ComponentArray[i].szComponent);
}
error:
RRETURN(hr);
}
HRESULT
AppendComponent(
LPWSTR szDSPathName,
PCOMPONENT pComponent
){
DebugBreak();
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->RootRDN) {
//
// There are no CNs in this pathname and
// no Root name specified. This is the
// namespace object - its parent is the
// @ADs! object
//
wsprintf(szParent,L"ADs:");
RRETURN(S_OK);
} else if (!dwNumComponents && pObjectInfo->RootRDN) {
//
// There are no CNs in this pathname and a Root
// name has been specified. This is the root
// object - its parent is the @Sample! object
wsprintf(szParent, L"%s:", pObjectInfo->ProviderName);
//
// And the common name is the RootRDN
//
wsprintf(szCommonName,L"%s", pObjectInfo->RootRDN);
RRETURN(S_OK);
}else {
//
// There are one or more CNs, a Root 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->RootRDN
);
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:
RRETURN(hr);
}
HRESULT
InstantiateDerivedObject(
IADs FAR * pADs,
REFIID riid,
void ** ppObject
)
{
*ppObject = 0;
RRETURN(S_OK);
}
//+---------------------------------------------------------------------------
// Function: GetNamespaceObject
//
// Synopsis: called by GetObject
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
//----------------------------------------------------------------------------
HRESULT
GetNamespaceObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject
)
{
HRESULT hr;
hr = ValidateNamespaceObject(
pObjectInfo
);
BAIL_ON_FAILURE(hr);
hr = CoCreateInstance(CLSID_SampleDSNamespace,
NULL,
CLSCTX_INPROC_SERVER,
IID_IUnknown,
(void **)ppObject
);
error:
RRETURN(hr);
}
HRESULT
ValidateNamespaceObject(
POBJECTINFO pObjectInfo
)
{
if (!_wcsicmp(pObjectInfo->ProviderName, g_szProviderName)) {
}
RRETURN(S_OK);
}
HRESULT
ValidateProvider(
POBJECTINFO pObjectInfo
)
{
//
// The provider name is case-sensitive. This is a restriction that OLE
// has put on us.
//
if (!(wcscmp(pObjectInfo->ProviderName, g_szProviderName))) {
RRETURN(S_OK);
}
RRETURN(E_FAIL);
}
//+---------------------------------------------------------------------------
// Function: GetSchemaObject
//
// Synopsis: called by GetObject
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
//----------------------------------------------------------------------------
HRESULT
GetSchemaObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject
)
{
HRESULT hr = S_OK;
WCHAR szParent[MAX_PATH];
WCHAR szCommonName[MAX_PATH];
WCHAR szSampleDSPathName[MAX_PATH];
DWORD dwObjectType = 0;
HANDLE hObject= NULL;
hr = ValidateSchemaObject(
pObjectInfo,
&dwObjectType
);
BAIL_ON_FAILURE(hr);
hr = BuildADsParentPath(
pObjectInfo,
szParent,
szCommonName
);
BAIL_ON_FAILURE(hr);
switch(dwObjectType) {
case SampleDS_CLASS_ID:
case SampleDS_PROPERTY_ID:
case SampleDS_CLASSPROP_ID:
wcscpy(szSampleDSPathName, L"\\");
wcscat(szSampleDSPathName, szCommonName);
hr = SampleDSOpenObject(
szSampleDSPathName,
&hObject,
NULL,
REG_SCHEMA
);
BAIL_ON_FAILURE(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 SampleDS_SCHEMA_ID:
hr = CSampleDSSchema::CreateSchema(
szParent,
szCommonName,
ADS_OBJECT_BOUND,
IID_IUnknown,
ppObject
);
break;
case SampleDS_CLASSPROP_ID:
hr = CSampleDSClass::CreateClass(
szParent,
szCommonName,
hObject,
ADS_OBJECT_BOUND,
IID_IUnknown,
ppObject
);
if (FAILED(hr)) {
hr = CSampleDSProperty::CreateProperty(
szParent,
szCommonName,
hObject,
ADS_OBJECT_BOUND,
IID_IUnknown,
ppObject
);
}
break;
default:
hr = E_ADS_UNKNOWN_OBJECT;
break;
}
error:
if (hObject) {
SampleDSCloseObject(hObject);
}
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 = SampleDS_SCHEMA_ID;
RRETURN(S_OK);
}
break;
case 2:
*pdwObjectType = SampleDS_CLASSPROP_ID;
RRETURN(S_OK);
default:
break;
}
RRETURN(E_FAIL);
}
HRESULT
BuildADsParentPath(
POBJECTINFO pObjectInfo,
LPWSTR szParent,
LPWSTR szCommonName
)
{
DWORD i = 0;
DWORD dwNumComponents = 0;
LPWSTR pszComponent = NULL, pszValue = NULL;
dwNumComponents = pObjectInfo->NumComponents;
if (!dwNumComponents && !pObjectInfo->RootRDN) {
//
// There are no CNs in this pathname and
// no root name specified. This is the
// namespace object - its parent is the
// @ADs! object
//
wsprintf(szParent,L"ADs:");
RRETURN(S_OK);
} else if (!dwNumComponents && pObjectInfo->RootRDN) {
//
// There are no CNs in this pathname and a root
// name has been specified. This is the root
// object - its parent is the @Sample! object
wsprintf(szParent, L"%s:", pObjectInfo->ProviderName);
//
// And the common name is the RootRDN. Remember the
// "//" will be added on when we reconstruct the full
// pathname
//
wsprintf(szCommonName,L"%s", pObjectInfo->RootRDN);
RRETURN(S_OK);
}else {
//
// There are one or more CNs, a root 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->RootRDN
);
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);
}
HRESULT
ValidateObjectType(
POBJECTINFO pObjectInfo
)
{
pObjectInfo->ObjectType = TOKEN_DSOBJECT;
if (pObjectInfo->ProviderName && !pObjectInfo->RootRDN
&& !pObjectInfo->NumComponents) {
pObjectInfo->ObjectType = TOKEN_NAMESPACE;
}else if (pObjectInfo->ProviderName && pObjectInfo->RootRDN
&& pObjectInfo->NumComponents) {
if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"schema")) {
pObjectInfo->ObjectType = TOKEN_SCHEMA;
}
}
RRETURN(S_OK);
}
HRESULT
BuildSampleDSRootRDNFromADsPath(
LPWSTR szBuffer,
LPWSTR szDSRootRDN
)
{
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->RootRDN) {
//
// There are no CNs in this pathname and
// no root name specified. This is the
// namespace object - its parent is the
// @ADs! object
//
hr = E_FAIL;
} else if (!dwNumComponents && pObjectInfo->RootRDN) {
//
// There are no CNs in this pathname and a root
// name has been specified. This is the root
// object - its parent is the @Sample! object
wsprintf(szDSRootRDN,L"\\\\%s", pObjectInfo->RootRDN);
hr = S_OK;
}else {
//
// There are one or more CNs, a root name has been
// specified. In the worst case the parent is the
// root object. In the best case a long CN.
//
wsprintf(szDSRootRDN,L"\\\\%s", pObjectInfo->RootRDN);
hr = S_OK;
}
error:
RRETURN(hr);
}
HRESULT
BuildDSPathFromADsPath(
LPWSTR szADsPathName,
LPWSTR szDSRootRDN,
LPWSTR szDSPathName
)
{
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(szDSRootRDN, L"\\");
wcscat(szDSRootRDN, pObjectInfo->RootRDN);
*szDSPathName = L'\0';
for (i = dwNumComponents; i > 0; i--) {
wcscat(szDSPathName, pObjectInfo->ComponentArray[i-1].szComponent);
if (i>1) wcscat(szDSPathName, L"\\");
}
error:
RRETURN(hr);
}