//************************************************************* // File name: GPMGR.C // // Description: Group Policy Manager - property sheet extension // for DS Admin // // // Microsoft Confidential // Copyright (c) Microsoft Corporation 1998 // All rights reserved // //************************************************************* #include "main.h" unsigned int CGroupPolicyMgr::m_cfDSObjectName = RegisterClipboardFormat(CFSTR_DSOBJECTNAMES); unsigned int CGroupPolicyMgr::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE); // // Snapin manager's CLSID // const CLSID CLSID_NodeInit = {0x43136EB5,0xD36C,0x11CF,{0xAD,0xBC,0x00,0xAA,0x00,0xA8,0x00,0x33}}; // // CheckMark string // TCHAR szCheckMark[] = TEXT("a"); // In the Marlett font, "a" becomes a check mark TCHAR szNoCheckMark[] = TEXT(""); // // Help ids // DWORD aGroupPolicyMgrHelpIds[] = { IDC_GPM_DCNAME, IDH_GPMGR_DCNAME, IDC_GPM_LIST, IDH_GPMGR_LIST, IDC_GPM_UP, IDH_GPMGR_UP, IDC_GPM_DOWN, IDH_GPMGR_DOWN, IDC_GPM_ADD, IDH_GPMGR_ADD, IDC_GPM_EDIT, IDH_GPMGR_EDIT, IDC_GPM_DELETE, IDH_GPMGR_DELETE, IDC_GPM_PROPERTIES, IDH_GPMGR_PROPERTIES, IDC_GPM_BLOCK, IDH_GPMGR_BLOCK, IDC_GPM_NEW, IDH_GPMGR_NEW, IDC_GPM_OPTIONS, IDH_GPMGR_OPTIONS, IDC_GPM_TITLE, -1, IDC_GPM_ICON, -1, IDC_GPM_LINE1, -1, IDC_GPM_PRIORITY, -1, IDC_GPM_LINE2, -1, 0, 0 }; DWORD aLinkOptionsHelpIds[] = { IDC_GPM_NOOVERRIDE, IDH_GPMGR_NOOVERRIDE, IDC_GPM_DISABLED, IDH_GPMGR_DISABLED, 0, 0 }; DWORD aRemoveGPOHelpIds[] = { IDC_REMOVE_LIST, IDH_REMOVE_LIST, IDC_REMOVE_DS, IDH_REMOVE_DS, 0, 0 }; /////////////////////////////////////////////////////////////////////////////// // // // CGroupPolicyMgr object implementation // // // /////////////////////////////////////////////////////////////////////////////// CGroupPolicyMgr::CGroupPolicyMgr() { InterlockedIncrement(&g_cRefThisDll); m_cRef = 1; m_lpDSObject = NULL; m_lpGPODCName = NULL; m_lpDSADCName = NULL; m_lpDomainName = NULL; m_hDefaultFont = NULL; m_hMarlettFont = NULL; m_bReadOnly = FALSE; m_bDirty = FALSE; m_gpHint = GPHintUnknown; } CGroupPolicyMgr::~CGroupPolicyMgr() { if (m_hMarlettFont) { DeleteObject (m_hMarlettFont); } if (m_lpDSObject) { LocalFree (m_lpDSObject); } if (m_lpGPODCName) { LocalFree (m_lpGPODCName); } if (m_lpDSADCName) { LocalFree (m_lpDSADCName); } if (m_lpDomainName) { LocalFree (m_lpDomainName); } InterlockedDecrement(&g_cRefThisDll); } /////////////////////////////////////////////////////////////////////////////// // // // CGroupPolicyMgr object implementation (IUnknown) // // // /////////////////////////////////////////////////////////////////////////////// HRESULT CGroupPolicyMgr::QueryInterface (REFIID riid, void **ppv) { if (IsEqualIID(riid, IID_IUnknown) ||IsEqualIID(riid, IID_IExtendPropertySheet)) { *ppv = (LPEXTENDPROPERTYSHEET)this; m_cRef++; return S_OK; } else if (IsEqualIID(riid, IID_ISnapinHelp)) { *ppv = (LPSNAPINHELP)this; m_cRef++; return S_OK; } else { *ppv = NULL; return E_NOINTERFACE; } } ULONG CGroupPolicyMgr::AddRef (void) { return ++m_cRef; } ULONG CGroupPolicyMgr::Release (void) { if (--m_cRef == 0) { delete this; return 0; } return m_cRef; } /////////////////////////////////////////////////////////////////////////////// // // // CGroupPolicyMgr object implementation (ISnapinHelp) // // // /////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CGroupPolicyMgr::GetHelpTopic(LPOLESTR *lpCompiledHelpFile) { LPOLESTR lpHelpFile; lpHelpFile = (LPOLESTR) CoTaskMemAlloc (MAX_PATH * sizeof(WCHAR)); if (!lpHelpFile) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::GetHelpTopic: Failed to allocate memory."))); return E_OUTOFMEMORY; } ExpandEnvironmentStringsW (L"%SystemRoot%\\Help\\gpedit.chm", lpHelpFile, MAX_PATH); *lpCompiledHelpFile = lpHelpFile; return S_OK; } /////////////////////////////////////////////////////////////////////////////// // // // CGroupPolicyMgr object implementation (IExtendPropertySheet) // // // /////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CGroupPolicyMgr::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT lpDataObject) { HRESULT hr; PROPSHEETPAGE psp; HPROPSHEETPAGE hPage; FORMATETC fm; STGMEDIUM medium; LPDSOBJECTNAMES lpNames; LPTSTR lpTemp; // // Ask DS admin for the ldap path to the selected object // ZeroMemory (&fm, sizeof(fm)); fm.cfFormat = (WORD)m_cfDSObjectName; fm.tymed = TYMED_HGLOBAL; ZeroMemory (&medium, sizeof(medium)); medium.tymed = TYMED_HGLOBAL; medium.hGlobal = GlobalAlloc (GMEM_MOVEABLE | GMEM_NODISCARD, 512); if (medium.hGlobal) { hr = lpDataObject->GetData(&fm, &medium); if (SUCCEEDED(hr)) { lpNames = (LPDSOBJECTNAMES) GlobalLock (medium.hGlobal); lpTemp = (LPWSTR) (((LPBYTE)lpNames) + lpNames->aObjects[0].offsetName); if (m_lpDSObject) { LocalFree (m_lpDSObject); } m_lpDSObject = (LPTSTR) LocalAlloc (LPTR, (lstrlen (lpTemp) + 1) * sizeof(TCHAR)); if (m_lpDSObject) { lstrcpy (m_lpDSObject, lpTemp); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::CreatePropertyPages: LDAP path from DS Admin %s"), m_lpDSObject)); // // Now look at the object type to get a hint type // m_gpHint = GPHintUnknown; if (lpNames->aObjects[0].offsetClass) { lpTemp = (LPWSTR) (((LPBYTE)lpNames) + lpNames->aObjects[0].offsetClass); if (lstrcmpi (lpTemp, TEXT("domainDNS")) == 0) { m_gpHint = GPHintDomain; } else if (lstrcmpi (lpTemp, TEXT("organizationalUnit")) == 0) { m_gpHint = GPHintOrganizationalUnit; } else if (lstrcmpi (lpTemp, TEXT("site")) == 0) { m_gpHint = GPHintSite; } DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::CreatePropertyPages: m_gpHint = %d"), m_gpHint)); } else { DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::CreatePropertyPages: No objectclass defined."))); } } else { hr = HRESULT_FROM_WIN32(GetLastError()); } GlobalUnlock (medium.hGlobal); } #if FGPO_SUPPORT else { // ToDo: remove this code after the dstree snapin supports // dsobjectnames on its root node // // if we're supposed to be on the forest then we can just fudge it // fm.cfFormat = (WORD)m_cfNodeTypeString; if (SUCCEEDED(lpDataObject->GetDataHere(&fm, &medium))) { lpTemp = (LPWSTR) GlobalLock (medium.hGlobal); if (lstrcmpi(lpTemp, TEXT("{4c06495e-a241-11d0-b09b-00c04fd8dca6}"))) // DSTree snapin's root node { // croft up our own forest path lpTemp = GetPathToForest(NULL); if (lpTemp) { m_lpDSObject = (LPTSTR) LocalAlloc(LPTR, (lstrlen(lpTemp) + 1) * sizeof(TCHAR)); if (m_lpDSObject) { lstrcpy (m_lpDSObject, lpTemp); m_gpHint = GPHintForest; hr = S_OK; } delete [] lpTemp; } } GlobalUnlock (medium.hGlobal); } } #endif GlobalFree (medium.hGlobal); } else { hr = HRESULT_FROM_WIN32(GetLastError()); } // // Add the GPM property sheet page // if (SUCCEEDED(hr)) { ZeroMemory (&psp, sizeof(psp)); psp.dwSize = sizeof(psp); psp.dwFlags = PSP_USECALLBACK; psp.hInstance = g_hInstance; psp.pszTemplate = MAKEINTRESOURCE (IDD_GPMANAGER); psp.pfnDlgProc = GPMDlgProc; psp.lParam = (LPARAM) this; psp.pfnCallback = PropSheetPageCallback; hPage = CreatePropertySheetPage(&psp); if (hPage) { hr = lpProvider->AddPage(hPage); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::CreatePropertyPages: Failed to create property sheet page with %d."), GetLastError())); hr = E_FAIL; } } return (hr); } STDMETHODIMP CGroupPolicyMgr::QueryPagesFor(LPDATAOBJECT lpDataObject) { return S_OK; } UINT CALLBACK CGroupPolicyMgr::PropSheetPageCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp) { CGroupPolicyMgr * pGPM; pGPM = (CGroupPolicyMgr *) ppsp->lParam; if (uMsg == PSPCB_ADDREF) { pGPM->AddRef(); } else if (uMsg == PSPCB_RELEASE) { pGPM->Release(); } return 1; } INT_PTR CALLBACK CGroupPolicyMgr::GPMDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { CGroupPolicyMgr * pGPM; static BOOL bDisableWarningIssued; switch (message) { case WM_INITDIALOG: pGPM = (CGroupPolicyMgr *) (((LPPROPSHEETPAGE)lParam)->lParam); SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pGPM); SetWaitCursor(); bDisableWarningIssued = FALSE; EnableWindow (GetDlgItem (hDlg, IDC_GPM_DELETE), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_EDIT), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_UP), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_DOWN), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_OPTIONS), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_PROPERTIES), FALSE); if (!pGPM->OnInitDialog(hDlg)) { EnableWindow (GetDlgItem (hDlg, IDC_GPM_LIST), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_NEW), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_ADD), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_BLOCK), FALSE); } if (pGPM->m_bReadOnly) { EnableWindow (GetDlgItem (hDlg, IDC_GPM_NEW), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_ADD), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_DELETE), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_UP), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_DOWN), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_OPTIONS), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_BLOCK), FALSE); } #if FGPO_SUPPORT if (pGPM->m_gpHint == GPHintForest) #else if (pGPM->m_gpHint == GPHintSite) #endif { EnableWindow (GetDlgItem (hDlg, IDC_GPM_BLOCK), FALSE); } ClearWaitCursor(); break; case WM_COMMAND: pGPM = (CGroupPolicyMgr *) GetWindowLongPtr (hDlg, DWLP_USER); if (!pGPM) { break; } if ((LOWORD(wParam) == IDC_GPM_ADD) || (LOWORD(wParam) == IDM_GPM_ADD)) { TCHAR szPath[512]; TCHAR szName[MAX_FRIENDLYNAME]; TCHAR szTitle[100]; LPTSTR lpNamelessPath; GPOBROWSEINFO stGBI; IADs * pADs; HRESULT hr; BOOL bReadOnly = FALSE; LoadString (g_hInstance, IDS_GPM_ADDTITLE, szTitle, ARRAYSIZE(szTitle)); ZeroMemory(&stGBI, sizeof(GPOBROWSEINFO)); stGBI.dwSize = sizeof(GPOBROWSEINFO); stGBI.dwFlags = GPO_BROWSE_NOCOMPUTERS | GPO_BROWSE_DISABLENEW; stGBI.hwndOwner = hDlg; stGBI.lpTitle = szTitle; stGBI.lpInitialOU = pGPM->m_lpDSObject; stGBI.lpDSPath = szPath; stGBI.dwDSPathSize = ARRAYSIZE(szPath); stGBI.lpName = szName; stGBI.dwNameSize = ARRAYSIZE(szName); if (SUCCEEDED(BrowseForGPO(&stGBI))) { // // Check if the user has write access to the select GPO // lpNamelessPath = MakeNamelessPath (szPath); if (lpNamelessPath) { hr = OpenDSObject(szPath, IID_IADs, (void **)&pADs); if (SUCCEEDED(hr)) { if (FAILED(CheckDSWriteAccess((LPUNKNOWN) pADs, GPO_VERSION_PROPERTY))) { bReadOnly = TRUE; } pADs->Release(); } // // Read the policy value for the GPO link // HKEY hKey; DWORD dwSize, dwType; BOOL bDisabledLink = FALSE; // // Check if there is a user preference or policy that // any new GPOs should be created with a disabled link // by default // if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(bDisabledLink); RegQueryValueEx (hKey, NEW_LINKS_DISABLED_VALUE, NULL, &dwType, (LPBYTE) &bDisabledLink, &dwSize); RegCloseKey (hKey); } if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_POLICIES_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(bDisabledLink); RegQueryValueEx (hKey, NEW_LINKS_DISABLED_VALUE, NULL, &dwType, (LPBYTE) &bDisabledLink, &dwSize); RegCloseKey (hKey); } if (pGPM->AddGPOToList (GetDlgItem(hDlg, IDC_GPM_LIST), szName, lpNamelessPath, (bDisabledLink ? GPO_FLAG_DISABLE : 0), FALSE, pGPM->IsGPODisabled (lpNamelessPath), bReadOnly)) { pGPM->m_bDirty = TRUE; SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); SetFocus (GetDlgItem(hDlg, IDC_GPM_LIST)); PostMessage (hDlg, WM_REFRESHDISPLAY, 0, 0); } LocalFree (lpNamelessPath); } } } if ((LOWORD(wParam) == IDC_GPM_DELETE) || (LOWORD(wParam) == IDM_GPM_DELETE)) { INT iIndex, iNext; HWND hLV = GetDlgItem(hDlg, IDC_GPM_LIST); LVITEM item; // // Enumerate through the selected items // iIndex = ListView_GetNextItem (hLV, -1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { HRESULT hr; LPGPOITEM lpGPO, lpTemp; LPGROUPPOLICYOBJECT pGPO; TCHAR szMessageFmt[100]; LPTSTR lpMessage; TCHAR szTitle[100]; INT iResult; LPTSTR lpDSPath; LPTSTR lpFullPath; // // The GPO item pointer // item.mask = LVIF_PARAM; item.iItem = iIndex; item.iSubItem = 0; if (!ListView_GetItem (hLV, &item)) { break; } lpGPO = (LPGPOITEM) item.lParam; if ( !lpGPO ) { break; } lpGPO->bLocked = TRUE; // // Offer the user a choice of Remove actions // iResult = (INT)DialogBoxParam (g_hInstance, MAKEINTRESOURCE(IDD_REMOVE_GPO), hDlg, RemoveGPODlgProc, (LPARAM) lpGPO); if ((iResult == -1) || (iResult == 0)) { SetFocus (hLV); lpGPO->bLocked = FALSE; break; } iNext = ListView_GetNextItem (hLV, iIndex, LVNI_ALL); if (iNext > 0) { iNext--; } else { iNext = 0; } if (iResult == 1) { IADs * pADs; // // Bind to the DS object to make sure it's still reachable // hr = OpenDSObject(pGPM->m_lpDSObject, IID_IADs, (void **)&pADs); if (SUCCEEDED(hr)) { pADs->Release(); ListView_DeleteItem (hLV, iIndex); } else { DebugMsg((DM_WARNING, TEXT("GPMDlgProc: Failed to get IADs interface with 0x%x"), hr)); ReportError(hDlg, hr, IDS_FAILEDGPINFO); lpGPO->bLocked = FALSE; break; } } else if (iResult == 2) { // // Confirm the delete operation // LoadString (g_hInstance, IDS_DELETECONFIRM, szMessageFmt, ARRAYSIZE(szMessageFmt)); lpMessage = (LPTSTR) LocalAlloc (LPTR, (lstrlen(szMessageFmt) + lstrlen(lpGPO->lpDisplayName) + 1) * sizeof(TCHAR)); if (!lpMessage) { DebugMsg((DM_WARNING, TEXT("GPMDlgProc: Failed to allocate memory with %d."), GetLastError())); SetFocus (hLV); ClearWaitCursor (); lpGPO->bLocked = FALSE; break; } wsprintf (lpMessage, szMessageFmt, lpGPO->lpDisplayName); LoadString (g_hInstance, IDS_CONFIRMTITLE, szTitle, ARRAYSIZE(szTitle)); if (MessageBox (hDlg, lpMessage, szTitle, MB_YESNO | MB_ICONEXCLAMATION) != IDYES) { LocalFree (lpMessage); SetFocus (hLV); lpGPO->bLocked = FALSE; break; } LocalFree (lpMessage); SetWaitCursor (); lpDSPath = (LPTSTR) LocalAlloc (LPTR, (lstrlen(lpGPO->lpDSPath) + 1) * sizeof(TCHAR)); if (!lpDSPath) { DebugMsg((DM_WARNING, TEXT("GPMDlgProc: Failed to allocate memory with %d."), GetLastError())); SetFocus (hLV); ClearWaitCursor (); lpGPO->bLocked = FALSE; break; } lstrcpy (lpDSPath, lpGPO->lpDSPath); // // Create a new GPO object to work with // hr = CoCreateInstance (CLSID_GroupPolicyObject, NULL, CLSCTX_SERVER, IID_IGroupPolicyObject, (void**)&pGPO); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("GPMDlgProc: Failed to create GPO object with 0x%x."), hr)); LocalFree (lpDSPath); SetFocus (hLV); ClearWaitCursor (); lpGPO->bLocked = FALSE; break; } lpFullPath = pGPM->GetFullGPOPath (lpGPO->lpDSPath, hDlg); if (!lpFullPath) { pGPO->Release(); LocalFree (lpDSPath); SetFocus (hLV); ClearWaitCursor (); lpGPO->bLocked = FALSE; break; } // // Open the requested object without mounting the registry // hr = pGPO->OpenDSGPO(lpFullPath, 0); LocalFree (lpFullPath); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("GPMDlgProc: Failed to open GPO object with 0x%x."), hr)); ReportError(hDlg, hr, IDS_FAILEDGPODELETE, lpGPO->lpDisplayName); pGPO->Release(); LocalFree (lpDSPath); SetFocus (hLV); ClearWaitCursor (); lpGPO->bLocked = FALSE; break; } // // Delete the object // hr = pGPO->Delete(); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("GPMDlgProc: Failed to delete GPO object with 0x%x."), hr)); ReportError(hDlg, hr, IDS_FAILEDGPODELETE, lpGPO->lpDisplayName); pGPO->Release(); LocalFree (lpDSPath); SetFocus (hLV); ClearWaitCursor (); lpGPO->bLocked = FALSE; break; } pGPO->Release(); // // Delete all the entries of this item in the listview // iIndex = (ListView_GetItemCount (hLV) - 1); while (iIndex >= 0) { item.mask = LVIF_PARAM; item.iItem = iIndex; item.iSubItem = 0; if (!ListView_GetItem (hLV, &item)) { lpGPO->bLocked = FALSE; break; } lpTemp = (LPGPOITEM) item.lParam; if (lpTemp) { if (!lstrcmpi(lpTemp->lpDSPath, lpDSPath)) { if (iNext == iIndex) { iNext--; } ListView_DeleteItem (hLV, iIndex); } } iIndex--; } LocalFree (lpDSPath); ClearWaitCursor (); } if (iNext < 0) { iNext = 0; } // // Select the next item // item.mask = LVIF_STATE; item.iItem = iNext; item.iSubItem = 0; item.state = LVIS_SELECTED | LVIS_FOCUSED; item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; SendMessage (hLV, LVM_SETITEMSTATE, iNext, (LPARAM) &item); pGPM->m_bDirty = TRUE; if (!pGPM->Save(hDlg)) { pGPM->RefreshGPM (hDlg, FALSE); } SendMessage (GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0); SetFocus (hLV); PostMessage (hDlg, WM_REFRESHDISPLAY, 0, 0); lpGPO->bLocked = FALSE; } } if (LOWORD(wParam) == IDC_GPM_UP) { INT iSrc, iDest, iSrcImage, iDestImage; LPGPOITEM lpSrc, lpDest; HWND hLV = GetDlgItem(hDlg, IDC_GPM_LIST); LVITEM item; ListView_EditLabel (hLV, -1); iSrc = ListView_GetNextItem (hLV, -1, LVNI_ALL | LVNI_SELECTED); if (iSrc != -1) { iDest = iSrc - 1; // // Get the current lpGPOItem pointers // item.mask = LVIF_PARAM | LVIF_IMAGE; item.iItem = iSrc; item.iSubItem = 0; if (!ListView_GetItem (hLV, &item)) { break; } lpSrc = (LPGPOITEM) item.lParam; iSrcImage = item.iImage; item.mask = LVIF_PARAM | LVIF_IMAGE; item.iItem = iDest; item.iSubItem = 0; if (!ListView_GetItem (hLV, &item)) { break; } lpDest = (LPGPOITEM) item.lParam; iDestImage = item.iImage; // // Swap them // item.mask = LVIF_PARAM | LVIF_IMAGE; item.iItem = iSrc; item.iImage = iDestImage; item.iSubItem = 0; item.lParam = (LPARAM)lpDest; if (!ListView_SetItem (hLV, &item)) { break; } item.mask = LVIF_PARAM | LVIF_IMAGE; item.iItem = iDest; item.iImage = iSrcImage; item.iSubItem = 0; item.lParam = (LPARAM)lpSrc; if (!ListView_SetItem (hLV, &item)) { break; } // // Select the item // item.mask = LVIF_STATE; item.iItem = iSrc; item.iSubItem = 0; item.state = 0; item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; SendMessage (hLV, LVM_SETITEMSTATE, iSrc, (LPARAM) &item); item.mask = LVIF_STATE; item.iItem = iDest; item.iSubItem = 0; item.state = LVIS_SELECTED | LVIS_FOCUSED; item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; SendMessage (hLV, LVM_SETITEMSTATE, iDest, (LPARAM) &item); SendMessage (hLV, LVM_ENSUREVISIBLE, iDest, (LPARAM) FALSE); // // Update the listview // ListView_RedrawItems (hLV, iDest, iSrc); pGPM->m_bDirty = TRUE; SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); SetFocus (hLV); } } if (LOWORD(wParam) == IDC_GPM_DOWN) { INT iSrc, iDest, iSrcImage, iDestImage; LPGPOITEM lpSrc, lpDest; HWND hLV = GetDlgItem(hDlg, IDC_GPM_LIST); LVITEM item; ListView_EditLabel (hLV, -1); iSrc = ListView_GetNextItem (hLV, -1, LVNI_ALL | LVNI_SELECTED); if (iSrc != -1) { iDest = iSrc + 1; // // Get the current lpGPOItem pointers // item.mask = LVIF_PARAM | LVIF_IMAGE; item.iItem = iSrc; item.iSubItem = 0; if (!ListView_GetItem (hLV, &item)) { break; } lpSrc = (LPGPOITEM) item.lParam; iSrcImage = item.iImage; item.mask = LVIF_PARAM | LVIF_IMAGE; item.iItem = iDest; item.iSubItem = 0; if (!ListView_GetItem (hLV, &item)) { break; } lpDest = (LPGPOITEM) item.lParam; iDestImage = item.iImage; // // Swap them // item.mask = LVIF_PARAM | LVIF_IMAGE; item.iItem = iSrc; item.iImage = iDestImage; item.iSubItem = 0; item.lParam = (LPARAM)lpDest; if (!ListView_SetItem (hLV, &item)) { break; } item.mask = LVIF_PARAM | LVIF_IMAGE; item.iItem = iDest; item.iImage = iSrcImage; item.iSubItem = 0; item.lParam = (LPARAM)lpSrc; if (!ListView_SetItem (hLV, &item)) { break; } // // Select the item // item.mask = LVIF_STATE; item.iItem = iSrc; item.iSubItem = 0; item.state = 0; item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; SendMessage (hLV, LVM_SETITEMSTATE, iSrc, (LPARAM) &item); item.mask = LVIF_STATE; item.iItem = iDest; item.iSubItem = 0; item.state = LVIS_SELECTED | LVIS_FOCUSED; item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; SendMessage (hLV, LVM_SETITEMSTATE, iDest, (LPARAM) &item); SendMessage (hLV, LVM_ENSUREVISIBLE, iDest, (LPARAM) FALSE); // // Update the listview // ListView_RedrawItems (hLV, iSrc, iDest); pGPM->m_bDirty = TRUE; SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); SetFocus (hLV); } } if (LOWORD(wParam) == IDM_GPM_NOOVERRIDE) { INT iIndex; LPGPOITEM lpItem; LVITEM item; HWND hLV = GetDlgItem(hDlg, IDC_GPM_LIST); // // Enumerate through the selected items // iIndex = ListView_GetNextItem (hLV, -1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { item.mask = LVIF_PARAM; item.iItem = iIndex; item.iSubItem = 0; if (ListView_GetItem (hLV, &item)) { lpItem = (LPGPOITEM) item.lParam; lpItem->bLocked = TRUE; if (lpItem->dwOptions & GPO_FLAG_FORCE) lpItem->dwOptions &= ~GPO_FLAG_FORCE; else lpItem->dwOptions |= GPO_FLAG_FORCE; ListView_RedrawItems (hLV, iIndex, iIndex); UpdateWindow (hLV); pGPM->m_bDirty = TRUE; SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); SetFocus (hLV); lpItem->bLocked = FALSE; } } } if (LOWORD(wParam) == IDM_GPM_DISABLED) { INT iIndex; LPGPOITEM lpItem; LVITEM item; HWND hLV = GetDlgItem(hDlg, IDC_GPM_LIST); // // Enumerate through the selected items // iIndex = ListView_GetNextItem (hLV, -1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { item.mask = LVIF_PARAM; item.iItem = iIndex; item.iSubItem = 0; if (ListView_GetItem (hLV, &item)) { lpItem = (LPGPOITEM) item.lParam; if (lpItem->dwOptions & GPO_FLAG_DISABLE) lpItem->dwOptions &= ~GPO_FLAG_DISABLE; else { if (bDisableWarningIssued) { lpItem->dwOptions |= GPO_FLAG_DISABLE; } else { 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) == IDYES) { lpItem->dwOptions |= GPO_FLAG_DISABLE; } } } ListView_RedrawItems (hLV, iIndex, iIndex); UpdateWindow (hLV); pGPM->m_bDirty = TRUE; SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); SetFocus (hLV); } } } if ((LOWORD(wParam) == IDC_GPM_EDIT) || (LOWORD(wParam) == IDM_GPM_EDIT)) { INT iIndex; LPGPOITEM lpItem; LVITEM item; HWND hLV = GetDlgItem(hDlg, IDC_GPM_LIST); // // Enumerate through the selected items // iIndex = ListView_GetNextItem (hLV, -1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { item.mask = LVIF_PARAM; item.iItem = iIndex; item.iSubItem = 0; if (ListView_GetItem (hLV, &item)) { lpItem = (LPGPOITEM) item.lParam; lpItem->bLocked = TRUE; pGPM->StartGPE (lpItem->lpDSPath, hDlg); lpItem->bLocked = FALSE; SetFocus (hLV); } } } if ((LOWORD(wParam) == IDC_GPM_NEW) || (LOWORD(wParam) == IDM_GPM_NEW)) { SetWaitCursor(); pGPM->OnNew (hDlg); ClearWaitCursor(); } if (LOWORD(wParam) == IDC_GPM_OPTIONS) { INT iIndex; LPGPOITEM lpItem; LVITEM item; HWND hLV = GetDlgItem(hDlg, IDC_GPM_LIST); // // Enumerate through the selected items // iIndex = ListView_GetNextItem (hLV, -1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { item.mask = LVIF_PARAM; item.iItem = iIndex; item.iSubItem = 0; if (ListView_GetItem (hLV, &item)) { lpItem = (LPGPOITEM) item.lParam; lpItem->bLocked = TRUE; if (DialogBoxParam (g_hInstance, MAKEINTRESOURCE(IDD_GPM_LINK_OPTIONS), hDlg, LinkOptionsDlgProc, (LPARAM) lpItem)) { ListView_RedrawItems (hLV, iIndex, iIndex); UpdateWindow (hLV); pGPM->m_bDirty = TRUE; SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); } lpItem->bLocked = FALSE; SetFocus (hLV); } } } if (LOWORD(wParam) == IDM_GPM_RENAME) { INT iIndex; HWND hLV = GetDlgItem(hDlg, IDC_GPM_LIST); // // Enumerate through the selected items // iIndex = ListView_GetNextItem (hLV, -1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { ListView_EditLabel (hLV, iIndex); } } if ((LOWORD(wParam) == IDC_GPM_PROPERTIES) || (LOWORD(wParam) == IDM_GPM_PROPERTIES)) { pGPM->OnProperties (hDlg); } if (LOWORD(wParam) == IDM_GPM_REFRESH) { pGPM->RefreshGPM (hDlg, FALSE); } if (LOWORD(wParam) == IDC_GPM_BLOCK) { pGPM->m_bDirty = TRUE; SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); } break; case WM_NOTIFY: pGPM = (CGroupPolicyMgr *) GetWindowLongPtr (hDlg, DWLP_USER); if (!pGPM) { break; } switch (((NMHDR FAR*)lParam)->code) { case NM_CUSTOMDRAW: { LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam; SelectObject(lplvcd->nmcd.hdc, pGPM->m_hDefaultFont); if ((lplvcd->nmcd.dwDrawStage == CDDS_PREPAINT) || (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)) { SetWindowLongPtr (hDlg, DWLP_MSGRESULT, CDRF_NOTIFYSUBITEMDRAW); return TRUE; } if ((lplvcd->nmcd.dwDrawStage == (CDDS_SUBITEM | CDDS_ITEMPREPAINT)) && (lplvcd->iSubItem > 0)) { SelectObject(lplvcd->nmcd.hdc, pGPM->m_hMarlettFont); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, CDRF_NEWFONT); return TRUE; } SetWindowLongPtr (hDlg, DWLP_MSGRESULT, CDRF_DODEFAULT); return TRUE; } case LVN_GETDISPINFO: { NMLVDISPINFO * lpDispInfo = (NMLVDISPINFO *) lParam; LPGPOITEM lpItem = (LPGPOITEM)lpDispInfo->item.lParam; if (lpDispInfo->item.iSubItem == 0) { lpDispInfo->item.pszText = lpItem->lpDisplayName; } else { lpDispInfo->item.pszText = szNoCheckMark; if ((lpDispInfo->item.iSubItem == 1) && (lpItem->dwOptions & GPO_FLAG_FORCE)) { lpDispInfo->item.pszText = szCheckMark; } if ((lpDispInfo->item.iSubItem == 2) && (lpItem->dwOptions & GPO_FLAG_DISABLE)) { lpDispInfo->item.pszText = szCheckMark; } } } break; case LVN_DELETEITEM: { NMLISTVIEW * pLVInfo = (NMLISTVIEW *) lParam; if (pLVInfo->lParam) { LocalFree ((LPTSTR)pLVInfo->lParam); } } break; case LVN_ITEMCHANGED: PostMessage (hDlg, WM_REFRESHDISPLAY, 0, 0); break; case LVN_ITEMACTIVATE: { LPNMITEMACTIVATE pItem = (LPNMITEMACTIVATE) lParam; LPGPOITEM lpItem; LVITEM item; HWND hLV = GetDlgItem(hDlg, IDC_GPM_LIST); if (pItem->uKeyFlags != 0) { break; } item.mask = LVIF_PARAM; item.iItem = pItem->iItem; item.iSubItem = 0; if (!ListView_GetItem (hLV, &item)) { break; } lpItem = (LPGPOITEM) item.lParam; if (!lpItem) { break; } if (pItem->iSubItem == 0) { if (!lpItem->bReadOnly) { pGPM->StartGPE (lpItem->lpDSPath, hDlg); } } else if (pItem->iSubItem == 1) { if (!pGPM->m_bReadOnly) { if (lpItem->dwOptions & GPO_FLAG_FORCE) lpItem->dwOptions &= ~GPO_FLAG_FORCE; else lpItem->dwOptions |= GPO_FLAG_FORCE; ListView_RedrawItems (hLV, pItem->iItem, pItem->iItem); UpdateWindow (hLV); pGPM->m_bDirty = TRUE; SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); } } else if (pItem->iSubItem == 2) { if (!pGPM->m_bReadOnly) { lpItem = (LPGPOITEM) item.lParam; if (lpItem->dwOptions & GPO_FLAG_DISABLE) { lpItem->dwOptions &= ~GPO_FLAG_DISABLE; } else { if (bDisableWarningIssued) { lpItem->dwOptions |= GPO_FLAG_DISABLE; } else { 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) == IDYES) { lpItem->dwOptions |= GPO_FLAG_DISABLE; } } } ListView_RedrawItems (hLV, pItem->iItem, pItem->iItem); UpdateWindow (hLV); pGPM->m_bDirty = TRUE; SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); } } } break; case LVN_BEGINLABELEDIT: { NMLVDISPINFO * pInfo = (NMLVDISPINFO *) lParam; LPGPOITEM lpItem; if (pInfo) { lpItem = (LPGPOITEM) pInfo->item.lParam; if (lpItem) { if (lpItem->bReadOnly) { SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 1); return TRUE; } else { HWND hEdit; hEdit = ListView_GetEditControl(GetDlgItem(hDlg, IDC_GPM_LIST)); if (hEdit) { SetWindowText (hEdit, lpItem->lpGPOName); } } } } } break; case LVN_ENDLABELEDIT: { NMLVDISPINFO * pInfo = (NMLVDISPINFO *) lParam; LPGROUPPOLICYOBJECT pGPO; LPGPOITEM lpItem, lpTemp; LV_ITEM item; HRESULT hr; DWORD dwSize; LPTSTR lpFullPath; TCHAR szDisplayName[MAX_FRIENDLYNAME]; if (pInfo->item.pszText && (*pInfo->item.pszText)) { // // Get the LPGPOITEM pointer // lpItem = (LPGPOITEM) pInfo->item.lParam; if (!lpItem) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::GPMDlgProc: NULL lpGPOItem pointer"))); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 0); return TRUE; } if ( lpItem->bLocked ) { SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 0); return TRUE; } // // Create a GPO object to work with // hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL, CLSCTX_SERVER, IID_IGroupPolicyObject, (void **)&pGPO); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::GPMDlgProc: CoCreateInstance failed with 0x%x"), hr)); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 0); return TRUE; } lpFullPath = pGPM->GetFullGPOPath (lpItem->lpDSPath, hDlg); if (!lpFullPath) { pGPO->Release(); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 0); return TRUE; } // // Open GPO object without opening registry data // hr = pGPO->OpenDSGPO(lpFullPath, 0); LocalFree (lpFullPath); if (FAILED(hr)) { ReportError(hDlg, hr, IDS_FAILEDDS); DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::GPMDlgProc: OpenDSGPO failed with 0x%x"), hr)); pGPO->Release(); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 0); return TRUE; } // // Rename it // hr = pGPO->SetDisplayName(pInfo->item.pszText); if (FAILED(hr)) { ReportError(hDlg, hr, IDS_FAILEDSETNAME); DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::GPMDlgProc: SetDisplayName failed with 0x%x"), hr)); pGPO->Release(); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 0); return TRUE; } // // Query for the display name again in case its been truncated // hr = pGPO->GetDisplayName(szDisplayName, ARRAYSIZE(szDisplayName)); if (FAILED(hr)) { ReportError(hDlg, hr, IDS_FAILEDSETNAME); DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::GPMDlgProc: GetDisplayName failed with 0x%x"), hr)); pGPO->Release(); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 0); return TRUE; } pGPO->Release(); // // Update the name in the LPGPOITEM structure // lpTemp = pGPM->CreateEntry (szDisplayName, lpItem->lpDSPath, lpItem->dwOptions, lpItem->dwDisabled, lpItem->bReadOnly); if (!lpTemp) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::GPMDlgProc: Failed to create replacement entry."))); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 1); return TRUE; } ZeroMemory (&item, sizeof(item)); item.mask = LVIF_PARAM; item.iItem = pInfo->item.iItem; item.lParam = (LPARAM)lpTemp; ListView_SetItem (GetDlgItem (hDlg, IDC_GPM_LIST), &item); LocalFree (lpItem); SetWindowLongPtr (hDlg, DWLP_MSGRESULT, 1); } } return TRUE; case LVN_KEYDOWN: { LPNMLVKEYDOWN pKey = (LPNMLVKEYDOWN) lParam; if (pKey->wVKey == VK_DELETE) { if (!pGPM->m_bReadOnly) { PostMessage (hDlg, WM_COMMAND, IDC_GPM_DELETE, 0); } } if (pKey->wVKey == VK_F5) { PostMessage (hDlg, WM_COMMAND, IDM_GPM_REFRESH, 0); } if (pKey->wVKey == VK_RETURN) { PostMessage (hDlg, WM_COMMAND, IDM_GPM_PROPERTIES, 0); } if (pKey->wVKey == VK_F2) { HWND hLV; int i; LPGPOITEM lpItem; LV_ITEM item; // // Allow the rename only if it is possible to rename // // // Get the selected item (if any) // hLV = GetDlgItem (hDlg, IDC_GPM_LIST); i = ListView_GetNextItem(GetDlgItem (hDlg, IDC_GPM_LIST), -1, LVNI_SELECTED); if (i >= 0) { // // Get the lpGPOItem structure pointer // ZeroMemory(&item, sizeof(item)); item.mask = LVIF_PARAM; item.iItem = i; ListView_GetItem(hLV, &item); lpItem = (LPGPOITEM)item.lParam; if ( (lpItem) && (!(lpItem->bReadOnly)) ) { PostMessage (hDlg, WM_COMMAND, IDM_GPM_RENAME, 0); } } } } break; case PSN_APPLY: { PSHNOTIFY * pNotify = (PSHNOTIFY *) lParam; if (!pGPM->Save(hDlg)) { SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_INVALID); return TRUE; } } // fall through... case PSN_RESET: SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR); return TRUE; } break; case WM_REFRESHDISPLAY: { INT iIndex, iCount; LPGPOITEM lpItem = NULL; HWND hLV = GetDlgItem(hDlg, IDC_GPM_LIST); LVITEM item; pGPM = (CGroupPolicyMgr *) GetWindowLongPtr (hDlg, DWLP_USER); iIndex = ListView_GetNextItem (hLV, -1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { item.mask = LVIF_PARAM; item.iItem = iIndex; item.iSubItem = 0; if (!ListView_GetItem (hLV, &item)) { break; } lpItem = (LPGPOITEM) item.lParam; } if (pGPM && (!pGPM->m_bReadOnly)) { if (iIndex != -1) { EnableWindow (GetDlgItem (hDlg, IDC_GPM_DELETE), TRUE); if (lpItem && !lpItem->bReadOnly) { EnableWindow (GetDlgItem (hDlg, IDC_GPM_EDIT), TRUE); } else { EnableWindow (GetDlgItem (hDlg, IDC_GPM_EDIT), FALSE); } EnableWindow (GetDlgItem (hDlg, IDC_GPM_OPTIONS), TRUE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_PROPERTIES), TRUE); iCount = ListView_GetItemCount(hLV); if (iIndex > 0) EnableWindow (GetDlgItem (hDlg, IDC_GPM_UP), TRUE); else EnableWindow (GetDlgItem (hDlg, IDC_GPM_UP), FALSE); if (iIndex < (iCount - 1)) EnableWindow (GetDlgItem (hDlg, IDC_GPM_DOWN), TRUE); else EnableWindow (GetDlgItem (hDlg, IDC_GPM_DOWN), FALSE); } else { EnableWindow (GetDlgItem (hDlg, IDC_GPM_DELETE), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_EDIT), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_UP), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_DOWN), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_OPTIONS), FALSE); EnableWindow (GetDlgItem (hDlg, IDC_GPM_PROPERTIES), FALSE); } } else { if (lpItem) { EnableWindow (GetDlgItem (hDlg, IDC_GPM_PROPERTIES), TRUE); if (!lpItem->bReadOnly) { EnableWindow (GetDlgItem (hDlg, IDC_GPM_EDIT), TRUE); } else { EnableWindow (GetDlgItem (hDlg, IDC_GPM_EDIT), FALSE); } } else { EnableWindow (GetDlgItem (hDlg, IDC_GPM_PROPERTIES), FALSE); } } } break; case WM_CONTEXTMENU: if (GetDlgItem(hDlg, IDC_GPM_LIST) == (HWND)wParam) { pGPM = (CGroupPolicyMgr *) GetWindowLongPtr (hDlg, DWLP_USER); if (pGPM) { pGPM->OnContextMenu(hDlg, lParam); } } else { // right mouse click WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU, (ULONG_PTR) (LPSTR) aGroupPolicyMgrHelpIds); } return TRUE; case WM_HELP: // F1 WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (ULONG_PTR) (LPSTR) aGroupPolicyMgrHelpIds); break; } return FALSE; } void CGroupPolicyMgr::OnContextMenu(HWND hDlg, LPARAM lParam) { LPGPOITEM lpItem; LV_ITEM item; HMENU hPopup; HWND hLV; int i; RECT rc; POINT pt; // // Get the selected item (if any) // hLV = GetDlgItem (hDlg, IDC_GPM_LIST); i = ListView_GetNextItem(hLV, -1, LVNI_SELECTED); // // Figure out where to place the context menu // pt.x = ((int)(short)LOWORD(lParam)); pt.y = ((int)(short)HIWORD(lParam)); GetWindowRect (hLV, &rc); if (!PtInRect (&rc, pt)) { if ((lParam == (LPARAM) -1) && (i >= 0)) { rc.left = LVIR_SELECTBOUNDS; SendMessage (hLV, LVM_GETITEMRECT, i, (LPARAM) &rc); pt.x = rc.left + 8; pt.y = rc.top + ((rc.bottom - rc.top) / 2); ClientToScreen (hLV, &pt); } else { pt.x = rc.left + ((rc.right - rc.left) / 2); pt.y = rc.top + ((rc.bottom - rc.top) / 2); } } // // Load the context menu // hPopup = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_GPM_CONTEXTMENU)); if (!hPopup) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnContextMenu: LoadMenu failed with error %d"), GetLastError())); return; } HMENU hSubMenu = GetSubMenu(hPopup, 0); // // If there is an item selected, then set the checkmarks appropriately // if (i >= 0) { // // Get the lpGPOItem structure pointer // ZeroMemory(&item, sizeof(item)); item.mask = LVIF_PARAM; item.iItem = i; ListView_GetItem(hLV, &item); lpItem = (LPGPOITEM)item.lParam; if (!lpItem) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnContextMenu: Failed to get lpGPOItem pointer"))); return; } // // Check the menu items // if (lpItem->dwOptions & GPO_FLAG_DISABLE) { CheckMenuRadioItem(hSubMenu, IDM_GPM_DISABLED, IDM_GPM_DISABLED, IDM_GPM_DISABLED, MF_BYCOMMAND); } if (lpItem->dwOptions & GPO_FLAG_FORCE) { CheckMenuRadioItem(hSubMenu, IDM_GPM_NOOVERRIDE, IDM_GPM_NOOVERRIDE, IDM_GPM_NOOVERRIDE, MF_BYCOMMAND); } RemoveMenu(hSubMenu, 9, MF_BYPOSITION); RemoveMenu(hSubMenu, IDM_GPM_REFRESH, MF_BYCOMMAND); // // Gray out Edit / Rename if read only // if (lpItem->bReadOnly) { EnableMenuItem (hSubMenu, IDM_GPM_EDIT, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hSubMenu, IDM_GPM_RENAME, MF_BYCOMMAND | MF_GRAYED); } } else { // // No item selected, remove some of the items on the // context menu // RemoveMenu(hSubMenu, IDM_GPM_NOOVERRIDE, MF_BYCOMMAND); RemoveMenu(hSubMenu, IDM_GPM_DISABLED, MF_BYCOMMAND); RemoveMenu(hSubMenu, 0, MF_BYPOSITION); RemoveMenu(hSubMenu, IDM_GPM_EDIT, MF_BYCOMMAND); RemoveMenu(hSubMenu, IDM_GPM_DELETE, MF_BYCOMMAND); RemoveMenu(hSubMenu, IDM_GPM_RENAME, MF_BYCOMMAND); RemoveMenu(hSubMenu, IDM_GPM_PROPERTIES, MF_BYCOMMAND); RemoveMenu(hSubMenu, (GetMenuItemCount(hSubMenu) - 1), MF_BYPOSITION); RemoveMenu(hSubMenu, (GetMenuItemCount(hSubMenu) - 2), MF_BYPOSITION); } // // Gray out some menu items in read only mode // if (m_bReadOnly) { EnableMenuItem (hSubMenu, IDM_GPM_NEW, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hSubMenu, IDM_GPM_ADD, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hSubMenu, IDM_GPM_DELETE, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hSubMenu, IDM_GPM_NOOVERRIDE, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem (hSubMenu, IDM_GPM_DISABLED, MF_BYCOMMAND | MF_GRAYED); } // // Display the menu // TrackPopupMenu(hSubMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hDlg, NULL); DestroyMenu(hPopup); } void CGroupPolicyMgr::OnProperties(HWND hDlg) { INT iIndex; LVITEM item; HWND hLV; HRESULT hr; LPGPOITEM pItem; LPGROUPPOLICYOBJECT pGPO; HPROPSHEETPAGE *hPages; UINT i, uPageCount; PROPSHEETHEADER psh; LPTSTR lpTemp; // // Get the selected item // hLV = GetDlgItem (hDlg, IDC_GPM_LIST); iIndex = ListView_GetNextItem(hLV, -1, LVNI_ALL | LVNI_SELECTED); if (iIndex >= 0) { SetWaitCursor(); // // Get the lpGPOItem pointer // ZeroMemory(&item, sizeof(item)); item.mask = LVIF_PARAM; item.iItem = iIndex; ListView_GetItem(hLV, &item); pItem = (LPGPOITEM)item.lParam; if (!pItem) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnProperties: Failed to get lpGPOItem pointer"))); ClearWaitCursor(); return; } pItem->bLocked = TRUE; hr = CoCreateInstance (CLSID_GroupPolicyObject, NULL, CLSCTX_SERVER, IID_IGroupPolicyObject, (void**)&pGPO); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnProperties: CoCreateInstance failed with 0x%x"), hr)); pItem->bLocked = FALSE; ClearWaitCursor(); return; } lpTemp = GetFullGPOPath (pItem->lpDSPath, hDlg); if (!lpTemp) { ClearWaitCursor(); pItem->bLocked = FALSE; ReportError(hDlg, hr, IDS_FAILEDDS); return; } // // Open the requested object without mounting the registry // hr = pGPO->OpenDSGPO(lpTemp, pItem->bReadOnly ? GPO_OPEN_READ_ONLY : 0); LocalFree (lpTemp); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnProperties: Failed to open GPO object with 0x%x"), hr)); pItem->bLocked = FALSE; ClearWaitCursor(); ReportError(hDlg, hr, IDS_FAILEDDS); return; } // // Ask the GPO for the property sheet pages // hr = pGPO->GetPropertySheetPages (&hPages, &uPageCount); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnProperties: Failed to query property sheet pages with 0x%x."), hr)); pGPO->Release(); pItem->bLocked = FALSE; ClearWaitCursor(); return; } // // Display the property sheet // ZeroMemory (&psh, sizeof(psh)); psh.dwSize = sizeof(psh); psh.dwFlags = PSH_PROPTITLE; psh.hwndParent = hDlg; psh.hInstance = g_hInstance; psh.pszCaption = pItem->lpDisplayName; psh.nPages = uPageCount; psh.phpage = hPages; PropertySheet (&psh); LocalFree (hPages); pGPO->Release(); CheckIconStatus (hLV, pItem); pItem->bLocked = FALSE; ClearWaitCursor(); } } void CGroupPolicyMgr::OnNew(HWND hDlg) { HRESULT hr; HWND hLV; INT iIndex; LPGROUPPOLICYOBJECT pGPO = NULL; TCHAR szName[256]; TCHAR szGPOPath[MAX_PATH]; LPOLESTR lpDomain = NULL; HKEY hKey; DWORD dwSize, dwType; BOOL bDisabledLink = FALSE; // // Check if there is a user preference or policy that // any new GPOs should be created with a disabled link // by default // if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(bDisabledLink); RegQueryValueEx (hKey, NEW_LINKS_DISABLED_VALUE, NULL, &dwType, (LPBYTE) &bDisabledLink, &dwSize); RegCloseKey (hKey); } if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_POLICIES_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(bDisabledLink); RegQueryValueEx (hKey, NEW_LINKS_DISABLED_VALUE, NULL, &dwType, (LPBYTE) &bDisabledLink, &dwSize); RegCloseKey (hKey); } // // Get the domain name // lpDomain = GetDomainFromLDAPPath(m_lpDSObject); if (!lpDomain) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnNew: Failed to get the domain name"))); goto Exit; } // // Create a new GPO object to work with // hr = CoCreateInstance (CLSID_GroupPolicyObject, NULL, CLSCTX_SERVER, IID_IGroupPolicyObject, (void**)&pGPO); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnNew: CoCreateInstance failed with 0x%x"), hr)); goto Exit; } // // Create a new GPO without mounting the registry // GetNewGPODisplayName (szName, ARRAYSIZE(szName)); #if FGPO_SUPPORT hr = pGPO->New(lpDomain, szName, (m_gpHint == GPHintForest) ? GPO_OPEN_FOREST : 0); #else hr = pGPO->New(lpDomain, szName, 0); #endif if (FAILED(hr)) { ReportError(hDlg, hr, IDS_FAILEDNEW); DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnNew: Failed to create GPO object with 0x%x"), hr)); goto Exit; } hr = pGPO->GetPath(szGPOPath, ARRAYSIZE(szGPOPath)); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnNew: Failed to get GPO object path with 0x%x"), hr)); pGPO->Delete(); goto Exit; } // // Add the GPO to the list view // hLV = GetDlgItem (hDlg, IDC_GPM_LIST); if (!AddGPOToList (hLV, szName, szGPOPath, (bDisabledLink ? GPO_FLAG_DISABLE : 0), FALSE, FALSE, FALSE)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnNew: Failed to add the GPO to the listview"))); pGPO->Delete(); goto Exit; } m_bDirty = TRUE; Save(hDlg); SendMessage (GetParent(hDlg), PSM_CANCELTOCLOSE, 0, 0); iIndex = ListView_GetItemCount(hLV) - 1; // // Now trigger an edit of the entry // SetFocus(hLV); ListView_EnsureVisible (hLV, iIndex, FALSE); ListView_EditLabel(hLV, iIndex); Exit: if (lpDomain) { delete [] lpDomain; } if (pGPO) { pGPO->Release(); } } BOOL CGroupPolicyMgr::RefreshGPM (HWND hDlg, BOOL bInitial) { HRESULT hr; BOOL bResult = FALSE; TCHAR szHeaderName[50]; TCHAR szBuffer1[100]; TCHAR szBuffer2[MAX_FRIENDLYNAME]; HWND hLV = GetDlgItem (hDlg, IDC_GPM_LIST); LV_COLUMN col; RECT rc; INT iTotal = 0, iCurrent, iMaxVisibleItems, iSize; IADs * pADs; VARIANT var; BSTR bstrProperty; // // Prep work // SetWaitCursor(); SendMessage (hLV, WM_SETREDRAW, 0, 0); ListView_DeleteAllItems(hLV); CheckDlgButton (hDlg, IDC_GPM_BLOCK, BST_UNCHECKED); // // Insert Columns // if (bInitial) { GetClientRect (hLV, &rc); LoadString(g_hInstance, IDS_GPM_NAME, szHeaderName, ARRAYSIZE(szHeaderName)); col.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; col.fmt = LVCFMT_LEFT; iCurrent = (int)(rc.right * .65); iTotal += iCurrent; col.cx = iCurrent; col.pszText = szHeaderName; col.iSubItem = 0; ListView_InsertColumn (hLV, 0, &col); LoadString(g_hInstance, IDS_GPM_NOOVERRIDE, szHeaderName, ARRAYSIZE(szHeaderName)); iCurrent = (int)(rc.right * .20); iTotal += iCurrent; col.cx = iCurrent; col.fmt = LVCFMT_CENTER; col.iSubItem = 1; ListView_InsertColumn (hLV, 1, &col); LoadString(g_hInstance, IDS_GPM_DISABLED, szHeaderName, ARRAYSIZE(szHeaderName)); col.iSubItem = 2; col.cx = rc.right - iTotal; col.fmt = LVCFMT_CENTER; ListView_InsertColumn (hLV, 2, &col); } // // Set the DC name // if (bInitial) { LoadString (g_hInstance, IDS_GPM_DCNAME, szBuffer1, ARRAYSIZE(szBuffer1)); wsprintf (szBuffer2, szBuffer1, m_lpGPODCName); SetDlgItemText (hDlg, IDC_GPM_DCNAME, szBuffer2); } // // Bind to the object and get the friendly name // hr = OpenDSObject(m_lpDSObject, IID_IADs, (void **)&pADs); if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::RefreshGPM: %s does not exist on the server."), m_lpDSObject)); DialogBoxParam (g_hInstance, MAKEINTRESOURCE(IDD_NODSOBJECT), hDlg, NoDSObjectDlgProc, (LPARAM) this); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::RefreshGPM: OpenDSObject failed with 0x%x"), hr)); ReportError(hDlg, hr, IDS_FAILEDGPQUERY, hr); } goto Exit; } if (bInitial) { #if FGPO_SUPPORT if (m_gpHint != GPHintForest) { #endif VariantInit(&var); bstrProperty = SysAllocString (GPM_NAME_PROPERTY); if (!bstrProperty) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::RefreshGPM: Failed to allocate memory with %d"), GetLastError())); ReportError(hDlg, hr, IDS_FAILEDGPQUERY, hr); VariantClear (&var); pADs->Release(); goto Exit; } hr = pADs->Get(bstrProperty, &var); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::RefreshGPM: Failed to query for display name with 0x%x"), hr)); ReportError(hDlg, hr, IDS_FAILEDGPQUERY, hr); SysFreeString (bstrProperty); VariantClear (&var); pADs->Release(); goto Exit; } LoadString (g_hInstance, IDS_GPM_DESCRIPTION, szBuffer1, ARRAYSIZE(szBuffer1)); wsprintf (szBuffer2, szBuffer1, var.bstrVal); SysFreeString (bstrProperty); VariantClear (&var); #if FGPO_SUPPORT } else { LoadString (g_hInstance, IDS_GPM_FORESTDESC, szBuffer2, ARRAYSIZE(szBuffer2)); } #endif SetDlgItemText (hDlg, IDC_GPM_TITLE, szBuffer2); // // Check if the user has write access to gPLink // hr = CheckDSWriteAccess ((LPUNKNOWN)pADs, TEXT("gPLink")); if (FAILED(hr)) { DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::RefreshGPM: User has read only access to the gPLink property."))); m_bReadOnly = TRUE; } } // // Get the options for this DS object // VariantInit(&var); bstrProperty = SysAllocString (GPM_OPTIONS_PROPERTY); if (bstrProperty) { hr = pADs->Get(bstrProperty, &var); if (SUCCEEDED(hr)) { if (var.lVal & GPC_BLOCK_POLICY) { CheckDlgButton (hDlg, IDC_GPM_BLOCK, BST_CHECKED); } } SysFreeString (bstrProperty); } VariantClear (&var); // // Get the GPOs linked to this object // VariantInit(&var); bstrProperty = SysAllocString (GPM_LINK_PROPERTY); if (bstrProperty) { hr = pADs->Get(bstrProperty, &var); if (SUCCEEDED(hr)) { AddGPOs (hDlg, var.bstrVal); } SysFreeString (bstrProperty); } VariantClear (&var); pADs->Release(); // // Get the max number of visible items and the total number // of items in the listview // if (bInitial) { iMaxVisibleItems = ListView_GetCountPerPage (hLV); iTotal = ListView_GetItemCount(hLV); // // If the number of items in the listview is greater than // the max visible items, then we need to make the first // column smaller by the width of a vertical scroll bar so // that the horizontal scroll bar doesn't appear // if (iTotal > iMaxVisibleItems) { iSize = ListView_GetColumnWidth (hLV, 0); iSize -= GetSystemMetrics(SM_CYHSCROLL); ListView_SetColumnWidth (hLV, 0, iSize); } } PropSheet_UnChanged (GetParent(hDlg), hDlg); // // Success // bResult = TRUE; Exit: SendMessage (hLV, WM_SETREDRAW, 1, 0); ClearWaitCursor(); return bResult; } BOOL CGroupPolicyMgr::OnInitDialog (HWND hDlg) { BOOL bResult = FALSE; HWND hLV = GetDlgItem (hDlg, IDC_GPM_LIST); LOGFONT lf; HICON hIcon; HIMAGELIST hImageList; HRESULT hr; LPOLESTR pszDomain; LPTSTR lpTemp; // // Retreive the name of the DC DSAdmin is using // m_lpDSADCName = ExtractServerName (m_lpDSObject); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyObject::OnInitDialog: DS Admin is focused on DC %s"), m_lpDSADCName)); // // Get the friendly domain name // pszDomain = GetDomainFromLDAPPath(m_lpDSObject); if (!pszDomain) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OnInitDialog: Failed to get domain name"))); return FALSE; } // // Convert LDAP to dot (DN) style // hr = ConvertToDotStyle (pszDomain, &m_lpDomainName); delete [] pszDomain; if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreatePropertyPages: Failed to convert domain name with 0x%x"), hr)); } // // Get the GPO DC for this domain // m_lpGPODCName = GetDCName (m_lpDomainName, m_lpDSADCName, hDlg, TRUE, VALIDATE_INHERIT_DC); if (!m_lpGPODCName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OnInitDialog: Failed to get DC name for %s"), m_lpDomainName)); return FALSE; } // // Switch to using the GPO domain controller for this DS object // lpTemp = MakeFullPath (m_lpDSObject, m_lpGPODCName); if (!lpTemp) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::OnInitDialog: Failed to build new DS object path"))); return FALSE; } LocalFree (m_lpDSObject); m_lpDSObject = lpTemp; // // Create the Marlett font based upon the currently selected font // m_hDefaultFont = (HFONT) SendMessage (hLV, WM_GETFONT, 0, 0); GetObject (m_hDefaultFont, sizeof(lf), &lf); lf.lfHeight += (LONG)(lf.lfHeight * .20); lf.lfCharSet = SYMBOL_CHARSET; lf.lfPitchAndFamily = FF_DECORATIVE | DEFAULT_PITCH; lstrcpy (lf.lfFaceName, TEXT("Marlett")); m_hMarlettFont = CreateFontIndirect (&lf); // // Set extended LV styles // SendMessage(hLV, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP); // // Create the imagelist // hImageList = ImageList_Create (16, 16, ILC_MASK, 3, 3); if (!hImageList) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnInitDialog: Failed to create the image list"))); return FALSE; } hIcon = (HICON) LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_POLICY), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); ImageList_AddIcon (hImageList, hIcon); DestroyIcon (hIcon); hIcon = (HICON) LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_POLICY2), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); ImageList_AddIcon (hImageList, hIcon); DestroyIcon (hIcon); hIcon = (HICON) LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_POLICY3), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); ImageList_AddIcon (hImageList, hIcon); DestroyIcon (hIcon); // // Associate the imagelist with the listview. // The listview will free this when the // control is destroyed. // SendMessage (hLV, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM) hImageList); // // Refresh GPM // if (!RefreshGPM(hDlg, TRUE)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::OnInitDialog: Failed to refresh GPM"))); return FALSE; } return TRUE; } BOOL CGroupPolicyMgr::Save (HWND hDlg) { HRESULT hr; HWND hLV = GetDlgItem (hDlg, IDC_GPM_LIST); IADs * pADs; VARIANT var; BSTR bstrName; LVITEM item; LPGPOITEM lpItem; TCHAR szOptions[12]; LPTSTR lpTemp, lpResult = NULL; DWORD dwStrLen, dwOptions; TCHAR szEmpty [] = TEXT(" "); INT iIndex = -1; if (m_bReadOnly) { DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::Save: User only has read access, so no changes will be saved."))); return TRUE; } if (!m_bDirty) { DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::Save: Nothing has changed (dirty flag is FALSE), so no changes will be saved."))); return TRUE; } // // Enumerate through the selected items // while ((iIndex = ListView_GetNextItem (hLV, iIndex, LVNI_ALL)) != -1) { item.mask = LVIF_PARAM; item.iItem = iIndex; item.iSubItem = 0; if (!ListView_GetItem (hLV, &item)) { continue; } lpItem = (LPGPOITEM) item.lParam; _itot(lpItem->dwOptions, szOptions, 10); // [ ldap path ; options ] 0 dwStrLen = 1 + lstrlen(lpItem->lpDSPath) + 1 + lstrlen(szOptions) + 1 + 1; if (lpResult) { dwStrLen += lstrlen(lpResult); } dwStrLen *= sizeof(TCHAR); lpTemp = (LPTSTR) LocalAlloc (LPTR, dwStrLen); if (!lpTemp) { continue; } lstrcpy (lpTemp, TEXT("[")); lstrcat (lpTemp, lpItem->lpDSPath); lstrcat (lpTemp, TEXT(";")); lstrcat (lpTemp, szOptions); lstrcat (lpTemp, TEXT("]")); if (lpResult) { lstrcat (lpTemp, lpResult); LocalFree (lpResult); } lpResult = lpTemp; } if (!lpResult) { lpResult = szEmpty; } // // Bind to the DS object // hr = OpenDSObject(m_lpDSObject, IID_IADs, (void **)&pADs); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::Save: Failed to get gpo interface with 0x%x"), hr)); ReportError(hDlg, hr, IDS_FAILEDGPINFO); return FALSE; } // // Set the link property // VariantInit(&var); var.vt = VT_BSTR; var.bstrVal = SysAllocString (lpResult); if (!var.bstrVal) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::Save: Failed to allocate memory with %d"), GetLastError())); ReportError(hDlg, hr, IDS_FAILEDGPINFO); VariantClear (&var); pADs->Release(); return FALSE; } bstrName = SysAllocString (GPM_LINK_PROPERTY); if (!bstrName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::Save: Failed to allocate memory with %d"), GetLastError())); ReportError(hDlg, hr, IDS_FAILEDGPINFO); VariantClear (&var); pADs->Release(); return FALSE; } hr = pADs->Put(bstrName, var); SysFreeString (bstrName); VariantClear (&var); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::Save: Failed to put link property with 0x%x"), hr)); ReportError(hDlg, hr, IDS_FAILEDGPINFO); pADs->Release(); return FALSE; } dwOptions = 0; if (IsDlgButtonChecked (hDlg, IDC_GPM_BLOCK) == BST_CHECKED) { dwOptions |= GPC_BLOCK_POLICY; } // // Set the options // VariantInit(&var); var.vt = VT_I4; var.lVal = dwOptions; bstrName = SysAllocString (GPM_OPTIONS_PROPERTY); if (!bstrName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::Save: Failed to allocate memory with %d"), GetLastError())); ReportError(hDlg, hr, IDS_FAILEDGPINFO); VariantClear (&var); pADs->Release(); return FALSE; } hr = pADs->Put(bstrName, var); SysFreeString (bstrName); VariantClear (&var); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::Save: Failed to set options with 0x%x"), hr)); ReportError(hDlg, hr, IDS_FAILEDGPINFO); pADs->Release(); return FALSE; } // // Commit the changes // hr = pADs->SetInfo(); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::Save: Failed to commit changes with 0x%x"), hr)); ReportError(hDlg, hr, IDS_FAILEDGPINFO); pADs->Release(); return FALSE; } if (lpResult != szEmpty) { LocalFree (lpResult); } pADs->Release(); m_bDirty = FALSE; return TRUE; } BOOL CGroupPolicyMgr::AddGPOs (HWND hDlg, LPTSTR lpGPOList) { HRESULT hr; TCHAR szGPO[512]; TCHAR szOptions[20]; TCHAR szDisplayName[MAX_PATH]; DWORD dwOptions; LPTSTR lpTemp, lpGPO, lpNamedGPO; HWND hLV = GetDlgItem (hDlg, IDC_GPM_LIST); IADs * pADs; VARIANT var; BSTR bstrProperty; DWORD dwDisabled; BOOL bReadOnly; if (!lpGPOList) { return TRUE; } lpTemp = lpGPOList; while (TRUE) { szDisplayName[0] = TEXT('\0'); dwDisabled = 0; bReadOnly = FALSE; // // Look for the [ // while (*lpTemp && (*lpTemp != TEXT('['))) lpTemp++; if (!(*lpTemp)) goto Exit; lpTemp++; // // Copy the GPO name // lpGPO = szGPO; while (*lpTemp && (*lpTemp != TEXT(';'))) *lpGPO++ = *lpTemp++; *lpGPO = TEXT('\0'); if (!(*lpTemp)) goto Exit; lpTemp++; // // Get the options // lpGPO = szOptions; while (*lpTemp && (*lpTemp != TEXT(']'))) *lpGPO++ = *lpTemp++; *lpGPO = TEXT('\0'); dwOptions = _ttoi (szOptions); if (!(*lpTemp)) goto Exit; lpTemp++; // // Convert the nameless path into a named path // lpNamedGPO = GetFullGPOPath (szGPO, hDlg); if (lpNamedGPO) { // // Get the friendly display name and GPO options // hr = OpenDSObject(lpNamedGPO, IID_IADs, (void **)&pADs); if (SUCCEEDED(hr)) { VariantInit(&var); bstrProperty = SysAllocString (GPO_NAME_PROPERTY); if (bstrProperty) { hr = pADs->Get(bstrProperty, &var); if (SUCCEEDED(hr)) { lstrcpyn (szDisplayName, var.bstrVal, ARRAYSIZE(szDisplayName)); } SysFreeString (bstrProperty); } VariantClear (&var); // // Query for the options // VariantInit(&var); bstrProperty = SysAllocString (GPO_OPTIONS_PROPERTY); if (bstrProperty) { hr = pADs->Get(bstrProperty, &var); if (SUCCEEDED(hr)) { dwDisabled = var.lVal; } SysFreeString (bstrProperty); } VariantClear (&var); if (FAILED(CheckDSWriteAccess((LPUNKNOWN) pADs, GPO_VERSION_PROPERTY))) { bReadOnly = TRUE; } pADs->Release(); } else { if (hr == HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT)) { DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::AddGPOs: Skipping link to deleted object. %s"), lpNamedGPO)); LocalFree (lpNamedGPO); continue; } DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::AddGPOs: OpenDSObject failed with 0x%x"), hr)); } LocalFree (lpNamedGPO); } else { DebugMsg((DM_WARNING, TEXT("CGroupPolicyMgr::AddGPOs: Failed to get the full domain name for %s"), szGPO)); } if (szDisplayName[0] == TEXT('\0')) { LoadString (g_hInstance, IDS_GPM_NOGPONAME, szDisplayName, ARRAYSIZE(szDisplayName)); dwDisabled = (GPO_OPTION_DISABLE_USER | GPO_OPTION_DISABLE_MACHINE); bReadOnly = TRUE; } AddGPOToList (hLV, szDisplayName, szGPO, dwOptions, TRUE, dwDisabled, bReadOnly); } Exit: return TRUE; } LPGPOITEM CGroupPolicyMgr::CreateEntry (LPTSTR szName, LPTSTR szGPO, DWORD dwOptions, DWORD dwDisabled, BOOL bReadOnly) { LPGPOITEM lpItem; DWORD dwSize; TCHAR szFormat[20]; LPTSTR lpResult, lpName = szName, lpFullName = NULL; LPOLESTR pszDomain; // // Check if the GPO is in this domain // pszDomain = GetDomainFromLDAPPath(szGPO); if (pszDomain) { if (SUCCEEDED(ConvertToDotStyle (pszDomain, &lpResult))) { if (lstrcmpi(lpResult, m_lpDomainName) != 0) { LoadString (g_hInstance, IDS_GPM_DOMAINNAME, szFormat, ARRAYSIZE(szFormat)); lpFullName = (LPTSTR) LocalAlloc (LPTR, (lstrlen (szName) + lstrlen (szFormat) + lstrlen (lpResult)) * sizeof(TCHAR)); if (lpFullName) { wsprintf (lpFullName, szFormat, szName, lpResult); lpName = lpFullName; } } LocalFree (lpResult); } delete [] pszDomain; } // // Calculate the size needed and fill in the structure // dwSize = sizeof(GPOITEM); dwSize += ((lstrlen(lpName) + 1) * sizeof(TCHAR)); dwSize += ((lstrlen(szName) + 1) * sizeof(TCHAR)); dwSize += ((lstrlen(szGPO) + 1) * sizeof(TCHAR)); lpItem = (LPGPOITEM) LocalAlloc (LPTR, dwSize); if (!lpItem) { if (lpFullName) { LocalFree (lpFullName); } return NULL; } lpItem->lpDisplayName = (LPTSTR) (((LPBYTE)lpItem) + sizeof(GPOITEM)); lstrcpy (lpItem->lpDisplayName, lpName); lpItem->lpGPOName = lpItem->lpDisplayName + lstrlen (lpItem->lpDisplayName) + 1; lstrcpy (lpItem->lpGPOName, szName); lpItem->lpDSPath = lpItem->lpGPOName + lstrlen (lpItem->lpGPOName) + 1; lstrcpy (lpItem->lpDSPath, szGPO); lpItem->dwOptions = dwOptions; lpItem->dwDisabled = dwDisabled; lpItem->bReadOnly = bReadOnly; lpItem->bLocked = FALSE; DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::CreateEntry: Adding %s"), lpName)); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::CreateEntry: GPO Name %s"), szName)); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::CreateEntry: DS Path %s"), szGPO)); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::CreateEntry: Options %d"), dwOptions)); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::CreateEntry: Disabled %d"), dwDisabled)); DebugMsg((DM_VERBOSE, TEXT("CGroupPolicyMgr::CreateEntry: ReadOnly %d"), bReadOnly)); if (lpFullName) { LocalFree (lpFullName); } return lpItem; } BOOL CGroupPolicyMgr::AddGPOToList (HWND hLV, LPTSTR szName, LPTSTR szGPO, DWORD dwOptions, BOOL bHighest, DWORD dwDisabled, BOOL bReadOnly) { LPGPOITEM lpItem; LV_ITEM item; INT iItem; // // Create the link list entry // lpItem = CreateEntry (szName, szGPO, dwOptions, dwDisabled, bReadOnly); if (!lpItem) { return FALSE; } // // Add the item // item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; item.iItem = (bHighest ? 0 : ListView_GetItemCount(hLV)); item.iSubItem = 0; item.pszText = LPSTR_TEXTCALLBACK; item.lParam = (LPARAM) lpItem; if ((dwDisabled & GPO_OPTION_DISABLE_USER) && (dwDisabled & GPO_OPTION_DISABLE_MACHINE)) { item.iImage = 1; } else if (dwDisabled == 0) { item.iImage = 0; } else { item.iImage = 2; } iItem = ListView_InsertItem (hLV, &item); // // Select the item // item.mask = LVIF_STATE; item.iItem = iItem; item.iSubItem = 0; item.state = LVIS_SELECTED | LVIS_FOCUSED; item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; SendMessage (hLV, LVM_SETITEMSTATE, 0, (LPARAM) &item); return TRUE; } INT_PTR CALLBACK CGroupPolicyMgr::RemoveGPODlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { LPGPOITEM lpGPO = (LPGPOITEM)lParam; TCHAR szBuffer[200]; LPTSTR lpTitle; HICON hIcon; hIcon = LoadIcon (NULL, IDI_QUESTION); if (hIcon) { SendDlgItemMessage (hDlg, IDC_QUESTION, STM_SETICON, (WPARAM) hIcon, 0); } GetDlgItemText (hDlg, IDC_REMOVE_TITLE, szBuffer, ARRAYSIZE(szBuffer)); lpTitle = (LPTSTR) LocalAlloc (LPTR, (lstrlen(szBuffer) + lstrlen(lpGPO->lpDisplayName) + 1) * sizeof(TCHAR)); if (lpTitle) { wsprintf (lpTitle, szBuffer, lpGPO->lpDisplayName); SetDlgItemText (hDlg, IDC_REMOVE_TITLE, lpTitle); LocalFree (lpTitle); } CheckDlgButton (hDlg, IDC_REMOVE_LIST, BST_CHECKED); if (lpGPO->bReadOnly) { EnableWindow (GetDlgItem(hDlg, IDC_REMOVE_DS), FALSE); } } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: if (IsDlgButtonChecked (hDlg, IDC_REMOVE_LIST) == BST_CHECKED) { EndDialog (hDlg, 1); } else { EndDialog (hDlg, 2); } return TRUE; case IDCANCEL: EndDialog (hDlg, 0); return TRUE; } break; case WM_HELP: // F1 WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (ULONG_PTR) (LPSTR) aRemoveGPOHelpIds); break; case WM_CONTEXTMENU: // right mouse click WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU, (ULONG_PTR) (LPSTR) aRemoveGPOHelpIds); return (TRUE); } return FALSE; } INT_PTR CALLBACK CGroupPolicyMgr::LinkOptionsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { LPGPOITEM lpItem = (LPGPOITEM) lParam; TCHAR szBuffer[50]; LPTSTR lpTitle; SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) lpItem); GetWindowText (hDlg, szBuffer, ARRAYSIZE(szBuffer)); lpTitle = (LPTSTR) LocalAlloc (LPTR, (lstrlen(szBuffer) + lstrlen(lpItem->lpDisplayName) + 1) * sizeof(TCHAR)); if (lpTitle) { wsprintf (lpTitle, szBuffer, lpItem->lpDisplayName); SetWindowText (hDlg, lpTitle); LocalFree (lpTitle); } if (lpItem->dwOptions & GPO_FLAG_DISABLE) { CheckDlgButton (hDlg, IDC_GPM_DISABLED, BST_CHECKED); } if (lpItem->dwOptions & GPO_FLAG_FORCE) { CheckDlgButton (hDlg, IDC_GPM_NOOVERRIDE, BST_CHECKED); } } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_GPM_DISABLED: { if ((HIWORD(wParam) == BN_CLICKED) && (IsDlgButtonChecked (hDlg, IDC_GPM_DISABLED) == BST_CHECKED)) { TCHAR szMessage[200]; TCHAR szTitle[100]; 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, IDC_GPM_DISABLED, BST_UNCHECKED); } } } break; case IDOK: { LPGPOITEM lpItem; DWORD dwTemp = 0; lpItem = (LPGPOITEM) GetWindowLongPtr (hDlg, DWLP_USER); if (IsDlgButtonChecked (hDlg, IDC_GPM_DISABLED) == BST_CHECKED) { dwTemp |= GPO_FLAG_DISABLE; } if (IsDlgButtonChecked (hDlg, IDC_GPM_NOOVERRIDE) == BST_CHECKED) { dwTemp |= GPO_FLAG_FORCE; } if (dwTemp != lpItem->dwOptions) { lpItem->dwOptions = dwTemp; EndDialog (hDlg, 1); } else { EndDialog (hDlg, 0); } } return TRUE; case IDCANCEL: EndDialog (hDlg, 0); return TRUE; } break; case WM_HELP: // F1 WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (ULONG_PTR) (LPSTR) aLinkOptionsHelpIds); break; case WM_CONTEXTMENU: // right mouse click WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU, (ULONG_PTR) (LPSTR) aLinkOptionsHelpIds); return (TRUE); } return FALSE; } INT_PTR CALLBACK CGroupPolicyMgr::NoDSObjectDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { CGroupPolicyMgr *pGPM = (CGroupPolicyMgr *)lParam; TCHAR szBuffer[100]; TCHAR szTitle[300]; LPTSTR lpMsg, lpMsgEx; INT iSize; HWND hMsg = GetDlgItem (hDlg, IDC_NODSOBJECT_TEXT); HICON hIcon; hIcon = LoadIcon (NULL, IDI_ERROR); if (hIcon) { SendDlgItemMessage (hDlg, IDC_NODSOBJECT_ICON, STM_SETICON, (WPARAM) hIcon, 0); } GetWindowText (hDlg, szBuffer, ARRAYSIZE(szBuffer)); wsprintf (szTitle, szBuffer, pGPM->m_lpGPODCName); SetWindowText (hDlg, szTitle); iSize = 600; iSize += lstrlen(pGPM->m_lpGPODCName); iSize += lstrlen(pGPM->m_lpDSADCName); iSize++; lpMsg = (LPTSTR) LocalAlloc(LPTR, iSize * sizeof(TCHAR)); if (lpMsg) { lpMsgEx = (LPTSTR) LocalAlloc(LPTR, iSize * sizeof(TCHAR)); if (lpMsgEx) { LoadString (g_hInstance, IDS_NODSOBJECT_MSG, lpMsg, iSize); wsprintf (lpMsgEx, lpMsg, pGPM->m_lpGPODCName, pGPM->m_lpDSADCName); SetWindowText (hMsg, lpMsgEx); LocalFree (lpMsgEx); } LocalFree (lpMsg); } } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: EndDialog (hDlg, 1); return TRUE; case IDHELP: WinExec("hh.exe spconcepts.chm::/sag_spTShoot.htm", SW_SHOWNORMAL); break; } break; } return FALSE; } DWORD CGroupPolicyMgr::IsGPODisabled(LPTSTR lpGPO) { HRESULT hr; LPTSTR lpTemp; DWORD dwOptions = 0; LPGROUPPOLICYOBJECT pGPO = NULL; // // Create a GroupPolicyObject to work with // hr = CoCreateInstance (CLSID_GroupPolicyObject, NULL, CLSCTX_SERVER, IID_IGroupPolicyObject, (void**)&pGPO); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("IsGPODisabled: Failed to create GPO object with 0x%x."), hr)); return 0; } lpTemp = GetFullGPOPath (lpGPO, NULL); if (!lpTemp) { pGPO->Release(); return 0; } // // Open the requested object without mounting the registry // hr = pGPO->OpenDSGPO(lpTemp, GPO_OPEN_READ_ONLY); LocalFree (lpTemp); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("IsGPODisabled: Failed to open GPO object with 0x%x."), hr)); pGPO->Release(); return 0; } // // Get the options // hr = pGPO->GetOptions(&dwOptions); if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("IsGPODisabled: Failed to get GPO options with 0x%x."), hr)); pGPO->Release(); return 0; } pGPO->Release(); return dwOptions; } void CGroupPolicyMgr::CheckIconStatus (HWND hLV, LPGPOITEM lpGPO) { LPGPOITEM lpItem; LV_ITEM item; INT iIndex = -1; DWORD dwDisabled; // // Check if the GPO disabled // dwDisabled = IsGPODisabled(lpGPO->lpDSPath); // // If the status hasn't changed, exit now // if (dwDisabled == lpGPO->dwDisabled) { return; } // // Enumerate through the items // while ((iIndex = ListView_GetNextItem (hLV, iIndex, LVNI_ALL)) != -1) { item.mask = LVIF_PARAM; item.iItem = iIndex; item.iSubItem = 0; if (!ListView_GetItem (hLV, &item)) { continue; } lpItem = (LPGPOITEM) item.lParam; // // If the item has a path to the GPO in question, // update the icon // if (!lstrcmpi (lpItem->lpDSPath, lpGPO->lpDSPath)) { // // Update the icon if appropriate // item.mask = LVIF_IMAGE; item.iItem = iIndex; item.iSubItem = 0; if ((dwDisabled & GPO_OPTION_DISABLE_USER) && (dwDisabled & GPO_OPTION_DISABLE_MACHINE)) { item.iImage = 1; } else if (dwDisabled == 0) { item.iImage = 0; } else { item.iImage = 2; } SendMessage (hLV, LVM_SETITEM, 0, (LPARAM) &item); ListView_RedrawItems (hLV, iIndex, iIndex); } } lpGPO->dwDisabled = dwDisabled; } LPTSTR CGroupPolicyMgr::GetFullGPOPath (LPTSTR lpGPO, HWND hParent) { LPTSTR lpFullPath = NULL, lpDomainName = NULL; LPTSTR lpGPODCName; LPOLESTR pszDomain; HRESULT hr; // // Get the friendly domain name // pszDomain = GetDomainFromLDAPPath(lpGPO); if (!pszDomain) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetFullGPOPath: Failed to get domain name"))); return NULL; } // // Convert LDAP to dot (DN) style // hr = ConvertToDotStyle (pszDomain, &lpDomainName); delete [] pszDomain; if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreatePropertyPages: Failed to convert domain name with 0x%x"), hr)); return NULL; } if (!lstrcmpi(lpDomainName, m_lpDomainName)) { // // Make the full path // lpFullPath = MakeFullPath (lpGPO, m_lpGPODCName); if (!lpFullPath) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetFullGPOPath: Failed to build new DS object path"))); goto Exit; } } else { // // Get the GPO DC for this domain // lpGPODCName = GetDCName (lpDomainName, NULL, hParent, TRUE, 0); if (!lpGPODCName) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetFullGPOPath: Failed to get DC name for %s"), lpDomainName)); goto Exit; } // // Make the full path // lpFullPath = MakeFullPath (lpGPO, lpGPODCName); LocalFree (lpGPODCName); if (!lpFullPath) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::GetFullGPOPath: Failed to build new DS object path"))); goto Exit; } } Exit: if (lpDomainName) { LocalFree (lpDomainName); } return lpFullPath; } BOOL CGroupPolicyMgr::StartGPE (LPTSTR lpGPO, HWND hParent) { LPTSTR lpDomainName; LPOLESTR pszDomain; HRESULT hr; BOOL bResult; // // Get the friendly domain name // pszDomain = GetDomainFromLDAPPath(lpGPO); if (!pszDomain) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::StartGPE: Failed to get domain name"))); return FALSE; } // // Convert LDAP to dot (DN) style // hr = ConvertToDotStyle (pszDomain, &lpDomainName); delete [] pszDomain; if (FAILED(hr)) { DebugMsg((DM_WARNING, TEXT("CGroupPolicyObject::CreatePropertyPages: Failed to convert domain name with 0x%x"), hr)); return FALSE; } // // Check if the GPO is in the same domain as GPM is focused on // if (!lstrcmpi(lpDomainName, m_lpDomainName)) { bResult = SpawnGPE (lpGPO, m_gpHint, m_lpGPODCName, hParent); } else { bResult = SpawnGPE (lpGPO, m_gpHint, NULL, hParent); } LocalFree (lpDomainName); return bResult; } /////////////////////////////////////////////////////////////////////////////// // // // Class factory object implementation // // // /////////////////////////////////////////////////////////////////////////////// CGroupPolicyMgrCF::CGroupPolicyMgrCF() { m_cRef = 1; InterlockedIncrement(&g_cRefThisDll); } CGroupPolicyMgrCF::~CGroupPolicyMgrCF() { InterlockedDecrement(&g_cRefThisDll); } /////////////////////////////////////////////////////////////////////////////// // // // Class factory object implementation (IUnknown) // // // /////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_(ULONG) CGroupPolicyMgrCF::AddRef() { return ++m_cRef; } STDMETHODIMP_(ULONG) CGroupPolicyMgrCF::Release() { if (--m_cRef == 0) { delete this; return 0; } return m_cRef; } STDMETHODIMP CGroupPolicyMgrCF::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 CGroupPolicyMgrCF::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID FAR* ppvObj) { *ppvObj = NULL; if (pUnkOuter) return CLASS_E_NOAGGREGATION; CGroupPolicyMgr *pComponentData = new CGroupPolicyMgr(); // ref count == 1 if (!pComponentData) return E_OUTOFMEMORY; HRESULT hr = pComponentData->QueryInterface(riid, ppvObj); pComponentData->Release(); // release initial ref return hr; } STDMETHODIMP CGroupPolicyMgrCF::LockServer(BOOL fLock) { return E_NOTIMPL; }