Jason Edmeades : cmd.exe: Add support for move with simple wildcards.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Apr 12 10:00:01 CDT 2007


Module: wine
Branch: master
Commit: 32fc366955683a237d78beba69568f8b873b68ed
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=32fc366955683a237d78beba69568f8b873b68ed

Author: Jason Edmeades <us at edmeades.me.uk>
Date:   Wed Apr 11 22:25:51 2007 +0100

cmd.exe: Add support for move with simple wildcards.

---

 programs/cmd/builtins.c |  101 ++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 95 insertions(+), 6 deletions(-)

diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 36d41a0..7e79aeb 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -843,18 +843,107 @@ void WCMD_remove_dir (char *command) {
 
 void WCMD_rename (void) {
 
-  int status;
+  int             status;
+  HANDLE          hff;
+  WIN32_FIND_DATA fd;
+  char            input[MAX_PATH];
+  char           *dotDst = NULL;
+  char            drive[10];
+  char            dir[MAX_PATH];
+  char            fname[MAX_PATH];
+  char            ext[MAX_PATH];
+  DWORD           attribs;
+
+  errorlevel = 0;
 
+  /* Must be at least two args */
   if (param1[0] == 0x00 || param2[0] == 0x00) {
     WCMD_output ("Argument missing\n");
+    errorlevel = 1;
     return;
   }
-  if ((strchr(param1,'*') != NULL) || (strchr(param1,'%') != NULL)) {
-    WCMD_output ("Wildcards not yet supported\n");
-    return;
+
+  /* Destination cannot contain a drive letter or directory separator */
+  if ((strchr(param1,':') != NULL) || (strchr(param1,'\\') != NULL)) {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      WCMD_print_error();
+      errorlevel = 1;
+      return;
+  }
+
+  /* Convert partial path to full path */
+  GetFullPathName (param1, sizeof(input), input, NULL);
+  WINE_TRACE("Rename from '%s'('%s') to '%s'\n", input, param1, param2);
+  dotDst = strchr(param2, '.');
+
+  /* Split into components */
+  WCMD_splitpath(input, drive, dir, fname, ext);
+
+  hff = FindFirstFile (input, &fd);
+  while (hff != INVALID_HANDLE_VALUE) {
+    char  dest[MAX_PATH];
+    char  src[MAX_PATH];
+    char *dotSrc = NULL;
+    int   dirLen;
+
+    WINE_TRACE("Processing file '%s'\n", fd.cFileName);
+
+    /* FIXME: If dest name or extension is *, replace with filename/ext
+       part otherwise use supplied name. This supports:
+          ren *.fred *.jim
+          ren jim.* fred.* etc
+       However, windows has a more complex algorithum supporting eg
+          ?'s and *'s mid name                                         */
+    dotSrc = strchr(fd.cFileName, '.');
+
+    /* Build src & dest name */
+    strcpy(src, drive);
+    strcat(src, dir);
+    strcpy(dest, src);
+    dirLen = strlen(src);
+    strcat(src, fd.cFileName);
+
+    /* Build name */
+    if (param2[0] == '*') {
+      strcat(dest, fd.cFileName);
+      if (dotSrc) dest[dirLen + (dotSrc - fd.cFileName)] = 0x00;
+    } else {
+      strcat(dest, param2);
+      if (dotDst) dest[dirLen + (dotDst - param2)] = 0x00;
+    }
+
+    /* Build Extension */
+    if (dotDst && (*(dotDst+1)=='*')) {
+      if (dotSrc) strcat(dest, dotSrc);
+    } else if (dotDst) {
+      if (dotDst) strcat(dest, dotDst);
+    }
+
+    WINE_TRACE("Source '%s'\n", src);
+    WINE_TRACE("Dest   '%s'\n", dest);
+
+    /* Check if file is read only, otherwise move it */
+    attribs = GetFileAttributesA(src);
+    if ((attribs != INVALID_FILE_ATTRIBUTES) &&
+        (attribs & FILE_ATTRIBUTE_READONLY)) {
+      SetLastError(ERROR_ACCESS_DENIED);
+      status = 0;
+    } else {
+      status = MoveFile (src, dest);
+    }
+
+    if (!status) {
+      WCMD_print_error ();
+      errorlevel = 1;
+    }
+
+    /* Step on to next match */
+    if (FindNextFile(hff, &fd) == 0) {
+      FindClose(hff);
+      hff = INVALID_HANDLE_VALUE;
+      break;
+    }
   }
-  status = MoveFile (param1, param2);
-  if (!status) WCMD_print_error ();
 }
 
 /*****************************************************************************




More information about the wine-cvs mailing list