|
|
//#--------------------------------------------------------------
//
// File: infohelper.cpp
//
// Synopsis: Implementation of helper methods
// which are used by the sdoserverinfo COM object
//
//
// History: 06/08/98 MKarki Created
//
// Copyright (C) 1997-98 Microsoft Corporation
// All rights reserved.
//
//----------------------------------------------------------------
#include "stdafx.h"
#include "infohelper.h"
#include "sdoias.h"
#include "dsconnection.h"
#include <lmcons.h>
#include <lmwksta.h>
#include <lmserver.h>
#include <lmerr.h>
#include <winldap.h>
#include <explicitlink.h>
#include <lmaccess.h>
#include <lmapibuf.h>
#include <activeds.h>
#include <winsock2.h>
//
// reg key to be queried
//
const WCHAR PRODUCT_OPTIONS_REGKEY [] = L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions";
//
// maximum Domain name
//
const DWORD MAX_DOMAINNAME_LENGTH = 1024;
//
// this holds the matrix to get SYSTEMTYPE from the
// NTTYPE and VERSION type
//
const IASOSTYPE g_OsInfoTable [2][2] = { SYSTEM_TYPE_NT4_WORKSTATION, SYSTEM_TYPE_NT5_WORKSTATION, SYSTEM_TYPE_NT4_SERVER, SYSTEM_TYPE_NT5_SERVER };
//++--------------------------------------------------------------
//
// Function: SdoGetOSInfo
//
// Synopsis: This is method used to get OS System information
// Currently it returns the following info:
// 1) Os Version: 4 or 5
// 2) NtType: Wks or Svr
//
// Arguments:
// LPCWSTR - machine name
// PSYSTEMTYPE - info to be returned
//
// Returns: HRESULT
//
// History: MKarki Created 06/08/98
//
//----------------------------------------------------------------
HRESULT SdoGetOSInfo ( /*[in]*/ LPCWSTR lpServerName, /*[out]*/ PIASOSTYPE pSystemType ) { HRESULT hr = S_OK; NTVERSION eNtVersion; NTTYPE eNtType;
_ASSERT ((NULL != lpServerName) && (NULL != pSystemType));
do { //
// get the OS Version now
//
hr = ::GetNTVersion (lpServerName, &eNtVersion); if (FAILED (hr)) { IASTracePrintf( "Error in SDO - SdoGetOSInfo() - GetNTVersion() failed..." ); break; }
//
// get the OS type - NT Server or Workstation
//
hr = ::IsWorkstationOrServer (lpServerName, &eNtType); if (FAILED (hr)) { IASTracePrintf( "Error in SDO - SdoGetOSInfo()" "- IsWorkstationOrServer() failed..." ); break; }
//
// now decide which machine type this is
//
*pSystemType = g_OsInfoTable [eNtType][eNtVersion];
} while (FALSE);
return (hr);
} // end of ::SdoServerInfo method
//++--------------------------------------------------------------
//
// Function: SdoGetDomainInfo
//
// Synopsis: This is method used to get the domain type
// information
//
// Arguments:
// LPCWSTR - machine name
// LPCWSTR - Domain name
// PDOMAINTYPE - Domain Info
//
// Returns: HRESULT
//
// History: MKarki Created 06/08/98
//
//----------------------------------------------------------------
HRESULT SdoGetDomainInfo ( /*[in]*/ LPCWSTR pszServerName, /*[in]*/ LPCWSTR pszDomainName, /*[out]*/ PIASDOMAINTYPE pDomainType ) { HRESULT hr = S_OK; BOOL bHasDC = FALSE; BOOL bHasDS = FALSE; BOOL bMixed = FALSE; LPBYTE pNetBuffer = NULL; WCHAR szGeneratedDomainName [MAX_DOMAINNAME_LENGTH + 3]; PDOMAIN_CONTROLLER_INFO pDCInfo = NULL;
_ASSERT (pDomainType);
//
// get the domain information by calling DsGetDcName
// where this API is supported
//
DWORD dwErr = ::DsGetDcName ( pszServerName, pszDomainName, NULL, NULL, DS_FORCE_REDISCOVERY | DS_DIRECTORY_SERVICE_PREFERRED, &pDCInfo ); if (NO_ERROR == dwErr) { //
// we sure have a domain controller
//
bHasDC = TRUE;
//
// check if DS is available
//
bHasDS = ((pDCInfo->Flags & DS_DS_FLAG) != 0);
if (NULL == pszDomainName) { pszDomainName = pDCInfo->DomainName; } } else if (ERROR_NO_SUCH_DOMAIN == dwErr) { IASTracePrintf( "Error in SDO - SdoGetDomainInfo()" " - domain could not be located..." ); } else { IASTracePrintf( "Error in SDO - SdoGetDomainInfo()" " - DsGetDcName(DS_PREFERRED) failed with error:%d", dwErr ); hr = HRESULT_FROM_WIN32 (dwErr); goto Cleanup; }
#if 0
//
// case of NT4 - which we don't support as of now
//
else { WCHAR szShortDomainName[MAX_DOMAINNAME_LENGTH +2]; if (NULL != pszDomainName) { lstrcpy (szShortDomainName, pszDomainName); PWCHAR pTemp = wcschr (szShortDomainName, L'.'); if (NULL != pTemp) { *pTemp = L'\0'; } }
//
// DsGetDcName not availabe so call NetGetDCName
// could be Nt 4 machine
//
LPBYTE pNetBuffer = NULL; NET_API_STATUS status = ::NetGetAnyDCName ( pszServerName, (NULL == pszDomainName) ? NULL:szShortDomainName, &pNetBuffer ); if (NERR_Success != status) { IASTracePrintf( "Error in SDO - SdoGetDomainInfo()" " -NetGetAnyDCName (ANY_DOMAIN) failed with error:%d", status ); } else { //
// we sure have a domain controller
//
bHasDC = TRUE;
//
// get domain name if we don't have one already
//
if (NULL == pszDomainName) { hr = ::SdoGetDomainName (pszServerName, szGeneratedDomainName); if (FAILED (hr)) { IASTracePrintf( "Error in SDO - SdoGetDomainInfo()" " - SdoGetDomainName() failed with error:%x", hr ); goto Cleanup; } }
//
// skip the leading "\\"
//
PWCHAR pDomainServerName = 2 + reinterpret_cast <PWCHAR>(pNetBuffer); //
// try connecting to LDAP port on this server
//
LDAP *ld = ldap_openW ( const_cast <PWCHAR> (pDomainServerName), LDAP_PORT ); bHasDS = ld ? ldap_unbind (ld), TRUE:FALSE; } } #endif
//
// if we have NT5 DC, check if its mixed or native domain
//
if (TRUE == bHasDS) { hr = ::IsMixedDomain (pszDomainName, &bMixed); if (FAILED (hr)) { IASTracePrintf( "Error in SDO - SdoGetOSInfo()" " - IsMixedDomain() failed with errror:%x", hr ); } }
//
// now set the info in the pDomainInfo struct
//
if (SUCCEEDED (hr)) { if (bMixed) *pDomainType = DOMAIN_TYPE_MIXED; else if (bHasDS) *pDomainType = DOMAIN_TYPE_NT5; else if (bHasDC) *pDomainType = DOMAIN_TYPE_NT4; else *pDomainType = DOMAIN_TYPE_NONE; }
//
// cleanup here
//
Cleanup:
if (NULL != pDCInfo) ::NetApiBufferFree (pDCInfo);
if (NULL != pNetBuffer) ::NetApiBufferFree (pNetBuffer);
return (hr);
} // end of SdoGetDomainInfo method
//++--------------------------------------------------------------
//
// Function: IsWorkstationOrServer
//
// Synopsis: This is method determines if a specific machine
// is running NT workstation or Server
//
// Arguments:
// LPCWSTR - machine name
// NTTYPE*
//
// Returns: HRESULT
//
// History: MKarki Created 06/08/98
//
//----------------------------------------------------------------
HRESULT IsWorkstationOrServer ( /*[in]*/ LPCWSTR pszComputerName, /*[out]*/ NTTYPE *pNtType ) { HRESULT hr = S_OK; WCHAR szCompleteName [IAS_MAX_SERVER_NAME + 3]; PWCHAR pszTempName = const_cast <PWCHAR> (pszComputerName);
_ASSERT ((NULL != pszComputerName) && (NULL != pNtType));
do { //
// the computer name should have a "\\" in front
//
if ((L'\\' != *pszComputerName) || (L'\\' != *(pszComputerName + 1))) { if (::wcslen (pszComputerName) > IAS_MAX_SERVER_NAME) { IASTracePrintf( "Error in Server Info SDO - IsWorkstationOrServer()" " - Computer name is too big..." ); hr = E_FAIL; break; } ::wcscpy (szCompleteName, L"\\\\"); ::wcscat (szCompleteName, pszComputerName); pszTempName = szCompleteName; }
//
// Connect to the registry
//
HKEY hResult; DWORD dwErr = ::RegConnectRegistry ( pszTempName, HKEY_LOCAL_MACHINE, &hResult ); if (ERROR_SUCCESS != dwErr) { IASTracePrintf( "Error in SDO - IsWorkstationOrServer()" " - RegConnectRegistry() failed with error:%d", dwErr ); hr = HRESULT_FROM_WIN32 (dwErr); break; }
//
// open the registry key now
//
HKEY hValueKey; dwErr = ::RegOpenKeyEx ( hResult, PRODUCT_OPTIONS_REGKEY, 0, KEY_QUERY_VALUE, &hValueKey ); if (ERROR_SUCCESS != dwErr) { IASTracePrintf( "Error in SDO - IsWorkstationOrServer()" " - RegOpenKeyEx() failed with error:%d", hr ); RegCloseKey (hResult); hr = HRESULT_FROM_WIN32 (dwErr); break; }
//
// get the value now
//
WCHAR szProductType [MAX_PATH]; DWORD dwBufferLength = MAX_PATH; dwErr = RegQueryValueEx ( hValueKey, L"ProductType", NULL, NULL, (LPBYTE)szProductType, &dwBufferLength ); if (ERROR_SUCCESS != dwErr) { IASTracePrintf( "Error in SDO - IsWorkstationOrServer()" " - RegQueryValueEx() failed with error:%d", hr ); RegCloseKey (hValueKey); RegCloseKey (hResult); hr = HRESULT_FROM_WIN32 (dwErr); }
//
// determine which NT Type we have on this machine
//
if (_wcsicmp (L"WINNT", szProductType) == 0) { *pNtType = NT_WKSTA; } else if (!_wcsicmp (L"SERVERNT", szProductType) || !_wcsicmp (L"LanmanNT", szProductType)) { *pNtType = NT_SVR; } else { IASTracePrintf( "Error in SDO - IsWorkstationOrServer()" " - Could not determine machine type..." ); RegCloseKey (hValueKey); RegCloseKey (hResult); hr = E_FAIL; }
//
// cleanup
//
RegCloseKey (hValueKey); RegCloseKey (hResult);
} while (FALSE);
return (hr);
} // end of ::IsWorkstationOrServer method
//++--------------------------------------------------------------
//
// Function: GetNTVersion
//
// Synopsis: This is method determines which version of NT
// is running on this machine
//
// Arguments:
// LPCWSTR - machine name
// NTVERSION*
//
// Returns: HRESULT
//
// History: MKarki Created 06/08/98
//
//----------------------------------------------------------------
HRESULT GetNTVersion ( /*[in]*/ LPCWSTR lpComputerName, /*[out]*/ NTVERSION *pNtVersion ) { HRESULT hr = S_OK;
_ASSERT ((NULL != lpComputerName) && (NULL != pNtVersion));
do { //
// get level 100 workstation information
//
PWKSTA_INFO_100 pInfo = NULL; DWORD dwErr = ::NetWkstaGetInfo ( (LPWSTR)lpComputerName, 100, (LPBYTE*)&pInfo ); if (NERR_Success != dwErr) { IASTracePrintf( "Error in SDO - GetNTVersion()" "- NTWkstaGetInfo failed with error:%d", dwErr ); hr = HRESULT_FROM_WIN32 (dwErr); break; }
//
// get the version info
//
if (4 == pInfo->wki100_ver_major) { *pNtVersion = NTVERSION_4; } else if ( 5 == pInfo->wki100_ver_major) { *pNtVersion = NTVERSION_5; } else { IASTracePrintf( "Error in SDO - GetNTVersion()" " - Unsupported OS version..." ); hr = E_FAIL; }
} while (FALSE);
return (hr);
} // end of ::GetNTVersion method
//++--------------------------------------------------------------
//
// Function: IsMixedDomain
//
// Synopsis: This is method determines which version of NT
// is running on this machine
//
// Arguments:
// [in] LPCWSTR - machine name
// [out] PBOOL - is mixed
//
// Returns: HRESULT
//
// History: MKarki Created 06/08/98
//
//----------------------------------------------------------------
HRESULT IsMixedDomain ( /*[in]*/ LPCWSTR pszDomainName, /*[out]*/ PBOOL pbIsMixed ) { HRESULT hr = S_OK; WCHAR szTempName [MAX_DOMAINNAME_LENGTH + 8];
_ASSERT ((NULL != pszDomainName) && (NULL != pbIsMixed));
do { //
// check the arguments passedin
//
if ((NULL == pszDomainName) || (NULL == pbIsMixed)) { IASTracePrintf( "Error in SDO - IsMixedDomain()" " - Invalid parameter - NULL" ); hr = E_INVALIDARG; break; }
if (::wcslen (pszDomainName) > MAX_DOMAINNAME_LENGTH) { IASTracePrintf( "Error in SDO - IsMixedDomain()" " - Invalid parameter (domain name is to long)..." ); hr = E_FAIL; break; }
//
// form the DN name
//
wcscpy (szTempName, L"LDAP://"); wcscat (szTempName, pszDomainName);
//
// get the domain object
//
CComPtr <IADs> pIADs; hr = ::ADsGetObject ( szTempName, IID_IADs, reinterpret_cast <PVOID*> (&pIADs) ); if (FAILED (hr)) { IASTracePrintf( "Error in SDO - IsMixedDomain()" " - Could not get the domain object from the DS with error:%x", hr ); break; }
//
// get the Mixed Domain info
//
_variant_t varMixedInfo; hr = pIADs->Get (L"nTMixedDomain", &varMixedInfo); if (FAILED (hr)) { if (E_ADS_PROPERTY_NOT_FOUND == hr) { //
// this is OK
//
*pbIsMixed = FALSE; hr = S_OK; } else { IASTracePrintf( "Error in SDO - IsMixedDomain()" "- Could not get the 'nTMixedDomain' property" "from the domain object, failed with error:%x", hr ); } break; }
_ASSERT ( (VT_BOOL == V_VT (&varMixedInfo)) || (VT_I4 == V_VT (&varMixedInfo)) );
//
// get the values from the variant
//
if (VT_I4 == V_VT (&varMixedInfo)) { *pbIsMixed = V_I4 (&varMixedInfo); } else if (VT_BOOL == V_VT (&varMixedInfo)) { *pbIsMixed = (VARIANT_TRUE == V_BOOL (&varMixedInfo)); } else { IASTracePrintf( "Error in SDO - IsMixedDomain()" "-'nTMixedDomain property has an invalid value..." ); hr = E_FAIL; break; }
} while (FALSE);
return (hr);
} // end of IsMixedDomain
//++--------------------------------------------------------------
//
// Function: SdoGetDomainName
//
// Synopsis: This is method determines the domain name
// given the server name
//
// Arguments:
// LPCWSTR - machine name
// LPWSTR - pDomanName
//
// Returns: HRESULT
//
// History: MKarki Created 06/08/98
//
//----------------------------------------------------------------
HRESULT SdoGetDomainName ( /*[in]*/ LPCWSTR pszServerName, /*[out]*/ LPWSTR pDomainName ) { _ASSERT (NULL != pDomainName);
#if 0
SERVER_INFO_503 ServerInfo; ServerInfo.sv503_domain = pDomainName; DWORD dwErr = ::NetServerGetInfo ( const_cast <LPWSTR> (pszServerName), 503, reinterpret_cast <LPBYTE*> (&ServerInfo) ); if (NERR_Success != dwErr) { IASTracePrintf("Error in SDO - SdoGetDomainName() - NetServerGetInfo() failed..."); return (HRESULT_FROM_WIN32 (dwErr)); }
return (S_OK);
#endif
return (E_FAIL);
} // end of ::SdoGetDomainName method
|