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