mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
[CMD]
replace FILE IO with Memory IO functions for batch files Patch by HansH (hans at atbas dot org) See issue #5807 for more details. svn path=/trunk/; revision=52047
This commit is contained in:
parent
73f8eda071
commit
7c988c53c5
3 changed files with 136 additions and 39 deletions
|
@ -156,6 +156,22 @@ LPTSTR BatchParams (LPTSTR s1, LPTSTR s2)
|
|||
return dp;
|
||||
}
|
||||
|
||||
/*
|
||||
* free the allocated memory of a batch file
|
||||
*/
|
||||
VOID ClearBatch()
|
||||
{
|
||||
TRACE ("ClearBatch mem = %08x free = %d\n", bc->mem, bc->memfree);
|
||||
|
||||
if (bc->mem && bc->memfree)
|
||||
cmd_free(bc->mem);
|
||||
|
||||
if (bc->raw_params)
|
||||
cmd_free(bc->raw_params);
|
||||
|
||||
if (bc->params)
|
||||
cmd_free(bc->params);
|
||||
}
|
||||
|
||||
/*
|
||||
* If a batch file is current, exits it, freeing the context block and
|
||||
|
@ -169,20 +185,10 @@ LPTSTR BatchParams (LPTSTR s1, LPTSTR s2)
|
|||
|
||||
VOID ExitBatch()
|
||||
{
|
||||
ClearBatch();
|
||||
|
||||
TRACE ("ExitBatch\n");
|
||||
|
||||
if (bc->hBatchFile)
|
||||
{
|
||||
CloseHandle (bc->hBatchFile);
|
||||
bc->hBatchFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (bc->raw_params)
|
||||
cmd_free(bc->raw_params);
|
||||
|
||||
if (bc->params)
|
||||
cmd_free(bc->params);
|
||||
|
||||
UndoRedirection(bc->RedirList, NULL);
|
||||
FreeRedirection(bc->RedirList);
|
||||
|
||||
|
@ -195,6 +201,33 @@ VOID ExitBatch()
|
|||
bc = bc->prev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load batch file into memory
|
||||
*
|
||||
*/
|
||||
void BatchFile2Mem(HANDLE hBatchFile)
|
||||
{
|
||||
TRACE ("BatchFile2Mem ()\n");
|
||||
|
||||
bc->memsize = GetFileSize(hBatchFile, NULL);
|
||||
bc->mem = (char *)cmd_alloc(bc->memsize+1); /* 1 extra for '\0' */
|
||||
|
||||
/* if memory is available, read it in and close the file */
|
||||
if (bc->mem != NULL)
|
||||
{
|
||||
TRACE ("BatchFile2Mem memory %08x - %08x\n",bc->mem,bc->memsize);
|
||||
SetFilePointer (hBatchFile, 0, NULL, FILE_BEGIN);
|
||||
ReadFile(hBatchFile, (LPVOID)bc->mem, bc->memsize, &bc->memsize, NULL);
|
||||
bc->mem[bc->memsize]='\0'; /* end this, so you can dump it as a string */
|
||||
bc->memfree=TRUE; /* this one needs to be freed */
|
||||
}
|
||||
else
|
||||
{
|
||||
bc->memsize=0; /* this will prevent mem being accessed */
|
||||
bc->memfree=FALSE;
|
||||
}
|
||||
bc->mempos = 0; /* set position to the start */
|
||||
}
|
||||
|
||||
/*
|
||||
* Start batch file execution
|
||||
|
@ -209,31 +242,37 @@ INT Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
|
|||
LPFOR_CONTEXT saved_fc;
|
||||
INT i;
|
||||
INT ret = 0;
|
||||
BOOL same_fn = FALSE;
|
||||
|
||||
HANDLE hFile;
|
||||
HANDLE hFile = 0;
|
||||
SetLastError(0);
|
||||
hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
|
||||
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
|
||||
TRACE ("Batch: (\'%s\', \'%s\', \'%s\') hFile = %x\n",
|
||||
debugstr_aw(fullname), debugstr_aw(firstword), debugstr_aw(param), hFile);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
if (bc && bc->mem)
|
||||
{
|
||||
ConErrResPuts(STRING_BATCH_ERROR);
|
||||
return 1;
|
||||
TCHAR fpname[MAX_PATH];
|
||||
GetFullPathName(fullname, sizeof(fpname) / sizeof(TCHAR), fpname, NULL);
|
||||
if (_tcsicmp(bc->BatchFilePath,fpname)==0)
|
||||
same_fn=TRUE;
|
||||
}
|
||||
TRACE ("Batch: (\'%s\', \'%s\', \'%s\') same_fn = %d\n",
|
||||
debugstr_aw(fullname), debugstr_aw(firstword), debugstr_aw(param), same_fn);
|
||||
|
||||
if (!same_fn)
|
||||
{
|
||||
hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
|
||||
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ConErrResPuts(STRING_BATCH_ERROR);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (bc != NULL && Cmd == bc->current)
|
||||
{
|
||||
/* Then we are transferring to another batch */
|
||||
CloseHandle (bc->hBatchFile);
|
||||
bc->hBatchFile = INVALID_HANDLE_VALUE;
|
||||
if (bc->params)
|
||||
cmd_free (bc->params);
|
||||
if (bc->raw_params)
|
||||
cmd_free (bc->raw_params);
|
||||
ClearBatch();
|
||||
AddBatchRedirection(&Cmd->Redirections);
|
||||
}
|
||||
else
|
||||
|
@ -261,15 +300,27 @@ INT Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
|
|||
/* Create a new context. This function will not
|
||||
* return until this context has been exited */
|
||||
new.prev = bc;
|
||||
/* copy some fields in the new structure if it is the same file */
|
||||
if (same_fn) {
|
||||
new.mem = bc->mem;
|
||||
new.memsize = bc->memsize;
|
||||
new.mempos = 0;
|
||||
new.memfree = FALSE; /* don't free this, being used before this */
|
||||
}
|
||||
bc = &new;
|
||||
bc->RedirList = NULL;
|
||||
bc->setlocal = setlocal;
|
||||
}
|
||||
|
||||
GetFullPathName(fullname, sizeof(bc->BatchFilePath) / sizeof(TCHAR), bc->BatchFilePath, NULL);
|
||||
|
||||
bc->hBatchFile = hFile;
|
||||
SetFilePointer (bc->hBatchFile, 0, NULL, FILE_BEGIN);
|
||||
/* if a new batch file, load it into memory and close the file */
|
||||
if (!same_fn)
|
||||
{
|
||||
BatchFile2Mem(hFile);
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
bc->mempos = 0; /* goto begin of batch file */
|
||||
bc->bEcho = bEcho; /* Preserve echo across batch calls */
|
||||
for (i = 0; i < 10; i++)
|
||||
bc->shiftlevel[i] = i;
|
||||
|
@ -339,6 +390,49 @@ VOID AddBatchRedirection(REDIRECTION **RedirList)
|
|||
*RedirList = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a single line from the batch file from the current batch/memory position.
|
||||
* Almost a copy of FileGetString with same UNICODE handling
|
||||
*/
|
||||
BOOL BatchGetString (LPTSTR lpBuffer, INT nBufferLength)
|
||||
{
|
||||
LPSTR lpString;
|
||||
INT len = 0;
|
||||
#ifdef _UNICODE
|
||||
lpString = cmd_alloc(nBufferLength);
|
||||
#else
|
||||
lpString = lpBuffer;
|
||||
#endif
|
||||
/* read all chars from memory until a '\n' is encountered */
|
||||
if (bc->mem)
|
||||
{
|
||||
for (; (bc->mempos < bc->memsize && len < (nBufferLength-1)); len++)
|
||||
{
|
||||
lpString[len] = bc->mem[bc->mempos++];
|
||||
if (lpString[len] == '\n' )
|
||||
{
|
||||
len++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!len)
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
cmd_free(lpString);
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lpString[len++] = '\0';
|
||||
#ifdef _UNICODE
|
||||
MultiByteToWideChar(OutputCodePage, 0, lpString, -1, lpBuffer, len);
|
||||
cmd_free(lpString);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read and return the next executable line form the current batch file
|
||||
*
|
||||
|
@ -347,7 +441,6 @@ VOID AddBatchRedirection(REDIRECTION **RedirList)
|
|||
*
|
||||
* Set eflag to 0 if line is not to be echoed else 1
|
||||
*/
|
||||
|
||||
LPTSTR ReadBatchLine ()
|
||||
{
|
||||
TRACE ("ReadBatchLine ()\n");
|
||||
|
@ -360,7 +453,7 @@ LPTSTR ReadBatchLine ()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!FileGetString (bc->hBatchFile, textline, sizeof (textline) / sizeof (textline[0]) - 1))
|
||||
if (!BatchGetString (textline, sizeof (textline) / sizeof (textline[0]) - 1))
|
||||
{
|
||||
TRACE ("ReadBatchLine(): Reached EOF!\n");
|
||||
/* End of file.... */
|
||||
|
|
|
@ -9,7 +9,10 @@
|
|||
typedef struct tagBATCHCONTEXT
|
||||
{
|
||||
struct tagBATCHCONTEXT *prev;
|
||||
HANDLE hBatchFile;
|
||||
char *mem; /* batchfile content in memory */
|
||||
DWORD memsize; /* size of batchfile */
|
||||
DWORD mempos; /* current position to read from */
|
||||
BOOL memfree; /* true if it need to be freed when exitbatch is called */
|
||||
TCHAR BatchFilePath[MAX_PATH];
|
||||
LPTSTR params;
|
||||
LPTSTR raw_params; /* Holds the raw params given by the input */
|
||||
|
@ -47,5 +50,6 @@ LPTSTR FindArg (TCHAR, BOOL *);
|
|||
LPTSTR BatchParams (LPTSTR, LPTSTR);
|
||||
VOID ExitBatch (VOID);
|
||||
INT Batch (LPTSTR, LPTSTR, LPTSTR, PARSED_COMMAND *);
|
||||
BOOL BatchGetString (LPTSTR lpBuffer, INT nBufferLength);
|
||||
LPTSTR ReadBatchLine(VOID);
|
||||
VOID AddBatchRedirection(REDIRECTION **);
|
||||
VOID AddBatchRedirection(REDIRECTION **);
|
||||
|
|
|
@ -74,14 +74,14 @@ INT cmd_goto (LPTSTR param)
|
|||
/* jump to end of the file */
|
||||
if ( _tcsicmp( param, _T(":eof"))==0)
|
||||
{
|
||||
SetFilePointer (bc->hBatchFile, 0, &lNewPosHigh, FILE_END);
|
||||
bc->mempos=bc->memsize; /* position at the end of the batchfile */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* jump to begin of the file */
|
||||
SetFilePointer (bc->hBatchFile, 0, &lNewPosHigh, FILE_BEGIN);
|
||||
bc->mempos=0;
|
||||
|
||||
while (FileGetString (bc->hBatchFile, textline, sizeof(textline) / sizeof(textline[0])))
|
||||
while (BatchGetString (textline, sizeof(textline) / sizeof(textline[0])))
|
||||
{
|
||||
int pos;
|
||||
int size;
|
||||
|
|
Loading…
Reference in a new issue