ReactOS  0.4.15-dev-1207-g698a8e6
ShellExecCmdLine.cpp File Reference
#include "shelltest.h"
#include <shlwapi.h>
#include <strsafe.h>
#include <versionhelpers.h>
#include <debug.h>
#include <stdio.h>
Include dependency graph for ShellExecCmdLine.cpp:

Go to the source code of this file.

Classes

struct  TEST_ENTRY
 

Macros

#define NDEBUG
 
#define SECL_NO_UI   0x2
 
#define SECL_LOG_USAGE   0x8
 
#define SECL_USE_IDLIST   0x10
 
#define SECL_ALLOW_NONEXE   0x20
 
#define SECL_RUNAS   0x40
 
#define ShellExecCmdLine   proxy_ShellExecCmdLine
 
#define shell32_hInstance   GetModuleHandle(NULL)
 
#define IDS_FILE_NOT_FOUND   (-1)
 
#define RETRY_COUNT   5
 
#define RETRY_INTERVAL   250
 

Typedefs

typedef HRESULT(WINAPISHELLEXECCMDLINE) (HWND, LPCWSTR, LPCWSTR, INT, LPVOID, DWORD)
 
typedef struct TEST_ENTRY TEST_ENTRY
 

Functions

static __inline void __SHCloneStrW (WCHAR **target, const WCHAR *source)
 
static LPCWSTR SplitParams (LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0)
 
HRESULT WINAPI ShellExecCmdLine (HWND hwnd, LPCWSTR pwszCommand, LPCWSTR pwszStartDir, int nShow, LPVOID pUnused, DWORD dwSeclFlags)
 
static void DoEntry (const TEST_ENTRY *pEntry)
 
 START_TEST (ShellExecCmdLine)
 

Variables

static const WCHAR wszOpen [] = L"open"
 
static const WCHAR wszExe [] = L".exe"
 
static const WCHAR wszCom [] = L".com"
 
SHELLEXECCMDLINE g_pShellExecCmdLine = NULL
 
static const char s_testfile1 [] = "Test File.txt"
 
static const char s_testfile2 [] = "Test File.bat"
 
static char s_notepad [] = "notepad.exe"
 
static const TEST_ENTRY s_entries []
 

Macro Definition Documentation

◆ IDS_FILE_NOT_FOUND

#define IDS_FILE_NOT_FOUND   (-1)

Definition at line 27 of file ShellExecCmdLine.cpp.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file ShellExecCmdLine.cpp.

◆ RETRY_COUNT

#define RETRY_COUNT   5

◆ RETRY_INTERVAL

#define RETRY_INTERVAL   250

◆ SECL_ALLOW_NONEXE

#define SECL_ALLOW_NONEXE   0x20

Definition at line 20 of file ShellExecCmdLine.cpp.

◆ SECL_LOG_USAGE

#define SECL_LOG_USAGE   0x8

Definition at line 18 of file ShellExecCmdLine.cpp.

◆ SECL_NO_UI

#define SECL_NO_UI   0x2

Definition at line 17 of file ShellExecCmdLine.cpp.

◆ SECL_RUNAS

#define SECL_RUNAS   0x40

Definition at line 21 of file ShellExecCmdLine.cpp.

◆ SECL_USE_IDLIST

#define SECL_USE_IDLIST   0x10

Definition at line 19 of file ShellExecCmdLine.cpp.

◆ shell32_hInstance

HINSTANCE shell32_hInstance   GetModuleHandle(NULL)

Definition at line 26 of file ShellExecCmdLine.cpp.

Referenced by CFSDropTarget::_GetEffectFromMenu(), CFSDropTarget::_GetUniqueFileName(), _ILGetFileType(), _InsertMenuItemW(), _SetOperationTitle(), _SHGetDefaultValue(), AboutDlgProc(), ActionDlg_OnBrowse(), COpenWithMenu::AddChooseProgramItem(), CDefaultContextMenu::AddStaticContextMenusToMenu(), COpenWithDialog::Browse(), BrsFolder_NewFolder(), ConfirmDialog(), Control_CreateListView(), Control_DoInterface(), Control_WndProc(), Control_WndProc_Create(), CFileDefExt::CountFolderAndFiles(), CNewMenu::CreateNewFolder(), CShellLink::CreateShortcutIcon(), do_error_dialog(), CDefaultContextMenu::DoCreateNewFolder(), DrivesContextMenuCallback(), EditTypeDlg_OnCommand(), CDrvDefExt::ExtraPageProc(), FileTypesDlg_DoList(), FileTypesDlg_InitListView(), CDefView::FillEditMenu(), CDefView::FillViewMenu(), FolderOptionsFileTypesDlg(), FormatDriveDlg(), FormatExCB(), GeneralDlg_UpdateIcons(), CControlPanelFolder::GetDetailsOf(), CRecycleBin::GetDetailsOf(), CDrivesFolder::GetDisplayNameOf(), GetDriveNameWithLetter(), GetFileTypeIconsEx(), HCR_GetClassNameA(), HCR_GetClassNameW(), COpenWithDialog::Init(), CFileDefExt::InitFileAttr(), CDrvDefExt::InitGeneralPage(), CFileDefExt::InitGeneralPage(), CDesktopBrowser::Initialize(), CNewMenu::Initialize(), InitializeFormatDriveDlg(), InitializeRecycleBinDlg(), CFileDefExt::InitOpensWithField(), InsertDefaultClusterSizeForFs(), CNewMenu::InsertShellNewItems(), COpenWithDialog::IsNoOpen(), LogoffWindowsDialog(), CNewMenu::NewItemByNonCommand(), CShellLink::OnCommand(), CDefView::OnCreate(), PickIconDlg(), PickIconProc(), Printer_LoadIconsW(), PropSheetProc(), CDefViewBckgrndMenu::QueryContextMenu(), COpenWithMenu::QueryContextMenu(), CRecycleBin::QueryContextMenu(), CNewMenu::QueryContextMenu(), CRecycleBinItemContextMenu::QueryContextMenu(), RunDlgProc(), RunFileDlg(), SetFileTypeEntryDefaultIcon(), SH_CreatePropertySheetPage(), SH_FormatByteSize(), SH_ShowRecycleBinProperties(), SHBrowseForFolderW(), SHCreateDirectoryExW(), SHELL_ConfirmDialogW(), SHELL_ConfirmIDs(), SHELL_ConfirmMsgBox(), ShellAboutW(), ShellExecCmdLine(), SHEmptyRecycleBinW(), SHFormatDrive(), SHOpenWithDialog(), ShowFolderOptionsDialog(), SHWinHelp(), SIC_Initialize(), CFileDefExt::UpdateFolderIcon(), and CDefView::UpdateStatusbar().

◆ ShellExecCmdLine

#define ShellExecCmdLine   proxy_ShellExecCmdLine

Definition at line 24 of file ShellExecCmdLine.cpp.

Typedef Documentation

◆ SHELLEXECCMDLINE

typedef HRESULT(WINAPI * SHELLEXECCMDLINE) (HWND, LPCWSTR, LPCWSTR, INT, LPVOID, DWORD)

Definition at line 241 of file ShellExecCmdLine.cpp.

◆ TEST_ENTRY

Function Documentation

◆ __SHCloneStrW()

static __inline void __SHCloneStrW ( WCHAR **  target,
const WCHAR source 
)
static

Definition at line 33 of file ShellExecCmdLine.cpp.

34 {
35  *target = (WCHAR *)SHAlloc((lstrlenW(source) + 1) * sizeof(WCHAR) );
37 }
#define lstrlenW
Definition: compat.h:609
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define lstrcpyW
Definition: compat.h:608
GLenum target
Definition: glext.h:7315
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:309

Referenced by ShellExecCmdLine().

◆ DoEntry()

static void DoEntry ( const TEST_ENTRY pEntry)
static

Definition at line 407 of file ShellExecCmdLine.cpp.

408 {
409  HRESULT hr;
410  DWORD dwSeclFlags;
411 
412  if (pEntry->bAllowNonExe)
413  dwSeclFlags = SECL_NO_UI | SECL_ALLOW_NONEXE;
414  else
415  dwSeclFlags = SECL_NO_UI;
416 
417  _SEH2_TRY
418  {
419  if (IsReactOS())
420  {
421  hr = proxy_ShellExecCmdLine(NULL, pEntry->pwszCommand, pEntry->pwszStartDir,
422  SW_SHOWNORMAL, NULL, dwSeclFlags);
423  }
424  else
425  {
426  hr = (*g_pShellExecCmdLine)(NULL, pEntry->pwszCommand, pEntry->pwszStartDir,
427  SW_SHOWNORMAL, NULL, dwSeclFlags);
428  }
429  }
431  {
432  hr = 0xDEADFACE;
433  }
434  _SEH2_END;
435 
436  ok(hr == pEntry->hr, "Line %d: hr expected 0x%lX, was 0x%lX\n", pEntry->lineno, pEntry->hr, hr);
437 
438 #define RETRY_COUNT 5
439 #define RETRY_INTERVAL 250
440  if (SUCCEEDED(hr) && pEntry->pwszWindowClass)
441  {
442  BOOL bFound = FALSE;
443  Sleep(RETRY_INTERVAL / 2);
444  for (int i = 0; i < RETRY_COUNT; ++i)
445  {
447  if (hwnd)
448  {
449  bFound = TRUE;
450  SendMessage(hwnd, WM_CLOSE, 0, 0);
452  break;
453  }
455  }
456  ok(bFound, "Line %d: The window not found\n", pEntry->lineno);
457  }
458 #undef RETRY_COUNT
459 #undef RETRY_INTERVAL
460 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
HRESULT hr
Definition: shlfolder.c:183
LPCWSTR pwszStartDir
LPCWSTR pwszCommand
#define TRUE
Definition: types.h:120
#define SECL_NO_UI
_SEH2_TRY
Definition: create.c:4226
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FALSE
Definition: types.h:117
#define RETRY_INTERVAL
unsigned int BOOL
Definition: ntddk_ex.h:94
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
#define SECL_ALLOW_NONEXE
INT lineno
Definition: DPtoLP.c:34
HWND WINAPI FindWindowW(_In_opt_ LPCWSTR, _In_opt_ LPCWSTR)
LONG HRESULT
Definition: typedefs.h:79
LPCWSTR pwszWindowClass
#define WM_CLOSE
Definition: winuser.h:1603
BOOL bAllowNonExe
unsigned long DWORD
Definition: ntddk_ex.h:95
HRESULT hr
#define SW_SHOWNORMAL
Definition: winuser.h:764
_SEH2_END
Definition: create.c:4400
#define ok(value,...)
Definition: atltest.h:57
#define SendMessage
Definition: winuser.h:5818
#define RETRY_COUNT
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define SUCCEEDED(hr)
Definition: intsafe.h:49

Referenced by START_TEST().

◆ ShellExecCmdLine()

HRESULT WINAPI ShellExecCmdLine ( HWND  hwnd,
LPCWSTR  pwszCommand,
LPCWSTR  pwszStartDir,
int  nShow,
LPVOID  pUnused,
DWORD  dwSeclFlags 
)

Definition at line 87 of file ShellExecCmdLine.cpp.

94 {
97  LPCWSTR pszVerb = NULL;
98  WCHAR szFile[MAX_PATH], szFile2[MAX_PATH];
99  HRESULT hr;
100  LPCWSTR pchParams;
101  LPWSTR lpCommand = NULL;
102 
103  if (pwszCommand == NULL)
105  1, (ULONG_PTR*)pwszCommand);
106 
107  __SHCloneStrW(&lpCommand, pwszCommand);
108  StrTrimW(lpCommand, L" \t");
109 
110  if (dwSeclFlags & SECL_NO_UI)
112  if (dwSeclFlags & SECL_LOG_USAGE)
114  if (dwSeclFlags & SECL_USE_IDLIST)
116 
117  if (dwSeclFlags & SECL_RUNAS)
118  {
119  dwSize = 0;
120  hr = AssocQueryStringW(0, ASSOCSTR_COMMAND, lpCommand, L"RunAs", NULL, &dwSize);
121  if (SUCCEEDED(hr) && dwSize != 0)
122  {
123  pszVerb = L"runas";
124  }
125  }
126 
127  if (UrlIsFileUrlW(lpCommand))
128  {
129  StringCchCopyW(szFile, _countof(szFile), lpCommand);
130  pchParams = NULL;
131  }
132  else
133  {
134  pchParams = SplitParams(lpCommand, szFile, _countof(szFile));
135  if (szFile[0] != UNICODE_NULL && szFile[1] == L':' &&
136  szFile[2] == UNICODE_NULL)
137  {
138  PathAddBackslashW(szFile);
139  }
140 
141  WCHAR szCurDir[MAX_PATH];
142  GetCurrentDirectoryW(_countof(szCurDir), szCurDir);
143  if (pwszStartDir)
144  {
145  SetCurrentDirectoryW(pwszStartDir);
146  }
147 
148  if (PathIsRelativeW(szFile) &&
149  GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) &&
150  PathFileExistsW(szFile2))
151  {
152  StringCchCopyW(szFile, _countof(szFile), szFile2);
153  }
154  else if (SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL) ||
155  SearchPathW(NULL, szFile, wszExe, _countof(szFile2), szFile2, NULL) ||
156  SearchPathW(NULL, szFile, wszCom, _countof(szFile2), szFile2, NULL) ||
157  SearchPathW(pwszStartDir, szFile, NULL, _countof(szFile2), szFile2, NULL) ||
158  SearchPathW(pwszStartDir, szFile, wszExe, _countof(szFile2), szFile2, NULL) ||
159  SearchPathW(pwszStartDir, szFile, wszCom, _countof(szFile2), szFile2, NULL))
160  {
161  StringCchCopyW(szFile, _countof(szFile), szFile2);
162  }
163  else if (SearchPathW(NULL, lpCommand, NULL, _countof(szFile2), szFile2, NULL) ||
164  SearchPathW(NULL, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) ||
165  SearchPathW(NULL, lpCommand, wszCom, _countof(szFile2), szFile2, NULL) ||
166  SearchPathW(pwszStartDir, lpCommand, NULL, _countof(szFile2), szFile2, NULL) ||
167  SearchPathW(pwszStartDir, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) ||
168  SearchPathW(pwszStartDir, lpCommand, wszCom, _countof(szFile2), szFile2, NULL))
169  {
170  StringCchCopyW(szFile, _countof(szFile), szFile2);
171  pchParams = NULL;
172  }
173 
174  if (pwszStartDir)
175  {
176  SetCurrentDirectoryW(szCurDir);
177  }
178 
179  if (!(dwSeclFlags & SECL_ALLOW_NONEXE))
180  {
181  if (!GetBinaryTypeW(szFile, &dwType))
182  {
183  SHFree(lpCommand);
184 
185  if (!(dwSeclFlags & SECL_NO_UI))
186  {
187  WCHAR szText[128 + MAX_PATH], szFormat[128];
189  StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
191  }
192  return CO_E_APPNOTFOUND;
193  }
194  }
195  else
196  {
198  {
199  SHFree(lpCommand);
200 
201  if (!(dwSeclFlags & SECL_NO_UI))
202  {
203  WCHAR szText[128 + MAX_PATH], szFormat[128];
205  StringCchPrintfW(szText, _countof(szText), szFormat, szFile);
207  }
209  }
210  }
211  }
212 
213  ZeroMemory(&info, sizeof(info));
214  info.cbSize = sizeof(info);
215  info.fMask = dwFlags;
216  info.hwnd = hwnd;
217  info.lpVerb = pszVerb;
218  info.lpFile = szFile;
219  info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL;
220  info.lpDirectory = pwszStartDir;
221  info.nShow = nShow;
222  if (ShellExecuteExW(&info))
223  {
224  if (info.lpIDList)
225  CoTaskMemFree(info.lpIDList);
226 
227  SHFree(lpCommand);
228 
229  return S_OK;
230  }
231 
232  dwError = GetLastError();
233 
234  SHFree(lpCommand);
235 
236  return HRESULT_FROM_WIN32(dwError);
237 }
static const WCHAR wszExe[]
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
Definition: path.c:1558
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define SECL_USE_IDLIST
static __inline void __SHCloneStrW(WCHAR **target, const WCHAR *source)
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:308
#define SECL_NO_UI
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:615
#define EXCEPTION_NONCONTINUABLE
Definition: rtltypes.h:154
#define SECL_RUNAS
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
#define ZeroMemory
Definition: winbase.h:1648
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1105
static const WCHAR wszCom[]
BOOL WINAPI GetBinaryTypeW(LPCWSTR lpApplicationName, LPDWORD lpBinaryType)
Definition: vdm.c:1235
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
struct _test_info info[]
Definition: SetCursorPos.c:19
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define UNICODE_NULL
static const WCHAR szText[]
Definition: dialog.c:139
LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
Definition: path.c:289
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
smooth NULL
Definition: ftsmooth.c:416
#define SEE_MASK_NOASYNC
Definition: shellapi.h:33
#define SEE_MASK_FLAG_NO_UI
Definition: shellapi.h:36
#define SECL_LOG_USAGE
#define SECL_ALLOW_NONEXE
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2263
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1756
HRESULT WINAPI AssocQueryStringW(ASSOCF cfFlags, ASSOCSTR str, LPCWSTR pszAssoc, LPCWSTR pszExtra, LPWSTR pszOut, DWORD *pcchOut)
Definition: assoc.c:427
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
int WINAPI MessageBoxW(_In_opt_ HWND, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_ UINT)
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
#define _countof(array)
Definition: sndvol32.h:68
static LPCWSTR SplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0)
#define MAX_PATH
Definition: compat.h:34
#define SEE_MASK_DOENVSUBST
Definition: shellapi.h:35
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IDS_FILE_NOT_FOUND
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MB_ICONERROR
Definition: winuser.h:781
#define UrlIsFileUrlW(x)
Definition: shlwapi.h:1377
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1297
#define S_OK
Definition: intsafe.h:51
#define shell32_hInstance
VOID WINAPI RaiseException(IN DWORD dwExceptionCode, IN DWORD dwExceptionFlags, IN DWORD nNumberOfArguments, IN CONST ULONG_PTR *lpArguments OPTIONAL)
Definition: except.c:693
#define SEE_MASK_FLAG_LOG_USAGE
Definition: shellapi.h:57
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2248
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
BOOL WINAPI StrTrimW(LPWSTR lpszStr, LPCWSTR lpszTrim)
Definition: string.c:1869
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:331
#define SEE_MASK_INVOKEIDLIST
Definition: shellapi.h:28
#define CO_E_APPNOTFOUND
Definition: winerror.h:2808
WCHAR * LPWSTR
Definition: xmlstorage.h:184
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
#define SUCCEEDED(hr)
Definition: intsafe.h:49

◆ SplitParams()

static LPCWSTR SplitParams ( LPCWSTR  psz,
LPWSTR  pszArg0,
size_t  cchArg0 
)
static

Definition at line 41 of file ShellExecCmdLine.cpp.

42 {
43  LPCWSTR pch;
44  size_t ich = 0;
45  if (*psz == L'"')
46  {
47  // 1st argument is quoted. the string in quotes is quoted 1st argument.
48  // [pch] --> [pszArg0+ich]
49  for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch)
50  {
51  if (*pch == L'"' && pch[1] == L'"')
52  {
53  // doubled double quotations found!
54  pszArg0[ich] = L'"';
55  }
56  else if (*pch == L'"')
57  {
58  // single double quotation found!
59  ++pch;
60  break;
61  }
62  else
63  {
64  // otherwise
65  pszArg0[ich] = *pch;
66  }
67  }
68  }
69  else
70  {
71  // 1st argument is unquoted. non-space sequence is 1st argument.
72  // [pch] --> [pszArg0+ich]
73  for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch)
74  {
75  pszArg0[ich] = *pch;
76  }
77  }
78  pszArg0[ich] = 0;
79 
80  // skip space
81  while (iswspace(*pch))
82  ++pch;
83 
84  return pch;
85 }
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define pch(ap)
Definition: match.c:418
#define iswspace(_c)
Definition: ctype.h:669
static const WCHAR L[]
Definition: oid.c:1250

Referenced by ShellExecCmdLine().

◆ START_TEST()

START_TEST ( ShellExecCmdLine  )

Definition at line 462 of file ShellExecCmdLine.cpp.

463 {
464  using namespace std;
465 
466  if (!IsReactOS())
467  {
469  {
470  skip("ShellExecCmdLine is not available on this platform\n");
471  return;
472  }
473 
474  HMODULE hShell32 = GetModuleHandleA("shell32");
476  if (!g_pShellExecCmdLine)
477  {
478  skip("ShellExecCmdLine is not found\n");
479  return;
480  }
481  }
482 
483  // s_testfile1
484  FILE *fp = fopen(s_testfile1, "wb");
485  ok(fp != NULL, "failed to create a test file\n");
486  fclose(fp);
487 
488  // s_testfile2
489  fp = fopen(s_testfile2, "wb");
490  ok(fp != NULL, "failed to create a test file\n");
491  if (fp)
492  {
493  fprintf(fp, "echo OK\n");
494  }
495  fclose(fp);
496 
497  for (size_t i = 0; i < _countof(s_entries); ++i)
498  {
499  DoEntry(&s_entries[i]);
500  }
501 
502  WCHAR buf0[MAX_PATH];
503  WCHAR buf1[MAX_PATH];
504  WCHAR buf2[MAX_PATH];
505  TEST_ENTRY additionals[] =
506  {
507  { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf0, NULL },
508  { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf0, L"." },
509  { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf0, L"system32" },
510  { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf1, NULL },
511  { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf1, L"." },
512  { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf1, L"system32" },
513  { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf2, NULL },
514  { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf2, L"." },
515  { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf2, L"system32" },
516  { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", buf0, NULL }, // FIXME
517  { __LINE__, S_OK, TRUE, L"Notepad", buf0, L"." },
518  { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", buf0, L"system32" }, // FIXME
519  { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", buf1, NULL }, // FIXME
520  { __LINE__, S_OK, TRUE, L"Notepad", buf1, L"." },
521  { __LINE__, S_OK, TRUE, L"Notepad", buf1, L"system32" },
522  { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", buf2, NULL }, // FIXME
523  { __LINE__, S_OK, TRUE, L"Notepad", buf2, L"." },
524  { __LINE__, S_OK, TRUE, L"Notepad", buf2, L"system32" },
525  };
526 
527  wsprintfW(buf0, L"%hs", s_testfile1);
528  wsprintfW(buf1, L"\"%hs\"", s_testfile1);
529  wsprintfW(buf2, L"\"%hs\" \"Test File.txt\"", s_testfile1);
530  for (size_t i = 0; i < _countof(additionals); ++i)
531  {
532  DoEntry(&additionals[i]);
533  }
534 
535  TEST_ENTRY additionals2[] =
536  {
537  { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf0, NULL },
538  { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf0, L"." },
539  { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf0, L"system32" },
540  { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf1, NULL },
541  { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf1, L"." },
542  { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf1, L"system32" },
543  { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf2, NULL },
544  { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf2, L"." },
545  { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf2, L"system32" },
546  { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, NULL, buf0, NULL }, // FIXME
547  { __LINE__, S_OK, TRUE, NULL, buf0, L"." },
548  { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, NULL, buf0, L"system32" }, // FIXME
549  { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, NULL, buf1, NULL }, // FIXME
550  { __LINE__, S_OK, TRUE, NULL, buf1, L"." },
551  { __LINE__, S_OK, TRUE, NULL, buf1, L"system32" },
552  { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, NULL, buf2, NULL }, // FIXME
553  { __LINE__, S_OK, TRUE, NULL, buf2, L"." },
554  { __LINE__, S_OK, TRUE, NULL, buf2, L"system32" },
555  };
556 
557  wsprintfW(buf0, L"%hs", s_testfile2);
558  wsprintfW(buf1, L"\"%hs\"", s_testfile2);
559  wsprintfW(buf2, L"\"%hs\" \"Test File.txt\"", s_testfile2);
560  for (size_t i = 0; i < _countof(additionals2); ++i)
561  {
562  DoEntry(&additionals2[i]);
563  }
564 
565  char path[MAX_PATH];
566  ok((INT_PTR)FindExecutableA("notepad.exe", NULL, s_notepad) >= 32, "FindExecutableA failed\n");
567  ok(GetModuleFileNameA(NULL, path, _countof(path)), "GetModuleFileNameA failed\n");
568  char *pch = strrchr(path, '\\');
569 
570  if (pch == NULL)
571  {
572  skip("pch == NULL\n");
573  }
574  else
575  {
576  // create "My Directory"
577  strcpy(pch, "\\My Directory");
579  ok(CreateDirectoryA(path, NULL), "CreateDirectoryA failed\n");
580 
581  // create "My Directory\\Notepad.exe" as clone of Notepad.exe
582  strcpy(pch, "\\My Directory\\Notepad.exe");
583  ok(CopyFileA(s_notepad, path, FALSE), "CopyFileA failed\n");
584 
585  wsprintfW(buf0, L"%hs", path);
586  wsprintfW(buf1, L"\"%hs\"", path);
587  wsprintfW(buf2, L"\"%hs\" \"Test File.txt\"", path);
588  TEST_ENTRY additionals3[] =
589  {
590  { __LINE__, S_OK, FALSE, NULL, buf0, NULL },
591  { __LINE__, S_OK, FALSE, NULL, buf0, L"." },
592  { __LINE__, S_OK, FALSE, NULL, buf0, L"system32" },
593  { __LINE__, S_OK, FALSE, NULL, buf1, NULL },
594  { __LINE__, S_OK, FALSE, NULL, buf1, L"." },
595  { __LINE__, S_OK, FALSE, NULL, buf1, L"system32" },
596  { __LINE__, S_OK, FALSE, NULL, buf2, NULL },
597  { __LINE__, S_OK, FALSE, NULL, buf2, L"." },
598  { __LINE__, S_OK, FALSE, NULL, buf2, L"system32" },
599  { __LINE__, S_OK, TRUE, NULL, buf0, NULL },
600  { __LINE__, S_OK, TRUE, NULL, buf0, L"." },
601  { __LINE__, S_OK, TRUE, NULL, buf0, L"system32" },
602  { __LINE__, S_OK, TRUE, NULL, buf1, NULL },
603  { __LINE__, S_OK, TRUE, NULL, buf1, L"." },
604  { __LINE__, S_OK, TRUE, NULL, buf1, L"system32" },
605  { __LINE__, S_OK, TRUE, NULL, buf2, NULL },
606  { __LINE__, S_OK, TRUE, NULL, buf2, L"." },
607  { __LINE__, S_OK, TRUE, NULL, buf2, L"system32" },
608  };
609  for (size_t i = 0; i < _countof(additionals3); ++i)
610  {
611  DoEntry(&additionals3[i]);
612  }
613 
614  DeleteFileA(path);
615 
616  strcpy(pch, "\\My Directory");
618  }
619 
620  // clean up
621  ok(DeleteFileA(s_testfile1), "failed to delete the test file\n");
622  ok(DeleteFileA(s_testfile2), "failed to delete the test file\n");
623 }
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
static const char s_testfile2[]
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define TRUE
Definition: types.h:120
HRESULT(WINAPI * SHELLEXECCMDLINE)(HWND, LPCWSTR, LPCWSTR, INT, LPVOID, DWORD)
#define RemoveDirectory
Definition: winbase.h:3735
BOOL WINAPI CopyFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:404
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
int32_t INT_PTR
Definition: typedefs.h:64
Definition: features.h:417
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
#define pch(ap)
Definition: match.c:418
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FALSE
Definition: types.h:117
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:636
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
VERSIONHELPERAPI IsWindowsVistaOrGreater()
const char * LPCSTR
Definition: xmlstorage.h:183
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static const char s_testfile1[]
SHELLEXECCMDLINE g_pShellExecCmdLine
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _countof(array)
Definition: sndvol32.h:68
#define MAX_PATH
Definition: compat.h:34
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static const TEST_ENTRY s_entries[]
HINSTANCE WINAPI FindExecutableA(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
Definition: shlexec.cpp:1223
Definition: cmd.c:12
static const WCHAR L[]
Definition: oid.c:1250
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
#define S_OK
Definition: intsafe.h:51
#define ok(value,...)
Definition: atltest.h:57
static void DoEntry(const TEST_ENTRY *pEntry)
#define skip(...)
Definition: atltest.h:64
static char s_notepad[]
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define GetProcAddress(x, y)
Definition: compat.h:612
#define CO_E_APPNOTFOUND
Definition: winerror.h:2808
static HMODULE hShell32
Definition: string.c:34

Variable Documentation

◆ g_pShellExecCmdLine

SHELLEXECCMDLINE g_pShellExecCmdLine = NULL

Definition at line 242 of file ShellExecCmdLine.cpp.

Referenced by START_TEST().

◆ s_entries

const TEST_ENTRY s_entries[]
static

Definition at line 258 of file ShellExecCmdLine.cpp.

Referenced by START_TEST().

◆ s_notepad

char s_notepad[] = "notepad.exe"
static

Definition at line 256 of file ShellExecCmdLine.cpp.

Referenced by START_TEST().

◆ s_testfile1

const char s_testfile1[] = "Test File.txt"
static

Definition at line 254 of file ShellExecCmdLine.cpp.

Referenced by START_TEST().

◆ s_testfile2

const char s_testfile2[] = "Test File.bat"
static

Definition at line 255 of file ShellExecCmdLine.cpp.

Referenced by START_TEST().

◆ wszCom

const WCHAR wszCom[] = L".com"
static

Definition at line 31 of file ShellExecCmdLine.cpp.

Referenced by ShellExecCmdLine().

◆ wszExe

const WCHAR wszExe[] = L".exe"
static

Definition at line 30 of file ShellExecCmdLine.cpp.

Referenced by ShellExecCmdLine().

◆ wszOpen

const WCHAR wszOpen[] = L"open"
static

Definition at line 29 of file ShellExecCmdLine.cpp.