Commit ebecf502 authored by Dave Pickles's avatar Dave Pickles Committed by Alexandre Julliard

Added support for ERRORLEVEL.

Most errors reported via FormatMessage(). COPY command now works correctly if output specifier is a directory.
parent 1da10fdc
v0.14 - 1 August 2000
Errorlevel support added
Most errors reported via FormatMessage()
COPY command now works correctly if output specifier is a directory.
v0.13 - 30 July 2000
By Jason Edmeades (jason@the-edmeades.fsnet.co.uk)
-Enhanced 'if' support
-Use of PATHEXT env var (NT) - eg. run file with non-normal extension
if allowed through pathext
-Better searching of path for these files
-Support of .cmd as extension for batch (NT allows this)
-Support for %* as a batch option
-Lookup in registry for filetype to see how it should be launched
(HKEY_CLASSES_ROOT, then its name, getting shell->open->command and
launching the appropriate program).
v0.12 - 4 July 1999
FOR and IF commands added.
MOVE command added, but no wildcard support.
......
......@@ -22,18 +22,18 @@ READONLY setting depends on the Unix file permissions. All other flags are
always clear. The Wine attributes API calls map to the Unix stat() function
which cannot handle the other attributes available in DOS.
- Date/timestamps of files in the DIR listing are shown using the current
locale. As there is AFAIK no way to set the locale, they will always appear in
US format.
locale, which is set using the Unix LANG environment variable. By default the
US date-time format is used. Set eg "LANG=en_GB" for DD/MM/YY dates and 24-hour
times.
- Line editing and command recall doesn't work due to missing functionality in
Wine.
- File sizes in the DIR function are all given in 32 bits, though totals and
free space are computed to 64 bits.
- DIR/S fails if there is no matching file in the starting directory, ie
"DIR C:\TEMP\*.c /S" doesn't work if there is no file matching *.c in C:\TEMP
but one does exist in a lower directory.
- DIR/S only works if no file specification is given, ie "DIR C:\TEMP /S" works
but "DIR C:\TEMP\*.C" doesn't work if a matching file exists in a lower
directory.
- Copy, rename, move, need the source and destination to be specified fully
with an absolute or relative path but no wildcards or partial filenames.
- The IF ERRORLEVEL construct is not implemented.
- Redirection is implemented as a command line is parsed. This means that ">"
and "<" symbols cannot appear in command arguments even within quotes.
- In many cases parsing and syntax checking is less rigorous than DOS. Thus an
......
......@@ -16,7 +16,7 @@ extern char version_string[];
extern int echo_mode;
extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
extern BATCH_CONTEXT *context;
extern DWORD errorlevel;
/****************************************************************************
......@@ -43,7 +43,8 @@ BATCH_CONTEXT *prev_context;
if (strstr (string, ".bat") == NULL) strcat (string, ".bat");
h = CreateFile (string, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (h == INVALID_HANDLE_VALUE) {
WCMD_output ("File %s not found\n", string);
SetLastError (ERROR_FILE_NOT_FOUND);
WCMD_print_error ();
return;
}
......@@ -223,7 +224,7 @@ char *p;
}
}
/****************************************************************************
/****************************************************************************
* WCMD_fgets
*
* Get one line from a batch file. We can't use the native f* functions because
......@@ -244,7 +245,7 @@ char *p;
if (*s == '\n') bytes = 0;
else if (*s != '\r') {
s++;
n--;
n--;
}
*s = '\0';
} while ((bytes == 1) && (n > 1));
......
......@@ -29,6 +29,7 @@ extern char anykey[];
extern int echo_mode, verify_mode;
extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
extern BATCH_CONTEXT *context;
extern DWORD errorlevel;
......@@ -61,7 +62,6 @@ void WCMD_change_tty () {
*
* Copy a file or wildcarded set.
* FIXME: No wildcard support
* FIXME: Needs output file to be fully specified (can't just enter directory)
*/
void WCMD_copy () {
......@@ -71,13 +71,22 @@ WIN32_FIND_DATA fd;
HANDLE hff;
BOOL force, status;
static char *overwrite = "Overwrite file (Y/N)?";
char string[8], outpath[MAX_PATH];
char string[8], outpath[MAX_PATH], inpath[MAX_PATH], *infile;
if ((strchr(param1,'*') != NULL) && (strchr(param1,'%') != NULL)) {
WCMD_output ("Wildcards not yet supported\n");
return;
}
GetFullPathName (param2, sizeof(outpath), outpath, NULL);
hff = FindFirstFile (outpath, &fd);
if (hff != INVALID_HANDLE_VALUE) {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
GetFullPathName (param1, sizeof(inpath), inpath, &infile);
strcat (outpath, "\\");
strcat (outpath, infile);
}
FindClose (hff);
}
force = (strstr (quals, "/Y") != NULL);
if (!force) {
hff = FindFirstFile (outpath, &fd);
......@@ -236,7 +245,9 @@ int i;
}
}
/*
/*****************************************************************************
* WCMD_Execute
*
* Execute a command after substituting variable text for the supplied parameter
*/
......@@ -283,10 +294,10 @@ char buffer[2048];
else {
for (i=0; i<=WCMD_EXIT; i++) {
if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
param1, -1, inbuilt[i], -1) == 2) {
LoadString (0, i, buffer, sizeof(buffer));
WCMD_output (buffer);
return;
param1, -1, inbuilt[i], -1) == 2) {
LoadString (hinst, i, buffer, sizeof(buffer));
WCMD_output (buffer);
return;
}
}
WCMD_output ("No help available for %s\n", param1);
......@@ -322,7 +333,6 @@ char string[MAX_PATH];
* WCMD_if
*
* Batch file conditional.
* FIXME: The "errorlevel" version is not supported.
* FIXME: Much more syntax checking needed!
*/
......@@ -340,7 +350,7 @@ char condition[MAX_PATH], *command, *s;
lstrcpy (condition, param1);
}
if (!lstrcmpi (condition, "errorlevel")) {
WCMD_output (nyi);
if (errorlevel >= atoi(WCMD_parameter (p, 1+negate, NULL))) test = 1;
return;
}
else if (!lstrcmpi (condition, "exist")) {
......@@ -421,17 +431,11 @@ void WCMD_remove_dir () {
void WCMD_rename () {
int status;
static char *dirmsg = "Input file is a directory. Use the MOVE command\n\n";
if ((strchr(param1,'*') != NULL) || (strchr(param1,'%') != NULL)) {
WCMD_output ("Wildcards not yet supported\n");
return;
}
status = GetFileAttributes (param1);
if ((status != -1) && (status & FILE_ATTRIBUTE_DIRECTORY)) {
WCMD_output (dirmsg);
return;
}
status = MoveFile (param1, param2);
if (!status) WCMD_print_error ();
}
......
......@@ -29,6 +29,7 @@ extern char version_string[];
extern char anykey[];
extern int echo_mode;
extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
extern DWORD errorlevel;
int file_total, dir_total, line_count, page_mode, recurse;
__int64 byte_total;
......@@ -52,7 +53,11 @@ DWORD spc, bps, fc, capacity;
page_mode = (strstr(quals, "/P") != NULL);
recurse = (strstr(quals, "/S") != NULL);
if (param1[0] == '\0') strcpy (param1, ".");
GetFullPathName (param1, sizeof(path), path, NULL);
status = GetFullPathName (param1, sizeof(path), path, NULL);
if (!status) {
WCMD_print_error();
return;
}
lstrcpyn (drive, path, 3);
status = WCMD_volume (0, drive);
if (!status) {
......@@ -121,7 +126,8 @@ __int64 byte_count;
fd = malloc (sizeof(WIN32_FIND_DATA));
hff = FindFirstFile (search_path, fd);
if (hff == INVALID_HANDLE_VALUE) {
WCMD_output ("File Not Found\n");
SetLastError (ERROR_FILE_NOT_FOUND);
WCMD_print_error ();
free (fd);
return;
}
......
......@@ -20,10 +20,12 @@ char *inbuilt[] = {"ATTRIB", "CALL", "CD", "CHDIR", "CLS", "COPY", "CTTY",
"PROMPT", "REM", "REN", "RENAME", "RD", "RMDIR", "SET", "SHIFT",
"TIME", "TYPE", "VERIFY", "VER", "VOL", "EXIT"};
HINSTANCE hinst;
DWORD errorlevel;
int echo_mode = 1, verify_mode = 0;
char nyi[] = "Not Yet Implemented\n\n";
char newline[] = "\n";
char version_string[] = "WCMD Version 0.12\n\n";
char version_string[] = "WCMD Version 0.14\n\n";
char anykey[] = "Press any key to continue: ";
char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
BATCH_CONTEXT *context = NULL;
......@@ -376,6 +378,8 @@ char filetorun[MAX_PATH];
if (!status) {
WCMD_print_error ();
}
GetExitCodeProcess (pe.hProcess, &errorlevel);
if (errorlevel == STILL_ACTIVE) errorlevel = 0;
}
/******************************************************************************
......@@ -459,30 +463,25 @@ char *p, *q;
/****************************************************************************
* WCMD_print_error
*
* Print the message for GetLastError - not much use yet as Wine doesn't have
* the messages available, so we show meaningful messages for the most likely.
* Print the message for GetLastError
*/
void WCMD_print_error () {
LPVOID lpMsgBuf;
DWORD error_code;
int status;
error_code = GetLastError ();
switch (error_code) {
case ERROR_FILE_NOT_FOUND:
WCMD_output ("File Not Found\n");
break;
case ERROR_PATH_NOT_FOUND:
WCMD_output ("Path Not Found\n");
break;
default:
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error_code,
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL);
WCMD_output (lpMsgBuf);
LocalFree ((HLOCAL)lpMsgBuf);
status = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error_code, 0, (LPTSTR) &lpMsgBuf, 0, NULL);
if (!status) {
WCMD_output ("FIXME: Cannot display message for error %d, status %d\n",
error_code, GetLastError());
return;
}
WCMD_output (lpMsgBuf);
LocalFree ((HLOCAL)lpMsgBuf);
WCMD_output (newline);
return;
}
......@@ -568,7 +567,10 @@ void WCMD_output_asis (char *message) {
/* Remove leading spaces from a string. Return a pointer to the first
/***************************************************************************
* WCMD_strtrim_leading_spaces
*
* Remove leading spaces from a string. Return a pointer to the first
* non-space character. Does not modify the input string
*/
......@@ -581,7 +583,10 @@ char *ptr;
return ptr;
}
/* Remove trailing spaces from a string. This routine modifies the input
/*************************************************************************
* WCMD_strtrim_trailing_spaces
*
* Remove trailing spaces from a string. This routine modifies the input
* string by placing a null after the last non-space character
*/
......
......@@ -64,11 +64,10 @@ GOTO has no effect when used interactively.\n"
\
Syntax: IF [NOT] EXIST filename command \
IF [NOT] string1==string2 command \
IF [NOT] ERRORLEVEL number command \
\
In the second form of the command, string1 and string2 must be in double \
quotes. The comparison is not case-sensitive.\
\
The form IF [NOT] ERRORLEVEL number is not implemented in Wcmd.\n"
quotes. The comparison is not case-sensitive.\n"
WCMD_LABEL, "Help about LABEL\n"
WCMD_MD, "Help about MD\n"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment