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>
14 #define PROFILE_NAME_LENGTH 80
16 typedef struct _PROFILE
18 WCHAR szFriendlyName
[PROFILE_NAME_LENGTH
];
20 DWORD dwProfileNumber
;
21 DWORD dwPreferenceOrder
;
24 typedef struct _PROFILEDATA
28 DWORD dwSelectedProfile
;
29 DWORD dwSelectedProfileIndex
;
31 } PROFILEDATA
, *PPROFILEDATA
;
33 typedef struct _PROFILENAMES
35 WCHAR szSourceName
[PROFILE_NAME_LENGTH
];
36 WCHAR szDestinationName
[PROFILE_NAME_LENGTH
];
37 PPROFILEDATA pProfileData
;
38 } PROFILENAMES
, *PPROFILENAMES
;
45 PPROFILEDATA pProfileData
)
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
);
52 if (pProfileData
->dwProfileCount
< 2)
54 EnableWindow(GetDlgItem(hwndDlg
, IDC_HRDPROFUP
), FALSE
);
55 EnableWindow(GetDlgItem(hwndDlg
, IDC_HRDPROFDWN
), FALSE
);
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
);
70 PPROFILENAMES pProfileNames
,
75 for (i
= 0; i
< pProfileNames
->pProfileData
->dwProfileCount
; i
++)
77 if (bIgnoreCurrent
== TRUE
&& i
== pProfileNames
->pProfileData
->dwSelectedProfileIndex
)
80 if (wcscmp(pProfileNames
->pProfileData
->pProfiles
[i
].szFriendlyName
, pProfileNames
->szDestinationName
) == 0)
97 PPROFILENAMES pProfileNames
;
99 pProfileNames
= (PPROFILENAMES
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
104 SetWindowLongPtr(hwndDlg
, DWLP_USER
, lParam
);
105 pProfileNames
= (PPROFILENAMES
)lParam
;
107 /* Set the old name */
108 SetDlgItemText(hwndDlg
, IDC_COPYPROFILEFROM
, pProfileNames
->szSourceName
);
110 /* Set the new name */
111 SendDlgItemMessageW(hwndDlg
, IDC_COPYPROFILETO
, EM_SETLIMITTEXT
, PROFILE_NAME_LENGTH
- 1, 0);
112 SetDlgItemText(hwndDlg
, IDC_COPYPROFILETO
, pProfileNames
->szDestinationName
);
116 switch (LOWORD(wParam
))
119 GetDlgItemText(hwndDlg
,
121 pProfileNames
->szDestinationName
,
122 PROFILE_NAME_LENGTH
);
123 if (IsProfileNameInUse(pProfileNames
, FALSE
))
124 ResourceMessageBox(hApplet
,
126 MB_OK
| MB_ICONERROR
,
127 IDS_HWPROFILE_WARNING
,
128 IDS_HWPROFILE_ALREADY_IN_USE
);
130 EndDialog(hwndDlg
, IDOK
);
134 EndDialog(hwndDlg
, IDCANCEL
);
148 PPROFILEDATA pProfileData
)
150 PROFILENAMES ProfileNames
;
151 PPROFILE pProfile
, pNewProfiles
, pNewProfile
;
154 pProfile
= &pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
];
156 LoadStringW(hApplet
, IDS_HWPROFILE_PROFILE
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
158 wcscpy(ProfileNames
.szSourceName
, pProfile
->szFriendlyName
);
159 swprintf(ProfileNames
.szDestinationName
, L
"%s %lu", szBuffer
, pProfileData
->dwProfileCount
);
161 ProfileNames
.pProfileData
= pProfileData
;
163 if (DialogBoxParam(hApplet
,
164 MAKEINTRESOURCE(IDD_COPYPROFILE
),
167 (LPARAM
)&ProfileNames
) != IDOK
)
170 /* Apply new name only if it has been changed */
171 if (wcscmp(ProfileNames
.szSourceName
, ProfileNames
.szDestinationName
) == 0)
174 /* Allocate memory for the new profile */
175 pNewProfiles
= HeapReAlloc(GetProcessHeap(),
177 pProfileData
->pProfiles
,
178 (pProfileData
->dwProfileCount
+ 1) * sizeof(PROFILE
));
179 if (pNewProfiles
== NULL
)
181 DPRINT1("HeapReAlloc() failed!\n");
185 pProfileData
->dwProfileCount
++;
186 pProfileData
->pProfiles
= pNewProfiles
;
188 pNewProfile
= &pProfileData
->pProfiles
[pProfileData
->dwProfileCount
- 1];
190 CopyMemory(pNewProfile
, pProfile
, sizeof(PROFILE
));
192 wcscpy(pNewProfile
->szFriendlyName
, ProfileNames
.szDestinationName
);
194 pNewProfile
->dwProfileNumber
= ++pProfileData
->dwLastProfile
;
195 swprintf(pNewProfile
->szName
, L
"%04lu", pNewProfile
->dwProfileNumber
);
197 pNewProfile
->dwPreferenceOrder
= pNewProfile
->dwProfileNumber
;
199 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_ADDSTRING
, 0, (LPARAM
)pNewProfile
->szFriendlyName
);
201 UpdateButtons(hwndDlg
, pProfileData
);
208 RenameProfileDlgProc(
214 PPROFILENAMES pProfileNames
;
216 pProfileNames
= (PPROFILENAMES
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
221 SetWindowLongPtr(hwndDlg
, DWLP_USER
, lParam
);
222 pProfileNames
= (PPROFILENAMES
)lParam
;
224 /* Set the old name */
225 SetDlgItemText(hwndDlg
, IDC_RENPROFEDITFROM
, pProfileNames
->szSourceName
);
227 /* Set the new name */
228 SendDlgItemMessageW(hwndDlg
, IDC_RENPROFEDITTO
, EM_SETLIMITTEXT
, PROFILE_NAME_LENGTH
- 1, 0);
229 SetDlgItemText(hwndDlg
, IDC_RENPROFEDITTO
, pProfileNames
->szDestinationName
);
233 switch (LOWORD(wParam
))
236 GetDlgItemText(hwndDlg
,
238 pProfileNames
->szDestinationName
,
239 PROFILE_NAME_LENGTH
);
240 if (IsProfileNameInUse(pProfileNames
, TRUE
))
241 ResourceMessageBox(hApplet
,
243 MB_OK
| MB_ICONERROR
,
244 IDS_HWPROFILE_WARNING
,
245 IDS_HWPROFILE_ALREADY_IN_USE
);
247 EndDialog(hwndDlg
, IDOK
);
251 EndDialog(hwndDlg
, IDCANCEL
);
263 RenameHardwareProfile(
265 PPROFILEDATA pProfileData
)
267 PROFILENAMES ProfileNames
;
271 pProfile
= &pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
];
273 LoadStringW(hApplet
, IDS_HWPROFILE_PROFILE
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
275 wcscpy(ProfileNames
.szSourceName
, pProfile
->szFriendlyName
);
276 swprintf(ProfileNames
.szDestinationName
, L
"%s %lu", szBuffer
, pProfileData
->dwProfileCount
);
278 ProfileNames
.pProfileData
= pProfileData
;
280 if (DialogBoxParam(hApplet
,
281 MAKEINTRESOURCE(IDD_RENAMEPROFILE
),
283 RenameProfileDlgProc
,
284 (LPARAM
)&ProfileNames
) != IDOK
)
287 /* Apply new name only if it has been changed */
288 if (wcscmp(pProfile
->szFriendlyName
, ProfileNames
.szDestinationName
) == 0)
291 /* Replace the profile name in the profile list */
292 wcscpy(pProfile
->szFriendlyName
, ProfileNames
.szDestinationName
);
294 /* Replace the profile name in the listbox */
295 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_DELETESTRING
, pProfileData
->dwSelectedProfileIndex
, 0);
296 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_INSERTSTRING
, pProfileData
->dwSelectedProfileIndex
, (LPARAM
)pProfile
->szFriendlyName
);
302 DeleteHardwareProfile(
304 PPROFILEDATA pProfileData
)
306 WCHAR szMessage
[256];
312 pProfile
= &pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
];
314 LoadStringW(hApplet
, IDS_HWPROFILE_CONFIRM_DELETE_TITLE
, szCaption
, sizeof(szCaption
) / sizeof(WCHAR
));
315 LoadStringW(hApplet
, IDS_HWPROFILE_CONFIRM_DELETE
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
316 swprintf(szMessage
, szBuffer
, pProfile
->szFriendlyName
);
321 MB_YESNO
| MB_ICONQUESTION
) != IDYES
)
324 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_DELETESTRING
, pProfileData
->dwSelectedProfileIndex
, 0);
326 if (pProfileData
->dwSelectedProfileIndex
!= pProfileData
->dwProfileCount
- 1)
328 RtlMoveMemory(&pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
],
329 &pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
+ 1],
330 (pProfileData
->dwProfileCount
- pProfileData
->dwSelectedProfileIndex
- 1) * sizeof(PROFILE
));
334 pProfileData
->dwSelectedProfileIndex
--;
337 pProfiles
= HeapReAlloc(GetProcessHeap(),
339 pProfileData
->pProfiles
,
340 (pProfileData
->dwProfileCount
- 1) * sizeof(PROFILE
));
341 if (pProfiles
== NULL
)
343 DPRINT1("HeapReAlloc() failed!\n");
347 pProfileData
->dwProfileCount
--;
348 pProfileData
->pProfiles
= pProfiles
;
350 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_SETCURSEL
, pProfileData
->dwSelectedProfileIndex
, 0);
352 UpdateButtons(hwndDlg
, pProfileData
);
360 PPROFILEDATA pProfileData
,
364 PPROFILE pSrcProfile
, pDstProfile
;
365 DWORD dwSrcIndex
, dwDstIndex
;
367 dwSrcIndex
= pProfileData
->dwSelectedProfileIndex
;
368 dwDstIndex
= bMoveUp
? (dwSrcIndex
- 1) : (dwSrcIndex
+ 1);
370 pSrcProfile
= &pProfileData
->pProfiles
[dwSrcIndex
];
371 pDstProfile
= &pProfileData
->pProfiles
[dwDstIndex
];
373 CopyMemory(&TempProfile
, pDstProfile
, sizeof(PROFILE
));
374 CopyMemory(pDstProfile
, pSrcProfile
, sizeof(PROFILE
));
375 CopyMemory(pSrcProfile
, &TempProfile
, sizeof(PROFILE
));
377 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_DELETESTRING
, dwSrcIndex
, 0);
378 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_INSERTSTRING
, dwDstIndex
, (LPARAM
)pDstProfile
->szFriendlyName
);
380 pProfileData
->dwSelectedProfileIndex
= dwDstIndex
;
381 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_SETCURSEL
, pProfileData
->dwSelectedProfileIndex
, 0);
383 UpdateButtons(hwndDlg
, pProfileData
);
390 HardwareProfilePropertiesDlgProc(
396 UNREFERENCED_PARAMETER(hwndDlg
);
397 UNREFERENCED_PARAMETER(lParam
);
398 UNREFERENCED_PARAMETER(wParam
);
411 PropSheetProc(HWND hwndDlg
, UINT uMsg
, LPARAM lParam
)
413 // NOTE: This callback is needed to set large icon correctly.
417 case PSCB_INITIALIZED
:
419 hIcon
= LoadIconW(hApplet
, MAKEINTRESOURCEW(IDI_HARDPROF
));
420 SendMessageW(hwndDlg
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
429 HardwareProfileProperties(
431 PPROFILEDATA pProfileData
)
437 ZeroMemory(&psp
, sizeof(psp
));
438 psp
.dwSize
= sizeof(psp
);
439 psp
.dwFlags
= PSP_DEFAULT
;
440 psp
.hInstance
= hApplet
;
441 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_HARDWAREPROFILE
);
442 psp
.pfnDlgProc
= HardwareProfilePropertiesDlgProc
;
444 hpsp
= CreatePropertySheetPage(&psp
);
450 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
451 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
452 psh
.dwFlags
= PSH_PROPTITLE
| PSH_USEICONID
| PSH_USECALLBACK
;
453 psh
.hwndParent
= hwndDlg
;
454 psh
.hInstance
= hApplet
;
455 psh
.pszIcon
= MAKEINTRESOURCEW(IDI_HARDPROF
);
456 psh
.pszCaption
= pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
].szFriendlyName
;
460 psh
.pfnCallback
= PropSheetProc
;
468 GetUserWaitInterval(VOID
)
470 DWORD dwWaitInterval
= 30;
474 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
475 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
479 return dwWaitInterval
;
481 dwSize
= sizeof(DWORD
);
482 RegQueryValueExW(hKey
,
486 (LPBYTE
)&dwWaitInterval
,
491 return dwWaitInterval
;
497 SetUserWaitInterval(DWORD dwWaitInterval
)
501 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
502 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
512 (LPBYTE
)&dwWaitInterval
,
521 GetProfileCount(LPDWORD lpProfileCount
)
528 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
529 L
"System\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles",
533 if (lError
!= ERROR_SUCCESS
)
536 lError
= RegQueryInfoKeyW(hKey
, NULL
, NULL
, NULL
, lpProfileCount
,
537 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
541 if (lError
!= ERROR_SUCCESS
)
554 DWORD dwProfileNumber
,
561 lError
= RegOpenKeyExW(hKey
,
566 if (lError
!= ERROR_SUCCESS
)
569 dwSize
= PROFILE_NAME_LENGTH
* sizeof(WCHAR
);
570 lError
= RegQueryValueExW(hProfileKey
,
574 (LPBYTE
)pProfile
->szFriendlyName
,
576 if (lError
== ERROR_SUCCESS
)
578 DPRINT1("Profile: %S\n", pProfile
->szFriendlyName
);
581 dwSize
= sizeof(DWORD
);
582 lError
= RegQueryValueExW(hProfileKey
,
586 (LPBYTE
)&pProfile
->dwPreferenceOrder
,
588 if (lError
== ERROR_SUCCESS
)
590 DPRINT1("PreferenceOrder: %lu\n", pProfile
->dwPreferenceOrder
);
593 pProfile
->dwProfileNumber
= dwProfileNumber
;
595 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_ADDSTRING
, 0, (LPARAM
)pProfile
->szFriendlyName
);
597 RegCloseKey(hProfileKey
);
603 GetProfiles(HWND hwndDlg
)
605 PPROFILEDATA pProfileData
;
608 DWORD dwProfileNumber
;
613 pProfileData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(PROFILEDATA
));
614 if (pProfileData
== NULL
)
617 pProfileData
->dwLastProfile
= (DWORD
)-1;
618 pProfileData
->dwSelectedProfileIndex
= (DWORD
)-1;
620 if (!GetProfileCount(&pProfileData
->dwProfileCount
))
622 HeapFree(GetProcessHeap(), 0, pProfileData
);
626 pProfileData
->pProfiles
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
627 pProfileData
->dwProfileCount
* sizeof(PROFILE
));
628 if (pProfileData
->pProfiles
== NULL
)
630 HeapFree(GetProcessHeap(), 0, pProfileData
);
634 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pProfileData
);
636 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
637 L
"System\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles",
640 &hKey
) != ERROR_SUCCESS
)
643 for (dwIndex
= 0; dwIndex
< pProfileData
->dwProfileCount
; dwIndex
++)
646 lError
= RegEnumKeyExW(hKey
,
654 if (lError
!= ERROR_SUCCESS
)
657 dwProfileNumber
= wcstoul(szName
, NULL
, 10);
658 DPRINT("Profile name: %S\n", szName
);
659 DPRINT("Profile number: %lu\n", dwProfileNumber
);
661 if ((pProfileData
->dwLastProfile
== (DWORD
)-1) ||
662 (pProfileData
->dwLastProfile
< dwProfileNumber
))
663 pProfileData
->dwLastProfile
= dwProfileNumber
;
665 DPRINT("Last Profile number: %lu\n", pProfileData
->dwLastProfile
);
667 GetProfile(hwndDlg
, hKey
, szName
, dwProfileNumber
, &pProfileData
->pProfiles
[dwIndex
]);
678 OnInitHardProfDialog(HWND hwndDlg
)
680 DWORD dwWaitInterval
;
682 DPRINT("OnInitHardProfDialog()\n");
684 SendMessage(GetDlgItem(hwndDlg
, IDC_HRDPROFUP
),
685 BM_SETIMAGE
,(WPARAM
)IMAGE_ICON
,
686 (LPARAM
)(HANDLE
)LoadIcon(hApplet
, MAKEINTRESOURCE(IDI_UP
)));
687 SendMessage(GetDlgItem(hwndDlg
, IDC_HRDPROFDWN
),
688 BM_SETIMAGE
,(WPARAM
)IMAGE_ICON
,
689 (LPARAM
)(HANDLE
)LoadIcon(hApplet
, MAKEINTRESOURCE(IDI_DOWN
)));
691 if (!GetProfiles(hwndDlg
))
694 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFUPDWN
, UDM_SETRANGE
, (WPARAM
)0, (LPARAM
)MAKELONG((SHORT
)500, 0));
696 dwWaitInterval
= GetUserWaitInterval();
697 if (dwWaitInterval
== (DWORD
)-1)
699 CheckDlgButton(hwndDlg
, IDC_HRDPROFWAIT
, BST_CHECKED
);
700 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFUPDWN
, UDM_SETPOS
, 0, 30);
701 EnableWindow(GetDlgItem(hwndDlg
, IDC_HRDPROFEDIT
), FALSE
);
705 CheckDlgButton(hwndDlg
, IDC_HRDPROFSELECT
, BST_CHECKED
);
706 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFUPDWN
, UDM_SETPOS
, 0, dwWaitInterval
);
717 DWORD dwWaitInterval
;
719 if (IsDlgButtonChecked(hwndDlg
, IDC_HRDPROFWAIT
) == BST_CHECKED
)
721 dwWaitInterval
= (DWORD
)-1;
725 dwWaitInterval
= LOWORD(SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFUPDWN
, UDM_GETPOS
, 0, 0));
728 SetUserWaitInterval(dwWaitInterval
);
732 /* Property page dialog callback */
735 HardProfDlgProc(HWND hwndDlg
,
740 PPROFILEDATA pProfileData
;
742 UNREFERENCED_PARAMETER(lParam
);
743 UNREFERENCED_PARAMETER(wParam
);
744 UNREFERENCED_PARAMETER(hwndDlg
);
746 pProfileData
= (PPROFILEDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
751 return OnInitHardProfDialog(hwndDlg
);
754 if (pProfileData
!= NULL
)
756 if (pProfileData
->pProfiles
!= NULL
)
757 HeapFree(GetProcessHeap(), 0, pProfileData
->pProfiles
);
758 HeapFree(GetProcessHeap(), 0, pProfileData
);
763 switch (LOWORD(wParam
))
765 case IDC_HRDPROFPROP
:
766 HardwareProfileProperties(hwndDlg
, pProfileData
);
769 case IDC_HRDPROFCOPY
:
770 CopyHardwareProfile(hwndDlg
, pProfileData
);
773 case IDC_HRDPROFRENAME
:
774 RenameHardwareProfile(hwndDlg
, pProfileData
);
778 DeleteHardwareProfile(hwndDlg
, pProfileData
);
782 MoveHardwareProfile(hwndDlg
, pProfileData
, TRUE
);
786 MoveHardwareProfile(hwndDlg
, pProfileData
, FALSE
);
789 case IDC_HRDPROFWAIT
:
790 EnableWindow(GetDlgItem(hwndDlg
, IDC_HRDPROFEDIT
), FALSE
);
793 case IDC_HRDPROFSELECT
:
794 EnableWindow(GetDlgItem(hwndDlg
, IDC_HRDPROFEDIT
), TRUE
);
797 case IDC_HRDPROFLSTBOX
:
798 if (HIWORD(wParam
) == LBN_SELCHANGE
)
800 pProfileData
->dwSelectedProfileIndex
= (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_GETCURSEL
, 0, 0);
801 UpdateButtons(hwndDlg
, pProfileData
);
809 EndDialog(hwndDlg
, LOWORD(wParam
));