windows-nt/Source/XPSP1/NT/ds/security/gina/policy/poledit/policy.c
2020-09-26 16:20:57 +08:00

359 lines
9.5 KiB
C

//*********************************************************************
//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1994 **
//*********************************************************************
#include "admincfg.h"
INT_PTR CALLBACK PolicyDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
BOOL OnPolicyDlgCreate(HWND hDlg,LPARAM lParam);
VOID ProcessMouseDown(HWND hwndParent,HWND hwndTree);
VOID ProcessMouseUp(HWND hwndParent,HWND hwndTree);
VOID ProcessMouseMove(HWND hwndParent,HWND hwndTree);
VOID SetKeyboardHook(HWND hDlg);
VOID RemoveKeyboardHook(VOID);
extern VOID EnsureSettingControlVisible(HWND hDlg,HWND hwndCtrl);
extern HIMAGELIST hImageListSmall;
UINT CALLBACK PropSheetHeaderCallback (HWND hDlg, UINT msg, LPARAM lParam)
{
LPDLGTEMPLATE pDlgTemplate = (LPDLGTEMPLATE) lParam;
//
// Turn off context sensitive help
//
if (msg == PSCB_PRECREATE) {
pDlgTemplate->style &= ~DS_CONTEXTHELP;
}
return 1;
}
BOOL DoPolicyDlg(HWND hwndOwner,HGLOBAL hUser)
{
USERHDR UserHdr;
POLICYDLGINFO * pdi;
PROPSHEETPAGE pagePolicies;
HPROPSHEETPAGE hpagePolicies,hpage[2] = {NULL,NULL};
PROPSHEETHEADER psh;
BOOL fRet;
HGLOBAL hUserTmp=NULL;
USERDATA * pUserData=NULL,*pUserDataTmp=NULL;
memset(&pagePolicies,0,sizeof(pagePolicies));
memset(&psh,0,sizeof(psh));
if (!GetUserHeader(hUser,&UserHdr)) {
MsgBox(hwndOwner,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
return FALSE;
}
if (!(pUserData = (USERDATA *) GlobalLock(hUser)) ||
!(hUserTmp = GlobalAlloc(GHND,pUserData->dwSize)) ||
!(pUserDataTmp = GlobalLock(hUserTmp)) ||
!(pdi = (POLICYDLGINFO *) GlobalAlloc(GPTR,sizeof(POLICYDLGINFO)))) {
if (pUserData)
GlobalUnlock(hUser);
if (hUserTmp) {
if (pUserDataTmp)
GlobalUnlock(hUserTmp);
GlobalFree(hUserTmp);
}
if (pdi) GlobalFree(pdi);
MsgBox(hwndOwner,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
return FALSE;
}
// make a copy of the user buffer to operate on, so that changes can
// be cancelled
memcpy(pUserDataTmp,pUserData,pUserData->dwSize);
GlobalUnlock(hUser);
GlobalUnlock(hUserTmp);
pdi->dwControlTableSize = DEF_CONTROLS * sizeof(POLICYCTRLINFO);
pdi->nControls = 0;
pdi->hUser = hUserTmp;
pdi->pEntryRoot = (UserHdr.dwType & UT_USER ?
gClassList.pUserCategoryList : gClassList.pMachineCategoryList);
pdi->hwndApp = hwndOwner;
if (!(pdi->pControlTable = (POLICYCTRLINFO *)
GlobalAlloc(GPTR,pdi->dwControlTableSize))) {
GlobalFree(hUserTmp);
GlobalFree(pdi);
MsgBox(hwndOwner,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
return FALSE;
}
pagePolicies.dwSize = sizeof(PROPSHEETPAGE);
pagePolicies.dwFlags = PSP_DEFAULT;
pagePolicies.hInstance = ghInst;
pagePolicies.pfnDlgProc = PolicyDlgProc;
pagePolicies.pszTemplate = MAKEINTRESOURCE(DLG_POLICIES);
pagePolicies.lParam = (LPARAM) pdi;
if (!(hpagePolicies = CreatePropertySheetPage(&pagePolicies))) {
MsgBox(hwndOwner,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
fRet=FALSE;
goto cleanup;
}
hpage[0] = hpagePolicies;
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPTITLE | PSH_USEICONID | PSH_NOAPPLYNOW | PSH_USECALLBACK;
psh.hwndParent = hwndOwner;
psh.hInstance = ghInst;
psh.nPages = 1;
psh.nStartPage = 0;
psh.phpage = hpage;
psh.pszCaption = UserHdr.szName;
psh.pszIcon = MAKEINTRESOURCE(IDI_APPICON);
psh.pfnCallback = PropSheetHeaderCallback;
fRet=(BOOL) PropertySheet(&psh);
if (fRet) {
// user hit OK, copy the temporary user buffer to the real one.
// may have to resize 'real' buffer.
if (!CopyUser(hUserTmp,hUser)) {
MsgBox(hwndOwner,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
fRet = FALSE;
}
dwAppState |= AS_FILEDIRTY;
EnableMenuItems(hwndOwner,dwAppState);
}
cleanup:
GlobalFree(pdi->pControlTable);
GlobalFree(pdi);
GlobalFree(hUserTmp);
return fRet;
}
INT_PTR CALLBACK PolicyDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
switch (uMsg) {
case WM_INITDIALOG:
if (!OnPolicyDlgCreate(hDlg,lParam)) {
return FALSE;
}
SetKeyboardHook(hDlg);
break;
case WM_NOTIFY:
if ( ((NMHDR *) lParam)->hwndFrom == GetDlgItem(hDlg,IDD_TVPOLICIES)
&& ((POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER))->fActive) {
BOOL fRet;
fRet=OnTreeNotify(hDlg,( (NMHDR *)lParam)->hwndFrom,
(NM_TREEVIEW *) lParam);
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,(LPARAM) fRet);
return fRet;
}
switch ( ((NMHDR * ) lParam)->code) {
case PSN_APPLY:
if (IsSelectedItemChecked(GetDlgItem(hDlg,IDD_TVPOLICIES)) &&
!ProcessSettingsControls(hDlg,PSC_VALIDATENOISY)) {
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,(LPARAM) TRUE);
return TRUE;
}
((POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER))->fActive=FALSE;
RemoveKeyboardHook();
return TRUE;
break;
case PSN_RESET:
((POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER))->fActive=FALSE;
RemoveKeyboardHook();
return TRUE;
break;
}
break;
case WM_SETCURSOR:
switch (HIWORD(lParam)) {
case WM_LBUTTONDOWN:
ProcessMouseDown(hDlg,GetDlgItem(hDlg,IDD_TVPOLICIES));
break;
case WM_LBUTTONUP:
ProcessMouseUp(hDlg,GetDlgItem(hDlg,IDD_TVPOLICIES));
break;
case WM_MOUSEMOVE:
ProcessMouseMove(hDlg,GetDlgItem(hDlg,IDD_TVPOLICIES));
break;
}
break;
case WM_MOUSEMOVE:
ProcessMouseMove(hDlg,GetDlgItem(hDlg,IDD_TVPOLICIES));
break;
default:
return FALSE;
}
return TRUE;
}
BOOL OnPolicyDlgCreate(HWND hDlg,LPARAM lParam)
{
POLICYDLGINFO * pdi;
HWND hwndPolicy = GetDlgItem(hDlg,IDD_TVPOLICIES);
CHAR szTitle[255];
USERHDR UserHdr;
WINDOWPLACEMENT wp;
if (!(pdi = (POLICYDLGINFO *) (( (PROPSHEETPAGE *) lParam)->lParam) ))
return FALSE;
if (!GetUserHeader(pdi->hUser,&UserHdr)) return FALSE;
// Set the title of the dialog to "Policies for <user>"
wsprintf(szTitle,LoadSz(IDS_POLICIESFOR,szSmallBuf,sizeof(szSmallBuf)),
UserHdr.szName);
SetWindowText(hDlg,szTitle);
wp.length = sizeof(wp);
GetWindowPlacement(pdi->hwndApp,&wp);
SetWindowPos(hDlg,NULL,wp.rcNormalPosition.left+30,
wp.rcNormalPosition.top+40,0,0,SWP_NOSIZE | SWP_NOZORDER);
// lParam is pointer to POLICYDLGINFO struct with information for this
// instance of the dialog, store the pointer in the window data
pdi->fActive=TRUE;
SetWindowLongPtr(hDlg,DWLP_USER,(LPARAM) pdi);
// now that we've stored pointer to POLICYDLGINFO struct in our extra
// window data, send WM_USER to clip window to tell it to create a
// child container window (and store the handle in our POLICYDLGINFO)
SendDlgItemMessage(hDlg,IDD_TVSETTINGS,WM_USER,0,0L);
SetWindowLong(hwndPolicy,GWL_EXSTYLE,WS_EX_CLIENTEDGE);
SetWindowLong(GetDlgItem(hDlg,IDD_TVSETTINGS),GWL_EXSTYLE,WS_EX_CLIENTEDGE);
SetScrollRange(GetDlgItem(hDlg,IDD_TVSETTINGS),SB_VERT,0,100,TRUE);
SetScrollRange(GetDlgItem(hDlg,IDD_TVSETTINGS),SB_VERT,0,0,TRUE);
SetScrollRange(hwndPolicy,SB_VERT,0,100,TRUE);
SetScrollRange(hwndPolicy,SB_VERT,0,0,TRUE);
TreeView_SetImageList(hwndPolicy,hImageListSmall,TVSIL_NORMAL);
if (!RefreshTreeView(pdi,hwndPolicy,pdi->pEntryRoot,pdi->hUser)) {
MsgBox(hDlg,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
return FALSE;
}
return TRUE;
}
BOOL SetPolicyState(HWND hDlg,TABLEENTRY * pTableEntry,UINT uState)
{
POLICY * pPolicy = (POLICY *) pTableEntry;
USERDATA * pUserData;
POLICYDLGINFO * pdi;
if (!pPolicy) return FALSE;
if (!(pdi = (POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER)))
return FALSE;
if (!(pUserData = (USERDATA *) GlobalLock(pdi->hUser))) {
return FALSE;
}
pUserData->SettingData[pPolicy->uDataIndex].uData = uState;
GlobalUnlock(pdi->hUser);
return TRUE;
}
HHOOK hKbdHook = NULL;
HWND hDlgActive = NULL;
LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam,LPARAM lParam)
{
if (wParam == VK_TAB && !(lParam & 0x80000000)) { // tab key depressed
BOOL fShift = (GetKeyState(VK_SHIFT) & 0x80000000);
HWND hwndFocus = GetFocus();
POLICYDLGINFO * pdi;
int iIndex;
int iDelta;
if (!(pdi = (POLICYDLGINFO *) GetWindowLongPtr(hDlgActive, DWLP_USER)))
return 0;
// see if the focus control is one of the setting controls
for (iIndex=0;iIndex<(int)pdi->nControls;iIndex++)
if (pdi->pControlTable[iIndex].hwnd == hwndFocus)
break;
if (iIndex == (int) pdi->nControls)
return 0; // no, we don't care
iDelta = (fShift ? -1 : 1);
// from the current setting control, scan forwards or backwards
// (depending if on shift state, this can be TAB or shift-TAB)
// to find the next control to give focus to
for (iIndex += iDelta;iIndex>=0 && iIndex<(int) pdi->nControls;
iIndex += iDelta) {
if (pdi->pControlTable[iIndex].uDataIndex !=
NO_DATA_INDEX &&
IsWindowEnabled(pdi->pControlTable[iIndex].hwnd)) {
// found it, set the focus on that control and return 1
// to eat the keystroke
SetFocus(pdi->pControlTable[iIndex].hwnd);
EnsureSettingControlVisible(hDlgActive,
pdi->pControlTable[iIndex].hwnd);
return 1;
}
}
// at first or last control in settings table, let dlg code
// handle it and give focus to next (or previous) control in dialog
}
return 0;
}
VOID SetKeyboardHook(HWND hDlg)
{
// hook the keyboard to trap TABs. If this fails for some reason,
// fail silently and go on, not critical that tabs work correctly
// (unless you have no mouse :) )
if (hKbdHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardHookProc,
ghInst,GetCurrentThreadId())) {
hDlgActive = hDlg;
}
}
VOID RemoveKeyboardHook(VOID)
{
if (hKbdHook) {
UnhookWindowsHookEx(hKbdHook);
hKbdHook = NULL;
hDlgActive = NULL;
}
}