[PATCH 1/9] Add dir /X support (sort of...)

Jason Edmeades us at edmeades.me.uk
Tue Mar 13 15:27:45 CDT 2007


The code here was also tested on windows and works, but under wine
it fails with a fixme in GetFileSecurity, but since I had written
it its submitted for completeness so when that routine is finally
implemented then this code will also work

Fixed as requested to remove malloc (and removed existing one
while I was at it)
---
 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..31ac6d0 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;
+}
-- 
1.5.0




More information about the wine-patches mailing list