void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HANDLE pgmHandle) { HANDLE h = INVALID_HANDLE_VALUE; BATCH_CONTEXT *prev_context; if (startLabel == NULL) { h = CreateFileW (file, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) { SetLastError (ERROR_FILE_NOT_FOUND); WCMD_print_error (); return; } } else { DuplicateHandle(GetCurrentProcess(), pgmHandle, GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS); } /* * Create a context structure for this batch file. */ prev_context = context; context = LocalAlloc (LMEM_FIXED, sizeof (BATCH_CONTEXT)); context -> h = h; context->batchfileW = heap_strdupW(file); context -> command = command; memset(context -> shift_count, 0x00, sizeof(context -> shift_count)); context -> prev_context = prev_context; context -> skip_rest = FALSE; /* If processing a call :label, 'goto' the label in question */ if (startLabel) { strcpyW(param1, startLabel); WCMD_goto(NULL); } /* * Work through the file line by line. Specific batch commands are processed here, * the rest are handled by the main command processor. */ while (context -> skip_rest == FALSE) { CMD_LIST *toExecute = NULL; /* Commands left to be executed */ if (!WCMD_ReadAndParseLine(NULL, &toExecute, h)) break; /* Note: although this batch program itself may be called, we are not retrying the command as a result of a call failing to find a program, hence the retryCall parameter below is FALSE */ WCMD_process_commands(toExecute, FALSE, FALSE); WCMD_free_commands(toExecute); toExecute = NULL; } CloseHandle (h); /* * If there are outstanding setlocal's to the current context, unwind them. */ while (saved_environment && saved_environment->batchhandle == context->h) { WCMD_endlocal(); } /* * If invoked by a CALL, we return to the context of our caller. Otherwise return * to the caller's caller. */ heap_free(context->batchfileW); LocalFree (context); if ((prev_context != NULL) && (!called)) { WINE_TRACE("Batch completed, but was not 'called' so skipping outer batch too\n"); prev_context -> skip_rest = TRUE; context = prev_context; } context = prev_context; }
void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HANDLE pgmHandle) { #define WCMD_BATCH_EXT_SIZE 5 HANDLE h = INVALID_HANDLE_VALUE; WCHAR string[MAXSTRING]; static const WCHAR extension_batch[][WCMD_BATCH_EXT_SIZE] = {{'.','b','a','t','\0'}, {'.','c','m','d','\0'}}; static const WCHAR extension_exe[WCMD_BATCH_EXT_SIZE] = {'.','e','x','e','\0'}; unsigned int i; BATCH_CONTEXT *prev_context; if (startLabel == NULL) { for(i=0; (i<sizeof(extension_batch)/(WCMD_BATCH_EXT_SIZE * sizeof(WCHAR))) && (h == INVALID_HANDLE_VALUE); i++) { strcpyW (string, file); CharLower (string); if (strstrW (string, extension_batch[i]) == NULL) strcatW (string, extension_batch[i]); h = CreateFile (string, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } if (h == INVALID_HANDLE_VALUE) { strcpyW (string, file); CharLower (string); if (strstrW (string, extension_exe) == NULL) strcatW (string, extension_exe); if (GetFileAttributes (string) != INVALID_FILE_ATTRIBUTES) { WCMD_run_program (command, 0); } else { SetLastError (ERROR_FILE_NOT_FOUND); WCMD_print_error (); } return; } } else { DuplicateHandle(GetCurrentProcess(), pgmHandle, GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS); } /* * Create a context structure for this batch file. */ prev_context = context; context = (BATCH_CONTEXT *)LocalAlloc (LMEM_FIXED, sizeof (BATCH_CONTEXT)); context -> h = h; context -> command = command; memset(context -> shift_count, 0x00, sizeof(context -> shift_count)); context -> prev_context = prev_context; context -> skip_rest = FALSE; /* If processing a call :label, 'goto' the label in question */ if (startLabel) { strcpyW(param1, startLabel); WCMD_goto(NULL); } /* * Work through the file line by line. Specific batch commands are processed here, * the rest are handled by the main command processor. */ while (context -> skip_rest == FALSE) { CMD_LIST *toExecute = NULL; /* Commands left to be executed */ if (WCMD_ReadAndParseLine(NULL, &toExecute, h) == NULL) break; WCMD_process_commands(toExecute, FALSE, NULL, NULL); WCMD_free_commands(toExecute); toExecute = NULL; } CloseHandle (h); /* * If invoked by a CALL, we return to the context of our caller. Otherwise return * to the caller's caller. */ LocalFree ((HANDLE)context); if ((prev_context != NULL) && (!called)) { prev_context -> skip_rest = TRUE; context = prev_context; } context = prev_context; }
void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HANDLE pgmHandle) { HANDLE h = INVALID_HANDLE_VALUE; BATCH_CONTEXT *prev_context; if (startLabel == NULL) { h = CreateFileW (file, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) { SetLastError (ERROR_FILE_NOT_FOUND); WCMD_print_error (); return; } } else { DuplicateHandle(GetCurrentProcess(), pgmHandle, GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS); } /* * Create a context structure for this batch file. */ prev_context = context; context = LocalAlloc (LMEM_FIXED, sizeof (BATCH_CONTEXT)); context -> h = h; context->batchfileW = WCMD_strdupW(file); context -> command = command; memset(context -> shift_count, 0x00, sizeof(context -> shift_count)); context -> prev_context = prev_context; context -> skip_rest = FALSE; /* If processing a call :label, 'goto' the label in question */ if (startLabel) { strcpyW(param1, startLabel); WCMD_goto(NULL); } /* * Work through the file line by line. Specific batch commands are processed here, * the rest are handled by the main command processor. */ while (context -> skip_rest == FALSE) { CMD_LIST *toExecute = NULL; /* Commands left to be executed */ if (!WCMD_ReadAndParseLine(NULL, &toExecute, h)) break; WCMD_process_commands(toExecute, FALSE, NULL, NULL); WCMD_free_commands(toExecute); toExecute = NULL; } CloseHandle (h); /* * If invoked by a CALL, we return to the context of our caller. Otherwise return * to the caller's caller. */ HeapFree(GetProcessHeap(), 0, context->batchfileW); LocalFree (context); if ((prev_context != NULL) && (!called)) { prev_context -> skip_rest = TRUE; context = prev_context; } context = prev_context; }