COMMON.CPP

/*++ 

Copyright (c) 1996 Microsoft Corporation

Module Name:

Common.cpp

Abstract:

Contains routines and properties that are common to
all tshirt objects. thsirt objects get the routines and
properties through C++ inheritance.

Author:

Environment:

User mode

Revision History :

--*/
#include "adssmp.h"
#pragma hdrstop


FILTERS Filters[] = {
{L"organizational unit", SampleDS_OU_ID},
{L"class", SampleDS_CLASS_ID},
{L"property", SampleDS_PROPERTY_ID}
};

#define MAX_FILTERS (sizeof(Filters)/sizeof(FILTERS))

PFILTERS gpFilters = Filters;
DWORD gdwMaxFilters = MAX_FILTERS;

extern WCHAR * g_szProviderName;

HRESULT
xx_put_BSTR(BSTR* lppItemName, BSTR lpName)
{
if (*lppItemName) {
SysFreeString(*lppItemName);
*lppItemName = NULL;
}

if (!lpName) {
RRETURN(S_OK);
}

*lppItemName = SysAllocString(lpName);

if (!*lppItemName) {
RRETURN(E_FAIL);
}
RRETURN(S_OK);
}

HRESULT
xx_put_LONG(long * plnItem, long lnItem)
{
*plnItem = lnItem;
RRETURN(S_OK);
}

HRESULT
xx_put_DATE(DATE * pdaItem, DATE daItem)
{
*pdaItem = daItem;
RRETURN(S_OK);
}


HRESULT
xx_put_VARIANT_BOOL(VARIANT_BOOL * pfItem, VARIANT_BOOL fItem)
{
*pfItem = fItem;
RRETURN(S_OK);
}


HRESULT
xx_put_VARIANT(VARIANT * * ppvItem, VARIANT vItem)
{
if (!*ppvItem) {
if (!(*ppvItem = (VARIANT *)AllocProvMem(sizeof(VARIANT)))){
RRETURN(E_OUTOFMEMORY);
}
}
RRETURN(VariantCopy(*ppvItem, &vItem));
}

HRESULT
BuildADsPath(
BSTR Parent,
BSTR Name,
BSTR *pADsPath
)
{
WCHAR ADsPath[MAX_PATH];
WCHAR ProviderName[MAX_PATH];
HRESULT hr = S_OK;

//
// We will assert if bad parameters are passed to us.
// This is because this should never be the case. This
// is an internal call
//

ADsAssert(Parent && Name);
ADsAssert(pADsPath);


//
// Special case the Namespace object; if
// the parent is L"ADs:", then Name = ADsPath
//

if (!_wcsicmp(Parent, L"ADs:")) {
RRETURN(xx_put_BSTR(pADsPath, Name));
}

//
// The rest of the cases we expect valid data,
// Path, Parent and Name are read-only, the end-user
// cannot modify this data
//

//
// For first level objects we do not add
// the first backslash; so we examine that the parent is
// L"Sample:" and skip the slash otherwise we start with
// the slash
//

wsprintf(ProviderName, L"%s:", g_szProviderName);

wcscpy(ADsPath, Parent);

if (_wcsicmp(ADsPath, ProviderName)) {
wcscat(ADsPath, L"/");
}else {
wcscat(ADsPath, L"//");
}
wcscat(ADsPath, Name);

hr = xx_put_BSTR(pADsPath, ADsPath);

RRETURN(hr);
}

HRESULT
BuildSchemaPath(
BSTR bstrADsPath,
BSTR bstrClass,
BSTR *pSchemaPath
)
{
WCHAR ADsSchema[MAX_PATH];
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = &ObjectInfo;
CLexer Lexer(bstrADsPath);
HRESULT hr = S_OK;

wcscpy(ADsSchema, L"");

if (bstrClass && *bstrClass) {
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = ADsObject(&Lexer, pObjectInfo);
BAIL_ON_FAILURE(hr);

if (pObjectInfo->RootRDN) {

wsprintf(ADsSchema,L"%s://",pObjectInfo->ProviderName);
wcscat(ADsSchema, pObjectInfo->RootRDN);
wcscat(ADsSchema,L"/schema/");
wcscat(ADsSchema, bstrClass);

}
}

hr = ProvAllocString( ADsSchema, pSchemaPath);

error:

if (pObjectInfo) {

//
// BugBug - KrishnaG; free up this piece of memory
//
}
RRETURN(hr);
}


HRESULT
BuildADsGuid(
REFCLSID clsid,
BSTR *pADsClass
){
WCHAR ADsClass[MAX_PATH];

StringFromGUID2(clsid, ADsClass, 256);

RRETURN(xx_put_BSTR(pADsClass, ADsClass));
}


typedef struct _typeinfotable
{
GUID iid;
ITypeInfo * pTypeInfo;
struct _typeinfotable *pNext;
}TYPEINFO_TABLE, *PTYPEINFO_TABLE;


PTYPEINFO_TABLE gpTypeInfoTable = NULL;

ITypeInfo *
FindTypeInfo(
PTYPEINFO_TABLE pTypeInfoTable,
REFIID iid
){
PTYPEINFO_TABLE pTemp = NULL;

pTemp = pTypeInfoTable;

while (pTemp) {
if (IsEqualIID(iid, pTemp->iid)) {
return(pTemp->pTypeInfo);
}
pTemp = pTemp->pNext;
}
return(NULL);
}


PTYPEINFO_TABLE
AddTypeInfo(
PTYPEINFO_TABLE pTypeInfoTable,
REFIID iid,
ITypeInfo * pTypeInfo
){
PTYPEINFO_TABLE pTemp = NULL;

pTemp = (PTYPEINFO_TABLE)AllocProvMem(
sizeof(TYPEINFO_TABLE)
);
if (!pTemp) {
return(NULL);
}

memcpy(&pTemp->iid, &iid, sizeof(GUID));
pTemp->pTypeInfo = pTypeInfo;
pTemp->pNext = pTypeInfoTable;

return(pTemp);
}

HRESULT
LoadTypeInfoEntry(
CDispatchMgr *pDispMgr,
REFIID libid,
REFIID iid,
void * pIntf,
DISPID SpecialId
){
ITypeInfo * pTypeInfo = NULL;
HRESULT hr;

pTypeInfo = FindTypeInfo(
gpTypeInfoTable,
iid
);
if (!pTypeInfo) {

hr = LoadTypeInfo(libid, iid, &pTypeInfo);
BAIL_IF_ERROR(hr);

gpTypeInfoTable = AddTypeInfo(
gpTypeInfoTable,
iid,
pTypeInfo
);
if (!gpTypeInfoTable) {
hr = HRESULT_FROM_WIN32(GetLastError());
BAIL_IF_ERROR(hr);
}
}
pTypeInfo->AddRef();


hr = pDispMgr->AddTypeInfo(pTypeInfo, pIntf);
BAIL_IF_ERROR(hr);

if (SpecialId == -4) {
hr = pDispMgr->MarkAsNewEnum(pTypeInfo);
}

RRETURN(S_OK);

cleanup:

if (pTypeInfo) {
pTypeInfo->Release();
}
RRETURN(hr);
}

HRESULT
ValidateOutParameter(BSTR * retval)
{
if (!retval) {
RRETURN(E_ADS_BAD_PARAMETER);
}
RRETURN(S_OK);
}


PKEYDATA
CreateTokenList(
LPWSTR pKeyData,
WCHAR ch
){
DWORD cTokens;
DWORD cb;
PKEYDATA pResult;
LPWSTR pDest;
LPWSTR psz = pKeyData;
LPWSTR *ppToken;
WCHAR szTokenList[MAX_PATH];


if (!psz || !*psz)
return NULL;

wsprintf(szTokenList, L"%c", ch);

cTokens=1;

// Scan through the string looking for commas,
// ensuring that each is followed by a non-NULL character:

while ((psz = wcschr(psz, ch)) && psz[1]) {

cTokens++;
psz++;
}

cb = sizeof(KEYDATA) + (cTokens-1) * sizeof(LPWSTR) +
wcslen(pKeyData)*sizeof(WCHAR) + sizeof(WCHAR);

if (!(pResult = (PKEYDATA)AllocProvMem(cb)))
return NULL;

// Initialise pDest to point beyond the token pointers:

pDest = (LPWSTR)((LPBYTE)pResult + sizeof(KEYDATA) +
(cTokens-1) * sizeof(LPWSTR));

// Then copy the key data buffer there:

wcscpy(pDest, pKeyData);

ppToken = pResult->pTokens;


// Remember, wcstok has the side effect of replacing the delimiter
// by NULL, which is precisely what we want:

psz = wcstok (pDest, szTokenList);

while (psz) {

*ppToken++ = psz;
psz = wcstok (NULL, szTokenList);
}

pResult->cTokens = cTokens;

return( pResult );
}

//+------------------------------------------------------------------------
//
// Function: LoadTypeInfo
//
// Synopsis: Loads a typeinfo from a registered typelib.
//
// Arguments: [clsidTL] -- TypeLib GUID
// [clsidTI] -- TypeInfo GUID
// [ppTI] -- Resulting typeInfo
//
// Returns: HRESULT
//
//-------------------------------------------------------------------------

HRESULT
LoadTypeInfo(CLSID clsidTL, CLSID clsidTI, LPTYPEINFO *ppTI)
{
HRESULT hr;
ITypeLib * pTL;

ADsAssert(ppTI);
*ppTI = NULL;
hr = LoadRegTypeLib(clsidTL, 1, 0, LOCALE_SYSTEM_DEFAULT, &pTL);
if (hr)
RRETURN(hr);

hr = pTL->GetTypeInfoOfGuid(clsidTI, ppTI);
pTL->Release();
RRETURN(hr);
}