[SYSDM] Retrieve and show the domain and user names for the user profiles
[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 PWSTR pszFullName;
18 } PROFILEDATA, *PPROFILEDATA;
19
20
21 static VOID
22 SetListViewColumns(HWND hwndListView)
23 {
24 LV_COLUMN column;
25 RECT rect;
26 TCHAR szStr[32];
27
28 GetClientRect(hwndListView, &rect);
29
30 SendMessage(hwndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
31
32 memset(&column, 0x00, sizeof(column));
33 column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
34 column.fmt = LVCFMT_LEFT;
35 column.cx = (INT)((rect.right - rect.left) * 0.40);
36 column.iSubItem = 0;
37 LoadString(hApplet, IDS_USERPROFILE_NAME, szStr, 32);
38 column.pszText = szStr;
39 (void)ListView_InsertColumn(hwndListView, 0, &column);
40
41 column.fmt = LVCFMT_RIGHT;
42 column.cx = (INT)((rect.right - rect.left) * 0.15);
43 column.iSubItem = 1;
44 LoadString(hApplet, IDS_USERPROFILE_SIZE, szStr, 32);
45 column.pszText = szStr;
46 (void)ListView_InsertColumn(hwndListView, 1, &column);
47
48 column.fmt = LVCFMT_LEFT;
49 column.cx = (INT)((rect.right - rect.left) * 0.15);
50 column.iSubItem = 2;
51 LoadString(hApplet, IDS_USERPROFILE_TYPE, szStr, 32);
52 column.pszText = szStr;
53 (void)ListView_InsertColumn(hwndListView, 2, &column);
54
55 column.fmt = LVCFMT_LEFT;
56 column.cx = (INT)((rect.right - rect.left) * 0.15);
57 column.iSubItem = 3;
58 LoadString(hApplet, IDS_USERPROFILE_STATUS, szStr, 32);
59 column.pszText = szStr;
60 (void)ListView_InsertColumn(hwndListView, 3, &column);
61
62 column.fmt = LVCFMT_LEFT;
63 column.cx = (INT)((rect.right - rect.left) * 0.15) - GetSystemMetrics(SM_CYHSCROLL);
64 column.iSubItem = 4;
65 LoadString(hApplet, IDS_USERPROFILE_MODIFIED, szStr, 32);
66 column.pszText = szStr;
67 (void)ListView_InsertColumn(hwndListView, 4, &column);
68 }
69
70
71 static VOID
72 AddUserProfile(HWND hwndListView,
73 LPTSTR lpProfileSid)
74 {
75 PPROFILEDATA pProfileData = NULL;
76 PWSTR pszAccountName = NULL;
77 PWSTR pszDomainName = NULL;
78 SID_NAME_USE Use;
79 DWORD dwAccountNameSize, dwDomainNameSize;
80 DWORD dwProfileData;
81 PWSTR ptr;
82 PSID pSid = NULL;
83 LV_ITEM lvi;
84
85 if (!ConvertStringSidToSid(lpProfileSid,
86 &pSid))
87 return;
88
89 dwAccountNameSize = 0;
90 dwDomainNameSize = 0;
91 LookupAccountSidW(NULL,
92 pSid,
93 NULL,
94 &dwAccountNameSize,
95 NULL,
96 &dwDomainNameSize,
97 &Use);
98
99 pszDomainName = HeapAlloc(GetProcessHeap(),
100 0,
101 dwDomainNameSize * sizeof(WCHAR));
102 if (pszDomainName == NULL)
103 goto done;
104
105 pszAccountName = HeapAlloc(GetProcessHeap(),
106 0,
107 dwAccountNameSize * sizeof(WCHAR));
108 if (pszAccountName == NULL)
109 goto done;
110
111 if (!LookupAccountSidW(NULL,
112 pSid,
113 pszAccountName,
114 &dwAccountNameSize,
115 pszDomainName,
116 &dwDomainNameSize,
117 &Use))
118 goto done;
119
120 /* Show only the user accounts */
121 if (Use != SidTypeUser)
122 goto done;
123
124 dwProfileData = sizeof(PROFILEDATA) +
125 ((wcslen(pszDomainName) + wcslen(pszAccountName) + 2) * sizeof(WCHAR));
126 pProfileData = HeapAlloc(GetProcessHeap(),
127 0,
128 dwProfileData);
129 if (pProfileData == NULL)
130 goto done;
131
132 ptr = (PWSTR)((ULONG_PTR)pProfileData + sizeof(PROFILEDATA));
133 pProfileData->pszFullName = ptr;
134
135 wsprintf(pProfileData->pszFullName, L"%s\\%s", pszDomainName, pszAccountName);
136
137 memset(&lvi, 0x00, sizeof(lvi));
138 lvi.mask = LVIF_TEXT | LVIF_STATE;
139 lvi.pszText = pProfileData->pszFullName;
140 lvi.state = 0;
141 ListView_InsertItem(hwndListView, &lvi);
142
143 done:
144 if (pProfileData == NULL)
145 HeapFree(GetProcessHeap(), 0, pProfileData);
146
147 if (pszDomainName == NULL)
148 HeapFree(GetProcessHeap(), 0, pszDomainName);
149
150 if (pszAccountName == NULL)
151 HeapFree(GetProcessHeap(), 0, pszAccountName);
152
153 if (pSid != NULL)
154 LocalFree(pSid);
155 }
156
157
158 static VOID
159 AddUserProfiles(HWND hwndListView)
160 {
161 HKEY hKeyUserProfiles;
162 DWORD dwIndex;
163 TCHAR szProfileSid[64];
164 DWORD dwSidLength;
165 FILETIME ftLastWrite;
166
167 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
168 _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList"),
169 0,
170 KEY_READ,
171 &hKeyUserProfiles))
172 return;
173
174 for (dwIndex = 0; ; dwIndex++)
175 {
176 dwSidLength = 64;
177 if (RegEnumKeyEx(hKeyUserProfiles,
178 dwIndex,
179 szProfileSid,
180 &dwSidLength,
181 NULL,
182 NULL,
183 NULL,
184 &ftLastWrite))
185 break;
186
187 AddUserProfile(hwndListView, szProfileSid);
188 }
189
190 RegCloseKey(hKeyUserProfiles);
191 }
192
193
194 static VOID
195 OnInitUserProfileDialog(HWND hwndDlg)
196 {
197 /* Initialize the list view control */
198 SetListViewColumns(GetDlgItem(hwndDlg, IDC_USERPROFILE_LIST));
199
200 AddUserProfiles(GetDlgItem(hwndDlg, IDC_USERPROFILE_LIST));
201
202 /* Disable the "Delete" and "Copy To" buttons if the user is not an admin */
203 if (!IsUserAnAdmin())
204 {
205 EnableWindow(GetDlgItem(hwndDlg, IDC_USERPROFILE_DELETE), FALSE);
206 EnableWindow(GetDlgItem(hwndDlg, IDC_USERPROFILE_COPY), FALSE);
207 }
208 }
209
210
211 /* Property page dialog callback */
212 INT_PTR CALLBACK
213 UserProfileDlgProc(HWND hwndDlg,
214 UINT uMsg,
215 WPARAM wParam,
216 LPARAM lParam)
217 {
218 switch (uMsg)
219 {
220 case WM_INITDIALOG:
221 OnInitUserProfileDialog(hwndDlg);
222 break;
223
224 case WM_COMMAND:
225 if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL))
226 {
227 EndDialog(hwndDlg,
228 LOWORD(wParam));
229 return TRUE;
230 }
231 break;
232
233 case WM_NOTIFY:
234 {
235 NMHDR *nmhdr = (NMHDR *)lParam;
236
237 if (nmhdr->idFrom == IDC_USERACCOUNT_LINK && nmhdr->code == NM_CLICK)
238 {
239 ShellExecuteW(hwndDlg, NULL, L"usrmgr.cpl", NULL, NULL, 0);
240 }
241 break;
242 }
243 }
244
245 return FALSE;
246 }