- Finished migration to new client library model
[public/netxms.git] / src / console / win32 / UserEditor.cpp
1 // UserEditor.cpp : implementation file
2 //
3
4 #include "stdafx.h"
5 #include "nxcon.h"
6 #include "UserEditor.h"
7
8 #ifdef _DEBUG
9 #define new DEBUG_NEW
10 #undef THIS_FILE
11 static char THIS_FILE[] = __FILE__;
12 #endif
13
14 /////////////////////////////////////////////////////////////////////////////
15 // CUserEditor
16
17 IMPLEMENT_DYNCREATE(CUserEditor, CMDIChildWnd)
18
19 CUserEditor::CUserEditor()
20 {
21 m_dwCurrentUser = INVALID_UID;
22 }
23
24 CUserEditor::~CUserEditor()
25 {
26 }
27
28
29 BEGIN_MESSAGE_MAP(CUserEditor, CMDIChildWnd)
30 //{{AFX_MSG_MAP(CUserEditor)
31 ON_WM_CLOSE()
32 ON_WM_DESTROY()
33 ON_WM_CREATE()
34 ON_WM_SIZE()
35 ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh)
36 ON_COMMAND(ID_USER_CREATE_GROUP, OnUserCreateGroup)
37 ON_COMMAND(ID_USER_CREATE_USER, OnUserCreateUser)
38 ON_WM_SETFOCUS()
39 ON_COMMAND(ID_USER_PROPERTIES, OnUserProperties)
40 ON_COMMAND(ID_USER_DELETE, OnUserDelete)
41 ON_WM_CONTEXTMENU()
42 ON_UPDATE_COMMAND_UI(ID_USER_PROPERTIES, OnUpdateUserProperties)
43 ON_UPDATE_COMMAND_UI(ID_USER_DELETE, OnUpdateUserDelete)
44 ON_COMMAND(ID_USER_SETPASSWORD, OnUserSetpassword)
45 ON_UPDATE_COMMAND_UI(ID_USER_SETPASSWORD, OnUpdateUserSetpassword)
46 //}}AFX_MSG_MAP
47 ON_MESSAGE(WM_USERDB_CHANGE, OnUserDBChange)
48 ON_NOTIFY(NM_DBLCLK, IDC_LIST_VIEW, OnListViewDblClk)
49 ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_VIEW, OnListViewItemChange)
50 END_MESSAGE_MAP()
51
52 /////////////////////////////////////////////////////////////////////////////
53 // CUserEditor message handlers
54
55 BOOL CUserEditor::PreCreateWindow(CREATESTRUCT& cs)
56 {
57 if (cs.lpszClass == NULL)
58 cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
59 NULL,
60 GetSysColorBrush(COLOR_WINDOW),
61 AfxGetApp()->LoadIcon(IDI_USER_GROUP));
62 return CMDIChildWnd::PreCreateWindow(cs);
63 }
64
65
66 //
67 // WM_CLOSE message handler
68 //
69
70 void CUserEditor::OnClose()
71 {
72 DoRequestArg1(NXCUnlockUserDB, g_hSession, "Unlocking user database...");
73 CMDIChildWnd::OnClose();
74 }
75
76
77 //
78 // WM_DESTROY message handler
79 //
80
81 void CUserEditor::OnDestroy()
82 {
83 theApp.OnViewDestroy(IDR_USER_EDITOR, this);
84 CMDIChildWnd::OnDestroy();
85 }
86
87
88 //
89 // WM_CREATE message handler
90 //
91
92 int CUserEditor::OnCreate(LPCREATESTRUCT lpCreateStruct)
93 {
94 RECT rect;
95 CImageList *pImageList;
96
97 if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
98 return -1;
99
100 theApp.OnViewCreate(IDR_USER_EDITOR, this);
101
102 // Create list view control
103 GetClientRect(&rect);
104 m_wndListCtrl.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL, rect, this, IDC_LIST_VIEW);
105 m_wndListCtrl.SetExtendedStyle(LVS_EX_TRACKSELECT | LVS_EX_UNDERLINEHOT | LVS_EX_FULLROWSELECT);
106 m_wndListCtrl.SetHoverTime(0x7FFFFFFF);
107
108 // Create image list
109 pImageList = new CImageList;
110 pImageList->Create(16, 16, ILC_COLOR8 | ILC_MASK, 8, 8);
111 pImageList->Add(AfxGetApp()->LoadIcon(IDI_USER));
112 pImageList->Add(AfxGetApp()->LoadIcon(IDI_USER_GROUP));
113 pImageList->Add(AfxGetApp()->LoadIcon(IDI_EVERYONE));
114 m_wndListCtrl.SetImageList(pImageList, LVSIL_SMALL);
115
116 // Setup columns
117 m_wndListCtrl.InsertColumn(0, "Name", LVCFMT_LEFT, 100);
118 m_wndListCtrl.InsertColumn(1, "Full Name", LVCFMT_LEFT, 170);
119 m_wndListCtrl.InsertColumn(2, "Description", LVCFMT_LEFT, 300);
120
121 PostMessage(WM_COMMAND, ID_VIEW_REFRESH, 0);
122
123 return 0;
124 }
125
126
127 //
128 // Handler for WM_NOTIFY::NM_DBLCLK from IDC_LIST_VIEW
129 //
130
131 void CUserEditor::OnListViewDblClk(LPNMITEMACTIVATE pNMHDR, LRESULT *pResult)
132 {
133 PostMessage(WM_COMMAND, ID_USER_PROPERTIES, 0);
134 }
135
136
137 //
138 // WM_SIZE message handler
139 //
140
141 void CUserEditor::OnSize(UINT nType, int cx, int cy)
142 {
143 CMDIChildWnd::OnSize(nType, cx, cy);
144
145 m_wndListCtrl.SetWindowPos(NULL, 0, 0, cx, cy, SWP_NOZORDER);
146 }
147
148
149 //
150 // Add new item to list
151 //
152
153 int CUserEditor::AddListItem(NXC_USER *pUser)
154 {
155 int iItem;
156
157 iItem = m_wndListCtrl.InsertItem(0x7FFFFFFF, pUser->szName,
158 (pUser->dwId == GROUP_EVERYONE) ? 2 : ((pUser->dwId & GROUP_FLAG) ? 1 : 0));
159 if (iItem != -1)
160 {
161 m_wndListCtrl.SetItemData(iItem, pUser->dwId);
162 m_wndListCtrl.SetItemText(iItem, 1, pUser->szFullName);
163 m_wndListCtrl.SetItemText(iItem, 2, pUser->szDescription);
164 }
165 return iItem;
166 }
167
168
169 //
170 // WM_COMMAND::ID_VIEW_REFRESH message handler
171 //
172
173 void CUserEditor::OnViewRefresh()
174 {
175 NXC_USER *pUserList;
176 DWORD i, dwNumUsers;
177
178 m_wndListCtrl.DeleteAllItems();
179
180 // Fill in list view
181 if (NXCGetUserDB(g_hSession, &pUserList, &dwNumUsers))
182 {
183 for(i = 0; i < dwNumUsers; i++)
184 if (!(pUserList[i].wFlags & UF_DELETED))
185 AddListItem(&pUserList[i]);
186 }
187 }
188
189
190 //
191 // WM_COMMAND::ID_USER_CREATE_USER message handler
192 //
193
194 void CUserEditor::OnUserCreateUser()
195 {
196 CNewUserDlg wndDialog;
197
198 wndDialog.m_strTitle = "New User";
199 wndDialog.m_strHeader = "Login name";
200 wndDialog.m_bDefineProperties = TRUE;
201 if (wndDialog.DoModal() == IDOK)
202 CreateUserObject((LPCTSTR)wndDialog.m_strName, FALSE, wndDialog.m_bDefineProperties);
203 }
204
205
206 //
207 // WM_COMMAND::ID_USER_CREATE_GROUP message handler
208 //
209
210 void CUserEditor::OnUserCreateGroup()
211 {
212 CNewUserDlg wndDialog;
213
214 wndDialog.m_strTitle = "New Group";
215 wndDialog.m_strHeader = "Group name";
216 wndDialog.m_bDefineProperties = TRUE;
217 if (wndDialog.DoModal() == IDOK)
218 CreateUserObject((LPCTSTR)wndDialog.m_strName, TRUE, wndDialog.m_bDefineProperties);
219 }
220
221
222 //
223 // Create user or group
224 //
225
226 void CUserEditor::CreateUserObject(const char *pszName, BOOL bIsGroup, BOOL bShowProp)
227 {
228 DWORD dwResult, dwNewId;
229
230 // Send request to server
231 dwResult = DoRequestArg4(NXCCreateUser, g_hSession, (void *)pszName, (void *)bIsGroup,
232 &dwNewId, bIsGroup ? "Creating new group..." : "Creating new user...");
233 if (dwResult == RCC_SUCCESS)
234 {
235 int iItem, iOldItem;
236 LVFINDINFO lvfi;
237
238 // Find related item
239 lvfi.flags = LVFI_PARAM;
240 lvfi.lParam = dwNewId;
241 iItem = m_wndListCtrl.FindItem(&lvfi, -1);
242
243 if (iItem == -1)
244 {
245 NXC_USER user;
246
247 memset(&user, 0, sizeof(NXC_USER));
248 user.dwId = dwNewId;
249 strcpy(user.szName, pszName);
250 iItem = AddListItem(&user);
251 }
252
253 // Select newly created item
254 iOldItem = m_wndListCtrl.GetNextItem(-1, LVNI_FOCUSED);
255 if (iOldItem != -1)
256 m_wndListCtrl.SetItemState(iOldItem, 0, LVIS_SELECTED | LVIS_FOCUSED);
257 m_wndListCtrl.EnsureVisible(iItem, FALSE);
258 m_wndListCtrl.SetItemState(iItem, LVIS_SELECTED | LVIS_FOCUSED,
259 LVIS_SELECTED | LVIS_FOCUSED);
260
261 if (bShowProp)
262 PostMessage(WM_COMMAND, ID_USER_PROPERTIES, 0);
263 }
264 else
265 {
266 char szBuffer[256];
267
268 sprintf(szBuffer, "Error creating %s object: %s",
269 bIsGroup ? "group" : "user", NXCGetErrorText(dwResult));
270 MessageBox(szBuffer, "Error", MB_OK | MB_ICONSTOP);
271 }
272 }
273
274
275 //
276 // WM_USERDB_CHANGE message handler
277 //
278
279 void CUserEditor::OnUserDBChange(int iCode, NXC_USER *pUserInfo)
280 {
281 int iItem;
282 LVFINDINFO lvfi;
283
284 // Find related item
285 lvfi.flags = LVFI_PARAM;
286 lvfi.lParam = pUserInfo->dwId;
287 iItem = m_wndListCtrl.FindItem(&lvfi, -1);
288
289 // Modify list control
290 switch(iCode)
291 {
292 case USER_DB_CREATE:
293 if (iItem == -1)
294 AddListItem(pUserInfo);
295 break;
296 case USER_DB_MODIFY:
297 if (iItem == -1)
298 {
299 AddListItem(pUserInfo);
300 }
301 else
302 {
303 m_wndListCtrl.SetItemText(iItem, 0, pUserInfo->szName);
304 m_wndListCtrl.SetItemText(iItem, 1, pUserInfo->szFullName);
305 m_wndListCtrl.SetItemText(iItem, 2, pUserInfo->szDescription);
306 }
307 break;
308 case USER_DB_DELETE:
309 if (iItem != -1)
310 m_wndListCtrl.DeleteItem(iItem);
311 break;
312 }
313 }
314
315
316 //
317 // WM_SETFOCUS message handler
318 //
319
320 void CUserEditor::OnSetFocus(CWnd* pOldWnd)
321 {
322 CMDIChildWnd::OnSetFocus(pOldWnd);
323
324 m_wndListCtrl.SetFocus();
325 }
326
327
328 //
329 // WM_COMMAND::ID_USER_PROPERTIES message handler
330 //
331
332 void CUserEditor::OnUserProperties()
333 {
334 int iItem;
335
336 iItem = m_wndListCtrl.GetNextItem(-1, LVNI_FOCUSED);
337 if (iItem != -1)
338 {
339 DWORD dwId;
340 NXC_USER *pUser;
341
342 dwId = m_wndListCtrl.GetItemData(iItem);
343 pUser = NXCFindUserById(g_hSession, dwId);
344 if (pUser != NULL)
345 {
346 NXC_USER userInfo;
347 BOOL bModify = FALSE;
348
349 memset(&userInfo, 0, sizeof(NXC_USER));
350 if (dwId & GROUP_FLAG)
351 {
352 CGroupPropDlg dlg;
353
354 dlg.m_pGroup = pUser;
355 dlg.m_strName = pUser->szName;
356 dlg.m_strDescription = pUser->szDescription;
357 dlg.m_bDisabled = (pUser->wFlags & UF_DISABLED) ? TRUE : FALSE;
358 dlg.m_bDropConn = (pUser->wSystemRights & SYSTEM_ACCESS_DROP_CONNECTIONS) ? TRUE : FALSE;
359 dlg.m_bManageConfig = (pUser->wSystemRights & SYSTEM_ACCESS_SERVER_CONFIG) ? TRUE : FALSE;
360 dlg.m_bConfigureTraps = (pUser->wSystemRights & SYSTEM_ACCESS_CONFIGURE_TRAPS) ? TRUE : FALSE;
361 dlg.m_bEditEventDB = (pUser->wSystemRights & SYSTEM_ACCESS_EDIT_EVENT_DB) ? TRUE : FALSE;
362 dlg.m_bViewEventDB = (pUser->wSystemRights & SYSTEM_ACCESS_VIEW_EVENT_DB) ? TRUE : FALSE;
363 dlg.m_bManageUsers = (pUser->wSystemRights & SYSTEM_ACCESS_MANAGE_USERS) ? TRUE : FALSE;
364 dlg.m_bManageActions = (pUser->wSystemRights & SYSTEM_ACCESS_MANAGE_ACTIONS) ? TRUE : FALSE;
365 dlg.m_bManageEPP = (pUser->wSystemRights & SYSTEM_ACCESS_EPP) ? TRUE : FALSE;
366 if (dlg.DoModal() == IDOK)
367 {
368 userInfo.dwId = pUser->dwId;
369 strcpy(userInfo.szName, (LPCTSTR)dlg.m_strName);
370 strcpy(userInfo.szDescription, (LPCTSTR)dlg.m_strDescription);
371 userInfo.wFlags = dlg.m_bDisabled ? UF_DISABLED : 0;
372 userInfo.wSystemRights = (dlg.m_bDropConn ? SYSTEM_ACCESS_DROP_CONNECTIONS : 0) |
373 (dlg.m_bManageUsers ? SYSTEM_ACCESS_MANAGE_USERS : 0) |
374 (dlg.m_bManageActions ? SYSTEM_ACCESS_MANAGE_ACTIONS : 0) |
375 (dlg.m_bManageEPP ? SYSTEM_ACCESS_EPP : 0) |
376 (dlg.m_bManageConfig ? SYSTEM_ACCESS_SERVER_CONFIG : 0) |
377 (dlg.m_bConfigureTraps ? SYSTEM_ACCESS_CONFIGURE_TRAPS : 0) |
378 (dlg.m_bEditEventDB ? SYSTEM_ACCESS_EDIT_EVENT_DB : 0) |
379 (dlg.m_bViewEventDB ? SYSTEM_ACCESS_VIEW_EVENT_DB : 0);
380 userInfo.dwNumMembers = dlg.m_dwNumMembers;
381 if (userInfo.dwNumMembers > 0)
382 {
383 userInfo.pdwMemberList = (DWORD *)malloc(sizeof(DWORD) * userInfo.dwNumMembers);
384 memcpy(userInfo.pdwMemberList, dlg.m_pdwMembers, sizeof(DWORD) * userInfo.dwNumMembers);
385 }
386 bModify = TRUE;
387 }
388 }
389 else
390 {
391 CUserPropDlg dlg;
392
393 dlg.m_pUser = pUser;
394 dlg.m_strLogin = pUser->szName;
395 dlg.m_strFullName = pUser->szFullName;
396 dlg.m_strDescription = pUser->szDescription;
397 dlg.m_bAccountDisabled = (pUser->wFlags & UF_DISABLED) ? TRUE : FALSE;
398 dlg.m_bChangePassword = (pUser->wFlags & UF_CHANGE_PASSWORD) ? TRUE : FALSE;
399 dlg.m_bDropConn = (pUser->wSystemRights & SYSTEM_ACCESS_DROP_CONNECTIONS) ? TRUE : FALSE;
400 dlg.m_bManageConfig = (pUser->wSystemRights & SYSTEM_ACCESS_SERVER_CONFIG) ? TRUE : FALSE;
401 dlg.m_bConfigureTraps = (pUser->wSystemRights & SYSTEM_ACCESS_CONFIGURE_TRAPS) ? TRUE : FALSE;
402 dlg.m_bEditEventDB = (pUser->wSystemRights & SYSTEM_ACCESS_EDIT_EVENT_DB) ? TRUE : FALSE;
403 dlg.m_bViewEventDB = (pUser->wSystemRights & SYSTEM_ACCESS_VIEW_EVENT_DB) ? TRUE : FALSE;
404 dlg.m_bManageUsers = (pUser->wSystemRights & SYSTEM_ACCESS_MANAGE_USERS) ? TRUE : FALSE;
405 dlg.m_bManageActions = (pUser->wSystemRights & SYSTEM_ACCESS_MANAGE_ACTIONS) ? TRUE : FALSE;
406 dlg.m_bManageEPP = (pUser->wSystemRights & SYSTEM_ACCESS_EPP) ? TRUE : FALSE;
407 if (dlg.DoModal() == IDOK)
408 {
409 userInfo.dwId = pUser->dwId;
410 strcpy(userInfo.szName, (LPCTSTR)dlg.m_strLogin);
411 strcpy(userInfo.szFullName, (LPCTSTR)dlg.m_strFullName);
412 strcpy(userInfo.szDescription, (LPCTSTR)dlg.m_strDescription);
413 userInfo.wFlags = (dlg.m_bAccountDisabled ? UF_DISABLED : 0) |
414 (dlg.m_bChangePassword ? UF_CHANGE_PASSWORD : 0);
415 userInfo.wSystemRights = (dlg.m_bDropConn ? SYSTEM_ACCESS_DROP_CONNECTIONS : 0) |
416 (dlg.m_bManageUsers ? SYSTEM_ACCESS_MANAGE_USERS : 0) |
417 (dlg.m_bManageActions ? SYSTEM_ACCESS_MANAGE_ACTIONS : 0) |
418 (dlg.m_bManageEPP ? SYSTEM_ACCESS_EPP : 0) |
419 (dlg.m_bManageConfig ? SYSTEM_ACCESS_SERVER_CONFIG : 0) |
420 (dlg.m_bConfigureTraps ? SYSTEM_ACCESS_CONFIGURE_TRAPS : 0) |
421 (dlg.m_bEditEventDB ? SYSTEM_ACCESS_EDIT_EVENT_DB : 0) |
422 (dlg.m_bViewEventDB ? SYSTEM_ACCESS_VIEW_EVENT_DB : 0);
423 bModify = TRUE;
424 }
425 }
426
427 // Modify user if OK was pressed
428 if (bModify)
429 {
430 DWORD dwResult;
431
432 dwResult = DoRequestArg2(NXCModifyUser, g_hSession, &userInfo, "Updating user database...");
433 if (dwResult != RCC_SUCCESS)
434 theApp.ErrorBox(dwResult, "Cannot modify user record: %s");
435
436 // Destroy group members list
437 safe_free(userInfo.pdwMemberList);
438 }
439 }
440 else
441 {
442 MessageBox("Attempt to edit non-existing user record", "Internal Error", MB_ICONSTOP | MB_OK);
443 PostMessage(WM_COMMAND, ID_VIEW_REFRESH, 0);
444 }
445 }
446 }
447
448
449 //
450 // WM_COMMAND::ID_USER_DELETE message handler
451 //
452
453 void CUserEditor::OnUserDelete()
454 {
455 int iItem;
456
457 iItem = m_wndListCtrl.GetNextItem(-1, LVNI_FOCUSED);
458 if (iItem != -1)
459 {
460 DWORD dwId;
461
462 dwId = m_wndListCtrl.GetItemData(iItem);
463 if (dwId == 0)
464 {
465 MessageBox("System administrator account cannot be deleted",
466 "Warning", MB_ICONEXCLAMATION | MB_OK);
467 }
468 else if (dwId == GROUP_EVERYONE)
469 {
470 MessageBox("Everyone group cannot be deleted",
471 "Warning", MB_ICONEXCLAMATION | MB_OK);
472 }
473 else
474 {
475 NXC_USER *pUser;
476
477 pUser = NXCFindUserById(g_hSession, dwId);
478 if (pUser != NULL)
479 {
480 char szBuffer[256];
481
482 sprintf(szBuffer, "Do you really wish to delete %s %s ?",
483 dwId & GROUP_FLAG ? "group" : "user", pUser->szName);
484 if (MessageBox(szBuffer, "Delete account", MB_ICONQUESTION | MB_YESNO) == IDYES)
485 {
486 DWORD dwResult;
487
488 dwResult = DoRequestArg2(NXCDeleteUser, g_hSession, (void *)dwId, "Deleting user...");
489 if (dwResult != RCC_SUCCESS)
490 theApp.ErrorBox(dwResult, "Cannot delete user record: %s");
491 }
492 }
493 else
494 {
495 MessageBox("Attempt to delete non-existing user record", "Internal Error", MB_ICONSTOP | MB_OK);
496 PostMessage(WM_COMMAND, ID_VIEW_REFRESH, 0);
497 }
498 }
499 }
500 }
501
502
503 //
504 // WM_CONTEXTMENU message handler
505 //
506
507 void CUserEditor::OnContextMenu(CWnd* pWnd, CPoint point)
508 {
509 CMenu *pMenu;
510
511 pMenu = theApp.GetContextMenu(0);
512 pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this, NULL);
513 }
514
515
516 //
517 // WM_NOTIFY::LVN_ITEMACTIVATE message handler
518 //
519
520 void CUserEditor::OnListViewItemChange(LPNMLISTVIEW pNMHDR, LRESULT *pResult)
521 {
522 if (pNMHDR->iItem != -1)
523 if (pNMHDR->uChanged & LVIF_STATE)
524 {
525 if (pNMHDR->uNewState & LVIS_FOCUSED)
526 {
527 m_dwCurrentUser = m_wndListCtrl.GetItemData(pNMHDR->iItem);
528 }
529 else
530 {
531 m_dwCurrentUser = INVALID_UID;
532 }
533 }
534 }
535
536
537 //
538 // WM_COMMAND::ID_USER_SETPASSWORD message handler
539 //
540
541 void CUserEditor::OnUserSetpassword()
542 {
543 int iItem;
544
545 iItem = m_wndListCtrl.GetNextItem(-1, LVNI_FOCUSED);
546 if (iItem != -1)
547 {
548 DWORD dwId;
549 NXC_USER *pUser;
550
551 dwId = m_wndListCtrl.GetItemData(iItem);
552
553 pUser = NXCFindUserById(g_hSession, dwId);
554 if (pUser != NULL)
555 {
556 CPasswordChangeDlg dlg;
557
558 if (dlg.DoModal() == IDOK)
559 {
560 DWORD dwResult;
561
562 dwResult = DoRequestArg3(NXCSetPassword, g_hSession, (void *)dwId, dlg.m_szPassword, "Changing password...");
563 if (dwResult != RCC_SUCCESS)
564 theApp.ErrorBox(dwResult, "Cannot change password: %s");
565 else
566 MessageBox("Password was successfully changed", "Information", MB_ICONINFORMATION | MB_OK);
567 }
568 }
569 else
570 {
571 MessageBox("Attempt to modify non-existing user record", "Internal Error", MB_ICONSTOP | MB_OK);
572 PostMessage(WM_COMMAND, ID_VIEW_REFRESH, 0);
573 }
574 }
575 }
576
577
578 //
579 // UPDATE_COMMAND_UI handlers
580 //
581
582 void CUserEditor::OnUpdateUserProperties(CCmdUI* pCmdUI)
583 {
584 pCmdUI->Enable(m_dwCurrentUser != INVALID_UID);
585 }
586
587 void CUserEditor::OnUpdateUserDelete(CCmdUI* pCmdUI)
588 {
589 pCmdUI->Enable(m_dwCurrentUser != INVALID_UID);
590 }
591
592 void CUserEditor::OnUpdateUserSetpassword(CCmdUI* pCmdUI)
593 {
594 pCmdUI->Enable((m_dwCurrentUser != INVALID_UID) && (!(m_dwCurrentUser & GROUP_FLAG)));
595 }