|
|
//*************************************************************
// File name: GPOBJ.CPP
//
// Description: Group Policy Object class
//
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1998
// All rights reserved
//
//*************************************************************
#include "main.h"
#include "browser.h"
//
// Help ids
//
DWORD aPropertiesHelpIds[] = { IDC_TITLE, IDH_PROP_TITLE, IDC_DISABLE_COMPUTER, IDH_PROP_DISABLE_COMPUTER, IDC_DISABLE_USER, IDH_PROP_DISABLE_USER,
0, 0 };
DWORD aLinkHelpIds[] = { IDC_CBDOMAIN, IDH_LINK_DOMAIN, IDC_ACTION, IDH_LINK_BUTTON, IDC_RESULTLIST, IDH_LINK_RESULT,
0, 0 };
DWORD aWQLFilterHelpIds[] = { IDC_NONE, IDH_WQL_FILTER_NONE, IDC_THIS_FILTER, IDH_WQL_FILTER_THIS_FILTER, IDC_FILTER_NAME, IDH_WQL_FILTER_NAME, IDC_FILTER_BROWSE, IDH_WQL_FILTER_BROWSE,
0, 0 };
///////////////////////////////////////////////////////////////////////////////
// //
// CGroupPolicyObject implementation //
// //
///////////////////////////////////////////////////////////////////////////////
CGroupPolicyObject::CGroupPolicyObject() { InterlockedIncrement(&g_cRefThisDll);
m_cRef = 1; m_bInitialized = FALSE; m_pADs = NULL; m_gpoType = GPOTypeLocal; m_dwFlags = 0; m_pName = NULL; m_pDisplayName = NULL; m_pMachineName = NULL; m_pUser = NULL; m_pMachine = NULL;
m_hinstDSSec = NULL; m_pfnDSCreateSecurityPage = NULL;
m_pTempFilterString = NULL;
m_pDSPath = NULL; m_pFileSysPath = NULL; }
CGroupPolicyObject::~CGroupPolicyObject() { CleanUp();
if (m_hinstDSSec) { FreeLibrary (m_hinstDSSec); }
InterlockedDecrement(&g_cRefThisDll); }
///////////////////////////////////////////////////////////////////////////////
// //
// CGroupPolicyObject object implementation (IUnknown) //
// //
///////////////////////////////////////////////////////////////////////////////
HRESULT CGroupPolicyObject::QueryInterface (REFIID riid, void **ppv) {
if (IsEqualIID(riid, IID_IGroupPolicyObject) || IsEqualIID(riid, IID_IUnknown)) { *ppv = (LPGROUPPOLICYOBJECT)this; m_cRef++; return S_OK; } else { *ppv = NULL; return E_NOINTERFACE; } }
ULONG CGroupPolicyObject::AddRef (void) { return ++m_cRef; }
ULONG CGroupPolicyObject::Release (void) { if (--m_cRef == 0) { delete this; return 0; }
return m_cRef; }
///////////////////////////////////////////////////////////////////////////////
// //
// CGroupPolicyObject object implementation (IGroupPolicyObject) //
// //
///////////////////////////////////////////////////////////////////////////////
//*************************************************************
//
// CGroupPolicyObject::New()
//
// Purpose: Creates a new GPO in the DS
//
// Parameters: pszDomainName - Domain to create GPO in
// pszDisplayName - GPO friendly name (optional)
// dwFlags - Open / creation flags
//
// Note: The domain passed in should be in this format:
// LDAP://DC=domain,DC=company,DC=COM
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::New (LPOLESTR pszDomainName, LPOLESTR pszDisplayName, DWORD dwFlags) { HRESULT hr = E_FAIL; IADsPathname * pADsPathname = NULL; BSTR bstrContainer = NULL; BSTR bstrGPC = NULL; LPTSTR lpResult = NULL, lpDCName = NULL; LPTSTR lpEnd = NULL, lpTemp = NULL, lpGPTPath = NULL; LPTSTR lpForest = NULL; DWORD dwResult; GUID guid; TCHAR szGPOName[50]; TCHAR szTemp[100]; TCHAR szGPOPath[2*MAX_PATH]; WIN32_FILE_ATTRIBUTE_DATA fad; IADs *pADs = NULL; ULONG ulNoChars; PSECURITY_DESCRIPTOR pSD = NULL; SECURITY_INFORMATION si = (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION);
//
// Check if this object has already been initialized
//
if (m_bInitialized) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Called on an initialized object."))); return STG_E_INUSE; }
//
// Check parameters
//
if (!pszDomainName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Null domain name"))); hr = E_INVALIDARG; goto Exit; }
if (CompareString (LOCALE_USER_DEFAULT, NORM_STOP_ON_NULL, TEXT("LDAP://"), 7, pszDomainName, 7) != CSTR_EQUAL) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Domain name does not start with LDAP://"))); hr = E_INVALIDARG; goto Exit; }
//
// Verbose output
//
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: Entering with:"))); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: Domain Name: %s"), pszDomainName)); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: Flags: 0x%x"), dwFlags));
//
// Convert the ADSI domain name into a DNS style name
//
hr = ConvertToDotStyle (pszDomainName, &lpResult);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to convert domain name with 0x%x"), hr)); goto Exit; }
//
// If we are working on the enterprise then we need to get the name of the
// forest.
//
#if FGPO_SUPPORT
if (GPO_OPEN_FOREST == (dwFlags & GPO_OPEN_FOREST)) { DWORD dwResult = QueryForForestName(NULL, lpResult, DS_PDC_REQUIRED | DS_RETURN_DNS_NAME, &lpTemp); if (dwResult != ERROR_SUCCESS) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: QueryForestName failed for domain name %s with %d"), lpResult, dwResult)); hr = HRESULT_FROM_WIN32(dwResult); goto Exit; }
int cch = 0; int n=0; // count the dots in lpTemp;
while (lpTemp[n]) { if (L'.' == lpTemp[n]) { cch++; } n++; } cch *= 3; // multiply the number of dots by 3;
cch += 11; // add 10 + 1 (for the null)
cch += n; // add the string size;
lpForest = (LPTSTR) LocalAlloc(LPTR, sizeof(WCHAR) * cch); if (!lpForest) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for forest name with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } NameToPath(lpForest, lpTemp, cch);
// substitute the forest's dot path for the domain's dot path
LocalFree(lpResult); lpResult = lpTemp; lpTemp = NULL;
//
// Check to see if we have a domain path to a specific DC.
// If we don't then the string will start "LDAP://DC=".
// The equal sign in particular can only be there if we don't have a specific
// DC so we'll just check for the equal sign.
//
if (*(pszDomainName + 9) != TEXT('=')) { // we have a path to a specific DC
// need to extract the server path and prepend it to the forest name
lpDCName = ExtractServerName(pszDomainName);
if (!lpDCName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to extract server name for Forest path"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
lpTemp = MakeFullPath(lpForest, lpDCName);
if (!lpTemp) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to combine server name with Forest path"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
// clean up the variables we just borrowed so they can be used later
LocalFree(lpDCName); lpDCName = NULL; LocalFree(lpForest); lpForest = lpTemp; lpTemp = NULL; }
// Substitute the path to the forest for the path to the domain
pszDomainName = lpForest; } #endif
//
// Check to see if we have a domain path to a specific DC.
// If we don't then the string will start "LDAP://DC=".
// The equal sign in particular can only be there if we don't have a specific
// DC so we'll just check for the equal sign.
//
if (*(pszDomainName + 9) == TEXT('=')) {
//
// Convert LDAP to dot (DN) style
//
hr = ConvertToDotStyle (pszDomainName, &lpTemp);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to convert domain name with 0x%x"), hr)); goto Exit; }
//
// Get the GPO DC for this domain
//
lpDCName = GetDCName (lpTemp, NULL, NULL, FALSE, 0);
if (!lpDCName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to get DC name with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
//
// Build a fully qualified domain name to a specific DC
//
lpTemp = MakeFullPath (pszDomainName, lpDCName);
if (!lpTemp) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } } else {
lpDCName = ExtractServerName (pszDomainName);
if (!lpDCName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to extract server name from ADSI path"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
ulNoChars = lstrlen(pszDomainName) + 1; lpTemp = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR)); if (!lpTemp) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for true domain name with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpTemp, ulNoChars, pszDomainName); ASSERT(SUCCEEDED(hr)); }
//
// Create a pathname object we can work with
//
hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER, IID_IADsPathname, (LPVOID*)&pADsPathname);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create adspathname instance with 0x%x"), hr)); LocalFree (lpTemp); goto Exit; }
//
// Add the domain name
//
BSTR bstrTemp = SysAllocString( lpTemp ); if ( bstrTemp == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for BSTR"))); LocalFree(lpTemp); hr = E_OUTOFMEMORY; goto Exit; }
hr = pADsPathname->Set (bstrTemp, ADS_SETTYPE_FULL); SysFreeString( bstrTemp ); LocalFree (lpTemp);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to set pathname with 0x%x"), hr)); goto Exit; } #if FGPO_SUPPORT
if (GPO_OPEN_FOREST != (dwFlags & GPO_OPEN_FOREST)) { #endif
//
// Add the system folder to the path unless we're on the enterprise
//
BSTR bstrCNSystem = SysAllocString( TEXT("CN=System") ); if ( bstrCNSystem == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for BSTR"))); hr = E_OUTOFMEMORY; goto Exit; } hr = pADsPathname->AddLeafElement ( bstrCNSystem ); SysFreeString( bstrCNSystem );
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to add system folder with 0x%x"), hr)); goto Exit; } #if FGPO_SUPPORT
} else { //
// We're on the enterprise so point at the Configuration folder instead
//
BSTR bstrCNConfiguration = SysAllocString(TEXT("CN=Configuration")); if ( bstrCNConfiguration == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for BSTR"))); hr = E_OUTOFMEMORY; goto Exit; } hr = pADsPathname->AddLeafElement (bstrCNConfiguration); SysFreeString( bstrCNConfiguration );
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to add system folder with 0x%x"), hr)); goto Exit; } } #endif
//
// Retreive the container path - this is the path to the parent of the policies folder
//
hr = pADsPathname->Retrieve (ADS_FORMAT_X500, &bstrContainer);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to retreive container path with 0x%x"), hr)); goto Exit; }
//
// Create the Policies container
//
hr = CreateContainer (bstrContainer, TEXT("Policies"), FALSE); if (FAILED(hr)) { if (hr != HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create the gpo container with 0x%x"), hr)); goto Exit; } }
SysFreeString (bstrContainer); bstrContainer = NULL;
//
// Add the policies container to the path
//
BSTR bstrCNPolicies = SysAllocString(TEXT("CN=Policies")); if ( bstrCNPolicies == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for BSTR"))); hr = E_OUTOFMEMORY; goto Exit; } hr = pADsPathname->AddLeafElement (bstrCNPolicies); SysFreeString( bstrCNPolicies );
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to add policies folder with 0x%x"), hr)); goto Exit; }
//
// Retreive the container path - this is the path to the policies folder
//
hr = pADsPathname->Retrieve (ADS_FORMAT_X500, &bstrContainer);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to retreive container path with 0x%x"), hr)); goto Exit; }
//
// Create a new GPO name (guid)
//
if (FAILED(CoCreateGuid(&guid))) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create GUID."))); goto Exit; }
if (!StringFromGUID2 (guid, szGPOName, ARRAYSIZE(szGPOName))) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to convert GUID."))); goto Exit; }
//
// Create a container for this GPO
//
hr = CreateContainer (bstrContainer, szGPOName, TRUE);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create the gpo container with 0x%x"), hr)); goto Exit; }
SysFreeString (bstrContainer); bstrContainer = NULL;
//
// Add the GPO name to the path
//
hr = StringCchCopy (szTemp, ARRAYSIZE(szTemp), TEXT("CN=")); if (SUCCEEDED(hr)) { hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), szGPOName); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO name with 0x%x"), hr)); goto Exit; }
bstrTemp = SysAllocString(szTemp); if ( bstrTemp == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for BSTR"))); hr = E_OUTOFMEMORY; goto Exit; } hr = pADsPathname->AddLeafElement (bstrTemp); SysFreeString( bstrTemp );
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to add machine folder with 0x%x"), hr)); goto Exit; }
//
// Retreive the GPC path
//
hr = pADsPathname->Retrieve (ADS_FORMAT_X500, &bstrGPC);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to retreive container path with 0x%x"), hr)); goto Exit; }
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: GPO container path is: %s"), bstrGPC));
//
// Now create the machine and user containers
//
hr = CreateContainer (bstrGPC, MACHINE_SECTION, FALSE);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create the machine container with 0x%x"), hr)); goto Exit; }
hr = CreateContainer (bstrGPC, USER_SECTION, FALSE);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create the user container with 0x%x"), hr)); goto Exit; }
//
// Prepare the file system storage on the sysvol
//
// Build the name
//
hr = StringCchPrintf (szGPOPath, ARRAYSIZE(szGPOPath), TEXT("\\\\%s\\SysVol\\%s\\Policies\\%s"), lpDCName, lpResult, szGPOName); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
ulNoChars = lstrlen(szGPOPath) + 1; lpGPTPath = (LPTSTR) LocalAlloc(LPTR, ulNoChars * sizeof(TCHAR));
if (!lpGPTPath) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to allocate memory for GPT path with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpGPTPath, ulNoChars, szGPOPath); ASSERT(SUCCEEDED(hr));
if (!CreateNestedDirectory (szGPOPath, NULL)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create file system directory %s with %d"), szGPOPath, GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: File system folder is: %s"), szGPOPath));
//
// Set the security of the sysvol to match the security of the DS
//
// First, enable some security privilages so we can set the owner / sacl information
//
if (!EnableSecurityPrivs()) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to enable the security privilages with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
//
// Bind to the GPO
//
hr = OpenDSObject(bstrGPC, IID_IADs, (void **)&pADs);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to get gpo IADs interface with 0x%x"), hr)); (void) SetThreadToken(NULL, NULL); goto Exit; }
//
// Get the security descriptor from the DS
//
hr = GetSecurityDescriptor (pADs, si, &pSD);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to query the security descriptor with 0x%x"), hr)); (void) SetThreadToken(NULL, NULL); goto Exit; }
//
// Set the security information on the sysvol
//
dwResult = SetSysvolSecurity (szGPOPath, si, pSD);
if (dwResult != ERROR_SUCCESS) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to set sysvol security for %s with %d"), szGPOPath, dwResult)); hr = HRESULT_FROM_WIN32(dwResult); (void) SetThreadToken(NULL, NULL); goto Exit; }
//
// Reset the security privilages
//
if ( !SetThreadToken(NULL, NULL) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Call to SetThreadToken failed with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
lpEnd = CheckSlash(szGPOPath); ulNoChars = lstrlen(szGPOPath);
//
// Set the initial version number
//
hr = StringCchCat (szGPOPath, ARRAYSIZE(szGPOPath), TEXT("GPT.INI")); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO path with 0x%x"), hr)); goto Exit; } if (!WritePrivateProfileString (TEXT("General"), TEXT("Version"), TEXT("0"), szGPOPath)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to set initial version number for %s with %d"), szGPOPath, GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
//
// Create the user and machine directories
//
hr = StringCchCopy (lpEnd, ARRAYSIZE(szGPOPath) - ulNoChars, MACHINE_SECTION); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
if (!CreateNestedDirectory (szGPOPath, NULL)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create machine file system directory %s with %d"), szGPOPath, GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpEnd, ARRAYSIZE(szGPOPath) - ulNoChars, USER_SECTION); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
if (!CreateNestedDirectory (szGPOPath, NULL)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to create user file system directory %s with %d"), szGPOPath, GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
//
// Set the GPO specific information
//
// Note that we use the nameless form of the sysvol path
//
hr = StringCchPrintf (szGPOPath, ARRAYSIZE(szGPOPath), TEXT("\\\\%s\\SysVol\\%s\\Policies\\%s"), lpResult, lpResult, szGPOName); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
hr = SetGPOInfo (bstrGPC, pszDisplayName, szGPOPath);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to set GPO information with 0x%x"), hr)); goto Exit; }
//
// Call OpenDSGPO to do the loading work
//
hr = OpenDSGPO(bstrGPC, dwFlags);
Exit:
if (lpForest) { LocalFree (lpForest); }
if (lpDCName) { LocalFree (lpDCName); }
if (lpResult) { LocalFree (lpResult); }
if (bstrContainer) { SysFreeString (bstrContainer); }
if (bstrGPC) { if (FAILED(hr)) { if (FAILED(DSDelnode(bstrGPC))) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to delete GPC with 0x%x"), hr)); } }
SysFreeString (bstrGPC); }
if (lpGPTPath) { if (FAILED(hr)) { if (!Delnode(lpGPTPath)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::New: Failed to delete GPT with %d"), GetLastError())); } } }
if (pADsPathname) { pADsPathname->Release(); }
if (pADs) { pADs->Release(); }
if (pSD) { LocalFree (pSD); }
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::New: Leaving with a status of 0x%x"), hr));
return hr; }
//*************************************************************
//
// OpenDSGPO()
//
// Purpose: Opens a DS Group Policy Object
//
// Parameters: pszPath - Path to the GPO to open
// dwFlags - Open / creation flags
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::OpenDSGPO (LPOLESTR pszPath, DWORD dwFlags) { HRESULT hr = E_FAIL; VARIANT var; IADsPathname * pADsPathname = NULL; IADsObjectOptions *pOptions = NULL; BSTR bstrProperty; BSTR bstrGPOName = NULL; BSTR bstrContainer; BSTR bstrDCName; TCHAR* szUserKeyName = NULL; TCHAR* szMachineKeyName = NULL; TCHAR szPath[2*MAX_PATH]; LPTSTR lpTemp; LPTSTR lpEnd; LPTSTR pszFullPath = NULL; DWORD dwResult; WIN32_FILE_ATTRIBUTE_DATA fad; DFS_INFO_101 Info101; LPTSTR lpDCName = NULL; LPOLESTR pszDomain; UINT uiSize; TCHAR szFormat[10]; LPTSTR lpNames[2]; ULONG ulNoChars; LPTSTR lpDottedDomainName = NULL;
//
// Check if this object has already been initialized
//
if (m_bInitialized) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Called on an uninitialized object."))); return STG_E_INUSE; }
//
// Check parameters
//
if (!pszPath) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: NULL GPO name"))); return E_INVALIDARG; }
if (CompareString (LOCALE_USER_DEFAULT, NORM_STOP_ON_NULL, TEXT("LDAP://"), 7, pszPath, 7) != CSTR_EQUAL) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: %s does not start with LDAP://"), pszPath)); hr = E_INVALIDARG; goto Exit; }
//
// Verbose output
//
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Entering with:"))); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: GPO Path: %s"), pszPath)); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Flags: %d"), dwFlags));
//
// Save the flags
//
m_dwFlags = dwFlags;
//
// Retreive the server name if defined
//
lpDCName = ExtractServerName (pszPath);
if (lpDCName) { pszFullPath = pszPath; } else { //
// Get the domain name
//
pszDomain = GetDomainFromLDAPPath(pszPath);
if (!pszDomain) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to get domain name"))); hr = E_FAIL; goto Exit; }
//
// Convert LDAP to dot (DN) style
//
hr = ConvertToDotStyle (pszDomain, &lpTemp);
delete [] pszDomain;
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to convert domain name with 0x%x"), hr)); goto Exit; }
//
// Get the GPO DC for this domain
//
lpDCName = GetDCName (lpTemp, NULL, NULL, FALSE, 0);
LocalFree (lpTemp);
if (!lpDCName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to get DC name with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
//
// Make the fully qualified path
//
pszFullPath = MakeFullPath (pszPath, lpDCName);
if (!pszFullPath) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to make full GPO path"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } }
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Using server %s"), lpDCName)); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Using fully qualifed pathname of %s"), pszFullPath));
//
// Save the DC name
//
ulNoChars = lstrlen(lpDCName) + 1; m_pMachineName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pMachineName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory for machine name"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pMachineName, ulNoChars, lpDCName); ASSERT(SUCCEEDED(hr));
//
// Save the DS path
//
ulNoChars = lstrlen(pszFullPath) + 2; m_pDSPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pDSPath) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory for ds path"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pDSPath, ulNoChars, pszFullPath); ASSERT(SUCCEEDED(hr));
//
// Bind to the DS object. Note we hold on to this bind until
// the object goes away. This way other ADSI calls will go to
// the same DC.
//
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Binding to the object")));
hr = OpenDSObject(m_pDSPath, IID_IADs, (void **)&m_pADs);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: OpenDSObject failed with 0x%x"), hr)); goto Exit; }
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Bound successfully.")));
//
// Check if the user has write permission to the GPO
//
if (!(m_dwFlags & GPO_OPEN_READ_ONLY)) { DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Checking for write access")));
hr = CheckDSWriteAccess ((LPUNKNOWN)m_pADs, TEXT("versionNumber"));
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: CheckDSWriteAccess failed with 0x%x"), hr)); goto Exit; }
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Write access granted"))); }
//
// Query for the file system path
//
bstrProperty = SysAllocString (GPT_PATH_PROPERTY);
if (!bstrProperty) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; goto Exit; }
VariantInit(&var);
hr = m_pADs->Get(bstrProperty, &var);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to query GPT path with 0x%x"), hr)); SysFreeString (bstrProperty); VariantClear (&var); goto Exit; }
ulNoChars = lstrlen(var.bstrVal) + 2; m_pFileSysPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pFileSysPath) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory for gpt path"))); SysFreeString (bstrProperty); VariantClear (&var); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pFileSysPath, ulNoChars, var.bstrVal); ASSERT(SUCCEEDED(hr));
SysFreeString (bstrProperty); VariantClear (&var);
//
// Query for the display name
//
bstrProperty = SysAllocString (GPO_NAME_PROPERTY);
if (!bstrProperty) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; goto Exit; }
VariantInit(&var);
hr = m_pADs->Get(bstrProperty, &var);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to query for display name with 0x%x"), hr)); SysFreeString (bstrProperty); VariantClear (&var); goto Exit; }
ulNoChars = lstrlen(var.bstrVal) + 1; m_pDisplayName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pDisplayName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory for display name"))); SysFreeString (bstrProperty); VariantClear (&var); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pDisplayName, ulNoChars, var.bstrVal); ASSERT(SUCCEEDED(hr));
SysFreeString (bstrProperty); VariantClear (&var);
//
// Create a pathname object we can work with
//
hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER, IID_IADsPathname, (LPVOID*)&pADsPathname);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to create adspathname instance with 0x%x"), hr)); goto Exit; }
//
// Add the domain name
//
BSTR bstrDSPath = SysAllocString( m_pDSPath ); if ( bstrDSPath == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate BSTR memory"))); hr = E_OUTOFMEMORY; goto Exit; } hr = pADsPathname->Set (bstrDSPath, ADS_SETTYPE_FULL); SysFreeString( bstrDSPath );
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to set pathname with 0x%x"), hr)); goto Exit; }
//
// Retrieve the GPO name
//
hr = pADsPathname->GetElement (0, &bstrGPOName);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to retreive GPO name with 0x%x"), hr)); goto Exit; }
//
// Make a copy of the GPO name
//
ulNoChars = lstrlen(bstrGPOName) + 1 - 3; m_pName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate memory for gpo name"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pName, ulNoChars, (bstrGPOName + 3)); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Could not copy GPO name"))); goto Exit; }
//
// Set the ADSI preferred DC.
//
hr = m_pADs->QueryInterface(IID_IADsObjectOptions, (void**)&pOptions);
if (SUCCEEDED(hr)) { //
// Get the domain name
//
pszDomain = GetDomainFromLDAPPath(pszPath);
if (!pszDomain) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to get domain name"))); hr = E_FAIL; goto Exit; }
//
// Convert LDAP to dot (DN) style
//
hr = ConvertToDotStyle (pszDomain, &lpTemp);
delete [] pszDomain;
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to convert domain name with 0x%x"), hr)); goto Exit; }
//
// Build a variant containing the domain and dc names
//
VariantInit(&var);
lpNames[0] = lpTemp; lpNames[1] = lpDCName;
hr = ADsBuildVarArrayStr (lpNames, 2, &var);
LocalFree (lpTemp);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to convert domain name with 0x%x"), hr)); goto Exit; }
//
// Set the DC name
//
hr = pOptions->SetOption(ADS_PRIVATE_OPTION_SPECIFIC_SERVER, var);
VariantClear (&var);
if (FAILED(hr)) {
//
// TODO: Remove this block after lab03 RI's -- or -- remove post whistler beta2
//
if (hr == E_ADS_BAD_PARAMETER) { //
// Set the DC name the old way
//
VariantInit(&var); var.vt = VT_BSTR; var.bstrVal = SysAllocString (lpDCName);
if (var.bstrVal) { hr = pOptions->SetOption(ADS_PRIVATE_OPTION_SPECIFIC_SERVER, var); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to allocate bstr DCName string"))); }
VariantClear (&var); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to set private DC name with 0x%x"), hr)); } }
pOptions->Release(); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to get DS object options interface with 0x%x"), hr)); }
//
// Ask the MUP to read/write to this DC's sysvol.
// We first have to get attributes for the nameless path. This causes the MUP's
// cache to be initialize if it isn't already. Then we can tell
// the MUP which server to use.
//
if (!GetFileAttributesEx (m_pFileSysPath, GetFileExInfoStandard, &fad)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: GetFileAttributes for %s FAILED with %d."), m_pFileSysPath, GetLastError())); }
//
// Now we need to take the full path and trim it down to just
// domain name \ share
//
hr = StringCchCopy (szPath, ARRAYSIZE(szPath), m_pFileSysPath); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Could not copy GPO Path"))); goto Exit; }
if ((szPath[0] != TEXT('\\')) || (szPath[1] != TEXT('\\'))) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Sysvol path doesn't start with \\\\"))); goto Exit; }
lpTemp = szPath + 2;
while (*lpTemp && (*lpTemp != TEXT('\\'))) lpTemp++;
if (!(*lpTemp)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to find slash between domain name and share"))); goto Exit; }
lpTemp++;
while (*lpTemp && (*lpTemp != TEXT('\\'))) lpTemp++;
if (!(*lpTemp)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to find slash between share and directory"))); goto Exit; }
*lpTemp = TEXT('\0');
Info101.State = DFS_STORAGE_STATE_ACTIVE; dwResult = NetDfsSetClientInfo (szPath, lpDCName, L"SysVol", 101, (LPBYTE)&Info101);
if (dwResult != NERR_Success) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to set %s as the active sysvol with %d"), lpDCName, dwResult)); }
//
// Now load the registry information
//
if (m_dwFlags & GPO_OPEN_LOAD_REGISTRY) { DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Loading registry files")));
hr = StringCchCopy (szPath, ARRAYSIZE(szPath), m_pFileSysPath); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Could not copy Sysvol path"))); goto Exit; }
lpEnd = CheckSlash (szPath); ulNoChars = lstrlen(szPath);
//
// Initialize the user registry (HKCU)
//
m_pUser = new CRegistryHive();
if (!m_pUser) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to create User registry"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpEnd, ARRAYSIZE(szPath) - ulNoChars, USER_SECTION); if (SUCCEEDED(hr)) { hr = StringCchCat (lpEnd, ARRAYSIZE(szPath) - ulNoChars, TEXT("\\Registry.pol")); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Could not copy Sysvol path"))); goto Exit; }
//
// Get the domain name
//
pszDomain = GetDomainFromLDAPPath(pszPath); if (!pszDomain) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to get domain name"))); hr = E_FAIL; goto Exit; } //
// Convert LDAP to dot (DN) style
//
hr = ConvertToDotStyle (pszDomain, &lpDottedDomainName); delete [] pszDomain; if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to convert domain name with 0x%x"), hr)); goto Exit; }
GUID tmpGuid; TCHAR szTmpGuid[50];
hr = CoCreateGuid(&tmpGuid); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Registry couldn't create guid"))); goto Exit; }
if (!StringFromGUID2(tmpGuid, szTmpGuid, ARRAYSIZE(szTmpGuid))) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Registry couldn't convert guid to string"))); goto Exit; }
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Mapping Registry to Guid <%s>"), szTmpGuid));
//
// The key name looks like <domain name><a tmp guid><user_section_name>
//
DWORD cchUserKeyName = lstrlen( lpDottedDomainName ) + lstrlen( szTmpGuid ) + sizeof(USER_SECTION) / sizeof(WCHAR) + 1; szUserKeyName = new TCHAR[ cchUserKeyName ];
if ( ! szUserKeyName ) { hr = E_OUTOFMEMORY; goto Exit; }
hr = StringCchCopy (szUserKeyName, cchUserKeyName, lpDottedDomainName );
if (SUCCEEDED(hr)) { hr = StringCchCat (szUserKeyName, cchUserKeyName, szTmpGuid); } if (SUCCEEDED(hr)) { hr = StringCchCat (szUserKeyName, cchUserKeyName, USER_SECTION); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Could not copy key name"))); goto Exit; }
hr = m_pUser->Initialize (szPath, szUserKeyName);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: User registry failed to initialize"))); goto Exit; }
//
// Initialize the machine registry (HKLM)
//
m_pMachine = new CRegistryHive();
if (!m_pMachine) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenDSGPO: Failed to create machine registry"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpEnd, ARRAYSIZE(szPath) - ulNoChars, MACHINE_SECTION); if (SUCCEEDED(hr)) { hr = StringCchCat (lpEnd, ARRAYSIZE(szPath) - ulNoChars, TEXT("\\Registry.pol")); }
//
// The key name looks like <domain name><a tmp guid><machine_section_name>
//
DWORD cchMachineKeyName = 0;
if ( SUCCEEDED(hr) ) { cchMachineKeyName = lstrlen( lpDottedDomainName ) + lstrlen( szTmpGuid ) + sizeof(MACHINE_SECTION) / sizeof(WCHAR) + 1; szMachineKeyName = new TCHAR[ cchMachineKeyName ];
if ( ! szMachineKeyName ) { hr = E_OUTOFMEMORY; } }
if (SUCCEEDED(hr)) { hr = StringCchCopy (szMachineKeyName, cchMachineKeyName, lpDottedDomainName); }
if (SUCCEEDED(hr)) { hr = StringCchCat (szMachineKeyName, cchMachineKeyName, szTmpGuid); }
if (SUCCEEDED(hr)) { hr = StringCchCat (szMachineKeyName, cchMachineKeyName, MACHINE_SECTION); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeGPT: Could not copy GPO path"))); goto Exit; }
hr = m_pMachine->Initialize (szPath, szMachineKeyName);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeGPT: machine registry failed to initialize"))); goto Exit; } }
//
// Success
//
hr = S_OK;
Exit:
if (pADsPathname) { pADsPathname->Release(); }
if (bstrGPOName) { SysFreeString (bstrGPOName); }
if (lpDCName) { LocalFree (lpDCName); }
if (lpDottedDomainName) { LocalFree (lpDottedDomainName ); }
if (pszFullPath != pszPath) { LocalFree (pszFullPath); }
if (SUCCEEDED(hr)) { m_gpoType = GPOTypeDS; m_bInitialized = TRUE; } else { CleanUp(); }
delete [] szUserKeyName; delete [] szMachineKeyName;
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenDSGPO: Leaving with a status of 0x%x"), hr));
return hr; }
//*************************************************************
//
// OpenLocalMachineGPO()
//
// Purpose: Opens this machines GPO
//
// Parameters: dwFlags - load flags
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::OpenLocalMachineGPO (DWORD dwFlags) { HRESULT hr = E_FAIL; TCHAR szBuffer[MAX_PATH]; TCHAR szKeyName[100]; LPTSTR lpEnd; TCHAR szPath[MAX_PATH]; TCHAR szFuncVersion[10]; UINT uRet = 0; ULONG ulNoChars;
//
// Check if this object has already been initialized
//
if (m_bInitialized) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Called on an uninitialized object."))); return STG_E_INUSE; }
//
// Save the flags
//
m_dwFlags = dwFlags;
//
// Get the path to the local GPO
//
ExpandEnvironmentStrings (LOCAL_GPO_DIRECTORY, szBuffer, ARRAYSIZE(szBuffer));
//
// Save the file system path
//
ulNoChars = lstrlen(szBuffer) + 1; m_pFileSysPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pFileSysPath) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to allocate memory for gpt path"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pFileSysPath, ulNoChars, szBuffer); ASSERT(SUCCEEDED(hr));
//
// We disable 32-bit redirection on 64-bit for the local gpo contents -- note
// that we do not re-enable it, since these files should always be redirected
// on this thread
//
DISABLE_32BIT_FILE_REDIRECTION_ON_64BIT(szBuffer);
//
// Create the directory
//
uRet = CreateSecureDirectory (szBuffer); if (!uRet) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to create file system directory %s with %d"), szBuffer, GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
SetFileAttributes (szBuffer, FILE_ATTRIBUTE_HIDDEN);
//
// Check if the user has write access to the directory
//
if (!(m_dwFlags & GPO_OPEN_READ_ONLY)) { hr = CheckFSWriteAccess (szBuffer);
if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: User does not have write access to this GPO (access denied)."))); goto Exit; } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: CheckFSWriteAccess failed with 0x%x"), hr)); } } }
if ( uRet != ERROR_ALREADY_EXISTS ) { hr = StringCchCopy( szPath, ARRAYSIZE(szPath), m_pFileSysPath); if (SUCCEEDED(hr)) { lpEnd = CheckSlash(szPath); hr = StringCchCat( szPath, ARRAYSIZE(szPath), TEXT("gpt.ini") ); }
if (SUCCEEDED(hr)) { hr = StringCchPrintf( szFuncVersion, ARRAYSIZE(szFuncVersion), TEXT("%d"), GPO_FUNCTIONALITY_VERSION ); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
DISABLE_32BIT_FILE_REDIRECTION_ON_64BIT(szPath);
if (!WritePrivateProfileString (TEXT("General"), TEXT("gPCFunctionalityVersion"), szFuncVersion, szPath)) { hr = HRESULT_FROM_WIN32(GetLastError()); DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to write functionality version with 0x%x"), hr)); goto Exit; } }
lpEnd = CheckSlash(szBuffer); ulNoChars = lstrlen(szBuffer);
//
// Create the user and machine directories
//
hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, MACHINE_SECTION); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
DISABLE_32BIT_FILE_REDIRECTION_ON_64BIT(szBuffer);
if (!CreateNestedDirectory (szBuffer, NULL)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to create machine subdirectory with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, USER_SECTION); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
DISABLE_32BIT_FILE_REDIRECTION_ON_64BIT(szBuffer);
if (!CreateNestedDirectory (szBuffer, NULL)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to create user subdirectory with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
//
// Load the GPO name
//
LoadString (g_hInstance, IDS_LOCAL_NAME, szBuffer, ARRAYSIZE(szBuffer));
ulNoChars = lstrlen(szBuffer) + 2; m_pName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to allocate memory for name"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pName, ulNoChars, szBuffer); ASSERT(SUCCEEDED(hr));
//
// Load the display name
//
LoadString (g_hInstance, IDS_LOCAL_DISPLAY_NAME, szBuffer, ARRAYSIZE(szBuffer));
ulNoChars = lstrlen(szBuffer) + 2; m_pDisplayName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pDisplayName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to allocate memory for display name"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pDisplayName, ulNoChars, szBuffer); ASSERT(SUCCEEDED(hr));
//
// Now load the registry information
//
if (m_dwFlags & GPO_OPEN_LOAD_REGISTRY) { hr = StringCchCopy (szBuffer, ARRAYSIZE(szBuffer), m_pFileSysPath); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
lpEnd = CheckSlash (szBuffer); ulNoChars = lstrlen(szBuffer);
//
// Initialize the user registry (HKCU)
//
GUID tmpGuid; TCHAR szTmpGuid[50];
hr = CoCreateGuid(&tmpGuid); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Registry couldn't create guid"))); goto Exit; }
if (!StringFromGUID2(tmpGuid, szTmpGuid, ARRAYSIZE(szTmpGuid))) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Registry couldn't convert guid to string"))); goto Exit; }
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Mapping Registry to Guid <%s>"), szTmpGuid));
m_pUser = new CRegistryHive();
if (!m_pUser) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to create User registry"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, USER_SECTION); if (SUCCEEDED(hr)) { hr = StringCchCat (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, TEXT("\\Registry.pol")); }
if (SUCCEEDED(hr)) { hr = StringCchCopy (szKeyName, ARRAYSIZE(szKeyName), szTmpGuid); }
if (SUCCEEDED(hr)) { hr = StringCchCat (szKeyName, ARRAYSIZE(szKeyName), USER_SECTION); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
hr = m_pUser->Initialize (szBuffer, szKeyName);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: User registry failed to initialize"))); goto Exit; }
//
// Initialize the machine registry (HKLM)
//
m_pMachine = new CRegistryHive();
if (!m_pMachine) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Failed to create machine registry"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, MACHINE_SECTION); if (SUCCEEDED(hr)) { hr = StringCchCat (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, TEXT("\\Registry.pol")); }
if (SUCCEEDED(hr)) { hr = StringCchCopy (szKeyName, ARRAYSIZE(szKeyName), szTmpGuid); }
if (SUCCEEDED(hr)) { hr = StringCchCat (szKeyName, ARRAYSIZE(szKeyName), MACHINE_SECTION); } if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenLocalMachineGPO: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
hr = m_pMachine->Initialize (szBuffer, szKeyName);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeGPT: machine registry failed to initialize"))); goto Exit; } }
//
// Success
//
hr = S_OK;
Exit:
if (SUCCEEDED(hr)) { m_gpoType = GPOTypeLocal; m_bInitialized = TRUE; } else { CleanUp(); }
return hr; }
//*************************************************************
//
// OpenRemoteMachineGPO()
//
// Purpose: Opens a remote machines GPO
// dwFlags - load flags
//
// Parameters: pszComputerName - name of computer
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::OpenRemoteMachineGPO (LPOLESTR pszComputerName, DWORD dwFlags) { HRESULT hr = E_FAIL; TCHAR szComputerName[MAX_PATH]; TCHAR szBuffer[MAX_PATH]; TCHAR szKeyName[100]; LPTSTR lpEnd; TCHAR szPath[MAX_PATH]; TCHAR szFuncVersion[10]; UINT uRet = 0; ULONG ulNoChars;
//
// Check if this object has already been initialized
//
if (m_bInitialized) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Called on an uninitialized object."))); return STG_E_INUSE; }
//
// Check parameters
//
if (!pszComputerName) return E_INVALIDARG;
//
// Save the flags
//
m_dwFlags = dwFlags;
//
// Parse the computer name
//
if ((pszComputerName[0] == TEXT('\\')) && (pszComputerName[1] == TEXT('\\'))) { hr = StringCchCopy (szComputerName, ARRAYSIZE(szComputerName), pszComputerName+2); } else { hr = StringCchCopy (szComputerName, ARRAYSIZE(szComputerName), pszComputerName); }
if (FAILED(hr)) { return hr; }
//
// Save the machine name
//
ulNoChars = lstrlen(szComputerName) + 1; m_pMachineName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pMachineName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to allocate memory for machine name"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pMachineName, ulNoChars, szComputerName); ASSERT(SUCCEEDED(hr));
//
// Get the path to the local GPO
//
hr = StringCchPrintf (szBuffer, ARRAYSIZE(szBuffer), REMOTE_GPO_DIRECTORY, szComputerName); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy path to local GPO"))); goto Exit; }
//
// Save the file system path
//
ulNoChars = lstrlen(szBuffer) + 1; m_pFileSysPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pFileSysPath) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to allocate memory for gpt path"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pFileSysPath, ulNoChars, szBuffer); ASSERT(SUCCEEDED(hr));
//
// Create the directory
//
uRet = CreateSecureDirectory (szBuffer); if (!uRet) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to create file system directory %s with %d"), szBuffer, GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
SetFileAttributes (szBuffer, FILE_ATTRIBUTE_HIDDEN);
//
// Check if the user has write access to the directory
//
if (!(m_dwFlags & GPO_OPEN_READ_ONLY)) { hr = CheckFSWriteAccess (szBuffer);
if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: User does not have write access to this GPO (access denied)."))); goto Exit; } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: CheckFSWriteAccess failed with 0x%x"), hr)); } } }
if ( uRet != ERROR_ALREADY_EXISTS ) { hr = StringCchCopy ( szPath, ARRAYSIZE(szPath), m_pFileSysPath ); if (SUCCEEDED(hr)) { lpEnd = CheckSlash(szPath); hr = StringCchCat ( szPath, ARRAYSIZE(szPath), TEXT("gpt.ini") ); }
if (SUCCEEDED(hr)) { hr = StringCchPrintf( szFuncVersion, ARRAYSIZE(szFuncVersion), TEXT("%d"), GPO_FUNCTIONALITY_VERSION ); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path"))); goto Exit; }
if (!WritePrivateProfileString (TEXT("General"), TEXT("gPCFunctionalityVersion"), szFuncVersion, szPath)) { hr = HRESULT_FROM_WIN32(GetLastError()); DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to write functionality version with 0x%x"), hr)); goto Exit; } }
lpEnd = CheckSlash(szBuffer); ulNoChars = lstrlen(szBuffer);
//
// Create the user and machine directories
//
hr = StringCchCat (szBuffer, ARRAYSIZE(szBuffer), MACHINE_SECTION); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path"))); goto Exit; }
if (!CreateNestedDirectory (szBuffer, NULL)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to create machine subdirectory with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, USER_SECTION); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path"))); goto Exit; }
if (!CreateNestedDirectory (szBuffer, NULL)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to create user subdirectory with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
//
// Load the GPO name
//
ulNoChars = lstrlen(szComputerName) + 2; m_pName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to allocate memory for name"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pName, ulNoChars, szComputerName); ASSERT(SUCCEEDED(hr));
//
// Load the display name
//
ulNoChars = lstrlen(szComputerName) + 2; m_pDisplayName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (!m_pDisplayName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to allocate memory for display name"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (m_pDisplayName, ulNoChars, szComputerName); ASSERT(SUCCEEDED(hr));
//
// Now load the registry information
//
if (m_dwFlags & GPO_OPEN_LOAD_REGISTRY) { hr = StringCchCopy (szBuffer, ARRAYSIZE(szBuffer), m_pFileSysPath); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path"))); goto Exit; } lpEnd = CheckSlash (szBuffer); ulNoChars = lstrlen(szBuffer);
GUID tmpGuid; TCHAR szTmpGuid[50];
hr = CoCreateGuid(&tmpGuid); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Registry couldn't create guid"))); goto Exit; }
if (!StringFromGUID2(tmpGuid, szTmpGuid, ARRAYSIZE(szTmpGuid))) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Registry couldn't convert guid to string"))); goto Exit; }
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Mapping Registry to Guid <%s>"), szTmpGuid));
//
// Initialize the user registry (HKCU)
//
m_pUser = new CRegistryHive();
if (!m_pUser) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to create User registry"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, USER_SECTION); if (SUCCEEDED(hr)) { hr = StringCchCat (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, TEXT("\\Registry.pol")); }
if (SUCCEEDED(hr)) { hr = StringCchCopy (szKeyName, ARRAYSIZE(szKeyName), szTmpGuid); }
if (SUCCEEDED(hr)) { hr = StringCchCat (szKeyName, ARRAYSIZE(szKeyName), USER_SECTION); } if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path"))); goto Exit; }
hr = m_pUser->Initialize (szBuffer, szKeyName);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: User registry failed to initialize"))); goto Exit; } //
// Initialize the machine registry (HKLM)
//
m_pMachine = new CRegistryHive();
if (!m_pMachine) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Failed to create machine registry"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
hr = StringCchCopy (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, MACHINE_SECTION); if (SUCCEEDED(hr)) { hr = StringCchCat (lpEnd, ARRAYSIZE(szBuffer) - ulNoChars, TEXT("\\Registry.pol")); }
if (SUCCEEDED(hr)) { hr = StringCchCopy (szKeyName, ARRAYSIZE(szKeyName), szTmpGuid); }
if (SUCCEEDED(hr)) { hr = StringCchCat (szKeyName, ARRAYSIZE(szKeyName), MACHINE_SECTION); } if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path"))); goto Exit; } hr = m_pMachine->Initialize (szBuffer, szKeyName);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CComponentData::InitializeGPT: machine registry failed to initialize"))); goto Exit; } }
//
// Success
//
hr = S_OK;
Exit:
if (SUCCEEDED(hr)) { m_gpoType = GPOTypeRemote; m_bInitialized = TRUE; } else { CleanUp(); }
return hr;
}
//*************************************************************
//
// Save()
//
// Purpose: Saves the registry information and bumps the
// version number
//
// Parameters: none
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::Save (BOOL bMachine, BOOL bAdd, GUID *pGuidExtension, GUID *pGuidSnapin) { HRESULT hr; TCHAR szPath[2*MAX_PATH]; TCHAR szVersion[25]; ULONG ulVersion, ulOriginal; USHORT uMachine, uUser; BSTR bstrName; VARIANT var; GUID RegistryGuid = REGISTRY_EXTENSION_GUID; BOOL bEmpty;
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::Save: Entering with bMachine = %d and bAdd = %d"), bMachine, bAdd));
if (!m_bInitialized) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Called on an uninitialized object."))); return OLE_E_BLANK; }
if ( pGuidExtension == 0 || pGuidSnapin == 0 ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: One of the guids is null"))); return ERROR_INVALID_PARAMETER; }
if (m_dwFlags & GPO_OPEN_READ_ONLY) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Called on a READ ONLY GPO"))); return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); }
//
// Save registry settings
//
if (!CompareGuid (pGuidExtension, &RegistryGuid)) { if (bMachine) { if (m_pMachine) { hr = m_pMachine->Save();
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to save the machine registry with 0x%x"), hr)); return hr; }
hr = m_pMachine->IsRegistryEmpty(&bEmpty);
if (SUCCEEDED(hr) && bEmpty) { bAdd = FALSE; } else { bAdd = TRUE; } } } else { if (m_pUser) { hr = m_pUser->Save();
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to save the user registry with 0x%x"), hr)); return hr; }
hr = m_pUser->IsRegistryEmpty(&bEmpty);
if (SUCCEEDED(hr) && bEmpty) { bAdd = FALSE; } else { bAdd = TRUE; } } } }
XPtrST<TCHAR> xValueIn; hr = GetProperty( bMachine ? GPO_MACHEXTENSION_NAMES : GPO_USEREXTENSION_NAMES, xValueIn ); if ( FAILED(hr) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to GetProperty with 0x%x"), hr)); return hr; }
CGuidList guidList;
hr = guidList.UnMarshallGuids( xValueIn.GetPointer() ); if ( FAILED(hr) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to unmarshall guids with 0x%x"), hr)); return hr; }
hr = guidList.Update( bAdd, pGuidExtension, pGuidSnapin ); if ( FAILED(hr) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to update with 0x%x"), hr)); return hr; }
if ( guidList.GuidsChanged() ) { XPtrST<TCHAR> xValueOut;
hr = guidList.MarshallGuids( xValueOut ); if ( FAILED(hr ) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to marshall guids with 0x%x"), hr)); return hr; }
hr = SetProperty( bMachine ? GPO_MACHEXTENSION_NAMES : GPO_USEREXTENSION_NAMES, xValueOut.GetPointer() ); if ( FAILED(hr ) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to set property guids with 0x%x"), hr)); return hr; } }
//
// Get the current version number
//
hr = StringCchCopy (szPath, ARRAYSIZE(szPath), m_pFileSysPath); if (SUCCEEDED(hr)) { hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("\\GPT.INI")); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO Path"))); return hr; }
if (m_gpoType == GPOTypeDS) {
bstrName = SysAllocString (GPO_VERSION_PROPERTY);
if (!bstrName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to allocate memory"))); return E_OUTOFMEMORY; }
VariantInit(&var); hr = m_pADs->Get(bstrName, &var);
if (SUCCEEDED(hr)) { ulOriginal = var.lVal; }
SysFreeString (bstrName); VariantClear (&var);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to get ds version number with 0x%x"), hr)); return hr; } } else { //
// We disable 32-bit redirection on 64-bit for the local gpt.ini -- note
// that we do not re-enable it, since this file should always be redirected
// on this thread
//
DISABLE_32BIT_FILE_REDIRECTION_ON_64BIT(szPath)
ulOriginal = GetPrivateProfileInt(TEXT("General"), TEXT("Version"), 0, szPath); }
//
// Separate the user and machine version numbers
//
uUser = (USHORT) HIWORD(ulOriginal); uMachine = (USHORT) LOWORD(ulOriginal);
//
// Increment the version number
//
if (bMachine) { uMachine = uMachine + 1;
if (uMachine == 0) uMachine++; } else { uUser = uUser + 1;
if (uUser == 0) uUser++; }
//
// Put the version number back together
//
ulVersion = (ULONG) MAKELONG (uMachine, uUser);
//
// Update version number in the GPT
//
hr = StringCchPrintf (szVersion, ARRAYSIZE(szVersion), TEXT("%d"), ulVersion); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO version"))); return hr; }
if (!WritePrivateProfileString (TEXT("General"), TEXT("Version"), szVersion, szPath)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to write sysvol version number with %d"), GetLastError())); return HRESULT_FROM_WIN32(GetLastError()); }
//
// Put the original version number in szVersion in case
// we need to roll backwards below
//
hr = StringCchPrintf (szVersion, ARRAYSIZE(szVersion), TEXT("%d"), ulOriginal); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OpenRemoteMachineGPO: Could not copy GPO original version"))); return hr; }
//
// Set the version number in the GPC
//
if (m_gpoType == GPOTypeDS) { bstrName = SysAllocString (GPO_VERSION_PROPERTY);
if (bstrName) { VariantInit(&var); var.vt = VT_I4; var.lVal = ulVersion;
hr = m_pADs->Put(bstrName, var);
VariantClear (&var); SysFreeString (bstrName); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to allocate memory"))); hr = E_OUTOFMEMORY; }
if (SUCCEEDED(hr)) { //
// Commit the changes
//
hr = m_pADs->SetInfo();
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to commit version number update with 0x%x"), hr)); if (!WritePrivateProfileString (TEXT("General"), TEXT("Version"), szVersion, szPath)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to reset the sysvol version number with %d"), GetLastError())); } }
} else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to update version number with 0x%x"), hr)); if (!WritePrivateProfileString (TEXT("General"), TEXT("Version"), szVersion, szPath)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Save: Failed to reset the sysvol version number with %d"), GetLastError())); }
} }
//
// If we are editing the local group policy object, then call
// RefreshGroupPolicy() so that the end user can see the results
// immediately.
//
if (m_gpoType == GPOTypeLocal) { RefreshGroupPolicy (bMachine); }
DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::Save: Leaving with 0x%x"), hr));
return hr; }
//*************************************************************
//
// Delete()
//
// Purpose: Deletes this Group Policy Object
//
// Parameters: none
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::Delete (void) { HRESULT hr;
if (!m_bInitialized) { return OLE_E_BLANK; }
if (m_dwFlags & GPO_OPEN_READ_ONLY) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Delete: Delete called on a READ ONLY GPO"))); return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); }
//
// Unmount the registry information
//
if (m_pUser) { m_pUser->Release(); m_pUser = NULL; }
if (m_pMachine) { m_pMachine->Release(); m_pMachine = NULL; }
//
// Clean out the DS stuff
//
if (m_gpoType == GPOTypeDS) { hr = DSDelnode (m_pDSPath);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Delete: Failed to delete DS storage with 0x%x"), hr)); goto Exit; } }
//
// Delete the file system stuff
//
if (Delnode (m_pFileSysPath)) { hr = S_OK; } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::Delete: Failed to delete file system storage with %d"), GetLastError())); hr = HRESULT_FROM_WIN32(GetLastError()); }
if (SUCCEEDED(hr)) { CleanUp(); }
Exit:
return hr; }
//*************************************************************
//
// GetName()
//
// Purpose: Gets the unique GPO name
//
// Parameters: pszName is a pointer to a buffer which receives the name
// cchMaxLength is the max size of the buffer
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::GetName (LPOLESTR pszName, int cchMaxLength) {
//
// Check parameters
//
if (!pszName || (cchMaxLength <= 0)) return E_INVALIDARG;
if (!m_bInitialized) { return OLE_E_BLANK; }
//
// Save the name
//
if ((lstrlen (m_pName) + 1) <= cchMaxLength) { HRESULT hr;
hr = StringCchCopy (pszName, cchMaxLength, m_pName); return hr; }
return E_OUTOFMEMORY; }
//*************************************************************
//
// GetDisplayName()
//
// Purpose: Gets the friendly name for this GPO
//
// Parameters: pszName is a pointer to a buffer which receives the name
// cchMaxLength is the max size of the buffer
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::GetDisplayName (LPOLESTR pszName, int cchMaxLength) {
//
// Check parameters
//
if (!pszName || (cchMaxLength <= 0)) return E_INVALIDARG;
if (!m_bInitialized) { return OLE_E_BLANK; }
if ((lstrlen (m_pDisplayName) + 1) <= cchMaxLength) { HRESULT hr;
hr = StringCchCopy (pszName, cchMaxLength, m_pDisplayName); return hr; }
return E_OUTOFMEMORY; }
//+--------------------------------------------------------------------------
//
// Member: CGroupPolicyObject::SetDisplayName
//
// Synopsis: changes the friendly display name for a group policy object
//
// Arguments: [pszName] - new name (can be NULL to clear name)
//
// Returns: S_OK - success
//
// Modifies:
//
// Derivation:
//
// History: 05-002-1998 stevebl Created
//
// Notes:
//
//---------------------------------------------------------------------------
STDMETHODIMP CGroupPolicyObject::SetDisplayName (LPOLESTR lpDisplayName) { HRESULT hr = E_FAIL; BSTR bstrName; VARIANT var; LPOLESTR lpNewName; LPTSTR lpPath, lpEnd; DWORD dwSize;
//
// Check parameters
//
if (!m_bInitialized) { return OLE_E_BLANK; }
if (m_gpoType != GPOTypeDS) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayName: Called for a non DS GPO"))); hr = E_INVALIDARG; goto Exit; }
if (!lpDisplayName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayName: NULL display name"))); hr = E_INVALIDARG; goto Exit; }
if (m_dwFlags & GPO_OPEN_READ_ONLY) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayName: Called for a READ ONLY GPO"))); hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); goto Exit; }
//
// Call the internal method to set the display name
//
hr = SetDisplayNameI (m_pADs, lpDisplayName, m_pFileSysPath, TRUE);
Exit:
return hr; }
//*************************************************************
//
// GetPath()
//
// Purpose: Returns the path to the GPO
//
// If the GPO is in the DS, this is an DN path
// If the GPO is machine based, it is a file system path
//
// Parameters: pszPath is a pointer to a buffer which receives the path
// cchMaxLength is the max size of the buffer
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::GetPath (LPOLESTR pszPath, int cchMaxLength) { LPTSTR lpTemp;
//
// Check parameters
//
if (!pszPath || (cchMaxLength <= 0)) return E_INVALIDARG;
if (!m_bInitialized) { return OLE_E_BLANK; }
if (m_gpoType == GPOTypeDS) { lpTemp = MakeNamelessPath (m_pDSPath);
if (lpTemp) { if ((lstrlen (lpTemp) + 1) <= cchMaxLength) { HRESULT hr;
hr = StringCchCopy (pszPath, cchMaxLength, lpTemp); LocalFree (lpTemp); return hr; }
LocalFree (lpTemp); } } else { if ((lstrlen (m_pFileSysPath) + 1) <= cchMaxLength) { HRESULT hr;
hr = StringCchCopy (pszPath, cchMaxLength, m_pFileSysPath); return hr; } }
return E_OUTOFMEMORY; }
//*************************************************************
//
// GetDSPath()
//
// Purpose: Returns a DS path to the requested section
//
// Parameters: dwSection identifies root vs user vs machine
// pszPath is a pointer to a buffer which receives the path
// cchMaxLength is the max size of the buffer
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::GetDSPath (DWORD dwSection, LPOLESTR pszPath, int cchMaxPath) { HRESULT hr = E_FAIL; BSTR bstrPath = NULL; TCHAR szTemp[100]; IADsPathname * pADsPathname = NULL;
//
// Check for initialization
//
if (!m_bInitialized) { return OLE_E_BLANK; }
//
// Check parameters
//
if (!pszPath || (cchMaxPath <= 0)) return E_INVALIDARG;
if ((dwSection != GPO_SECTION_ROOT) && (dwSection != GPO_SECTION_USER) && (dwSection != GPO_SECTION_MACHINE)) return E_INVALIDARG;
//
// If this is a local or remote machine GPO, then the
// caller gets an empty string back.
//
if (m_gpoType != GPOTypeDS) { *pszPath = TEXT('\0'); hr = S_OK; goto Exit; }
//
// Create a pathname object we can work with
//
hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER, IID_IADsPathname, (LPVOID*)&pADsPathname);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to create adspathname instance with 0x%x"), hr)); goto Exit; }
//
// Add the GPO name
//
BSTR bstrDSPath = SysAllocString( m_pDSPath ); if ( bstrDSPath == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to allocate BSTR memory"))); hr = E_OUTOFMEMORY; goto Exit; } hr = pADsPathname->Set (bstrDSPath, ADS_SETTYPE_FULL); SysFreeString( bstrDSPath );
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to set pathname with 0x%x"), hr)); goto Exit; }
//
// Add the appropriate subcontainer
//
if (dwSection != GPO_SECTION_ROOT) { hr = StringCchCopy (szTemp, ARRAYSIZE(szTemp), TEXT("CN=")); if (SUCCEEDED(hr)) { if (dwSection == GPO_SECTION_USER) { hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), USER_SECTION); } else { hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), MACHINE_SECTION); } }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Could not copy GPO path with 0x%x"), hr)); goto Exit; }
BSTR bstrTemp = SysAllocString( szTemp ); if ( bstrTemp == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to allocate BSTR memory"))); hr = E_OUTOFMEMORY; goto Exit; } hr = pADsPathname->AddLeafElement (bstrTemp); SysFreeString( bstrTemp ); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to add subcontainer with 0x%x"), hr)); goto Exit; } }
hr = pADsPathname->Retrieve (ADS_FORMAT_X500_NO_SERVER, &bstrPath);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetDSPath: Failed to retreive container path with 0x%x"), hr)); goto Exit; }
if ((lstrlen(bstrPath) + 1) <= cchMaxPath) { hr = StringCchCopy (pszPath, cchMaxPath, bstrPath); } else { hr = E_OUTOFMEMORY; }
SysFreeString (bstrPath);
Exit:
if (pADsPathname) { pADsPathname->Release(); }
return hr; }
//*************************************************************
//
// GetFileSysPath()
//
// Purpose: Returns the file system path to the requested section
//
// Parameters: dwSection identifies user vs machine
// pszPath is a pointer to a buffer which receives the path
// cchMaxLength is the max size of the buffer
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::GetFileSysPath (DWORD dwSection, LPOLESTR pszPath, int cchMaxPath) { TCHAR szPath[2*MAX_PATH]; HRESULT hr;
//
// Check parameters
//
if (!pszPath || (cchMaxPath <= 0)) return E_INVALIDARG;
if (!m_bInitialized) { return OLE_E_BLANK; }
hr = StringCchCopy (szPath, ARRAYSIZE(szPath), m_pFileSysPath); if (FAILED(hr)) { return hr; }
if (dwSection != GPO_SECTION_ROOT) { if (dwSection == GPO_SECTION_USER) { (void) CheckSlash (szPath); hr = StringCchCat (szPath, ARRAYSIZE(szPath), USER_SECTION); } else if (dwSection == GPO_SECTION_MACHINE) { (void) CheckSlash (szPath); hr = StringCchCat (szPath, ARRAYSIZE(szPath), MACHINE_SECTION); } else { return E_INVALIDARG; }
if (FAILED(hr)) { return hr; } }
if ((lstrlen(szPath) + 1) <= cchMaxPath) { hr = StringCchCopy (pszPath, cchMaxPath, szPath); return hr; }
return E_OUTOFMEMORY; }
//*************************************************************
//
// GetRegistryKey()
//
// Purpose: Returns the requested registry key
//
// Parameters: dwSection identifies user vs machine
// hKey receives the opened registry key
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::GetRegistryKey (DWORD dwSection, HKEY *hKey) { HRESULT hr = E_FAIL;
if (!m_bInitialized) { return OLE_E_BLANK; }
switch (dwSection) { case GPO_SECTION_USER: if (m_pUser) { hr = m_pUser->GetHKey(hKey); } break;
case GPO_SECTION_MACHINE: if (m_pMachine) { hr = m_pMachine->GetHKey(hKey); } break; }
return (hr); }
//*************************************************************
//
// GetOptions()
//
// Purpose: Gets the GPO options
//
// Parameters: dwOptions receives the options
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::GetOptions (DWORD * dwOptions) { HRESULT hr;
//
// Check for initialization
//
if (!m_bInitialized) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Called on an uninitialized object."))); return OLE_E_BLANK; }
//
// Check argument
//
if (!dwOptions) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Received a NULL ptr."))); return E_INVALIDARG; }
//
// If this is a DS GPO, the options are stored as a property on the
// GPC. If this a machine GPO, they are in the gpt.ini file.
//
if (m_gpoType == GPOTypeDS) { VARIANT var; BSTR bstrProperty;
//
// Query for the options
//
bstrProperty = SysAllocString (GPO_OPTIONS_PROPERTY);
if (bstrProperty) { VariantInit(&var);
hr = m_pADs->Get(bstrProperty, &var);
if (SUCCEEDED(hr)) { *dwOptions = var.lVal; } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Failed to query for options with 0x%x"), hr)); }
VariantClear (&var); SysFreeString (bstrProperty); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; } } else { TCHAR szPath[2*MAX_PATH]; LPTSTR lpEnd;
//
// Get the file system path
//
hr = GetPath (szPath, ARRAYSIZE(szPath));
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Failed to get path with 0x%x"), hr)); return hr; }
//
// Tack on gpt.ini
//
lpEnd = CheckSlash (szPath); hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("GPT.INI")); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Could not copy GPO path with 0x%x"), hr)); return hr; }
//
// Get the options
//
*dwOptions = GetPrivateProfileInt (TEXT("General"), TEXT("Options"), 0, szPath);
hr = S_OK; }
return hr; }
//*************************************************************
//
// SetOptions()
//
// Purpose: Sets the GPO options
//
// Parameters: dwOptions is the new options
// dwMask states which options should be set
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::SetOptions (DWORD dwOptions, DWORD dwMask) { HRESULT hr; DWORD dwResult = 0, dwOriginal;
//
// Check for initialization
//
if (!m_bInitialized) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Called on an uninitialized object."))); return OLE_E_BLANK; }
if (m_dwFlags & GPO_OPEN_READ_ONLY) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Called for a READ ONLY GPO"))); return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); }
//
// Query for the current options
//
hr = GetOptions (&dwResult);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Failed to get previous options with 0x%x"), hr)); return hr; }
//
// Save the original options so we can compare later
//
dwOriginal = dwResult;
//
// Check for the machine disabled option
//
if (dwMask & GPO_OPTION_DISABLE_MACHINE) { if (dwOptions & GPO_OPTION_DISABLE_MACHINE) { dwResult |= GPO_OPTION_DISABLE_MACHINE; } else { dwResult &= ~GPO_OPTION_DISABLE_MACHINE; } }
//
// Check for the user disabled option
//
if (dwMask & GPO_OPTION_DISABLE_USER) { if (dwOptions & GPO_OPTION_DISABLE_USER) { dwResult |= GPO_OPTION_DISABLE_USER; } else { dwResult &= ~GPO_OPTION_DISABLE_USER; } }
//
// If something changed, set the options back in the GPO
//
if (dwResult != dwOriginal) {
//
// Set the options in the DS or gpt.ini as appropriate
//
if (m_gpoType == GPOTypeDS) { VARIANT var; BSTR bstrName;
bstrName = SysAllocString (GPO_OPTIONS_PROPERTY);
if (bstrName) { VariantInit(&var); var.vt = VT_I4; var.lVal = dwResult;
hr = m_pADs->Put(bstrName, var);
VariantClear (&var); SysFreeString (bstrName); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; }
if (SUCCEEDED(hr)) { hr = m_pADs->SetInfo(); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Failed to set options with 0x%x"), hr)); } } else { TCHAR szPath[2*MAX_PATH]; TCHAR szOptions[20]; LPTSTR lpEnd;
//
// Get the file system path
//
hr = GetPath (szPath, ARRAYSIZE(szPath));
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Failed to get path with 0x%x"), hr)); return hr; }
//
// Tack on gpt.ini
//
lpEnd = CheckSlash (szPath); hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("GPT.INI")); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetOptions: Could not copy GPO path with 0x%x"), hr)); return hr; }
//
// Convert the options to string format
//
_itot (dwResult, szOptions, 10);
//
// Set the options
//
if (!WritePrivateProfileString (TEXT("General"), TEXT("Options"), szOptions, szPath)) { hr = HRESULT_FROM_WIN32(GetLastError()); DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetOptions: Failed to set options with 0x%x"), hr)); return hr; }
//
// If this is the local GPO, trigger a policy refresh if appropriate
//
if (m_gpoType == GPOTypeLocal) { RefreshGroupPolicy (TRUE); RefreshGroupPolicy (FALSE); }
hr = S_OK;
} } else { hr = S_OK; }
return hr; }
//*************************************************************
//
// GetType()
//
// Purpose: Gets the GPO type
//
// Parameters: gpoType receives the type
//
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::GetType (GROUP_POLICY_OBJECT_TYPE *gpoType) {
//
// Check for initialization
//
if (!m_bInitialized) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetType: Called on an uninitialized object."))); return OLE_E_BLANK; }
//
// Check argument
//
if (!gpoType) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetType: Received a NULL ptr."))); return E_INVALIDARG; }
//
// Store type
//
*gpoType = m_gpoType;
return S_OK; }
//*************************************************************
//
// GetMachineName()
//
// Purpose: Gets the machine name of the remote GPO
//
// Parameters: pszName is a pointer to a buffer which receives the name
// cchMaxLength is the max size of the buffer
//
// Note: This method returns the name passed to OpenRemoteMachineGPO
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::GetMachineName (LPOLESTR pszName, int cchMaxLength) { HRESULT hr = S_OK;
//
// Check parameters
//
if (!pszName || (cchMaxLength <= 0)) return E_INVALIDARG;
if (!m_bInitialized) { return OLE_E_BLANK; }
if (m_pMachineName) { //
// Save the name
//
if ((lstrlen (m_pMachineName) + 1) <= cchMaxLength) { hr = StringCchCopy (pszName, cchMaxLength, m_pMachineName); } else { hr = E_OUTOFMEMORY; } } else { *pszName = TEXT('\0'); }
return hr; }
BOOL EnableWMIFilters( LPWSTR );
//*************************************************************
//
// GetPropertySheetPages()
//
// Purpose: Returns an array of property sheet pages for
// the callee to use. The callee needs to free
// the buffer with LocalFree when finished.
//
// Parameters: hPages receives a pointer to an array of page handles
// uPageCount receives the number of pages in hPages
//
// Return: S_OK if successful
//
//*************************************************************
STDMETHODIMP CGroupPolicyObject::GetPropertySheetPages (HPROPSHEETPAGE **hPages, UINT *uPageCount) { HPROPSHEETPAGE hTempPages[4]; HPROPSHEETPAGE *lpPages; PROPSHEETPAGE psp; UINT i, uTempPageCount = 0; HRESULT hr;
//
// Create the General property sheet
//
psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = 0; psp.hInstance = g_hInstance; psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPERTIES); psp.pfnDlgProc = PropertiesDlgProc; psp.lParam = (LPARAM) this;
hTempPages[uTempPageCount] = CreatePropertySheetPage(&psp);
if (!hTempPages[uTempPageCount]) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetPropertySheetPages: Failed to create property sheet page with %d."), GetLastError())); return E_FAIL; }
uTempPageCount++;
//
// If this is a DS GPO, then create the links, DS security, and WMI filter pages
//
if (m_gpoType == GPOTypeDS) { // Create the search for links page
psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = 0; psp.hInstance = g_hInstance; psp.pszTemplate = MAKEINTRESOURCE(IDD_GPE_LINKS); psp.pfnDlgProc = GPELinksDlgProc; psp.lParam = (LPARAM) this;
hTempPages[uTempPageCount] = CreatePropertySheetPage(&psp);
if (!hTempPages[uTempPageCount]) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetPropertySheetPages: Failed to create property sheet page with %d."), GetLastError())); // destroy the previous prop page
DestroyPropertySheetPage(hTempPages[uTempPageCount - 1]); return E_FAIL; }
uTempPageCount++;
//
// Load DSSec.dll
//
if (!m_hinstDSSec) { m_hinstDSSec = LoadLibrary (TEXT("dssec.dll")); }
if (m_hinstDSSec) {
if (!m_pfnDSCreateSecurityPage) { m_pfnDSCreateSecurityPage = (PFNDSCREATESECPAGE) GetProcAddress ( m_hinstDSSec, "DSCreateSecurityPage"); }
if (m_pfnDSCreateSecurityPage) {
//
// Call DSCreateSecurityPage
//
hr = m_pfnDSCreateSecurityPage (m_pDSPath, L"groupPolicyContainer", DSSI_IS_ROOT | ((m_dwFlags & GPO_OPEN_READ_ONLY) ? DSSI_READ_ONLY : 0), &hTempPages[uTempPageCount], ReadSecurityDescriptor, WriteSecurityDescriptor, (LPARAM)this);
if (SUCCEEDED(hr)) { uTempPageCount++; } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetPropertySheetPages: Failed to create DS security page with 0x%x."), hr)); } } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetPropertySheetPages: Failed to get function entry point with %d."), GetLastError())); } } else { DebugMsg((DM_WARNING, TEXT("CComponentData::CreatePropertyPages: Failed to load dssec.dll with %d."), GetLastError())); }
if ( EnableWMIFilters( m_pDSPath ) ) { // Create the WQL filter page
psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = 0; psp.hInstance = g_hInstance; psp.pszTemplate = MAKEINTRESOURCE(IDD_WQLFILTER); psp.pfnDlgProc = WQLFilterDlgProc; psp.lParam = (LPARAM) this;
hTempPages[uTempPageCount] = CreatePropertySheetPage(&psp);
if (!hTempPages[uTempPageCount]) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetPropertySheetPages: Failed to create property sheet page with %d."), GetLastError()));
for (i=0; i < uTempPageCount; i++) { DestroyPropertySheetPage(hTempPages[i]); } return E_FAIL; }
uTempPageCount++; } }
//
// Save the results
//
lpPages = (HPROPSHEETPAGE *)LocalAlloc (LPTR, sizeof(HPROPSHEETPAGE) * uTempPageCount);
if (!lpPages) { for (i=0; i < uTempPageCount; i++) { DestroyPropertySheetPage(hTempPages[i]); }
return E_OUTOFMEMORY; }
for (i=0; i < uTempPageCount; i++) { lpPages[i] = hTempPages[i]; }
*hPages = lpPages; *uPageCount = uTempPageCount;
return S_OK; }
///////////////////////////////////////////////////////////////////////////////
// //
// Internal methods //
// //
///////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CGroupPolicyObject::CreateContainer (LPOLESTR lpParent, LPOLESTR lpCommonName, BOOL bGPC) { HRESULT hr = E_FAIL; VARIANT var; IADs * pADs = NULL; IADsContainer * pADsContainer = NULL; IDispatch * pDispatch = NULL; BSTR bstrProvider = NULL; BSTR bstrName = NULL; TCHAR szTemp[MAX_PATH];
// test to see if the container already exists
{ szTemp[0] = 0; // scan lpParent to find the first instance of "CN="
LPTSTR lpSub = StrStr(lpParent, TEXT("CN=")); // insert CN=lpCommonName at that point
if (lpSub) { lstrcpyn(szTemp, lpParent, ((int)(lpSub - lpParent)) + 1); hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), TEXT("CN=")); if (SUCCEEDED(hr)) { hr = StringCchCat(szTemp, ARRAYSIZE(szTemp), lpCommonName); }
if (SUCCEEDED(hr)) { hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), TEXT(",")); }
if (SUCCEEDED(hr)) { hr = StringCchCat(szTemp, ARRAYSIZE(szTemp), lpSub); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Could not copy container name with 0x%x"), hr)); goto Exit; }
}
BSTR bstrTemp = SysAllocString( szTemp ); if ( bstrTemp == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to allocate BSTR memory"))); hr = E_OUTOFMEMORY; goto Exit; } hr = OpenDSObject(bstrTemp, IID_IADsContainer, (void **)&pADsContainer); SysFreeString( bstrTemp );
if (SUCCEEDED(hr)) { hr = ERROR_OBJECT_ALREADY_EXISTS; goto Exit; } }
//
// Bind to the parent object so we can create the container
//
BSTR bstrParent = SysAllocString( lpParent ); if ( bstrParent == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to allocate BSTR memory"))); hr = E_OUTOFMEMORY; goto Exit; } hr = OpenDSObject(bstrParent, IID_IADsContainer, (void **)&pADsContainer); SysFreeString( bstrParent );
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to get gpo container interface with 0x%x"), hr)); goto Exit; }
//
// Create the container (either GPC or normal container)
//
hr = StringCchCopy (szTemp, ARRAYSIZE(szTemp), TEXT("CN=")); if (SUCCEEDED(hr)) { hr = StringCchCat (szTemp, ARRAYSIZE(szTemp), lpCommonName); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Could not copy container name with 0x%x"), hr)); goto Exit; }
BSTR bstrTemp = SysAllocString( szTemp ); if ( bstrTemp == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to allocate BSTR memory"))); hr = E_OUTOFMEMORY; goto Exit; } BSTR bstrContainer = SysAllocString( (bGPC ? TEXT("groupPolicyContainer") : TEXT("container")) ); if ( bstrContainer == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to allocate BSTR memory"))); hr = E_OUTOFMEMORY; SysFreeString( bstrTemp ); goto Exit; } hr = pADsContainer->Create ( bstrContainer, bstrTemp, &pDispatch); SysFreeString( bstrTemp ); SysFreeString( bstrContainer ); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to create container with 0x%x"), hr)); goto Exit; }
//
// Query for the IADs interface so we can set the CN name and
// commit the changes
//
hr = pDispatch->QueryInterface(IID_IADs, (LPVOID *)&pADs);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: QI for IADs failed with 0x%x"), hr)); goto Exit; }
//
// Set the common name (aka "cn")
//
bstrName = SysAllocString (L"cn");
if (bstrName) { VariantInit(&var); var.vt = VT_BSTR; var.bstrVal = SysAllocString (lpCommonName);
hr = pADs->Put(bstrName, var);
VariantClear (&var); SysFreeString (bstrName); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreateContainer: Failed to put common name with 0x%x"), hr)); goto Exit; }
//
// Call SetInfo to commit the changes
//
hr = pADs->SetInfo();
Exit:
if (pDispatch) { pDispatch->Release(); }
if (pADs) { pADs->Release(); }
if (pADsContainer) { pADsContainer->Release(); }
return hr; }
STDMETHODIMP CGroupPolicyObject::SetDisplayNameI (IADs * pADs, LPOLESTR lpDisplayName, LPOLESTR lpGPTPath, BOOL bUpdateDisplayVar) { HRESULT hr = E_FAIL; BSTR bstrName; VARIANT var; LPOLESTR lpNewName; LPTSTR lpPath, lpEnd; DWORD dwSize;
//
// Make a copy of the display name and limit it to MAX_FRIENDLYNAME characters
//
dwSize = lstrlen(lpDisplayName);
if (dwSize > (MAX_FRIENDLYNAME - 1)) { dwSize = (MAX_FRIENDLYNAME - 1); }
lpNewName = (LPOLESTR) LocalAlloc (LPTR, (dwSize + 2) * sizeof(OLECHAR));
if (!lpNewName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to allocate memory for display name"))); hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
lstrcpyn (lpNewName, lpDisplayName, (dwSize + 1));
//
// Set the display name
//
bstrName = SysAllocString (GPO_NAME_PROPERTY);
if (!bstrName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to allocate memory"))); LocalFree (lpNewName); return ERROR_OUTOFMEMORY; }
VariantInit(&var); var.vt = VT_BSTR; var.bstrVal = SysAllocString (lpNewName);
if (var.bstrVal) { hr = pADs->Put(bstrName, var); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; }
SysFreeString (bstrName); VariantClear (&var);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to put display name with 0x%x"), hr)); LocalFree (lpNewName); goto Exit; }
//
// Commit the changes
//
hr = pADs->SetInfo();
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to commit changes with 0x%x"), hr)); LocalFree (lpNewName); goto Exit; }
//
// Put the display name in the gpt.ini file also
//
ULONG ulNoChars;
ulNoChars = lstrlen(lpGPTPath) + 10; lpPath = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (lpPath) { hr = StringCchCopy(lpPath, ulNoChars, lpGPTPath); if (SUCCEEDED(hr)) { lpEnd = CheckSlash(lpPath); hr = StringCchCat (lpPath, ulNoChars, TEXT("gpt.ini")); }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Could not copy GPO path with 0x%x"), hr)); LocalFree(lpPath); LocalFree (lpNewName); goto Exit; }
if (!WritePrivateProfileString (TEXT("General"), GPO_NAME_PROPERTY, lpNewName, lpPath)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetDisplayNameI: Failed to write display name to gpt.ini with 0x%x"), hr)); }
LocalFree (lpPath); }
//
// Update the member variable if appropriate
//
if (bUpdateDisplayVar) { //
// Update the display name variable
//
if (m_pDisplayName) { LocalFree (m_pDisplayName); m_pDisplayName = NULL; }
m_pDisplayName = lpNewName; } else { LocalFree (lpNewName); }
Exit:
return hr; }
STDMETHODIMP CGroupPolicyObject::SetGPOInfo (LPOLESTR lpGPO, LPOLESTR lpDisplayName, LPOLESTR lpGPTPath) { HRESULT hr = E_FAIL; IADs * pADs = NULL; BSTR bstrName; VARIANT var; TCHAR szDefaultName[MAX_FRIENDLYNAME];
//
// Bind to the GPO container
//
hr = OpenDSObject(lpGPO, IID_IADs, (void **)&pADs);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to get gpo interface with 0x%x"), hr)); goto Exit; }
//
// Set the display name
//
GetNewGPODisplayName (szDefaultName, ARRAYSIZE(szDefaultName));
hr = SetDisplayNameI (pADs, (lpDisplayName ? lpDisplayName : szDefaultName), lpGPTPath, FALSE);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to set display name"))); goto Exit; }
//
// Set the GPT location
//
bstrName = SysAllocString (GPT_PATH_PROPERTY);
if (bstrName) { VariantInit(&var); var.vt = VT_BSTR; var.bstrVal = SysAllocString (lpGPTPath);
if (var.bstrVal) { hr = pADs->Put(bstrName, var); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; }
VariantClear (&var); SysFreeString (bstrName); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to save GPT path with 0x%x"), hr)); goto Exit; }
//
// Set the version number
//
bstrName = SysAllocString (GPO_VERSION_PROPERTY);
if (bstrName) { VariantInit(&var); var.vt = VT_I4; var.lVal = 0;
hr = pADs->Put(bstrName, var);
VariantClear (&var); SysFreeString (bstrName); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to set version number with 0x%x"), hr)); goto Exit; }
//
// Set the functionality version number
//
bstrName = SysAllocString (GPO_FUNCTION_PROPERTY);
if (bstrName) { VariantInit(&var); var.vt = VT_I4; var.lVal = GPO_FUNCTIONALITY_VERSION;
hr = pADs->Put(bstrName, var);
VariantClear (&var); SysFreeString (bstrName); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to set functionality version number with 0x%x"), hr)); goto Exit; }
//
// Set the options
//
bstrName = SysAllocString (GPO_OPTIONS_PROPERTY);
if (bstrName) { VariantInit(&var); var.vt = VT_I4; var.lVal = 0;
hr = pADs->Put(bstrName, var);
VariantClear (&var); SysFreeString (bstrName); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to allocate memory"))); hr = ERROR_OUTOFMEMORY; }
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetGPOInfo: Failed to set options with 0x%x"), hr)); goto Exit; }
//
// Commit the changes
//
hr = pADs->SetInfo();
Exit:
if (pADs) { pADs->Release(); }
return hr; }
STDMETHODIMP CGroupPolicyObject::CheckFSWriteAccess (LPOLESTR lpLocalGPO) { TCHAR szBuffer[MAX_PATH]; LPTSTR lpEnd; HRESULT hr;
hr = StringCchCopy (szBuffer, ARRAYSIZE(szBuffer), lpLocalGPO); if (SUCCEEDED(hr)) { lpEnd = CheckSlash (szBuffer); hr = StringCchCat (szBuffer, ARRAYSIZE(szBuffer), TEXT("gpt.ini")); }
if (SUCCEEDED(hr)) { if (!WritePrivateProfileString (TEXT("General"), TEXT("AccessCheck"), TEXT("test"), szBuffer)) { hr = HRESULT_FROM_WIN32(GetLastError()); } else { WritePrivateProfileString (TEXT("General"), TEXT("AccessCheck"), NULL, szBuffer); hr = S_OK; } }
return hr; }
STDMETHODIMP CGroupPolicyObject::GetSecurityDescriptor (IADs *pADs, SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR *pSD) { HRESULT hr; VARIANT var; LPWSTR pszSDProperty = L"nTSecurityDescriptor"; IDirectoryObject *pDsObject = NULL; IADsObjectOptions *pOptions = NULL; PADS_ATTR_INFO pSDAttributeInfo = NULL; DWORD dwAttributesReturned;
//
// Retreive the DS Object interface
//
hr = pADs->QueryInterface(IID_IDirectoryObject, (void**)&pDsObject);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetSecurityDescriptor: Failed to get gpo DS object interface with 0x%x"), hr)); goto Exit; }
//
// Retreive the DS Object Options interface
//
hr = pADs->QueryInterface(IID_IADsObjectOptions, (void**)&pOptions);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetSecurityDescriptor: Failed to get DS object options interface with 0x%x"), hr)); goto Exit; }
//
// Set the SECURITY_INFORMATION mask
//
VariantInit(&var); var.vt = VT_I4; var.lVal = si;
hr = pOptions->SetOption(ADS_OPTION_SECURITY_MASK, var);
VariantClear (&var);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetSecurityDescriptor: Failed to set ADSI security options with 0x%x"), hr)); goto Exit; }
//
// Read the security descriptor
//
hr = pDsObject->GetObjectAttributes(&pszSDProperty, 1, &pSDAttributeInfo, &dwAttributesReturned);
if (SUCCEEDED(hr) && !pSDAttributeInfo) { hr = E_ACCESSDENIED; // This happens for SACL if no SecurityPrivilege
}
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetSecurityDescriptor: Failed to get DS object attributes with 0x%x"), hr)); goto Exit; }
//
// Duplicate the security descriptor
//
*pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, pSDAttributeInfo->pADsValues->SecurityDescriptor.dwLength);
if (!*pSD) { hr = HRESULT_FROM_WIN32(GetLastError()); DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetSecurityDescriptor: Failed to allocate memory with 0x%x"), hr)); goto Exit; }
CopyMemory(*pSD, pSDAttributeInfo->pADsValues->SecurityDescriptor.lpValue, pSDAttributeInfo->pADsValues->SecurityDescriptor.dwLength);
Exit:
if (pSDAttributeInfo) { FreeADsMem(pSDAttributeInfo); }
if (pOptions) { pOptions->Release(); }
if (pDsObject) { pDsObject->Release(); }
return hr; }
BOOL CGroupPolicyObject::EnableSecurityPrivs(void) { BOOL bResult; HANDLE hToken; HANDLE hNewToken; BYTE buffer[sizeof(PRIVILEGE_SET) + sizeof(LUID_AND_ATTRIBUTES)]; PTOKEN_PRIVILEGES pPrivileges = (PTOKEN_PRIVILEGES)buffer;
//
// Get a token and enable the Security and Take Ownership
// privileges, if possible.
//
bResult = OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, TRUE, &hToken);
if (!bResult) { bResult = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken); }
if (!bResult) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::EnableSecurityPrivs: Failed to get both thread and process token with %d"), GetLastError())); return FALSE; }
bResult = DuplicateTokenEx(hToken, TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, NULL, // PSECURITY_ATTRIBUTES
SecurityImpersonation, // SECURITY_IMPERSONATION_LEVEL
TokenImpersonation, // TokenType
&hNewToken); // Duplicate token
if (!bResult) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::EnableSecurityPrivs: Failed to duplicate the token with %d"), GetLastError())); CloseHandle(hToken); return FALSE; }
//
// PRIVILEGE_SET contains 1 LUID_AND_ATTRIBUTES already, so
// this is enough for 2 LUID_AND_ATTRIBUTES (2 privileges).
//
CloseHandle(hToken); hToken = hNewToken;
pPrivileges->PrivilegeCount = 2; pPrivileges->Privileges[0].Luid = RtlConvertUlongToLuid(SE_SECURITY_PRIVILEGE); pPrivileges->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; pPrivileges->Privileges[1].Luid = RtlConvertUlongToLuid(SE_TAKE_OWNERSHIP_PRIVILEGE); pPrivileges->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED;
bResult = AdjustTokenPrivileges(hToken, // TokenHandle
FALSE, // DisableAllPrivileges
pPrivileges,// NewState
0, // BufferLength
NULL, // PreviousState
NULL); // ReturnLength
if (!bResult) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::EnableSecurityPrivs: Failed to AdjustTokenPrivileges with %d"), GetLastError())); CloseHandle(hToken); return FALSE; }
//
// Set the new thread token
//
if ( !SetThreadToken(NULL, hToken) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::EnableSecurityPrivs: Failed to SetThreadToken with %d"), GetLastError() ) ); CloseHandle(hToken); return FALSE; }
CloseHandle(hToken);
return TRUE; }
DWORD CGroupPolicyObject::EnableInheritance (PACL pAcl) { WORD wIndex; DWORD dwResult = ERROR_SUCCESS; ACE_HEADER *pAceHeader;
if (pAcl) { //
// Loop through the ACL looking at each ACE entry
//
for (wIndex = 0; wIndex < pAcl->AceCount; wIndex++) {
if (!GetAce (pAcl, (DWORD)wIndex, (LPVOID *)&pAceHeader)) { dwResult = GetLastError(); DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::EnableInheritance: GetAce failed with %d"), dwResult)); goto Exit; }
//
// Turn on the inheritance flags
//
pAceHeader->AceFlags |= (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE); } }
Exit:
return dwResult; }
//
// This method will convert a DS security access list into a
// file system security access list and actually set the security
//
DWORD CGroupPolicyObject::SetSysvolSecurity (LPTSTR lpFileSysPath, SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR pSD) { return SetSysvolSecurityFromDSSecurity( lpFileSysPath, si, pSD); }
HRESULT WINAPI CGroupPolicyObject::ReadSecurityDescriptor (LPCWSTR lpGPOPath, SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR *pSD, LPARAM lpContext) { CGroupPolicyObject * pGPO; HRESULT hr;
//
// Convert lpContext into a pGPO
//
pGPO = (CGroupPolicyObject*)lpContext;
if (!pGPO) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::ReadSecurityDescriptor: GPO interface pointer is NULL"))); return E_FAIL; }
hr = pGPO->GetSecurityDescriptor (pGPO->m_pADs, si, pSD);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::ReadSecurityDescriptor: GetSecurityDescriptor returned 0x%x"), hr)); }
return (hr); }
HRESULT WINAPI CGroupPolicyObject::WriteSecurityDescriptor (LPCWSTR lpGPOPath, SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR pSD, LPARAM lpContext) { CGroupPolicyObject * pGPO; IDirectoryObject *pDsObject = NULL; IADsObjectOptions *pOptions = NULL; DWORD dwResult = ERROR_SUCCESS; HRESULT hr; VARIANT var; ADSVALUE attributeValue; ADS_ATTR_INFO attributeInfo; DWORD dwAttributesModified; DWORD dwSDLength; PSECURITY_DESCRIPTOR psd = NULL, pSDOrg = NULL; SECURITY_DESCRIPTOR_CONTROL sdControl = 0; DWORD dwRevision; PACL pAcl; BOOL bPresent, bDefault;
//
// Convert lpContext into a pGPO
//
pGPO = (CGroupPolicyObject*)lpContext;
if (!pGPO) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: GPO interface pointer is NULL"))); return E_FAIL; }
//
// Get the original security descriptor from the DS
//
hr = pGPO->GetSecurityDescriptor (pGPO->m_pADs, si, &pSDOrg);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to query the security descriptor with 0x%x"), hr)); goto Exit; }
//
// Retreive the DS Object interface
//
hr = pGPO->m_pADs->QueryInterface(IID_IDirectoryObject, (void**)&pDsObject);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to get DS object interface with 0x%x"), hr)); goto Exit; }
//
// Retreive the DS Object Options interface
//
hr = pGPO->m_pADs->QueryInterface(IID_IADsObjectOptions, (void**)&pOptions);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to get DS object options interface with 0x%x"), hr)); goto Exit; }
//
// Set the SECURITY_INFORMATION mask
//
VariantInit(&var); var.vt = VT_I4; var.lVal = si;
hr = pOptions->SetOption(ADS_OPTION_SECURITY_MASK, var);
VariantClear (&var);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to get DS object options interface with 0x%x"), hr)); goto Exit; }
//
// Need the total size of the security descriptor
//
dwSDLength = GetSecurityDescriptorLength(pSD);
//
// If necessary, make a self-relative copy of the security descriptor
//
if (!GetSecurityDescriptorControl(pSD, &sdControl, &dwRevision)) { dwResult = GetLastError(); DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to get security descriptor control with %d"), dwResult)); hr = HRESULT_FROM_WIN32(dwResult); goto Exit; }
if (!(sdControl & SE_SELF_RELATIVE)) { psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwSDLength);
if (!psd) { dwResult = GetLastError(); DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to allocate memory for new SD with %d"), dwResult)); hr = HRESULT_FROM_WIN32(dwResult); goto Exit; }
if (!MakeSelfRelativeSD(pSD, psd, &dwSDLength)) { dwResult = GetLastError(); DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: MakeSelfRelativeSD failed with %d"), dwResult)); hr = HRESULT_FROM_WIN32(dwResult); goto Exit; }
//
// Point to the self-relative copy
//
pSD = psd; }
//
// By default, the general page will set things up so the inheritance
// is for the root container only. We really want the inheritance to
// be for the root and all sub-containers, so run through the
// DACL and SACL and set the new inheritance flags
//
if (si & DACL_SECURITY_INFORMATION) { if (!GetSecurityDescriptorDacl(pSD, &bPresent, &pAcl, &bDefault)) { dwResult = GetLastError(); DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: GetSecurityDescriptorDacl failed with %d"), dwResult)); hr = HRESULT_FROM_WIN32(dwResult); goto Exit; }
dwResult = pGPO->EnableInheritance (pAcl);
if (dwResult != ERROR_SUCCESS) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: EnableInheritance failed with %d"), dwResult)); hr = HRESULT_FROM_WIN32(dwResult); goto Exit; } }
if (si & SACL_SECURITY_INFORMATION) { if (!GetSecurityDescriptorSacl(pSD, &bPresent, &pAcl, &bDefault)) { dwResult = GetLastError(); DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: GetSecurityDescriptorSacl failed with %d"), dwResult)); hr = HRESULT_FROM_WIN32(dwResult); goto Exit; }
dwResult = pGPO->EnableInheritance (pAcl);
if (dwResult != ERROR_SUCCESS) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: EnableInheritance failed with %d"), dwResult)); hr = HRESULT_FROM_WIN32(dwResult); goto Exit; } }
//
// Set the DS security
//
attributeValue.dwType = ADSTYPE_NT_SECURITY_DESCRIPTOR; attributeValue.SecurityDescriptor.dwLength = dwSDLength; attributeValue.SecurityDescriptor.lpValue = (LPBYTE)pSD;
attributeInfo.pszAttrName = L"nTSecurityDescriptor"; attributeInfo.dwControlCode = ADS_ATTR_UPDATE; attributeInfo.dwADsType = ADSTYPE_NT_SECURITY_DESCRIPTOR; attributeInfo.pADsValues = &attributeValue; attributeInfo.dwNumValues = 1;
hr = pDsObject->SetObjectAttributes(&attributeInfo, 1, &dwAttributesModified);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to set DS security with 0x%x"), hr)); goto Exit; }
//
// Set the sysvol security
//
dwResult = pGPO->SetSysvolSecurity (pGPO->m_pFileSysPath, si, pSD);
if (dwResult != ERROR_SUCCESS) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to set the security for the file system portion <%s> with %d"), pGPO->m_pFileSysPath, dwResult)); hr = HRESULT_FROM_WIN32(dwResult);
//
// Restore the orignal DS security
//
attributeValue.dwType = ADSTYPE_NT_SECURITY_DESCRIPTOR; attributeValue.SecurityDescriptor.dwLength = GetSecurityDescriptorLength(pSDOrg); attributeValue.SecurityDescriptor.lpValue = (LPBYTE)pSDOrg;
attributeInfo.pszAttrName = L"nTSecurityDescriptor"; attributeInfo.dwControlCode = ADS_ATTR_UPDATE; attributeInfo.dwADsType = ADSTYPE_NT_SECURITY_DESCRIPTOR; attributeInfo.pADsValues = &attributeValue; attributeInfo.dwNumValues = 1;
if (FAILED(pDsObject->SetObjectAttributes(&attributeInfo, 1, &dwAttributesModified))) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WriteSecurityDescriptor: Failed to restore DS security"))); }
goto Exit; }
Exit:
if (pDsObject) { pDsObject->Release(); }
if (pOptions) { pOptions->Release(); }
if (psd) { LocalFree(psd); }
if (pSDOrg) { LocalFree(pSDOrg); }
return (hr); }
STDMETHODIMP CGroupPolicyObject::CleanUp (void) {
if (m_pUser) { m_pUser->Release(); m_pUser = NULL; }
if (m_pMachine) { m_pMachine->Release(); m_pMachine = NULL; }
if (m_pName) { LocalFree (m_pName); m_pName = NULL; }
if (m_pDisplayName) { LocalFree (m_pDisplayName); m_pDisplayName = NULL; }
if (m_pDSPath) { LocalFree (m_pDSPath); m_pDSPath = NULL; }
if (m_pFileSysPath) { LocalFree (m_pFileSysPath); m_pFileSysPath = NULL; }
if (m_pMachineName) { LocalFree (m_pMachineName); m_pMachineName = NULL; }
if (m_pADs) { m_pADs->Release(); m_pADs = NULL; }
m_gpoType = GPOTypeLocal; m_bInitialized = FALSE;
return S_OK; }
STDMETHODIMP CGroupPolicyObject::RefreshGroupPolicy (BOOL bMachine) { HINSTANCE hInstUserEnv; PFNREFRESHPOLICY pfnRefreshPolicy;
//
// Load the function we need
//
hInstUserEnv = LoadLibrary (TEXT("userenv.dll"));
if (!hInstUserEnv) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::RefreshGroupPolicy: Failed to load userenv with %d."), GetLastError())); return (HRESULT_FROM_WIN32(GetLastError())); }
pfnRefreshPolicy = (PFNREFRESHPOLICY)GetProcAddress (hInstUserEnv, "RefreshPolicy");
if (!pfnRefreshPolicy) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::RefreshGroupPolicy: Failed to find RefreshPolicy with %d."), GetLastError())); FreeLibrary (hInstUserEnv); return (HRESULT_FROM_WIN32(GetLastError())); }
//
// Refresh policy
//
pfnRefreshPolicy (bMachine);
//
// Clean up
//
FreeLibrary (hInstUserEnv);
return S_OK; }
BSTR ParseDomainName( LPWSTR szDomain ) { BSTR bstrDomain = 0;
if ( szDomain ) { WCHAR szXDomain[MAX_PATH*2]; DWORD dwSize = MAX_PATH*2;
if ( TranslateName( szDomain, NameUnknown, NameCanonical, szXDomain, &dwSize ) ) { LPWSTR szTemp = wcschr( szXDomain, L'/' );
if ( szTemp ) { *szTemp = 0; }
bstrDomain = SysAllocString( szXDomain ); } }
DebugMsg((DM_VERBOSE, TEXT("ParseDomainName: *** %s ***"), bstrDomain ? bstrDomain : L"" ));
return bstrDomain; }
BSTR ParseDomainName2( LPWSTR szDSObject ) { BSTR bstrDomain = 0;
if ( !szDSObject ) { return bstrDomain; }
if ( CompareString( LOCALE_INVARIANT, NORM_IGNORECASE, szDSObject, 7, L"LDAP://", 7 ) == CSTR_EQUAL ) { szDSObject += 7; }
if ( *szDSObject ) { WCHAR szXDomain[MAX_PATH*2]; DWORD dwSize = MAX_PATH*2;
if ( TranslateName( szDSObject, NameUnknown, NameCanonical, szXDomain, &dwSize ) ) { LPWSTR szTemp = wcschr( szXDomain, L'/' );
if ( szTemp ) { *szTemp = 0; }
bstrDomain = SysAllocString( szXDomain ); } }
DebugMsg((DM_VERBOSE, TEXT("ParseDomainName2: *** %s ***"), bstrDomain ? bstrDomain : L"" ));
return bstrDomain; }
INT_PTR CALLBACK CGroupPolicyObject::WQLFilterDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { CGroupPolicyObject* pGPO;
switch (message) { case WM_INITDIALOG: { HRESULT hr; BSTR bstrName; VARIANT var; LPTSTR lpDisplayName;
pGPO = (CGroupPolicyObject*) (((LPPROPSHEETPAGE)lParam)->lParam); SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pGPO);
//
// Set the defaults
//
pGPO->m_pTempFilterString = NULL; CheckDlgButton (hDlg, IDC_NONE, BST_CHECKED); EnableWindow (GetDlgItem(hDlg, IDC_FILTER_NAME), FALSE); EnableWindow (GetDlgItem(hDlg, IDC_FILTER_BROWSE), FALSE);
if (pGPO->m_dwFlags & GPO_OPEN_READ_ONLY) { EnableWindow (GetDlgItem(hDlg, IDC_NONE), FALSE); EnableWindow (GetDlgItem(hDlg, IDC_THIS_FILTER), FALSE); }
//
// Query for the filter
//
bstrName = SysAllocString (GPO_WQLFILTER_PROPERTY);
if (!bstrName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to allocate memory"))); break; }
VariantInit(&var);
hr = pGPO->m_pADs->Get(bstrName, &var);
//
// If we find a filter, initialize the UI and save the filter string in the
// temporary buffer
//
if (SUCCEEDED(hr)) { //
// Check if we found a null filter (defined as one space character)
//
if (*var.bstrVal != TEXT(' ')) { ULONG ulNoChars = lstrlen(var.bstrVal) + 1;
pGPO->m_pTempFilterString = new TCHAR [ulNoChars];
if (!pGPO->m_pTempFilterString) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to allocate memory for filter"))); SysFreeString (bstrName); VariantClear (&var); break; }
hr = StringCchCopy (pGPO->m_pTempFilterString, ulNoChars, var.bstrVal); ASSERT(SUCCEEDED(hr));
lpDisplayName = GetWMIFilterDisplayName (hDlg, pGPO->m_pTempFilterString, TRUE, FALSE);
if (lpDisplayName) { SetDlgItemText (hDlg, IDC_FILTER_NAME, lpDisplayName); delete [] lpDisplayName;
CheckDlgButton (hDlg, IDC_NONE, BST_UNCHECKED); CheckDlgButton (hDlg, IDC_THIS_FILTER, BST_CHECKED); EnableWindow (GetDlgItem(hDlg, IDC_FILTER_NAME), TRUE);
if (!(pGPO->m_dwFlags & GPO_OPEN_READ_ONLY)) { EnableWindow (GetDlgItem(hDlg, IDC_FILTER_BROWSE), TRUE); } } } } else { if (hr != E_ADS_PROPERTY_NOT_FOUND) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to query filter with 0x%x"), hr)); } }
SysFreeString (bstrName); VariantClear (&var);
break; }
case WM_COMMAND: { pGPO = (CGroupPolicyObject *) GetWindowLongPtr (hDlg, DWLP_USER);
if (!pGPO) { break; }
if (LOWORD(wParam) == IDC_FILTER_BROWSE) { LPTSTR lpDisplayName = NULL, lpFilter = NULL; WCHAR szDomain[2*MAX_PATH]; HRESULT hr = pGPO->GetPath( szDomain, ARRAYSIZE( szDomain ) ); if ( FAILED( hr ) ) { break; }
BSTR bstrDomain = ParseDomainName2( szDomain );
if (!GetWMIFilter(FALSE, hDlg, TRUE, &lpDisplayName, &(pGPO->m_pTempFilterString), bstrDomain )) { SysFreeString( bstrDomain ); break; }
SysFreeString( bstrDomain );
if (!(pGPO->m_pTempFilterString)) { SetDlgItemText (hDlg, IDC_FILTER_NAME, TEXT(""));
EnableWindow (GetDlgItem(hDlg, IDC_FILTER_NAME), FALSE); EnableWindow (GetDlgItem(hDlg, IDC_FILTER_BROWSE), FALSE); CheckDlgButton (hDlg, IDC_NONE, BST_CHECKED); CheckDlgButton (hDlg, IDC_THIS_FILTER, BST_UNCHECKED); SetFocus (GetDlgItem(hDlg, IDC_NONE));
SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); } else { SetDlgItemText (hDlg, IDC_FILTER_NAME, lpDisplayName); delete [] lpDisplayName;
SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); } }
if (LOWORD(wParam) == IDC_NONE) { EnableWindow (GetDlgItem(hDlg, IDC_FILTER_NAME), FALSE); EnableWindow (GetDlgItem(hDlg, IDC_FILTER_BROWSE), FALSE);
if (pGPO->m_pTempFilterString) { delete [] pGPO->m_pTempFilterString; pGPO->m_pTempFilterString = NULL; } } else if (LOWORD(wParam) == IDC_THIS_FILTER) { EnableWindow (GetDlgItem(hDlg, IDC_FILTER_NAME), TRUE); EnableWindow (GetDlgItem(hDlg, IDC_FILTER_BROWSE), TRUE); }
break; }
case WM_NOTIFY: { pGPO = (CGroupPolicyObject *) GetWindowLongPtr (hDlg, DWLP_USER);
if (!pGPO) { break; }
switch (((NMHDR FAR*)lParam)->code) { case PSN_APPLY: { HRESULT hr; BSTR bstrName; VARIANT var;
//
// Save the current WQL filter
//
bstrName = SysAllocString (GPO_WQLFILTER_PROPERTY);
if (!bstrName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to allocate memory"))); break; }
VariantInit(&var); var.vt = VT_BSTR; var.bstrVal = SysAllocString (pGPO->m_pTempFilterString ? pGPO->m_pTempFilterString : TEXT(" "));
if (var.bstrVal) { hr = pGPO->m_pADs->Put(bstrName, var); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to allocate memory"))); SysFreeString (bstrName); break; }
SysFreeString (bstrName); VariantClear (&var);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to put display name with 0x%x"), hr)); break; }
//
// Commit the changes
//
hr = pGPO->m_pADs->SetInfo();
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::WQLFilterDlgProc: Failed to commit changes with 0x%x"), hr)); break; }
//
// Free the filter string if appropriate
//
if (((PSHNOTIFY *)lParam)->lParam) { if (pGPO->m_pTempFilterString) { delete [] pGPO->m_pTempFilterString; pGPO->m_pTempFilterString = NULL; } }
break; }
case PSN_RESET: { if (pGPO->m_pTempFilterString) { delete [] pGPO->m_pTempFilterString; pGPO->m_pTempFilterString = NULL; } break; } } break; }
case WM_HELP: // F1
WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (ULONG_PTR) (LPSTR) aWQLFilterHelpIds); break;
case WM_CONTEXTMENU: // right mouse click
WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU, (ULONG_PTR) (LPSTR) aWQLFilterHelpIds); return (TRUE);
default: break; }
return FALSE; }
#define MAX_BUTTON_LEN 64
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
INT_PTR CALLBACK CGroupPolicyObject::GPELinksDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { GLPARAM * pglp = NULL; switch (message) { case WM_INITDIALOG: { LV_COLUMN lvc = {LVCF_WIDTH}; RECT rc; HWND hList = GetDlgItem(hDlg, IDC_RESULTLIST);
// Allocate the per dialog structure
pglp = (GLPARAM*)LocalAlloc (LPTR, sizeof(GLPARAM)); if (pglp) { pglp->pGPO = (CGroupPolicyObject*) (((LPPROPSHEETPAGE)lParam)->lParam); SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pglp); pglp->pGPO->FillDomainList (GetDlgItem(hDlg, IDC_CBDOMAIN)); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GPELinksDlgProc: Failed to LocalAlloc in WM_INITDIALOG"))); }
// Set the Columns, in the list view
if (IsWindow(hList)) { SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_LABELTIP, LVS_EX_LABELTIP);
GetClientRect(hList, &rc); lvc.cx = (rc.right - rc.left); ListView_InsertColumn(hList, 0, &lvc); }
// Show icon in the corner
Animate_Open(GetDlgItem(hDlg, IDAC_FIND), MAKEINTRESOURCE(IDA_FIND)); break; }
case WM_COMMAND: { pglp = (GLPARAM *) GetWindowLongPtr (hDlg, DWLP_USER); if (!pglp) { break; }
if ((IDC_CBDOMAIN == LOWORD(wParam)) && ((CBN_SELCHANGE == HIWORD(wParam)) || (CBN_SELENDOK == HIWORD(wParam)))) { // Clear the list view
pglp->fAbort = TRUE; SendDlgItemMessage(hDlg, IDC_RESULTLIST, LVM_DELETEALLITEMS, 0, 0L); break; }
// If the IDC_ACTION was clicked then do search
if ((IDC_ACTION == LOWORD(wParam)) && (BN_CLICKED == HIWORD(wParam))) { // If we are have been asked to start a search, create the thread to do so
if (!pglp->fFinding) { HANDLE hThread = NULL; DWORD dwThreadId = 0; GLTHREADPARAM * pgltp = NULL; int nCurSel = 0;
// Make sure something has been selected in the combo box
nCurSel = (int)SendDlgItemMessage (hDlg, IDC_CBDOMAIN, CB_GETCURSEL, 0, 0L); if (CB_ERR == nCurSel) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GPELinksDlgProc: There was no Domain selected in the combo box. Exiting."))); break; }
// Allocate the Thread Param structure
pgltp = (GLTHREADPARAM*)LocalAlloc (LPTR, sizeof(GLTHREADPARAM)); if (!pgltp) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GPELinksDlgProc: Failed to LocalAlloc Thread Param structure"))); break; }
pgltp->hDlg = hDlg; pgltp->pGPO = pglp->pGPO; pgltp->pfAbort = &pglp->fAbort;
pgltp->pszLDAPName = (LPOLESTR)SendDlgItemMessage (hDlg, IDC_CBDOMAIN, CB_GETITEMDATA, nCurSel, 0L);
if (!pgltp->pszLDAPName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GPELinksDlgProc: The LDAP name buffer was NULL."))); LocalFree(pgltp); break; }
pgltp->pszLDAPName = MakeFullPath (pgltp->pszLDAPName, pglp->pGPO->m_pMachineName);
// Unset the abort flag
pglp->fAbort = FALSE;
// Clear the list view
SendDlgItemMessage(hDlg, IDC_RESULTLIST, LVM_DELETEALLITEMS, 0, 0L);
// Fire off the thread to fill the list view
hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)GLThreadFunc, pgltp, 0, &dwThreadId); if (!hThread) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GPELinksDlgProc: Could not create the search thread."))); LocalFree(pgltp); break; } CloseHandle (hThread);
// Change the text on the button to "Stop"
SendMessage (hDlg, PDM_CHANGEBUTTONTEXT, 0, 0L); } else { // The user wants to stop the search
pglp->fAbort = TRUE; } } break; }
case PDM_CHANGEBUTTONTEXT: { TCHAR szButtonText[MAX_BUTTON_LEN] = {0};
pglp = (GLPARAM *) GetWindowLongPtr (hDlg, DWLP_USER); if (!pglp) { break; }
if (!pglp->fFinding) Animate_Play(GetDlgItem(hDlg, IDAC_FIND), 0, -1, -1); else Animate_Stop(GetDlgItem(hDlg, IDAC_FIND));
// Set the button to show appropriate text
LoadString (g_hInstance, pglp->fFinding ? IDS_FINDNOW: IDS_STOP, szButtonText, ARRAYSIZE(szButtonText)); SetDlgItemText (hDlg, IDC_ACTION, szButtonText);
// Flip the toggle
pglp->fFinding = !pglp->fFinding; break; }
case WM_NOTIFY: { pglp = (GLPARAM *) GetWindowLongPtr (hDlg, DWLP_USER); if (!pglp) { break; }
switch (((NMHDR FAR*)lParam)->code) {
// In case thr user wants to cancel, bail from the thread
case PSN_QUERYCANCEL: pglp->fAbort = TRUE; break;
// In case thr user wants to close the prop sheet, bail from the thread
case PSN_APPLY: case PSN_RESET: { int nCount = 0;
PSHNOTIFY * pNotify = (PSHNOTIFY *) lParam;
// User just hit the Apply button don't destroy everything.
if (!pNotify->lParam) { SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR); return TRUE; }
pglp->fAbort = TRUE;
// When the dialog is going away, delete all the data that was stored with each CB item in
// FillDomainList() are freed
if (IsWindow(GetDlgItem(hDlg, IDC_CBDOMAIN))) { nCount = (int) SendDlgItemMessage(hDlg, IDC_CBDOMAIN, CB_GETCOUNT, 0, 0L); for (int nIndex = 0; nIndex < nCount; nIndex++) { LPOLESTR pszStr; pszStr = (LPOLESTR)SendDlgItemMessage(hDlg, IDC_CBDOMAIN, CB_GETITEMDATA, nIndex, 0L); if (pszStr) delete [] pszStr; } }
// Free the per dialog structure
LocalFree (pglp); SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) NULL); Animate_Close(GetDlgItem(hDlg, IDAC_FIND)); break; } } break; }
case WM_HELP: // F1
WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (ULONG_PTR) (LPSTR) aLinkHelpIds); break;
case WM_CONTEXTMENU: // right mouse click
WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU, (ULONG_PTR) (LPSTR) aLinkHelpIds); return (TRUE);
default: break; }
return FALSE; }
//////////////////////////////////////////////////////////////////////////////
// The thread that will look call the recursive find function. This function will clean up
// the param structure that has been passed in
//////////////////////////////////////////////////////////////////////////////
DWORD WINAPI CGroupPolicyObject::GLThreadFunc(GLTHREADPARAM * pgltp) { LPTSTR lpGPO; DWORD dwRet; HINSTANCE hInstance = LoadLibrary(TEXT("GPEdit.dll")); HRESULT hr;
//
// Initialize COM
//
hr = CoInitialize(NULL);
if (FAILED(hr)) { return 0L; }
//
// Make sure we have a thread param structure
//
if (pgltp) {
pgltp->pGPO->AddRef();
lpGPO = MakeNamelessPath (pgltp->pGPO->m_pDSPath);
if (lpGPO) { //
// Check if the user wants to abort. Otherwise make recursive call
//
if (!*(pgltp->pfAbort)) { dwRet = pgltp->pGPO->FindLinkInDomain(pgltp, lpGPO); }
if ((!*(pgltp->pfAbort)) && dwRet) { pgltp->pGPO->FindLinkInSite(pgltp, lpGPO); }
if (IsWindow(GetDlgItem(pgltp->hDlg, IDC_RESULTLIST))) { ListView_SetItemState(GetDlgItem(pgltp->hDlg, IDC_RESULTLIST), 0, LVIS_SELECTED |LVIS_FOCUSED, LVIS_SELECTED |LVIS_FOCUSED); }
//
// Switch the button text, change the cursor, and free the param that the
// dialog proc allocated and sent to us
//
SendMessage(pgltp->hDlg, PDM_CHANGEBUTTONTEXT, 0, 0L);
LocalFree (lpGPO); } pgltp->pGPO->Release();
LocalFree(pgltp->pszLDAPName); LocalFree(pgltp); }
//
// Uninitialize COM
//
CoUninitialize();
FreeLibraryAndExitThread(hInstance, 0); return 0L; }
DWORD WINAPI CGroupPolicyObject::FindLinkInSite(GLTHREADPARAM * pgltp, LPTSTR lpGPO) { IADsContainer * pADsContainer = NULL; HRESULT hr; IEnumVARIANT *pVar = NULL; IADs * pADs = NULL; VARIANT var; ULONG ulResult; IDispatch * pDispatch = NULL; BSTR bstrClassName; BSTR bstrSite = NULL; IADsPathname * pADsPathname = NULL;
//
// Create a pathname object we can work with
//
hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER, IID_IADsPathname, (LPVOID*)&pADsPathname);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to create adspathname instance with 0x%x"), hr)); goto Exit; }
//
// Add the gpo name
//
BSTR bstrLDAPName = SysAllocString( pgltp->pszLDAPName ); if ( bstrLDAPName == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to allocate BSTR memory"))); hr = E_OUTOFMEMORY; goto Exit; } hr = pADsPathname->Set ( bstrLDAPName, ADS_SETTYPE_FULL); SysFreeString( bstrLDAPName );
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to set pathname with 0x%x"), hr)); goto Exit; }
//
// Add the configuration folder to the path
//
BSTR bstrCNConfiguration = SysAllocString( TEXT("CN=Configuration") ); if ( bstrCNConfiguration == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to allocate BSTR memory"))); hr = E_OUTOFMEMORY; goto Exit; } hr = pADsPathname->AddLeafElement ( bstrCNConfiguration ); SysFreeString( bstrCNConfiguration );
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to add configuration folder with 0x%x"), hr)); goto Exit; }
//
// Add the sites container to the path
//
BSTR bstrCNSites = SysAllocString( TEXT("CN=Sites") ); if ( bstrCNSites == NULL ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to allocate BSTR memory"))); hr = E_OUTOFMEMORY; goto Exit; } hr = pADsPathname->AddLeafElement (bstrCNSites); SysFreeString( bstrCNSites );
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to add sites folder with 0x%x"), hr)); goto Exit; }
//
// Retreive the container path
//
hr = pADsPathname->Retrieve (ADS_FORMAT_X500, &bstrSite);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to retreive site path with 0x%x"), hr)); goto Exit; }
// Create Enumerator
hr = OpenDSObject(bstrSite, IID_IADsContainer, (void **)&pADsContainer);
if (FAILED(hr)) { DebugMsg((DM_VERBOSE, TEXT("FindLinkInSite: Failed to get gpo container interface with 0x%x for object %s"), hr, bstrSite)); goto Exit; }
// Build the enumerator
hr = ADsBuildEnumerator (pADsContainer, &pVar); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("FindLinkInSite: Failed to get enumerator with 0x%x"), hr)); goto Exit; }
//
// Enumerate
//
while (TRUE) { TCHAR lpSite[] = TEXT("site"); DWORD dwStrLen = lstrlen (lpSite);
// Check if the user wants to abort. Before proceeding
if (*(pgltp->pfAbort)) { break; }
VariantInit(&var);
hr = ADsEnumerateNext(pVar, 1, &var, &ulResult);
if (S_FALSE == hr) { VariantClear (&var); break; }
if ((FAILED(hr)) || (var.vt != VT_DISPATCH)) { DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::FindLinkInSite: Failed to enumerator with 0x%x or we didn't get the IDispatch"), hr)); VariantClear (&var); break; }
if (*(pgltp->pfAbort)) { VariantClear (&var); break; }
//
// We found something, get the IDispatch interface
//
pDispatch = var.pdispVal;
if (!pDispatch) { VariantClear (&var); goto Exit; }
//
// Now query for the IADs interface so we can get some
// properties from this object
//
hr = pDispatch->QueryInterface(IID_IADs, (LPVOID *)&pADs);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: QI for IADs failed with 0x%x"), hr)); VariantClear (&var); goto Exit; }
//
// Get the relative and class names
//
hr = pADs->get_Class (&bstrClassName);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("DSDelnodeRecurse: Failed get class name with 0x%x"), hr)); pADs->Release(); VariantClear (&var); goto Exit; }
if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL, lpSite, dwStrLen, bstrClassName, dwStrLen) == CSTR_EQUAL) {
VARIANT varLink; BSTR bstrLinkProp;
VariantInit(&varLink); bstrLinkProp = SysAllocString(GPM_LINK_PROPERTY);
if (bstrLinkProp) { // Now get the Name property
hr = pADs->Get(bstrLinkProp, &varLink);
// Create the new LDAP:// string and call FindLinkInDomain() recursively
if (SUCCEEDED(hr) && wcsstr(varLink.bstrVal, lpGPO)) { VARIANT varName; BSTR bstrNameProp;
VariantInit(&varName); bstrNameProp = SysAllocString(GPM_NAME_PROPERTY);
if (bstrNameProp) { // Now get the Name property
hr = pADs->Get(bstrNameProp, &varName);
if (SUCCEEDED(hr)) { LV_ITEM lvi = {LVIF_TEXT}; LPTSTR pszTemp = MakeNamelessPath(bstrSite);
if (pszTemp) { ULONG ulLen = wcslen(pszTemp) + 2 + wcslen(varName.bstrVal); LPOLESTR pszTranslated = new OLECHAR[ulLen];
if (pszTranslated) { // Move pointer over the lDAP:// string and insert the rest into the listview
pszTemp += wcslen(TEXT("LDAP://"));
lvi.iItem = 0x7FFFFFFF; ULONG ulNeeded = ulLen; BOOL bTranslated;
bTranslated = TranslateName(pszTemp, NameFullyQualifiedDN, NameCanonical, pszTranslated, &ulNeeded);
if ( ! bTranslated && ( ulNeeded > ulLen ) ) { delete [] pszTranslated;
pszTranslated = new OLECHAR[ulNeeded];
if ( pszTranslated ) { bTranslated = TranslateName(pszTemp, NameFullyQualifiedDN, NameCanonical, pszTranslated, &ulNeeded); } }
ulLen = ulNeeded;
if ( bTranslated ) { ULONG ulFullPath; WCHAR* pszFullPath;
ulFullPath = ulLen + sizeof(L'/') / sizeof(WCHAR) + lstrlen( varName.bstrVal ) + 1;
pszFullPath = new OLECHAR[ ulFullPath ];
if ( pszFullPath ) { HRESULT hrCopy;
hrCopy = StringCchCopy( pszFullPath, ulFullPath, pszTranslated ); ASSERT(SUCCEEDED(hrCopy));
hrCopy = StringCchCat (pszFullPath, ulFullPath, TEXT("/")); ASSERT(SUCCEEDED(hrCopy));
hrCopy = StringCchCat (pszFullPath, ulFullPath, varName.bstrVal); ASSERT(SUCCEEDED(hrCopy));
lvi.pszText = pszFullPath; ListView_InsertItem(GetDlgItem(pgltp->hDlg, IDC_RESULTLIST), &lvi);
delete [] pszFullPath; } } delete [] pszTranslated; }
LocalFree (pszTemp); } } SysFreeString (bstrNameProp); } VariantClear (&varName); }
SysFreeString (bstrLinkProp); } VariantClear (&varLink); }
pADs->Release(); SysFreeString (bstrClassName); }
Exit: if (pADsContainer) pADsContainer->Release();
if (pADsPathname) pADsPathname->Release();
if (bstrSite) SysFreeString (bstrSite);
return 1L; }
//////////////////////////////////////////////////////////////////////////////
// Recursive call that will look through all domains and OUs for our GUID
//////////////////////////////////////////////////////////////////////////////
DWORD WINAPI CGroupPolicyObject::FindLinkInDomain(GLTHREADPARAM * pgltp, LPTSTR lpGPO) { IADs * pADs = NULL; IADsContainer * pADsContainer = NULL; HRESULT hr; IEnumVARIANT *pVar = NULL; VARIANT var; ULONG ulResult; BSTR bstrClassName; IDispatch * pDispatch = NULL; DWORD dwResult = 1;
// Check if the user wants to abort. Before proceeding
if (*(pgltp->pfAbort)) { return 0; }
// Bind to Object
hr = OpenDSObject(pgltp->pszLDAPName, IID_IADs, (void **)&pADs);
if (SUCCEEDED(hr)) { BSTR bstrLinkProp; VariantInit(&var); bstrLinkProp = SysAllocString(GPM_LINK_PROPERTY);
if (bstrLinkProp) { // Now get the link property
hr = pADs->Get(bstrLinkProp, &var);
// Check if out GUID is in there.
if (SUCCEEDED(hr) && StrStrI(var.bstrVal, lpGPO)) { LV_ITEM lvi = {LVIF_TEXT};
//
// Check if this is a forest path
//
if (IsForest(pgltp->pszLDAPName)) { TCHAR szForest[50] = {0};
LoadString (g_hInstance, IDS_FOREST, szForest, ARRAYSIZE(szForest)); lvi.iItem = 0x7FFFFFFF; lvi.pszText = szForest; ListView_InsertItem(GetDlgItem(pgltp->hDlg, IDC_RESULTLIST), &lvi); } else { LPTSTR pszTemp = MakeNamelessPath(pgltp->pszLDAPName);
if (pszTemp) { ULONG ulLen = wcslen(pszTemp) + 2; LPOLESTR pszTranslated = new OLECHAR[ulLen];
if (pszTranslated) { // Move pointer over the lDAP:// string and insert the rest into the listview
pszTemp += wcslen(TEXT("LDAP://"));
lvi.iItem = 0x7FFFFFFF; if (TranslateName(pszTemp, NameFullyQualifiedDN, NameCanonical, pszTranslated, &ulLen)) { lvi.pszText = pszTranslated; ListView_InsertItem(GetDlgItem(pgltp->hDlg, IDC_RESULTLIST), &lvi); } delete [] pszTranslated; }
LocalFree (pszTemp); } } }
// Cleanup
SysFreeString(bstrLinkProp); } VariantClear(&var); pADs->Release(); } else { DebugMsg((DM_VERBOSE, TEXT("FindLinkInDomain: Failed to get IID_IADs. hr: 0x%x, for %s"),hr, pgltp->pszLDAPName)); ReportError(pgltp->hDlg, hr, IDS_DSBINDFAILED); dwResult = 0; goto Exit;
}
// Check if the user wants to abort. Before proceeding
if (*(pgltp->pfAbort)) { dwResult = 0; goto Exit; }
// Create Enumerator
hr = OpenDSObject(pgltp->pszLDAPName, IID_IADsContainer, (void **)&pADsContainer);
if (FAILED(hr)) { DebugMsg((DM_VERBOSE, TEXT("FindLinkInDomain: Failed to get gpo container interface with 0x%x for object %s"), hr, pgltp->pszLDAPName)); dwResult = 0; goto Exit; }
hr = ADsBuildEnumerator (pADsContainer, &pVar);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("FindLinkInDomain: Failed to get enumerator with 0x%x"), hr)); dwResult = 0; goto Exit; }
//
// Enumerate
//
while (TRUE) { TCHAR lpOU[] = TEXT("organizationalUnit"); DWORD dwStrLen = lstrlen (lpOU);
// Check if the user wants to abort. Before proceeding
if (*(pgltp->pfAbort)) { break; }
VariantInit(&var);
hr = ADsEnumerateNext(pVar, 1, &var, &ulResult);
if (S_FALSE == hr) { VariantClear (&var); break; }
if ((FAILED(hr)) || (var.vt != VT_DISPATCH)) { VariantClear (&var); break; }
if (*(pgltp->pfAbort)) { VariantClear (&var); break; }
//
// We found something, get the IDispatch interface
//
pDispatch = var.pdispVal;
if (!pDispatch) { VariantClear (&var); dwResult = 0; goto Exit; }
//
// Now query for the IADs interface so we can get some
// properties from this object
//
hr = pDispatch->QueryInterface(IID_IADs, (LPVOID *)&pADs);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("AddGPOsForDomain: QI for IADs failed with 0x%x"), hr)); VariantClear (&var); dwResult = 0; goto Exit; }
//
// Get the relative and class names
//
hr = pADs->get_Class (&bstrClassName);
if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("DSDelnodeRecurse: Failed get class name with 0x%x"), hr)); pADs->Release(); VariantClear (&var); dwResult = 0; goto Exit; }
if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL, lpOU, dwStrLen, bstrClassName, dwStrLen) == CSTR_EQUAL) { VARIANT varName; BSTR bstrNameProp;
VariantInit(&varName); bstrNameProp = SysAllocString(GPM_NAME_PROPERTY);
if (bstrNameProp) { // Now get the Name property
hr = pADs->Get(bstrNameProp, &varName);
// Create the new LDAP:// string and call FindLinkInDomain() recursively
if (SUCCEEDED(hr)) { GLTHREADPARAM gltp = *pgltp; IADsPathname * pADsPathname; ULONG ulNoChars = wcslen(varName.bstrVal) + 10; LPOLESTR pszNewName = new OLECHAR[ulNoChars]; BSTR bstr;
//
// Build the new element name
//
if (!pszNewName) { dwResult = 0; goto Exit; }
hr = StringCchCopy(pszNewName, ulNoChars, TEXT("OU=")); if (SUCCEEDED(hr)) { hr = StringCchCat(pszNewName, ulNoChars, varName.bstrVal); }
if (FAILED(hr)) { delete [] pszNewName; dwResult = 0; goto Exit; }
//
// Create a pathname object we can work with
//
hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER, IID_IADsPathname, (LPVOID*)&pADsPathname);
if (FAILED(hr)) { delete [] pszNewName; dwResult = 0; goto Exit; }
//
// Set the current name
//
BSTR bstrLDAPName = SysAllocString( pgltp->pszLDAPName ); if ( bstrLDAPName == NULL ) { delete [] pszNewName; pADsPathname->Release(); dwResult = 0; goto Exit; } hr = pADsPathname->Set ( bstrLDAPName, ADS_SETTYPE_FULL); SysFreeString( bstrLDAPName );
if (FAILED(hr)) { delete [] pszNewName; pADsPathname->Release(); dwResult = 0; goto Exit; }
//
// Check for escape characters
//
BSTR bstrNewName = SysAllocString( pszNewName ); delete [] pszNewName; if ( bstrNewName == NULL ) { pADsPathname->Release(); dwResult = 0; goto Exit; } hr = pADsPathname->GetEscapedElement (0, bstrNewName, &bstr); SysFreeString( bstrNewName );
if (FAILED(hr)) { pADsPathname->Release(); dwResult = 0; goto Exit; }
//
// Add the new element
//
hr = pADsPathname->AddLeafElement (bstr);
SysFreeString (bstr);
if (FAILED(hr)) { pADsPathname->Release(); dwResult = 0; goto Exit; }
//
// Get the new path
//
hr = pADsPathname->Retrieve(ADS_FORMAT_X500, &bstr); pADsPathname->Release();
if (FAILED(hr)) { dwResult = 0; goto Exit; }
//
// Recurse
//
gltp.pszLDAPName = bstr; if (FindLinkInDomain(&gltp, lpGPO) == 0) { SysFreeString( bstr ); dwResult = 0; goto Exit; }
SysFreeString (bstr);
} SysFreeString (bstrNameProp); } VariantClear (&varName); }
pADs->Release(); SysFreeString (bstrClassName); }
Exit: if (pADsContainer) pADsContainer->Release();
return dwResult; }
//////////////////////////////////////////////////////////////////////////////
// Fill the combobox with available domains
//////////////////////////////////////////////////////////////////////////////
BOOL CGroupPolicyObject::FillDomainList (HWND hWndCombo) { HRESULT hr; DWORD dwIndex = 0; LPOLESTR pszDomain; LPTSTR lpTemp; HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
// get the ordered tree of domains
LOOKDATA * pDomainList = BuildDomainList(NULL); LOOKDATA *pRemember = pDomainList;
// now walk the tree, adding elements to the dialog box
int nCBIndex;
// start at the head
while (pDomainList) {
// add the LDAP path for the doman in this node
//SendMessage(hWndCombo, CB_INSERTSTRING, (WPARAM) -1, (LPARAM)(LPCTSTR) pDomainList->szData);
nCBIndex = (int)SendMessage(hWndCombo, CB_INSERTSTRING, (WPARAM) -1, (LPARAM)(LPCTSTR) pDomainList->szName); SendMessage(hWndCombo, CB_SETITEMDATA, (WPARAM) nCBIndex, (LPARAM)(LPCTSTR) pDomainList->szData);
if (pDomainList->pChild) { // go to its child
pDomainList = pDomainList->pChild; } else { if (pDomainList->pSibling) { // go to its sibling if there are no children
pDomainList = pDomainList->pSibling; } else { // there are no children and no siblings
// back up until we find a parent with a sibling
// or there are no more parents (we're done)
do { pDomainList = pDomainList->pParent; if (pDomainList) { if (pDomainList->pSibling) { pDomainList = pDomainList->pSibling; break; } } else { break; } } while (TRUE); } } }
FreeDomainInfo (pRemember);
//
// Select the current domain in the combobox
//
pszDomain = GetDomainFromLDAPPath(m_pDSPath);
if (pszDomain) {
//
// Convert LDAP to dot (DN) style
//
hr = ConvertToDotStyle (pszDomain, &lpTemp);
if (SUCCEEDED(hr)) { dwIndex = (DWORD) SendMessage (hWndCombo, CB_FINDSTRINGEXACT, (WPARAM) -1, (LONG_PTR)lpTemp);
if (dwIndex == CB_ERR) { dwIndex = 0; }
LocalFree (lpTemp); }
delete [] pszDomain; }
SendMessage (hWndCombo, CB_SETCURSEL, (WPARAM)dwIndex, 0); SetCursor(hcur);
return TRUE; }
INT_PTR CALLBACK CGroupPolicyObject::PropertiesDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { CGroupPolicyObject * pGPO; static BOOL bDirty; static BOOL bDisableWarningIssued;
switch (message) { case WM_INITDIALOG: { DWORD dwTemp; LPTSTR lpEnd; TCHAR szBuffer[2*MAX_PATH]; TCHAR szDate[100]; TCHAR szTime[100]; TCHAR szFormat[80]; TCHAR szVersion[100]; WIN32_FILE_ATTRIBUTE_DATA fad; FILETIME filetime, CreateTime, ChangeTime; SYSTEMTIME systime; LPTSTR lpResult; LPOLESTR pszDomain; ULONG ulVersion = 0; USHORT uMachine, uUser; VARIANT var; BSTR bstrName; LPTSTR lpDisplayName; WORD wDosDate, wDosTime; ULONG ulNoChars; HRESULT hr;
pGPO = (CGroupPolicyObject *) (((LPPROPSHEETPAGE)lParam)->lParam); SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pGPO);
//
// Initialize
//
if ((pGPO->m_pMachineName) && (pGPO->m_gpoType == GPOTypeDS)) { ulNoChars = lstrlen(pGPO->m_pDisplayName) + lstrlen(pGPO->m_pMachineName) + 5; lpDisplayName = (LPTSTR) LocalAlloc (LPTR, ulNoChars * sizeof(TCHAR));
if (lpDisplayName) { LoadString (g_hInstance, IDS_NAMEFORMAT, szFormat, ARRAYSIZE(szFormat)); (void) StringCchPrintf (lpDisplayName, ulNoChars, szFormat, pGPO->m_pDisplayName, pGPO->m_pMachineName); SetDlgItemText (hDlg, IDC_TITLE, lpDisplayName); LocalFree (lpDisplayName); } } else { SetDlgItemText (hDlg, IDC_TITLE, pGPO->m_pDisplayName); }
if (pGPO->m_gpoType == GPOTypeDS) { if (IsForest(pGPO->m_pDSPath)) { LoadString (g_hInstance, IDS_FORESTHEADING, szBuffer, ARRAYSIZE(szBuffer)); SetDlgItemText (hDlg, IDC_DOMAIN_HEADING, szBuffer); }
pszDomain = GetDomainFromLDAPPath(pGPO->m_pDSPath);
if (pszDomain) { if (SUCCEEDED(ConvertToDotStyle (pszDomain, &lpResult))) { SetDlgItemText (hDlg, IDC_DOMAIN, lpResult); LocalFree (lpResult); }
delete [] pszDomain; }
SetDlgItemText (hDlg, IDC_UNIQUE_NAME, pGPO->m_pName); } else { LoadString (g_hInstance, IDS_NOTAPPLICABLE, szBuffer, ARRAYSIZE(szBuffer)); SetDlgItemText (hDlg, IDC_DOMAIN, szBuffer); SetDlgItemText (hDlg, IDC_UNIQUE_NAME, szBuffer); }
if (SUCCEEDED(pGPO->GetOptions(&dwTemp))) { if (dwTemp & GPO_OPTION_DISABLE_MACHINE) { CheckDlgButton (hDlg, IDC_DISABLE_COMPUTER, BST_CHECKED); }
if (dwTemp & GPO_OPTION_DISABLE_USER) { CheckDlgButton (hDlg, IDC_DISABLE_USER, BST_CHECKED); } }
hr = StringCchCopy (szBuffer, ARRAYSIZE(szBuffer), pGPO->m_pFileSysPath); if (SUCCEEDED(hr)) { lpEnd = CheckSlash (szBuffer); hr = StringCchCat (szBuffer, ARRAYSIZE(szBuffer), TEXT("gpt.ini")); }
if (SUCCEEDED(hr)) { if (pGPO->m_gpoType == GPOTypeDS) { VariantInit(&var); bstrName = SysAllocString (GPO_VERSION_PROPERTY);
if (bstrName) { if (SUCCEEDED(pGPO->m_pADs->Get(bstrName, &var))) { ulVersion = var.lVal; }
SysFreeString (bstrName); }
VariantClear (&var); } else { ulVersion = GetPrivateProfileInt(TEXT("General"), TEXT("Version"), 0, szBuffer); } }
uMachine = (USHORT) LOWORD(ulVersion); uUser = (USHORT) HIWORD(ulVersion);
LoadString (g_hInstance, IDS_REVISIONFORMAT, szFormat, ARRAYSIZE(szFormat)); (void) StringCchPrintf (szVersion, ARRAYSIZE(szVersion), szFormat, uMachine, uUser);
SetDlgItemText (hDlg, IDC_REVISION, szVersion);
//
// Get the date / time info
//
CreateTime.dwLowDateTime = 0; CreateTime.dwHighDateTime = 0; ChangeTime.dwLowDateTime = 0; ChangeTime.dwHighDateTime = 0;
if (pGPO->m_gpoType == GPOTypeDS) { //
// Get the creation time
//
VariantInit(&var); bstrName = SysAllocString (TEXT("whenCreated"));
if (bstrName) { if (SUCCEEDED(pGPO->m_pADs->Get(bstrName, &var))) { if (VariantTimeToDosDateTime (var.date, &wDosDate, &wDosTime)) { DosDateTimeToFileTime (wDosDate, wDosTime, &CreateTime); } }
SysFreeString (bstrName); }
VariantClear (&var);
//
// Get the last write time
//
VariantInit(&var); bstrName = SysAllocString (TEXT("whenChanged"));
if (bstrName) { if (SUCCEEDED(pGPO->m_pADs->Get(bstrName, &var))) { if (VariantTimeToDosDateTime (var.date, &wDosDate, &wDosTime)) { DosDateTimeToFileTime (wDosDate, wDosTime, &ChangeTime); } }
SysFreeString (bstrName); }
VariantClear (&var); } else { //
// Get the time info from the gpt.ini file
//
if (GetFileAttributesEx (szBuffer, GetFileExInfoStandard, &fad)) {
CreateTime.dwLowDateTime = fad.ftCreationTime.dwLowDateTime; CreateTime.dwHighDateTime = fad.ftCreationTime.dwHighDateTime;
ChangeTime.dwLowDateTime = fad.ftLastWriteTime.dwLowDateTime; ChangeTime.dwHighDateTime = fad.ftLastWriteTime.dwHighDateTime; } }
//
// Format & display the date / time information
//
FileTimeToLocalFileTime (&CreateTime, &filetime); FileTimeToSystemTime (&filetime, &systime); GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime, NULL, szDate, ARRAYSIZE (szDate));
GetTimeFormat (LOCALE_USER_DEFAULT, 0, &systime, NULL, szTime, ARRAYSIZE (szTime));
LoadString (g_hInstance, IDS_DATETIMEFORMAT, szFormat, ARRAYSIZE(szFormat)); (void) StringCchPrintf (szBuffer, ARRAYSIZE(szBuffer), szFormat, szDate, szTime); SetDlgItemText (hDlg, IDC_CREATE_DATE, szBuffer);
FileTimeToLocalFileTime (&ChangeTime, &filetime); FileTimeToSystemTime (&filetime, &systime); GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime, NULL, szDate, ARRAYSIZE (szDate));
GetTimeFormat (LOCALE_USER_DEFAULT, 0, &systime, NULL, szTime, ARRAYSIZE (szTime));
(void) StringCchPrintf (szBuffer, ARRAYSIZE(szBuffer), szFormat, szDate, szTime); SetDlgItemText (hDlg, IDC_MODIFIED_DATE, szBuffer);
if (pGPO->m_dwFlags & GPO_OPEN_READ_ONLY) { EnableWindow (GetDlgItem(hDlg, IDC_DISABLE_COMPUTER), FALSE); EnableWindow (GetDlgItem(hDlg, IDC_DISABLE_USER), FALSE); }
bDirty = FALSE; bDisableWarningIssued = FALSE; break; }
case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { if ((LOWORD(wParam) == IDC_DISABLE_COMPUTER) || (LOWORD(wParam) == IDC_DISABLE_USER)) { if (!bDisableWarningIssued) { if (IsDlgButtonChecked (hDlg, LOWORD(wParam)) == BST_CHECKED) { TCHAR szMessage[200]; TCHAR szTitle[100];
bDisableWarningIssued = TRUE;
LoadString (g_hInstance, IDS_CONFIRMDISABLE, szMessage, ARRAYSIZE(szMessage)); LoadString (g_hInstance, IDS_CONFIRMTITLE2, szTitle, ARRAYSIZE(szTitle));
if (MessageBox (hDlg, szMessage, szTitle, MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) == IDNO) {
CheckDlgButton (hDlg, LOWORD(wParam), BST_UNCHECKED); break; } } } }
if (!bDirty) { SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); bDirty = TRUE; } } break;
case WM_NOTIFY:
pGPO = (CGroupPolicyObject *) GetWindowLongPtr (hDlg, DWLP_USER);
if (!pGPO) { break; }
switch (((NMHDR FAR*)lParam)->code) { case PSN_APPLY: { if (bDirty) { DWORD dwTemp = 0; HRESULT hr;
//
// Set the disable flags in the GPO
//
if (IsDlgButtonChecked (hDlg, IDC_DISABLE_COMPUTER) == BST_CHECKED) { dwTemp |= GPO_OPTION_DISABLE_MACHINE; }
if (IsDlgButtonChecked (hDlg, IDC_DISABLE_USER) == BST_CHECKED) { dwTemp |= GPO_OPTION_DISABLE_USER; }
hr = pGPO->SetOptions (dwTemp, (GPO_OPTION_DISABLE_MACHINE | GPO_OPTION_DISABLE_USER));
if (FAILED(hr)) { ReportError(hDlg, hr, IDS_FAILEDPROPERTIES); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_INVALID); return TRUE; }
bDirty = FALSE; } } // fall through...
case PSN_RESET: SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR); return TRUE; } break;
case WM_HELP: // F1
WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (ULONG_PTR) (LPSTR) aPropertiesHelpIds); break;
case WM_CONTEXTMENU: // right mouse click
WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU, (ULONG_PTR) (LPSTR) aPropertiesHelpIds); return (TRUE); }
return FALSE; }
///////////////////////////////////////////////////////////////////////////////
// //
// Class factory object implementation //
// //
///////////////////////////////////////////////////////////////////////////////
CGroupPolicyObjectCF::CGroupPolicyObjectCF() { m_cRef = 1; InterlockedIncrement(&g_cRefThisDll); }
CGroupPolicyObjectCF::~CGroupPolicyObjectCF() { InterlockedDecrement(&g_cRefThisDll); }
///////////////////////////////////////////////////////////////////////////////
// //
// Class factory object implementation (IUnknown) //
// //
///////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CGroupPolicyObjectCF::AddRef() { return ++m_cRef; }
STDMETHODIMP_(ULONG) CGroupPolicyObjectCF::Release() { if (--m_cRef == 0) { delete this; return 0; }
return m_cRef; }
STDMETHODIMP CGroupPolicyObjectCF::QueryInterface(REFIID riid, LPVOID FAR* ppv) { if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)) { *ppv = (LPCLASSFACTORY)this; m_cRef++; return S_OK; } else { *ppv = NULL; return E_NOINTERFACE; } }
///////////////////////////////////////////////////////////////////////////////
// //
// Class factory object implementation (IClassFactory) //
// //
///////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CGroupPolicyObjectCF::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID FAR* ppvObj) { *ppvObj = NULL;
if (pUnkOuter) return CLASS_E_NOAGGREGATION;
CGroupPolicyObject *pGroupPolicyObject = new CGroupPolicyObject(); // ref count == 1
if (!pGroupPolicyObject) return E_OUTOFMEMORY;
HRESULT hr = pGroupPolicyObject->QueryInterface(riid, ppvObj); pGroupPolicyObject->Release(); // release initial ref
return hr; }
STDMETHODIMP CGroupPolicyObjectCF::LockServer(BOOL fLock) { return E_NOTIMPL; }
//*************************************************************
//
// CGroupPolicyObject::GetProperty
//
// Purpose: Retrieves a property from DS or from gpt.ini
//
// Parameters: pszProp - Property to get
// xValueIn - Value returned here
//
// Returns: S_OK if successful
//
//*************************************************************
HRESULT CGroupPolicyObject::GetProperty( TCHAR *pszProp, XPtrST<TCHAR>& xValueIn ) { HRESULT hr = E_FAIL;
if ( m_gpoType == GPOTypeDS ) { VARIANT var; BSTR bstrProperty;
VariantInit( &var ); bstrProperty = SysAllocString( pszProp );
if ( bstrProperty == NULL ) return E_OUTOFMEMORY;
hr = m_pADs->Get( bstrProperty, &var );
if ( SUCCEEDED(hr) ) { ULONG ulNoChars = lstrlen(var.bstrVal) + 1; TCHAR *pszValue = new TCHAR[ulNoChars]; if ( pszValue == 0 ) hr = E_OUTOFMEMORY; else { hr = StringCchCopy ( pszValue, ulNoChars, var.bstrVal ); ASSERT(SUCCEEDED(hr)); xValueIn.Set( pszValue );
hr = S_OK; } } else if ( hr == E_ADS_PROPERTY_NOT_FOUND ) { //
// Property has not be written out before
//
hr = S_OK; }
if ( FAILED(hr) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetProperty: Failed with errorcode 0x%x"), hr)); }
SysFreeString( bstrProperty ); VariantClear( &var );
return hr; } else { TCHAR szPath[2*MAX_PATH];
//
// Get the file system path
//
hr = GetPath (szPath, ARRAYSIZE(szPath)); if ( FAILED(hr) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetProperty: Failed with errorcode 0x%x"), hr)); }
(void) CheckSlash (szPath); hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("GPT.INI")); if (FAILED(hr)) { return hr; }
XPtrST<TCHAR> xszValue( new TCHAR[2*MAX_PATH] ); if ( xszValue.GetPointer() == NULL ) return E_OUTOFMEMORY;
DWORD dwSize = (2*MAX_PATH); DWORD dwCount = GetPrivateProfileString( TEXT("General"), pszProp, TEXT(""), xszValue.GetPointer(), dwSize, szPath ); while ( dwCount == dwSize - 1 ) { //
// Value has been truncated, so retry with larger buffer
//
dwSize *= 2; delete xszValue.Acquire(); xszValue.Set( new TCHAR[dwSize] );
if ( xszValue.GetPointer() == NULL ) return E_OUTOFMEMORY;
dwCount = GetPrivateProfileString( TEXT("General"), pszProp, TEXT(""), xszValue.GetPointer(), dwSize, szPath ); }
xValueIn.Set( xszValue.Acquire() );
return S_OK; } }
//*************************************************************
//
// CGroupPolicyObject::SetProperty
//
// Purpose: Writes a property to DS or to gpt.ini
//
// Parameters: pszProp - Property to set
// pszPropValue - Property value
//
// Returns: S_OK if successful
//
//*************************************************************
HRESULT CGroupPolicyObject::SetProperty( TCHAR *pszProp, TCHAR *pszPropValue ) { HRESULT hr = E_FAIL;
if ( m_gpoType == GPOTypeDS ) { VARIANT var;
VariantInit( &var );
var.vt = VT_BSTR; var.bstrVal = SysAllocString( pszPropValue ); if ( var.bstrVal == 0 ) return E_OUTOFMEMORY;
BSTR bstrProperty = SysAllocString( pszProp ); if ( bstrProperty == 0 ) { VariantClear( &var ); return E_OUTOFMEMORY; }
hr = m_pADs->Put( bstrProperty, var ); if ( FAILED(hr) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetProperty: Failed with errorcode 0x%x"), hr)); return hr; }
SysFreeString( bstrProperty ); VariantClear( &var );
return S_OK; } else { TCHAR szPath[2*MAX_PATH];
//
// Get the file system path
//
hr = GetPath (szPath, ARRAYSIZE(szPath)); if ( FAILED(hr) ) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::SetProperty: Failed with errorcode 0x%x"), hr)); }
(void) CheckSlash (szPath); hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("GPT.INI")); if (FAILED(hr)) { return hr; }
BOOL bOk = WritePrivateProfileString( TEXT("General"), pszProp, pszPropValue, szPath ); if ( bOk ) hr = S_OK; else hr = GetLastError();
return hr; } }
|