xref: /reactos/dll/cpl/sysdm/hardprof.c (revision 1734f297)
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 } PROFILEDATA, *PPROFILEDATA;
32 
33 typedef struct _PROFILENAMES
34 {
35     WCHAR szSourceName[PROFILE_NAME_LENGTH];
36     WCHAR szDestinationName[PROFILE_NAME_LENGTH];
37     PPROFILEDATA pProfileData;
38 } PROFILENAMES, *PPROFILENAMES;
39 
40 
41 static
42 VOID
43 UpdateButtons(
44     HWND hwndDlg,
45     PPROFILEDATA pProfileData)
46 {
47     EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFPROP), (pProfileData->dwSelectedProfileIndex != (DWORD)-1) ? TRUE : FALSE);
48     EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFCOPY), (pProfileData->dwSelectedProfileIndex != (DWORD)-1) ? TRUE : FALSE);
49     EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFRENAME), (pProfileData->dwSelectedProfileIndex != (DWORD)-1) ? TRUE : FALSE);
50     EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFDEL), (pProfileData->dwSelectedProfileIndex != (DWORD)-1) ? TRUE : FALSE);
51 
52     if (pProfileData->dwProfileCount < 2)
53     {
54         EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFUP), FALSE);
55         EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFDWN), FALSE);
56     }
57     else
58     {
59         EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFUP),
60                      (pProfileData->dwSelectedProfileIndex > 0) ? TRUE : FALSE);
61         EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFDWN),
62                      (pProfileData->dwSelectedProfileIndex < pProfileData->dwProfileCount - 1) ? TRUE : FALSE);
63     }
64 }
65 
66 
67 static
68 BOOL
69 IsProfileNameInUse(
70     PPROFILENAMES pProfileNames,
71     BOOL bIgnoreCurrent)
72 {
73     DWORD i;
74 
75     for (i = 0; i < pProfileNames->pProfileData->dwProfileCount; i++)
76     {
77         if (bIgnoreCurrent == TRUE && i == pProfileNames->pProfileData->dwSelectedProfileIndex)
78             continue;
79 
80         if (wcscmp(pProfileNames->pProfileData->pProfiles[i].szFriendlyName, pProfileNames->szDestinationName) == 0)
81             return TRUE;
82     }
83 
84     return FALSE;
85 }
86 
87 
88 static
89 INT_PTR
90 CALLBACK
91 CopyProfileDlgProc(
92     HWND hwndDlg,
93     UINT uMsg,
94     WPARAM wParam,
95     LPARAM lParam)
96 {
97     PPROFILENAMES pProfileNames;
98 
99     pProfileNames = (PPROFILENAMES)GetWindowLongPtr(hwndDlg, DWLP_USER);
100 
101     switch (uMsg)
102     {
103         case WM_INITDIALOG:
104             SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
105             pProfileNames = (PPROFILENAMES)lParam;
106 
107             /* Set the old name */
108             SetDlgItemText(hwndDlg, IDC_COPYPROFILEFROM, pProfileNames->szSourceName);
109 
110             /* Set the new name */
111             SendDlgItemMessageW(hwndDlg, IDC_COPYPROFILETO, EM_SETLIMITTEXT, PROFILE_NAME_LENGTH - 1, 0);
112             SetDlgItemText(hwndDlg, IDC_COPYPROFILETO, pProfileNames->szDestinationName);
113             break;
114 
115         case WM_COMMAND:
116             switch (LOWORD(wParam))
117             {
118                 case IDOK:
119                     GetDlgItemText(hwndDlg,
120                                    IDC_COPYPROFILETO,
121                                    pProfileNames->szDestinationName,
122                                    PROFILE_NAME_LENGTH);
123                     if (IsProfileNameInUse(pProfileNames, FALSE))
124                     {
125                         ResourceMessageBox(hApplet,
126                                            hwndDlg,
127                                            MB_OK | MB_ICONERROR,
128                                            IDS_HWPROFILE_WARNING,
129                                            IDS_HWPROFILE_ALREADY_IN_USE);
130                     }
131                     else
132                     {
133                         EndDialog(hwndDlg, IDOK);
134                     }
135                     return TRUE;
136 
137                 case IDCANCEL:
138                     EndDialog(hwndDlg, IDCANCEL);
139                     return TRUE;
140             }
141             break;
142     }
143 
144     return FALSE;
145 }
146 
147 
148 static
149 VOID
150 CopyHardwareProfile(
151     HWND hwndDlg,
152     PPROFILEDATA pProfileData)
153 {
154     PROFILENAMES ProfileNames;
155     PPROFILE pProfile, pNewProfiles, pNewProfile;
156     WCHAR szBuffer[80];
157 
158     pProfile = &pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex];
159 
160     LoadStringW(hApplet, IDS_HWPROFILE_PROFILE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR));
161 
162     wcscpy(ProfileNames.szSourceName, pProfile->szFriendlyName);
163     swprintf(ProfileNames.szDestinationName, L"%s %lu", szBuffer, pProfileData->dwProfileCount);
164 
165     ProfileNames.pProfileData = pProfileData;
166 
167     if (DialogBoxParam(hApplet,
168                        MAKEINTRESOURCE(IDD_COPYPROFILE),
169                        hwndDlg,
170                        CopyProfileDlgProc,
171                        (LPARAM)&ProfileNames) != IDOK)
172         return;
173 
174     /* Apply new name only if it has been changed */
175     if (wcscmp(ProfileNames.szSourceName, ProfileNames.szDestinationName) == 0)
176         return;
177 
178     /* Allocate memory for the new profile */
179     pNewProfiles = HeapReAlloc(GetProcessHeap(),
180                                HEAP_ZERO_MEMORY,
181                                pProfileData->pProfiles,
182                                (pProfileData->dwProfileCount + 1) * sizeof(PROFILE));
183     if (pNewProfiles == NULL)
184     {
185         DPRINT1("HeapReAlloc() failed!\n");
186         return;
187     }
188 
189     pProfileData->dwProfileCount++;
190     pProfileData->pProfiles = pNewProfiles;
191 
192     pNewProfile = &pProfileData->pProfiles[pProfileData->dwProfileCount - 1];
193 
194     CopyMemory(pNewProfile, pProfile, sizeof(PROFILE));
195 
196     wcscpy(pNewProfile->szFriendlyName, ProfileNames.szDestinationName);
197 
198     pNewProfile->dwProfileNumber = ++pProfileData->dwLastProfile;
199     swprintf(pNewProfile->szName, L"%04lu", pNewProfile->dwProfileNumber);
200 
201     pNewProfile->dwPreferenceOrder = pNewProfile->dwProfileNumber;
202 
203     SendDlgItemMessageW(hwndDlg, IDC_HRDPROFLSTBOX, LB_ADDSTRING, 0, (LPARAM)pNewProfile->szFriendlyName);
204 
205     UpdateButtons(hwndDlg, pProfileData);
206 }
207 
208 
209 static
210 INT_PTR
211 CALLBACK
212 RenameProfileDlgProc(
213     HWND hwndDlg,
214     UINT uMsg,
215     WPARAM wParam,
216     LPARAM lParam)
217 {
218     PPROFILENAMES pProfileNames;
219 
220     pProfileNames = (PPROFILENAMES)GetWindowLongPtr(hwndDlg, DWLP_USER);
221 
222     switch (uMsg)
223     {
224         case WM_INITDIALOG:
225             SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
226             pProfileNames = (PPROFILENAMES)lParam;
227 
228             /* Set the old name */
229             SetDlgItemText(hwndDlg, IDC_RENPROFEDITFROM, pProfileNames->szSourceName);
230 
231             /* Set the new name */
232             SendDlgItemMessageW(hwndDlg, IDC_RENPROFEDITTO, EM_SETLIMITTEXT, PROFILE_NAME_LENGTH - 1, 0);
233             SetDlgItemText(hwndDlg, IDC_RENPROFEDITTO, pProfileNames->szDestinationName);
234             break;
235 
236         case WM_COMMAND:
237             switch (LOWORD(wParam))
238             {
239                 case IDOK:
240                     GetDlgItemText(hwndDlg,
241                                    IDC_RENPROFEDITTO,
242                                    pProfileNames->szDestinationName,
243                                    PROFILE_NAME_LENGTH);
244                     if (IsProfileNameInUse(pProfileNames, TRUE))
245                     {
246                         ResourceMessageBox(hApplet,
247                                            hwndDlg,
248                                            MB_OK | MB_ICONERROR,
249                                            IDS_HWPROFILE_WARNING,
250                                            IDS_HWPROFILE_ALREADY_IN_USE);
251                     }
252                     else
253                     {
254                         EndDialog(hwndDlg, IDOK);
255                     }
256                     return TRUE;
257 
258                 case IDCANCEL:
259                     EndDialog(hwndDlg, IDCANCEL);
260                     return TRUE;
261             }
262             break;
263     }
264 
265     return FALSE;
266 }
267 
268 
269 static
270 VOID
271 RenameHardwareProfile(
272     HWND hwndDlg,
273     PPROFILEDATA pProfileData)
274 {
275     PROFILENAMES ProfileNames;
276     PPROFILE pProfile;
277     WCHAR szBuffer[80];
278 
279     pProfile = &pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex];
280 
281     LoadStringW(hApplet, IDS_HWPROFILE_PROFILE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR));
282 
283     wcscpy(ProfileNames.szSourceName, pProfile->szFriendlyName);
284     swprintf(ProfileNames.szDestinationName, L"%s %lu", szBuffer, pProfileData->dwProfileCount);
285 
286     ProfileNames.pProfileData = pProfileData;
287 
288     if (DialogBoxParam(hApplet,
289                        MAKEINTRESOURCE(IDD_RENAMEPROFILE),
290                        hwndDlg,
291                        RenameProfileDlgProc,
292                        (LPARAM)&ProfileNames) != IDOK)
293         return;
294 
295     /* Apply new name only if it has been changed */
296     if (wcscmp(pProfile->szFriendlyName, ProfileNames.szDestinationName) == 0)
297         return;
298 
299     /* Replace the profile name in the profile list */
300     wcscpy(pProfile->szFriendlyName, ProfileNames.szDestinationName);
301 
302     /* Replace the profile name in the listbox */
303     SendDlgItemMessageW(hwndDlg, IDC_HRDPROFLSTBOX, LB_DELETESTRING, pProfileData->dwSelectedProfileIndex, 0);
304     SendDlgItemMessageW(hwndDlg, IDC_HRDPROFLSTBOX, LB_INSERTSTRING, pProfileData->dwSelectedProfileIndex, (LPARAM)pProfile->szFriendlyName);
305 }
306 
307 
308 static
309 VOID
310 DeleteHardwareProfile(
311     HWND hwndDlg,
312     PPROFILEDATA pProfileData)
313 {
314     PPROFILE pProfiles;
315     PPROFILE pProfile;
316 
317     pProfile = &pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex];
318 
319     if (ResourceMessageBox(hApplet,
320                            hwndDlg,
321                            MB_YESNO | MB_ICONQUESTION,
322                            IDS_HWPROFILE_CONFIRM_DELETE_TITLE,
323                            IDS_HWPROFILE_CONFIRM_DELETE,
324                            pProfile->szFriendlyName) != IDYES)
325     {
326         return;
327     }
328 
329     SendDlgItemMessageW(hwndDlg, IDC_HRDPROFLSTBOX, LB_DELETESTRING, pProfileData->dwSelectedProfileIndex, 0);
330 
331     if (pProfileData->dwSelectedProfileIndex != pProfileData->dwProfileCount - 1)
332     {
333         RtlMoveMemory(&pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex],
334                       &pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex + 1],
335                       (pProfileData->dwProfileCount - pProfileData->dwSelectedProfileIndex - 1) * sizeof(PROFILE));
336     }
337     else
338     {
339         pProfileData->dwSelectedProfileIndex--;
340     }
341 
342     pProfiles = HeapReAlloc(GetProcessHeap(),
343                             HEAP_ZERO_MEMORY,
344                             pProfileData->pProfiles,
345                             (pProfileData->dwProfileCount - 1) * sizeof(PROFILE));
346     if (pProfiles == NULL)
347     {
348         DPRINT1("HeapReAlloc() failed!\n");
349         return;
350     }
351 
352     pProfileData->dwProfileCount--;
353     pProfileData->pProfiles = pProfiles;
354 
355     SendDlgItemMessageW(hwndDlg, IDC_HRDPROFLSTBOX, LB_SETCURSEL, pProfileData->dwSelectedProfileIndex, 0);
356 
357     UpdateButtons(hwndDlg, pProfileData);
358 }
359 
360 
361 static
362 VOID
363 MoveHardwareProfile(
364     HWND hwndDlg,
365     PPROFILEDATA pProfileData,
366     BOOL bMoveUp)
367 {
368     PROFILE TempProfile;
369     PPROFILE pSrcProfile, pDstProfile;
370     DWORD dwSrcIndex, dwDstIndex;
371 
372     dwSrcIndex = pProfileData->dwSelectedProfileIndex;
373     dwDstIndex = bMoveUp ? (dwSrcIndex - 1) : (dwSrcIndex + 1);
374 
375     pSrcProfile = &pProfileData->pProfiles[dwSrcIndex];
376     pDstProfile = &pProfileData->pProfiles[dwDstIndex];
377 
378     CopyMemory(&TempProfile, pDstProfile, sizeof(PROFILE));
379     CopyMemory(pDstProfile, pSrcProfile, sizeof(PROFILE));
380     CopyMemory(pSrcProfile, &TempProfile, sizeof(PROFILE));
381 
382     SendDlgItemMessageW(hwndDlg, IDC_HRDPROFLSTBOX, LB_DELETESTRING, dwSrcIndex, 0);
383     SendDlgItemMessageW(hwndDlg, IDC_HRDPROFLSTBOX, LB_INSERTSTRING, dwDstIndex, (LPARAM)pDstProfile->szFriendlyName);
384 
385     pProfileData->dwSelectedProfileIndex = dwDstIndex;
386     SendDlgItemMessageW(hwndDlg, IDC_HRDPROFLSTBOX, LB_SETCURSEL, pProfileData->dwSelectedProfileIndex, 0);
387 
388     UpdateButtons(hwndDlg, pProfileData);
389 }
390 
391 
392 static
393 INT_PTR
394 CALLBACK
395 HardwareProfilePropertiesDlgProc(
396     HWND hwndDlg,
397     UINT uMsg,
398     WPARAM wParam,
399     LPARAM lParam)
400 {
401     UNREFERENCED_PARAMETER(hwndDlg);
402     UNREFERENCED_PARAMETER(lParam);
403     UNREFERENCED_PARAMETER(wParam);
404 
405     switch (uMsg)
406     {
407         case WM_INITDIALOG:
408             return TRUE;
409 
410     }
411 
412     return FALSE;
413 }
414 
415 static int CALLBACK
416 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
417 {
418     // NOTE: This callback is needed to set large icon correctly.
419     HICON hIcon;
420     switch (uMsg)
421     {
422         case PSCB_INITIALIZED:
423         {
424             hIcon = LoadIconW(hApplet, MAKEINTRESOURCEW(IDI_HARDPROF));
425             SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
426             break;
427         }
428     }
429     return 0;
430 }
431 
432 static
433 VOID
434 HardwareProfileProperties(
435     HWND hwndDlg,
436     PPROFILEDATA pProfileData)
437 {
438     HPROPSHEETPAGE hpsp;
439     PROPSHEETHEADER psh;
440     PROPSHEETPAGE psp;
441 
442     ZeroMemory(&psp, sizeof(psp));
443     psp.dwSize = sizeof(psp);
444     psp.dwFlags = PSP_DEFAULT;
445     psp.hInstance = hApplet;
446     psp.pszTemplate = MAKEINTRESOURCE(IDD_HARDWAREPROFILE);
447     psp.pfnDlgProc = HardwareProfilePropertiesDlgProc;
448 
449     hpsp = CreatePropertySheetPage(&psp);
450     if (hpsp == NULL)
451     {
452         return;
453     }
454 
455     ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
456     psh.dwSize = sizeof(PROPSHEETHEADER);
457     psh.dwFlags = PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK;
458     psh.hwndParent = hwndDlg;
459     psh.hInstance = hApplet;
460     psh.pszIcon = MAKEINTRESOURCEW(IDI_HARDPROF);
461     psh.pszCaption = pProfileData->pProfiles[pProfileData->dwSelectedProfileIndex].szFriendlyName;
462     psh.nPages = 1;
463     psh.nStartPage = 0;
464     psh.phpage = &hpsp;
465     psh.pfnCallback = PropSheetProc;
466 
467     PropertySheet(&psh);
468 }
469 
470 
471 static
472 DWORD
473 GetUserWaitInterval(VOID)
474 {
475     DWORD dwWaitInterval = 30;
476     DWORD dwSize;
477     HKEY hKey;
478 
479     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
480                       L"System\\CurrentControlSet\\Control\\IDConfigDB",
481                       0,
482                       KEY_QUERY_VALUE,
483                       &hKey))
484         return dwWaitInterval;
485 
486     dwSize = sizeof(DWORD);
487     RegQueryValueExW(hKey,
488                      L"UserWaitInterval",
489                      NULL,
490                      NULL,
491                      (LPBYTE)&dwWaitInterval,
492                      &dwSize);
493 
494     RegCloseKey(hKey);
495 
496     return dwWaitInterval;
497 }
498 
499 
500 static
501 VOID
502 SetUserWaitInterval(DWORD dwWaitInterval)
503 {
504     HKEY hKey;
505 
506     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
507                       L"System\\CurrentControlSet\\Control\\IDConfigDB",
508                       0,
509                       KEY_SET_VALUE,
510                       &hKey))
511         return;
512 
513     RegSetValueExW(hKey,
514                    L"UserWaitInterval",
515                    0,
516                    REG_DWORD,
517                    (LPBYTE)&dwWaitInterval,
518                    sizeof(DWORD));
519 
520     RegCloseKey(hKey);
521 }
522 
523 
524 static
525 BOOL
526 GetProfileCount(LPDWORD lpProfileCount)
527 {
528     HKEY hKey;
529     LONG lError;
530 
531     *lpProfileCount = 0;
532 
533     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
534                            L"System\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles",
535                            0,
536                            KEY_READ,
537                            &hKey);
538     if (lError != ERROR_SUCCESS)
539         return FALSE;
540 
541     lError = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, lpProfileCount,
542                               NULL, NULL, NULL, NULL, NULL, NULL, NULL);
543 
544     RegCloseKey(hKey);
545 
546     if (lError != ERROR_SUCCESS)
547         return FALSE;
548 
549     return TRUE;
550 }
551 
552 
553 static
554 VOID
555 GetProfile(
556     HWND hwndDlg,
557     HKEY hKey,
558     LPWSTR lpName,
559     DWORD dwProfileNumber,
560     PPROFILE pProfile)
561 {
562     HKEY hProfileKey;
563     DWORD dwSize;
564     LONG lError;
565 
566     lError = RegOpenKeyExW(hKey,
567                            lpName,
568                            0,
569                            KEY_READ,
570                            &hProfileKey);
571     if (lError != ERROR_SUCCESS)
572         return;
573 
574     dwSize = PROFILE_NAME_LENGTH * sizeof(WCHAR);
575     lError = RegQueryValueExW(hProfileKey,
576                               L"FriendlyName",
577                               NULL,
578                               NULL,
579                               (LPBYTE)pProfile->szFriendlyName,
580                               &dwSize);
581     if (lError == ERROR_SUCCESS)
582     {
583         DPRINT1("Profile: %S\n", pProfile->szFriendlyName);
584     }
585 
586     dwSize = sizeof(DWORD);
587     lError = RegQueryValueExW(hProfileKey,
588                               L"PreferenceOrder",
589                               NULL,
590                               NULL,
591                               (LPBYTE)&pProfile->dwPreferenceOrder,
592                               &dwSize);
593     if (lError == ERROR_SUCCESS)
594     {
595         DPRINT1("PreferenceOrder: %lu\n", pProfile->dwPreferenceOrder);
596     }
597 
598     pProfile->dwProfileNumber = dwProfileNumber;
599 
600     SendDlgItemMessageW(hwndDlg, IDC_HRDPROFLSTBOX, LB_ADDSTRING, 0, (LPARAM)pProfile->szFriendlyName);
601 
602     RegCloseKey(hProfileKey);
603 }
604 
605 
606 static
607 BOOL
608 GetProfiles(HWND hwndDlg)
609 {
610     PPROFILEDATA pProfileData;
611     WCHAR szName[8];
612     DWORD dwNameLength;
613     DWORD dwProfileNumber;
614     DWORD dwIndex = 0;
615     HKEY hKey;
616     LONG lError;
617 
618     pProfileData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PROFILEDATA));
619     if (pProfileData == NULL)
620         return FALSE;
621 
622     pProfileData->dwLastProfile = (DWORD)-1;
623     pProfileData->dwSelectedProfileIndex = (DWORD)-1;
624 
625     if (!GetProfileCount(&pProfileData->dwProfileCount))
626     {
627         HeapFree(GetProcessHeap(), 0, pProfileData);
628         return FALSE;
629     }
630 
631     pProfileData->pProfiles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
632                                         pProfileData->dwProfileCount * sizeof(PROFILE));
633     if (pProfileData->pProfiles == NULL)
634     {
635         HeapFree(GetProcessHeap(), 0, pProfileData);
636         return FALSE;
637     }
638 
639     SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pProfileData);
640 
641     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
642                       L"System\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles",
643                       0,
644                       KEY_READ,
645                       &hKey) != ERROR_SUCCESS)
646         return FALSE;
647 
648     for (dwIndex = 0; dwIndex < pProfileData->dwProfileCount; dwIndex++)
649     {
650         dwNameLength = 8;
651         lError = RegEnumKeyExW(hKey,
652                                dwIndex,
653                                szName,
654                                &dwNameLength,
655                                NULL,
656                                NULL,
657                                NULL,
658                                NULL);
659         if (lError != ERROR_SUCCESS)
660             break;
661 
662         dwProfileNumber = wcstoul(szName, NULL, 10);
663         DPRINT("Profile name: %S\n", szName);
664         DPRINT("Profile number: %lu\n", dwProfileNumber);
665 
666         if ((pProfileData->dwLastProfile == (DWORD)-1) ||
667             (pProfileData->dwLastProfile < dwProfileNumber))
668             pProfileData->dwLastProfile = dwProfileNumber;
669 
670         DPRINT("Last Profile number: %lu\n", pProfileData->dwLastProfile);
671 
672         GetProfile(hwndDlg, hKey, szName, dwProfileNumber, &pProfileData->pProfiles[dwIndex]);
673     }
674 
675     RegCloseKey(hKey);
676 
677     return TRUE;
678 }
679 
680 
681 static
682 BOOL
683 OnInitHardProfDialog(HWND hwndDlg)
684 {
685     DWORD dwWaitInterval;
686 
687     DPRINT("OnInitHardProfDialog()\n");
688 
689     SendMessage(GetDlgItem(hwndDlg, IDC_HRDPROFUP),
690                 BM_SETIMAGE,(WPARAM)IMAGE_ICON,
691                 (LPARAM)(HANDLE)LoadIcon(hApplet, MAKEINTRESOURCE(IDI_UP)));
692     SendMessage(GetDlgItem(hwndDlg, IDC_HRDPROFDWN),
693                 BM_SETIMAGE,(WPARAM)IMAGE_ICON,
694                 (LPARAM)(HANDLE)LoadIcon(hApplet, MAKEINTRESOURCE(IDI_DOWN)));
695 
696     if (!GetProfiles(hwndDlg))
697         return FALSE;
698 
699     SendDlgItemMessageW(hwndDlg, IDC_HRDPROFUPDWN, UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG((SHORT)500, 0));
700 
701     dwWaitInterval = GetUserWaitInterval();
702     if (dwWaitInterval == (DWORD)-1)
703     {
704         CheckDlgButton(hwndDlg, IDC_HRDPROFWAIT, BST_CHECKED);
705         SendDlgItemMessageW(hwndDlg, IDC_HRDPROFUPDWN, UDM_SETPOS, 0, 30);
706         EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFEDIT), FALSE);
707     }
708     else
709     {
710         CheckDlgButton(hwndDlg, IDC_HRDPROFSELECT, BST_CHECKED);
711         SendDlgItemMessageW(hwndDlg, IDC_HRDPROFUPDWN, UDM_SETPOS, 0, dwWaitInterval);
712     }
713 
714     return TRUE;
715 }
716 
717 
718 static
719 VOID
720 OnOk(HWND hwndDlg)
721 {
722     DWORD dwWaitInterval;
723 
724     if (IsDlgButtonChecked(hwndDlg, IDC_HRDPROFWAIT) == BST_CHECKED)
725     {
726         dwWaitInterval = (DWORD)-1;
727     }
728     else
729     {
730         dwWaitInterval = LOWORD(SendDlgItemMessageW(hwndDlg, IDC_HRDPROFUPDWN, UDM_GETPOS, 0, 0));
731     }
732 
733     SetUserWaitInterval(dwWaitInterval);
734 }
735 
736 
737 /* Property page dialog callback */
738 INT_PTR
739 CALLBACK
740 HardProfDlgProc(HWND hwndDlg,
741                 UINT uMsg,
742                 WPARAM wParam,
743                 LPARAM lParam)
744 {
745     PPROFILEDATA pProfileData;
746 
747     UNREFERENCED_PARAMETER(lParam);
748     UNREFERENCED_PARAMETER(wParam);
749     UNREFERENCED_PARAMETER(hwndDlg);
750 
751     pProfileData = (PPROFILEDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
752 
753     switch (uMsg)
754     {
755         case WM_INITDIALOG:
756             return OnInitHardProfDialog(hwndDlg);
757 
758         case WM_DESTROY:
759             if (pProfileData != NULL)
760             {
761                 if (pProfileData->pProfiles != NULL)
762                     HeapFree(GetProcessHeap(), 0, pProfileData->pProfiles);
763                 HeapFree(GetProcessHeap(), 0, pProfileData);
764             }
765             break;
766 
767         case WM_COMMAND:
768             switch (LOWORD(wParam))
769             {
770                 case IDC_HRDPROFPROP:
771                     HardwareProfileProperties(hwndDlg, pProfileData);
772                     break;
773 
774                 case IDC_HRDPROFCOPY:
775                     CopyHardwareProfile(hwndDlg, pProfileData);
776                     break;
777 
778                 case IDC_HRDPROFRENAME:
779                     RenameHardwareProfile(hwndDlg, pProfileData);
780                     break;
781 
782                 case IDC_HRDPROFDEL:
783                     DeleteHardwareProfile(hwndDlg, pProfileData);
784                     break;
785 
786                 case IDC_HRDPROFUP:
787                     MoveHardwareProfile(hwndDlg, pProfileData, TRUE);
788                     break;
789 
790                 case IDC_HRDPROFDWN:
791                     MoveHardwareProfile(hwndDlg, pProfileData, FALSE);
792                     break;
793 
794                 case IDC_HRDPROFWAIT:
795                     EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFEDIT), FALSE);
796                     return TRUE;
797 
798                 case IDC_HRDPROFSELECT:
799                     EnableWindow(GetDlgItem(hwndDlg, IDC_HRDPROFEDIT), TRUE);
800                     return TRUE;
801 
802                 case IDC_HRDPROFLSTBOX:
803                     if (HIWORD(wParam) == LBN_SELCHANGE)
804                     {
805                         pProfileData->dwSelectedProfileIndex = (DWORD)SendDlgItemMessage(hwndDlg, IDC_HRDPROFLSTBOX, LB_GETCURSEL, 0, 0);
806                         UpdateButtons(hwndDlg, pProfileData);
807                     }
808                     return TRUE;
809 
810                 case IDOK:
811                     OnOk(hwndDlg);
812 
813                 case IDCANCEL:
814                     EndDialog(hwndDlg, LOWORD(wParam));
815                     return TRUE;
816             }
817             break;
818     }
819 
820     return FALSE;
821 }
822