ReactOS 0.4.17-dev-482-g1b46029
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 "evalcmd.h"
#include <wine/debug.h>
Include dependency graph for evalcmd.cpp:

Go to the source code of this file.

Macros

#define PATH_VALID_CHARS
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (evalcmd)
 
static PCWSTR _PathGetArgsLikeCreateProcess (PCWSTR lpString)
 
EXTERN_C 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)
 
EXTERN_C HRESULT _PathFindInFolder (_In_ INT csidl, _In_ PCWSTR pszSrc, _Out_ PWSTR pszPath, _In_ UINT cchPath)
 
EXTERN_C 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 22 of file evalcmd.cpp.

Function Documentation

◆ _GetAppPath()

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

Definition at line 123 of file evalcmd.cpp.

124{
125 WCHAR szSubKey[MAX_PATH];
126 _MakeAppPathKey(pszPath, szSubKey, _countof(szSubKey));
127 DWORD cbData = cchValue * sizeof(WCHAR);
129 return error == ERROR_SUCCESS;
130}
#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:114
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 114 of file evalcmd.cpp.

115{
117 L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths",
118 pszPath, PATHCCH_NONE);
119 if (SUCCEEDED(hr))
120 PathCchAddExtension(pszDest, cchDest, L".exe");
121}
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:1161

Referenced by _GetAppPath().

◆ _PathCopyExeAndTrimWhiteSpaces()

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

Definition at line 53 of file evalcmd.cpp.

54{
55 HRESULT hr = StringCchCopyNW(pszBuff, cchBuff, pszSrc, cchSrc);
56 if (SUCCEEDED(hr))
57 StrTrimW(pszBuff, L" \t");
58 return hr;
59}
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 _ExeFromCmd(), and SHEvaluateSystemCommandTemplate().

◆ _PathExeExists()

static HRESULT _PathExeExists ( _In_ PCWSTR  pszPath)
static

Definition at line 132 of file evalcmd.cpp.

133{
136
138 DWORD attrs;
139 if (!PathFileExistsDefExtAndAttributesW(szPath, dwWhich, &attrs) ||
140 (attrs & FILE_ATTRIBUTE_DIRECTORY))
141 {
142 return CO_E_APPNOTFOUND;
143 }
144 return S_OK;
145}
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()

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

Definition at line 148 of file evalcmd.cpp.

149{
150 WCHAR szDir[MAX_PATH];
151 HRESULT hr = SHGetFolderPathW(0, csidl, 0, 0, szDir);
152 if (FAILED(hr))
153 return hr;
154
155 hr = PathCchCombineEx(pszPath, cchPath, szDir, pszSrc, PATHCCH_NONE);
156 if (FAILED(hr))
157 return hr;
158
159 return _PathExeExists(pszPath);
160}
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:132
#define FAILED(hr)
Definition: intsafe.h:51

Referenced by _PathFindInSystem().

◆ _PathFindInSystem()

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

Definition at line 162 of file evalcmd.cpp.

163{
166 if (FAILED(hr))
168 if (FAILED(hr))
169 return hr;
170 return StringCchCopyW(pszPath, cchPath, szPath);
171}
EXTERN_C HRESULT _PathFindInFolder(_In_ INT csidl, _In_ PCWSTR pszSrc, _Out_ PWSTR pszPath, _In_ UINT cchPath)
Definition: evalcmd.cpp:148
#define CSIDL_SYSTEM
Definition: shlobj.h:2226
#define CSIDL_WINDOWS
Definition: shlobj.h:2225

Referenced by _ExeFromCmd(), and 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 29 of file evalcmd.cpp.

30{
31 PCWSTR pch;
32 if (*lpString == L'"')
33 {
34 pch = StrChrW(lpString + 1, L'"');
35 if (pch)
36 {
37 ++pch;
38 if (*pch == L' ')
39 ++pch;
40 return pch;
41 }
42 }
43 else
44 {
45 pch = StrChrW(lpString, L' ');
46 if (pch)
47 return pch + 1;
48 }
49 return &lpString[lstrlenW(lpString)];
50}
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 73 of file evalcmd.cpp.

74{
75 PCWSTR pSpaceStart = NULL;
76 BOOL bValid = TRUE;
77
78 for (; *pszPath && bValid; ++pszPath)
79 {
80 switch (*pszPath)
81 {
82 case L' ':
83 if (!pSpaceStart)
84 pSpaceStart = pszPath;
85 break;
86
87 case L'"':
88 case L'%':
89 bValid = FALSE;
90 break;
91
92 case L'\\':
93 bValid = !PathIsUNCW(pszPath);
94 if (bValid)
95 pSpaceStart = NULL;
96 break;
97
98 default:
99 bValid = PathIsValidCharW(*pszPath, PATH_VALID_CHARS);
100 break;
101 }
102 }
103
104 if (pSpaceStart)
105 {
106 while (*pSpaceStart == L' ')
107 ++pSpaceStart;
108 return pSpaceStart;
109 }
110
111 return bValid ? pszPath : NULL;
112}
#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:22
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 64 of file evalcmd.cpp.

65{
66 WCHAR pszPath[MAX_PATH];
68 INT cch = lstrlenW(pszPath);
69 return StrCmpNIW(lpString, pszPath, cch) == 0;
70}
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:2227
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 182 of file evalcmd.cpp.

187{
188 HRESULT hr;
189 BOOL bQuoted;
190 WCHAR szExe[MAX_PATH], szProgram[MAX_PATH];
191
192 PCWSTR pszArgs = _PathGetArgsLikeCreateProcess(pszCmdTemplate);
193 UINT cchArgs = (UINT)(pszArgs - pszCmdTemplate);
194 hr = _PathCopyExeAndTrimWhiteSpaces(szExe, _countof(szExe), pszCmdTemplate, cchArgs);
195 if (FAILED(hr))
196 goto Exit;
197
198 // Unquote if necessary
199 bQuoted = (szExe[0] == L'"');
200 if (bQuoted)
201 PathUnquoteSpacesW(szExe);
202
203 hr = StringCchCopyW(szProgram, _countof(szProgram), szExe);
205
206 if (PathIsAbsolute(szExe))
207 {
208 if (bQuoted)
209 {
210 hr = _PathExeExists(szExe);
211 }
212 else // Not quoted
213 {
214 if (_PathMatchesSuspicious(szExe)) // ProgramFiles-likely?
216 else
217 hr = _PathExeExists(szExe);
218 }
219
220 // Detect where the full executable path ends and the arguments start
221 while (FAILED(hr))
222 {
223 if (bQuoted || !*pszArgs)
224 break;
225
226 pszArgs = _PathGuessNextBestArgs(pszArgs);
227 if (!pszArgs)
228 break;
229
230 cchArgs = (UINT)(pszArgs - pszCmdTemplate);
231 hr = _PathCopyExeAndTrimWhiteSpaces(szExe, _countof(szExe), pszCmdTemplate, cchArgs);
232 if (FAILED(hr))
233 break;
234
235 hr = _PathExeExists(szExe);
236 }
237 }
238 else
239 {
240 if (!PathIsFileSpecW(szExe))
241 {
243 goto Exit;
244 }
245
246 if (_GetAppPath(szExe, szExe, _countof(szExe)))
247 {
248 hr = StringCchCopyW(szProgram, _countof(szProgram), PathFindFileNameW(szExe));
249 }
250 else if (SHWindowsPolicyEx(POLID_UsePathEnvVarForCommandTemplates, FALSE))
251 {
253 }
254 else
255 {
256 hr = _PathFindInSystem(szExe, _countof(szExe));
257 }
258 }
259
260Exit:
261 *ppszApplication = NULL;
262 if (ppszCommandLine)
263 *ppszCommandLine = NULL;
264 if (ppszParameters)
265 *ppszParameters = NULL;
266
267 if (!pszArgs)
268 pszArgs = L"";
269
270 // Create output strings
271 if (SUCCEEDED(hr))
272 hr = SHStrDupW(szExe, ppszApplication);
273
274 if (SUCCEEDED(hr) && ppszCommandLine)
275 {
276 size_t cch = lstrlenW(szProgram) + lstrlenW(pszArgs) + 4; // 4 for '"', '"', ' ', NUL
277 hr = SHCoAlloc(cch * sizeof(WCHAR), (PVOID*)ppszCommandLine);
278 if (SUCCEEDED(hr))
279 hr = StringCchPrintfW(*ppszCommandLine, cch, L"\"%s\" %s", szProgram, pszArgs);
280 }
281
282 if (SUCCEEDED(hr) && ppszParameters)
283 hr = SHStrDupW(pszArgs, ppszParameters);
284
285 if (FAILED(hr))
286 {
287 // Clean up
288 if (*ppszApplication)
289 {
290 CoTaskMemFree(*ppszApplication);
291 *ppszApplication = NULL;
292 }
293 if (ppszCommandLine && *ppszCommandLine)
294 {
295 CoTaskMemFree(*ppszCommandLine);
296 *ppszCommandLine = NULL;
297 }
298 if (ppszParameters && *ppszParameters)
299 {
300 CoTaskMemFree(*ppszParameters);
301 *ppszParameters = NULL;
302 }
303 }
304
305 return hr;
306}
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
EXTERN_C HRESULT _PathCopyExeAndTrimWhiteSpaces(PWSTR pszBuff, size_t cchBuff, PCWSTR pszSrc, size_t cchSrc)
Definition: evalcmd.cpp:53
static BOOL _PathMatchesSuspicious(PCWSTR lpString)
"Program Files" contains space. It needs special handling. This function will detect it.
Definition: evalcmd.cpp:64
static PCWSTR _PathGetArgsLikeCreateProcess(PCWSTR lpString)
Definition: evalcmd.cpp:29
static BOOL _GetAppPath(PCWSTR pszPath, PWSTR pszValue, DWORD cchValue)
Definition: evalcmd.cpp:123
EXTERN_C HRESULT _PathFindInSystem(_Inout_ PWSTR pszPath, _In_ UINT cchPath)
Definition: evalcmd.cpp:162
static PCWSTR _PathGuessNextBestArgs(PCWSTR pszPath)
Definition: evalcmd.cpp:73
unsigned int UINT
Definition: sysinfo.c:13
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

Referenced by _ExeFromCmd().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( evalcmd  )