Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165/* * REDIR.C - redirection handling. * * * History: * * 12/15/95 (Tim Norman) * started. * * 12 Jul 98 (Hans B Pufal) * Rewrote to make more efficient and to conform to new command.c * and batch.c processing. * * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>) * Added config.h include * * 22-Jan-1999 (Eric Kohl) * Unicode safe! * Added new error redirection "2>" and "2>>". * * 26-Jan-1999 (Eric Kohl) * Added new error AND output redirection "&>" and "&>>". * * 24-Jun-2005 (Brandon Turner <turnerb7@msu.edu>) * simple check to fix > and | bug with 'rem' */
#include "precomp.h"
#ifdef FEATURE_REDIRECTION
/* * CMD allows redirection of handles numbered 3-9 even though * these don't correspond to any STD_ constant. */static const PCON_STREAM StdStreams[] = { StdIn, StdOut, StdErr };static HANDLE ExtraHandles[10 - 3]; // 3 == ARRAYSIZE(StdStreams)
HANDLE GetHandle(UINT Number){ if (Number < 3) return ConStreamGetOSHandle(StdStreams[Number]); // return GetStdHandle(STD_INPUT_HANDLE - Number); else if (Number < ARRAYSIZE(ExtraHandles) + 3) return ExtraHandles[Number - 3]; else return INVALID_HANDLE_VALUE;}
VOID SetHandle(UINT Number, HANDLE Handle){ if (Number < 3) { ConStreamSetOSHandle(StdStreams[Number], Handle); /* Synchronize the associated Win32 handle */ SetStdHandle(STD_INPUT_HANDLE - Number, Handle); } else if (Number < ARRAYSIZE(ExtraHandles) + 3) ExtraHandles[Number - 3] = Handle;}
BOOLPerformRedirection(REDIRECTION *RedirList){ REDIRECTION *Redir; LPTSTR Filename; HANDLE hNew; UINT DupNumber;
static SECURITY_ATTRIBUTES SecAttr = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
/* Some parameters used for read, write, and append, respectively */ static struct REDIR_PARAMS { DWORD dwDesiredAccess; DWORD dwShareMode; DWORD dwCreationDisposition; } RedirParams[] = { {GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING}, // REDIR_READ {GENERIC_WRITE, FILE_SHARE_READ , CREATE_ALWAYS}, // REDIR_WRITE {GENERIC_WRITE, FILE_SHARE_READ , OPEN_ALWAYS } // REDIR_APPEND };
for (Redir = RedirList; Redir; Redir = Redir->Next) { Filename = DoDelayedExpansion(Redir->Filename); if (!Filename) goto redir_error; StripQuotes(Filename);
if (*Filename == _T('&')) { DupNumber = Filename[1] - _T('0'); if (DupNumber >= 10 || !DuplicateHandle(GetCurrentProcess(), GetHandle(DupNumber), GetCurrentProcess(), &hNew, 0, TRUE, DUPLICATE_SAME_ACCESS)) { hNew = INVALID_HANDLE_VALUE; } } else { hNew = CreateFile(Filename, RedirParams[Redir->Mode].dwDesiredAccess, RedirParams[Redir->Mode].dwShareMode, &SecAttr, RedirParams[Redir->Mode].dwCreationDisposition, 0, NULL); }
if (hNew == INVALID_HANDLE_VALUE) { /* TODO: Print a more detailed message */ ConErrResPrintf(Redir->Mode == REDIR_READ ? STRING_CMD_ERROR1 : STRING_CMD_ERROR3, Filename); cmd_free(Filename);redir_error: /* Undo all the redirections before this one */ UndoRedirection(RedirList, Redir); return FALSE; }
if (Redir->Mode == REDIR_APPEND) SetFilePointer(hNew, 0, NULL, FILE_END); Redir->OldHandle = GetHandle(Redir->Number); SetHandle(Redir->Number, hNew);
TRACE("%d redirected to: %s\n", Redir->Number, debugstr_aw(Filename)); cmd_free(Filename); } return TRUE;}
VOIDUndoRedirection(REDIRECTION *Redir, REDIRECTION *End){ for (; Redir != End; Redir = Redir->Next) { CloseHandle(GetHandle(Redir->Number)); SetHandle(Redir->Number, Redir->OldHandle); Redir->OldHandle = INVALID_HANDLE_VALUE; }}
VOIDFreeRedirection(REDIRECTION *Redir){ REDIRECTION *Next; for (; Redir; Redir = Next) { Next = Redir->Next; ASSERT(Redir->OldHandle == INVALID_HANDLE_VALUE); cmd_free(Redir); }}
#endif /* FEATURE_REDIRECTION */