2 * PROJECT: ReactOS System Control Panel Applet
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/sysdm/userprofile.c
5 * PURPOSE: Computer settings for networking
6 * COPYRIGHT: Copyright Thomas Weidenmueller <w3seek@reactos.org>
7 * Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
16 typedef struct _PROFILEDATA
20 } PROFILEDATA
, *PPROFILEDATA
;
27 PPROFILEDATA pProfileData
)
29 PWSTR pszRawBuffer
= NULL
, pszCookedBuffer
= NULL
;
32 nLength
= LoadStringW(hApplet
, IDS_USERPROFILE_TYPE_TEXT
, (PWSTR
)&pszRawBuffer
, 0);
37 pszRawBuffer
= HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(WCHAR
));
38 if (pszRawBuffer
== NULL
)
41 LoadStringW(hApplet
, IDS_USERPROFILE_TYPE_TEXT
, pszRawBuffer
, nLength
+ 1);
43 pszCookedBuffer
= HeapAlloc(GetProcessHeap(), 0, (nLength
+ wcslen(pProfileData
->pszFullName
) + 1) * sizeof(WCHAR
));
44 if (pszCookedBuffer
== NULL
)
47 swprintf(pszCookedBuffer
, pszRawBuffer
, pProfileData
->pszFullName
);
49 /* Set the full text */
50 SetDlgItemText(hwndDlg
, IDC_USERPROFILE_TYPE_TEXT
, pszCookedBuffer
);
52 /* FIXME: Right now, we support local user profiles only! */
53 EnableWindow(GetDlgItem(hwndDlg
, IDC_USERPROFILE_TYPE_ROAMING
), FALSE
);
54 Button_SetCheck(GetDlgItem(hwndDlg
, IDC_USERPROFILE_TYPE_LOCAL
), BST_CHECKED
);
55 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
58 if (pszCookedBuffer
!= NULL
)
59 HeapFree(GetProcessHeap(), 0, pszCookedBuffer
);
61 if (pszRawBuffer
!= NULL
)
62 HeapFree(GetProcessHeap(), 0, pszRawBuffer
);
71 UserProfileTypeDlgProc(HWND hwndDlg
,
79 OnProfileTypeInit(hwndDlg
, (PPROFILEDATA
)lParam
);
86 switch (LOWORD(wParam
))
103 ChangeUserProfileType(
110 DPRINT("ChangeUserProfileType(%p)\n", hwndDlg
);
112 hwndListView
= GetDlgItem(hwndDlg
, IDC_USERPROFILE_LIST
);
113 if (hwndListView
== NULL
)
116 iSelected
= ListView_GetNextItem(hwndListView
, -1, LVNI_SELECTED
);
120 ZeroMemory(&Item
, sizeof(LVITEM
));
121 Item
.mask
= LVIF_PARAM
;
122 Item
.iItem
= iSelected
;
124 if (!ListView_GetItem(hwndListView
, &Item
))
127 if (Item
.lParam
== 0)
130 if (DialogBoxParam(hApplet
,
131 MAKEINTRESOURCE(IDD_USERPROFILE_TYPE
),
133 UserProfileTypeDlgProc
,
134 (LPARAM
)Item
.lParam
) == IDOK
)
136 /* FIXME: Update the profile list view */
146 _In_ HWND hwndListView
)
152 GetClientRect(hwndListView
, &rect
);
154 SendMessage(hwndListView
, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, LVS_EX_FULLROWSELECT
);
156 memset(&column
, 0x00, sizeof(column
));
157 column
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_SUBITEM
| LVCF_TEXT
;
158 column
.fmt
= LVCFMT_LEFT
;
159 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.40);
161 LoadString(hApplet
, IDS_USERPROFILE_NAME
, szStr
, ARRAYSIZE(szStr
));
162 column
.pszText
= szStr
;
163 (void)ListView_InsertColumn(hwndListView
, 0, &column
);
165 column
.fmt
= LVCFMT_RIGHT
;
166 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.15);
168 LoadString(hApplet
, IDS_USERPROFILE_SIZE
, szStr
, ARRAYSIZE(szStr
));
169 column
.pszText
= szStr
;
170 (void)ListView_InsertColumn(hwndListView
, 1, &column
);
172 column
.fmt
= LVCFMT_LEFT
;
173 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.15);
175 LoadString(hApplet
, IDS_USERPROFILE_TYPE
, szStr
, ARRAYSIZE(szStr
));
176 column
.pszText
= szStr
;
177 (void)ListView_InsertColumn(hwndListView
, 2, &column
);
179 column
.fmt
= LVCFMT_LEFT
;
180 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.15);
182 LoadString(hApplet
, IDS_USERPROFILE_STATUS
, szStr
, ARRAYSIZE(szStr
));
183 column
.pszText
= szStr
;
184 (void)ListView_InsertColumn(hwndListView
, 3, &column
);
186 column
.fmt
= LVCFMT_LEFT
;
187 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.15) - GetSystemMetrics(SM_CYHSCROLL
);
189 LoadString(hApplet
, IDS_USERPROFILE_MODIFIED
, szStr
, ARRAYSIZE(szStr
));
190 column
.pszText
= szStr
;
191 (void)ListView_InsertColumn(hwndListView
, 4, &column
);
197 _In_ HWND hwndListView
,
198 _In_ LPTSTR lpProfileSid
,
200 _In_ HKEY hProfileKey
)
202 PPROFILEDATA pProfileData
= NULL
;
203 WCHAR szAccountName
[128], szDomainName
[128];
204 WCHAR szNameBuffer
[256];
206 DWORD dwAccountNameSize
, dwDomainNameSize
;
212 if (!ConvertStringSidToSid(lpProfileSid
,
216 dwAccountNameSize
= ARRAYSIZE(szAccountName
);
217 dwDomainNameSize
= ARRAYSIZE(szDomainName
);
218 if (!LookupAccountSidW(NULL
,
226 /* Unknown account */
227 LoadStringW(hApplet
, IDS_USERPROFILE_ACCOUNT_UNKNOWN
, szNameBuffer
, ARRAYSIZE(szNameBuffer
));
231 /* Show only the user accounts */
232 if (Use
!= SidTypeUser
)
235 if (szAccountName
[0] == UNICODE_NULL
)
237 /* Deleted account */
238 LoadStringW(hApplet
, IDS_USERPROFILE_ACCOUNT_DELETED
, szNameBuffer
, ARRAYSIZE(szNameBuffer
));
243 wsprintf(szNameBuffer
, L
"%s\\%s", szDomainName
, szAccountName
);
247 dwProfileData
= sizeof(PROFILEDATA
) +
248 ((wcslen(szNameBuffer
) + 1) * sizeof(WCHAR
));
249 pProfileData
= HeapAlloc(GetProcessHeap(),
252 if (pProfileData
== NULL
)
255 pProfileData
->bMyProfile
= EqualSid(pMySid
, pSid
);
257 ptr
= (PWSTR
)((ULONG_PTR
)pProfileData
+ sizeof(PROFILEDATA
));
258 pProfileData
->pszFullName
= ptr
;
260 wcscpy(pProfileData
->pszFullName
, szNameBuffer
);
262 memset(&lvi
, 0x00, sizeof(lvi
));
263 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_PARAM
;
264 lvi
.pszText
= pProfileData
->pszFullName
;
266 lvi
.lParam
= (LPARAM
)pProfileData
;
267 ListView_InsertItem(hwndListView
, &lvi
);
278 _In_ HWND hwndListView
)
284 iSelected
= ListView_GetNextItem(hwndListView
, -1, LVNI_SELECTED
);
287 Item
.mask
= LVIF_PARAM
;
288 Item
.iItem
= iSelected
;
290 if (ListView_GetItem(hwndListView
, &Item
))
292 if (Item
.lParam
!= 0)
294 bMyProfile
= ((PPROFILEDATA
)Item
.lParam
)->bMyProfile
;
295 if (/*IsUserAnAdmin() &&*/ !bMyProfile
)
297 EnableWindow(GetDlgItem(hwndDlg
, IDC_USERPROFILE_DELETE
), TRUE
);
298 EnableWindow(GetDlgItem(hwndDlg
, IDC_USERPROFILE_COPY
), TRUE
);
302 EnableWindow(GetDlgItem(hwndDlg
, IDC_USERPROFILE_CHANGE
), TRUE
);
306 EnableWindow(GetDlgItem(hwndDlg
, IDC_USERPROFILE_CHANGE
), FALSE
);
307 EnableWindow(GetDlgItem(hwndDlg
, IDC_USERPROFILE_DELETE
), FALSE
);
308 EnableWindow(GetDlgItem(hwndDlg
, IDC_USERPROFILE_COPY
), FALSE
);
316 _In_ HWND hwndListView
)
318 HKEY hKeyUserProfiles
= INVALID_HANDLE_VALUE
;
321 WCHAR szProfileSid
[64];
323 FILETIME ftLastWrite
;
325 HANDLE hToken
= NULL
;
326 PTOKEN_USER pTokenUser
= NULL
;
328 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &hToken
))
331 GetTokenInformation(hToken
, TokenUser
, NULL
, 0, &dwSize
);
335 pTokenUser
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
336 if (pTokenUser
== NULL
)
339 if (!GetTokenInformation(hToken
, TokenUser
, pTokenUser
, dwSize
, &dwSize
))
342 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
343 L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
349 for (dwIndex
= 0; ; dwIndex
++)
351 dwSidLength
= ARRAYSIZE(szProfileSid
);
352 if (RegEnumKeyExW(hKeyUserProfiles
,
362 if (RegOpenKeyExW(hKeyUserProfiles
,
366 &hProfileKey
) == ERROR_SUCCESS
)
368 AddUserProfile(hwndListView
, szProfileSid
, pTokenUser
->User
.Sid
, hProfileKey
);
369 RegCloseKey(hProfileKey
);
373 if (ListView_GetItemCount(hwndListView
) != 0)
374 ListView_SetItemState(hwndListView
, 0, LVIS_SELECTED
, LVIS_SELECTED
);
376 UpdateButtonState(hwndDlg
, hwndListView
);
379 if (hKeyUserProfiles
!= INVALID_HANDLE_VALUE
)
380 RegCloseKey(hKeyUserProfiles
);
382 if (pTokenUser
!= NULL
)
383 HeapFree(GetProcessHeap(), 0, pTokenUser
);
391 OnInitUserProfileDialog(HWND hwndDlg
)
393 /* Initialize the list view control */
394 SetListViewColumns(GetDlgItem(hwndDlg
, IDC_USERPROFILE_LIST
));
396 AddUserProfiles(hwndDlg
, GetDlgItem(hwndDlg
, IDC_USERPROFILE_LIST
));
409 hwndList
= GetDlgItem(hwndDlg
, IDC_USERPROFILE_LIST
);
411 nItems
= ListView_GetItemCount(hwndList
);
412 for (i
= 0; i
< nItems
; i
++)
416 if (ListView_GetItem(hwndList
, &Item
))
418 if (Item
.lParam
!= 0)
419 HeapFree(GetProcessHeap(), 0, (PVOID
)Item
.lParam
);
431 if (nmhdr
->idFrom
== IDC_USERACCOUNT_LINK
&& nmhdr
->code
== NM_CLICK
)
433 ShellExecuteW(hwndDlg
, NULL
, L
"usrmgr.cpl", NULL
, NULL
, 0);
435 else if (nmhdr
->idFrom
== IDC_USERPROFILE_LIST
&& nmhdr
->code
== LVN_ITEMCHANGED
)
437 UpdateButtonState(hwndDlg
, nmhdr
->hwndFrom
);
447 WCHAR szTitle
[64], szRawText
[128], szCookedText
[256];
451 PPROFILEDATA pProfileData
;
453 DPRINT("DeleteUserProfile()\n");
455 hwndListView
= GetDlgItem(hwndDlg
, IDC_USERPROFILE_LIST
);
456 if (hwndListView
== NULL
)
459 iSelected
= ListView_GetNextItem(hwndListView
, -1, LVNI_SELECTED
);
463 ZeroMemory(&Item
, sizeof(LVITEM
));
464 Item
.mask
= LVIF_PARAM
;
465 Item
.iItem
= iSelected
;
467 if (!ListView_GetItem(hwndListView
, &Item
))
470 if (Item
.lParam
== 0)
473 pProfileData
= (PPROFILEDATA
)Item
.lParam
;
474 if (pProfileData
->bMyProfile
)
477 LoadStringW(hApplet
, IDS_USERPROFILE_CONFIRM_DELETE_TITLE
, szTitle
, ARRAYSIZE(szTitle
));
478 LoadStringW(hApplet
, IDS_USERPROFILE_CONFIRM_DELETE
, szRawText
, ARRAYSIZE(szRawText
));
479 swprintf(szCookedText
, szRawText
, pProfileData
->pszFullName
);
481 if (MessageBoxW(hwndDlg
,
484 MB_ICONQUESTION
| MB_YESNO
) == IDNO
)
487 /* FIXME: Delete the profile here! */
493 /* Property page dialog callback */
495 UserProfileDlgProc(HWND hwndDlg
,
503 OnInitUserProfileDialog(hwndDlg
);
511 switch (LOWORD(wParam
))
519 case IDC_USERPROFILE_CHANGE
:
520 ChangeUserProfileType(hwndDlg
);
523 case IDC_USERPROFILE_DELETE
:
524 DeleteUserProfile(hwndDlg
);
527 case IDC_USERPROFILE_COPY
:
533 OnNotify(hwndDlg
, (NMHDR
*)lParam
);