Added support for ERRORLEVEL.
Most errors reported via FormatMessage().
COPY command now works correctly if output specifier is a directory.
diff --git a/programs/wcmd/ChangeLog b/programs/wcmd/ChangeLog
index eccc8c2..4fc945b 100644
--- a/programs/wcmd/ChangeLog
+++ b/programs/wcmd/ChangeLog
@@ -1,3 +1,20 @@
+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.
diff --git a/programs/wcmd/README b/programs/wcmd/README
index 9496ba1..995c10b 100644
--- a/programs/wcmd/README
+++ b/programs/wcmd/README
@@ -22,18 +22,18 @@
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
diff --git a/programs/wcmd/batch.c b/programs/wcmd/batch.c
index 6bb9c22..acfbc1e 100644
--- a/programs/wcmd/batch.c
+++ b/programs/wcmd/batch.c
@@ -16,7 +16,7 @@
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 @@
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 @@
}
}
-/****************************************************************************
+/****************************************************************************
* WCMD_fgets
*
* Get one line from a batch file. We can't use the native f* functions because
@@ -244,7 +245,7 @@
if (*s == '\n') bytes = 0;
else if (*s != '\r') {
s++;
- n--;
+ n--;
}
*s = '\0';
} while ((bytes == 1) && (n > 1));
diff --git a/programs/wcmd/builtins.c b/programs/wcmd/builtins.c
index cdc18a6..1ccac73 100644
--- a/programs/wcmd/builtins.c
+++ b/programs/wcmd/builtins.c
@@ -29,6 +29,7 @@
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 @@
*
* 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 @@
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 @@
}
}
-/*
+/*****************************************************************************
+ * WCMD_Execute
+ *
* Execute a command after substituting variable text for the supplied parameter
*/
@@ -283,10 +294,10 @@
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 @@
* WCMD_if
*
* Batch file conditional.
- * FIXME: The "errorlevel" version is not supported.
* FIXME: Much more syntax checking needed!
*/
@@ -340,7 +350,7 @@
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_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 ();
}
diff --git a/programs/wcmd/directory.c b/programs/wcmd/directory.c
index 6d264ee..2799e1d 100644
--- a/programs/wcmd/directory.c
+++ b/programs/wcmd/directory.c
@@ -29,6 +29,7 @@
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 @@
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 @@
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;
}
diff --git a/programs/wcmd/wcmdmain.c b/programs/wcmd/wcmdmain.c
index 1e6825d..8325868 100644
--- a/programs/wcmd/wcmdmain.c
+++ b/programs/wcmd/wcmdmain.c
@@ -20,10 +20,12 @@
"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 @@
if (!status) {
WCMD_print_error ();
}
+ GetExitCodeProcess (pe.hProcess, &errorlevel);
+ if (errorlevel == STILL_ACTIVE) errorlevel = 0;
}
/******************************************************************************
@@ -459,30 +463,25 @@
/****************************************************************************
* 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 @@
-/* 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 @@
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
*/
diff --git a/programs/wcmd/wcmdrc.rc b/programs/wcmd/wcmdrc.rc
index 16ffa26..33343e0 100644
--- a/programs/wcmd/wcmdrc.rc
+++ b/programs/wcmd/wcmdrc.rc
@@ -64,11 +64,10 @@
\
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"