Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}