Jason Edmeades : cmd.exe: Add dir /X support (sort of...).

Alexandre Julliard julliard at wine.codeweavers.com
Wed Mar 14 07:25:27 CDT 2007


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

Author: Jason Edmeades <us at edmeades.me.uk>
Date:   Tue Mar 13 20:27:45 2007 +0000

cmd.exe: Add dir /X support (sort of...).

---

 programs/cmd/directory.c |  101 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 79 insertions(+), 22 deletions(-)

diff --git a/programs/cmd/directory.c b/programs/cmd/directory.c
index d787a29..0c8c5af 100644
--- a/programs/cmd/directory.c
+++ b/programs/cmd/directory.c
@@ -33,7 +33,7 @@ int WCMD_dir_sort (const void *a, const void *b);
 void WCMD_list_directory (char *path, int level);
 char * WCMD_filesize64 (ULONGLONG free);
 char * WCMD_strrev (char *buff);
-
+static void WCMD_getfileowner(char *filename, char *owner, int ownerlen);
 
 extern int echo_mode;
 extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
@@ -47,7 +47,7 @@ typedef enum _DISPLAYTIME
 } DISPLAYTIME;
 
 static int file_total, dir_total, recurse, wide, bare, max_width, lower;
-static int shortname;
+static int shortname, usernames;
 static ULONGLONG byte_total;
 static DISPLAYTIME dirTime;
 
@@ -77,6 +77,7 @@ void WCMD_directory (void) {
   bare       = (strstr(quals, "/B") != NULL);
   lower      = (strstr(quals, "/L") != NULL);
   shortname  = (strstr(quals, "/X") != NULL);
+  usernames  = (strstr(quals, "/Q") != NULL);
 
   if ((p = strstr(quals, "/T")) != NULL) {
     p = p + 2;
@@ -98,6 +99,7 @@ void WCMD_directory (void) {
   /* Handle conflicting args and initialization */
   if (bare || shortname) wide = FALSE;
   if (bare) shortname = FALSE;
+  if (wide) usernames = FALSE;
 
   if (wide) {
       if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
@@ -198,12 +200,12 @@ void WCMD_list_directory (char *search_path, int level) {
   lstrcpyn (real_path, search_path, (p-search_path+2));
 
   /* Load all files into an in memory structure */
-  fd = malloc (sizeof(WIN32_FIND_DATA));
+  fd = HeapAlloc(GetProcessHeap(),0,sizeof(WIN32_FIND_DATA));
   hff = FindFirstFile (search_path, fd);
   if (hff == INVALID_HANDLE_VALUE) {
     SetLastError (ERROR_FILE_NOT_FOUND);
     WCMD_print_error ();
-    free (fd);
+    HeapFree(GetProcessHeap(),0,fd);
     return;
   }
   do {
@@ -216,7 +218,7 @@ void WCMD_list_directory (char *search_path, int level) {
        if (tmpLen > widest) widest = tmpLen;
     }
 
-    fd = realloc (fd, (entry_count+1)*sizeof(WIN32_FIND_DATA));
+    fd = HeapReAlloc(GetProcessHeap(),0,fd,(entry_count+1)*sizeof(WIN32_FIND_DATA));
     if (fd == NULL) {
       FindClose (hff);
       WCMD_output ("Memory Allocation Error");
@@ -235,6 +237,7 @@ void WCMD_list_directory (char *search_path, int level) {
   }
 
   for (i=0; i<entry_count; i++) {
+    char username[24];
 
     /* /L convers all names to lower case */
     if (lower) {
@@ -242,6 +245,14 @@ void WCMD_list_directory (char *search_path, int level) {
         while ( (*p = tolower(*p)) ) ++p;
     }
 
+    /* /Q gets file ownership information */
+    if (usernames) {
+        p = strrchr (search_path, '\\');
+        lstrcpyn (string, search_path, (p-search_path+2));
+        lstrcat (string, (fd+i)->cFileName);
+        WCMD_getfileowner(string, username, sizeof(username));
+    }
+
     if (dirTime == Written) {
       FileTimeToLocalFileTime (&(fd+i)->ftLastWriteTime, &ft);
     } else if (dirTime == Access) {
@@ -283,13 +294,10 @@ void WCMD_list_directory (char *search_path, int level) {
       dir_count++;
 
       if (!bare) {
-         if (shortname) {
-             WCMD_output ("%10s  %8s  <DIR>         %-13s%s\n",
-		     datestring, timestring, (fd+i)->cAlternateFileName, (fd+i)->cFileName);
-         } else {
-             WCMD_output ("%10s  %8s  <DIR>         %s\n",
-		     datestring, timestring, (fd+i)->cFileName);
-         }
+         WCMD_output ("%10s  %8s  <DIR>         ", datestring, timestring);
+         if (shortname) WCMD_output ("%-13s", (fd+i)->cAlternateFileName);
+         if (usernames) WCMD_output ("%-23s", username);
+         WCMD_output("%s\n",(fd+i)->cFileName);
       } else {
          if (!((strcmp((fd+i)->cFileName, ".") == 0) ||
                (strcmp((fd+i)->cFileName, "..") == 0))) {
@@ -303,15 +311,11 @@ void WCMD_list_directory (char *search_path, int level) {
       file_size.u.HighPart = (fd+i)->nFileSizeHigh;
       byte_count.QuadPart += file_size.QuadPart;
       if (!bare) {
-         if (shortname) {
-             WCMD_output ("%10s  %8s    %10s  %-13s%s\n",
-	         datestring, timestring,
-                 WCMD_filesize64(file_size.QuadPart), (fd+i)->cAlternateFileName, (fd+i)->cFileName);
-         } else {
-             WCMD_output ("%10s  %8s    %10s  %s\n",
-	         datestring, timestring,
-                 WCMD_filesize64(file_size.QuadPart), (fd+i)->cFileName);
-         }
+         WCMD_output ("%10s  %8s    %10s  ", datestring, timestring,
+                      WCMD_filesize64(file_size.QuadPart));
+         if (shortname) WCMD_output ("%-13s", (fd+i)->cAlternateFileName);
+         if (usernames) WCMD_output ("%-23s", username);
+         WCMD_output("%s\n",(fd+i)->cFileName);
       } else {
          WCMD_output ("%s%s\n", recurse?real_path:"", (fd+i)->cFileName);
       }
@@ -352,7 +356,7 @@ void WCMD_list_directory (char *search_path, int level) {
       WCMD_list_directory (string, 1);
     }
   }
-  free (fd);
+  HeapFree(GetProcessHeap(),0,fd);
   return;
 }
 
@@ -411,3 +415,56 @@ int WCMD_dir_sort (const void *a, const void *b)
   return (lstrcmpi(((const WIN32_FIND_DATA *)a)->cFileName,
                    ((const WIN32_FIND_DATA *)b)->cFileName));
 }
+
+/*****************************************************************************
+ * WCMD_getfileowner
+ *
+ * Reverse a character string in-place (strrev() is not available under unixen :-( ).
+ */
+void WCMD_getfileowner(char *filename, char *owner, int ownerlen) {
+
+    ULONG sizeNeeded = 0;
+    DWORD rc;
+    char name[MAXSTRING];
+    char domain[MAXSTRING];
+
+    /* In case of error, return empty string */
+    *owner = 0x00;
+
+    /* Find out how much space we need for the owner security descritpor */
+    GetFileSecurity(filename, OWNER_SECURITY_INFORMATION, 0, 0, &sizeNeeded);
+    rc = GetLastError();
+
+    if(rc == ERROR_INSUFFICIENT_BUFFER && sizeNeeded > 0) {
+
+        LPBYTE secBuffer;
+        PSID pSID = NULL;
+        BOOL defaulted = FALSE;
+        ULONG nameLen = MAXSTRING;
+        ULONG domainLen = MAXSTRING;
+        SID_NAME_USE nameuse;
+
+        secBuffer = (LPBYTE) HeapAlloc(GetProcessHeap(),0,sizeNeeded * sizeof(BYTE));
+        if(!secBuffer) return;
+
+        /* Get the owners security descriptor */
+        if(!GetFileSecurity(filename, OWNER_SECURITY_INFORMATION, secBuffer,
+                            sizeNeeded, &sizeNeeded)) {
+            HeapFree(GetProcessHeap(),0,secBuffer);
+            return;
+        }
+
+        /* Get the SID from the SD */
+        if(!GetSecurityDescriptorOwner(secBuffer, &pSID, &defaulted)) {
+            HeapFree(GetProcessHeap(),0,secBuffer);
+            return;
+        }
+
+        /* Convert to a username */
+        if (LookupAccountSid(NULL, pSID, name, &nameLen, domain, &domainLen, &nameuse)) {
+            snprintf(owner, ownerlen, "%s%c%s", domain, '\\', name);
+        }
+        HeapFree(GetProcessHeap(),0,secBuffer);
+    }
+    return;
+}




More information about the wine-cvs mailing list