ReactOS 0.4.17-dev-387-ga401325
evalcmd.cpp File Reference
#include <windef.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <shlguid_undoc.h>
#include <shlobj_undoc.h>
#include <shlwapi_undoc.h>
#include <strsafe.h>
#include <pathcch.h>
#include <assert.h>
Include dependency graph for evalcmd.cpp:

Go to the source code of this file.

Macros

#define PATH_VALID_CHARS
 

Functions

static PCWSTR _PathGetArgsLikeCreateProcess (PCWSTR lpString)
 
static HRESULT _PathCopyExeAndTrimWhiteSpaces (PWSTR pszBuff, size_t cchBuff, PCWSTR pszSrc, size_t cchSrc)
 
static BOOL _PathMatchesSuspicious (PCWSTR lpString)
 "Program Files" contains space. It needs special handling. This function will detect it.
 
static PCWSTR _PathGuessNextBestArgs (PCWSTR pszPath)
 
static VOID _MakeAppPathKey (PCWSTR pszPath, PWSTR pszDest, UINT cchDest)
 
static BOOL _GetAppPath (PCWSTR pszPath, PWSTR pszValue, DWORD cchValue)
 
static HRESULT _PathExeExists (_In_ PCWSTR pszPath)
 
static HRESULT _PathFindInFolder (_In_ INT csidl, _In_ PCWSTR pszSrc, _Out_ PWSTR pszPath, _In_ UINT cchPath)
 
static HRESULT _PathFindInSystem (_Inout_ PWSTR pszPath, _In_ UINT cchPath)
 
EXTERN_C HRESULT WINAPI SHEvaluateSystemCommandTemplate (_In_ PCWSTR pszCmdTemplate, _Outptr_ PWSTR *ppszApplication, _Outptr_opt_ PWSTR *ppszCommandLine, _Outptr_opt_ PWSTR *ppszParameters)
 

Macro Definition Documentation

◆ PATH_VALID_CHARS

#define PATH_VALID_CHARS
Value:
#define PATH_CHAR_CLASS_OTHER_VALID
Definition: path.c:2115
#define PATH_CHAR_CLASS_SPACE
Definition: path.c:2114
#define PATH_CHAR_CLASS_SEMICOLON
Definition: path.c:2112
#define PATH_CHAR_CLASS_COMMA
Definition: path.c:2113
#define PATH_CHAR_CLASS_DOT
Definition: path.c:2109

Definition at line 18 of file evalcmd.cpp.

Function Documentation

◆ _GetAppPath()

static BOOL _GetAppPath ( PCWSTR  pszPath,
PWSTR  pszValue,
DWORD  cchValue 
)
static

Definition at line 119 of file evalcmd.cpp.

120{
121 WCHAR szSubKey[MAX_PATH];
122 _MakeAppPathKey(pszPath, szSubKey, _countof(szSubKey));
123 DWORD cbData = cchValue * sizeof(WCHAR);
125 return error == ERROR_SUCCESS;
126}
#define ERROR_SUCCESS
Definition: deptool.c:10
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI SHGetValueW(HKEY hkey, const WCHAR *subkey, const WCHAR *value, DWORD *type, void *data, DWORD *data_len)
Definition: main.c:2222
static VOID _MakeAppPathKey(PCWSTR pszPath, PWSTR pszDest, UINT cchDest)
Definition: evalcmd.cpp:110
unsigned long DWORD
Definition: ntddk_ex.h:95
#define error(str)
Definition: mkdosfs.c:1605
short WCHAR
Definition: pedump.c:58
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
_In_opt_ LPCSTR _In_opt_ LPCSTR pszValue
Definition: shlwapi.h:783
#define _countof(array)
Definition: sndvol32.h:70
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by SHEvaluateSystemCommandTemplate().

◆ _MakeAppPathKey()

static VOID _MakeAppPathKey ( PCWSTR  pszPath,
PWSTR  pszDest,
UINT  cchDest 
)
static

Definition at line 110 of file evalcmd.cpp.

111{
113 L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths",
114 pszPath, PATHCCH_NONE);
115 if (SUCCEEDED(hr))
116 PathCchAddExtension(pszDest, cchDest, L".exe");
117}
HRESULT hr
Definition: delayimp.cpp:582
HRESULT WINAPI PathCchAddExtension(WCHAR *path, SIZE_T size, const WCHAR *extension)
Definition: path.c:542
HRESULT WINAPI PathCchCombineEx(WCHAR *out, SIZE_T size, const WCHAR *path1, const WCHAR *path2, DWORD flags)
Definition: path.c:674
#define L(x)
Definition: resources.c:13
#define SUCCEEDED(hr)
Definition: intsafe.h:50
@ PATHCCH_NONE
Definition: pathcch.h:39
_In_ INT cchDest
Definition: shlwapi.h:1151

Referenced by _GetAppPath().

◆ _PathCopyExeAndTrimWhiteSpaces()

static HRESULT _PathCopyExeAndTrimWhiteSpaces ( PWSTR  pszBuff,
size_t  cchBuff,
PCWSTR  pszSrc,
size_t  cchSrc 
)
static

Definition at line 49 of file evalcmd.cpp.

50{
51 HRESULT hr = StringCchCopyNW(pszBuff, cchBuff, pszSrc, cchSrc);
52 if (SUCCEEDED(hr))
53 StrTrimW(pszBuff, L" \t");
54 return hr;
55}
BOOL WINAPI StrTrimW(WCHAR *str, const WCHAR *trim)
Definition: string.c:804
STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:236
_In_ DWORD _In_ int cchSrc
Definition: winnls.h:1275

Referenced by SHEvaluateSystemCommandTemplate().

◆ _PathExeExists()

static HRESULT _PathExeExists ( _In_ PCWSTR  pszPath)
static

Definition at line 128 of file evalcmd.cpp.

129{
132
134 DWORD attrs;
135 if (!PathFileExistsDefExtAndAttributesW(szPath, dwWhich, &attrs) ||
136 (attrs & FILE_ATTRIBUTE_DIRECTORY))
137 {
138 return CO_E_APPNOTFOUND;
139 }
140 return S_OK;
141}
BOOL WINAPI PathFileExistsDefExtAndAttributesW(_Inout_ LPWSTR pszPath, _In_ DWORD dwWhich, _Out_opt_ LPDWORD pdwFileAttributes)
Definition: utils.cpp:661
#define S_OK
Definition: intsafe.h:52
LPCWSTR szPath
Definition: env.c:37
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define WHICH_BAT
#define WHICH_CMD
#define WHICH_COM
#define WHICH_EXE
#define WHICH_PIF
#define WHICH_OPTIONAL
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
#define CO_E_APPNOTFOUND
Definition: winerror.h:3921

Referenced by _PathFindInFolder(), and SHEvaluateSystemCommandTemplate().

◆ _PathFindInFolder()

static HRESULT _PathFindInFolder ( _In_ INT  csidl,
_In_ PCWSTR  pszSrc,
_Out_ PWSTR  pszPath,
_In_ UINT  cchPath 
)
static

Definition at line 144 of file evalcmd.cpp.

145{
146 WCHAR szDir[MAX_PATH];
147 HRESULT hr = SHGetFolderPathW(0, csidl, 0, 0, szDir);
148 if (FAILED(hr))
149 return hr;
150
151 hr = PathCchCombineEx(pszPath, cchPath, szDir, pszSrc, PATHCCH_NONE);
152 if (FAILED(hr))
153 return hr;
154
155 return _PathExeExists(pszPath);
156}
HRESULT WINAPI SHGetFolderPathW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
Definition: shellpath.c:2716
static HRESULT _PathExeExists(_In_ PCWSTR pszPath)
Definition: evalcmd.cpp:128
#define FAILED(hr)
Definition: intsafe.h:51

Referenced by _PathFindInSystem().

◆ _PathFindInSystem()

static HRESULT _PathFindInSystem ( _Inout_ PWSTR  pszPath,
_In_ UINT  cchPath 
)
static

Definition at line 158 of file evalcmd.cpp.

159{
162 if (FAILED(hr))
164 if (FAILED(hr))
165 return hr;
166 return StringCchCopyW(pszPath, cchPath, szPath);
167}
static HRESULT _PathFindInFolder(_In_ INT csidl, _In_ PCWSTR pszSrc, _Out_ PWSTR pszPath, _In_ UINT cchPath)
Definition: evalcmd.cpp:144
#define CSIDL_SYSTEM
Definition: shlobj.h:2217
#define CSIDL_WINDOWS
Definition: shlobj.h:2216

Referenced by SHEvaluateSystemCommandTemplate().

◆ _PathGetArgsLikeCreateProcess()

static PCWSTR _PathGetArgsLikeCreateProcess ( PCWSTR  lpString)
static

Get the position of the arguments of a command line string as CreateProcess does.

Definition at line 25 of file evalcmd.cpp.

26{
27 PCWSTR pch;
28 if (*lpString == L'"')
29 {
30 pch = StrChrW(lpString + 1, L'"');
31 if (pch)
32 {
33 ++pch;
34 if (*pch == L' ')
35 ++pch;
36 return pch;
37 }
38 }
39 else
40 {
41 pch = StrChrW(lpString, L' ');
42 if (pch)
43 return pch + 1;
44 }
45 return &lpString[lstrlenW(lpString)];
46}
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
#define lstrlenW
Definition: compat.h:750
#define pch(ap)
Definition: match.c:418
const uint16_t * PCWSTR
Definition: typedefs.h:57

Referenced by SHEvaluateSystemCommandTemplate().

◆ _PathGuessNextBestArgs()

static PCWSTR _PathGuessNextBestArgs ( PCWSTR  pszPath)
static

Definition at line 69 of file evalcmd.cpp.

70{
71 PCWSTR pSpaceStart = NULL;
72 BOOL bValid = TRUE;
73
74 for (; *pszPath && bValid; ++pszPath)
75 {
76 switch (*pszPath)
77 {
78 case L' ':
79 if (!pSpaceStart)
80 pSpaceStart = pszPath;
81 break;
82
83 case L'"':
84 case L'%':
85 bValid = FALSE;
86 break;
87
88 case L'\\':
89 bValid = !PathIsUNCW(pszPath);
90 if (bValid)
91 pSpaceStart = NULL;
92 break;
93
94 default:
95 bValid = PathIsValidCharW(*pszPath, PATH_VALID_CHARS);
96 break;
97 }
98 }
99
100 if (pSpaceStart)
101 {
102 while (*pSpaceStart == L' ')
103 ++pSpaceStart;
104 return pSpaceStart;
105 }
106
107 return bValid ? pszPath : NULL;
108}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI PathIsUNCW(const WCHAR *path)
Definition: path.c:989
BOOL WINAPI PathIsValidCharW(WCHAR c, DWORD class)
Definition: path.c:2197
#define PATH_VALID_CHARS
Definition: evalcmd.cpp:18
unsigned int BOOL
Definition: ntddk_ex.h:94

Referenced by SHEvaluateSystemCommandTemplate().

◆ _PathMatchesSuspicious()

static BOOL _PathMatchesSuspicious ( PCWSTR  lpString)
static

"Program Files" contains space. It needs special handling. This function will detect it.

Definition at line 60 of file evalcmd.cpp.

61{
62 WCHAR pszPath[MAX_PATH];
64 INT cch = lstrlenW(pszPath);
65 return StrCmpNIW(lpString, pszPath, cch) == 0;
66}
INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:307
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
#define CSIDL_PROGRAM_FILES
Definition: shlobj.h:2218
int32_t INT
Definition: typedefs.h:58

Referenced by SHEvaluateSystemCommandTemplate().

◆ SHEvaluateSystemCommandTemplate()

EXTERN_C HRESULT WINAPI SHEvaluateSystemCommandTemplate ( _In_ PCWSTR  pszCmdTemplate,
_Outptr_ PWSTR ppszApplication,
_Outptr_opt_ PWSTR ppszCommandLine,
_Outptr_opt_ PWSTR ppszParameters 
)

Definition at line 178 of file evalcmd.cpp.

183{
184 HRESULT hr;
185 BOOL bQuoted;
186 WCHAR szExe[MAX_PATH], szProgram[MAX_PATH];
187
188 PCWSTR pszArgs = _PathGetArgsLikeCreateProcess(pszCmdTemplate);
189 UINT cchArgs = (UINT)(pszArgs - pszCmdTemplate);
190 hr = _PathCopyExeAndTrimWhiteSpaces(szExe, _countof(szExe), pszCmdTemplate, cchArgs);
191 if (FAILED(hr))
192 goto Exit;
193
194 // Unquote if necessary
195 bQuoted = (szExe[0] == L'"');
196 if (bQuoted)
197 PathUnquoteSpacesW(szExe);
198
199 hr = StringCchCopyW(szProgram, _countof(szProgram), szExe);
201
202 if (PathIsAbsolute(szExe))
203 {
204 if (bQuoted)
205 {
206 hr = _PathExeExists(szExe);
207 }
208 else // Not quoted
209 {
210 if (_PathMatchesSuspicious(szExe)) // ProgramFiles-likely?
212 else
213 hr = _PathExeExists(szExe);
214 }
215
216 // Detect where the full executable path ends and the arguments start
217 while (FAILED(hr))
218 {
219 if (bQuoted || !*pszArgs)
220 break;
221
222 pszArgs = _PathGuessNextBestArgs(pszArgs);
223 if (!pszArgs)
224 break;
225
226 cchArgs = (UINT)(pszArgs - pszCmdTemplate);
227 hr = _PathCopyExeAndTrimWhiteSpaces(szExe, _countof(szExe), pszCmdTemplate, cchArgs);
228 if (FAILED(hr))
229 break;
230
231 hr = _PathExeExists(szExe);
232 }
233 }
234 else
235 {
236 if (!PathIsFileSpecW(szExe))
237 {
239 goto Exit;
240 }
241
242 if (_GetAppPath(szExe, szExe, _countof(szExe)))
243 {
244 hr = StringCchCopyW(szProgram, _countof(szProgram), PathFindFileNameW(szExe));
245 }
246 else if (SHWindowsPolicyEx(POLID_UsePathEnvVarForCommandTemplates, FALSE))
247 {
249 }
250 else
251 {
252 hr = _PathFindInSystem(szExe, _countof(szExe));
253 }
254 }
255
256Exit:
257 *ppszApplication = NULL;
258 if (ppszCommandLine)
259 *ppszCommandLine = NULL;
260 if (ppszParameters)
261 *ppszParameters = NULL;
262
263 if (!pszArgs)
264 pszArgs = L"";
265
266 // Create output strings
267 if (SUCCEEDED(hr))
268 hr = SHStrDupW(szExe, ppszApplication);
269
270 if (SUCCEEDED(hr) && ppszCommandLine)
271 {
272 size_t cch = lstrlenW(szProgram) + lstrlenW(pszArgs) + 4; // 4 for '"', '"', ' ', NUL
273 hr = SHCoAlloc(cch * sizeof(WCHAR), (PVOID*)ppszCommandLine);
274 if (SUCCEEDED(hr))
275 hr = StringCchPrintfW(*ppszCommandLine, cch, L"\"%s\" %s", szProgram, pszArgs);
276 }
277
278 if (SUCCEEDED(hr) && ppszParameters)
279 hr = SHStrDupW(pszArgs, ppszParameters);
280
281 if (FAILED(hr))
282 {
283 // Clean up
284 if (*ppszApplication)
285 {
286 CoTaskMemFree(*ppszApplication);
287 *ppszApplication = NULL;
288 }
289 if (ppszCommandLine && *ppszCommandLine)
290 {
291 CoTaskMemFree(*ppszCommandLine);
292 *ppszCommandLine = NULL;
293 }
294 if (ppszParameters && *ppszParameters)
295 {
296 CoTaskMemFree(*ppszParameters);
297 *ppszParameters = NULL;
298 }
299 }
300
301 return hr;
302}
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
void WINAPI PathUnquoteSpacesW(WCHAR *path)
Definition: path.c:1982
WCHAR *WINAPI PathFindFileNameW(const WCHAR *path)
Definition: path.c:1677
BOOL WINAPI PathIsFileSpecW(const WCHAR *path)
Definition: path.c:1818
#define assert(_expr)
Definition: assert.h:32
HRESULT WINAPI SHStrDupW(const WCHAR *src, WCHAR **dest)
Definition: main.c:1692
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
Definition: path.c:404
static BOOL _PathMatchesSuspicious(PCWSTR lpString)
"Program Files" contains space. It needs special handling. This function will detect it.
Definition: evalcmd.cpp:60
static HRESULT _PathFindInSystem(_Inout_ PWSTR pszPath, _In_ UINT cchPath)
Definition: evalcmd.cpp:158
static PCWSTR _PathGetArgsLikeCreateProcess(PCWSTR lpString)
Definition: evalcmd.cpp:25
static BOOL _GetAppPath(PCWSTR pszPath, PWSTR pszValue, DWORD cchValue)
Definition: evalcmd.cpp:119
static HRESULT _PathCopyExeAndTrimWhiteSpaces(PWSTR pszBuff, size_t cchBuff, PCWSTR pszSrc, size_t cchSrc)
Definition: evalcmd.cpp:49
static PCWSTR _PathGuessNextBestArgs(PCWSTR pszPath)
Definition: evalcmd.cpp:69
unsigned int UINT
Definition: ndis.h:50
static HRESULT SHCoAlloc(_In_ SIZE_T cb, _Outptr_ PVOID *ppData)
static DWORD SHWindowsPolicyEx(_In_ REFGUID rpolid, _In_ DWORD dwDefaultValue)
static BOOL PathIsAbsolute(_In_ PCWSTR pszPath)
static void Exit(void)
Definition: sock.c:1330
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define E_ACCESSDENIED
Definition: winerror.h:4116