sync with trunk head (34904)
[reactos.git] / reactos / base / applications / control / control.c
1 /*
2 * PROJECT: ReactOS System Control Panel
3 * FILE: base/applications/control/control.c
4 * PURPOSE: ReactOS System Control Panel
5 * PROGRAMMERS: Gero Kuehn (reactos.filter@gkware.com)
6 * Colin Finck (mail@colinfinck.de)
7 */
8
9 #include "control.h"
10
11 static const TCHAR szWindowClass[] = _T("DummyControlClass");
12
13 HANDLE hProcessHeap;
14 HINSTANCE hInst;
15
16 static INT
17 OpenShellFolder(LPTSTR lpFolderCLSID)
18 {
19 TCHAR szParameters[MAX_PATH];
20
21 /* Open a shell folder using "explorer.exe".
22 The passed CLSID's are all subfolders of the "Control Panel" shell folder. */
23 _tcscpy(szParameters, _T("/n,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"));
24 _tcscat(szParameters, lpFolderCLSID);
25
26 return (INT)(INT_PTR)ShellExecute(NULL, _T("open"), _T("explorer.exe"), szParameters, NULL, SW_SHOWDEFAULT) > 32;
27 }
28
29 static INT
30 RunControlPanel(LPTSTR lpCmd)
31 {
32 TCHAR szParameters[MAX_PATH];
33
34 _tcscpy(szParameters, _T("shell32.dll,Control_RunDLL "));
35 _tcscat(szParameters, lpCmd);
36
37 return RUNDLL(szParameters);
38 }
39
40 int WINAPI
41 _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
42 {
43 HKEY hKey;
44
45 hInst = hInstance;
46 hProcessHeap = GetProcessHeap();
47
48 /* Show the control panel window if no argument or "panel" was passed */
49 if(lpCmdLine[0] == 0 || !_tcsicmp(lpCmdLine, _T("panel")))
50 return OpenShellFolder(_T(""));
51
52 /* Check one of the built-in control panel handlers */
53 if (!_tcsicmp(lpCmdLine, _T("admintools"))) return OpenShellFolder(_T("\\::{D20EA4E1-3957-11d2-A40B-0C5020524153}"));
54 else if (!_tcsicmp(lpCmdLine, _T("color"))) return RunControlPanel(_T("desk.cpl")); /* TODO: Switch to the "Apperance" tab */
55 else if (!_tcsicmp(lpCmdLine, _T("date/time"))) return RunControlPanel(_T("timedate.cpl"));
56 else if (!_tcsicmp(lpCmdLine, _T("desktop"))) return RunControlPanel(_T("desk.cpl"));
57 else if (!_tcsicmp(lpCmdLine, _T("folders"))) return RUNDLL(_T("shell32.dll,Options_RunDLL"));
58 else if (!_tcsicmp(lpCmdLine, _T("fonts"))) return OpenShellFolder(_T("\\::{D20EA4E1-3957-11d2-A40B-0C5020524152}"));
59 else if (!_tcsicmp(lpCmdLine, _T("infrared"))) return RunControlPanel(_T("irprops.cpl"));
60 else if (!_tcsicmp(lpCmdLine, _T("international"))) return RunControlPanel(_T("intl.cpl"));
61 else if (!_tcsicmp(lpCmdLine, _T("keyboard"))) return RunControlPanel(_T("main.cpl @1"));
62 else if (!_tcsicmp(lpCmdLine, _T("mouse"))) return RunControlPanel(_T("main.cpl @0"));
63 else if (!_tcsicmp(lpCmdLine, _T("netconnections"))) return OpenShellFolder(_T("\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}"));
64 else if (!_tcsicmp(lpCmdLine, _T("netware"))) return RunControlPanel(_T("nwc.cpl"));
65 else if (!_tcsicmp(lpCmdLine, _T("ports"))) return RunControlPanel(_T("sysdm.cpl")); /* TODO: Switch to the "Computer Name" tab */
66 else if (!_tcsicmp(lpCmdLine, _T("printers"))) return OpenShellFolder(_T("\\::{2227A280-3AEA-1069-A2DE-08002B30309D}"));
67 else if (!_tcsicmp(lpCmdLine, _T("scannercamera"))) return OpenShellFolder(_T("\\::{E211B736-43FD-11D1-9EFB-0000F8757FCD}"));
68 else if (!_tcsicmp(lpCmdLine, _T("schedtasks"))) return OpenShellFolder(_T("\\::{D6277990-4C6A-11CF-8D87-00AA0060F5BF}"));
69 else if (!_tcsicmp(lpCmdLine, _T("telephony"))) return RunControlPanel(_T("telephon.cpl"));
70 else if (!_tcsicmp(lpCmdLine, _T("userpasswords"))) return RunControlPanel(_T("nusrmgr.cpl")); /* Graphical User Account Manager */
71 else if (!_tcsicmp(lpCmdLine, _T("userpasswords2"))) return RUNDLL(_T("netplwiz.dll,UsersRunDll")); /* Dialog based advanced User Account Manager */
72
73 /* It is none of them, so look for a handler in the registry */
74 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
75 {
76 DWORD dwIndex;
77
78 for(dwIndex = 0; ; ++dwIndex)
79 {
80 DWORD dwDataSize;
81 DWORD dwValueSize = MAX_VALUE_NAME;
82 TCHAR szValueName[MAX_VALUE_NAME];
83
84 /* Get the value name and data size */
85 if(RegEnumValue(hKey, dwIndex, szValueName, &dwValueSize, 0, NULL, NULL, &dwDataSize) != ERROR_SUCCESS)
86 break;
87
88 /* Check if the parameter is the value name */
89 if(!_tcsicmp(lpCmdLine, szValueName))
90 {
91 LPTSTR pszData;
92
93 /* Allocate memory for the data plus two more characters, so we can quote the file name if required */
94 pszData = (LPTSTR) HeapAlloc(hProcessHeap, 0, dwDataSize + 2 * sizeof(TCHAR));
95 ++pszData;
96
97 /* This value is the one we are looking for, so get the data. It is the path to a .cpl file */
98 if(RegQueryValueEx(hKey, szValueName, 0, NULL, (LPBYTE)pszData, &dwDataSize) == ERROR_SUCCESS)
99 {
100 INT nReturnValue;
101
102 /* Quote the file name if required */
103 if(*pszData != '\"')
104 {
105 *(--pszData) = '\"';
106 pszData[dwDataSize / sizeof(TCHAR)] = '\"';
107 pszData[(dwDataSize / sizeof(TCHAR)) + 1] = 0;
108 }
109
110 nReturnValue = RunControlPanel(pszData);
111 HeapFree(hProcessHeap, 0, pszData);
112 RegCloseKey(hKey);
113
114 return nReturnValue;
115 }
116
117 HeapFree(hProcessHeap, 0, pszData);
118 }
119 }
120
121 RegCloseKey(hKey);
122 }
123
124 /* It's none of the known parameters, so interpret the parameter as the file name of a control panel applet */
125 return RunControlPanel(lpCmdLine);
126 }