Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

573 lines
13 KiB

//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 1998.
//
// File: pathwrap.cxx
//
// Contents: Utility class for thread safe set/retrieve operations on
// an IADsPathname interface.
//
// Classes: CADsPathWrapper
//
// History: 08-08-1998 DavidMun Created
//
//---------------------------------------------------------------------------
#include "headers.hxx"
#pragma hdrstop
DEBUG_DECLARE_INSTANCE_COUNTER(CADsPathWrapper)
//+--------------------------------------------------------------------------
//
// Member: CADsPathWrapper::CADsPathWrapper
//
// Synopsis: ctor
//
// History: 08-08-1998 DavidMun Created
//
//---------------------------------------------------------------------------
CADsPathWrapper::CADsPathWrapper():
m_cRefs(1),
m_cLocks(0)
{
TRACE_CONSTRUCTOR(CADsPathWrapper);
DEBUG_INCREMENT_INSTANCE_COUNTER(CADsPathWrapper);
HRESULT hr;
// NTRAID#NTBUG9-548146-2002/02/20-lucios. Pending fix.
InitializeCriticalSection(&m_cs);
do
{
hr = m_rpADsPath.AcquireViaCreateInstance(
CLSID_Pathname,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsPathname);
BREAK_ON_FAIL_HRESULT(hr);
hr = m_rpADsPath->put_EscapedMode(ADS_ESCAPEDMODE_OFF);
ASSERT(SUCCEEDED(hr));
} while (0);
}
//+--------------------------------------------------------------------------
//
// Member: CADsPathWrapper::~CADsPathWrapper
//
// Synopsis: dtor
//
// History: 08-08-1998 DavidMun Created
//
//---------------------------------------------------------------------------
CADsPathWrapper::~CADsPathWrapper()
{
TRACE_DESTRUCTOR(CADsPathWrapper);
DEBUG_DECREMENT_INSTANCE_COUNTER(CADsPathWrapper);
ASSERT(!m_cLocks);
DeleteCriticalSection(&m_cs);
}
//+--------------------------------------------------------------------------
//
// Member: CADsPathWrapper::SetRetrieve
//
// Synopsis: Perform an atomic set and retrieve
//
// Arguments: [ulFmtIn] - ADS_SETTYPE_*
// [pwzIn] - ADs path to set
// [ulFmtOut] - ADS_FORMAT_*
// [pbstrOut] - filled with BSTR containing new format
//
// Returns: HRESULT
//
// Modifies: *[pbstrOut]
//
// History: 08-08-1998 DavidMun Created
//
// Notes: Caller must SysFreeString(*[pbstrOut])
//
//---------------------------------------------------------------------------
HRESULT
CADsPathWrapper::SetRetrieve(
ULONG ulFmtIn,
PCWSTR pwzIn,
ULONG ulFmtOut,
BSTR *pbstrOut)
{
ASSERT(pwzIn);
ASSERT(pbstrOut);
if (!m_rpADsPath.get())
{
return E_FAIL;
}
HRESULT hr = S_OK;
do
{
CAutoCritSec Lock(&m_cs);
*pbstrOut = NULL;
hr = m_rpADsPath->Set(AutoBstr(pwzIn), ulFmtIn);
if (FAILED(hr))
{
Dbg(DEB_TRACE,
"IADsPathName::Set(%ws,%#x) hr=%#x\n",
pwzIn,
ulFmtIn,
hr);
break;
}
hr = m_rpADsPath->Retrieve(ulFmtOut, pbstrOut);
if (FAILED(hr))
{
Dbg(DEB_TRACE,
"IADsPathName::Retrieve(%#x) hr=%#x\n",
ulFmtOut,
hr);
break;
}
} while (0);
return hr;
}
HRESULT
CADsPathWrapper::SetRetrieveContainer(
ULONG ulFmtIn,
PCWSTR pwzIn,
ULONG ulFmtOut,
BSTR *pbstrOut)
{
if (!m_rpADsPath.get())
{
return E_FAIL;
}
HRESULT hr = S_OK;
do
{
CAutoCritSec Lock(&m_cs);
*pbstrOut = NULL;
hr = m_rpADsPath->Set(AutoBstr(pwzIn), ulFmtIn);
BREAK_ON_FAIL_HRESULT(hr);
hr = m_rpADsPath->RemoveLeafElement();
BREAK_ON_FAIL_HRESULT(hr);
hr = m_rpADsPath->Retrieve(ulFmtOut, pbstrOut);
BREAK_ON_FAIL_HRESULT(hr);
} while (0);
return hr;
}
#define LDAP_GC_PORT_STR L":3268"
//+--------------------------------------------------------------------------
//
// Member: CADsPathWrapper::ConvertProvider
//
// Synopsis: Substitute provider string [pwzNewProvider] for the
// provider in ADsPath [pstrPath].
//
// Arguments: [pstrPath] - points to path to modify
// [pwzNewProvider] - new provider
//
// Returns: S_OK or E_INVALIDARG (if [pstrPath] is ill-formed)
//
// Modifies: *[pstrPath]
//
// History: 02-11-1999 DavidMun Created
//
//---------------------------------------------------------------------------
HRESULT
CADsPathWrapper::ConvertProvider(
String *pstrPath,
PCWSTR pwzNewProvider)
{
size_t idxDelim = pstrPath->find(L"://");
if (idxDelim == String::npos || idxDelim == 0)
{
DBG_OUT_HRESULT(E_INVALIDARG);
return E_INVALIDARG;
}
pstrPath->StringBase::replace(0, idxDelim, pwzNewProvider);
//
// If there's a GC port number, remove it.
//
idxDelim = pstrPath->find(LDAP_GC_PORT_STR);
if (idxDelim != String::npos)
{
pstrPath->erase(idxDelim, lstrlen(LDAP_GC_PORT_STR));
}
return S_OK;
}
//+--------------------------------------------------------------------------
//
// Member: CADsPathWrapper::GetMostSignificantElement
//
// Synopsis: Return the path element closest to the provider type.
//
// Arguments: [pwzIn] - ADS path to set
// [pbstrOut] - most significant element
//
// Returns: HRESULT
//
// Modifies: *[pbstrOut]
//
// History: 01-22-1999 DavidMun Created
//
//---------------------------------------------------------------------------
HRESULT
CADsPathWrapper::GetMostSignificantElement(
PCWSTR pwzIn,
BSTR *pbstrOut)
{
if (!m_rpADsPath.get())
{
return E_FAIL;
}
HRESULT hr = S_OK;
do
{
CAutoCritSec Lock(&m_cs);
*pbstrOut = NULL;
hr = m_rpADsPath->Set(AutoBstr(pwzIn), ADS_SETTYPE_FULL);
BREAK_ON_FAIL_HRESULT(hr);
long cElements;
hr = m_rpADsPath->GetNumElements(&cElements);
BREAK_ON_FAIL_HRESULT(hr);
ASSERT(cElements > 0);
hr = m_rpADsPath->GetElement(cElements - 1, pbstrOut);
BREAK_ON_FAIL_HRESULT(hr);
} while (0);
return hr;
}
HRESULT
CADsPathWrapper::GetWinntPathServerName(
PCWSTR pwzIn,
BSTR *pbstrOut)
{
if (!m_rpADsPath.get())
{
return E_FAIL;
}
HRESULT hr = S_OK;
do
{
CAutoCritSec Lock(&m_cs);
*pbstrOut = NULL;
hr = m_rpADsPath->Set(AutoBstr(pwzIn), ADS_SETTYPE_FULL);
BREAK_ON_FAIL_HRESULT(hr);
long cElements;
hr = m_rpADsPath->GetNumElements(&cElements);
BREAK_ON_FAIL_HRESULT(hr);
ASSERT(cElements > 0);
// the server name is the most significant element in some
// cases, like WinNT://server/user (form 1), but not always, as in
// WinNT://workgroup/server/user or WinNT://domain/server/user (form 2)
// Not astonishingly, given the all-around badness of
// IADsPathname, the server format returns the domain name for form
// (2) paths, and the server name for form (1) paths. And the 1st
// element of the path after the provider name is unreachable
// except with Retrieve!
if (cElements >= 2)
{
// form 2 name, so get the next-to-last element
hr = m_rpADsPath->GetElement(1, pbstrOut);
BREAK_ON_FAIL_HRESULT(hr);
}
else
{
// form 1 name
hr = m_rpADsPath->Retrieve(ADS_FORMAT_SERVER, pbstrOut);
BREAK_ON_FAIL_HRESULT(hr);
}
} while (0);
return hr;
}
HRESULT
CADsPathWrapper::GetWinntPathRDN(
PCWSTR pwzIn,
String *pstrRDN)
{
if(!pwzIn || !pstrRDN)
return E_POINTER;
if (!m_rpADsPath.get())
{
return E_FAIL;
}
HRESULT hr = S_OK;
do
{
CAutoCritSec Lock(&m_cs);
pstrRDN->erase();
hr = m_rpADsPath->Set(AutoBstr(pwzIn), ADS_SETTYPE_FULL);
BREAK_ON_FAIL_HRESULT(hr);
long cElements;
hr = m_rpADsPath->GetNumElements(&cElements);
BREAK_ON_FAIL_HRESULT(hr);
ASSERT(cElements > 0);
// path can have following format. (form1) WinNT://servername
// (form2) WinNT://server/user,
// (form3) WinNT://workgroup/server/user or WinNT://domain/server/user
// In form1 there is no rdn while in 2 and 3 least significant element is
// RDN
if (cElements >= 2)
{
// form 2 or 3 name, so get the last element
BSTR bstr;
hr = m_rpADsPath->GetElement(0, &bstr);
BREAK_ON_FAIL_HRESULT(hr);
*pstrRDN = bstr;
SysFreeString(bstr);
}
} while (0);
return hr;
}
//+--------------------------------------------------------------------------
//
// Member: CADsPathWrapper::Set
//
// Synopsis: Wrap IADsPathname::Set.
//
// History: 3-12-1999 DavidMun Created
//
//---------------------------------------------------------------------------
HRESULT
CADsPathWrapper::Set(
PCWSTR pwzPath,
long lSetType)
{
//TRACE_METHOD(CADsPathWrapper, Set);
ASSERT(m_cLocks);
if (!m_rpADsPath.get())
{
return E_FAIL;
}
return m_rpADsPath->Set(AutoBstr(pwzPath), lSetType);
}
//+--------------------------------------------------------------------------
//
// Member: CADsPathWrapper::GetNumElements
//
// Synopsis: Wrap IADsPathname::GetNumElements.
//
// History: 3-12-1999 DavidMun Created
//
//---------------------------------------------------------------------------
HRESULT
CADsPathWrapper::GetNumElements(
long *pcElem)
{
//TRACE_METHOD(CADsPathWrapper, GetNumElements);
ASSERT(m_cLocks);
if (!m_rpADsPath.get())
{
return E_FAIL;
}
return m_rpADsPath->GetNumElements(pcElem);
}
//+--------------------------------------------------------------------------
//
// Member: CADsPathWrapper::Escape
//
// Synopsis: Escape name element [pwzIn].
//
// Arguments: [pwzIn] - element to escape
// [pbstrOut] - filled with BSTR containing escaped element
//
// Returns: HRESULT
//
// Modifies: *[pbstrOut]
//
// History: 5-04-1999 davidmun Created
//
// Notes: Caller must call SysFreeString on returned BSTR.
//
//---------------------------------------------------------------------------
HRESULT
CADsPathWrapper::Escape(
PCWSTR pwzIn,
BSTR *pbstrOut)
{
HRESULT hr = S_OK;
do
{
if (!m_rpADsPath.get())
{
hr = E_FAIL;
DBG_OUT_HRESULT(hr);
break;
}
CAutoCritSec Lock(&m_cs);
hr = m_rpADsPath->Set(AutoBstr(L"LDAP"), ADS_SETTYPE_PROVIDER);
BREAK_ON_FAIL_HRESULT(hr);
hr = m_rpADsPath->GetEscapedElement(0, AutoBstr(pwzIn), pbstrOut);
CHECK_HRESULT(hr);
} while (0);
return hr;
}
//+--------------------------------------------------------------------------
//
// Member: CADsPathWrapper::GetElement
//
// Synopsis: Wrap IADsPathname::GetElement.
//
// History: 3-12-1999 DavidMun Created
//
//---------------------------------------------------------------------------
HRESULT
CADsPathWrapper::GetElement(
long idxElem,
BSTR *pbstrElem)
{
//TRACE_METHOD(CADsPathWrapper, GetElement);
ASSERT(m_cLocks);
if (!m_rpADsPath.get())
{
return E_FAIL;
}
return m_rpADsPath->GetElement(idxElem, pbstrElem);
}
//+--------------------------------------------------------------------------
//
// Member: CADsPathWrapper::RemoveLeafElement
//
// Synopsis: Wrap IADsPathname::RemoveLeafElement.
//
// History: 3-12-1999 DavidMun Created
//
//---------------------------------------------------------------------------
HRESULT
CADsPathWrapper::RemoveLeafElement()
{
//TRACE_METHOD(CADsPathWrapper, RemoveLeafElement);
ASSERT(m_cLocks);
if (!m_rpADsPath.get())
{
return E_FAIL;
}
return m_rpADsPath->RemoveLeafElement();
}