[SYSDM] Update the credits list
[reactos.git] / dll / cpl / sysdm / userprofile.c
1 /*
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>
8 *
9 */
10
11 #include "precomp.h"
12 #include <sddl.h>
13
14
15 typedef struct _PROFILEDATA
16 {
17 BOOL bMyProfile;
18 PWSTR pszFullName;
19 } PROFILEDATA, *PPROFILEDATA;
20
21
22 static VOID
23 SetListViewColumns(HWND hwndListView)
24 {
25 LV_COLUMN column;
26 RECT rect;
27 TCHAR szStr[32];
28
29 GetClientRect(hwndListView, &rect);
30
31 SendMessage(hwndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
32
33 memset(&column, 0x00, sizeof(column));
34 column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
35 column.fmt = LVCFMT_LEFT;
36 column.cx = (INT)((rect.right - rect.left) * 0.40);
37 column.iSubItem = 0;
38 LoadString(hApplet, IDS_USERPROFILE_NAME, szStr, ARRAYSIZE(szStr));
39 column.pszText = szStr;
40 (void)ListView_InsertColumn(hwndListView, 0, &column);
41
42 column.fmt = LVCFMT_RIGHT;
43 column.cx = (INT)((rect.right - rect.left) * 0.15);
44 column.iSubItem = 1;
45 LoadString(hApplet, IDS_USERPROFILE_SIZE, szStr, ARRAYSIZE(szStr));
46 column.pszText = szStr;
47 (void)ListView_InsertColumn(hwndListView, 1, &column);
48
49 column.fmt = LVCFMT_LEFT;
50 column.cx = (INT)((rect.right - rect.left) * 0.15);
51 column.iSubItem = 2;
52 LoadString(hApplet, IDS_USERPROFILE_TYPE, szStr, ARRAYSIZE(szStr));
53 column.pszText = szStr;
54 (void)ListView_InsertColumn(hwndListView, 2, &column);
55
56 column.fmt = LVCFMT_LEFT;
57 column.cx = (INT)((rect.right - rect.left) * 0.15);
58 column.iSubItem = 3;
59 LoadString(hApplet, IDS_USERPROFILE_STATUS, szStr, ARRAYSIZE(szStr));
60 column.pszText = szStr;
61 (void)ListView_InsertColumn(hwndListView, 3, &column);
62
63 column.fmt = LVCFMT_LEFT;
64 column.cx = (INT)((rect.right - rect.left) * 0.15) - GetSystemMetrics(SM_CYHSCROLL);
65 column.iSubItem = 4;
66 LoadString(hApplet, IDS_USERPROFILE_MODIFIED, szStr, ARRAYSIZE(szStr));
67 column.pszText = szStr;
68 (void)ListView_InsertColumn(hwndListView, 4, &column);
69 }
70
71
72 static VOID
73 AddUserProfile(
74 _In_ HWND hwndListView,
75 _In_ LPTSTR lpProfileSid,
76 _In_ PSID pMySid)
77 {
78 PPROFILEDATA pProfileData = NULL;
79 PWSTR pszAccountName = NULL;
80 PWSTR pszDomainName = NULL;
81 SID_NAME_USE Use;
82 DWORD dwAccountNameSize, dwDomainNameSize;
83 DWORD dwProfileData;
84 PWSTR ptr;
85 PSID pSid = NULL;
86 LV_ITEM lvi;
87
88 if (!ConvertStringSidToSid(lpProfileSid,
89 &pSid))
90 return;
91
92 dwAccountNameSize = 0;
93 dwDomainNameSize = 0;
94 LookupAccountSidW(NULL,
95 pSid,
96 NULL,
97 &dwAccountNameSize,
98 NULL,
99 &dwDomainNameSize,
100 &Use);
101
102 pszDomainName = HeapAlloc(GetProcessHeap(),
103 0,
104 dwDomainNameSize * sizeof(WCHAR));
105 if (pszDomainName == NULL)
106 goto done;
107
108 pszAccountName = HeapAlloc(GetProcessHeap(),
109 0,
110 dwAccountNameSize * sizeof(WCHAR));
111 if (pszAccountName == NULL)
112 goto done;
113
114 if (!LookupAccountSidW(NULL,
115 pSid,
116 pszAccountName,
117 &dwAccountNameSize,
118 pszDomainName,
119 &dwDomainNameSize,
120 &Use))
121 goto done;
122
123 /* Show only the user accounts */
124 if (Use != SidTypeUser)
125 goto done;
126
127 dwProfileData = sizeof(PROFILEDATA) +
128 ((wcslen(pszDomainName) + wcslen(pszAccountName) + 2) * sizeof(WCHAR));
129 pProfileData = HeapAlloc(GetProcessHeap(),
130 0,
131 dwProfileData);
132 if (pProfileData == NULL)
133 goto done;
134
135 pProfileData->bMyProfile = EqualSid(pMySid, pSid);
136
137 ptr = (PWSTR)((ULONG_PTR)pProfileData + sizeof(PROFILEDATA));
138 pProfileData->pszFullName = ptr;
139
140 wsprintf(pProfileData->pszFullName, L"%s\\%s", pszDomainName, pszAccountName);
141
142 memset(&lvi, 0x00, sizeof(lvi));
143 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
144 lvi.pszText = pProfileData->pszFullName;
145 lvi.state = 0;
146 lvi.lParam = (LPARAM)pProfileData;
147 ListView_InsertItem(hwndListView, &lvi);
148
149 done:
150 if (pszDomainName != NULL)
151 HeapFree(GetProcessHeap(), 0, pszDomainName);
152
153 if (pszAccountName != NULL)
154 HeapFree(GetProcessHeap(), 0, pszAccountName);
155
156 if (pSid != NULL)
157 LocalFree(pSid);
158 }
159
160
161 static VOID
162 AddUserProfiles(HWND hwndListView)
163 {
164 HKEY hKeyUserProfiles = INVALID_HANDLE_VALUE;
165 DWORD dwIndex;
166 WCHAR szProfileSid[64];
167 DWORD dwSidLength;
168 FILETIME ftLastWrite;
169 DWORD dwSize;
170 HANDLE hToken = NULL;
171 PTOKEN_USER pTokenUser = NULL;
172
173 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
174 return;
175
176 GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
177 if (dwSize == 0)
178 goto done;
179
180 pTokenUser = HeapAlloc(GetProcessHeap(), 0, dwSize);
181 if (pTokenUser == NULL)
182 goto done;
183
184 if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
185 goto done;
186
187 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
188 L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
189 0,
190 KEY_READ,
191 &hKeyUserProfiles))
192 goto done;
193
194 for (dwIndex = 0; ; dwIndex++)
195 {
196 dwSidLength = ARRAYSIZE(szProfileSid);
197 if (RegEnumKeyExW(hKeyUserProfiles,
198 dwIndex,
199 szProfileSid,
200 &dwSidLength,
201 NULL,
202 NULL,
203 NULL,
204 &ftLastWrite))
205 break;
206
207 AddUserProfile(hwndListView, szProfileSid, pTokenUser->User.Sid);
208 }
209
210 if (ListView_GetItemCount(hwndListView) != 0)
211 ListView_SetItemState(hwndListView, 0, LVIS_SELECTED, LVIS_SELECTED);
212
213 done:
214 if (hKeyUserProfiles != INVALID_HANDLE_VALUE)
215 RegCloseKey(hKeyUserProfiles);
216
217 if (pTokenUser != NULL)
218 HeapFree(GetProcessHeap(), 0, pTokenUser);
219
220 if (hToken != NULL)
221 CloseHandle(hToken);
222 }
223
224
225 static VOID
226 OnInitUserProfileDialog(HWND hwndDlg)
227 {
228 /* Initialize the list view control */
229 SetListViewColumns(GetDlgItem(hwndDlg, IDC_USERPROFILE_LIST));
230
231 AddUserProfiles(GetDlgItem(hwndDlg, IDC_USERPROFILE_LIST));
232
233 /* Disable the "Delete" and "Copy To" buttons if the user is not an admin */
234 if (!IsUserAnAdmin())
235 {
236 EnableWindow(GetDlgItem(hwndDlg, IDC_USERPROFILE_DELETE), FALSE);
237 EnableWindow(GetDlgItem(hwndDlg, IDC_USERPROFILE_COPY), FALSE);
238 }
239 }
240
241
242 static
243 VOID
244 OnDestroy(
245 _In_ HWND hwndDlg)
246 {
247 HWND hwndList;
248 INT nItems, i;
249 LVITEM Item;
250
251 hwndList = GetDlgItem(hwndDlg, IDC_USERPROFILE_LIST);
252
253 nItems = ListView_GetItemCount(hwndList);
254 for (i = 0; i < nItems; i++)
255 {
256 Item.iItem = i;
257 Item.iSubItem = 0;
258 if (ListView_GetItem(hwndList, &Item))
259 {
260 if (Item.lParam != 0)
261 HeapFree(GetProcessHeap(), 0, (PVOID)Item.lParam);
262 }
263 }
264 }
265
266
267 static
268 VOID
269 OnNotify(
270 _In_ HWND hwndDlg,
271 _In_ NMHDR *nmhdr)
272 {
273 if (nmhdr->idFrom == IDC_USERACCOUNT_LINK && nmhdr->code == NM_CLICK)
274 {
275 ShellExecuteW(hwndDlg, NULL, L"usrmgr.cpl", NULL, NULL, 0);
276 }
277 else if (nmhdr->idFrom == IDC_USERPROFILE_LIST && nmhdr->code == LVN_ITEMCHANGED)
278 {
279 if (ListView_GetSelectedCount(nmhdr->hwndFrom) == 0)
280 {
281 EnableWindow(GetDlgItem(hwndDlg, IDC_USERPROFILE_CHANGE), FALSE);
282 EnableWindow(GetDlgItem(hwndDlg, IDC_USERPROFILE_DELETE), FALSE);
283 EnableWindow(GetDlgItem(hwndDlg, IDC_USERPROFILE_COPY), FALSE);
284 }
285 else
286 {
287 LVITEM Item;
288 INT iSelected;
289 BOOL bMyProfile = FALSE;
290
291 iSelected = ListView_GetNextItem(nmhdr->hwndFrom, -1, LVNI_SELECTED);
292 if (iSelected != -1)
293 {
294 Item.iItem = iSelected;
295 Item.iSubItem = 0;
296 if (ListView_GetItem(nmhdr->hwndFrom, &Item))
297 {
298 if (Item.lParam != 0)
299 {
300 bMyProfile = ((PPROFILEDATA)Item.lParam)->bMyProfile;
301 }
302 }
303 }
304
305 EnableWindow(GetDlgItem(hwndDlg, IDC_USERPROFILE_CHANGE), TRUE);
306 if (IsUserAnAdmin() && !bMyProfile)
307 {
308 EnableWindow(GetDlgItem(hwndDlg, IDC_USERPROFILE_DELETE), TRUE);
309 EnableWindow(GetDlgItem(hwndDlg, IDC_USERPROFILE_COPY), TRUE);
310 }
311 }
312 }
313 }
314
315
316 /* Property page dialog callback */
317 INT_PTR CALLBACK
318 UserProfileDlgProc(HWND hwndDlg,
319 UINT uMsg,
320 WPARAM wParam,
321 LPARAM lParam)
322 {
323 switch (uMsg)
324 {
325 case WM_INITDIALOG:
326 OnInitUserProfileDialog(hwndDlg);
327 break;
328
329 case WM_DESTROY:
330 OnDestroy(hwndDlg);
331 break;
332
333 case WM_COMMAND:
334 switch (LOWORD(wParam))
335 {
336 case IDOK:
337 case IDCANCEL:
338 EndDialog(hwndDlg,
339 LOWORD(wParam));
340 return TRUE;
341
342 case IDC_USERPROFILE_DELETE:
343 break;
344 }
345 break;
346
347 case WM_NOTIFY:
348 OnNotify(hwndDlg, (NMHDR *)lParam);
349 break;
350 }
351
352 return FALSE;
353 }