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.
 
 
 
 
 
 

1370 lines
31 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1997.
//
// File: pathmgmt.cxx
//
// Contents:
//
// Functions:
//
// History: 25-April-97 KrishnaG Created.
//
//----------------------------------------------------------------------------
#include "ldapc.hxx"
#pragma hdrstop
#define STRING_LENGTH(p) ( p ? wcslen(p) : 0)
HRESULT
BuildADsParentPathFromObjectInfo2(
POBJECTINFO pObjectInfo,
LPWSTR *ppszParent,
LPWSTR *ppszCommonName
)
{
DWORD i = 0;
DWORD dwNumComponents = 0;
HRESULT hr = S_OK;
LPWSTR pszComponent = NULL, pszValue = NULL;
hr = ComputeAllocateParentCommonNameSize(pObjectInfo, ppszParent, ppszCommonName);
BAIL_ON_FAILURE(hr);
hr = BuildADsParentPathFromObjectInfo(
pObjectInfo,
*ppszParent,
*ppszCommonName
);
BAIL_ON_FAILURE(hr);
RRETURN(hr);
error:
if (*ppszParent) {
FreeADsMem(*ppszParent);
}
if (*ppszCommonName) {
FreeADsMem(*ppszCommonName);
}
RRETURN(hr);
}
HRESULT
BuildADsParentPath(
LPWSTR szBuffer,
LPWSTR *ppszParent,
LPWSTR *ppszCommonName
)
{
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = &ObjectInfo;
HRESULT hr = S_OK;
LPWSTR pszCommonName = NULL;
LPWSTR pszParent = NULL;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = ADsObject(szBuffer, pObjectInfo);
BAIL_ON_FAILURE(hr);
// The length of pszParent or pszCommon is definitely less than the
// length of the total buffer.
pszParent = (LPWSTR) AllocADsMem( (_tcslen(szBuffer) + 1) * sizeof(TCHAR));
if ( pszParent == NULL )
{
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
pszCommonName = (LPWSTR) AllocADsMem( (_tcslen(szBuffer) + 1) * sizeof(TCHAR));
if ( pszCommonName == NULL )
{
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
hr = BuildADsParentPathFromObjectInfo(
pObjectInfo,
pszParent,
pszCommonName
);
BAIL_ON_FAILURE(hr);
*ppszParent = pszParent;
*ppszCommonName = pszCommonName;
FreeObjectInfo( &ObjectInfo );
RRETURN(hr);
error:
if (pszCommonName) {
FreeADsMem(pszCommonName);
}
if (pszParent) {
FreeADsMem(pszParent);
}
FreeObjectInfo( &ObjectInfo );
RRETURN(hr);
}
HRESULT
BuildADsParentPathFromObjectInfo(
POBJECTINFO pObjectInfo,
LPWSTR pszParent,
LPWSTR pszCommonName
)
{
DWORD i = 0;
DWORD dwNumComponents = 0;
HRESULT hr = S_OK;
LPWSTR pszComponent = NULL, pszValue = NULL;
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(pszParent,L"ADs:");
wsprintf(pszCommonName, L"%s:", pObjectInfo->NamespaceName);
hr = 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(pszParent, L"%s:", pObjectInfo->NamespaceName);
//
// And the common name is the TreeName (and port)
//
if ( IS_EXPLICIT_PORT(pObjectInfo->PortNumber) ) {
wsprintf(pszCommonName,L"%s:%d", pObjectInfo->TreeName, pObjectInfo->PortNumber);
}
else {
wsprintf(pszCommonName,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.
//
switch (pObjectInfo->dwServerPresent) {
case TRUE:
if ( IS_EXPLICIT_PORT(pObjectInfo->PortNumber) ) {
wsprintf(
pszParent, L"%s://%s:%d",
pObjectInfo->NamespaceName,
pObjectInfo->DisplayTreeName,
pObjectInfo->PortNumber
);
}
else {
wsprintf(
pszParent, L"%s://%s",
pObjectInfo->NamespaceName,
pObjectInfo->DisplayTreeName
);
}
break;
case FALSE:
wsprintf(
pszParent, L"%s:",
pObjectInfo->NamespaceName
);
break;
}
switch (pObjectInfo->dwPathType) {
case PATHTYPE_X500:
default: // where we cannot make a determination whether its X500 or Windows style
if (dwNumComponents > 1) {
if (pObjectInfo->dwServerPresent) {
wcscat(pszParent, L"/");
}else {
wcscat(pszParent,L"//");
}
for (i = 1; i < dwNumComponents; i++) {
AppendComponent(pszParent, &(pObjectInfo->DisplayComponentArray[i]));
if (i < (dwNumComponents - 1)) {
wcscat(pszParent, L",");
}
}
}
//
// And the common name is the last component
//
pszComponent = pObjectInfo->DisplayComponentArray[0].szComponent;
pszValue = pObjectInfo->DisplayComponentArray[0].szValue;
if (pszComponent && pszValue) {
wsprintf(pszCommonName, L"%s=%s",pszComponent, pszValue);
}else if (pszComponent){
wsprintf(pszCommonName, L"%s", pszComponent);
}else {
//
// Error - we should never hit this case!!
//
}
hr = S_OK;
break;
case PATHTYPE_WINDOWS:
switch (pObjectInfo->dwServerPresent) {
case FALSE:
if (dwNumComponents > 1) {
wcscat(pszParent,L"//");
for (i = 0; i < dwNumComponents - 1; i++) {
if (i ) {
wcscat(pszParent, L"/");
}
AppendComponent(pszParent, &(pObjectInfo->DisplayComponentArray[i]));
}
}
break;
case TRUE:
for (i = 0; i < dwNumComponents - 1; i++) {
wcscat(pszParent, L"/");
AppendComponent(pszParent, &(pObjectInfo->DisplayComponentArray[i]));
}
break;
}
//
// And the common name is the last component
//
pszComponent = pObjectInfo->DisplayComponentArray[dwNumComponents - 1].szComponent;
pszValue = pObjectInfo->DisplayComponentArray[dwNumComponents - 1].szValue;
if (pszComponent && pszValue) {
wsprintf(pszCommonName, L"%s=%s",pszComponent, pszValue);
}else if (pszComponent){
wsprintf(pszCommonName, L"%s", pszComponent);
}else {
//
// Error - we should never hit this case!!
//
}
break;
}
}
RRETURN(hr);
}
HRESULT
AppendComponent(
LPWSTR pszADsPathName,
PCOMPONENT pComponent
)
{
HRESULT hr = S_OK;
LPWSTR pszComponent = NULL, pszValue = NULL;
pszComponent = pComponent->szComponent;
pszValue = pComponent->szValue;
if (pszComponent && pszValue) {
wcscat(
pszADsPathName,
pComponent->szComponent
);
wcscat(pszADsPathName,L"=");
wcscat(
pszADsPathName,
pComponent->szValue
);
}else if (pszComponent){
wcscat(
pszADsPathName,
pComponent->szComponent
);
}else {
//
// Error - we should never hit this case!!
//
}
RRETURN(S_OK);
}
HRESULT
ComputeAllocateParentCommonNameSize(
POBJECTINFO pObjectInfo,
LPWSTR * ppszParent,
LPWSTR * ppszCommonName
)
{
HRESULT hr = S_OK;
LPWSTR pszParent = NULL;
LPWSTR pszCommonName = NULL;
DWORD dwPathSz = 0;
WCHAR szPort[32];
DWORD i = 0;
//
// the ADsPath of the Parent is atleast as long as the standard
// pathname
//
//
// the CommonName is atleast as long as the parent name
//
dwPathSz += STRING_LENGTH(pObjectInfo->NamespaceName);
dwPathSz += STRING_LENGTH(pObjectInfo->ProviderName);
dwPathSz += 2;
dwPathSz += STRING_LENGTH(pObjectInfo->DisplayTreeName);
//
// If an explicit port has been specified
//
if ( IS_EXPLICIT_PORT(pObjectInfo->PortNumber) ) {
wsprintf(szPort, L":%d", pObjectInfo->PortNumber);
dwPathSz += wcslen(szPort);
}
dwPathSz += 1;
for (i = 0; i < pObjectInfo->NumComponents; i++) {
dwPathSz += STRING_LENGTH(pObjectInfo->DisplayComponentArray[i].szComponent);
dwPathSz += 1;
dwPathSz += STRING_LENGTH(pObjectInfo->DisplayComponentArray[i].szValue);
dwPathSz += 1;
}
dwPathSz += 1;
pszCommonName = (LPWSTR)AllocADsMem((dwPathSz)*sizeof(WCHAR));
if (!pszCommonName) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
pszParent = (LPWSTR)AllocADsMem((dwPathSz)*sizeof(WCHAR));
if (!pszParent) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
*ppszCommonName = pszCommonName;
*ppszParent = pszParent;
RRETURN(hr);
error:
if (pszCommonName ) {
FreeADsMem(pszCommonName);
}
if (pszParent) {
FreeADsMem(pszParent);
}
RRETURN(hr);
}
HRESULT
BuildADsPathFromParent(
LPWSTR Parent,
LPWSTR Name,
LPWSTR *ppszADsPath
)
{
OBJECTINFO ObjectInfo;
POBJECTINFO pParentObjectInfo = &ObjectInfo;
HRESULT hr = S_OK;
LPWSTR pszCommonName = NULL;
LPWSTR pszADsPath = NULL;
memset(pParentObjectInfo, 0, sizeof(OBJECTINFO));
hr = ADsObject(Parent, pParentObjectInfo);
BAIL_ON_FAILURE(hr);
// The length of the pszADsPath is the total path + name + 1;
//
// The length of pszParent or pszCommon is definitely less than the
// length of the total buffer.
//
// The Name part may be expanded to include escaping characters. In
// the worst case, the number of characters will double. Extra 2+1 is for
// the "//" and a NULL
//
pszADsPath = (LPWSTR) AllocADsMem( (_tcslen(Parent) + (_tcslen(Name)*2) + 2 + 1) * sizeof(TCHAR));
if (!pszADsPath) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
hr = BuildADsPathFromParentObjectInfo(
pParentObjectInfo,
Name,
pszADsPath
);
BAIL_ON_FAILURE(hr);
*ppszADsPath = pszADsPath;
cleanup:
if (pParentObjectInfo) {
FreeObjectInfo( pParentObjectInfo );
}
RRETURN(hr);
error:
if (pszADsPath) {
FreeADsMem(pszADsPath);
}
goto cleanup;
}
HRESULT
BuildADsPathFromParentObjectInfo(
POBJECTINFO pParentObjectInfo,
LPWSTR pszName,
LPWSTR pszADsPath
)
{
DWORD i = 0;
DWORD dwNumComponents = 0;
HRESULT hr = S_OK;
LPWSTR pszDisplayName = NULL;
//
// Get the display name for the name; The display name will have the proper
// escaping for characters that have special meaning in an ADsPath like
// '/' etc.
//
hr = GetDisplayName(
pszName,
&pszDisplayName
);
BAIL_ON_FAILURE(hr);
dwNumComponents = pParentObjectInfo->NumComponents;
if (!dwNumComponents && !pParentObjectInfo->DisplayTreeName) {
//
// Should never happen --- ADs is the root of the tree,
// and has no parent
//
ADsAssert(_wcsicmp(pszDisplayName, L"ADs:") != 0);
if (!_wcsicmp(pParentObjectInfo->NamespaceName, L"ADs")) {
//
// In this one particular case we take in LDAP: as the Name
// or GC: as the name
//
//
// Do not add another : - so bogus!! Krishna
//
wsprintf(pszADsPath, L"%s", pszDisplayName);
}else {
//
// There are no CNs in this pathname and
// no tree name specified. This is the
// namespace object
//
// Its pszName is a TreeName and we will concatenate
// the treename with a slash slash
//
wsprintf(pszADsPath,
L"%s://%s",
pParentObjectInfo->NamespaceName,
pszDisplayName
);
}
hr = S_OK;
} else if (!dwNumComponents && pParentObjectInfo->DisplayTreeName) {
//
// There are no CNs in this pathname and a tree
// name has been specified.
//
if (IS_EXPLICIT_PORT(pParentObjectInfo->PortNumber) ) {
wsprintf(
pszADsPath,
L"%s://%s:%d/%s",
pParentObjectInfo->NamespaceName,
pParentObjectInfo->DisplayTreeName,
pParentObjectInfo->PortNumber,
pszDisplayName
);
}
else {
wsprintf(
pszADsPath,
L"%s://%s/%s",
pParentObjectInfo->NamespaceName,
pParentObjectInfo->DisplayTreeName,
pszDisplayName
);
}
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.
//
switch (pParentObjectInfo->dwServerPresent) {
case TRUE:
if ( IS_EXPLICIT_PORT(pParentObjectInfo->PortNumber) ) {
wsprintf(
pszADsPath, L"%s://%s:%d",
pParentObjectInfo->NamespaceName,
pParentObjectInfo->DisplayTreeName,
pParentObjectInfo->PortNumber
);
}
else {
wsprintf(
pszADsPath, L"%s://%s",
pParentObjectInfo->NamespaceName,
pParentObjectInfo->DisplayTreeName
);
}
break;
case FALSE:
wsprintf(
pszADsPath, L"%s://",
pParentObjectInfo->NamespaceName
);
}
switch (pParentObjectInfo->dwPathType) {
case PATHTYPE_WINDOWS:
switch (pParentObjectInfo->dwServerPresent) {
case TRUE:
for (i = 0; i < dwNumComponents; i++) {
wcscat(pszADsPath, L"/");
AppendComponent(pszADsPath, &(pParentObjectInfo->DisplayComponentArray[i]));
}
wcscat(pszADsPath, L"/");
wcscat(pszADsPath, pszDisplayName);
hr = S_OK;
break;
case FALSE:
for (i = 0; i < dwNumComponents; i++) {
if (i ) {
wcscat(pszADsPath, L"/");
}
AppendComponent(pszADsPath, &(pParentObjectInfo->DisplayComponentArray[i]));
}
wcscat(pszADsPath, L"/");
wcscat(pszADsPath, pszDisplayName);
hr = S_OK;
break;
}
break;
case PATHTYPE_X500:
default:
switch (pParentObjectInfo->dwServerPresent) {
case TRUE:
wcscat(pszADsPath, L"/");
break;
case FALSE:
break;
}
wcscat(pszADsPath, pszDisplayName);
wcscat(pszADsPath, L",");
for (i = 0; i < dwNumComponents; i++) {
AppendComponent(pszADsPath, &(pParentObjectInfo->DisplayComponentArray[i]));
if (i < (dwNumComponents - 1)) {
wcscat(pszADsPath, L",");
}
}
hr = S_OK;
break;
}
}
error:
if (pszDisplayName) {
FreeADsMem(pszDisplayName);
}
RRETURN(hr);
}
HRESULT
BuildLDAPPathFromADsPath(
LPWSTR szADsPathName,
LPWSTR *pszLDAPPathName
)
{
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = &ObjectInfo;
DWORD i = 0;
DWORD dwNumComponents = 0;
HRESULT hr = S_OK;
LPWSTR szLDAPPathName = NULL;
*pszLDAPPathName = NULL;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = ADsObject(szADsPathName, pObjectInfo);
BAIL_ON_FAILURE(hr);
dwNumComponents = pObjectInfo->NumComponents;
//
// Assumption LDAPPath is always less than the ADsPath
//
szLDAPPathName = AllocADsStr(szADsPathName);
if (!szLDAPPathName) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
if (!pObjectInfo->TreeName) {
//
// At the very minimum, we need a treename
//
hr = E_FAIL;
BAIL_ON_FAILURE(hr);
}else if (pObjectInfo->TreeName && !dwNumComponents){
_tcscpy(szLDAPPathName, TEXT("\\\\"));
_tcscat(szLDAPPathName, pObjectInfo->TreeName);
}else if (pObjectInfo->TreeName && dwNumComponents){
_tcscpy(szLDAPPathName, TEXT("\\\\"));
_tcscat(szLDAPPathName, pObjectInfo->TreeName);
_tcscat(szLDAPPathName, TEXT("\\"));
switch (pObjectInfo->dwPathType) {
case PATHTYPE_X500:
default:
for (i = 0; i < dwNumComponents; i++) {
AppendComponent(
szLDAPPathName,
&(pObjectInfo->ComponentArray[i])
);
if (i < (dwNumComponents - 1)){
_tcscat(szLDAPPathName, TEXT(","));
}
}
break;
case PATHTYPE_WINDOWS:
for (i = dwNumComponents; i > 0; i--) {
AppendComponent(
szLDAPPathName,
&(pObjectInfo->ComponentArray[i-1])
);
if ((i - 1) > 0){
_tcscat(szLDAPPathName, TEXT(","));
}
}
break;
}
}
*pszLDAPPathName = szLDAPPathName;
error:
FreeObjectInfo( &ObjectInfo );
RRETURN(hr);
}
HRESULT
BuildADsPathFromLDAPPath(
LPWSTR szADsPathContext,
LPWSTR szTargetLdapDN,
LPWSTR * ppszADsPathName
)
{
LPWSTR pszADsPathName = NULL;
PKEYDATA pKeyData = NULL;
DWORD dwCount = 0, dwLen = 0;
DWORD i = 0;
int cHostNameLen;
HRESULT hr;
LPWSTR pszHostName = NULL, pszTemp = NULL;
LPWSTR pszLDAPServer = NULL;
LPWSTR pszLDAPDn = NULL;
WCHAR szPort[32];
DWORD dwPortNumber = 0;
OBJECTINFO ObjectInfo, ObjectInfo2;
POBJECTINFO pObjectInfo = &ObjectInfo;
POBJECTINFO pObjectInfo2 = &ObjectInfo2;
LPWSTR pszDisplayDN = NULL;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
memset(pObjectInfo2, 0, sizeof(OBJECTINFO));
if (!szADsPathContext || !szTargetLdapDN) {
RRETURN(E_FAIL);
}
hr = GetDisplayName(
szTargetLdapDN,
&pszDisplayDN
);
BAIL_ON_FAILURE(hr);
if (!pszDisplayDN) {
BAIL_ON_FAILURE(hr = E_FAIL);
}
*ppszADsPathName = NULL;
hr = ADsObject(szADsPathContext, pObjectInfo);
BAIL_ON_FAILURE(hr);
hr = BuildLDAPPathFromADsPath2(
szADsPathContext,
&pszLDAPServer,
&pszLDAPDn,
&dwPortNumber
);
BAIL_ON_FAILURE(hr);
dwLen = STRING_LENGTH(pObjectInfo->NamespaceName) +
STRING_LENGTH(pszLDAPServer) +
STRING_LENGTH(pszDisplayDN) +
STRING_LENGTH(L"://") +
STRING_LENGTH(L"/") +
1;
if (IS_EXPLICIT_PORT(dwPortNumber) ) {
wsprintf(szPort, L":%d", dwPortNumber);
dwLen += wcslen(szPort);
}
pszADsPathName = (LPWSTR) AllocADsMem( dwLen * sizeof(WCHAR) );
if(!pszADsPathName)
{
hr = E_OUTOFMEMORY;
goto error;
}
pszTemp = (LPWSTR) AllocADsMem( dwLen * sizeof(WCHAR) );
if(!pszTemp) {
if(pszADsPathName)
{
FreeADsMem(pszADsPathName);
}
hr = E_OUTOFMEMORY;
goto error;
}
switch (pObjectInfo->dwPathType) {
case PATHTYPE_WINDOWS:
//
// Simplistic way to do this is to create the X500 based name and then
// reparse it to generate the Windows style name
//
switch (pObjectInfo->dwServerPresent) {
case TRUE:
wsprintf(pszADsPathName,L"%s://", pObjectInfo->NamespaceName);
wcscat(pszADsPathName, pszLDAPServer);
if (IS_EXPLICIT_PORT(pObjectInfo->PortNumber) ) {
wsprintf(szPort, L":%d", pObjectInfo->PortNumber);
wcscat(pszADsPathName, szPort);
}
wcscat(pszADsPathName, L"/");
wcscpy(pszTemp, pszADsPathName);
wcscat(pszADsPathName, pszDisplayDN);
break;
case FALSE:
wsprintf(pszADsPathName,L"%s://", pObjectInfo->NamespaceName);
wcscpy(pszTemp, pszADsPathName);
wcscat(pszADsPathName, pszDisplayDN);
break;
}
hr = ADsObject(pszADsPathName, pObjectInfo2);
BAIL_ON_FAILURE(hr);
wcscpy (pszADsPathName, pszTemp);
for (i = pObjectInfo2->NumComponents; i > 0; i--) {
AppendComponent(
pszADsPathName,
&(pObjectInfo2->DisplayComponentArray[i-1])
);
if ((i - 1) > 0){
_tcscat(pszADsPathName, TEXT("/"));
}
}
break;
case PATHTYPE_X500:
default:
switch (pObjectInfo->dwServerPresent) {
case TRUE:
wsprintf(pszADsPathName,L"%s://", pObjectInfo->NamespaceName);
wcscat(pszADsPathName, pszLDAPServer);
if (IS_EXPLICIT_PORT(pObjectInfo->PortNumber) ) {
wsprintf(szPort, L":%d", pObjectInfo->PortNumber);
wcscat(pszADsPathName, szPort);
}
wcscat(pszADsPathName, L"/");
wcscat(pszADsPathName, pszDisplayDN);
break;
case FALSE:
wsprintf(pszADsPathName,L"%s://", pObjectInfo->NamespaceName);
wcscat(pszADsPathName, pszDisplayDN);
break;
}
break;
}
*ppszADsPathName = pszADsPathName;
error:
if (pObjectInfo) {
FreeObjectInfo(pObjectInfo);
}
if (pObjectInfo2) {
FreeObjectInfo(pObjectInfo2);
}
if (pszTemp) {
FreeADsMem(pszTemp);
}
if (pszLDAPServer) {
FreeADsStr(pszLDAPServer);
}
if (pszLDAPDn) {
FreeADsStr(pszLDAPDn);
}
if (pszDisplayDN) {
FreeADsMem(pszDisplayDN);
}
RRETURN(hr);
}
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;
_stprintf(szTokenList, TEXT("%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)AllocADsMem(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 );
}
HRESULT
BuildLDAPPathFromADsPath2(
LPWSTR szADsPathName,
LPWSTR *pszLDAPServer,
LPWSTR *pszLDAPDn,
DWORD * pdwPort
)
{
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = &ObjectInfo;
DWORD i = 0;
DWORD dwNumComponents = 0;
HRESULT hr = S_OK;
LPWSTR szLDAPServer = NULL;
LPWSTR szLDAPDn = NULL;
DWORD dwPortNumber = 0;
*pszLDAPServer = NULL;
*pszLDAPDn = NULL;
*pdwPort = 0;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = ADsObject(szADsPathName, pObjectInfo);
BAIL_ON_FAILURE(hr);
dwPortNumber = pObjectInfo->PortNumber;
dwNumComponents = pObjectInfo->NumComponents;
//
// Assumption LDAPPath is always less than the ADsPath
//
if (!pObjectInfo->TreeName && !dwNumComponents) {
//
// At the very minimum, we need a treename
//
hr = E_FAIL;
BAIL_ON_FAILURE(hr);
}
if (pObjectInfo->TreeName){
szLDAPServer = (LPWSTR)AllocADsMem((wcslen(szADsPathName) +1)*sizeof(WCHAR));
if (!szLDAPServer) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
_tcscat(szLDAPServer, pObjectInfo->TreeName);
}
if (dwNumComponents){
szLDAPDn = (LPWSTR)AllocADsMem((wcslen(szADsPathName) +1)*sizeof(WCHAR));
if (!szLDAPDn) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
switch (pObjectInfo->dwPathType) {
case PATHTYPE_X500:
default:
for (i = 0; i < dwNumComponents; i++) {
AppendComponent(
szLDAPDn,
&(pObjectInfo->ComponentArray[i])
);
if (i < (dwNumComponents - 1)){
_tcscat(szLDAPDn, TEXT(","));
}
}
break;
case PATHTYPE_WINDOWS:
for (i = dwNumComponents; i > 0; i--) {
AppendComponent(
szLDAPDn,
&(pObjectInfo->ComponentArray[i-1])
);
if ((i - 1) > 0){
_tcscat(szLDAPDn, TEXT(","));
}
}
break;
}
}
if (szLDAPServer && *szLDAPServer) {
*pszLDAPServer = szLDAPServer;
}
if (szLDAPDn && *szLDAPDn) {
*pszLDAPDn = szLDAPDn;
}
*pdwPort = dwPortNumber;
error:
if (szLDAPServer && (*szLDAPServer == NULL)) {
FreeADsMem(szLDAPServer);
}
if (szLDAPDn && (*szLDAPDn == NULL)) {
FreeADsMem(szLDAPDn);
}
FreeObjectInfo( &ObjectInfo );
RRETURN(hr);
}
HRESULT
BuildADsPathFromLDAPPath2(
DWORD dwServerPresent,
LPWSTR szADsNamespace,
LPWSTR szLDAPServer,
DWORD dwPort,
LPWSTR szLDAPDn,
LPWSTR * ppszADsPathName
)
{
LPWSTR pszADsPathName = NULL;
HRESULT hr = S_OK;
DWORD dwLen;
WCHAR szPort[32];
LPWSTR pszDisplayDN = NULL;
hr = GetDisplayName(
szLDAPDn,
&pszDisplayDN
);
BAIL_ON_FAILURE(hr);
dwLen = STRING_LENGTH(szADsNamespace) +
STRING_LENGTH(szLDAPServer) +
STRING_LENGTH(pszDisplayDN) +
STRING_LENGTH(L"//") +
STRING_LENGTH(L"/") +
1;
if (IS_EXPLICIT_PORT(dwPort) ) {
wsprintf(szPort, L":%d", dwPort);
dwLen += STRING_LENGTH(szPort);
}
pszADsPathName = (LPWSTR) AllocADsMem( dwLen * sizeof(WCHAR) );
if(!pszADsPathName) {
hr = E_OUTOFMEMORY;
goto error;
}
wsprintf(pszADsPathName,L"%s//", szADsNamespace);
if (dwServerPresent) {
if (szLDAPServer && *szLDAPServer) {
wcscat(pszADsPathName, szLDAPServer);
if (IS_EXPLICIT_PORT(dwPort) ) {
wsprintf(szPort, L":%d", dwPort);
wcscat(pszADsPathName, szPort);
}
}
if (pszDisplayDN && *pszDisplayDN) {
wcscat(pszADsPathName, L"/");
wcscat(pszADsPathName, pszDisplayDN);
}
}else {
if (pszDisplayDN && *pszDisplayDN) {
wcscat(pszADsPathName, pszDisplayDN);
}
}
*ppszADsPathName = pszADsPathName;
error:
if (pszDisplayDN) {
FreeADsMem(pszDisplayDN);
}
RRETURN(hr);
}
HRESULT
GetNamespaceFromADsPath(
LPWSTR szADsPath,
LPWSTR pszNamespace
)
{
LPWSTR pszTemp;
// Get the namespace name
pszTemp = _tcschr( szADsPath, TEXT(':'));
if (!pszTemp) {
RRETURN(E_FAIL);
}
_tcsncpy (pszNamespace, szADsPath, (int)(pszTemp - szADsPath));
pszNamespace[pszTemp - szADsPath] = L'\0';
RRETURN(S_OK);
}
//
// Change the separator of a DN from '\' to '/' so that it can be used in
// an ADsPath
HRESULT
ChangeSeparator(
LPWSTR pszDN
)
{
LPWSTR ptr;
if (pszDN) {
while (ptr = wcschr(pszDN, '\\')) {
*ptr = '/';
}
}
return (S_OK);
}