[SYSDM]
[reactos.git] / reactos / dll / cpl / sysdm / hardprof.c
1 /*
2 * PROJECT: ReactOS System Control Panel Applet
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/sysdm/hardprof.c
5 * PURPOSE: Modify hardware profiles
6 * COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
7 *
8 */
9
10 #include "precomp.h"
11
12 #include <debug.h>
13
14 #define PROFILE_NAME_LENGTH 80
15
16 typedef struct _PROFILE
17 {
18 WCHAR szFriendlyName[PROFILE_NAME_LENGTH];
19 WCHAR szName[5];
20 DWORD dwProfileNumber;
21 DWORD dwPreferenceOrder;
22 } PROFILE, *PPROFILE;
23
24 typedef struct _PROFILEDATA
25 {
26 DWORD dwProfileCount;
27 DWORD dwLastProfile;
28 DWORD dwSelectedProfile;
29 DWORD dwSelectedProfileIndex;
30 PPROFILE pProfiles;
31 HWND hwndProfileDlg;
32 } PROFILEDATA, *PPROFILEDATA;
33
34
35 static
36 VOID
37 OnCopyProfileInit(HWND hwndDlg,
38 PPROFILEDATA pProfileData,
39 UINT idFrom,
40 UINT idTo)
41 {
42 WCHAR szNewProfileName[PROFILE_NAME_LENGTH];
43
44 SetDlgItemText(hwndDlg, idFrom, pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex].szFriendlyName);
45
46 swprintf(szNewProfileName, L"Profile %lu", pProfileData->dwProfileCount);
47 SendDlgItemMessageW(hwndDlg, idTo, EM_SETLIMITTEXT, PROFILE_NAME_LENGTH - 1, 0);
48 SetDlgItemText(hwndDlg, idTo, szNewProfileName);
49 }
50
51
52 static
53 VOID
54 CopyProfile(
55 HWND hwndDlg,
56 PPROFILEDATA pProfileData)
57 {
58 PPROFILE pProfiles;
59 // PPROFILE pSrcProfile
60 PPROFILE pDstProfile;
61
62 /* Allocate memory for the new profile */
63 pProfiles = HeapReAlloc(GetProcessHeap(),
64 HEAP_ZERO_MEMORY,
65 pProfileData->pProfiles,
66 (pProfileData->dwProfileCount + 1) * sizeof(PROFILE));
67 if (pProfiles == NULL)
68 {
69 DPRINT1("HeapReAlloc() failed!\n");
70 return;
71 }
72
73 pProfileData->dwProfileCount++;
74 pProfileData->pProfiles = pProfiles;
75
76 // pSrcProfile = &pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex];
77 pDstProfile = &pProfileData->pProfiles[pProfileData->dwProfileCount - 1];
78
79 GetDlgItemText(hwndDlg,
80 IDC_COPYPROFILETO,
81 pDstProfile->szFriendlyName,
82 PROFILE_NAME_LENGTH);
83
84 pDstProfile->dwProfileNumber = ++pProfileData->dwLastProfile;
85 swprintf(pDstProfile->szName, L"%04lu", pDstProfile->dwProfileNumber);
86
87 pDstProfile->dwPreferenceOrder = pDstProfile->dwProfileNumber;
88
89 SendDlgItemMessageW(pProfileData->hwndProfileDlg, IDC_HRDPROFLSTBOX, LB_ADDSTRING, 0, (LPARAM)pDstProfile->szFriendlyName);
90 }
91
92
93 static
94 INT_PTR
95 CALLBACK
96 CopyProfileDlgProc(HWND hwndDlg,
97 UINT uMsg,
98 WPARAM wParam,
99 LPARAM lParam)
100 {
101 PPROFILEDATA pProfileData;
102
103 pProfileData = (PPROFILEDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
104
105 switch (uMsg)
106 {
107 case WM_INITDIALOG:
108 SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
109 pProfileData = (PPROFILEDATA)lParam;
110 OnCopyProfileInit(hwndDlg, pProfileData, IDC_COPYPROFILEFROM, IDC_COPYPROFILETO);
111 break;
112
113 case WM_COMMAND:
114 switch (LOWORD(wParam))
115 {
116 case IDOK:
117 CopyProfile(hwndDlg, pProfileData);
118 EndDialog(hwndDlg, IDOK);
119 return TRUE;
120
121 case IDCANCEL:
122 EndDialog(hwndDlg, IDCANCEL);
123 return TRUE;
124 }
125 break;
126 }
127 return FALSE;
128 }
129
130
131 static
132 VOID
133 RenameProfile(
134 HWND hwndDlg,
135 PPROFILEDATA pProfileData)
136 {
137 PPROFILE pProfile;
138
139 pProfile = &pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex];
140
141 GetDlgItemText(hwndDlg,
142 IDC_RENPROFEDITTO,
143 pProfile->szFriendlyName,
144 PROFILE_NAME_LENGTH);
145
146 /* Replace the listbox string */
147 SendDlgItemMessageW(pProfileData->hwndProfileDlg, IDC_HRDPROFLSTBOX, LB_DELETESTRING, pProfileData->dwSelectedProfileIndex, 0);
148 SendDlgItemMessageW(pProfileData->hwndProfileDlg, IDC_HRDPROFLSTBOX, LB_INSERTSTRING, pProfileData->dwSelectedProfileIndex, (LPARAM)pProfile->szFriendlyName);
149 }
150
151
152 static
153 INT_PTR
154 CALLBACK
155 RenameProfileDlgProc(HWND hwndDlg,
156 UINT uMsg,
157 WPARAM wParam,
158 LPARAM lParam)
159 {
160 PPROFILEDATA pProfileData;
161
162 pProfileData = (PPROFILEDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
163
164 switch (uMsg)
165 {
166 case WM_INITDIALOG:
167 SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
168 pProfileData = (PPROFILEDATA)lParam;
169 OnCopyProfileInit(hwndDlg, pProfileData, IDC_RENPROFEDITFROM, IDC_RENPROFEDITTO);
170 break;
171
172 case WM_COMMAND:
173 switch (LOWORD(wParam))
174 {
175 case IDOK:
176 RenameProfile(hwndDlg, pProfileData);
177 EndDialog(hwndDlg, IDOK);
178 return TRUE;
179
180 case IDCANCEL:
181 EndDialog(hwndDlg, IDCANCEL);
182 return TRUE;
183 }
184 break;
185 }
186
187 return FALSE;
188 }
189
190
191 static
192 VOID
193 DeleteHardwareProfile(PPROFILEDATA pProfileData)
194 {
195 WCHAR szMessage[256];
196 WCHAR szBuffer[128];
197 WCHAR szCaption[80];
198 PPROFILE pProfiles;
199 PPROFILE pProfile;
200 INT n;
201
202 pProfile = &pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex];
203
204 LoadStringW(hApplet, IDS_HWPROFILE_CONFIRM_DELETE_TITLE, szCaption, sizeof(szCaption) / sizeof(WCHAR));
205 LoadStringW(hApplet, IDS_HWPROFILE_CONFIRM_DELETE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR));
206 swprintf(szMessage, szBuffer, pProfile->szFriendlyName);
207
208 n = MessageBox(NULL,
209 szMessage,
210 szCaption,
211 MB_YESNO | MB_ICONQUESTION);
212 if (n == IDYES)
213 {
214 SendDlgItemMessageW(pProfileData->hwndProfileDlg, IDC_HRDPROFLSTBOX, LB_DELETESTRING, pProfileData->dwSelectedProfileIndex, 0);
215
216 if (pProfileData->dwSelectedProfileIndex != pProfileData->dwProfileCount - 1)
217 {
218 RtlMoveMemory(&pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex],
219 &pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex + 1],
220 (pProfileData->dwProfileCount - pProfileData->dwSelectedProfileIndex - 1) * sizeof(PPROFILE));
221 }
222 else
223 {
224 pProfileData->dwSelectedProfileIndex--;
225 }
226
227 pProfiles = HeapReAlloc(GetProcessHeap(),
228 HEAP_ZERO_MEMORY,
229 pProfileData->pProfiles,
230 (pProfileData->dwProfileCount - 1) * sizeof(PROFILE));
231 if (pProfiles == NULL)
232 {
233 DPRINT1("HeapReAlloc() failed!\n");
234 return;
235 }
236
237 pProfileData->dwProfileCount--;
238 pProfileData->pProfiles = pProfiles;
239
240 SendDlgItemMessageW(pProfileData->hwndProfileDlg, IDC_HRDPROFLSTBOX, LB_SETCURSEL, pProfileData->dwSelectedProfileIndex, 0);
241 }
242 }
243
244
245 static
246 DWORD
247 GetUserWaitInterval(VOID)
248 {
249 DWORD dwWaitInterval = 30;
250 DWORD dwSize;
251 HKEY hKey;
252
253 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
254 L"System\\CurrentControlSet\\Control\\IDConfigDB",
255 0,
256 KEY_QUERY_VALUE,
257 &hKey))
258 return dwWaitInterval;
259
260 dwSize = sizeof(DWORD);
261 RegQueryValueExW(hKey,
262 L"UserWaitInterval",
263 NULL,
264 NULL,
265 (LPBYTE)&dwWaitInterval,
266 &dwSize);
267
268 RegCloseKey(hKey);
269
270 return dwWaitInterval;
271 }
272
273
274 static
275 VOID
276 SetUserWaitInterval(DWORD dwWaitInterval)
277 {
278 HKEY hKey;
279
280 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
281 L"System\\CurrentControlSet\\Control\\IDConfigDB",
282 0,
283 KEY_SET_VALUE,
284 &hKey))
285 return;
286
287 RegSetValueExW(hKey,
288 L"UserWaitInterval",
289 0,
290 REG_DWORD,
291 (LPBYTE)&dwWaitInterval,
292 sizeof(DWORD));
293
294 RegCloseKey(hKey);
295 }
296
297
298 static
299 BOOL
300 GetProfileCount(LPDWORD lpProfileCount)
301 {
302 HKEY hKey;
303 LONG lError;
304
305 *lpProfileCount = 0;
306
307 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
308 L"System\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles",
309 0,
310 KEY_READ,
311 &hKey);
312 if (lError != ERROR_SUCCESS)
313 return FALSE;
314
315 lError = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, lpProfileCount,
316 NULL, NULL, NULL, NULL, NULL, NULL, NULL);
317
318 RegCloseKey(hKey);
319
320 if (lError != ERROR_SUCCESS)
321 return FALSE;
322
323 return TRUE;
324 }
325
326
327 static
328 VOID
329 GetProfile(
330 HWND hwndDlg,
331 HKEY hKey,
332 LPWSTR lpName,
333 DWORD dwProfileNumber,
334 PPROFILE pProfile)
335 {
336 HKEY hProfileKey;
337 DWORD dwSize;
338 LONG lError;
339
340 lError = RegOpenKeyExW(hKey,
341 lpName,
342 0,
343 KEY_READ,
344 &hProfileKey);
345 if (lError != ERROR_SUCCESS)
346 return;
347
348 dwSize = PROFILE_NAME_LENGTH * sizeof(WCHAR);
349 lError = RegQueryValueExW(hProfileKey,
350 L"FriendlyName",
351 NULL,
352 NULL,
353 (LPBYTE)pProfile->szFriendlyName,
354 &dwSize);
355 if (lError == ERROR_SUCCESS)
356 {
357 DPRINT1("Profile: %S\n", pProfile->szFriendlyName);
358 }
359
360 dwSize = sizeof(DWORD);
361 lError = RegQueryValueExW(hProfileKey,
362 L"PreferenceOrder",
363 NULL,
364 NULL,
365 (LPBYTE)pProfile->dwPreferenceOrder,
366 &dwSize);
367 if (lError == ERROR_SUCCESS)
368 {
369 DPRINT1("PreferenceOrder: %lu\n", pProfile->dwPreferenceOrder);
370 }
371
372 pProfile->dwProfileNumber = dwProfileNumber;
373
374 SendDlgItemMessageW(hwndDlg, IDC_HRDPROFLSTBOX, LB_ADDSTRING, 0, (LPARAM)pProfile->szFriendlyName);
375
376 RegCloseKey(hProfileKey);
377 }
378
379
380 static
381 BOOL
382 GetProfiles(HWND hwndDlg)
383 {
384 PPROFILEDATA pProfileData;
385 WCHAR szName[8];
386 DWORD dwNameLength;
387 DWORD dwProfileNumber;
388 DWORD dwIndex = 0;
389 HKEY hKey;
390 LONG lError;
391
392 pProfileData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PROFILEDATA));
393 if (pProfileData == NULL)
394 return FALSE;
395
396 pProfileData->hwndProfileDlg = hwndDlg;
397 pProfileData->dwLastProfile = (DWORD)-1;
398 pProfileData->dwSelectedProfileIndex = (DWORD)-1;
399
400 if (!GetProfileCount(&pProfileData->dwProfileCount))
401 {
402 HeapFree(GetProcessHeap(), 0, pProfileData);
403 return FALSE;
404 }
405
406 pProfileData->pProfiles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
407 pProfileData->dwProfileCount * sizeof(PROFILE));
408 if (pProfileData->pProfiles == NULL)
409 {
410 HeapFree(GetProcessHeap(), 0, pProfileData);
411 return FALSE;
412 }
413
414 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pProfileData);
415
416 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
417 L"System\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles",
418 0,
419 KEY_READ,
420 &hKey) != ERROR_SUCCESS)
421 return FALSE;
422
423 for (dwIndex = 0; dwIndex < pProfileData->dwProfileCount; dwIndex++)
424 {
425 dwNameLength = 8;
426 lError = RegEnumKeyExW(hKey,
427 dwIndex,
428 szName,
429 &dwNameLength,
430 NULL,
431 NULL,
432 NULL,
433 NULL);
434 if (lError != ERROR_SUCCESS)
435 break;
436
437 dwProfileNumber = wcstoul(szName, NULL, 10);
438 DPRINT("Profile name: %S\n", szName);
439 DPRINT("Profile number: %lu\n", dwProfileNumber);
440
441 if ((pProfileData->dwLastProfile == (DWORD)-1) ||
442 (pProfileData->dwLastProfile < dwProfileNumber))
443 pProfileData->dwLastProfile = dwProfileNumber;
444
445 DPRINT("Last Profile number: %lu\n", pProfileData->dwLastProfile);
446
447 GetProfile(hwndDlg, hKey, szName, dwProfileNumber, &pProfileData->pProfiles[dwIndex]);
448 }
449
450 RegCloseKey(hKey);
451
452 return TRUE;
453 }
454
455
456 static
457 BOOL
458 OnInitDialog(HWND hwndDlg)
459 {
460 DWORD dwWaitInterval;
461
462 DPRINT("OnInitDialog()\n");
463
464 SendMessage(GetDlgItem(hwndDlg, IDC_HRDPROFUP),
465 BM_SETIMAGE,(WPARAM)IMAGE_ICON,
466 (LPARAM)(HANDLE)LoadIcon(hApplet, MAKEINTRESOURCE(IDI_UP)));
467 SendMessage(GetDlgItem(hwndDlg, IDC_HRDPROFDWN),
468 BM_SETIMAGE,(WPARAM)IMAGE_ICON,
469 (LPARAM)(HANDLE)LoadIcon(hApplet, MAKEINTRESOURCE(IDI_DOWN)));
470
471 if (!GetProfiles(hwndDlg))
472 return FALSE;
473
474 SendDlgItemMessageW(hwndDlg, IDC_HRDPROFUPDWN, UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG((SHORT)500, 0));
475
476 dwWaitInterval = GetUserWaitInterval();
477 if (dwWaitInterval == (DWORD)-1)
478 {
479 CheckDlgButton(hwndDlg, IDC_HRDPROFWAIT, BST_CHECKED);
480 SendDlgItemMessageW(hwndDlg, IDC_HRDPROFUPDWN, UDM_SETPOS, 0, 30);
481 EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFEDIT), FALSE);
482 }
483 else
484 {
485 CheckDlgButton(hwndDlg, IDC_HRDPROFSELECT, BST_CHECKED);
486 SendDlgItemMessageW(hwndDlg, IDC_HRDPROFUPDWN, UDM_SETPOS, 0, dwWaitInterval);
487 }
488
489 return TRUE;
490 }
491
492
493 static
494 VOID
495 OnOk(HWND hwndDlg)
496 {
497 DWORD dwWaitInterval;
498
499 if (IsDlgButtonChecked(hwndDlg, IDC_HRDPROFWAIT) == BST_CHECKED)
500 {
501 dwWaitInterval = (DWORD)-1;
502 }
503 else
504 {
505 dwWaitInterval = LOWORD(SendDlgItemMessageW(hwndDlg, IDC_HRDPROFUPDWN, UDM_GETPOS, 0, 0));
506 }
507
508 SetUserWaitInterval(dwWaitInterval);
509 }
510
511
512 /* Property page dialog callback */
513 INT_PTR
514 CALLBACK
515 HardProfDlgProc(HWND hwndDlg,
516 UINT uMsg,
517 WPARAM wParam,
518 LPARAM lParam)
519 {
520 PPROFILEDATA pProfileData;
521
522 UNREFERENCED_PARAMETER(lParam);
523 UNREFERENCED_PARAMETER(wParam);
524 UNREFERENCED_PARAMETER(hwndDlg);
525
526 pProfileData = (PPROFILEDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
527
528 switch (uMsg)
529 {
530 case WM_INITDIALOG:
531 return OnInitDialog(hwndDlg);
532
533 case WM_DESTROY:
534 if (pProfileData != NULL)
535 {
536 if (pProfileData->pProfiles != NULL)
537 HeapFree(GetProcessHeap(), 0, pProfileData->pProfiles);
538 HeapFree(GetProcessHeap(), 0, pProfileData);
539 }
540 break;
541
542 case WM_COMMAND:
543 switch (LOWORD(wParam))
544 {
545 case IDC_HRDPROFCOPY:
546 DialogBoxParam(hApplet,
547 MAKEINTRESOURCE(IDD_COPYPROFILE),
548 hwndDlg,
549 (DLGPROC)CopyProfileDlgProc,
550 (LPARAM)pProfileData);
551 break;
552
553 case IDC_HRDPROFRENAME:
554 DialogBoxParam(hApplet,
555 MAKEINTRESOURCE(IDD_RENAMEPROFILE),
556 hwndDlg,
557 (DLGPROC)RenameProfileDlgProc,
558 (LPARAM)pProfileData);
559 break;
560
561 case IDC_HRDPROFDEL:
562 DeleteHardwareProfile(pProfileData);
563 break;
564
565 case IDC_HRDPROFWAIT:
566 EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFEDIT), FALSE);
567 return TRUE;
568
569 case IDC_HRDPROFSELECT:
570 EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFEDIT), TRUE);
571 return TRUE;
572
573 case IDC_HRDPROFLSTBOX:
574 if (HIWORD(wParam) == LBN_SELCHANGE)
575 {
576 pProfileData->dwSelectedProfileIndex = (DWORD)SendDlgItemMessage(hwndDlg, IDC_HRDPROFLSTBOX, LB_GETCURSEL, 0, 0);
577
578 EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFCOPY), (pProfileData->dwSelectedProfileIndex != (DWORD)-1) ? TRUE : FALSE);
579 EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFRENAME), (pProfileData->dwSelectedProfileIndex != (DWORD)-1) ? TRUE : FALSE);
580 EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFDEL), (pProfileData->dwSelectedProfileIndex != (DWORD)-1) ? TRUE : FALSE);
581 }
582 return TRUE;
583
584 case IDOK:
585 OnOk(hwndDlg);
586
587 case IDCANCEL:
588 EndDialog(hwndDlg, LOWORD(wParam));
589 return TRUE;
590 }
591 break;
592 }
593
594 return FALSE;
595 }