ReactOS 0.4.15-dev-7953-g1f49173
cmd.c File Reference
#include "precomp.h"
Include dependency graph for cmd.c:

Go to the source code of this file.

Classes

struct  TEST_ENTRY
 

Macros

#define TIMEOUT   3000
 

Typedefs

typedef struct TEST_ENTRY TEST_ENTRY
 

Functions

static BOOL MyDuplicateHandle (HANDLE hFile, PHANDLE phFile, BOOL bInherit)
 
static BOOL PrepareForRedirect (STARTUPINFOA *psi, PHANDLE phInputWrite, PHANDLE phOutputRead, PHANDLE phErrorRead)
 
static void DoTestEntry (const TEST_ENTRY *pEntry)
 
 START_TEST (exit)
 
 START_TEST (echo)
 
 START_TEST (cd)
 
 START_TEST (pushd)
 
 START_TEST (attrib)
 

Variables

static const TEST_ENTRY s_exit_entries []
 
static const TEST_ENTRY s_echo_entries []
 
static const TEST_ENTRY s_cd_entries []
 
static const TEST_ENTRY s_pushd_entries []
 
static const TEST_ENTRY s_attrib_entries []
 

Macro Definition Documentation

◆ TIMEOUT

#define TIMEOUT   3000

Definition at line 10 of file cmd.c.

Typedef Documentation

◆ TEST_ENTRY

Function Documentation

◆ DoTestEntry()

static void DoTestEntry ( const TEST_ENTRY pEntry)
static

Definition at line 403 of file cmd.c.

404{
405 STARTUPINFOA si;
407 DWORD dwExitCode, dwWait;
408 HANDLE hOutputRead = NULL;
409 HANDLE hErrorRead = NULL;
410 DWORD dwRead;
411 BOOL bStdOutput, bStdError;
412 CHAR szOut[512], szErr[512];
413
414 memset(&si, 0, sizeof(si));
415 si.cb = sizeof(si);
417
418 if (!PrepareForRedirect(&si, NULL, &hOutputRead, &hErrorRead))
419 {
420 skip("PrepareForRedirect failed\n");
421 return;
422 }
423
424 if (CreateProcessA(NULL, (char *)pEntry->cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
425 {
427 dwWait = WaitForSingleObject(pi.hProcess, TIMEOUT);
428 if (dwWait == WAIT_TIMEOUT)
429 {
430 TerminateProcess(pi.hProcess, 9999);
431 }
432 GetExitCodeProcess(pi.hProcess, &dwExitCode);
433 CloseHandle(pi.hThread);
434 CloseHandle(pi.hProcess);
435 }
436 else
437 {
438 dwExitCode = 8888;
439 }
440
441 ZeroMemory(szOut, sizeof(szOut));
442 PeekNamedPipe(hOutputRead, szOut, ARRAYSIZE(szOut), &dwRead, NULL, NULL);
443 szOut[ARRAYSIZE(szOut) - 1] = 0;
444 bStdOutput = dwRead != 0;
445
446 ZeroMemory(szErr, sizeof(szErr));
447 PeekNamedPipe(hErrorRead, szErr, ARRAYSIZE(szErr), &dwRead, NULL, NULL);
448 szErr[ARRAYSIZE(szErr) - 1] = 0;
449 bStdError = dwRead != 0;
450
451 if (si.hStdInput)
453 if (si.hStdOutput)
455 if (si.hStdError)
457
458 ok(pEntry->bStdOutput == bStdOutput,
459 "Line %u: bStdOutput %d vs %d\n",
460 pEntry->line, pEntry->bStdOutput, bStdOutput);
461
462 ok(pEntry->bStdError == bStdError,
463 "Line %u: bStdError %d vs %d\n",
464 pEntry->line, pEntry->bStdError, bStdError);
465
466 ok(pEntry->dwExitCode == dwExitCode,
467 "Line %u: dwExitCode %ld vs %ld\n",
468 pEntry->line, pEntry->dwExitCode, dwExitCode);
469
470 if (pEntry->OutputContains)
471 {
472 ok(strstr(szOut, pEntry->OutputContains) != NULL,
473 "Line %u: szOut was '%s'\n",
474 pEntry->line, szOut);
475 }
476
477 if (pEntry->ErrorContains)
478 {
479 ok(strstr(szErr, pEntry->ErrorContains) != NULL,
480 "Line %u: szErr was '%s'\n",
481 pEntry->line, szErr);
482 }
483
484 if (pEntry->OutputNotContains)
485 {
486 ok(strstr(szOut, pEntry->OutputNotContains) == NULL,
487 "Line %u: szOut was '%s'\n",
488 pEntry->line, szOut);
489 }
490
491 if (pEntry->ErrorNotContains)
492 {
493 ok(strstr(szErr, pEntry->ErrorNotContains) == NULL,
494 "Line %u: szErr was '%s'\n",
495 pEntry->line, szErr);
496 }
497}
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
TCHAR szErr[256]
Definition: service.c:38
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CloseHandle
Definition: compat.h:739
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4741
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
static BOOL PrepareForRedirect(STARTUPINFOA *psi, PHANDLE phInputWrite, PHANDLE phOutputRead, PHANDLE phErrorRead)
Definition: cmd.c:329
#define TIMEOUT
Definition: cmd.c:10
static refpint_t pi[]
Definition: server.c:96
BOOL WINAPI PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
Definition: npipe.c:1214
#define memset(x, y, z)
Definition: compat.h:39
HANDLE hStdOutput
Definition: winbase.h:847
HANDLE hStdError
Definition: winbase.h:848
DWORD dwFlags
Definition: winbase.h:842
DWORD cb
Definition: winbase.h:831
HANDLE hStdInput
Definition: winbase.h:846
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define ZeroMemory
Definition: winbase.h:1712
#define STARTF_USESTDHANDLES
Definition: winbase.h:499
char CHAR
Definition: xmlstorage.h:175

Referenced by START_TEST().

◆ MyDuplicateHandle()

static BOOL MyDuplicateHandle ( HANDLE  hFile,
PHANDLE  phFile,
BOOL  bInherit 
)
static

Definition at line 322 of file cmd.c.

323{
325 return DuplicateHandle(hProcess, hFile, hProcess, phFile, 0,
326 bInherit, DUPLICATE_SAME_ACCESS);
327}
#define GetCurrentProcess()
Definition: compat.h:759
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
_In_ HANDLE hFile
Definition: mswsock.h:90
#define DUPLICATE_SAME_ACCESS

Referenced by PrepareForRedirect().

◆ PrepareForRedirect()

static BOOL PrepareForRedirect ( STARTUPINFOA psi,
PHANDLE  phInputWrite,
PHANDLE  phOutputRead,
PHANDLE  phErrorRead 
)
static

Definition at line 329 of file cmd.c.

331{
332 HANDLE hInputRead = NULL, hInputWriteTmp = NULL;
333 HANDLE hOutputReadTmp = NULL, hOutputWrite = NULL;
334 HANDLE hErrorReadTmp = NULL, hErrorWrite = NULL;
335 SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
336
337 psi->hStdInput = NULL;
338 psi->hStdOutput = NULL;
339 psi->hStdError = NULL;
340
341 if (phInputWrite)
342 {
343 if (CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0))
344 {
345 if (!MyDuplicateHandle(hInputWriteTmp, phInputWrite, FALSE))
346 goto failed;
347
348 CloseHandle(hInputWriteTmp);
349 }
350 else
351 goto failed;
352 }
353
354 if (phOutputRead)
355 {
356 if (CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0))
357 {
358 if (!MyDuplicateHandle(hOutputReadTmp, phOutputRead, FALSE))
359 goto failed;
360
361 CloseHandle(hOutputReadTmp);
362 }
363 else
364 goto failed;
365 }
366
367 if (phOutputRead && phOutputRead == phErrorRead)
368 {
369 if (!MyDuplicateHandle(hOutputWrite, &hErrorWrite, TRUE))
370 goto failed;
371 }
372 else if (phErrorRead)
373 {
374 if (CreatePipe(&hErrorReadTmp, &hErrorWrite, &sa, 0))
375 {
376 if (!MyDuplicateHandle(hErrorReadTmp, phErrorRead, FALSE))
377 goto failed;
378 CloseHandle(hErrorReadTmp);
379 }
380 else
381 goto failed;
382 }
383
384 if (phInputWrite)
385 psi->hStdInput = hInputRead;
386 if (phOutputRead)
387 psi->hStdOutput = hOutputWrite;
388 if (phErrorRead)
389 psi->hStdError = hErrorWrite;
390
391 return TRUE;
392
393failed:
394 CloseHandle(hInputRead);
395 CloseHandle(hInputWriteTmp);
396 CloseHandle(hOutputReadTmp);
397 CloseHandle(hOutputWrite);
398 CloseHandle(hErrorReadTmp);
399 CloseHandle(hErrorWrite);
400 return FALSE;
401}
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
#define FALSE
Definition: types.h:117
static BOOL MyDuplicateHandle(HANDLE hFile, PHANDLE phFile, BOOL bInherit)
Definition: cmd.c:322
BOOL WINAPI CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
Definition: npipe.c:117

Referenced by DoTestEntry().

◆ START_TEST() [1/5]

START_TEST ( attrib  )

Definition at line 535 of file cmd.c.

536{
537 SIZE_T i;
538 for (i = 0; i < ARRAYSIZE(s_attrib_entries); ++i)
539 {
541 }
542}
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
static const TEST_ENTRY s_attrib_entries[]
Definition: cmd.c:127
static void DoTestEntry(const TEST_ENTRY *pEntry)
Definition: cmd.c:403
ULONG_PTR SIZE_T
Definition: typedefs.h:80

◆ START_TEST() [2/5]

START_TEST ( cd  )

Definition at line 517 of file cmd.c.

518{
519 SIZE_T i;
520 for (i = 0; i < ARRAYSIZE(s_cd_entries); ++i)
521 {
523 }
524}
static const TEST_ENTRY s_cd_entries[]
Definition: cmd.c:43

◆ START_TEST() [3/5]

START_TEST ( echo  )

Definition at line 508 of file cmd.c.

509{
510 SIZE_T i;
511 for (i = 0; i < ARRAYSIZE(s_echo_entries); ++i)
512 {
514 }
515}
static const TEST_ENTRY s_echo_entries[]
Definition: cmd.c:36

◆ START_TEST() [4/5]

START_TEST ( exit  )

Definition at line 499 of file cmd.c.

500{
501 SIZE_T i;
502 for (i = 0; i < ARRAYSIZE(s_exit_entries); ++i)
503 {
505 }
506}
static const TEST_ENTRY s_exit_entries[]
Definition: cmd.c:25

◆ START_TEST() [5/5]

START_TEST ( pushd  )

Definition at line 526 of file cmd.c.

527{
528 SIZE_T i;
529 for (i = 0; i < ARRAYSIZE(s_pushd_entries); ++i)
530 {
532 }
533}
static const TEST_ENTRY s_pushd_entries[]
Definition: cmd.c:56

Variable Documentation

◆ s_attrib_entries

const TEST_ENTRY s_attrib_entries[]
static

Definition at line 127 of file cmd.c.

Referenced by START_TEST().

◆ s_cd_entries

const TEST_ENTRY s_cd_entries[]
static
Initial value:
=
{
{ __LINE__, 0, "cmd /c cd \"C:\\ " },
{ __LINE__, 0, "cmd /c cd C:/" },
{ __LINE__, 0, "cmd /c cd \"\"", TRUE, FALSE },
{ __LINE__, 0, "cmd /c cd", TRUE, FALSE },
{ __LINE__, 1234, "cmd /c cd C:\\Program Files && exit 1234" },
{ __LINE__, 1234, "cmd /c cd \"C:\\ \" && exit 1234" },
{ __LINE__, 1234, "cmd /c cd \"C:\\Program Files\" && exit 1234" },
{ __LINE__, 1234, "cmd /c cd \"\" && exit 1234", TRUE, FALSE },
{ __LINE__, 1234, "cmd /c cd \\ && exit 1234" },
}

Definition at line 43 of file cmd.c.

Referenced by START_TEST().

◆ s_echo_entries

const TEST_ENTRY s_echo_entries[]
static
Initial value:
=
{
{ __LINE__, 0, "cmd /c echo.", TRUE, FALSE, "\r\n" },
{ __LINE__, 0, "cmd /c echo ABC", TRUE, FALSE, "ABC\r\n" },
}

Definition at line 36 of file cmd.c.

Referenced by START_TEST().

◆ s_exit_entries

const TEST_ENTRY s_exit_entries[]
static
Initial value:
=
{
{ __LINE__, 0, "cmd /c exit" },
{ __LINE__, 0, "cmd /c exit 0" },
{ __LINE__, 0, "cmd /c exit \"\"" },
{ __LINE__, 0, "cmd /c exit ABC" },
{ __LINE__, 0, "cmd /c exit \"ABC" },
{ __LINE__, 0, "cmd /c exit \"ABC\"" },
{ __LINE__, 1234, "cmd /c exit 1234" },
}

Definition at line 25 of file cmd.c.

Referenced by START_TEST().

◆ s_pushd_entries

const TEST_ENTRY s_pushd_entries[]
static

Definition at line 56 of file cmd.c.

Referenced by START_TEST().