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 35 Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow); 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 StringCbCopyW(szParameters, sizeof(szParameters), L"/n,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"); 47 StringCbCatW(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 58 RunControlPanel(LPCWSTR lpCmd) 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: */ 70 Control_RunDLLW(GetDesktopWindow(), 0, lpCmd, SW_SHOW); 71 return 1; 72 } 73 74 INT 75 WINAPI 76 wWinMain(HINSTANCE hInstance, 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,,2"); 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,,1"); 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 */ 109 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 110 L"Software\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls", 111 0, 112 KEY_QUERY_VALUE, 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 } 190