ReactOS  0.4.14-dev-315-gbb6fece
CommandLine.c File Reference
#include <apitest.h>
#include <stdio.h>
#include <ndk/umtypes.h>
#include "./CmdLineUtil/CmdLineUtil.h"
Include dependency graph for CommandLine.c:

Go to the source code of this file.

Classes

struct  _TEST_CASE
 

Macros

#define WIN32_NO_STATUS
 
#define COUNT_OF(x)   (sizeof((x))/sizeof((x)[0]))
 
#define SPACECHAR   L' '
 
#define DQUOTECHAR   L'"'
 

Typedefs

typedef struct _TEST_CASE TEST_CASE
 
typedef struct _TEST_CASEPTEST_CASE
 

Functions

LPWSTR ExtractCmdLine (IN LPWSTR lpszCommandLine)
 
VOID ExtractCmdLine_U (IN OUT PUNICODE_STRING pCommandLine_U)
 
static void Test_CommandLine (IN ULONG TestNumber, IN PTEST_CASE TestCase)
 
 START_TEST (CommandLine)
 

Variables

static WCHAR UtilityProgramDirectory [MAX_PATH]
 
static TEST_CASE TestCases []
 

Macro Definition Documentation

◆ COUNT_OF

#define COUNT_OF (   x)    (sizeof((x))/sizeof((x)[0]))

Definition at line 16 of file CommandLine.c.

◆ DQUOTECHAR

#define DQUOTECHAR   L'"'

Definition at line 23 of file CommandLine.c.

◆ SPACECHAR

#define SPACECHAR   L' '

Extracts the command tail from the command line (deletes the program's name and keep the rest).

Definition at line 22 of file CommandLine.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 10 of file CommandLine.c.

Typedef Documentation

◆ PTEST_CASE

◆ TEST_CASE

Function Documentation

◆ ExtractCmdLine()

LPWSTR ExtractCmdLine ( IN LPWSTR  lpszCommandLine)

Definition at line 25 of file CommandLine.c.

26 {
27  BOOL inDoubleQuote = FALSE;
28 
29  /*
30  * Skip the program's name (the first token in the command line).
31  * Handle quoted program's name.
32  */
33  if (lpszCommandLine)
34  {
35  while ( (*lpszCommandLine > SPACECHAR) ||
36  (*lpszCommandLine && inDoubleQuote) )
37  {
38  if (*lpszCommandLine == DQUOTECHAR)
39  inDoubleQuote = !inDoubleQuote;
40 
41  ++lpszCommandLine;
42  }
43 
44  /* Skip all white spaces preceeding the second token. */
45  while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR))
46  ++lpszCommandLine;
47  }
48 
49  return lpszCommandLine;
50 }
#define DQUOTECHAR
Definition: CommandLine.c:23
#define SPACECHAR
Definition: CommandLine.c:22
unsigned int BOOL
Definition: ntddk_ex.h:94

Referenced by Test_CommandLine().

◆ ExtractCmdLine_U()

VOID ExtractCmdLine_U ( IN OUT PUNICODE_STRING  pCommandLine_U)

Definition at line 52 of file CommandLine.c.

53 {
54  BOOL inDoubleQuote = FALSE;
55  PWSTR lpszCommandLine;
56 
57  /*
58  * Skip the program's name (the first token in the command line).
59  * Handle quoted program's name.
60  */
61  if (pCommandLine_U && pCommandLine_U->Buffer && (pCommandLine_U->Length != 0))
62  {
63  lpszCommandLine = pCommandLine_U->Buffer;
64 
65  while ( (pCommandLine_U->Length > 0) &&
66  ( (*lpszCommandLine > SPACECHAR) ||
67  (*lpszCommandLine && inDoubleQuote) ) )
68  {
69  if (*lpszCommandLine == DQUOTECHAR)
70  inDoubleQuote = !inDoubleQuote;
71 
72  ++lpszCommandLine;
73  pCommandLine_U->Length -= sizeof(WCHAR);
74  }
75 
76  /* Skip all white spaces preceeding the second token. */
77  while ((pCommandLine_U->Length > 0) && *lpszCommandLine && (*lpszCommandLine <= SPACECHAR))
78  {
79  ++lpszCommandLine;
80  pCommandLine_U->Length -= sizeof(WCHAR);
81  }
82 
83  pCommandLine_U->Buffer = lpszCommandLine;
84  }
85 
86  return;
87 }
#define DQUOTECHAR
Definition: CommandLine.c:23
#define SPACECHAR
Definition: CommandLine.c:22
uint16_t * PWSTR
Definition: typedefs.h:54
unsigned int BOOL
Definition: ntddk_ex.h:94
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by Test_CommandLine().

◆ START_TEST()

START_TEST ( CommandLine  )

Definition at line 285 of file CommandLine.c.

286 {
287  ULONG i;
288 
289  DWORD dwRet;
290  LPWSTR p = NULL;
291 
292 
293  /*
294  * Initialize the UtilityProgramDirectory variable.
295  */
297  ok(dwRet != 0, "ERROR: Cannot retrieve the path to the current running process, last error %lu\n", GetLastError());
298  if (dwRet == 0) return;
299 
300  /* Path : executable.exe or "executable.exe" or C:\path\executable.exe or "C:\path\executable.exe" */
302  if (p && *p != 0)
303  *++p = 0; /* Null-terminate there : C:\path\ or "C:\path\ */
304  else
305  UtilityProgramDirectory[0] = 0; /* Suppress the executable.exe name */
306 
307  wcscat(UtilityProgramDirectory, L"testdata\\CmdLineUtil.exe");
308 
309  /* Close the opened quote if needed. */
311 
312 
313  /*
314  * Now launch the tests.
315  */
316  for (i = 0 ; i < COUNT_OF(TestCases) ; ++i)
317  {
319  }
320 }
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:609
static void Test_CommandLine(IN ULONG TestNumber, IN PTEST_CASE TestCase)
Definition: CommandLine.c:114
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
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
smooth NULL
Definition: ftsmooth.c:416
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
#define COUNT_OF(x)
Definition: CommandLine.c:16
unsigned long DWORD
Definition: ntddk_ex.h:95
static TEST_CASE TestCases[]
Definition: CommandLine.c:101
static const WCHAR L[]
Definition: oid.c:1250
#define ok(value,...)
Definition: atltest.h:57
static WCHAR UtilityProgramDirectory[MAX_PATH]
Definition: CommandLine.c:92
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
unsigned int ULONG
Definition: retypes.h:1
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184

◆ Test_CommandLine()

static void Test_CommandLine ( IN ULONG  TestNumber,
IN PTEST_CASE  TestCase 
)
static

Definition at line 114 of file CommandLine.c.

116 {
117  BOOL bRet;
118 
119  BOOL bWasntInQuotes = (UtilityProgramDirectory[0] != L'"');
120  WCHAR CmdLine[MAX_PATH] = L"";
121  STARTUPINFOW si;
123 
124  ZeroMemory(&si, sizeof(si));
125  ZeroMemory(&pi, sizeof(pi));
126  si.cb = sizeof(si);
127 
128 
129  /* Initialize the command line. */
130  if (TestCase->bEncloseProgramNameInQuotes && bWasntInQuotes)
131  wcscpy(CmdLine, L"\"");
132 
134 
135  if (TestCase->bEncloseProgramNameInQuotes && bWasntInQuotes)
136  wcscat(CmdLine, L"\"");
137 
138  /* Add a separating space and copy the tested command line parameters. */
139  wcscat(CmdLine, L" ");
140  wcscat(CmdLine, TestCase->CmdLine);
141 
142 
143  /*
144  * Launch the utility program and wait till it's terminated.
145  */
146  bRet = CreateProcessW(NULL,
147  CmdLine,
148  NULL, NULL,
149  FALSE,
151  NULL, NULL,
152  &si, &pi);
153  ok(bRet, "Test %lu - Failed to launch ' %S ', error = %lu.\n", TestNumber, CmdLine, GetLastError());
154 
155  if (bRet)
156  {
157  /* Wait until child process exits. */
158  WaitForSingleObject(pi.hProcess, INFINITE);
159 
160  /* Close process and thread handles. */
161  CloseHandle(pi.hThread);
162  CloseHandle(pi.hProcess);
163  }
164 
165  /*
166  * Analyses the result.
167  */
168  {
169  /* Open the data file. */
171  GENERIC_READ,
172  0, NULL,
175  NULL);
176  ok(hFile != INVALID_HANDLE_VALUE, "Test %lu - Failed to open the data file 'C:\\cmdline.dat', error = %lu.\n", TestNumber, GetLastError());
177 
179  {
180  WCHAR BuffWinMain[MAX_PATH]; LPWSTR WinMainCmdLine = BuffWinMain;
181  WCHAR BuffWin32[MAX_PATH] ; LPWSTR Win32CmdLine = BuffWin32 ;
182  WCHAR BuffNT[0xffff /* Maximum USHORT size */];
183  UNICODE_STRING NTCmdLine;
184 
185  DWORD dwSize, dwStringSize;
186 
187  /*
188  * Format of the data file :
189  *
190  * [size_of_string 4 bytes][null_terminated_C_string]
191  * [size_of_string 4 bytes][null_terminated_C_string]
192  * [UNICODE_STRING_structure][string_buffer_of_UNICODE_STRING]
193  */
194 
195  /* 1- Read the WinMain's command line. */
196  dwStringSize = 0;
197 
198  ReadFile(hFile,
199  &dwStringSize,
200  sizeof(dwStringSize),
201  &dwSize,
202  NULL);
203 
204  dwStringSize = min(dwStringSize, sizeof(BuffWinMain));
205  ReadFile(hFile,
206  WinMainCmdLine,
207  dwStringSize,
208  &dwSize,
209  NULL);
210  *(LPWSTR)((ULONG_PTR)WinMainCmdLine + dwStringSize) = 0;
211 
212  /* 2- Read the Win32 mode command line. */
213  dwStringSize = 0;
214 
215  ReadFile(hFile,
216  &dwStringSize,
217  sizeof(dwStringSize),
218  &dwSize,
219  NULL);
220 
221  dwStringSize = min(dwStringSize, sizeof(BuffWin32));
222  ReadFile(hFile,
223  Win32CmdLine,
224  dwStringSize,
225  &dwSize,
226  NULL);
227  *(LPWSTR)((ULONG_PTR)Win32CmdLine + dwStringSize) = 0;
228 
229  /* 3- Finally, read the UNICODE_STRING command line. */
230  ReadFile(hFile,
231  &NTCmdLine,
232  sizeof(NTCmdLine),
233  &dwSize,
234  NULL);
235 
236  NTCmdLine.Buffer = BuffNT;
237  ReadFile(hFile,
238  NTCmdLine.Buffer,
239  NTCmdLine.Length,
240  &dwSize,
241  NULL);
242 
243  /* Now close the file. */
245 
246  /*
247  * Remove the program's name in the Win32 and NT command lines.
248  */
249  Win32CmdLine = ExtractCmdLine(Win32CmdLine);
250  ExtractCmdLine_U(&NTCmdLine);
251 
252  /* Print the results */
253  /*
254  *(LPWSTR)((ULONG_PTR)NTCmdLine.Buffer + NTCmdLine.Length) = 0;
255  printf("WinMain cmdline = '%S'\n"
256  "Win32 cmdline = '%S'\n"
257  "NT cmdline = '%S'\n"
258  "NT length = %u\n",
259  WinMainCmdLine,
260  Win32CmdLine,
261  NTCmdLine.Buffer, NTCmdLine.Length);
262  */
263 
264  /*
265  * Now check the results.
266  */
267  dwStringSize = min(wcslen(WinMainCmdLine), wcslen(Win32CmdLine));
268  ok(wcslen(WinMainCmdLine) == wcslen(Win32CmdLine), "Test %lu - WinMain and Win32 command lines do not have the same length !\n", TestNumber);
269  ok(wcsncmp(WinMainCmdLine, Win32CmdLine, dwStringSize) == 0, "Test %lu - WinMain and Win32 command lines are different !\n", TestNumber);
270 
271  dwStringSize = min(wcslen(WinMainCmdLine), NTCmdLine.Length / sizeof(WCHAR));
272  ok(wcsncmp(WinMainCmdLine, NTCmdLine.Buffer, dwStringSize) == 0, "Test %lu - WinMain and NT command lines are different !\n", TestNumber);
273 
274  dwStringSize = min(wcslen(Win32CmdLine), NTCmdLine.Length / sizeof(WCHAR));
275  ok(wcsncmp(Win32CmdLine, NTCmdLine.Buffer, dwStringSize) == 0, "Test %lu - Win32 and NT command lines are different !\n", TestNumber);
276  }
277  }
278 
279  /*
280  * Always delete the data file.
281  */
283 }
#define DATAFILE
Definition: CmdLineUtil.h:11
#define CloseHandle
Definition: compat.h:398
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:186
LPWSTR ExtractCmdLine(IN LPWSTR lpszCommandLine)
Definition: CommandLine.c:25
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
uint32_t ULONG_PTR
Definition: typedefs.h:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
smooth NULL
Definition: ftsmooth.c:416
VOID ExtractCmdLine_U(IN OUT PUNICODE_STRING pCommandLine_U)
Definition: CommandLine.c:52
#define OPEN_EXISTING
Definition: compat.h:426
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4593
DWORD cb
Definition: winbase.h:824
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
static DWORD pi
Definition: protocol.c:150
CHAR CmdLine[MAX_PATH]
Definition: mach.c:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
#define GENERIC_READ
Definition: compat.h:124
_In_ HANDLE hFile
Definition: mswsock.h:90
#define ok(value,...)
Definition: atltest.h:57
static WCHAR UtilityProgramDirectory[MAX_PATH]
Definition: CommandLine.c:92
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define min(a, b)
Definition: monoChain.cc:55
#define CreateFileW
Definition: compat.h:400
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define INFINITE
Definition: serial.h:102
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54

Referenced by START_TEST().

Variable Documentation

◆ TestCases

TEST_CASE TestCases[]
static
Initial value:
=
{
{L"", FALSE},
{L"foo bar", FALSE},
{L"\"foo bar\"", FALSE},
{L"foo \"bar John\" Doe", FALSE},
{L"", TRUE},
{L"foo bar", TRUE},
{L"\"foo bar\"", TRUE},
{L"foo \"bar John\" Doe", TRUE},
}
#define TRUE
Definition: types.h:120
static const WCHAR L[]
Definition: oid.c:1250

Definition at line 101 of file CommandLine.c.

Referenced by RunTestCases(), and START_TEST().

◆ UtilityProgramDirectory

WCHAR UtilityProgramDirectory[MAX_PATH]
static

Definition at line 92 of file CommandLine.c.

Referenced by START_TEST(), and Test_CommandLine().