[NTOS:IO]
[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 <stdio.h>
10
11 #define WIN32_NO_STATUS
12
13 #include <windef.h>
14 #include <winbase.h>
15 #include <winuser.h>
16 #include <winreg.h>
17 #include <shellapi.h>
18
19 #include "resource.h"
20
21 #define MAX_VALUE_NAME 16383
22
23 /*
24 * Macro for calling "rundll32.exe"
25 * According to MSDN, ShellExecute returns a value greater than 32
26 * if the operation was successful.
27 */
28 #define RUNDLL(param) \
29 ((INT_PTR)ShellExecuteW(NULL, L"open", L"rundll32.exe", (param), NULL, SW_SHOWDEFAULT) > 32)
30
31 VOID
32 WINAPI
33 Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow);
34
35 static INT
36 OpenShellFolder(LPWSTR lpFolderCLSID)
37 {
38 WCHAR szParameters[MAX_PATH];
39
40 /*
41 * Open a shell folder using "explorer.exe". The passed CLSIDs
42 * are all subfolders of the "Control Panel" shell folder.
43 */
44 wcscpy(szParameters, L"/n,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}");
45 wcscat(szParameters, lpFolderCLSID);
46
47 return (INT_PTR)ShellExecuteW(NULL,
48 L"open",
49 L"explorer.exe",
50 szParameters,
51 NULL,
52 SW_SHOWDEFAULT) > 32;
53 }
54
55 static INT
56 RunControlPanel(LPCWSTR lpCmd)
57 {
58 /*
59 * Old method:
60 *
61 WCHAR szParameters[MAX_PATH];
62 wcscpy(szParameters, L"shell32.dll,Control_RunDLL ");
63 wcscat(szParameters, lpCmd);
64 return RUNDLL(szParameters);
65 */
66
67 /* New method: */
68 Control_RunDLLW(GetDesktopWindow(), 0, lpCmd, SW_SHOW);
69 return 1;
70 }
71
72 INT
73 WINAPI
74 wWinMain(HINSTANCE hInstance,
75 HINSTANCE hPrevInstance,
76 LPWSTR lpCmdLine,
77 INT nCmdShow)
78 {
79 HKEY hKey;
80
81 /* Show the control panel window if no argument or "panel" was passed */
82 if (*lpCmdLine == 0 || !_wcsicmp(lpCmdLine, L"panel"))
83 return OpenShellFolder(L"");
84
85 /* Check one of the built-in control panel handlers */
86 if (!_wcsicmp(lpCmdLine, L"admintools")) return OpenShellFolder(L"\\::{D20EA4E1-3957-11d2-A40B-0C5020524153}");
87 else if (!_wcsicmp(lpCmdLine, L"color")) return RunControlPanel(L"desk.cpl"); /* TODO: Switch to the "Apperance" tab */
88 else if (!_wcsicmp(lpCmdLine, L"date/time")) return RunControlPanel(L"timedate.cpl");
89 else if (!_wcsicmp(lpCmdLine, L"desktop")) return RunControlPanel(L"desk.cpl");
90 else if (!_wcsicmp(lpCmdLine, L"folders")) return RUNDLL(L"shell32.dll,Options_RunDLL");
91 else if (!_wcsicmp(lpCmdLine, L"fonts")) return OpenShellFolder(L"\\::{D20EA4E1-3957-11d2-A40B-0C5020524152}");
92 else if (!_wcsicmp(lpCmdLine, L"infrared")) return RunControlPanel(L"irprops.cpl");
93 else if (!_wcsicmp(lpCmdLine, L"international")) return RunControlPanel(L"intl.cpl");
94 else if (!_wcsicmp(lpCmdLine, L"keyboard")) return RunControlPanel(L"main.cpl @1");
95 else if (!_wcsicmp(lpCmdLine, L"mouse")) return RunControlPanel(L"main.cpl @0");
96 else if (!_wcsicmp(lpCmdLine, L"netconnections")) return OpenShellFolder(L"\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}");
97 else if (!_wcsicmp(lpCmdLine, L"netware")) return RunControlPanel(L"nwc.cpl");
98 else if (!_wcsicmp(lpCmdLine, L"ports")) return RunControlPanel(L"sysdm.cpl"); /* TODO: Switch to the "Computer Name" tab */
99 else if (!_wcsicmp(lpCmdLine, L"printers")) return OpenShellFolder(L"\\::{2227A280-3AEA-1069-A2DE-08002B30309D}");
100 else if (!_wcsicmp(lpCmdLine, L"scannercamera")) return OpenShellFolder(L"\\::{E211B736-43FD-11D1-9EFB-0000F8757FCD}");
101 else if (!_wcsicmp(lpCmdLine, L"schedtasks")) return OpenShellFolder(L"\\::{D6277990-4C6A-11CF-8D87-00AA0060F5BF}");
102 else if (!_wcsicmp(lpCmdLine, L"telephony")) return RunControlPanel(L"telephon.cpl");
103 else if (!_wcsicmp(lpCmdLine, L"userpasswords")) return RunControlPanel(L"nusrmgr.cpl"); /* Graphical User Account Manager */
104 else if (!_wcsicmp(lpCmdLine, L"userpasswords2")) return RUNDLL(L"netplwiz.dll,UsersRunDll"); /* Dialog based advanced User Account Manager */
105
106 /* It is none of them, so look for a handler in the registry */
107 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
108 L"Software\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls",
109 0,
110 KEY_QUERY_VALUE,
111 &hKey) == ERROR_SUCCESS)
112 {
113 DWORD dwIndex;
114
115 for (dwIndex = 0; ; ++dwIndex)
116 {
117 DWORD dwDataSize;
118 DWORD dwValueSize = MAX_VALUE_NAME;
119 WCHAR szValueName[MAX_VALUE_NAME];
120
121 /* Get the value name and data size */
122 if (RegEnumValueW(hKey,
123 dwIndex,
124 szValueName,
125 &dwValueSize,
126 0,
127 NULL,
128 NULL,
129 &dwDataSize) != ERROR_SUCCESS)
130 {
131 break;
132 }
133
134 /* Check if the parameter is the value name */
135 if (!_wcsicmp(lpCmdLine, szValueName))
136 {
137 /*
138 * Allocate memory for the data plus two more characters,
139 * so we can quote the file name if required.
140 */
141 LPWSTR pszData;
142 pszData = HeapAlloc(GetProcessHeap(),
143 0,
144 dwDataSize + 2 * sizeof(WCHAR));
145 ++pszData;
146
147 /*
148 * This value is the one we are looking for, so get the data.
149 * It is the path to a .cpl file.
150 */
151 if (RegQueryValueExW(hKey,
152 szValueName,
153 0,
154 NULL,
155 (LPBYTE)pszData,
156 &dwDataSize) == ERROR_SUCCESS)
157 {
158 INT nReturnValue;
159
160 /* Quote the file name if required */
161 if (*pszData != L'\"')
162 {
163 *(--pszData) = L'\"';
164 pszData[dwDataSize / sizeof(WCHAR)] = L'\"';
165 pszData[(dwDataSize / sizeof(WCHAR)) + 1] = 0;
166 }
167
168 nReturnValue = RunControlPanel(pszData);
169 HeapFree(GetProcessHeap(), 0, pszData);
170 RegCloseKey(hKey);
171
172 return nReturnValue;
173 }
174
175 HeapFree(GetProcessHeap(), 0, pszData);
176 }
177 }
178
179 RegCloseKey(hKey);
180 }
181
182 /*
183 * It's none of the known parameters, so interpret the parameter
184 * as the file name of a control panel applet.
185 */
186 return RunControlPanel(lpCmdLine);
187 }