ReactOS 0.4.17-dev-966-gf06eace
control.c File Reference
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
#include <winuser.h>
#include <winreg.h>
#include <shellapi.h>
#include <strsafe.h>
#include <objbase.h>
#include <shobjidl.h>
#include <shlguid.h>
#include <shlwapi.h>
#include "resource.h"
Include dependency graph for control.c:

Go to the source code of this file.

Macros

#define WIN32_NO_STATUS
 
#define COBJMACROS
 
#define MAX_VALUE_NAME   16383
 
#define RUNDLL(param)    ((INT_PTR)ShellExecuteW(NULL, L"open", L"rundll32.exe", (param), NULL, SW_SHOWDEFAULT) > 32)
 
#define ShellExec(file, params)    ((INT_PTR)ShellExecuteW(NULL, NULL, (file), (params), NULL, SW_SHOWDEFAULT) > 32)
 

Functions

VOID WINAPI Control_RunDLLW (HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow)
 
static BOOL IsSwitch (LPCWSTR Switch, LPCWSTR Arg)
 
static HRESULT OpenControlPanelItem (LPCWSTR Name, LPCWSTR Page)
 
static INT OpenShellFolder (LPWSTR lpFolderCLSID)
 
static INT RunControlPanel (LPCWSTR lpCmd)
 
static BOOL OpenUserAccounts (VOID)
 
INT WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, INT nCmdShow)
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 13 of file control.c.

◆ MAX_VALUE_NAME

#define MAX_VALUE_NAME   16383

Definition at line 29 of file control.c.

◆ RUNDLL

#define RUNDLL (   param)     ((INT_PTR)ShellExecuteW(NULL, L"open", L"rundll32.exe", (param), NULL, SW_SHOWDEFAULT) > 32)

Definition at line 36 of file control.c.

◆ ShellExec

#define ShellExec (   file,
  params 
)     ((INT_PTR)ShellExecuteW(NULL, NULL, (file), (params), NULL, SW_SHOWDEFAULT) > 32)

Definition at line 38 of file control.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 12 of file control.c.

Function Documentation

◆ Control_RunDLLW()

VOID WINAPI Control_RunDLLW ( HWND  hWnd,
HINSTANCE  hInst,
LPCWSTR  cmd,
DWORD  nCmdShow 
)

Definition at line 1177 of file control.c.

1178{
1179 CPanel panel;
1180
1181 TRACE("(%p, %p, %s, 0x%08x)\n",
1182 hWnd, hInst, debugstr_w(cmd), nCmdShow);
1183
1184#ifndef __REACTOS__
1185 memset(&panel, 0, sizeof(panel));
1186 list_init( &panel.applets );
1187#endif
1188
1189 if (!cmd || !*cmd) {
1190 Control_DoWindow(&panel, hWnd, hInst);
1191 } else {
1192 Control_DoLaunch(&panel, hWnd, cmd);
1193 }
1194}
HWND hWnd
Definition: settings.c:17
static void list_init(struct list_entry *head)
Definition: list.h:51
static void Control_DoWindow(CPanel *panel, HWND hWnd, HINSTANCE hInst)
Definition: control.c:703
static void Control_DoLaunch(CPanel *panel, HWND hWnd, LPCWSTR wszCmd)
Definition: control.c:867
HINSTANCE hInst
Definition: dxdiag.c:13
#define debugstr_w
Definition: kernel32.h:32
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
Definition: cpanel.h:56
struct list applets
Definition: cpanel.h:57
Definition: ftp_var.h:139

Referenced by Control_RunDLLA().

◆ IsSwitch()

static BOOL IsSwitch ( LPCWSTR  Switch,
LPCWSTR  Arg 
)
static

Definition at line 46 of file control.c.

47{
48 if (*Arg == '/' || *Arg == '-')
49 {
50 return !lstrcmpiW(Arg+1, Switch);
51 }
52 return FALSE;
53}
#define FALSE
Definition: types.h:117
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171

Referenced by wWinMain().

◆ OpenControlPanelItem()

static HRESULT OpenControlPanelItem ( LPCWSTR  Name,
LPCWSTR  Page 
)
static

Definition at line 56 of file control.c.

57{
59 if (SUCCEEDED(hr))
60 {
61 IOpenControlPanel *pOCP;
62 hr = CoCreateInstance(&CLSID_OpenControlPanel, NULL, CLSCTX_INPROC_SERVER,
63 &IID_IOpenControlPanel, (void**)&pOCP);
64 if (SUCCEEDED(hr))
65 {
66 hr = IOpenControlPanel_Open(pOCP, Name, Page, NULL);
67 IOpenControlPanel_Release(pOCP);
68 }
70 }
71 return hr;
72}
HRESULT hr
Definition: delayimp.cpp:582
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
#define SUCCEEDED(hr)
Definition: intsafe.h:50
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1305

Referenced by wWinMain().

◆ OpenShellFolder()

static INT OpenShellFolder ( LPWSTR  lpFolderCLSID)
static

Definition at line 75 of file control.c.

76{
77 WCHAR szParameters[MAX_PATH];
78
79 /*
80 * Open a shell folder using "explorer.exe". If Explorer shell is not
81 * available, use ReactOS's alternative file browser instead.
82 * The passed CLSIDs are all subfolders of the "Control Panel" shell folder.
83 */
84 StringCbCopyW(szParameters, sizeof(szParameters), L"/n,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}");
85 StringCbCatW(szParameters, sizeof(szParameters), lpFolderCLSID);
86
88 L"open",
89 GetShellWindow() ? L"explorer.exe" : L"filebrowser.exe",
90 szParameters,
91 NULL,
92 SW_SHOWDEFAULT) > 32;
93}
#define MAX_PATH
Definition: compat.h:34
#define L(x)
Definition: resources.c:13
short WCHAR
Definition: pedump.c:58
#define SW_SHOWDEFAULT
Definition: winuser.h:791
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2787
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342
int32_t INT_PTR
Definition: typedefs.h:64
HWND WINAPI GetShellWindow(void)
Definition: input.c:974

Referenced by wWinMain().

◆ OpenUserAccounts()

static BOOL OpenUserAccounts ( VOID  )
static

Definition at line 107 of file control.c.

108{
110
112 PathAppendW(szPath, L"lusrmgr.msc");
114 return TRUE;
115
116 /*
117 * TODO: OpenControlPanelItem(L"Microsoft.UserAccounts", NULL) on Vista+ (needs usercpl.dll)
118 * See: https://learn.microsoft.com/en-us/windows/win32/shell/controlpanel-canonical-names#user-accounts
119 */
120
122 PathAppendW(szPath, L"nusrmgr.cpl"); /* The name used on WinXP */
124 return TRUE;
125
126 return RunControlPanel(L"usrmgr.cpl"); /* ROS specific name (CORE-10226) */
127}
#define ShellExec(file, params)
Definition: control.c:38
static INT RunControlPanel(LPCWSTR lpCmd)
Definition: control.c:96
#define TRUE
Definition: types.h:120
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2331
BOOL WINAPI PathFileExistsW(const WCHAR *path)
Definition: path.c:2583
BOOL WINAPI IsOS(DWORD feature)
Definition: main.c:2392
LPCWSTR szPath
Definition: env.c:37
#define PathAppendW
Definition: pathcch.h:310
#define OS_ANYSERVER
Definition: shlwapi.h:255
#define _countof(array)
Definition: sndvol32.h:70

Referenced by wWinMain().

◆ RunControlPanel()

static INT RunControlPanel ( LPCWSTR  lpCmd)
static

Definition at line 96 of file control.c.

97{
98 WCHAR szParameters[MAX_PATH];
99 StringCchCopyW(szParameters, ARRAYSIZE(szParameters), L"shell32.dll,Control_RunDLL ");
100 if (FAILED(StringCchCatW(szParameters, ARRAYSIZE(szParameters), lpCmd)))
101 return 0;
102
103 return RUNDLL(szParameters);
104}
#define RUNDLL(param)
Definition: control.c:36
#define ARRAYSIZE(a)
Definition: cat.c:25
#define FAILED(hr)
Definition: intsafe.h:51
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149

Referenced by DECLARE_INTERFACE_(), OpenUserAccounts(), and wWinMain().

◆ wWinMain()

INT WINAPI wWinMain ( HINSTANCE  hInstance,
HINSTANCE  hPrevInstance,
LPWSTR  lpCmdLine,
INT  nCmdShow 
)

Definition at line 131 of file control.c.

135{
136 HKEY hKey;
137 LPWSTR *argv;
138 int argc;
139
140 /* Show the control panel window if no argument or "panel" was passed */
141 if (*lpCmdLine == 0 || !_wcsicmp(lpCmdLine, L"panel"))
142 return OpenShellFolder(L"");
143
144 /* Map legacy control panels */
145 if (!_wcsicmp(lpCmdLine, L"sticpl.cpl")) lpCmdLine = (LPWSTR) L"scannercamera";
146
147 /* Check one of the built-in control panel handlers */
148 if (!_wcsicmp(lpCmdLine, L"admintools")) return OpenShellFolder(L"\\::{D20EA4E1-3957-11d2-A40B-0C5020524153}");
149 else if (!_wcsicmp(lpCmdLine, L"color")) return RunControlPanel(L"desk.cpl,,2");
150 else if (!_wcsicmp(lpCmdLine, L"date/time")) return RunControlPanel(L"timedate.cpl");
151 else if (!_wcsicmp(lpCmdLine, L"desktop")) return RunControlPanel(L"desk.cpl");
152 else if (!_wcsicmp(lpCmdLine, L"folders")) return RUNDLL(L"shell32.dll,Options_RunDLL");
153 else if (!_wcsicmp(lpCmdLine, L"fonts")) return OpenShellFolder(L"\\::{D20EA4E1-3957-11d2-A40B-0C5020524152}");
154 else if (!_wcsicmp(lpCmdLine, L"infrared")) return RunControlPanel(L"irprops.cpl");
155 else if (!_wcsicmp(lpCmdLine, L"international")) return RunControlPanel(L"intl.cpl");
156 else if (!_wcsicmp(lpCmdLine, L"keyboard")) return RunControlPanel(L"main.cpl @1");
157 else if (!_wcsicmp(lpCmdLine, L"mouse")) return RunControlPanel(L"main.cpl @0");
158 else if (!_wcsicmp(lpCmdLine, L"netconnections")) return OpenShellFolder(L"\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}");
159 else if (!_wcsicmp(lpCmdLine, L"netware")) return RunControlPanel(L"nwc.cpl");
160 else if (!_wcsicmp(lpCmdLine, L"ports")) return RunControlPanel(L"sysdm.cpl,,1");
161 else if (!_wcsicmp(lpCmdLine, L"printers")) return OpenShellFolder(L"\\::{2227A280-3AEA-1069-A2DE-08002B30309D}");
162 else if (!_wcsicmp(lpCmdLine, L"scannercamera")) return OpenShellFolder(L"\\::{E211B736-43FD-11D1-9EFB-0000F8757FCD}");
163 else if (!_wcsicmp(lpCmdLine, L"schedtasks")) return OpenShellFolder(L"\\::{D6277990-4C6A-11CF-8D87-00AA0060F5BF}");
164 else if (!_wcsicmp(lpCmdLine, L"telephony")) return RunControlPanel(L"telephon.cpl");
165 else if (!_wcsicmp(lpCmdLine, L"userpasswords")) return OpenUserAccounts(); /* Graphical User Account Manager */
166 else if (!_wcsicmp(lpCmdLine, L"userpasswords2")) return RUNDLL(L"netplwiz.dll,UsersRunDll"); /* Dialog based advanced User Account Manager */
167
168 /* https://learn.microsoft.com/en-us/windows/win32/shell/executing-control-panel-items#windows-vista-canonical-names */
169 argv = CommandLineToArgvW(lpCmdLine, &argc);
170 if (argv)
171 {
172 UINT argi = 0;
173 HRESULT hr = -1;
174 if (argc >= 2 && IsSwitch(L"name", argv[argi + 0]))
175 {
176 LPCWSTR pszPage = NULL;
177 if (argc >= 4 && IsSwitch(L"page", argv[argi + 2]))
178 {
179 pszPage = argv[argi + 3];
180 }
181 hr = OpenControlPanelItem(argv[argi + 1], pszPage);
182 }
184 if (hr != -1)
185 {
186 return SUCCEEDED(hr);
187 }
188 }
189
190 /* It is none of them, so look for a handler in the registry */
192 L"Software\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls",
193 0,
195 &hKey) == ERROR_SUCCESS)
196 {
197 DWORD dwIndex;
198
199 for (dwIndex = 0; ; ++dwIndex)
200 {
201 DWORD dwDataSize;
202 DWORD dwValueSize = MAX_VALUE_NAME;
203 WCHAR szValueName[MAX_VALUE_NAME];
204
205 /* Get the value name and data size */
207 dwIndex,
208 szValueName,
209 &dwValueSize,
210 0,
211 NULL,
212 NULL,
213 &dwDataSize) != ERROR_SUCCESS)
214 {
215 break;
216 }
217
218 /* Check if the parameter is the value name */
219 if (!_wcsicmp(lpCmdLine, szValueName))
220 {
221 /*
222 * Allocate memory for the data plus two more characters,
223 * so we can quote the file name if required.
224 */
225 LPWSTR pszData;
226 pszData = HeapAlloc(GetProcessHeap(),
227 0,
228 dwDataSize + 2 * sizeof(WCHAR));
229 ++pszData;
230
231 /*
232 * This value is the one we are looking for, so get the data.
233 * It is the path to a .cpl file.
234 */
236 szValueName,
237 0,
238 NULL,
239 (LPBYTE)pszData,
240 &dwDataSize) == ERROR_SUCCESS)
241 {
242 INT nReturnValue;
243
244 /* Quote the file name if required */
245 if (*pszData != L'\"')
246 {
247 *(--pszData) = L'\"';
248 pszData[dwDataSize / sizeof(WCHAR)] = L'\"';
249 pszData[(dwDataSize / sizeof(WCHAR)) + 1] = 0;
250 }
251
252 nReturnValue = RunControlPanel(pszData);
253 HeapFree(GetProcessHeap(), 0, pszData);
255
256 return nReturnValue;
257 }
258
259 HeapFree(GetProcessHeap(), 0, pszData);
260 }
261 }
262
264 }
265
266 /*
267 * It's none of the known parameters, so interpret the parameter
268 * as the file name of a control panel applet.
269 */
270 return RunControlPanel(lpCmdLine);
271}
static BOOL OpenUserAccounts(VOID)
Definition: control.c:107
static BOOL IsSwitch(LPCWSTR Switch, LPCWSTR Arg)
Definition: control.c:46
static HRESULT OpenControlPanelItem(LPCWSTR Name, LPCWSTR Page)
Definition: control.c:56
static INT OpenShellFolder(LPWSTR lpFolderCLSID)
Definition: control.c:75
#define MAX_VALUE_NAME
Definition: control.c:29
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
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:2830
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
MonoAssembly int argc
Definition: metahost.c:107
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:164
WCHAR **WINAPI CommandLineToArgvW(const WCHAR *cmdline, int *numargs)
Definition: main.c:294
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
unsigned int UINT
Definition: sysinfo.c:13
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define argv
Definition: mplay32.c:18
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
int32_t INT
Definition: typedefs.h:58
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12