ReactOS 0.4.16-dev-1946-g52006dd
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
 
#define TRISTATE   2
 

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.

◆ TRISTATE

#define TRISTATE   2

Definition at line 25 of file cmd.c.

Typedef Documentation

◆ TEST_ENTRY

Function Documentation

◆ DoTestEntry()

static void DoTestEntry ( const TEST_ENTRY pEntry)
static

Definition at line 405 of file cmd.c.

406{
407 STARTUPINFOA si;
409 DWORD dwExitCode, dwWait;
410 HANDLE hOutputRead = NULL;
411 HANDLE hErrorRead = NULL;
412 DWORD dwRead;
413 BOOL bStdOutput, bStdError;
414 CHAR szOut[512], szErr[512];
415
416 memset(&si, 0, sizeof(si));
417 si.cb = sizeof(si);
419
420 if (!PrepareForRedirect(&si, NULL, &hOutputRead, &hErrorRead))
421 {
422 skip("PrepareForRedirect failed\n");
423 return;
424 }
425
426 if (CreateProcessA(NULL, (char *)pEntry->cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
427 {
429 dwWait = WaitForSingleObject(pi.hProcess, TIMEOUT);
430 if (dwWait == WAIT_TIMEOUT)
431 {
432 TerminateProcess(pi.hProcess, 9999);
433 }
434 GetExitCodeProcess(pi.hProcess, &dwExitCode);
435 CloseHandle(pi.hThread);
436 CloseHandle(pi.hProcess);
437 }
438 else
439 {
440 dwExitCode = 8888;
441 }
442
443 ZeroMemory(szOut, sizeof(szOut));
444 PeekNamedPipe(hOutputRead, szOut, ARRAYSIZE(szOut), &dwRead, NULL, NULL);
445 szOut[ARRAYSIZE(szOut) - 1] = 0;
446 bStdOutput = dwRead != 0;
447
448 ZeroMemory(szErr, sizeof(szErr));
449 PeekNamedPipe(hErrorRead, szErr, ARRAYSIZE(szErr), &dwRead, NULL, NULL);
450 szErr[ARRAYSIZE(szErr) - 1] = 0;
451 bStdError = dwRead != 0;
452
453 if (si.hStdInput)
455 if (si.hStdOutput)
457 if (si.hStdError)
459
460 ok(pEntry->bStdOutput == bStdOutput || pEntry->bStdOutput == TRISTATE,
461 "Line %u: bStdOutput %d vs %d\n",
462 pEntry->line, pEntry->bStdOutput, bStdOutput);
463
464 ok(pEntry->bStdError == bStdError || pEntry->bStdOutput == TRISTATE,
465 "Line %u: bStdError %d vs %d\n",
466 pEntry->line, pEntry->bStdError, bStdError);
467
468 ok(pEntry->dwExitCode == dwExitCode,
469 "Line %u: dwExitCode %ld vs %ld\n",
470 pEntry->line, pEntry->dwExitCode, dwExitCode);
471
472 if (pEntry->OutputContains)
473 {
474 ok(strstr(szOut, pEntry->OutputContains) != NULL,
475 "Line %u: szOut was '%s'\n",
476 pEntry->line, szOut);
477 }
478
479 if (pEntry->ErrorContains)
480 {
481 ok(strstr(szErr, pEntry->ErrorContains) != NULL,
482 "Line %u: szErr was '%s'\n",
483 pEntry->line, szErr);
484 }
485
486 if (pEntry->OutputNotContains)
487 {
488 ok(strstr(szOut, pEntry->OutputNotContains) == NULL,
489 "Line %u: szOut was '%s'\n",
490 pEntry->line, szOut);
491 }
492
493 if (pEntry->ErrorNotContains)
494 {
495 ok(strstr(szErr, pEntry->ErrorNotContains) == NULL,
496 "Line %u: szErr was '%s'\n",
497 pEntry->line, szErr);
498 }
499}
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:4749
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1534
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
#define ZeroMemory
Definition: minwinbase.h:31
static BOOL PrepareForRedirect(STARTUPINFOA *psi, PHANDLE phInputWrite, PHANDLE phOutputRead, PHANDLE phErrorRead)
Definition: cmd.c:331
#define TIMEOUT
Definition: cmd.c:10
static refpint_t pi[]
Definition: server.c:112
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
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define STARTF_USESTDHANDLES
Definition: winbase.h:476
char CHAR
Definition: xmlstorage.h:175

Referenced by START_TEST().

◆ MyDuplicateHandle()

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

Definition at line 324 of file cmd.c.

325{
327 return DuplicateHandle(hProcess, hFile, hProcess, phFile, 0,
328 bInherit, DUPLICATE_SAME_ACCESS);
329}
#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 331 of file cmd.c.

333{
334 HANDLE hInputRead = NULL, hInputWriteTmp = NULL;
335 HANDLE hOutputReadTmp = NULL, hOutputWrite = NULL;
336 HANDLE hErrorReadTmp = NULL, hErrorWrite = NULL;
337 SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
338
339 psi->hStdInput = NULL;
340 psi->hStdOutput = NULL;
341 psi->hStdError = NULL;
342
343 if (phInputWrite)
344 {
345 if (CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0))
346 {
347 if (!MyDuplicateHandle(hInputWriteTmp, phInputWrite, FALSE))
348 goto failed;
349
350 CloseHandle(hInputWriteTmp);
351 }
352 else
353 goto failed;
354 }
355
356 if (phOutputRead)
357 {
358 if (CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0))
359 {
360 if (!MyDuplicateHandle(hOutputReadTmp, phOutputRead, FALSE))
361 goto failed;
362
363 CloseHandle(hOutputReadTmp);
364 }
365 else
366 goto failed;
367 }
368
369 if (phOutputRead && phOutputRead == phErrorRead)
370 {
371 if (!MyDuplicateHandle(hOutputWrite, &hErrorWrite, TRUE))
372 goto failed;
373 }
374 else if (phErrorRead)
375 {
376 if (CreatePipe(&hErrorReadTmp, &hErrorWrite, &sa, 0))
377 {
378 if (!MyDuplicateHandle(hErrorReadTmp, phErrorRead, FALSE))
379 goto failed;
380 CloseHandle(hErrorReadTmp);
381 }
382 else
383 goto failed;
384 }
385
386 if (phInputWrite)
387 psi->hStdInput = hInputRead;
388 if (phOutputRead)
389 psi->hStdOutput = hOutputWrite;
390 if (phErrorRead)
391 psi->hStdError = hErrorWrite;
392
393 return TRUE;
394
395failed:
396 CloseHandle(hInputRead);
397 CloseHandle(hInputWriteTmp);
398 CloseHandle(hOutputReadTmp);
399 CloseHandle(hOutputWrite);
400 CloseHandle(hErrorReadTmp);
401 CloseHandle(hErrorWrite);
402 return FALSE;
403}
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:324
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 537 of file cmd.c.

538{
539 SIZE_T i;
540 for (i = 0; i < ARRAYSIZE(s_attrib_entries); ++i)
541 {
543 }
544}
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:129
static void DoTestEntry(const TEST_ENTRY *pEntry)
Definition: cmd.c:405
ULONG_PTR SIZE_T
Definition: typedefs.h:80

◆ START_TEST() [2/5]

START_TEST ( cd  )

Definition at line 519 of file cmd.c.

520{
521 SIZE_T i;
522 for (i = 0; i < ARRAYSIZE(s_cd_entries); ++i)
523 {
525 }
526}
static const TEST_ENTRY s_cd_entries[]
Definition: cmd.c:45

◆ START_TEST() [3/5]

START_TEST ( echo  )

Definition at line 510 of file cmd.c.

511{
512 SIZE_T i;
513 for (i = 0; i < ARRAYSIZE(s_echo_entries); ++i)
514 {
516 }
517}
static const TEST_ENTRY s_echo_entries[]
Definition: cmd.c:38

◆ START_TEST() [4/5]

START_TEST ( exit  )

Definition at line 501 of file cmd.c.

502{
503 SIZE_T i;
504 for (i = 0; i < ARRAYSIZE(s_exit_entries); ++i)
505 {
507 }
508}
static const TEST_ENTRY s_exit_entries[]
Definition: cmd.c:27

◆ START_TEST() [5/5]

START_TEST ( pushd  )

Definition at line 528 of file cmd.c.

529{
530 SIZE_T i;
531 for (i = 0; i < ARRAYSIZE(s_pushd_entries); ++i)
532 {
534 }
535}
static const TEST_ENTRY s_pushd_entries[]
Definition: cmd.c:58

Variable Documentation

◆ s_attrib_entries

const TEST_ENTRY s_attrib_entries[]
static

Definition at line 129 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 45 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 38 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 27 of file cmd.c.

Referenced by START_TEST().

◆ s_pushd_entries

const TEST_ENTRY s_pushd_entries[]
static

Definition at line 58 of file cmd.c.

Referenced by START_TEST().