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
))
125 ResourceMessageBox(hApplet
,
127 MB_OK
| MB_ICONERROR
,
128 IDS_HWPROFILE_WARNING
,
129 IDS_HWPROFILE_ALREADY_IN_USE
);
133 EndDialog(hwndDlg
, IDOK
);
138 EndDialog(hwndDlg
, IDCANCEL
);
152 PPROFILEDATA pProfileData
)
154 PROFILENAMES ProfileNames
;
155 PPROFILE pProfile
, pNewProfiles
, pNewProfile
;
158 pProfile
= &pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
];
160 LoadStringW(hApplet
, IDS_HWPROFILE_PROFILE
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
162 wcscpy(ProfileNames
.szSourceName
, pProfile
->szFriendlyName
);
163 swprintf(ProfileNames
.szDestinationName
, L
"%s %lu", szBuffer
, pProfileData
->dwProfileCount
);
165 ProfileNames
.pProfileData
= pProfileData
;
167 if (DialogBoxParam(hApplet
,
168 MAKEINTRESOURCE(IDD_COPYPROFILE
),
171 (LPARAM
)&ProfileNames
) != IDOK
)
174 /* Apply new name only if it has been changed */
175 if (wcscmp(ProfileNames
.szSourceName
, ProfileNames
.szDestinationName
) == 0)
178 /* Allocate memory for the new profile */
179 pNewProfiles
= HeapReAlloc(GetProcessHeap(),
181 pProfileData
->pProfiles
,
182 (pProfileData
->dwProfileCount
+ 1) * sizeof(PROFILE
));
183 if (pNewProfiles
== NULL
)
185 DPRINT1("HeapReAlloc() failed!\n");
189 pProfileData
->dwProfileCount
++;
190 pProfileData
->pProfiles
= pNewProfiles
;
192 pNewProfile
= &pProfileData
->pProfiles
[pProfileData
->dwProfileCount
- 1];
194 CopyMemory(pNewProfile
, pProfile
, sizeof(PROFILE
));
196 wcscpy(pNewProfile
->szFriendlyName
, ProfileNames
.szDestinationName
);
198 pNewProfile
->dwProfileNumber
= ++pProfileData
->dwLastProfile
;
199 swprintf(pNewProfile
->szName
, L
"%04lu", pNewProfile
->dwProfileNumber
);
201 pNewProfile
->dwPreferenceOrder
= pNewProfile
->dwProfileNumber
;
203 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_ADDSTRING
, 0, (LPARAM
)pNewProfile
->szFriendlyName
);
205 UpdateButtons(hwndDlg
, pProfileData
);
212 RenameProfileDlgProc(
218 PPROFILENAMES pProfileNames
;
220 pProfileNames
= (PPROFILENAMES
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
225 SetWindowLongPtr(hwndDlg
, DWLP_USER
, lParam
);
226 pProfileNames
= (PPROFILENAMES
)lParam
;
228 /* Set the old name */
229 SetDlgItemText(hwndDlg
, IDC_RENPROFEDITFROM
, pProfileNames
->szSourceName
);
231 /* Set the new name */
232 SendDlgItemMessageW(hwndDlg
, IDC_RENPROFEDITTO
, EM_SETLIMITTEXT
, PROFILE_NAME_LENGTH
- 1, 0);
233 SetDlgItemText(hwndDlg
, IDC_RENPROFEDITTO
, pProfileNames
->szDestinationName
);
237 switch (LOWORD(wParam
))
240 GetDlgItemText(hwndDlg
,
242 pProfileNames
->szDestinationName
,
243 PROFILE_NAME_LENGTH
);
244 if (IsProfileNameInUse(pProfileNames
, TRUE
))
246 ResourceMessageBox(hApplet
,
248 MB_OK
| MB_ICONERROR
,
249 IDS_HWPROFILE_WARNING
,
250 IDS_HWPROFILE_ALREADY_IN_USE
);
254 EndDialog(hwndDlg
, IDOK
);
259 EndDialog(hwndDlg
, IDCANCEL
);
271 RenameHardwareProfile(
273 PPROFILEDATA pProfileData
)
275 PROFILENAMES ProfileNames
;
279 pProfile
= &pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
];
281 LoadStringW(hApplet
, IDS_HWPROFILE_PROFILE
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
283 wcscpy(ProfileNames
.szSourceName
, pProfile
->szFriendlyName
);
284 swprintf(ProfileNames
.szDestinationName
, L
"%s %lu", szBuffer
, pProfileData
->dwProfileCount
);
286 ProfileNames
.pProfileData
= pProfileData
;
288 if (DialogBoxParam(hApplet
,
289 MAKEINTRESOURCE(IDD_RENAMEPROFILE
),
291 RenameProfileDlgProc
,
292 (LPARAM
)&ProfileNames
) != IDOK
)
295 /* Apply new name only if it has been changed */
296 if (wcscmp(pProfile
->szFriendlyName
, ProfileNames
.szDestinationName
) == 0)
299 /* Replace the profile name in the profile list */
300 wcscpy(pProfile
->szFriendlyName
, ProfileNames
.szDestinationName
);
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
);
310 DeleteHardwareProfile(
312 PPROFILEDATA pProfileData
)
317 pProfile
= &pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
];
319 if (ResourceMessageBox(hApplet
,
321 MB_YESNO
| MB_ICONQUESTION
,
322 IDS_HWPROFILE_CONFIRM_DELETE_TITLE
,
323 IDS_HWPROFILE_CONFIRM_DELETE
,
324 pProfile
->szFriendlyName
) != IDYES
)
329 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_DELETESTRING
, pProfileData
->dwSelectedProfileIndex
, 0);
331 if (pProfileData
->dwSelectedProfileIndex
!= pProfileData
->dwProfileCount
- 1)
333 RtlMoveMemory(&pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
],
334 &pProfileData
->pProfiles
[pProfileData
->dwSelectedProfileIndex
+ 1],
335 (pProfileData
->dwProfileCount
- pProfileData
->dwSelectedProfileIndex
- 1) * sizeof(PROFILE
));
339 pProfileData
->dwSelectedProfileIndex
--;
342 pProfiles
= HeapReAlloc(GetProcessHeap(),
344 pProfileData
->pProfiles
,
345 (pProfileData
->dwProfileCount
- 1) * sizeof(PROFILE
));
346 if (pProfiles
== NULL
)
348 DPRINT1("HeapReAlloc() failed!\n");
352 pProfileData
->dwProfileCount
--;
353 pProfileData
->pProfiles
= pProfiles
;
355 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_SETCURSEL
, pProfileData
->dwSelectedProfileIndex
, 0);
357 UpdateButtons(hwndDlg
, pProfileData
);
365 PPROFILEDATA pProfileData
,
369 PPROFILE pSrcProfile
, pDstProfile
;
370 DWORD dwSrcIndex
, dwDstIndex
;
372 dwSrcIndex
= pProfileData
->dwSelectedProfileIndex
;
373 dwDstIndex
= bMoveUp
? (dwSrcIndex
- 1) : (dwSrcIndex
+ 1);
375 pSrcProfile
= &pProfileData
->pProfiles
[dwSrcIndex
];
376 pDstProfile
= &pProfileData
->pProfiles
[dwDstIndex
];
378 CopyMemory(&TempProfile
, pDstProfile
, sizeof(PROFILE
));
379 CopyMemory(pDstProfile
, pSrcProfile
, sizeof(PROFILE
));
380 CopyMemory(pSrcProfile
, &TempProfile
, sizeof(PROFILE
));
382 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_DELETESTRING
, dwSrcIndex
, 0);
383 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_INSERTSTRING
, dwDstIndex
, (LPARAM
)pDstProfile
->szFriendlyName
);
385 pProfileData
->dwSelectedProfileIndex
= dwDstIndex
;
386 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_SETCURSEL
, pProfileData
->dwSelectedProfileIndex
, 0);
388 UpdateButtons(hwndDlg
, pProfileData
);
395 HardwareProfilePropertiesDlgProc(
401 UNREFERENCED_PARAMETER(hwndDlg
);
402 UNREFERENCED_PARAMETER(lParam
);
403 UNREFERENCED_PARAMETER(wParam
);
416 PropSheetProc(HWND hwndDlg
, UINT uMsg
, LPARAM lParam
)
418 // NOTE: This callback is needed to set large icon correctly.
422 case PSCB_INITIALIZED
:
424 hIcon
= LoadIconW(hApplet
, MAKEINTRESOURCEW(IDI_HARDPROF
));
425 SendMessageW(hwndDlg
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
434 HardwareProfileProperties(
436 PPROFILEDATA pProfileData
)
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
;
449 hpsp
= CreatePropertySheetPage(&psp
);
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
;
465 psh
.pfnCallback
= PropSheetProc
;
473 GetUserWaitInterval(VOID
)
475 DWORD dwWaitInterval
= 30;
479 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
480 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
484 return dwWaitInterval
;
486 dwSize
= sizeof(DWORD
);
487 RegQueryValueExW(hKey
,
491 (LPBYTE
)&dwWaitInterval
,
496 return dwWaitInterval
;
502 SetUserWaitInterval(DWORD dwWaitInterval
)
506 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
507 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
517 (LPBYTE
)&dwWaitInterval
,
526 GetProfileCount(LPDWORD lpProfileCount
)
533 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
534 L
"System\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles",
538 if (lError
!= ERROR_SUCCESS
)
541 lError
= RegQueryInfoKeyW(hKey
, NULL
, NULL
, NULL
, lpProfileCount
,
542 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
546 if (lError
!= ERROR_SUCCESS
)
559 DWORD dwProfileNumber
,
566 lError
= RegOpenKeyExW(hKey
,
571 if (lError
!= ERROR_SUCCESS
)
574 dwSize
= PROFILE_NAME_LENGTH
* sizeof(WCHAR
);
575 lError
= RegQueryValueExW(hProfileKey
,
579 (LPBYTE
)pProfile
->szFriendlyName
,
581 if (lError
== ERROR_SUCCESS
)
583 DPRINT1("Profile: %S\n", pProfile
->szFriendlyName
);
586 dwSize
= sizeof(DWORD
);
587 lError
= RegQueryValueExW(hProfileKey
,
591 (LPBYTE
)&pProfile
->dwPreferenceOrder
,
593 if (lError
== ERROR_SUCCESS
)
595 DPRINT1("PreferenceOrder: %lu\n", pProfile
->dwPreferenceOrder
);
598 pProfile
->dwProfileNumber
= dwProfileNumber
;
600 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_ADDSTRING
, 0, (LPARAM
)pProfile
->szFriendlyName
);
602 RegCloseKey(hProfileKey
);
608 GetProfiles(HWND hwndDlg
)
610 PPROFILEDATA pProfileData
;
613 DWORD dwProfileNumber
;
618 pProfileData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(PROFILEDATA
));
619 if (pProfileData
== NULL
)
622 pProfileData
->dwLastProfile
= (DWORD
)-1;
623 pProfileData
->dwSelectedProfileIndex
= (DWORD
)-1;
625 if (!GetProfileCount(&pProfileData
->dwProfileCount
))
627 HeapFree(GetProcessHeap(), 0, pProfileData
);
631 pProfileData
->pProfiles
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
632 pProfileData
->dwProfileCount
* sizeof(PROFILE
));
633 if (pProfileData
->pProfiles
== NULL
)
635 HeapFree(GetProcessHeap(), 0, pProfileData
);
639 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pProfileData
);
641 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
642 L
"System\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles",
645 &hKey
) != ERROR_SUCCESS
)
648 for (dwIndex
= 0; dwIndex
< pProfileData
->dwProfileCount
; dwIndex
++)
651 lError
= RegEnumKeyExW(hKey
,
659 if (lError
!= ERROR_SUCCESS
)
662 dwProfileNumber
= wcstoul(szName
, NULL
, 10);
663 DPRINT("Profile name: %S\n", szName
);
664 DPRINT("Profile number: %lu\n", dwProfileNumber
);
666 if ((pProfileData
->dwLastProfile
== (DWORD
)-1) ||
667 (pProfileData
->dwLastProfile
< dwProfileNumber
))
668 pProfileData
->dwLastProfile
= dwProfileNumber
;
670 DPRINT("Last Profile number: %lu\n", pProfileData
->dwLastProfile
);
672 GetProfile(hwndDlg
, hKey
, szName
, dwProfileNumber
, &pProfileData
->pProfiles
[dwIndex
]);
683 OnInitHardProfDialog(HWND hwndDlg
)
685 DWORD dwWaitInterval
;
687 DPRINT("OnInitHardProfDialog()\n");
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
)));
696 if (!GetProfiles(hwndDlg
))
699 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFUPDWN
, UDM_SETRANGE
, (WPARAM
)0, (LPARAM
)MAKELONG((SHORT
)500, 0));
701 dwWaitInterval
= GetUserWaitInterval();
702 if (dwWaitInterval
== (DWORD
)-1)
704 CheckDlgButton(hwndDlg
, IDC_HRDPROFWAIT
, BST_CHECKED
);
705 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFUPDWN
, UDM_SETPOS
, 0, 30);
706 EnableWindow(GetDlgItem(hwndDlg
, IDC_HRDPROFEDIT
), FALSE
);
710 CheckDlgButton(hwndDlg
, IDC_HRDPROFSELECT
, BST_CHECKED
);
711 SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFUPDWN
, UDM_SETPOS
, 0, dwWaitInterval
);
722 DWORD dwWaitInterval
;
724 if (IsDlgButtonChecked(hwndDlg
, IDC_HRDPROFWAIT
) == BST_CHECKED
)
726 dwWaitInterval
= (DWORD
)-1;
730 dwWaitInterval
= LOWORD(SendDlgItemMessageW(hwndDlg
, IDC_HRDPROFUPDWN
, UDM_GETPOS
, 0, 0));
733 SetUserWaitInterval(dwWaitInterval
);
737 /* Property page dialog callback */
740 HardProfDlgProc(HWND hwndDlg
,
745 PPROFILEDATA pProfileData
;
747 UNREFERENCED_PARAMETER(lParam
);
748 UNREFERENCED_PARAMETER(wParam
);
749 UNREFERENCED_PARAMETER(hwndDlg
);
751 pProfileData
= (PPROFILEDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
756 return OnInitHardProfDialog(hwndDlg
);
759 if (pProfileData
!= NULL
)
761 if (pProfileData
->pProfiles
!= NULL
)
762 HeapFree(GetProcessHeap(), 0, pProfileData
->pProfiles
);
763 HeapFree(GetProcessHeap(), 0, pProfileData
);
768 switch (LOWORD(wParam
))
770 case IDC_HRDPROFPROP
:
771 HardwareProfileProperties(hwndDlg
, pProfileData
);
774 case IDC_HRDPROFCOPY
:
775 CopyHardwareProfile(hwndDlg
, pProfileData
);
778 case IDC_HRDPROFRENAME
:
779 RenameHardwareProfile(hwndDlg
, pProfileData
);
783 DeleteHardwareProfile(hwndDlg
, pProfileData
);
787 MoveHardwareProfile(hwndDlg
, pProfileData
, TRUE
);
791 MoveHardwareProfile(hwndDlg
, pProfileData
, FALSE
);
794 case IDC_HRDPROFWAIT
:
795 EnableWindow(GetDlgItem(hwndDlg
, IDC_HRDPROFEDIT
), FALSE
);
798 case IDC_HRDPROFSELECT
:
799 EnableWindow(GetDlgItem(hwndDlg
, IDC_HRDPROFEDIT
), TRUE
);
802 case IDC_HRDPROFLSTBOX
:
803 if (HIWORD(wParam
) == LBN_SELCHANGE
)
805 pProfileData
->dwSelectedProfileIndex
= (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_HRDPROFLSTBOX
, LB_GETCURSEL
, 0, 0);
806 UpdateButtons(hwndDlg
, pProfileData
);
814 EndDialog(hwndDlg
, LOWORD(wParam
));