mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 06:26:00 +00:00
[SHELL32][CONTROL] Added basic IOpenControlPanel support (#6248)
Add a basic IOpenControlPanel implementation that supports Vista canonical registry names. Implements `control.exe /name company.name [/page id]` and `IOpenControlPanel` handling of Vista-style canonical registry names. The documented `Microsoft.*` names don't work because they are simply not in our registry but "[Executable Control Panel Items](https://learn.microsoft.com/en-us/windows/win32/shell/how-to-register-an-executable-control-panel-item-registration-)" registered by 3rd-party ISVs will function correctly in control.exe and the COM API. Notes: - `IOpenControlPanel` is implemented in CControlPanelFolder.cpp because it is supposed to have tighter integration with that shell folder than it does in this PR. - `IOpenControlPanel` is also supposed to handle .cpl files with canonical names registered under [`Extended Properties`](https://learn.microsoft.com/en-us/windows/win32/shell/how-to-register-dll-control-panel-item-registration-#step-3) but the control panel folder does not implement `IShellFolder2::GetDetailsEx` yet, so it will have to wait. - These "Executable Control Panel Items" are also supposed to be displayed in the control panel itself but this PR does not address that. The `ITEMIDLIST` format for those needs investigation... - The Wow64 handling is perhaps not correct but it does not matter, `ShellExecuteEx` gets to deal with whatever is in the `...\shell\open\command` key. `CControlPanelFolder` would have to take more care when it starts reading those keys so it knows when to append "(32-bit)" to the display name. - `%s%s` because .cpl canonical names don't have the `::` prefix according to Geoff Chappell. - Always returns `CPVIEW_CLASSIC` because our `CControlPanelFolder` does not support the category view.
This commit is contained in:
parent
fb43301bad
commit
d41dec2e07
8 changed files with 281 additions and 1 deletions
|
@ -2,5 +2,7 @@
|
|||
add_rc_deps(control.rc ${CMAKE_CURRENT_SOURCE_DIR}/resources/config.ico)
|
||||
add_executable(control control.c control.rc)
|
||||
set_module_type(control win32gui UNICODE)
|
||||
add_delay_importlibs(control ole32)
|
||||
target_link_libraries(control uuid)
|
||||
add_importlibs(control advapi32 shell32 user32 msvcrt kernel32)
|
||||
add_cd_file(TARGET control DESTINATION reactos/system32 FOR all)
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
* PURPOSE: ReactOS System Control Panel
|
||||
* COPYRIGHT: Copyright 2004 Gero Kuehn (reactos.filter@gkware.com)
|
||||
* Copyright 2008 Colin Finck (colin@reactos.org)
|
||||
* Copyright 2014 Hermès Bélusca-Maïto (hermes.belusca-maito@reactos.org)
|
||||
* Copyright 2014 Hermès Bélusca-Maïto (hermes.belusca-maito@reactos.org)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#define COBJMACROS
|
||||
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
|
@ -17,6 +19,9 @@
|
|||
#include <winreg.h>
|
||||
#include <shellapi.h>
|
||||
#include <strsafe.h>
|
||||
#include <objbase.h>
|
||||
#include <shobjidl.h>
|
||||
#include <shlguid.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
|
@ -34,6 +39,35 @@ VOID
|
|||
WINAPI
|
||||
Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow);
|
||||
|
||||
static BOOL
|
||||
IsSwitch(LPCWSTR Switch, LPCWSTR Arg)
|
||||
{
|
||||
if (*Arg == '/' || *Arg == '-')
|
||||
{
|
||||
return !lstrcmpiW(Arg+1, Switch);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
OpenControlPanelItem(LPCWSTR Name, LPCWSTR Page)
|
||||
{
|
||||
HRESULT hr = CoInitialize(0);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
IOpenControlPanel *pOCP;
|
||||
hr = CoCreateInstance(&CLSID_OpenControlPanel, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IOpenControlPanel, (void**)&pOCP);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = IOpenControlPanel_Open(pOCP, Name, Page, NULL);
|
||||
IOpenControlPanel_Release(pOCP);
|
||||
}
|
||||
CoUninitialize();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static INT
|
||||
OpenShellFolder(LPWSTR lpFolderCLSID)
|
||||
{
|
||||
|
@ -73,11 +107,16 @@ wWinMain(HINSTANCE hInstance,
|
|||
INT nCmdShow)
|
||||
{
|
||||
HKEY hKey;
|
||||
LPWSTR *argv;
|
||||
int argc;
|
||||
|
||||
/* Show the control panel window if no argument or "panel" was passed */
|
||||
if (*lpCmdLine == 0 || !_wcsicmp(lpCmdLine, L"panel"))
|
||||
return OpenShellFolder(L"");
|
||||
|
||||
/* Map legacy control panels */
|
||||
if (!_wcsicmp(lpCmdLine, L"sticpl.cpl")) lpCmdLine = (LPWSTR) L"scannercamera";
|
||||
|
||||
/* Check one of the built-in control panel handlers */
|
||||
if (!_wcsicmp(lpCmdLine, L"admintools")) return OpenShellFolder(L"\\::{D20EA4E1-3957-11d2-A40B-0C5020524153}");
|
||||
else if (!_wcsicmp(lpCmdLine, L"color")) return RunControlPanel(L"desk.cpl,,2");
|
||||
|
@ -99,6 +138,28 @@ wWinMain(HINSTANCE hInstance,
|
|||
else if (!_wcsicmp(lpCmdLine, L"userpasswords")) return RunControlPanel(L"nusrmgr.cpl"); /* Graphical User Account Manager */
|
||||
else if (!_wcsicmp(lpCmdLine, L"userpasswords2")) return RUNDLL(L"netplwiz.dll,UsersRunDll"); /* Dialog based advanced User Account Manager */
|
||||
|
||||
/* https://learn.microsoft.com/en-us/windows/win32/shell/executing-control-panel-items#windows-vista-canonical-names */
|
||||
argv = CommandLineToArgvW(lpCmdLine, &argc);
|
||||
if (argv)
|
||||
{
|
||||
UINT argi = 0;
|
||||
HRESULT hr = -1;
|
||||
if (argc >= 2 && IsSwitch(L"name", argv[argi + 0]))
|
||||
{
|
||||
LPCWSTR pszPage = NULL;
|
||||
if (argc >= 4 && IsSwitch(L"page", argv[argi + 2]))
|
||||
{
|
||||
pszPage = argv[argi + 3];
|
||||
}
|
||||
hr = OpenControlPanelItem(argv[argi + 1], pszPage);
|
||||
}
|
||||
LocalFree(argv);
|
||||
if (hr != -1)
|
||||
{
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
}
|
||||
|
||||
/* It is none of them, so look for a handler in the registry */
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"Software\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue