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.
 
 
 
 
 
 

4302 lines
112 KiB

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: getobj.cxx
//
// Contents: Windows NT 3.5 GetObject functionality
//
// History:
//----------------------------------------------------------------------------
#include "winnt.hxx"
#pragma hdrstop
extern WCHAR * szWinNTPrefix;
//+---------------------------------------------------------------------------
// Function: GetObject
//
// Synopsis: Called by ResolvePathName to return an object
//
// Arguments: [LPWSTR szBuffer]
// [LPVOID *ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT
GetObject(
LPWSTR szBuffer,
LPVOID *ppObject,
CWinNTCredentials& Credentials
)
{
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = &ObjectInfo;
CLexer Lexer(szBuffer);
HRESULT hr;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = Object(&Lexer, pObjectInfo);
BAIL_IF_ERROR(hr);
hr = ValidateProvider(pObjectInfo);
BAIL_IF_ERROR(hr);
switch (pObjectInfo->ObjectType) {
case TOKEN_DOMAIN:
hr = GetDomainObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_USER:
hr = GetUserObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_COMPUTER:
hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_PRINTER:
hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_SERVICE:
hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_FILESERVICE:
hr = GetFileServiceObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_GROUP:
hr = GetGroupObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_LOCALGROUP:
hr = E_ADS_BAD_PATHNAME;
//hr = GetLocalGroupObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_GLOBALGROUP:
hr = E_ADS_BAD_PATHNAME;
//hr = GetGlobalGroupObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_FILESHARE:
hr = GetFileShareObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_SCHEMA:
hr = GetSchemaObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_CLASS:
hr = GetClassObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_PROPERTY:
hr = GetPropertyObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_SYNTAX:
hr = GetSyntaxObject(pObjectInfo, ppObject, Credentials);
break;
case TOKEN_WORKGROUP:
hr = GetWorkGroupObject(pObjectInfo, ppObject, Credentials);
break;
default:
hr = HeuristicGetObject(pObjectInfo, ppObject, Credentials);
break;
}
cleanup:
FreeObjectInfo( &ObjectInfo, TRUE );
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetDomainObject
//
// Synopsis: called by GetObject
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT
GetNamespaceObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
HRESULT hr;
hr = ValidateNamespaceObject(
pObjectInfo
);
BAIL_ON_FAILURE(hr);
// check if the call is from UMI
if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
hr = CWinNTNamespace::CreateNamespace(
L"ADs:",
L"WinNT:",
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
ppObject
);
}
else { // came in through ADSI
hr = CoCreateInstance(CLSID_WinNTNamespace,
NULL,
CLSCTX_INPROC_SERVER,
IID_IUnknown,
(void **)ppObject );
}
error:
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetDomainObject
//
// Synopsis: called by GetObject
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT
GetDomainObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
HRESULT hr;
IUnknown *pUnknown = NULL;
IADs *pADs = NULL;
NET_API_STATUS nasStatus;
WCHAR szHostServerName[MAX_PATH];
WCHAR ADsParent[MAX_ADS_PATH];
WCHAR szSAMName[MAX_ADS_PATH];
szSAMName[0] = L'\0';
*ppObject = NULL;
if (pObjectInfo->NumComponents != 1) {
RRETURN(E_ADS_INVALID_DOMAIN_OBJECT);
}
//
// Verify that this object is really a domain
//
// We can try and ref the domain here but it will
// anyway end up in WinNTGetCachedDCName call in
// CWinNTCredentials::RefDomain, so there is no point in
// doing that
hr = WinNTGetCachedDCName(
pObjectInfo->ComponentArray[0],
szHostServerName,
Credentials.GetFlags()
);
BAIL_ON_FAILURE(hr);
if (szSAMName[0] != L'\0') {
if (pObjectInfo->ComponentArray[0]) {
FreeADsStr(pObjectInfo->ComponentArray[0]);
}
pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName);
if (!pObjectInfo) {
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
}
}
hr = BuildParent(
pObjectInfo,
ADsParent
);
BAIL_ON_FAILURE(hr);
hr = CWinNTDomain::CreateDomain(
ADsParent,
pObjectInfo->ComponentArray[0],
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
error:
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetWorkgroupObject
//
// Synopsis: called by GetObject.
// Note: We really don't have a workgroup object. But we
// need to support a syntax such as @WinNT!workstation to
// allow for IADsContainer interface methods. There is
// no authentication that needs to done.
//
// Arguments: [POBJECTINFO pObjectInfo]
// [LPVOID * ppObject]
//
// Returns: HRESULT
//
// Modifies: -
//
// History: 05-23-96 RamV Created.
//
//----------------------------------------------------------------------------
HRESULT
GetWorkGroupObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
HRESULT hr;
IUnknown *pUnknown = NULL;
IADs *pADs = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
WCHAR szName[MAX_PATH];
*ppObject = NULL;
if (pObjectInfo->NumComponents != 1) {
RRETURN(E_ADS_INVALID_DOMAIN_OBJECT);
}
//
// any single component oleds path can be validated as a workgroup
//
hr = BuildParent(
pObjectInfo,
ADsParent
);
BAIL_ON_FAILURE(hr);
hr = CWinNTDomain::CreateDomain(
ADsParent,
pObjectInfo->ComponentArray[0],
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
error:
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetUserObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
// 8-8-96 ramv Modified.
//
//----------------------------------------------------------------------------
HRESULT
GetUserObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szServerName = NULL;
LPWSTR szDomainName = NULL;
LPWSTR szUserName = NULL;
DWORD dwParentId = 0;
WCHAR szComputerParent[MAX_PATH];
POBJECTINFO pUserObjectInfo = NULL;
hr = ValidateUserObject(
pObjectInfo,
&dwParentId,
Credentials
);
BAIL_ON_FAILURE(hr);
switch (pObjectInfo->NumComponents) {
case 2:
//
// could be user in computer or user in domain
//
if(dwParentId == WINNT_DOMAIN_ID){
szDomainName = pObjectInfo->ComponentArray[0];
szUserName = pObjectInfo->ComponentArray[1];
szServerName = NULL;
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
} else {
//
// user in a computer
//
hr = ConstructFullObjectInfo(pObjectInfo,
&pUserObjectInfo,
Credentials );
if (SUCCEEDED(hr)) {
hr = BuildParent(pUserObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pUserObjectInfo->ComponentArray[0];
szServerName = pUserObjectInfo->ComponentArray[1];
szUserName = pUserObjectInfo->ComponentArray[2];
}
else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
// We alread know that the object is valid,
// So we should set appropriate values and proceed to
// create the object
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = NULL;
szServerName = pObjectInfo->ComponentArray[0];
szUserName = pObjectInfo->ComponentArray[1];
}
}
break;
case 3:
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szUserName = pObjectInfo->ComponentArray[2];
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
break;
}
hr = CWinNTUser::CreateUser(ADsParent,
dwParentId,
szDomainName,
szServerName,
szUserName,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
FreeObjectInfo(pUserObjectInfo);
RRETURN(hr);
error:
if (pUnknown) {
pUnknown->Release();
}
*ppObject = NULL;
FreeObjectInfo(pUserObjectInfo);
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetUserObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 8-8-96 ramv Created.
//
//----------------------------------------------------------------------------
HRESULT
GetUserObjectInDomain(
LPWSTR pszHostServerName,
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szServerName = NULL;
LPWSTR szDomainName = NULL;
LPWSTR szUserName = NULL;
DWORD dwParentId = WINNT_DOMAIN_ID;
LPUSER_INFO_20 lpUI = NULL;
NET_API_STATUS nasStatus;
BOOL fRefAdded = FALSE;
LPUSER_INFO_0 lpUI_0 = NULL;
DWORD dwLevelUsed = 20;
// At this point a \\ has been prepended to the host
// we need to get rid of it.
hr = Credentials.RefServer(pszHostServerName+2);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
nasStatus = NetUserGetInfo(pszHostServerName,
pObjectInfo->ComponentArray[1],
20,
(LPBYTE *)&lpUI);
if (nasStatus == ERROR_ACCESS_DENIED) {
// try and drop down to level 0 as that may work
dwLevelUsed = 0;
nasStatus = NetUserGetInfo(
pszHostServerName,
pObjectInfo->ComponentArray[1],
0,
(LPBYTE *)&lpUI_0
);
}
// deref if necessary, note no error recovery possible
if (fRefAdded) {
Credentials.DeRefServer();
fRefAdded = FALSE;
}
hr = HRESULT_FROM_WIN32(nasStatus);
BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (dwLevelUsed == 20) {
if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) {
FreeADsStr(pObjectInfo->ComponentArray[1]);
pObjectInfo->ComponentArray[1] = AllocADsStr(lpUI->usri20_name);
}
if (!pObjectInfo->ComponentArray[1])
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
}
// if it is not a level 20 call then we will just use
// whatever the user gave us
szDomainName = pObjectInfo->ComponentArray[0];
szUserName = pObjectInfo->ComponentArray[1];
szServerName = NULL;
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
hr = CWinNTUser::CreateUser(ADsParent,
dwParentId,
szDomainName,
szServerName,
szUserName,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
error:
if (FAILED(hr) && pUnknown) {
pUnknown->Release();
*ppObject = NULL;
}
if (lpUI)
NetApiBufferFree((LPBYTE)lpUI);
if (lpUI_0) {
NetApiBufferFree((LPBYTE)lpUI_0);
}
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetUserObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
// 8-8-96 ramv Modified.
//
//----------------------------------------------------------------------------
HRESULT
GetUserObjectInComputer(
LPWSTR pszHostServerName, // pdc name
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szServerName = NULL;
LPWSTR szDomainName = NULL;
LPWSTR szUserName = NULL;
DWORD dwParentId = WINNT_COMPUTER_ID;
WCHAR szComputerParent[MAX_PATH];
POBJECTINFO pUserObjectInfo = NULL;
WCHAR lpszUncName[MAX_PATH];
NET_API_STATUS nasStatus;
LPBYTE lpUI = NULL;
BOOL fRefAdded = FALSE;
switch (pObjectInfo->NumComponents) {
case 2:
//
// could be user in computer
//
//
// first validate user
//
hr = Credentials.RefServer(pObjectInfo->ComponentArray[0]);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
MakeUncName(pObjectInfo->ComponentArray[0],
lpszUncName);
nasStatus = NetUserGetInfo(lpszUncName,
pObjectInfo->ComponentArray[1],
20,
&lpUI);
if (fRefAdded) {
Credentials.DeRefServer();
fRefAdded = FALSE;
}
hr = HRESULT_FROM_WIN32(nasStatus);
BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[1]
&& ((LPUSER_INFO_20)lpUI)->usri20_name) {
FreeADsStr(pObjectInfo->ComponentArray[1]);
pObjectInfo->ComponentArray[1]
= AllocADsStr(((LPUSER_INFO_20)lpUI)->usri20_name);
}
if (!pObjectInfo->ComponentArray[1])
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
// This call will add the domain information to the
// objectInfo blob, so that the ComponentArray[2] is valid
hr = ConstructFullObjectInfo(pObjectInfo,
&pUserObjectInfo,
Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pUserObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pUserObjectInfo->ComponentArray[0];
szServerName = pUserObjectInfo->ComponentArray[1];
szUserName = pUserObjectInfo->ComponentArray[2];
break;
case 3:
//
// ValidateComputerParent and validate user in computer
//
hr = ValidateComputerParent(pObjectInfo->ComponentArray[0],
pObjectInfo->ComponentArray[1],
Credentials);
BAIL_ON_FAILURE(hr);
hr = Credentials.RefServer(pObjectInfo->ComponentArray[1]);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
MakeUncName(pObjectInfo->ComponentArray[1],
lpszUncName);
nasStatus = NetUserGetInfo(lpszUncName,
pObjectInfo->ComponentArray[2],
20,
(LPBYTE *)&lpUI);
if (fRefAdded) {
Credentials.DeRefServer();
fRefAdded = FALSE;
}
hr = HRESULT_FROM_WIN32(nasStatus);
BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[2]
&& ((LPUSER_INFO_20)lpUI)->usri20_name) {
FreeADsStr(pObjectInfo->ComponentArray[2]);
pObjectInfo->ComponentArray[2]
= AllocADsStr(((LPUSER_INFO_20)lpUI)->usri20_name);
}
if (!pObjectInfo->ComponentArray[2])
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szUserName = pObjectInfo->ComponentArray[2];
break;
}
hr = CWinNTUser::CreateUser(ADsParent,
dwParentId,
szDomainName,
szServerName,
szUserName,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
error:
if (FAILED(hr)) {
if (pUnknown) {
pUnknown->Release();
}
*ppObject = NULL;
}
else {
*ppObject = pUnknown;
}
if (lpUI) {
NetApiBufferFree(lpUI);
}
FreeObjectInfo(pUserObjectInfo);
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetComputerObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT
GetComputerObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
HRESULT hr = S_OK;
WCHAR ADsParent[MAX_ADS_PATH];
TCHAR szUncName[MAX_PATH];
NET_API_STATUS nasStatus;
POBJECTINFO pComputerObjectInfo = NULL;
BOOL fNoWksta = FALSE;
WCHAR szCompName[MAX_PATH];
DWORD dwSize = MAX_PATH;
//
// The following function call merely checks to see if the domain is
// correct. If not, we can assume that the computer does not belong to
// a domain.
//
hr = ValidateComputerObject(pObjectInfo, Credentials);
if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted))
fNoWksta = TRUE;
else
BAIL_ON_FAILURE(hr);
// Normall we can expect that the workstation service will
// be started. This will not be the case for minimum installs
if (!fNoWksta) {
if(pObjectInfo->NumComponents == 1){
//
// we need to supply the workgroup name for this computer
// This is needed because EnumLocalGroups requires the
// workgroup name to function properly
//
hr = ConstructFullObjectInfo(pObjectInfo,
&pComputerObjectInfo,
Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pComputerObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
hr = CWinNTComputer::CreateComputer(
ADsParent,
pComputerObjectInfo->ComponentArray[0],
pComputerObjectInfo->ComponentArray[1],
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
ppObject
);
} else if(pObjectInfo->NumComponents == 2) {
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
hr = CWinNTComputer::CreateComputer(
ADsParent,
pObjectInfo->ComponentArray[0],
pObjectInfo->ComponentArray[1],
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
ppObject);
}
} else {
// Else clause for if(!fWksta)
// This means that workstation services were not
// started, we need to verify that the host computer
// is the one they are interested in.
if ((pObjectInfo->NumComponents != 1) || (!GetComputerName(szCompName, &dwSize))) {
// We cannot get the computer name so bail
BAIL_ON_FAILURE(hr);
}
// Compare the names before we continue
#ifdef WIN95
if (_wcsicmp(szCompName, pObjectInfo->ComponentArray[0])) {
#else
if (CompareStringW(
LOCALE_SYSTEM_DEFAULT,
NORM_IGNORECASE,
szCompName,
-1,
pObjectInfo->ComponentArray[0],
-1
) != CSTR_EQUAL ) {
#endif
// names do not match
BAIL_ON_FAILURE(hr);
}
hr = CWinNTComputer::CreateComputer(
L"WinNT:",
NULL,
pObjectInfo->ComponentArray[0],
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
ppObject
);
BAIL_ON_FAILURE(hr);
}
error:
if(pComputerObjectInfo){
FreeObjectInfo(pComputerObjectInfo);
}
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetPrinterObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 01/03/96 Ramv Created.
//
//----------------------------------------------------------------------------
HRESULT
GetPrinterObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR szADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szDomainName = NULL;
LPWSTR szServerName = NULL;
LPWSTR szPrinterName = NULL;
DWORD dwParentId = 0;
LPWSTR szComputerParent[MAX_PATH];
POBJECTINFO pPrinterObjectInfo = NULL;
if (!(pObjectInfo->NumComponents == 3 ||pObjectInfo->NumComponents == 2)){
RRETURN(E_ADS_BAD_PATHNAME);
}
// check to see that the printer is a valid one
hr = ValidatePrinterObject(pObjectInfo, Credentials);
BAIL_ON_FAILURE(hr);
dwParentId = WINNT_COMPUTER_ID;
if(pObjectInfo->NumComponents == 3) {
hr = BuildParent(pObjectInfo, szADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szPrinterName= pObjectInfo->ComponentArray[2];
} else if (pObjectInfo->NumComponents == 2){
hr = ConstructFullObjectInfo(pObjectInfo,
&pPrinterObjectInfo,
Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pPrinterObjectInfo, szADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pPrinterObjectInfo->ComponentArray[0];
szServerName = pPrinterObjectInfo->ComponentArray[1];
szPrinterName= pPrinterObjectInfo->ComponentArray[2];
}
hr = CWinNTPrintQueue::CreatePrintQueue(
szADsParent,
dwParentId,
szDomainName,
szServerName,
szPrinterName,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
FreeObjectInfo(pPrinterObjectInfo);
RRETURN(hr);
error:
if (pUnknown) {
pUnknown->Release();
}
*ppObject = NULL;
FreeObjectInfo(pPrinterObjectInfo);
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetServiceObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 01/03/96 Ramv Created.
//
//----------------------------------------------------------------------------
HRESULT
GetServiceObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR szADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szDomainName = NULL;
LPWSTR szServerName = NULL;
LPWSTR szServiceName = NULL;
DWORD dwParentId = 0;
POBJECTINFO pServiceObjectInfo = NULL;
//
// check to see that the printer is in a valid server(computer) object
//
if(!(pObjectInfo->NumComponents == 3 ||
pObjectInfo->NumComponents == 2))
{
RRETURN(E_ADS_BAD_PATHNAME);
}
hr = ValidateServiceObject(pObjectInfo, Credentials);
BAIL_ON_FAILURE(hr);
dwParentId = WINNT_COMPUTER_ID;
if(pObjectInfo->NumComponents == 3) {
hr = BuildParent(pObjectInfo, szADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szServiceName= pObjectInfo->ComponentArray[2];
hr = CWinNTService::Create(szADsParent,
szDomainName,
szServerName,
szServiceName,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown);
BAIL_ON_FAILURE(hr);
} else if (pObjectInfo->NumComponents == 2) {
hr = ConstructFullObjectInfo(pObjectInfo,
&pServiceObjectInfo,
Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pServiceObjectInfo, szADsParent);
BAIL_ON_FAILURE(hr);
szServerName = pServiceObjectInfo->ComponentArray[1];
szServiceName= pServiceObjectInfo->ComponentArray[2];
hr = CWinNTService::Create(szADsParent,
pServiceObjectInfo->ComponentArray[0],
szServerName,
szServiceName,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown);
BAIL_ON_FAILURE(hr);
}
*ppObject = pUnknown;
if(pServiceObjectInfo){
FreeObjectInfo(pServiceObjectInfo);
}
RRETURN(hr);
error:
if(pServiceObjectInfo){
FreeObjectInfo(pServiceObjectInfo);
}
if (pUnknown) {
pUnknown->Release();
}
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetFileServiceObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 01/15/96 Ramv Created.
//
//----------------------------------------------------------------------------
HRESULT
GetFileServiceObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR szADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szDomainName = NULL;
LPWSTR szServerName = NULL;
LPWSTR szFileServiceName = NULL;
DWORD dwParentId = 0;
POBJECTINFO pFileServiceObjectInfo = NULL;
//
// check to see that the service is in a valid server(computer) object
//
if (!(pObjectInfo->NumComponents == 3 || pObjectInfo->NumComponents == 2))
RRETURN(E_ADS_BAD_PATHNAME);
hr = ValidateFileServiceObject(pObjectInfo, Credentials);
BAIL_ON_FAILURE(hr);
if (pObjectInfo->NumComponents == 3){
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szFileServiceName= pObjectInfo->ComponentArray[2];
hr = BuildParent(pObjectInfo, szADsParent);
BAIL_ON_FAILURE(hr);
}
if (pObjectInfo->NumComponents == 2){
hr = ConstructFullObjectInfo(pObjectInfo,
&pFileServiceObjectInfo,
Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pFileServiceObjectInfo, szADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pFileServiceObjectInfo->ComponentArray[0];
szServerName = pFileServiceObjectInfo->ComponentArray[1];
szFileServiceName= pFileServiceObjectInfo->ComponentArray[2];
}
dwParentId = WINNT_COMPUTER_ID;
if(_tcsicmp(szFileServiceName,TEXT("LanmanServer")) == 0) {
hr = CWinNTFileService::CreateFileService(szADsParent,
dwParentId,
szDomainName,
szServerName,
szFileServiceName,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown);
BAIL_ON_FAILURE(hr);
}
else if(_tcsicmp(szFileServiceName,TEXT("FPNW")) == 0) {
hr = CFPNWFileService::CreateFileService(szADsParent,
dwParentId,
szDomainName,
szServerName,
szFileServiceName,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown);
BAIL_ON_FAILURE(hr);
}
*ppObject = pUnknown;
if(pFileServiceObjectInfo){
FreeObjectInfo(pFileServiceObjectInfo);
}
RRETURN(hr);
error:
if(pFileServiceObjectInfo){
FreeObjectInfo(pFileServiceObjectInfo);
}
if (pUnknown) {
pUnknown->Release();
}
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetFileShareObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 01/15/96 Ramv Created.
//
//----------------------------------------------------------------------------
HRESULT
GetFileShareObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR szADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPTSTR szDomainName = NULL;
LPTSTR szServerName = NULL;
LPTSTR szFileServiceName = NULL;
LPTSTR szFileShareName = NULL;
DWORD dwParentId = 0;
POBJECTINFO pFileShareObjectInfo = NULL;
WCHAR lpszUncName[MAX_PATH];
BOOL fRefAdded = FALSE;
//
// check to see that the share is in a valid fileservice
//
if (!(pObjectInfo->NumComponents == 4 ||
pObjectInfo->NumComponents == 3)) {
RRETURN(E_ADS_BAD_PATHNAME);
}
// The server is ref'ed in this routine.
hr = ValidateFileShareObject(pObjectInfo, Credentials);
BAIL_ON_FAILURE(hr);
dwParentId = WINNT_SERVICE_ID;
if(pObjectInfo->NumComponents == 4){
hr = BuildParent(pObjectInfo, szADsParent);
BAIL_ON_FAILURE(hr);
szServerName = pObjectInfo->ComponentArray[1];
szFileServiceName= pObjectInfo->ComponentArray[2];
szFileShareName = pObjectInfo ->ComponentArray[3];
} else if (pObjectInfo->NumComponents == 3){
hr = ConstructFullObjectInfo(pObjectInfo,
&pFileShareObjectInfo,
Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pFileShareObjectInfo, szADsParent);
BAIL_ON_FAILURE(hr);
szServerName = pObjectInfo->ComponentArray[0];
szFileServiceName= pObjectInfo->ComponentArray[1];
szFileShareName = pObjectInfo ->ComponentArray[2];
}
if(_tcsicmp(szFileServiceName,TEXT("LanmanServer")) == 0){
hr = CWinNTFileShare::Create(szADsParent,
szServerName,
szFileServiceName,
szFileShareName,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown);
BAIL_ON_FAILURE(hr);
}
else {
//
// we have validated it already, it *has* to be an FPNW server
//
hr = CFPNWFileShare::Create(szADsParent,
szServerName,
szFileServiceName,
szFileShareName,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown);
BAIL_ON_FAILURE(hr);
}
*ppObject = pUnknown;
if(pFileShareObjectInfo){
FreeObjectInfo(pFileShareObjectInfo);
}
RRETURN(hr);
error:
if (pUnknown) {
pUnknown->Release();
}
if(pFileShareObjectInfo){
FreeObjectInfo(pFileShareObjectInfo);
}
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetGroupObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT
GetGroupObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szServerName = NULL;
LPWSTR szDomainName = NULL;
LPWSTR szGroupName = NULL;
DWORD dwParentId = 0;
ULONG uGroupType = 0;
POBJECTINFO pGroupObjectInfo = NULL;
hr = ValidateGroupObject(
pObjectInfo,
&uGroupType,
&dwParentId,
Credentials
);
BAIL_ON_FAILURE(hr);
switch (pObjectInfo->NumComponents) {
case 2:
//
// could be group in computer or group in domain
//
if(dwParentId == WINNT_DOMAIN_ID){
szDomainName = pObjectInfo->ComponentArray[0];
szGroupName = pObjectInfo->ComponentArray[1];
szServerName = NULL;
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
} else {
//
// group in a computer
//
hr = ConstructFullObjectInfo(pObjectInfo,
&pGroupObjectInfo,
Credentials );
if (SUCCEEDED(hr)) {
hr = BuildParent(pGroupObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pGroupObjectInfo->ComponentArray[0];
szServerName = pGroupObjectInfo->ComponentArray[1];
szGroupName = pGroupObjectInfo->ComponentArray[2];
}
else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
//
// We will build the info without the parent
//
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = NULL;
szServerName = pObjectInfo->ComponentArray[0];
szGroupName = pObjectInfo->ComponentArray[1];
}
BAIL_ON_FAILURE(hr);
}
break;
case 3:
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szGroupName = pObjectInfo->ComponentArray[2];
break;
}
hr = CWinNTGroup::CreateGroup(
ADsParent,
dwParentId,
szDomainName,
szServerName,
szGroupName,
uGroupType,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
if(pGroupObjectInfo){
FreeObjectInfo(pGroupObjectInfo);
}
RRETURN(hr);
error:
if (pUnknown) {
pUnknown->Release();
}
if(pGroupObjectInfo){
FreeObjectInfo(pGroupObjectInfo);
}
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetGroupObjectInComputer
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 ramv Created.
//
//----------------------------------------------------------------------------
HRESULT
GetGroupObjectInComputer(
LPWSTR pszHostServerName, // pdc name
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szServerName = NULL;
LPWSTR szDomainName = NULL;
LPWSTR szGroupName = NULL;
DWORD dwParentId = WINNT_COMPUTER_ID;
ULONG uGroupType = 0;
POBJECTINFO pGroupObjectInfo = NULL;
WCHAR lpszUncName[MAX_PATH];
switch (pObjectInfo->NumComponents) {
case 2:
//
// group in a computer
//
MakeUncName(pObjectInfo->ComponentArray[0],
lpszUncName);
hr = ValidateGlobalGroupObject(
lpszUncName,
&(pObjectInfo->ComponentArray[1]),
Credentials
);
if (SUCCEEDED(hr)) {
uGroupType = WINNT_GROUP_GLOBAL;
}else{
hr = ValidateLocalGroupObject(
lpszUncName,
&(pObjectInfo->ComponentArray[1]),
Credentials
);
BAIL_ON_FAILURE(hr);
uGroupType = WINNT_GROUP_LOCAL;
}
hr = ConstructFullObjectInfo(pObjectInfo,
&pGroupObjectInfo,
Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pGroupObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pGroupObjectInfo->ComponentArray[0];
szServerName = pGroupObjectInfo->ComponentArray[1];
szGroupName = pGroupObjectInfo->ComponentArray[2];
break;
case 3:
hr = ValidateComputerParent(pObjectInfo->ComponentArray[0],
pObjectInfo->ComponentArray[1],
Credentials);
BAIL_ON_FAILURE(hr);
MakeUncName(
pObjectInfo->ComponentArray[1],
lpszUncName
);
hr = ValidateGlobalGroupObject(
lpszUncName,
&(pObjectInfo->ComponentArray[2]),
Credentials
);
if (SUCCEEDED(hr)) {
uGroupType = WINNT_GROUP_GLOBAL;
} else {
hr = ValidateLocalGroupObject(
lpszUncName,
&(pObjectInfo->ComponentArray[2]),
Credentials
);
BAIL_ON_FAILURE(hr);
uGroupType = WINNT_GROUP_LOCAL;
}
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szGroupName = pObjectInfo->ComponentArray[2];
break;
}
if (uGroupType == WINNT_GROUP_LOCAL) {
hr = CWinNTGroup::CreateGroup(ADsParent,
dwParentId,
szDomainName,
szServerName,
szGroupName,
uGroupType,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
}else {
hr = CWinNTGroup::CreateGroup(ADsParent,
dwParentId,
szDomainName,
szServerName,
szGroupName,
uGroupType,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
}
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
if(pGroupObjectInfo){
FreeObjectInfo(pGroupObjectInfo);
}
RRETURN(hr);
error:
if (pUnknown) {
pUnknown->Release();
}
if(pGroupObjectInfo){
FreeObjectInfo(pGroupObjectInfo);
}
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetGroupObjectInDomain
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 8-8-96 Ramv Created.
//
//----------------------------------------------------------------------------
HRESULT
GetGroupObjectInDomain(
LPWSTR pszHostServerName,
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szServerName = NULL;
LPWSTR szDomainName = NULL;
LPWSTR szGroupName = NULL;
DWORD dwParentId = WINNT_DOMAIN_ID;
ULONG uGroupType = 0;
BOOL fRefAdded = FALSE;
// At this point the host server name has a \\ prepended
// so we need to get rid of it.
hr = Credentials.RefServer(pszHostServerName+2);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
hr = ValidateGlobalGroupObject(
pszHostServerName,
&(pObjectInfo->ComponentArray[1]),
Credentials
);
if (FAILED(hr)) {
hr = ValidateLocalGroupObject(
pszHostServerName,
&(pObjectInfo->ComponentArray[1]),
Credentials
);
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) {
Credentials.DeRefServer();
fRefAdded = FALSE;
}
BAIL_ON_FAILURE(hr);
uGroupType = WINNT_GROUP_LOCAL;
}else {
uGroupType = WINNT_GROUP_GLOBAL;
}
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) {
Credentials.DeRefServer();
fRefAdded = FALSE;
}
szDomainName = pObjectInfo->ComponentArray[0];
szGroupName = pObjectInfo->ComponentArray[1];
szServerName = NULL;
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
if (uGroupType==WINNT_GROUP_LOCAL) {
hr = CWinNTGroup::CreateGroup(
ADsParent,
dwParentId,
szDomainName,
szServerName,
szGroupName,
uGroupType,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
} else {
hr = CWinNTGroup::CreateGroup(ADsParent,
dwParentId,
szDomainName,
szServerName,
szGroupName,
uGroupType,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
}
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error:
if (pUnknown) {
pUnknown->Release();
}
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetSchemaObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 1-17-96 yihsins Created.
//
//----------------------------------------------------------------------------
HRESULT
GetSchemaObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
if (pObjectInfo->NumComponents != 2)
RRETURN(E_ADS_BAD_PATHNAME);
if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
{
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
hr = CWinNTSchema::CreateSchema( ADsParent,
pObjectInfo->ComponentArray[1],
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown );
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error:
if (pUnknown)
pUnknown->Release();
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetClassObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 1-17-96 yihsins Created.
//
//----------------------------------------------------------------------------
HRESULT
GetClassObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
DWORD i;
if (pObjectInfo->NumComponents != 3)
RRETURN(E_ADS_BAD_PATHNAME);
if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
{
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
//
// Look for the given class name
//
for ( i = 0; i < g_cWinNTClasses; i++ )
{
if ( _wcsicmp( g_aWinNTClasses[i].bstrName,
pObjectInfo->ComponentArray[2] ) == 0 )
break;
}
if ( i == g_cWinNTClasses )
{
// Class name not found, return error
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
//
// Class name found, create and return the object
//
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
hr = CWinNTClass::CreateClass( ADsParent,
&g_aWinNTClasses[i],
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown );
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error:
if (pUnknown)
pUnknown->Release();
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetSyntaxObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 1-17-96 yihsins Created.
//
//----------------------------------------------------------------------------
HRESULT
GetSyntaxObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
DWORD i;
if (pObjectInfo->NumComponents != 3)
RRETURN(E_ADS_BAD_PATHNAME);
if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
{
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
//
// Look for the given syntax name
//
for ( i = 0; i < g_cWinNTSyntax; i++ )
{
if ( _wcsicmp( g_aWinNTSyntax[i].bstrName,
pObjectInfo->ComponentArray[2] ) == 0 )
break;
}
if ( i == g_cWinNTSyntax )
{
// Syntax name not found, return error
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
//
// Syntax name found, create and return the object
//
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
hr = CWinNTSyntax::CreateSyntax( ADsParent,
&(g_aWinNTSyntax[i]),
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown );
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error:
if (pUnknown)
pUnknown->Release();
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetPropertyObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 1-17-96 yihsins Created.
//
//----------------------------------------------------------------------------
HRESULT
GetPropertyObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
WCHAR ADsGrandParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
DWORD nClass, nProp;
if (pObjectInfo->NumComponents != 3)
RRETURN(E_ADS_BAD_PATHNAME);
if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) != 0 )
{
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
//
// We found the specified functional set, now see if we can locate
// the given property name
//
for ( nProp = 0; nProp < g_cWinNTProperties; nProp++ )
{
if ( _wcsicmp(g_aWinNTProperties[nProp].szPropertyName,
pObjectInfo->ComponentArray[2] ) == 0 )
break;
}
if ( nProp == g_cWinNTProperties )
{
// Return error because the given property name is not found
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
//
// Property name is found, so create and return the object
//
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
hr = CWinNTProperty::CreateProperty(
ADsParent,
&(g_aWinNTProperties[nProp]),
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown );
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
RRETURN(hr);
error:
if (pUnknown)
pUnknown->Release();
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function:
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT
HeuristicGetObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
HRESULT hr = S_OK;
WCHAR szHostServerName[MAX_PATH];
DWORD dwElementType;
WCHAR szName[MAX_PATH];
WCHAR szSAMName[MAX_ADS_PATH];
WCHAR lpszUncName[MAX_PATH];
szSAMName[0] = L'\0';
//
// Case 0: Zero components - must be a namespace object
//
if (pObjectInfo->NumComponents == 0) {
RRETURN(GetNamespaceObject(pObjectInfo, ppObject, Credentials));
}
//
// Case 1: Single component - must be a domain object or
// computer object
//
if (pObjectInfo->NumComponents == 1) {
//
// hr = WinNTGetCachedObject(type, hit/miss, pdcname/domain name)
//
// if (succeeded...
// switch(type) .... call the appropriate
// GetDomain or GetWorkGroup or GetComputer
//
hr = WinNTGetCachedName(
pObjectInfo->ComponentArray[0],
&dwElementType,
szHostServerName,
szSAMName,
Credentials
);
BAIL_IF_ERROR(hr);
// update the name to the one on SAM
if (szSAMName[0] != L'\0') {
FreeADsStr(pObjectInfo->ComponentArray[0]);
pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName);
}
if (!pObjectInfo->ComponentArray[0]) {
BAIL_IF_ERROR(hr = E_OUTOFMEMORY);
}
switch(dwElementType) {
case DOMAIN_ENTRY_TYPE:
hr = GetDomainObject(pObjectInfo, ppObject, Credentials);
break;
case COMPUTER_ENTRY_TYPE:
hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
break;
default:
hr = GetWorkGroupObject(pObjectInfo, ppObject, Credentials);
break;
}
goto cleanup;
}
//
// Case 2: Two components - could be user, group, computer,
// or any one of the computer's sub-objects.
//
if (pObjectInfo->NumComponents == 2) {
hr = GetSchemaObject(pObjectInfo, ppObject, Credentials);
if(SUCCEEDED(hr)){
goto cleanup;
}
if(FAILED(hr)) {
//
// try doing a WinNTGetCachedDCName first
// and if it goes through, then we have objects such as
// user,group,computer in domain, otherwise it is the
// computer case or workgroup case
//
// WinNtGetCachedObject will directly tell us to proceed or
// not
hr = WinNTGetCachedName(pObjectInfo->ComponentArray[0],
&dwElementType,
szHostServerName,
szSAMName,
Credentials );
BAIL_IF_ERROR(hr);
// Again we do not have to worry about the case of the
// object name, it is handled by the GetObject calls
switch(dwElementType) {
case DOMAIN_ENTRY_TYPE:
hr = GetUserObjectInDomain(szHostServerName,
pObjectInfo,
ppObject,
Credentials);
if (FAILED(hr)) {
hr = GetGroupObjectInDomain(szHostServerName,
pObjectInfo,
ppObject,
Credentials);
}
if (FAILED(hr)) {
hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
}
goto cleanup;
case COMPUTER_ENTRY_TYPE:
hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
if (FAILED(hr)) {
hr = GetFileServiceObject(
pObjectInfo,
ppObject,
Credentials
);
}
if (FAILED(hr)) {
hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
}
if(FAILED(hr)){
hr = GetUserObjectInComputer(
pObjectInfo->ComponentArray[0],
pObjectInfo,
ppObject,
Credentials
);
}
if (FAILED(hr)) {
hr = GetGroupObjectInComputer(
pObjectInfo->ComponentArray[0],
pObjectInfo,
ppObject,
Credentials
);
}
goto cleanup;
case WORKGROUP_ENTRY_TYPE:
hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
if (FAILED(hr)) {
if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) {
// In this case I want to mask the error
// as it means it could not find the object
hr = E_ADS_UNKNOWN_OBJECT;
}
}
goto cleanup;
default:
hr = E_ADS_UNKNOWN_OBJECT;
goto cleanup;
}
}
} /* NumComponents == 2 */
//
// Case 3: Three components - could be user, group, printer, fileservice
// or service or fileshare for computer in a workgroup environment.
//
if (pObjectInfo->NumComponents == 3) {
if ( _wcsicmp( pObjectInfo->ComponentArray[1], SCHEMA_NAME ) == 0 ){
hr = GetClassObject(pObjectInfo, ppObject, Credentials);
if (FAILED(hr)) {
hr = GetPropertyObject(pObjectInfo, ppObject, Credentials);
}
if (FAILED(hr)) {
hr = GetSyntaxObject(pObjectInfo, ppObject, Credentials);
}
}
else{
hr = GetUserObjectInComputer(pObjectInfo->ComponentArray[1],
pObjectInfo,
ppObject,
Credentials);
if (FAILED(hr)) {
hr = GetGroupObjectInComputer(pObjectInfo->ComponentArray[1],
pObjectInfo,
ppObject,
Credentials);
}
if(FAILED(hr)){
hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
}
if (FAILED(hr)) {
hr = GetFileServiceObject(pObjectInfo, ppObject, Credentials);
}
if (FAILED(hr)) {
hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
}
if (FAILED(hr)) {
hr = GetFileShareObject(pObjectInfo, ppObject, Credentials);
}
}
if(FAILED(hr) ){
RRETURN(hr);
}
else{
RRETURN(S_OK);
}
}
if (pObjectInfo->NumComponents == 4) {
hr = GetFileShareObject(pObjectInfo, ppObject, Credentials);
if(FAILED(hr)){
RRETURN(hr);
}
else{
RRETURN(S_OK);
}
}
RRETURN (E_ADS_UNKNOWN_OBJECT);
cleanup:
if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
//
// There is a very good chance that this is a case
// where they are trying to work on the local machine
// when there are no workstation services. Note that this
// means that a fully qualified name was not given.
//
hr = HeuristicGetObjectNoWksta(
pObjectInfo,
ppObject,
Credentials
);
}
//
// Propagate the error code which we have rather than
// mask it and return information of little value
//
if (FAILED(hr)) {
// the error code NERR_BadTransactConfig means that the
// object did not exist, we want to mask just that ecode
if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) {
hr = E_ADS_UNKNOWN_OBJECT;
}
RRETURN(hr);
} else {
RRETURN(S_OK);
}
}
//+---------------------------------------------------------------------------
// Function: HeuristicGetObjectNoWksta
//
// Synopsis: Tries to locate the object on local machine when there are no
// workstation services. This will happen in a minimum install of NT.
//
// Arguments: POBJECTINFO -> data about object being located.
// LPVOID -> Object to be returned in this arg.
// Credentials -> Credentials blob.
//
// Returns: Either S_OK or HR_From_Win32(NERR_WkstaNotStarted)
//
// Modifies:
//
// History: 08-03-98 AjayR Created.
//
//----------------------------------------------------------------------------
HRESULT
HeuristicGetObjectNoWksta(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
HRESULT hr = S_OK;
HRESULT hrNoWksta = HRESULT_FROM_WIN32(NERR_WkstaNotStarted);
WCHAR szHostServerName[MAX_PATH];
DWORD dwElementType;
WCHAR szName[MAX_PATH];
WCHAR szSAMName[MAX_ADS_PATH];
WCHAR lpszUncName[MAX_PATH];
szSAMName[0] = L'\0';
//
// Case 0: Zero components - Should no be hit here.
//
if (pObjectInfo->NumComponents == 0) {
RRETURN(hrNoWksta);
}
//
// Case 1: Single component - Can only be a computer object
//
if (pObjectInfo->NumComponents == 1) {
hr = GetComputerObject(pObjectInfo, ppObject, Credentials);
goto cleanup;
}
//
// Case 2: Two components - could be user or group for now.
// Other possible objects - TBD.
//
if (pObjectInfo->NumComponents == 2) {
hr = GetPrinterObject(pObjectInfo, ppObject, Credentials);
if (FAILED(hr)) {
hr = GetFileServiceObject(
pObjectInfo,
ppObject,
Credentials
);
}
if (FAILED(hr)) {
hr = GetServiceObject(pObjectInfo, ppObject, Credentials);
}
if(FAILED(hr)){
hr = GetUserObject(
pObjectInfo,
ppObject,
Credentials
);
}
if (FAILED(hr)) {
hr = GetLocalGroupObject(
pObjectInfo,
ppObject,
Credentials
);
}
goto cleanup;
} /* NumComponents == 2 */
//
// Case 3 or more : Three or more components - not possible
//
if (pObjectInfo->NumComponents > 2) {
RRETURN(hrNoWksta);
}
RRETURN (E_ADS_UNKNOWN_OBJECT);
cleanup:
//
// Propagate the error code which we have rather than
// mask it and return information of little value
//
if (FAILED(hr)) {
// the error code NERR_BadTransactConfig means that the
// object did not exist, we want to mask just that ecode
if (hr == HRESULT_FROM_WIN32(NERR_BadTransactConfig)) {
hr = E_ADS_UNKNOWN_OBJECT;
}
RRETURN(hr);
} else {
RRETURN(S_OK);
}
}
HRESULT
BuildParent(
POBJECTINFO pObjectInfo,
LPWSTR szBuffer
)
{
DWORD i = 0;
DWORD dwLen = 0;
if (!pObjectInfo->ProviderName) {
RRETURN(E_ADS_BAD_PATHNAME);
}
wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
if (pObjectInfo->NumComponents - 1) {
dwLen = wcslen(pObjectInfo->ProviderName) + 3 +
wcslen(pObjectInfo->DisplayComponentArray[0]);
if(dwLen >= MAX_ADS_PATH) {
RRETURN(E_ADS_BAD_PATHNAME);
}
wcscat(szBuffer, L"//");
wcscat(szBuffer, pObjectInfo->DisplayComponentArray[0]);
for (i = 1; i < (pObjectInfo->NumComponents - 1); i++) {
dwLen += (1 + wcslen(pObjectInfo->DisplayComponentArray[i]));
if(dwLen >= MAX_ADS_PATH) {
RRETURN(E_ADS_BAD_PATHNAME);
}
wcscat(szBuffer, L"/");
wcscat(szBuffer, pObjectInfo->DisplayComponentArray[i]);
}
}
RRETURN(S_OK);
}
HRESULT
BuildGrandParent(
POBJECTINFO pObjectInfo,
LPWSTR szBuffer
)
{
DWORD i = 0;
if (!pObjectInfo->ProviderName) {
RRETURN(E_ADS_BAD_PATHNAME);
}
wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
if (pObjectInfo->NumComponents - 2) {
wcscat(szBuffer, L"//");
wcscat(szBuffer, pObjectInfo->ComponentArray[0]);
for (i = 1; i < (pObjectInfo->NumComponents - 2); i++) {
wcscat(szBuffer, L"/");
wcscat(szBuffer, pObjectInfo->ComponentArray[i]);
}
}
RRETURN(S_OK);
}
HRESULT
BuildADsPath(
POBJECTINFO pObjectInfo,
LPWSTR szBuffer
)
{
DWORD i = 0;
if (!pObjectInfo->ProviderName) {
RRETURN(E_ADS_BAD_PATHNAME);
}
wsprintf(szBuffer, L"%s:", pObjectInfo->ProviderName);
if (pObjectInfo->NumComponents) {
wcscat(szBuffer, L"//");
wcscat(szBuffer, pObjectInfo->DisplayComponentArray[0]);
for (i = 1; i < (pObjectInfo->NumComponents); i++) {
wcscat(szBuffer, L"/");
wcscat(szBuffer, pObjectInfo->DisplayComponentArray[i]);
}
}
RRETURN(S_OK);
}
HRESULT
ValidateUserObject(
POBJECTINFO pObjectInfo,
PDWORD pdwParentId,
CWinNTCredentials& Credentials
)
{
WCHAR szHostServerName[MAX_PATH];
LPUSER_INFO_20 lpUI = NULL;
HRESULT hr;
WCHAR lpszUncName[MAX_PATH];
NET_API_STATUS nasStatus;
WCHAR szSAMName[MAX_PATH];
BOOL fRefAdded = FALSE;
LPUSER_INFO_0 lpUI_0 = NULL;
DWORD dwLevelUsed = 20;
WCHAR szCompName[MAX_PATH];
DWORD dwSize = MAX_PATH;
szSAMName[0] = L'\0';
switch (pObjectInfo->NumComponents) {
case 2:
//
// if 2 components then either it is user in computer
// or user in domain.
hr = WinNTGetCachedDCName(
pObjectInfo->ComponentArray[0],
szHostServerName,
Credentials.GetFlags()
);
if(SUCCEEDED(hr)){
// Need to ref the server, note that RefServer
// checks if the credentials are non null
// We are not concerned about any error as we may
// still succeed with default credentials.
// The +2 is to skip the \\ at the head.
hr = Credentials.RefServer(szHostServerName+2);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
nasStatus = NetUserGetInfo(szHostServerName,
pObjectInfo->ComponentArray[1],
20,
(LPBYTE *)&lpUI);
//
// This code is here because Level 20 reads the flags
// and if you accessed WinNT://ntdev/foo with Redmond\foo
// credentials, it will fail. This allow a bind but the
// GetInfo will fail.
//
if (nasStatus == ERROR_ACCESS_DENIED) {
// try and drop down to level 0 as that may work
dwLevelUsed = 0;
nasStatus = NetUserGetInfo(
szHostServerName,
pObjectInfo->ComponentArray[1],
0,
(LPBYTE *)&lpUI_0
);
}
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) {
Credentials.DeRefServer();
fRefAdded = FALSE;
}
hr = HRESULT_FROM_WIN32(nasStatus);
BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (dwLevelUsed == 20 ) {
if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) {
FreeADsStr(pObjectInfo->ComponentArray[1]);
pObjectInfo->ComponentArray[1]
= AllocADsStr(lpUI->usri20_name);
}
if (!pObjectInfo->ComponentArray[1])
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
}
*pdwParentId = WINNT_DOMAIN_ID;
}
//
// if we are here with hr != S_OK it could be that we have
// user in a computer.
//
if(FAILED(hr)){
hr = ValidateComputerParent(
NULL,
pObjectInfo->ComponentArray[0],
Credentials
);
if (SUCCEEDED(hr)) {
// Need to ref the server on which the object lives
// Note that RefServer checks if Credentials are null.
// Again, we are not concerned about any errors as we
// will drop down to default credentials automatically.
hr = Credentials.RefServer(pObjectInfo->ComponentArray[0]);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
MakeUncName(pObjectInfo->ComponentArray[0],
lpszUncName);
nasStatus = NetUserGetInfo(lpszUncName,
pObjectInfo->ComponentArray[1],
20,
(LPBYTE *)&lpUI);
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) {
Credentials.DeRefServer();
fRefAdded = FALSE;
}
hr = HRESULT_FROM_WIN32(nasStatus);
BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[1] && lpUI->usri20_name) {
FreeADsStr(pObjectInfo->ComponentArray[1]);
pObjectInfo->ComponentArray[1]
= AllocADsStr(lpUI->usri20_name);
}
if (!pObjectInfo->ComponentArray[1])
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
*pdwParentId = WINNT_COMPUTER_ID;
}
else if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
//
// Need to see if the problem was not workstation
// services in which case we need to still try and
// locate user if the comptuer name matches.
//
if (!GetComputerName(szCompName, &dwSize)) {
//
// We could not get the computer name so bail
//
BAIL_ON_FAILURE(hr);
}
//
// Test the name before continuing.
//
#ifdef WIN95
if (_wcsicmp(szCompName, pObjectInfo->ComponentArray[0])) {
#else
if (CompareStringW(
LOCALE_SYSTEM_DEFAULT,
NORM_IGNORECASE,
szCompName,
-1,
pObjectInfo->ComponentArray[0],
-1
) != CSTR_EQUAL ) {
#endif
// names do not match
BAIL_ON_FAILURE(hr);
}
//
// Valid computer name, so we can try and check for user
//
MakeUncName(pObjectInfo->ComponentArray[0], lpszUncName);
nasStatus = NetUserGetInfo(
lpszUncName,
pObjectInfo->ComponentArray[1],
20,
(LPBYTE *)&lpUI
);
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(nasStatus));
*pdwParentId = WINNT_COMPUTER_ID;
}
}
BAIL_ON_FAILURE(hr);
break;
case 3:
//
// user in domain\computer or user in workgroup\computer
//
hr = ValidateComputerParent(
pObjectInfo->ComponentArray[0],
pObjectInfo->ComponentArray[1],
Credentials
);
BAIL_ON_FAILURE(hr);
// Again we need to ref the server
hr = Credentials.RefServer(pObjectInfo->ComponentArray[1]);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
MakeUncName(pObjectInfo->ComponentArray[1],
lpszUncName);
nasStatus = NetUserGetInfo(lpszUncName,
pObjectInfo->ComponentArray[2],
20,
(LPBYTE *)&lpUI);
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) {
Credentials.DeRefServer();
fRefAdded = FALSE;
}
hr = HRESULT_FROM_WIN32(nasStatus);
BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[2] && lpUI->usri20_name) {
FreeADsStr(pObjectInfo->ComponentArray[2]);
pObjectInfo->ComponentArray[2]
= AllocADsStr(lpUI->usri20_name);
}
if (!pObjectInfo->ComponentArray[2])
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
*pdwParentId = WINNT_COMPUTER_ID;
break;
default:
RRETURN(E_ADS_BAD_PATHNAME);
}
error:
if (lpUI) {
NetApiBufferFree((LPBYTE)lpUI);
}
if (lpUI_0) {
NetApiBufferFree((LPBYTE)lpUI_0);
}
RRETURN(hr);
}
HRESULT
ValidateComputerParent(
LPWSTR pszDomainName,
LPWSTR pszComputerName,
CWinNTCredentials& Credentials
)
{
HRESULT hr;
NET_API_STATUS nasStatus;
WCHAR szName[MAX_PATH];
WCHAR szSAMName[MAX_PATH];
WCHAR szCompName[MAX_PATH];
DWORD dwSize = MAX_PATH;
if(pszDomainName && (wcslen(pszDomainName) >= MAX_PATH))
{
hr = E_FAIL;
goto error;
}
szSAMName[0] = szName[0] = L'\0';
if(pszDomainName)
{
wcscpy(szName, pszDomainName);
}
hr = WinNTGetCachedComputerName(
pszComputerName,
szName,
szSAMName,
Credentials
);
if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
//
// We want to see if the computer being validated is
// the current host.
//
if (!GetComputerName(szCompName, &dwSize)
#ifdef WIN95
|| (_wcsicmp(szCompName, pszComputerName))
#else
|| (CompareStringW(
LOCALE_SYSTEM_DEFAULT,
NORM_IGNORECASE,
szCompName,
-1,
pszComputerName,
-1
) != CSTR_EQUAL )
#endif
)
BAIL_ON_FAILURE(hr);
hr = S_OK;
}
BAIL_ON_FAILURE(hr);
if(pszDomainName == NULL){
//
// we are dealing with a case where we aren't supplied the
// computer's parent. Just validate the computer
//
hr = S_OK;
goto error;
} else {
#ifdef WIN95
//
// No NetpNameCompare for Win9x
//
if (!_wcsicmp(pszDomainName, szName)) {
#else
if ((CompareStringW(
LOCALE_SYSTEM_DEFAULT,
NORM_IGNORECASE,
pszDomainName,
-1,
szName,
-1
) == CSTR_EQUAL )
|| (NetpNameCompare(
NULL,
pszDomainName,
szName,
NAMETYPE_DOMAIN,
0
) == 0 )
) {
#endif
hr = S_OK;
}else {
hr = E_ADS_BAD_PATHNAME;
}
}
error:
RRETURN(hr);
}
// Overloaded ValidateComputerParent function.
// This is used when the case of pszComputerName on the SAM
// databsae is needed.
HRESULT
ValidateComputerParent(
LPWSTR pszDomainName,
LPWSTR pszComputerName,
LPWSTR pszSAMName,
CWinNTCredentials& Credentials
)
{
HRESULT hr;
NET_API_STATUS nasStatus;
WCHAR szName[MAX_PATH];
WCHAR szSAMName[MAX_PATH];
if(pszDomainName && wcslen(pszDomainName) >= MAX_PATH)
{
hr = E_FAIL;
goto error;
}
szSAMName[0] = szName[0] = L'\0';
if(pszDomainName)
{
wcscpy(szName, pszDomainName);
}
hr = WinNTGetCachedComputerName(
pszComputerName,
szName,
szSAMName,
Credentials
);
BAIL_ON_FAILURE(hr);
if (szSAMName[0] != L'\0') {
wcscpy(pszSAMName, szSAMName);
}
if(pszDomainName == NULL){
//
// we are dealing with a case where we aren't supplied the
// computer's parent. Just validate the computer
//
hr = S_OK;
goto error;
} else {
#ifdef WIN95
//
// No NetpNameCompare for Win9x
//
if (!_wcsicmp(pszDomainName, szName)) {
#else
if ((CompareStringW(
LOCALE_SYSTEM_DEFAULT,
NORM_IGNORECASE,
pszDomainName,
-1,
szName,
-1
) == CSTR_EQUAL )
|| (NetpNameCompare(
NULL,
pszDomainName,
szName,
NAMETYPE_DOMAIN,
0
) == 0 )
) {
#endif
hr = S_OK;
}else {
hr = E_FAIL;
}
}
error:
RRETURN(hr);
}
HRESULT
ValidateGroupObject(
POBJECTINFO pObjectInfo,
PULONG puGroupType,
PDWORD pdwParentId,
CWinNTCredentials& Credentials
)
{
WCHAR szHostServerName[MAX_PATH];
LPGROUP_INFO_0 lpGI = NULL;
HRESULT hr;
WCHAR lpszUncName[MAX_PATH];
NET_API_STATUS nasStatus;
ULONG uGroupType = 0L;
WCHAR szSAMName[MAX_PATH];
szSAMName[0] = L'\0';
switch (pObjectInfo->NumComponents) {
case 2:
//
// if 2 components then either it is a group in computer
// or group in domain.
//
hr = WinNTGetCachedDCName(
pObjectInfo->ComponentArray[0],
szHostServerName,
Credentials.GetFlags()
);
if(SUCCEEDED(hr)){
//
// must be a group in a domain
//
*pdwParentId = WINNT_DOMAIN_ID;
hr = ValidateGlobalGroupObject(
szHostServerName,
&(pObjectInfo->ComponentArray[1]),
Credentials
);
if (FAILED(hr)) {
hr = ValidateLocalGroupObject(
szHostServerName,
&(pObjectInfo->ComponentArray[1]),
Credentials
);
if(SUCCEEDED(hr)){
uGroupType = WINNT_GROUP_LOCAL;
}
}else{
uGroupType = WINNT_GROUP_GLOBAL;
}
}
if(FAILED(hr)){
//
// potentially a group in a computer
//
hr = ValidateComputerParent(NULL,
pObjectInfo->ComponentArray[0],
Credentials);
BAIL_ON_FAILURE(hr);
//
// group in a computer
//
*pdwParentId = WINNT_COMPUTER_ID;
MakeUncName(pObjectInfo->ComponentArray[0],
lpszUncName);
hr = ValidateGlobalGroupObject(
lpszUncName,
&(pObjectInfo->ComponentArray[1]),
Credentials
);
if (FAILED(hr)) {
hr = ValidateLocalGroupObject(
lpszUncName,
&(pObjectInfo->ComponentArray[1]),
Credentials
);
BAIL_ON_FAILURE(hr);
uGroupType = WINNT_GROUP_LOCAL;
}else{
uGroupType = WINNT_GROUP_GLOBAL;
}
}
break;
case 3:
//
// if there are 3 components then we must have parentid
// WINNT_COMPUTER_ID
//
*pdwParentId = WINNT_COMPUTER_ID;
hr = ValidateComputerParent(pObjectInfo->ComponentArray[0],
pObjectInfo->ComponentArray[1],
Credentials);
BAIL_ON_FAILURE(hr);
MakeUncName(
pObjectInfo->ComponentArray[1],
lpszUncName
);
hr = ValidateGlobalGroupObject(
lpszUncName,
&(pObjectInfo->ComponentArray[2]),
Credentials
);
if (FAILED(hr)) {
hr = ValidateLocalGroupObject(
lpszUncName,
&(pObjectInfo->ComponentArray[2]),
Credentials
);
BAIL_ON_FAILURE(hr);
uGroupType = WINNT_GROUP_LOCAL;
}else{
uGroupType = WINNT_GROUP_GLOBAL;
}
break;
default:
RRETURN(E_ADS_BAD_PATHNAME);
}
error:
if (lpGI) {
NetApiBufferFree((LPBYTE)lpGI);
}
*puGroupType = uGroupType;
RRETURN(hr);
}
HRESULT
ValidatePrinterObject(
POBJECTINFO pObjectInfo,
CWinNTCredentials& Credentials
)
{
LPTSTR szDomainName = NULL;
LPTSTR szServerName = NULL;
LPTSTR szPrinterName = NULL;
WCHAR szPrintObjectName[MAX_PATH];
HRESULT hr = E_ADS_UNKNOWN_OBJECT;
BOOL fStatus = FALSE;
HANDLE hPrinter = NULL;
PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_USE};
BOOLEAN fRefAdded = FALSE;
if (!(pObjectInfo->NumComponents == 3 ||pObjectInfo->NumComponents == 2)){
RRETURN(E_ADS_BAD_PATHNAME);
}
if(pObjectInfo->NumComponents == 3){
//
// printer in domain\computer or workgroup\computer
//
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szPrinterName = pObjectInfo->ComponentArray[2];
hr = ValidateComputerParent(szDomainName,
szServerName,
Credentials);
BAIL_IF_ERROR(hr);
} else if ( pObjectInfo-> NumComponents == 2 ){
szServerName = pObjectInfo->ComponentArray[0];
szPrinterName = pObjectInfo->ComponentArray[1];
}
MakeUncName(szServerName, szPrintObjectName);
wcscat(szPrintObjectName, TEXT("\\"));
wcscat(szPrintObjectName, szPrinterName);
//
// validate the printer in computer now
//
hr = Credentials.RefServer(szServerName);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
fStatus = OpenPrinter(szPrintObjectName,
&hPrinter,
&PrinterDefaults);
if(!fStatus){
hr = HRESULT_FROM_WIN32(GetLastError());
} else {
hr = S_OK;
}
cleanup:
if(hPrinter){
ClosePrinter(hPrinter);
}
if (fRefAdded) {
Credentials.DeRefServer();
fRefAdded = FALSE;
}
RRETURN(hr);
}
HRESULT
ValidateServiceObject(
POBJECTINFO pObjectInfo,
CWinNTCredentials& Credentials
)
{
LPTSTR szDomainName = NULL;
LPTSTR szServerName = NULL;
LPTSTR szServiceName = NULL;
SC_HANDLE schSCMHandle=NULL;
SC_HANDLE schServiceHandle=NULL;
HRESULT hr = S_OK;
BOOLEAN fRefAdded = FALSE;
if(!(pObjectInfo->NumComponents == 3 ||
pObjectInfo->NumComponents == 2))
{
RRETURN(E_ADS_BAD_PATHNAME);
}
if(pObjectInfo->NumComponents == 3){
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szServiceName = pObjectInfo->ComponentArray[2];
//
// First check to see if the computer is in the right domain
//
hr = ValidateComputerParent(
szDomainName,
szServerName,
Credentials
);
BAIL_ON_FAILURE(hr);
} else if (pObjectInfo->NumComponents == 2){
szServerName = pObjectInfo->ComponentArray[0];
szServiceName = pObjectInfo->ComponentArray[1];
}
//
// check to see if the service is valid by opening the active services
// database on the server
//
hr = Credentials.RefServer(szServerName);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
//
// Open the Service Control Manager.
//
schSCMHandle = OpenSCManager(szServerName,
NULL,
GENERIC_READ);
if (schSCMHandle == NULL) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto error;
}
//
// Need to ref the server before opening the service
//
//
// try to open the service
//
schServiceHandle = OpenService(schSCMHandle,
szServiceName,
GENERIC_READ);
if(schServiceHandle == NULL) {
CloseServiceHandle(schSCMHandle);
schSCMHandle = NULL;
hr = HRESULT_FROM_WIN32(GetLastError());
goto error;
}
CloseServiceHandle(schServiceHandle);
CloseServiceHandle(schSCMHandle);
error:
if (fRefAdded) {
Credentials.DeRefServer();
fRefAdded = FALSE;
}
RRETURN(hr);
}
HRESULT GetPrinterFromPath(LPTSTR *pszPrinter, LPWSTR szPathName)
{
//
// If passed an empty string, it returns an empty string
//
LPTSTR szRetval;
*pszPrinter = NULL;
szRetval = szPathName;
ADsAssert(szPathName);
while(!(*szRetval==L'\0' || *szRetval==L'\\')){
szRetval++;
}
if(*szRetval != L'\\'){
RRETURN(E_FAIL);
}
szRetval++;
*pszPrinter = szRetval;
RRETURN(S_OK);
}
HRESULT
ValidateComputerObject(
POBJECTINFO pObjectInfo,
CWinNTCredentials& Credentials)
{
HRESULT hr;
WCHAR szSAMName[MAX_PATH];
szSAMName[0] = L'\0';
if(!(pObjectInfo->NumComponents == 2 ||
pObjectInfo->NumComponents == 1)){
RRETURN(E_ADS_UNKNOWN_OBJECT);
}
if(pObjectInfo->NumComponents == 2){
hr = ValidateComputerParent(
pObjectInfo->ComponentArray[0],
pObjectInfo->ComponentArray[1],
szSAMName,
Credentials
);
BAIL_ON_FAILURE(hr);
if (szSAMName[0] != L'\0') {
FreeADsStr(pObjectInfo->ComponentArray[1]);
pObjectInfo->ComponentArray[1] = AllocADsStr(szSAMName);
if (!pObjectInfo->ComponentArray[1]) {
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
}
}
} else {
hr = ValidateComputerParent(
NULL,
pObjectInfo->ComponentArray[0],
szSAMName,
Credentials
);
BAIL_ON_FAILURE(hr);
if (szSAMName[0] != L'\0') {
FreeADsStr(pObjectInfo->ComponentArray[0]);
pObjectInfo->ComponentArray[0] = AllocADsStr(szSAMName);
if (!pObjectInfo->ComponentArray[0]) {
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
}
}
}
error:
RRETURN(hr);
}
HRESULT
ValidateFileServiceObject(
POBJECTINFO pObjectInfo,
CWinNTCredentials& Credentials
)
{
HRESULT hr = S_OK;
//
// check to see if it is a valid service
//
if(!(pObjectInfo->NumComponents == 3 ||
pObjectInfo->NumComponents == 2))
{
RRETURN(E_ADS_BAD_PATHNAME);
}
hr = ValidateServiceObject(pObjectInfo, Credentials);
if(FAILED(hr))
RRETURN(hr);
//
// check to see if it is the LanmanServer or FPNW service
//
if (pObjectInfo->NumComponents ==3){
if(!(_wcsicmp(pObjectInfo->ComponentArray[2],
TEXT("LanmanServer"))== 0
|| _wcsicmp(pObjectInfo->ComponentArray[2],TEXT("FPNW"))==0)){
RRETURN(E_ADS_BAD_PATHNAME);
}
}else if(pObjectInfo->NumComponents == 2) {
if(!(_wcsicmp(pObjectInfo->ComponentArray[1],
TEXT("LanmanServer"))== 0
|| _wcsicmp(pObjectInfo->ComponentArray[1],TEXT("FPNW"))==0)){
RRETURN(E_ADS_BAD_PATHNAME);
}
}
RRETURN(hr);
}
HRESULT
ValidateFileShareObject(
POBJECTINFO pObjectInfo,
CWinNTCredentials& Credentials
)
{
NET_API_STATUS nasStatus;
LPSHARE_INFO_1 lpShareInfo1 = NULL;
PNWVOLUMEINFO pVolumeInfo = NULL;
LPTSTR pszDomainName = NULL;
LPTSTR pszServerName = NULL;
LPTSTR pszShareName = NULL;
LPTSTR pszServerType = NULL;
HRESULT hr = S_OK;
DWORD dwSharePos = 3;
BOOL fRefAdded = FALSE;
//
// check to see if it is a valid file share
//
if (pObjectInfo->NumComponents == 4 ){
pszDomainName = pObjectInfo->ComponentArray[0];
pszServerName = pObjectInfo->ComponentArray[1];
pszServerType = pObjectInfo->ComponentArray[2];
pszShareName = pObjectInfo->ComponentArray[3];
dwSharePos = 3;
hr = ValidateComputerParent(pszDomainName,
pszServerName,
Credentials);
BAIL_ON_FAILURE(hr);
}
else if (pObjectInfo->NumComponents == 3 ){
pszServerName = pObjectInfo->ComponentArray[0];
pszServerType = pObjectInfo->ComponentArray[1];
pszShareName = pObjectInfo->ComponentArray[2];
dwSharePos = 2;
}
else {
hr = E_ADS_UNKNOWN_OBJECT;
goto error;
}
if(_tcsicmp(pszServerType,TEXT("LanmanServer")) == 0){
// Need to ref this server before we do the NetShareGetInfo
// so that we can authenticate against the server.
hr = Credentials.RefServer(pszServerName);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
nasStatus = NetShareGetInfo(pszServerName,
pszShareName,
1,
(LPBYTE*)&lpShareInfo1);
// DeRef if ref added, no recovery possible on failed deref
if (fRefAdded) {
hr = Credentials.DeRefServer();
fRefAdded = FALSE;
}
if(nasStatus != NERR_Success){
hr = HRESULT_FROM_WIN32(nasStatus);
goto error;
}
else {
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[dwSharePos]
&& lpShareInfo1->shi1_netname) {
FreeADsStr(pObjectInfo->ComponentArray[dwSharePos]);
pObjectInfo->ComponentArray[dwSharePos]
= AllocADsStr(lpShareInfo1->shi1_netname);
}
if (!pObjectInfo->ComponentArray[dwSharePos])
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
hr = S_OK;
goto error;
}
}
else if(_tcsicmp(pszServerType,TEXT("FPNW")) == 0){
hr = Credentials.RefServer(pszServerName);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
nasStatus = ADsNwVolumeGetInfo(pszServerName,
pszShareName,
1,
&pVolumeInfo);
// need to deref, nothing we can do if deref fails
if (fRefAdded) {
hr = Credentials.DeRefServer();
fRefAdded = FALSE;
}
if(nasStatus != NERR_Success){
hr = HRESULT_FROM_WIN32(nasStatus);
goto error;
}
else{
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if (pObjectInfo->ComponentArray[dwSharePos]
&& pVolumeInfo->lpPath) {
FreeADsStr(pObjectInfo->ComponentArray[dwSharePos]);
pObjectInfo->ComponentArray[dwSharePos]
= AllocADsStr(pVolumeInfo->lpPath);
}
if (!pObjectInfo->ComponentArray[dwSharePos])
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
hr = S_OK;
goto error;
}
} else {
hr = E_ADS_UNKNOWN_OBJECT ;
}
error:
if(pVolumeInfo){
ADsNwApiBufferFree(pVolumeInfo);
}
if(lpShareInfo1){
NetApiBufferFree(lpShareInfo1);
}
RRETURN(hr);
}
HRESULT
ValidateNamespaceObject(
POBJECTINFO pObjectInfo
)
{
if (!_wcsicmp(pObjectInfo->ProviderName, szProviderName)) {
RRETURN(S_OK);
}
RRETURN(E_FAIL);
}
HRESULT
ValidateLocalGroupObject(
LPWSTR szServerName,
LPWSTR *pszGroupName,
CWinNTCredentials& Credentials
)
{
NET_API_STATUS nasStatus;
LPLOCALGROUP_INFO_1 lpGI = NULL;
HRESULT hr = S_OK;
BOOL fRefAdded = FALSE;
// At this point the host server name has a \\ prepended
// so we need to get rid of it.
hr = Credentials.RefServer(szServerName+2);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
nasStatus = NetLocalGroupGetInfo(
szServerName,
*pszGroupName,
1,
(LPBYTE*)(&lpGI)
);
//
// if a ref has been added we need to delete if before
// checking the error status.
//
if (fRefAdded) {
hr = Credentials.DeRefServer();
// even if we fail, we have no recovery path
fRefAdded = FALSE;
}
hr = HRESULT_FROM_WIN32(nasStatus);
BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if ((*pszGroupName) && lpGI->lgrpi1_name) {
FreeADsStr(*pszGroupName);
*pszGroupName = AllocADsStr(lpGI->lgrpi1_name);
}
if (!(*pszGroupName))
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
error:
if (lpGI) {
NetApiBufferFree(lpGI);
}
RRETURN(hr);
}
HRESULT
ValidateGlobalGroupObject(
LPWSTR szServerName,
LPWSTR *pszGroupName,
CWinNTCredentials& Credentials
)
{
NET_API_STATUS nasStatus;
LPGROUP_INFO_1 lpGI = NULL;
HRESULT hr = S_OK;
BOOL fRefAdded = FALSE;
// At this point the host server name has a \\ prepended
// so we need to get rid of it.
hr = Credentials.RefServer(szServerName+2);
if (SUCCEEDED(hr)) {
fRefAdded = TRUE;
}
nasStatus = NetGroupGetInfo(
szServerName,
*pszGroupName,
1,
(LPBYTE*)(&lpGI)
);
//
// if a ref has been added we need to delete if before
// checking the error status.
//
if (fRefAdded) {
hr = Credentials.DeRefServer();
// even if we fail, we have no recovery path
fRefAdded = FALSE;
}
hr = HRESULT_FROM_WIN32(nasStatus);
BAIL_ON_FAILURE(hr);
// Need to use the name returned by the call as opposed
// to the name given in the ADsPath
if ((*pszGroupName) && lpGI->grpi1_name) {
FreeADsStr(*pszGroupName);
*pszGroupName = AllocADsStr(lpGI->grpi1_name);
}
if (!(*pszGroupName))
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
error:
if (lpGI) {
NetApiBufferFree(lpGI);
}
RRETURN(hr);
}
HRESULT
GetComputerParent(
LPTSTR pszComputerName,
LPTSTR *ppszComputerParentName,
CWinNTCredentials& Credentials
)
{
//
// This function returns the computer parent irrespective of whether
// the computer belongs to a domain or to a workgroup
//
HRESULT hr = S_OK;
LPTSTR pszComputerParentName = NULL;
WCHAR szDomainName[MAX_PATH];
WCHAR szSAMName[MAX_PATH];
szSAMName[0] = szDomainName[0] = L'\0';
hr = WinNTGetCachedComputerName(pszComputerName,
szDomainName,
szSAMName,
Credentials );
BAIL_ON_FAILURE(hr);
pszComputerParentName = AllocADsStr(szDomainName);
if(!pszComputerParentName){
hr = E_OUTOFMEMORY;
}
*ppszComputerParentName = pszComputerParentName;
error:
RRETURN(hr);
}
HRESULT
ConstructFullObjectInfo(
POBJECTINFO pObjectInfo,
POBJECTINFO *ppFullObjectInfo,
CWinNTCredentials& Credentials
)
{
//
// used in the case where the domain name is not specified.
// Here the assumption is that an objectinfo structure with
// domain name not filled in is passed down. We create a new
// object info structure with the domain/workgroup name filled
// in
HRESULT hr = S_OK;
POBJECTINFO pTempObjectInfo = NULL;
DWORD i;
LPWSTR pszComputerParent = NULL;
pTempObjectInfo = (POBJECTINFO)AllocADsMem(sizeof(OBJECTINFO));
if (!pTempObjectInfo) {
RRETURN(hr = E_OUTOFMEMORY);
}
memset(pTempObjectInfo, 0, sizeof(OBJECTINFO));
if(!pObjectInfo){
RRETURN(E_OUTOFMEMORY);
}
pTempObjectInfo->ProviderName = AllocADsStr(pObjectInfo->ProviderName);
if(!pTempObjectInfo->ProviderName){
hr = E_OUTOFMEMORY;
goto error;
}
pTempObjectInfo->ObjectType = pObjectInfo->ObjectType;
pTempObjectInfo->NumComponents = pObjectInfo->NumComponents +1;
for(i=0; i<MAXCOMPONENTS-1; i++){
if(pObjectInfo->ComponentArray[i]) {
pTempObjectInfo->ComponentArray[i+1] =
AllocADsStr(pObjectInfo->ComponentArray[i]);
if(!pTempObjectInfo->ComponentArray[i+1]){
hr = E_OUTOFMEMORY;
goto error;
}
}
if(pObjectInfo->DisplayComponentArray[i]) {
pTempObjectInfo->DisplayComponentArray[i+1] =
AllocADsStr(pObjectInfo->DisplayComponentArray[i]);
if(!pTempObjectInfo->DisplayComponentArray[i+1]){
hr = E_OUTOFMEMORY;
goto error;
}
}
}
hr = GetComputerParent(pObjectInfo->ComponentArray[0],
&(pTempObjectInfo->ComponentArray[0]),
Credentials );
BAIL_ON_FAILURE(hr);
hr = GetDisplayName(pTempObjectInfo->ComponentArray[0],
&(pTempObjectInfo->DisplayComponentArray[0]) );
*ppFullObjectInfo = pTempObjectInfo ;
RRETURN(S_OK);
error:
FreeObjectInfo( pTempObjectInfo );
*ppFullObjectInfo = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetGroupObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT
GetLocalGroupObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szServerName = NULL;
LPWSTR szDomainName = NULL;
LPWSTR szGroupName = NULL;
DWORD dwParentId = 0;
ULONG uGroupType = 0;
POBJECTINFO pGroupObjectInfo = NULL;
hr = ValidateGroupObject(
pObjectInfo,
&uGroupType,
&dwParentId,
Credentials
);
BAIL_ON_FAILURE(hr);
if (uGroupType != WINNT_GROUP_LOCAL) {
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
switch (pObjectInfo->NumComponents) {
case 2:
//
// could be group in computer or group in domain
//
if(dwParentId == WINNT_DOMAIN_ID){
szDomainName = pObjectInfo->ComponentArray[0];
szGroupName = pObjectInfo->ComponentArray[1];
szServerName = NULL;
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
} else {
//
// group in a computer
//
hr = ConstructFullObjectInfo(pObjectInfo,
&pGroupObjectInfo,
Credentials );
if (hr == HRESULT_FROM_WIN32(NERR_WkstaNotStarted)) {
//
// Case when there are no workstation services.
//
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = NULL;
szServerName = pObjectInfo->ComponentArray[0];
szGroupName = pObjectInfo->ComponentArray[1];
} else {
BAIL_ON_FAILURE(hr);
hr = BuildParent(pGroupObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pGroupObjectInfo->ComponentArray[0];
szServerName = pGroupObjectInfo->ComponentArray[1];
szGroupName = pGroupObjectInfo->ComponentArray[2];
}
}
break;
case 3:
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szGroupName = pObjectInfo->ComponentArray[2];
break;
}
hr = CWinNTGroup::CreateGroup(ADsParent,
dwParentId,
szDomainName,
szServerName,
szGroupName,
uGroupType,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
if(pGroupObjectInfo){
FreeObjectInfo(pGroupObjectInfo);
}
RRETURN(hr);
error:
if (pUnknown) {
pUnknown->Release();
}
if(pGroupObjectInfo){
FreeObjectInfo(pGroupObjectInfo);
}
*ppObject = NULL;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: GetGroupObject
//
// Synopsis:
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-3-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT
GetGlobalGroupObject(
POBJECTINFO pObjectInfo,
LPVOID * ppObject,
CWinNTCredentials& Credentials
)
{
LPUNKNOWN pUnknown = NULL;
WCHAR ADsParent[MAX_ADS_PATH];
HRESULT hr = S_OK;
LPWSTR szServerName = NULL;
LPWSTR szDomainName = NULL;
LPWSTR szGroupName = NULL;
DWORD dwParentId = 0;
ULONG uGroupType = 0;
POBJECTINFO pGroupObjectInfo = NULL;
hr = ValidateGroupObject(
pObjectInfo,
&uGroupType,
&dwParentId,
Credentials
);
BAIL_ON_FAILURE(hr);
if (uGroupType != WINNT_GROUP_GLOBAL) {
hr = E_ADS_BAD_PATHNAME;
BAIL_ON_FAILURE(hr);
}
switch (pObjectInfo->NumComponents) {
case 2:
//
// could be group in computer or group in domain
//
if(dwParentId == WINNT_DOMAIN_ID){
szDomainName = pObjectInfo->ComponentArray[0];
szGroupName = pObjectInfo->ComponentArray[1];
szServerName = NULL;
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
} else {
//
// group in a computer
//
hr = ConstructFullObjectInfo(pObjectInfo,
&pGroupObjectInfo,
Credentials );
BAIL_ON_FAILURE(hr);
hr = BuildParent(pGroupObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pGroupObjectInfo->ComponentArray[0];
szServerName = pGroupObjectInfo->ComponentArray[1];
szGroupName = pGroupObjectInfo->ComponentArray[2];
}
break;
case 3:
hr = BuildParent(pObjectInfo, ADsParent);
BAIL_ON_FAILURE(hr);
szDomainName = pObjectInfo->ComponentArray[0];
szServerName = pObjectInfo->ComponentArray[1];
szGroupName = pObjectInfo->ComponentArray[2];
break;
}
hr = CWinNTGroup::CreateGroup(ADsParent,
dwParentId,
szDomainName,
szServerName,
szGroupName,
uGroupType,
ADS_OBJECT_BOUND,
IID_IUnknown,
Credentials,
(void **)&pUnknown
);
BAIL_ON_FAILURE(hr);
*ppObject = pUnknown;
if(pGroupObjectInfo){
FreeObjectInfo(pGroupObjectInfo);
}
RRETURN(hr);
error:
if (pUnknown) {
pUnknown->Release();
}
if(pGroupObjectInfo){
FreeObjectInfo(pGroupObjectInfo);
}
*ppObject = NULL;
RRETURN(hr);
}