Author: tkreuzer
Date: Wed Jun  1 19:33:20 2011
New Revision: 52047

URL: http://svn.reactos.org/svn/reactos?rev=52047&view=rev
Log:
[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.

Modified:
    trunk/reactos/base/shell/cmd/batch.c
    trunk/reactos/base/shell/cmd/batch.h
    trunk/reactos/base/shell/cmd/goto.c

Modified: trunk/reactos/base/shell/cmd/batch.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/batch.c?rev=52047&r1=52046&r2=52047&view=diff
==============================================================================
--- trunk/reactos/base/shell/cmd/batch.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/batch.c [iso-8859-1] Wed Jun  1 19:33:20 2011
@@ -156,6 +156,22 @@
        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,19 +185,9 @@
 
 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 @@
        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 @@
        LPFOR_CONTEXT saved_fc;
        INT i;
        INT ret = 0;
-
-       HANDLE hFile;
+       BOOL same_fn = FALSE;   
+
+       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)
-       {
-               ConErrResPuts(STRING_BATCH_ERROR);
-               return 1;
-       }
-
+       if (bc && bc->mem) 
+       {
+               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 @@
                /* 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;
@@ -340,6 +391,49 @@
 }
 
 /*
+ *   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
  *
  * If no batch file is current or no further executable lines are found
@@ -347,7 +441,6 @@
  *
  * Set eflag to 0 if line is not to be echoed else 1
  */
-
 LPTSTR ReadBatchLine ()
 {
        TRACE ("ReadBatchLine ()\n");
@@ -360,7 +453,7 @@
                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.... */

Modified: trunk/reactos/base/shell/cmd/batch.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/batch.h?rev=52047&r1=52046&r2=52047&view=diff
==============================================================================
--- trunk/reactos/base/shell/cmd/batch.h [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/batch.h [iso-8859-1] Wed Jun  1 19:33:20 2011
@@ -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 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 **);

Modified: trunk/reactos/base/shell/cmd/goto.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/goto.c?rev=52047&r1=52046&r2=52047&view=diff
==============================================================================
--- trunk/reactos/base/shell/cmd/goto.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/goto.c [iso-8859-1] Wed Jun  1 19:33:20 2011
@@ -74,14 +74,14 @@
        /* 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;


Reply via email to