From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/batch.c | 12 ++++-------- programs/cmd/builtins.c | 5 ++--- programs/cmd/wcmd.h | 1 + programs/cmd/wcmdmain.c | 14 ++++++++++++-- 4 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c index 0b36117e960..0b93753eda8 100644 --- a/programs/cmd/batch.c +++ b/programs/cmd/batch.c @@ -87,6 +87,7 @@ RETURN_CODE WCMD_call_batch(const WCHAR *file, WCHAR *command) prev_context = context; context = malloc(sizeof (BATCH_CONTEXT)); context->h = h; + context->file_position.QuadPart = 0; context->batchfileW = xstrdupW(file); context->command = command; memset(context->shift_count, 0x00, sizeof(context->shift_count)); @@ -658,7 +659,6 @@ RETURN_CODE WCMD_call(WCHAR *command) } else if (context) { - LARGE_INTEGER li; WCHAR gotoLabel[MAX_PATH]; BATCH_CONTEXT *prev_context;
@@ -668,15 +668,10 @@ RETURN_CODE WCMD_call(WCHAR *command) as for loop variables do not survive a call */ WCMD_save_for_loop_context(TRUE);
- /* Save the current file position, call the same file, - restore position */ - li.QuadPart = 0; - li.u.LowPart = SetFilePointer(context->h, li.u.LowPart, - &li.u.HighPart, FILE_CURRENT); - prev_context = context; context = malloc(sizeof (BATCH_CONTEXT)); context->h = prev_context->h; + context->file_position = prev_context->file_position; /* will be overwritten by WCMD_GOTO below */ context->batchfileW = prev_context->batchfileW; context->command = buffer; memset(context->shift_count, 0x00, sizeof(context->shift_count)); @@ -692,7 +687,8 @@ RETURN_CODE WCMD_call(WCHAR *command) free(context); context = prev_context; return_code = errorlevel; - SetFilePointer(context->h, li.u.LowPart, &li.u.HighPart, FILE_BEGIN); + if (!SetFilePointerEx(context->h, context->file_position, NULL, FILE_BEGIN)) + return ERROR_INVALID_FUNCTION;
/* Restore the for loop context */ WCMD_restore_for_loop_context(); diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 4eec2119462..284cf1f84b6 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1818,7 +1818,7 @@ RETURN_CODE WCMD_goto(void) if (context != NULL) { WCHAR *paramStart = param1; - LARGE_INTEGER li, zeroli = {.QuadPart = 0}; + if (!param1[0]) { WCMD_output_stderr(WCMD_LoadMessage(WCMD_NOARG)); @@ -1837,8 +1837,7 @@ RETURN_CODE WCMD_goto(void) WCMD_set_label_end(paramStart); TRACE("goto label: '%s'\n", wine_dbgstr_w(paramStart));
- SetFilePointerEx(context->h, zeroli, &li, FILE_CURRENT); - if (WCMD_find_label(context->h, paramStart, &li)) + if (WCMD_find_label(context->h, paramStart, &context->file_position)) return RETURN_CODE_ABORTED; WCMD_output_stderr(WCMD_LoadMessage(WCMD_NOTARGET)); context->skip_rest = TRUE; diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 0b4004a0ed9..3023afc1cb0 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -260,6 +260,7 @@ typedef struct _BATCH_CONTEXT { WCHAR *command; /* The command which invoked the batch file */ HANDLE h; /* Handle to the open batch file */ + LARGE_INTEGER file_position; WCHAR *batchfileW; /* Name of same */ int shift_count[10]; /* Offset in terms of shifts for %0 - %9 */ struct _BATCH_CONTEXT *prev_context; /* Pointer to the previous context block */ diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 9775a73850c..c4f58a422b9 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -2691,8 +2691,18 @@ static WCHAR *fetch_next_line(BOOL feed, BOOL first_line, WCHAR* buffer)
if (feed) { - HANDLE from = context ? context->h : GetStdHandle(STD_INPUT_HANDLE); - if (!WCMD_fgets(buffer, MAXSTRING, from)) + BOOL ret; + if (context) + { + LARGE_INTEGER zeroli = {.QuadPart = 0}; + + ret = SetFilePointerEx(context->h, context->file_position, NULL, FILE_BEGIN) && + !!WCMD_fgets(buffer, MAXSTRING, context->h) && + SetFilePointerEx(context->h, zeroli, &context->file_position, FILE_CURRENT); + } + else + ret = !!WCMD_fgets(buffer, MAXSTRING, GetStdHandle(STD_INPUT_HANDLE)); + if (!ret) { buffer[0] = L'\0'; return NULL;