ReactOS  0.4.12-dev-102-g4b7f1e0
control.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS System Control Panel
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: ReactOS System Control Panel
5  * COPYRIGHT: Copyright 2004 Gero Kuehn (reactos.filter@gkware.com)
6  * Copyright 2008 Colin Finck (colin@reactos.org)
7  * Copyright 2014 Hermès Bélusca-Maïto (hermes.belusca-maito@reactos.org)
8  */
9 
10 #include <stdio.h>
11 
12 #define WIN32_NO_STATUS
13 
14 #include <windef.h>
15 #include <winbase.h>
16 #include <winuser.h>
17 #include <winreg.h>
18 #include <shellapi.h>
19 #include <strsafe.h>
20 
21 #include "resource.h"
22 
23 #define MAX_VALUE_NAME 16383
24 
25 /*
26  * Macro for calling "rundll32.exe"
27  * According to MSDN, ShellExecute returns a value greater than 32
28  * if the operation was successful.
29  */
30 #define RUNDLL(param) \
31  ((INT_PTR)ShellExecuteW(NULL, L"open", L"rundll32.exe", (param), NULL, SW_SHOWDEFAULT) > 32)
32 
33 VOID
34 WINAPI
36 
37 static INT
38 OpenShellFolder(LPWSTR lpFolderCLSID)
39 {
40  WCHAR szParameters[MAX_PATH];
41 
42  /*
43  * Open a shell folder using "explorer.exe". The passed CLSIDs
44  * are all subfolders of the "Control Panel" shell folder.
45  */
46  StringCbCopy(szParameters, sizeof(szParameters), L"/n,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}");
47  StringCbCat(szParameters,sizeof(szParameters), lpFolderCLSID);
48 
49  return (INT_PTR)ShellExecuteW(NULL,
50  L"open",
51  L"explorer.exe",
52  szParameters,
53  NULL,
54  SW_SHOWDEFAULT) > 32;
55 }
56 
57 static INT
59 {
60  /*
61  * Old method:
62  *
63  WCHAR szParameters[MAX_PATH];
64  wcscpy(szParameters, L"shell32.dll,Control_RunDLL ");
65  wcscat(szParameters, lpCmd);
66  return RUNDLL(szParameters);
67  */
68 
69  /* New method: */
71  return 1;
72 }
73 
74 INT
75 WINAPI
77  HINSTANCE hPrevInstance,
78  LPWSTR lpCmdLine,
79  INT nCmdShow)
80 {
81  HKEY hKey;
82 
83  /* Show the control panel window if no argument or "panel" was passed */
84  if (*lpCmdLine == 0 || !_wcsicmp(lpCmdLine, L"panel"))
85  return OpenShellFolder(L"");
86 
87  /* Check one of the built-in control panel handlers */
88  if (!_wcsicmp(lpCmdLine, L"admintools")) return OpenShellFolder(L"\\::{D20EA4E1-3957-11d2-A40B-0C5020524153}");
89  else if (!_wcsicmp(lpCmdLine, L"color")) return RunControlPanel(L"desk.cpl"); /* TODO: Switch to the "Apperance" tab */
90  else if (!_wcsicmp(lpCmdLine, L"date/time")) return RunControlPanel(L"timedate.cpl");
91  else if (!_wcsicmp(lpCmdLine, L"desktop")) return RunControlPanel(L"desk.cpl");
92  else if (!_wcsicmp(lpCmdLine, L"folders")) return RUNDLL(L"shell32.dll,Options_RunDLL");
93  else if (!_wcsicmp(lpCmdLine, L"fonts")) return OpenShellFolder(L"\\::{D20EA4E1-3957-11d2-A40B-0C5020524152}");
94  else if (!_wcsicmp(lpCmdLine, L"infrared")) return RunControlPanel(L"irprops.cpl");
95  else if (!_wcsicmp(lpCmdLine, L"international")) return RunControlPanel(L"intl.cpl");
96  else if (!_wcsicmp(lpCmdLine, L"keyboard")) return RunControlPanel(L"main.cpl @1");
97  else if (!_wcsicmp(lpCmdLine, L"mouse")) return RunControlPanel(L"main.cpl @0");
98  else if (!_wcsicmp(lpCmdLine, L"netconnections")) return OpenShellFolder(L"\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}");
99  else if (!_wcsicmp(lpCmdLine, L"netware")) return RunControlPanel(L"nwc.cpl");
100  else if (!_wcsicmp(lpCmdLine, L"ports")) return RunControlPanel(L"sysdm.cpl"); /* TODO: Switch to the "Computer Name" tab */
101  else if (!_wcsicmp(lpCmdLine, L"printers")) return OpenShellFolder(L"\\::{2227A280-3AEA-1069-A2DE-08002B30309D}");
102  else if (!_wcsicmp(lpCmdLine, L"scannercamera")) return OpenShellFolder(L"\\::{E211B736-43FD-11D1-9EFB-0000F8757FCD}");
103  else if (!_wcsicmp(lpCmdLine, L"schedtasks")) return OpenShellFolder(L"\\::{D6277990-4C6A-11CF-8D87-00AA0060F5BF}");
104  else if (!_wcsicmp(lpCmdLine, L"telephony")) return RunControlPanel(L"telephon.cpl");
105  else if (!_wcsicmp(lpCmdLine, L"userpasswords")) return RunControlPanel(L"nusrmgr.cpl"); /* Graphical User Account Manager */
106  else if (!_wcsicmp(lpCmdLine, L"userpasswords2")) return RUNDLL(L"netplwiz.dll,UsersRunDll"); /* Dialog based advanced User Account Manager */
107 
108  /* It is none of them, so look for a handler in the registry */
110  L"Software\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls",
111  0,
113  &hKey) == ERROR_SUCCESS)
114  {
115  DWORD dwIndex;
116 
117  for (dwIndex = 0; ; ++dwIndex)
118  {
119  DWORD dwDataSize;
120  DWORD dwValueSize = MAX_VALUE_NAME;
121  WCHAR szValueName[MAX_VALUE_NAME];
122 
123  /* Get the value name and data size */
124  if (RegEnumValueW(hKey,
125  dwIndex,
126  szValueName,
127  &dwValueSize,
128  0,
129  NULL,
130  NULL,
131  &dwDataSize) != ERROR_SUCCESS)
132  {
133  break;
134  }
135 
136  /* Check if the parameter is the value name */
137  if (!_wcsicmp(lpCmdLine, szValueName))
138  {
139  /*
140  * Allocate memory for the data plus two more characters,
141  * so we can quote the file name if required.
142  */
143  LPWSTR pszData;
144  pszData = HeapAlloc(GetProcessHeap(),
145  0,
146  dwDataSize + 2 * sizeof(WCHAR));
147  ++pszData;
148 
149  /*
150  * This value is the one we are looking for, so get the data.
151  * It is the path to a .cpl file.
152  */
153  if (RegQueryValueExW(hKey,
154  szValueName,
155  0,
156  NULL,
157  (LPBYTE)pszData,
158  &dwDataSize) == ERROR_SUCCESS)
159  {
160  INT nReturnValue;
161 
162  /* Quote the file name if required */
163  if (*pszData != L'\"')
164  {
165  *(--pszData) = L'\"';
166  pszData[dwDataSize / sizeof(WCHAR)] = L'\"';
167  pszData[(dwDataSize / sizeof(WCHAR)) + 1] = 0;
168  }
169 
170  nReturnValue = RunControlPanel(pszData);
171  HeapFree(GetProcessHeap(), 0, pszData);
172  RegCloseKey(hKey);
173 
174  return nReturnValue;
175  }
176 
177  HeapFree(GetProcessHeap(), 0, pszData);
178  }
179  }
180 
181  RegCloseKey(hKey);
182  }
183 
184  /*
185  * It's none of the known parameters, so interpret the parameter
186  * as the file name of a control panel applet.
187  */
188  return RunControlPanel(lpCmdLine);
189 }
#define SW_SHOWDEFAULT
Definition: winuser.h:774
static INT OpenShellFolder(LPWSTR lpFolderCLSID)
Definition: control.c:38
#define ERROR_SUCCESS
Definition: deptool.c:10
Definition: ftp_var.h:139
__wchar_t WCHAR
Definition: xmlstorage.h:180
HWND hWnd
Definition: settings.c:17
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
int32_t INT_PTR
Definition: typedefs.h:62
#define WCHAR
Definition: msvc.h:43
int32_t INT
Definition: typedefs.h:56
HINSTANCE hInstance
Definition: charmap.c:20
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
VOID WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow)
Definition: control.c:873
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2867
smooth NULL
Definition: ftsmooth.c:416
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:622
#define MAX_VALUE_NAME
Definition: control.c:23
#define SW_SHOW
Definition: winuser.h:769
#define StringCbCat
Definition: strsafe.h:334
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, INT nCmdShow)
Definition: control.c:76
#define StringCbCopy
Definition: strsafe.h:155
static const WCHAR L[]
Definition: oid.c:1087
static INT RunControlPanel(LPCWSTR lpCmd)
Definition: control.c:58
#define WINAPI
Definition: msvc.h:20
HINSTANCE hInst
Definition: dxdiag.c:13
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define RUNDLL(param)
Definition: control.c:30
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2236
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define HeapFree(x, y, z)
Definition: compat.h:394
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12