Module: wine Branch: master Commit: 1497a2fec420fcef81fb31c6343fa79f43602758 URL: http://source.winehq.org/git/wine.git/?a=commit;h=1497a2fec420fcef81fb31c634...
Author: Jason Edmeades us@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; +}