[ros-diffs] [tkreuzer] 52047: [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.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Wed Jun 1 19:33:20 UTC 2011


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;




More information about the Ros-diffs mailing list