Files
admin
base
com
developer
drivers
ds
adsi
dbgexts
deldsm
docs
drt
errmsg
include
ldap
ldapc
msext
nds
ndsext
nocairo
noole
novellnw
nw312
nwnds
nwutils
oledsiid
oledsvw
public
router
setup
tlb
types
utils
winnt
common
support
win95
winnt
_windows_nt_provider_component_description.htm
adsi_winnt_provider_{f273c0c6-f889-47a9-abcb-c03e0a193bbb}.sld
ccache.cxx
ccache.hxx
ccgi.cxx
ccgi.hxx
ccomp.cxx
ccomp.hxx
ccred.cxx
ccred.hxx
cdispmgr.cxx
cdispmgr.hxx
cdomain.cxx
cdomain.hxx
cdompwd.cxx
cdompwd.hxx
cenmfpre.cxx
cenmfpre.hxx
cenmfpse.cxx
cenmfpse.hxx
cenmfpsh.cxx
cenmfpsh.hxx
cenmlgrp.cxx
cenmlgrp.hxx
cenumcom.cxx
cenumcom.hxx
cenumdom.cxx
cenumdom.hxx
cenumfsh.cxx
cenumfsh.hxx
cenumgrp.cxx
cenumgrp.hxx
cenumjob.cxx
cenumjob.hxx
cenumns.cxx
cenumns.hxx
cenumres.cxx
cenumres.hxx
cenumsch.cxx
cenumsch.hxx
cenumses.cxx
cenumses.hxx
cenumusr.cxx
cenumusr.hxx
cenumvar.cxx
cenumvar.hxx
cextmgr.cxx
cextmgr.hxx
cfpnwfsh.cxx
cfpnwfsh.hxx
cfpnwres.cxx
cfpnwres.hxx
cfpnwses.cxx
cfpnwses.hxx
cfpnwsrv.cxx
cfpnwsrv.hxx
cfserv.cxx
cfserv.hxx
cfshare.cxx
cfshare.hxx
cggi.cxx
cggi.hxx
cgroup.cxx
cgroup.hxx
cgroups.cxx
cgroups.hxx
cjob.cxx
cjob.hxx
clgroups.cxx
clgroups.hxx
cnamcf.cxx
cnamcf.hxx
cnamesp.cxx
cnamesp.hxx
cobjcach.cxx
cobjcach.hxx
common.cxx
common.hxx
core.cxx
core.hxx
cpgi.cxx
cpgi.hxx
cprinter.cxx
cprinter.hxx
cprops.cxx
cprops.hxx
cprov.cxx
cprov.hxx
cprovcf.cxx
cprovcf.hxx
credel.cxx
credel.hxx
cres.cxx
cres.hxx
cschema.cxx
cschema.hxx
cserv.cxx
cserv.hxx
csess.cxx
csess.hxx
cuar.cxx
cuar.hxx
cuas.cxx
cuas.hxx
cubi.cxx
cubi.hxx
cumiconn.cxx
cumiconn.hxx
cumicurs.cxx
cumicurs.hxx
cumiobj.cxx
cumiobj.hxx
cumiprop.cxx
cumiprop.hxx
cuoi.cxx
cuoi.hxx
cuser.cxx
cuser.hxx
cusers.cxx
cusers.hxx
dirs
extension.cxx
extension.hxx
fpnwutil.cxx
fpnwutil.hxx
fsmacro.h
getobj.cxx
getobj.hxx
globals.cxx
globals.hxx
grput2.cxx
grput2.hxx
grput3.cxx
grput3.hxx
grputils.cxx
grputils.hxx
guid.c
guid.h
ids.hxx
jobhlp.cxx
jobhlp.hxx
libmain.cxx
macro.h
makefil0
nt2ods.cxx
nt2ods.hxx
nt2umi.cxx
nt2umi.hxx
nt2var.cxx
nt2var.hxx
ntcopy.cxx
ntcopy.hxx
ntmrshl.cxx
ntmrshl.hxx
nttypes.h
ntumrshl.cxx
ntumrshl.hxx
object.cxx
object.hxx
ods2nt.cxx
ods2nt.hxx
parse.cxx
parse.hxx
printhlp.cxx
printhlp.hxx
property.cxx
property.hxx
servhlp.cxx
servhlp.hxx
structs.hxx
system.cxx
system.hxx
umi.cxx
umi.hxx
umi2nt.cxx
umi2nt.hxx
umi_i.c
umiconcf.cxx
umiconcf.hxx
umierr.hxx
umiglob.cxx
umiglob.hxx
var2nt.cxx
var2nt.hxx
winnt.def
winnt.hxx
winnt.odl
winnt.rc
winnt2.h
winntrc.h
xml
adoinst.cmd
adsi40.mk
dirs
distnt40.cmd
install.cmd
makedist.cmd
makefil0
makerel.cmd
oleds.inc
relnt40.cmd
sources.inc
dns
ds
edb500
ese98
inc
nameres
netapi
nlrepl
nw
published
safealloca
security
win32
xpress
dirs
project.mk
enduser
inetcore
inetsrv
loc
mergedcomponents
multimedia
net
printscan
public
published
sdktools
shell
termsrv
tools
windows
dirs
makefil0
2025-04-27 07:49:33 -04:00

513 lines
15 KiB
C++

//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 2000.
//
// File: umi.cxx
//
// Contents: Contains miscellaneous UMI routines.
//
// History: 02-28-00 SivaramR Created.
//
//----------------------------------------------------------------------------
#include "winnt.hxx"
//----------------------------------------------------------------------------
// Function: IsPreDefinedErrorCode
//
// Synopsis: Returns TRUE if the error code passed in is a valid UMI error
// code i.e one that can be returned by a UMI method. Returns
// FALSE otherwise.
//
// Arguments: Self explanatory
//
// Returns: TRUE/FALSE as mentioned above
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
BOOL IsPreDefinedErrorCode(HRESULT hr)
{
switch(hr) {
case E_UNEXPECTED:
case E_NOTIMPL:
case E_OUTOFMEMORY:
case E_INVALIDARG:
case E_NOINTERFACE:
case E_POINTER:
case E_HANDLE:
case E_ABORT:
case E_FAIL:
case E_ACCESSDENIED:
case E_PENDING:
case UMI_E_TYPE_MISMATCH:
case UMI_E_NOT_FOUND:
case UMI_E_INVALID_FLAGS:
case UMI_E_UNSUPPORTED_OPERATION:
case UMI_E_UNSUPPORTED_FLAGS:
case UMI_E_SYNCHRONIZATION_REQUIRED:
case UMI_E_UNBOUND_OBJECT:
RRETURN(TRUE);
default:
RRETURN(FALSE);
}
}
//----------------------------------------------------------------------------
// Function: MapHrToUmiError
//
// Synopsis: This function returns the UMI error corresponding to a HRESULT
// returned by the WinNT provider. The HRESULT can be retrieved
// using GetLastStatus(), if required.
//
// Arguments: Self explanatory
//
// Returns: UMI error corresponding to the HRESULT
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
HRESULT MapHrToUmiError(HRESULT hr)
{
if(SUCCEEDED(hr)) {
if(S_FALSE == hr) // may be returned by end of cursor enumeration
RRETURN(UMI_S_FALSE);
else
RRETURN(UMI_S_NO_ERROR);
}
// we had a failure
if(TRUE == IsPreDefinedErrorCode(hr))
RRETURN(hr); // OK to return this as a UMI error
// Try to map ADSI errors to appropriate UMI errors. Default is to
// map to E_FAIL.
switch(hr) {
case E_ADS_INVALID_DOMAIN_OBJECT:
case E_ADS_INVALID_USER_OBJECT:
case E_ADS_INVALID_COMPUTER_OBJECT:
case E_ADS_UNKNOWN_OBJECT:
RRETURN(UMI_E_OBJECT_NOT_FOUND);
case E_ADS_PROPERTY_NOT_FOUND:
RRETURN(UMI_E_PROPERTY_NOT_FOUND);
case E_ADS_BAD_PARAMETER:
RRETURN(UMI_E_INVALIDARG);
case E_ADS_CANT_CONVERT_DATATYPE:
RRETURN(UMI_E_TYPE_MISMATCH);
case E_ADS_BAD_PATHNAME:
RRETURN(UMI_E_INVALIDARG);
case E_ADS_OBJECT_UNBOUND:
RRETURN(UMI_E_UNBOUND_OBJECT);
case HRESULT_FROM_WIN32(NERR_UserNotFound):
case HRESULT_FROM_WIN32(NERR_GroupNotFound):
case HRESULT_FROM_WIN32(ERROR_NO_SUCH_DOMAIN):
case HRESULT_FROM_WIN32(ERROR_BAD_NETPATH):
RRETURN(UMI_E_OBJECT_NOT_FOUND);
default:
RRETURN(UMI_E_FAIL);
}
}
//----------------------------------------------------------------------------
// Function: ValidateUrl
//
// Synopsis: This function checks to see if a UMI path has the correct
// namespace and server.
//
// Arguments:
//
// pURL Pointer to URL interface containing the UMI path
//
// Returns: S_OK on success. Error code otherwise.
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
static HRESULT ValidateUrl(
IUmiURL *pURL
)
{
HRESULT hr = S_OK;
WCHAR pszTmpArray[MAX_URL+1];
ULONG ulTmpArraySize = 0;
ULONGLONG PathType = 0;
hr = pURL->GetPathInfo(0, &PathType);
BAIL_ON_FAILURE(hr);
if(PathType & UMIPATH_INFO_RELATIVE_PATH)
// relative paths cannot be converted to a WinNT path
BAIL_ON_FAILURE(hr = UMI_E_INVALID_PATH);
// Make sure server name is empty. WinNT does not support servername
// in UMI path.
ulTmpArraySize = MAX_URL;
hr = pURL->GetLocator(
&ulTmpArraySize,
pszTmpArray
);
if(WBEM_E_BUFFER_TOO_SMALL == hr)
// Locator is not an empty string
hr = UMI_E_INVALID_PATH;
BAIL_ON_FAILURE(hr);
if(wcscmp(pszTmpArray, L""))
BAIL_ON_FAILURE(hr = UMI_E_INVALID_PATH);
// Make sure namespace is WinNT
ulTmpArraySize = MAX_URL;
hr = pURL->GetRootNamespace(
&ulTmpArraySize,
pszTmpArray
);
if(WBEM_E_BUFFER_TOO_SMALL == hr)
// Namespace is not WinNT
hr = UMI_E_INVALID_PATH;
BAIL_ON_FAILURE(hr);
if(_wcsicmp(pszTmpArray, L"WinNT"))
BAIL_ON_FAILURE(hr = UMI_E_INVALID_PATH);
error:
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: UmiToWinNTPath
//
// Synopsis: This function converts a UMI path into a native path.
//
// Arguments:
//
// pURL Pointer to URL interface containing the UMI path
// ppszWinNTPath Returns the WinNT path
// pdwNumComps Returns the number of components in the UMI path
// pppszClasses Returns the class of each component in the UMI path
//
// Returns: S_OK on success. Error code otherwise.
//
// Modifies: *ppszWinNTPath to return the WinNT path
// *pdwNumComps to return the number of components
// *pppszClasses to return the class of each component
//
//----------------------------------------------------------------------------
HRESULT UmiToWinNTPath(
IUmiURL *pURL,
WCHAR **ppszWinNTPath,
DWORD *pdwNumComps,
LPWSTR **pppszClasses
)
{
HRESULT hr = S_OK;
WCHAR *pszWinNTPath = NULL;
WCHAR pszTmpArray[MAX_URL+1], pszValueArray[MAX_URL+1];
WCHAR *pszValuePtr = NULL, pszClassArray[MAX_URL+1];
ULONG ulTmpArraySize = 0, ulNumComponents = 0, ulIndex = 0;
ULONG ulKeyCount = 0, ulValueArraySize = 0, ulClassArraySize = 0;
IUmiURLKeyList *pKeyList = NULL;
LPWSTR *ppszClasses = NULL;
ADsAssert( (pURL != NULL) && (ppszWinNTPath != NULL) &&
(pdwNumComps != NULL) && (pppszClasses != NULL) );
*ppszWinNTPath = NULL;
*pdwNumComps = 0;
*pppszClasses = NULL;
hr = ValidateUrl(pURL);
BAIL_ON_FAILURE(hr);
// Get the total length needed for the WinNT path
ulTmpArraySize = MAX_URL;
hr = pURL->Get(0, &ulTmpArraySize, pszTmpArray);
if(hr != WBEM_E_BUFFER_TOO_SMALL)
BAIL_ON_FAILURE(hr);
pszWinNTPath = (WCHAR *) AllocADsMem(ulTmpArraySize * sizeof(WCHAR));
if(NULL == pszWinNTPath)
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
wsprintf(pszWinNTPath, L"%s", L"WinNT:");
hr = pURL->GetComponentCount(&ulNumComponents);
BAIL_ON_FAILURE(hr);
if(0 == ulNumComponents) {
// umi:///winnt translates to WinNT: . Nothing more to do
*ppszWinNTPath = pszWinNTPath;
RRETURN(S_OK);
}
ppszClasses = (LPWSTR *) AllocADsMem(ulNumComponents * sizeof(LPWSTR *));
if(NULL == ppszClasses) {
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
}
memset(ppszClasses, 0, ulNumComponents * sizeof(LPWSTR *));
// we have at least one component in the path
wcscat(pszWinNTPath, L"/");
for(ulIndex = 0; ulIndex < ulNumComponents; ulIndex++) {
ulClassArraySize = MAX_URL;
pKeyList = NULL;
hr = pURL->GetComponent(
ulIndex,
&ulClassArraySize,
pszClassArray,
&pKeyList
);
if(WBEM_E_BUFFER_TOO_SMALL == hr)
// none of the WinNT classes is so long, so this has to be a bad path.
hr = UMI_E_INVALID_PATH;
BAIL_ON_FAILURE(hr);
// WinNT does not supports components with an empty class name
if(!wcscmp(pszClassArray, L""))
BAIL_ON_FAILURE(hr = UMI_E_INVALID_PATH);
ppszClasses[ulIndex] = AllocADsStr(pszClassArray);
if(NULL == ppszClasses[ulIndex]) {
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
}
ADsAssert(pKeyList != NULL);
// make sure there is only one key
hr = pKeyList->GetCount(&ulKeyCount);
BAIL_ON_FAILURE(hr);
if(ulKeyCount != 1)
BAIL_ON_FAILURE(hr = UMI_E_INVALID_PATH);
ulValueArraySize = MAX_URL;
ulTmpArraySize = MAX_URL;
pszValuePtr = pszValueArray;
hr = pKeyList->GetKey(
0,
0,
&ulTmpArraySize,
pszTmpArray,
&ulValueArraySize,
pszValueArray
);
if( (WBEM_E_BUFFER_TOO_SMALL == hr) && (ulValueArraySize > MAX_URL) ) {
pszValuePtr = (WCHAR *) AllocADsMem(ulValueArraySize);
if(NULL == pszValuePtr)
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
hr = pKeyList->GetKey(
0,
0,
&ulTmpArraySize,
pszTmpArray,
&ulValueArraySize,
pszValuePtr
);
}
if(WBEM_E_BUFFER_TOO_SMALL == hr)
// Key is always "Name" in WinNT. So, if the size required if so
// high, it indicates a bad path
hr = UMI_E_INVALID_PATH;
BAIL_ON_FAILURE(hr);
// Key has to be "Name" or empty in WinNT
if( _wcsicmp(pszTmpArray, WINNT_KEY_NAME) && wcscmp(pszTmpArray, L"") )
BAIL_ON_FAILURE(hr = UMI_E_INVALID_PATH);
// append the value to the WinNT path
wcscat(pszWinNTPath, L"/");
wcscat(pszWinNTPath, pszValuePtr);
if(pszValuePtr != pszValueArray)
FreeADsMem(pszValuePtr);
pKeyList->Release();
} // for
// append the class to the WInNT path
wcscat(pszWinNTPath, L",");
wcscat(pszWinNTPath, pszClassArray);
*ppszWinNTPath = pszWinNTPath;
*pdwNumComps = ulNumComponents;
*pppszClasses = ppszClasses;
RRETURN(S_OK);
error:
if(pszWinNTPath != NULL)
FreeADsMem(pszWinNTPath);
if( (pszValuePtr != NULL) && (pszValuePtr != pszValueArray) )
FreeADsMem(pszValuePtr);
if(ppszClasses != NULL) {
for(ulIndex = 0; ulIndex < ulNumComponents; ulIndex++) {
if(ppszClasses[ulIndex] != NULL)
FreeADsStr(ppszClasses[ulIndex]);
}
FreeADsMem(ppszClasses);
}
if(pKeyList != NULL)
pKeyList->Release();
RRETURN(hr);
}
//----------------------------------------------------------------------------
// Function: ADsToUmiPath
//
// Synopsis: This function converts an ADsPath to a UMI path (full, short or
// relative depending on a flag).
//
// Arguments:
//
// bstrADsPath ADsPath to be converted
// pObjectInfo Contains the values of each component in the ADsPath
// CompClasses Array containing the classes of each component of the ADsPath
// dwNumComponents Number of classes(components) in the ADsPath
// dwUmiPathType Specifies the format of the UMI path to be returned
// ppszUmiPath Returns UMI path in the requested format
//
// Returns: S_OK on success. Error code otherwise.
//
// Modifies: *ppszUmiPath to return the UMI path
//
//----------------------------------------------------------------------------
HRESULT ADsToUmiPath(
BSTR bstrADsPath,
OBJECTINFO *pObjectInfo,
LPWSTR CompClasses[],
DWORD dwNumComponents,
DWORD dwUmiPathType,
LPWSTR *ppszUmiPath
)
{
HRESULT hr = S_OK;
DWORD dwBufferLen = 0, dwIndex = 0;
LPWSTR pszUmiPath = NULL, *pszComponents = NULL;
ADsAssert( (bstrADsPath != NULL) && (CompClasses != NULL) &&
(pObjectInfo != NULL) && (ppszUmiPath != NULL) );
*ppszUmiPath = NULL;
// calculate approximate length of buffer required to return the UMI path
// Each component is of the form "class.name=value". "value" is already
// part of the ADSI path. Include the size of each class and add 6 to
// account for "Name" and '.' and '='.
dwBufferLen = wcslen(L"umi:///winnt/") + wcslen(bstrADsPath) +
dwNumComponents * (MAX_CLASS + 6) + 1;
pszUmiPath = (LPWSTR) AllocADsMem(dwBufferLen * sizeof(WCHAR));
if(NULL == pszUmiPath)
BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
// if ADsPath is empty and it is not a namespace object, then this must be
// a session, resource or printjob object. Return an empty path for these.
// Namespace objects have no components in the ADsPath, but they have a
// non-empty ADsPath ("WinNT:")
if( (0 == dwNumComponents) && _wcsicmp(CompClasses[0], L"Namespace") ) {
wcscpy(pszUmiPath, L"");
*ppszUmiPath = pszUmiPath;
RRETURN(S_OK);
}
if( (RELATIVE_UMI_PATH == dwUmiPathType) ||
(FULL_RELATIVE_UMI_PATH == dwUmiPathType) ) {
// return the last component, if any
if(0 == dwNumComponents) {
*pszUmiPath = '\0';
}
else {
wcscpy(pszUmiPath,
CompClasses[dwNumComponents - 1]
);
if(FULL_RELATIVE_UMI_PATH == dwUmiPathType)
wcscat(pszUmiPath, L".Name=");
else
wcscat(pszUmiPath, L"=");
pszComponents = pObjectInfo->DisplayComponentArray;
wcscat(pszUmiPath, pszComponents[dwNumComponents - 1]);
}
*ppszUmiPath = pszUmiPath;
RRETURN(S_OK);
}
wcscpy(pszUmiPath, L"umi:///winnt");
// for namespace objects, there are no components and hence the umi path
// is completely constructed at this point.
if(0 == dwNumComponents) {
*ppszUmiPath = pszUmiPath;
RRETURN(S_OK);
}
wcscat(pszUmiPath, L"/");
pszComponents = pObjectInfo->DisplayComponentArray;
for(dwIndex = 0; dwIndex < dwNumComponents; dwIndex++) {
wcscat(pszUmiPath, CompClasses[dwIndex]);
if(FULL_UMI_PATH == dwUmiPathType)
wcscat(pszUmiPath, L".Name=");
else if(SHORT_UMI_PATH == dwUmiPathType)
wcscat(pszUmiPath, L"=");
wcscat(pszUmiPath, pszComponents[dwIndex]);
if(dwIndex != (dwNumComponents - 1))
wcscat(pszUmiPath, L"/");
}
*ppszUmiPath = pszUmiPath;
RRETURN(S_OK);
error:
if(pszUmiPath != NULL)
FreeADsMem(pszUmiPath);
RRETURN(hr);
}