mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 23:03:00 +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;
|
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
|
* 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()
|
VOID ExitBatch()
|
||||||
{
|
{
|
||||||
|
ClearBatch();
|
||||||
|
|
||||||
TRACE ("ExitBatch\n");
|
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);
|
UndoRedirection(bc->RedirList, NULL);
|
||||||
FreeRedirection(bc->RedirList);
|
FreeRedirection(bc->RedirList);
|
||||||
|
|
||||||
|
@ -195,6 +201,33 @@ VOID ExitBatch()
|
||||||
bc = bc->prev;
|
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
|
* Start batch file execution
|
||||||
|
@ -209,31 +242,37 @@ INT Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
|
||||||
LPFOR_CONTEXT saved_fc;
|
LPFOR_CONTEXT saved_fc;
|
||||||
INT i;
|
INT i;
|
||||||
INT ret = 0;
|
INT ret = 0;
|
||||||
|
BOOL same_fn = FALSE;
|
||||||
|
|
||||||
HANDLE hFile;
|
HANDLE hFile = 0;
|
||||||
SetLastError(0);
|
SetLastError(0);
|
||||||
hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL,
|
if (bc && bc->mem)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
ConErrResPuts(STRING_BATCH_ERROR);
|
TCHAR fpname[MAX_PATH];
|
||||||
return 1;
|
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)
|
if (bc != NULL && Cmd == bc->current)
|
||||||
{
|
{
|
||||||
/* Then we are transferring to another batch */
|
/* Then we are transferring to another batch */
|
||||||
CloseHandle (bc->hBatchFile);
|
ClearBatch();
|
||||||
bc->hBatchFile = INVALID_HANDLE_VALUE;
|
|
||||||
if (bc->params)
|
|
||||||
cmd_free (bc->params);
|
|
||||||
if (bc->raw_params)
|
|
||||||
cmd_free (bc->raw_params);
|
|
||||||
AddBatchRedirection(&Cmd->Redirections);
|
AddBatchRedirection(&Cmd->Redirections);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -261,15 +300,27 @@ INT Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
|
||||||
/* Create a new context. This function will not
|
/* Create a new context. This function will not
|
||||||
* return until this context has been exited */
|
* return until this context has been exited */
|
||||||
new.prev = bc;
|
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 = &new;
|
||||||
bc->RedirList = NULL;
|
bc->RedirList = NULL;
|
||||||
bc->setlocal = setlocal;
|
bc->setlocal = setlocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetFullPathName(fullname, sizeof(bc->BatchFilePath) / sizeof(TCHAR), bc->BatchFilePath, NULL);
|
GetFullPathName(fullname, sizeof(bc->BatchFilePath) / sizeof(TCHAR), bc->BatchFilePath, NULL);
|
||||||
|
/* if a new batch file, load it into memory and close the file */
|
||||||
|
if (!same_fn)
|
||||||
|
{
|
||||||
|
BatchFile2Mem(hFile);
|
||||||
|
CloseHandle(hFile);
|
||||||
|
}
|
||||||
|
|
||||||
bc->hBatchFile = hFile;
|
bc->mempos = 0; /* goto begin of batch file */
|
||||||
SetFilePointer (bc->hBatchFile, 0, NULL, FILE_BEGIN);
|
|
||||||
bc->bEcho = bEcho; /* Preserve echo across batch calls */
|
bc->bEcho = bEcho; /* Preserve echo across batch calls */
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++)
|
||||||
bc->shiftlevel[i] = i;
|
bc->shiftlevel[i] = i;
|
||||||
|
@ -339,6 +390,49 @@ VOID AddBatchRedirection(REDIRECTION **RedirList)
|
||||||
*RedirList = NULL;
|
*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
|
* 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
|
* Set eflag to 0 if line is not to be echoed else 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LPTSTR ReadBatchLine ()
|
LPTSTR ReadBatchLine ()
|
||||||
{
|
{
|
||||||
TRACE ("ReadBatchLine ()\n");
|
TRACE ("ReadBatchLine ()\n");
|
||||||
|
@ -360,7 +453,7 @@ LPTSTR ReadBatchLine ()
|
||||||
return NULL;
|
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");
|
TRACE ("ReadBatchLine(): Reached EOF!\n");
|
||||||
/* End of file.... */
|
/* End of file.... */
|
||||||
|
|
|
@ -9,7 +9,10 @@
|
||||||
typedef struct tagBATCHCONTEXT
|
typedef struct tagBATCHCONTEXT
|
||||||
{
|
{
|
||||||
struct tagBATCHCONTEXT *prev;
|
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];
|
TCHAR BatchFilePath[MAX_PATH];
|
||||||
LPTSTR params;
|
LPTSTR params;
|
||||||
LPTSTR raw_params; /* Holds the raw params given by the input */
|
LPTSTR raw_params; /* Holds the raw params given by the input */
|
||||||
|
@ -47,5 +50,6 @@ LPTSTR FindArg (TCHAR, BOOL *);
|
||||||
LPTSTR BatchParams (LPTSTR, LPTSTR);
|
LPTSTR BatchParams (LPTSTR, LPTSTR);
|
||||||
VOID ExitBatch (VOID);
|
VOID ExitBatch (VOID);
|
||||||
INT Batch (LPTSTR, LPTSTR, LPTSTR, PARSED_COMMAND *);
|
INT Batch (LPTSTR, LPTSTR, LPTSTR, PARSED_COMMAND *);
|
||||||
|
BOOL BatchGetString (LPTSTR lpBuffer, INT nBufferLength);
|
||||||
LPTSTR ReadBatchLine(VOID);
|
LPTSTR ReadBatchLine(VOID);
|
||||||
VOID AddBatchRedirection(REDIRECTION **);
|
VOID AddBatchRedirection(REDIRECTION **);
|
||||||
|
|
|
@ -74,14 +74,14 @@ INT cmd_goto (LPTSTR param)
|
||||||
/* jump to end of the file */
|
/* jump to end of the file */
|
||||||
if ( _tcsicmp( param, _T(":eof"))==0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jump to begin of the file */
|
/* 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 pos;
|
||||||
int size;
|
int size;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue