aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2008-05-09 19:03:52 +0000
committerEli Zaretskii2008-05-09 19:03:52 +0000
commit8aaaec6b622da9620c85862a7cb717d4aee2276f (patch)
tree36df47a50386d7c7843ec718252e5a7aeb28ec52 /src
parent71e41ffb85e94bf77260acdb71eed141e6756a6f (diff)
downloademacs-8aaaec6b622da9620c85862a7cb717d4aee2276f.tar.gz
emacs-8aaaec6b622da9620c85862a7cb717d4aee2276f.zip
Support for reporting owner and group of each file on MS-Windows:
* dired.c (stat_uname, stat_gname): New functions, with special implementation for w32. (Ffile_attributes): Use them instead of getpwuid and getgrgid. * w32.c: (g_b_init_get_file_security, g_b_init_get_security_descriptor_owner) (g_b_init_get_security_descriptor_group, g_b_init_is_valid_sid): New initialization states. (globals_of_w32): Initialize them to zero. Initialize the default group name to "None". (GetFileSecurity_Name): New global var, the name of the function to call for GetFileSecurity. (GetFileSecurity_Proc, GetSecurityDescriptorOwner_Proc) (GetSecurityDescriptorGroup_Proc, IsValidSid_Proc): New typedefs. (get_file_security, get_security_descriptor_owner) (get_security_descriptor_group, is_valid_sid) (get_file_security_desc, get_rid, get_name_and_id) (get_file_owner_and_group): New functions. (stat): Use get_file_security_desc and get_file_owner_and_group to report the owner and primary group of each file. Don't ignore the high 32 bits of file's size, now that st_size is 64-bit wide. Fix test when to get true file attributes. (init_user_info): Use get_rid instead of equivalent inline code. (fstat): Don't ignore the high 32 bits of file's size.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog24
-rw-r--r--src/dired.c45
-rw-r--r--src/w32.c328
3 files changed, 353 insertions, 44 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 888b0f8b7c3..94c2dfc284e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,10 +1,34 @@
12008-05-09 Eli Zaretskii <eliz@gnu.org> 12008-05-09 Eli Zaretskii <eliz@gnu.org>
2 2
3 Support for reporting owner and group of each file on MS-Windows:
4 * dired.c (stat_uname, stat_gname): New functions, with special
5 implementation for w32.
6 (Ffile_attributes): Use them instead of getpwuid and getgrgid.
7
3 * w32.c: Rename the_passwd_* to dflt_passwd_*. 8 * w32.c: Rename the_passwd_* to dflt_passwd_*.
4 (dflt_group_name): New static variable. 9 (dflt_group_name): New static variable.
5 (dflt_group): Renamed from the_group. 10 (dflt_group): Renamed from the_group.
6 (init_user_info): Init dflt_group fields. Get user's group name 11 (init_user_info): Init dflt_group fields. Get user's group name
7 from LookupAccountSid. 12 from LookupAccountSid.
13 (g_b_init_get_file_security, g_b_init_get_security_descriptor_owner)
14 (g_b_init_get_security_descriptor_group, g_b_init_is_valid_sid):
15 New initialization states.
16 (globals_of_w32): Initialize them to zero. Initialize the default
17 group name to "None".
18 (GetFileSecurity_Name): New global var, the name of the function
19 to call for GetFileSecurity.
20 (GetFileSecurity_Proc, GetSecurityDescriptorOwner_Proc)
21 (GetSecurityDescriptorGroup_Proc, IsValidSid_Proc): New typedefs.
22 (get_file_security, get_security_descriptor_owner)
23 (get_security_descriptor_group, is_valid_sid)
24 (get_file_security_desc, get_rid, get_name_and_id)
25 (get_file_owner_and_group): New functions.
26 (stat): Use get_file_security_desc and get_file_owner_and_group to
27 report the owner and primary group of each file. Don't ignore the
28 high 32 bits of file's size, now that st_size is 64-bit wide. Fix
29 test when to get true file attributes.
30 (init_user_info): Use get_rid instead of equivalent inline code.
31 (fstat): Don't ignore the high 32 bits of file's size.
8 32
92008-05-09 Chong Yidong <cyd@stupidchicken.com> 332008-05-09 Chong Yidong <cyd@stupidchicken.com>
10 34
diff --git a/src/dired.c b/src/dired.c
index d3a6e7b7cec..7b4c9166545 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -899,6 +899,36 @@ make_time (time)
899 Fcons (make_number (time & 0177777), Qnil)); 899 Fcons (make_number (time & 0177777), Qnil));
900} 900}
901 901
902static char *
903stat_uname (struct stat *st)
904{
905#ifdef WINDOWSNT
906 return st->st_uname;
907#else
908 struct passwd *pw = (struct passwd *) getpwuid (st->st_uid);
909
910 if (pw)
911 return pw->pw_name;
912 else
913 return NULL;
914#endif
915}
916
917static char *
918stat_gname (struct stat *st)
919{
920#ifdef WINDOWSNT
921 return st->st_gname;
922#else
923 struct group *gr = (struct group *) getgrgid (st->st_gid);
924
925 if (gr)
926 return gr->gr_name;
927 else
928 return NULL;
929#endif
930}
931
902DEFUN ("file-attributes", Ffile_attributes, Sfile_attributes, 1, 2, 0, 932DEFUN ("file-attributes", Ffile_attributes, Sfile_attributes, 1, 2, 0,
903 doc: /* Return a list of attributes of file FILENAME. 933 doc: /* Return a list of attributes of file FILENAME.
904Value is nil if specified file cannot be opened. 934Value is nil if specified file cannot be opened.
@@ -935,8 +965,6 @@ Elements of the attribute list are:
935 Lisp_Object values[12]; 965 Lisp_Object values[12];
936 Lisp_Object encoded; 966 Lisp_Object encoded;
937 struct stat s; 967 struct stat s;
938 struct passwd *pw;
939 struct group *gr;
940#if defined (BSD4_2) || defined (BSD4_3) 968#if defined (BSD4_2) || defined (BSD4_3)
941 Lisp_Object dirname; 969 Lisp_Object dirname;
942 struct stat sdir; 970 struct stat sdir;
@@ -945,6 +973,7 @@ Elements of the attribute list are:
945 Lisp_Object handler; 973 Lisp_Object handler;
946 struct gcpro gcpro1; 974 struct gcpro gcpro1;
947 EMACS_INT ino; 975 EMACS_INT ino;
976 char *uname, *gname;
948 977
949 filename = Fexpand_file_name (filename, Qnil); 978 filename = Fexpand_file_name (filename, Qnil);
950 979
@@ -987,12 +1016,12 @@ Elements of the attribute list are:
987 else 1016 else
988 { 1017 {
989 BLOCK_INPUT; 1018 BLOCK_INPUT;
990 pw = (struct passwd *) getpwuid (s.st_uid); 1019 uname = stat_uname (&s);
991 values[2] = (pw ? build_string (pw->pw_name) 1020 values[2] = (uname ? build_string (uname)
992 : make_fixnum_or_float (s.st_uid)); 1021 : make_fixnum_or_float (s.st_uid));
993 gr = (struct group *) getgrgid (s.st_gid); 1022 gname = stat_gname (&s);
994 values[3] = (gr ? build_string (gr->gr_name) 1023 values[3] = (gname ? build_string (gname)
995 : make_fixnum_or_float (s.st_gid)); 1024 : make_fixnum_or_float (s.st_gid));
996 UNBLOCK_INPUT; 1025 UNBLOCK_INPUT;
997 } 1026 }
998 values[4] = make_time (s.st_atime); 1027 values[4] = make_time (s.st_atime);
diff --git a/src/w32.c b/src/w32.c
index 9b4d18afcfd..8dc61620c02 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -106,6 +106,7 @@ typedef HRESULT (WINAPI * ShGetFolderPath_fn)
106 (IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *); 106 (IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *);
107 107
108void globals_of_w32 (); 108void globals_of_w32 ();
109static DWORD get_rid (PSID);
109 110
110extern Lisp_Object Vw32_downcase_file_names; 111extern Lisp_Object Vw32_downcase_file_names;
111extern Lisp_Object Vw32_generate_fake_inodes; 112extern Lisp_Object Vw32_generate_fake_inodes;
@@ -132,6 +133,10 @@ static BOOL g_b_init_lookup_account_sid;
132static BOOL g_b_init_get_sid_identifier_authority; 133static BOOL g_b_init_get_sid_identifier_authority;
133static BOOL g_b_init_get_sid_sub_authority; 134static BOOL g_b_init_get_sid_sub_authority;
134static BOOL g_b_init_get_sid_sub_authority_count; 135static BOOL g_b_init_get_sid_sub_authority_count;
136static BOOL g_b_init_get_file_security;
137static BOOL g_b_init_get_security_descriptor_owner;
138static BOOL g_b_init_get_security_descriptor_group;
139static BOOL g_b_init_is_valid_sid;
135 140
136/* 141/*
137 BEGIN: Wrapper functions around OpenProcessToken 142 BEGIN: Wrapper functions around OpenProcessToken
@@ -160,8 +165,10 @@ GetProcessTimes_Proc get_process_times_fn = NULL;
160 165
161#ifdef _UNICODE 166#ifdef _UNICODE
162const char * const LookupAccountSid_Name = "LookupAccountSidW"; 167const char * const LookupAccountSid_Name = "LookupAccountSidW";
168const char * const GetFileSecurity_Name = "GetFileSecurityW";
163#else 169#else
164const char * const LookupAccountSid_Name = "LookupAccountSidA"; 170const char * const LookupAccountSid_Name = "LookupAccountSidA";
171const char * const GetFileSecurity_Name = "GetFileSecurityA";
165#endif 172#endif
166typedef BOOL (WINAPI * LookupAccountSid_Proc) ( 173typedef BOOL (WINAPI * LookupAccountSid_Proc) (
167 LPCTSTR lpSystemName, 174 LPCTSTR lpSystemName,
@@ -178,7 +185,22 @@ typedef PDWORD (WINAPI * GetSidSubAuthority_Proc) (
178 DWORD n); 185 DWORD n);
179typedef PUCHAR (WINAPI * GetSidSubAuthorityCount_Proc) ( 186typedef PUCHAR (WINAPI * GetSidSubAuthorityCount_Proc) (
180 PSID pSid); 187 PSID pSid);
181 188typedef BOOL (WINAPI * GetFileSecurity_Proc) (
189 LPCTSTR lpFileName,
190 SECURITY_INFORMATION RequestedInformation,
191 PSECURITY_DESCRIPTOR pSecurityDescriptor,
192 DWORD nLength,
193 LPDWORD lpnLengthNeeded);
194typedef BOOL (WINAPI * GetSecurityDescriptorOwner_Proc) (
195 PSECURITY_DESCRIPTOR pSecurityDescriptor,
196 PSID *pOwner,
197 LPBOOL lpbOwnerDefaulted);
198typedef BOOL (WINAPI * GetSecurityDescriptorGroup_Proc) (
199 PSECURITY_DESCRIPTOR pSecurityDescriptor,
200 PSID *pGroup,
201 LPBOOL lpbGroupDefaulted);
202typedef BOOL (WINAPI * IsValidSid_Proc) (
203 PSID sid);
182 204
183 /* ** A utility function ** */ 205 /* ** A utility function ** */
184static BOOL 206static BOOL
@@ -418,6 +440,114 @@ PUCHAR WINAPI get_sid_sub_authority_count (
418 return (s_pfn_Get_Sid_Sub_Authority_Count (pSid)); 440 return (s_pfn_Get_Sid_Sub_Authority_Count (pSid));
419} 441}
420 442
443BOOL WINAPI get_file_security (
444 LPCTSTR lpFileName,
445 SECURITY_INFORMATION RequestedInformation,
446 PSECURITY_DESCRIPTOR pSecurityDescriptor,
447 DWORD nLength,
448 LPDWORD lpnLengthNeeded)
449{
450 static GetFileSecurity_Proc s_pfn_Get_File_Security = NULL;
451 HMODULE hm_advapi32 = NULL;
452 if (is_windows_9x () == TRUE)
453 {
454 return FALSE;
455 }
456 if (g_b_init_get_file_security == 0)
457 {
458 g_b_init_get_file_security = 1;
459 hm_advapi32 = LoadLibrary ("Advapi32.dll");
460 s_pfn_Get_File_Security =
461 (GetFileSecurity_Proc) GetProcAddress (
462 hm_advapi32, GetFileSecurity_Name);
463 }
464 if (s_pfn_Get_File_Security == NULL)
465 {
466 return FALSE;
467 }
468 return (s_pfn_Get_File_Security (lpFileName, RequestedInformation,
469 pSecurityDescriptor, nLength,
470 lpnLengthNeeded));
471}
472
473BOOL WINAPI get_security_descriptor_owner (
474 PSECURITY_DESCRIPTOR pSecurityDescriptor,
475 PSID *pOwner,
476 LPBOOL lpbOwnerDefaulted)
477{
478 static GetSecurityDescriptorOwner_Proc s_pfn_Get_Security_Descriptor_Owner = NULL;
479 HMODULE hm_advapi32 = NULL;
480 if (is_windows_9x () == TRUE)
481 {
482 return FALSE;
483 }
484 if (g_b_init_get_security_descriptor_owner == 0)
485 {
486 g_b_init_get_security_descriptor_owner = 1;
487 hm_advapi32 = LoadLibrary ("Advapi32.dll");
488 s_pfn_Get_Security_Descriptor_Owner =
489 (GetSecurityDescriptorOwner_Proc) GetProcAddress (
490 hm_advapi32, "GetSecurityDescriptorOwner");
491 }
492 if (s_pfn_Get_Security_Descriptor_Owner == NULL)
493 {
494 return FALSE;
495 }
496 return (s_pfn_Get_Security_Descriptor_Owner (pSecurityDescriptor, pOwner,
497 lpbOwnerDefaulted));
498}
499
500BOOL WINAPI get_security_descriptor_group (
501 PSECURITY_DESCRIPTOR pSecurityDescriptor,
502 PSID *pGroup,
503 LPBOOL lpbGroupDefaulted)
504{
505 static GetSecurityDescriptorGroup_Proc s_pfn_Get_Security_Descriptor_Group = NULL;
506 HMODULE hm_advapi32 = NULL;
507 if (is_windows_9x () == TRUE)
508 {
509 return FALSE;
510 }
511 if (g_b_init_get_security_descriptor_group == 0)
512 {
513 g_b_init_get_security_descriptor_group = 1;
514 hm_advapi32 = LoadLibrary ("Advapi32.dll");
515 s_pfn_Get_Security_Descriptor_Group =
516 (GetSecurityDescriptorGroup_Proc) GetProcAddress (
517 hm_advapi32, "GetSecurityDescriptorGroup");
518 }
519 if (s_pfn_Get_Security_Descriptor_Group == NULL)
520 {
521 return FALSE;
522 }
523 return (s_pfn_Get_Security_Descriptor_Group (pSecurityDescriptor, pGroup,
524 lpbGroupDefaulted));
525}
526
527BOOL WINAPI is_valid_sid (
528 PSID sid)
529{
530 static IsValidSid_Proc s_pfn_Is_Valid_Sid = NULL;
531 HMODULE hm_advapi32 = NULL;
532 if (is_windows_9x () == TRUE)
533 {
534 return FALSE;
535 }
536 if (g_b_init_is_valid_sid == 0)
537 {
538 g_b_init_is_valid_sid = 1;
539 hm_advapi32 = LoadLibrary ("Advapi32.dll");
540 s_pfn_Is_Valid_Sid =
541 (IsValidSid_Proc) GetProcAddress (
542 hm_advapi32, "IsValidSid");
543 }
544 if (s_pfn_Is_Valid_Sid == NULL)
545 {
546 return FALSE;
547 }
548 return (s_pfn_Is_Valid_Sid (sid));
549}
550
421/* 551/*
422 END: Wrapper functions around OpenProcessToken 552 END: Wrapper functions around OpenProcessToken
423 and other functions in advapi32.dll that are only 553 and other functions in advapi32.dll that are only
@@ -616,8 +746,6 @@ init_user_info ()
616 TOKEN_USER user_token; 746 TOKEN_USER user_token;
617 TOKEN_PRIMARY_GROUP group_token; 747 TOKEN_PRIMARY_GROUP group_token;
618 748
619 /* "None" is the default group name on standalone workstations. */
620 strcpy (dflt_group_name, "None");
621 if (open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token) 749 if (open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token)
622 && get_token_information (token, TokenUser, 750 && get_token_information (token, TokenUser,
623 (PVOID)buf, sizeof (buf), &trash) 751 (PVOID)buf, sizeof (buf), &trash)
@@ -636,34 +764,14 @@ init_user_info ()
636 { 764 {
637 /* Use the last sub-authority value of the RID, the relative 765 /* Use the last sub-authority value of the RID, the relative
638 portion of the SID, as user/group ID. */ 766 portion of the SID, as user/group ID. */
639 DWORD n_subauthorities = 767 dflt_passwd.pw_uid = get_rid (user_token.User.Sid);
640 *get_sid_sub_authority_count (user_token.User.Sid);
641
642 if (n_subauthorities < 1)
643 dflt_passwd.pw_uid = 0; /* the "World" RID */
644 else
645 {
646 dflt_passwd.pw_uid =
647 *get_sid_sub_authority (user_token.User.Sid,
648 n_subauthorities - 1);
649 }
650 768
651 /* Get group id */ 769 /* Get group id and name. */
652 if (get_token_information (token, TokenPrimaryGroup, 770 if (get_token_information (token, TokenPrimaryGroup,
653 (PVOID)buf, sizeof (buf), &trash)) 771 (PVOID)buf, sizeof (buf), &trash))
654 { 772 {
655 memcpy (&group_token, buf, sizeof (group_token)); 773 memcpy (&group_token, buf, sizeof (group_token));
656 n_subauthorities = 774 dflt_passwd.pw_gid = get_rid (group_token.PrimaryGroup);
657 *get_sid_sub_authority_count (group_token.PrimaryGroup);
658
659 if (n_subauthorities < 1)
660 dflt_passwd.pw_gid = 0; /* the "World" RID */
661 else
662 {
663 dflt_passwd.pw_gid =
664 *get_sid_sub_authority (group_token.PrimaryGroup,
665 n_subauthorities - 1);
666 }
667 dlength = sizeof (domain); 775 dlength = sizeof (domain);
668 if (lookup_account_sid (NULL, group_token.PrimaryGroup, 776 if (lookup_account_sid (NULL, group_token.PrimaryGroup,
669 gname, &glength, NULL, &dlength, 777 gname, &glength, NULL, &dlength,
@@ -2548,6 +2656,136 @@ generate_inode_val (const char * name)
2548 2656
2549#endif 2657#endif
2550 2658
2659static PSECURITY_DESCRIPTOR
2660get_file_security_desc (const char *fname)
2661{
2662 PSECURITY_DESCRIPTOR psd = NULL;
2663 DWORD sd_len, err;
2664 SECURITY_INFORMATION si = OWNER_SECURITY_INFORMATION
2665 | GROUP_SECURITY_INFORMATION /* | DACL_SECURITY_INFORMATION */ ;
2666
2667 if (!get_file_security (fname, si, psd, 0, &sd_len))
2668 {
2669 err = GetLastError ();
2670 if (err != ERROR_INSUFFICIENT_BUFFER)
2671 return NULL;
2672 }
2673
2674 psd = xmalloc (sd_len);
2675 if (!get_file_security (fname, si, psd, sd_len, &sd_len))
2676 {
2677 xfree (psd);
2678 return NULL;
2679 }
2680
2681 return psd;
2682}
2683
2684static DWORD
2685get_rid (PSID sid)
2686{
2687 unsigned n_subauthorities;
2688
2689 /* Use the last sub-authority value of the RID, the relative
2690 portion of the SID, as user/group ID. */
2691 n_subauthorities = *get_sid_sub_authority_count (sid);
2692 if (n_subauthorities < 1)
2693 return 0; /* the "World" RID */
2694 return *get_sid_sub_authority (sid, n_subauthorities - 1);
2695}
2696
2697#define UID 1
2698#define GID 2
2699
2700static int
2701get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname,
2702 int *id, char *nm, int what)
2703{
2704 PSID sid = NULL;
2705 char machine[MAX_COMPUTERNAME_LENGTH+1];
2706 BOOL dflt;
2707 SID_NAME_USE ignore;
2708 char name[UNLEN+1];
2709 DWORD name_len = sizeof (name);
2710 char domain[1024];
2711 DWORD domain_len = sizeof(domain);
2712 char *mp = NULL;
2713 int use_dflt = 0;
2714 int result;
2715
2716 if (what == UID)
2717 result = get_security_descriptor_owner (psd, &sid, &dflt);
2718 else if (what == GID)
2719 result = get_security_descriptor_group (psd, &sid, &dflt);
2720 else
2721 result = 0;
2722
2723 if (!result || !is_valid_sid (sid))
2724 use_dflt = 1;
2725 else
2726 {
2727 /* If FNAME is a UNC, we need to lookup account on the
2728 specified machine. */
2729 if (IS_DIRECTORY_SEP (fname[0]) && IS_DIRECTORY_SEP (fname[1])
2730 && fname[2] != '\0')
2731 {
2732 const char *s;
2733 char *p;
2734
2735 for (s = fname + 2, p = machine;
2736 *s && !IS_DIRECTORY_SEP (*s); s++, p++)
2737 *p = *s;
2738 *p = '\0';
2739 mp = machine;
2740 }
2741
2742 if (!lookup_account_sid (mp, sid, name, &name_len,
2743 domain, &domain_len, &ignore)
2744 || name_len > UNLEN+1)
2745 use_dflt = 1;
2746 else
2747 {
2748 *id = get_rid (sid);
2749 strcpy (nm, name);
2750 }
2751 }
2752 return use_dflt;
2753}
2754
2755static void
2756get_file_owner_and_group (
2757 PSECURITY_DESCRIPTOR psd,
2758 const char *fname,
2759 struct stat *st)
2760{
2761 int dflt_usr = 0, dflt_grp = 0;
2762
2763 if (!psd)
2764 {
2765 dflt_usr = 1;
2766 dflt_grp = 1;
2767 }
2768 else
2769 {
2770 if (get_name_and_id (psd, fname, &st->st_uid, st->st_uname, UID))
2771 dflt_usr = 1;
2772 if (get_name_and_id (psd, fname, &st->st_gid, st->st_gname, GID))
2773 dflt_grp = 1;
2774 }
2775 /* Consider files to belong to current user/group, if we cannot get
2776 more accurate information. */
2777 if (dflt_usr)
2778 {
2779 st->st_uid = dflt_passwd.pw_uid;
2780 strcpy (st->st_uname, dflt_passwd.pw_name);
2781 }
2782 if (dflt_grp)
2783 {
2784 st->st_gid = dflt_passwd.pw_gid;
2785 strcpy (st->st_gname, dflt_group.gr_name);
2786 }
2787}
2788
2551/* MSVC stat function can't cope with UNC names and has other bugs, so 2789/* MSVC stat function can't cope with UNC names and has other bugs, so
2552 replace it with our own. This also allows us to calculate consistent 2790 replace it with our own. This also allows us to calculate consistent
2553 inode values without hacks in the main Emacs code. */ 2791 inode values without hacks in the main Emacs code. */
@@ -2561,6 +2799,7 @@ stat (const char * path, struct stat * buf)
2561 int permission; 2799 int permission;
2562 int len; 2800 int len;
2563 int rootdir = FALSE; 2801 int rootdir = FALSE;
2802 PSECURITY_DESCRIPTOR psd = NULL;
2564 2803
2565 if (path == NULL || buf == NULL) 2804 if (path == NULL || buf == NULL)
2566 { 2805 {
@@ -2658,9 +2897,9 @@ stat (const char * path, struct stat * buf)
2658 } 2897 }
2659 } 2898 }
2660 2899
2661 if (!NILP (Vw32_get_true_file_attributes) 2900 if (!(NILP (Vw32_get_true_file_attributes)
2662 && !(EQ (Vw32_get_true_file_attributes, Qlocal) && 2901 || (EQ (Vw32_get_true_file_attributes, Qlocal) &&
2663 GetDriveType (name) == DRIVE_FIXED) 2902 GetDriveType (name) != DRIVE_FIXED)))
2664 /* No access rights required to get info. */ 2903 /* No access rights required to get info. */
2665 && (fh = CreateFile (name, 0, 0, NULL, OPEN_EXISTING, 2904 && (fh = CreateFile (name, 0, 0, NULL, OPEN_EXISTING,
2666 FILE_FLAG_BACKUP_SEMANTICS, NULL)) 2905 FILE_FLAG_BACKUP_SEMANTICS, NULL))
@@ -2710,6 +2949,8 @@ stat (const char * path, struct stat * buf)
2710 } 2949 }
2711 } 2950 }
2712 CloseHandle (fh); 2951 CloseHandle (fh);
2952 psd = get_file_security_desc (name);
2953 get_file_owner_and_group (psd, name, buf);
2713 } 2954 }
2714 else 2955 else
2715 { 2956 {
@@ -2718,7 +2959,11 @@ stat (const char * path, struct stat * buf)
2718 S_IFDIR : S_IFREG; 2959 S_IFDIR : S_IFREG;
2719 buf->st_nlink = 1; 2960 buf->st_nlink = 1;
2720 fake_inode = 0; 2961 fake_inode = 0;
2962
2963 get_file_owner_and_group (NULL, name, buf);
2721 } 2964 }
2965 if (psd)
2966 xfree (psd);
2722 2967
2723#if 0 2968#if 0
2724 /* Not sure if there is any point in this. */ 2969 /* Not sure if there is any point in this. */
@@ -2738,16 +2983,14 @@ stat (const char * path, struct stat * buf)
2738 else 2983 else
2739 buf->st_ino = fake_inode; 2984 buf->st_ino = fake_inode;
2740 2985
2741 /* consider files to belong to current user */
2742 buf->st_uid = dflt_passwd.pw_uid;
2743 buf->st_gid = dflt_passwd.pw_gid;
2744
2745 /* volume_info is set indirectly by map_w32_filename */ 2986 /* volume_info is set indirectly by map_w32_filename */
2746 buf->st_dev = volume_info.serialnum; 2987 buf->st_dev = volume_info.serialnum;
2747 buf->st_rdev = volume_info.serialnum; 2988 buf->st_rdev = volume_info.serialnum;
2748 2989
2749 2990
2750 buf->st_size = wfd.nFileSizeLow; 2991 buf->st_size = wfd.nFileSizeHigh;
2992 buf->st_size <<= 32;
2993 buf->st_size += wfd.nFileSizeLow;
2751 2994
2752 /* Convert timestamps to Unix format. */ 2995 /* Convert timestamps to Unix format. */
2753 buf->st_mtime = convert_time (wfd.ftLastWriteTime); 2996 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
@@ -2826,14 +3069,20 @@ fstat (int desc, struct stat * buf)
2826 else 3069 else
2827 buf->st_ino = fake_inode; 3070 buf->st_ino = fake_inode;
2828 3071
2829 /* consider files to belong to current user */ 3072 /* Consider files to belong to current user.
3073 FIXME: this should use GetSecurityInfo API, but it is only
3074 available for _WIN32_WINNT >= 0x501. */
2830 buf->st_uid = dflt_passwd.pw_uid; 3075 buf->st_uid = dflt_passwd.pw_uid;
2831 buf->st_gid = dflt_passwd.pw_gid; 3076 buf->st_gid = dflt_passwd.pw_gid;
3077 strcpy (buf->st_uname, dflt_passwd.pw_name);
3078 strcpy (buf->st_gname, dflt_group.gr_name);
2832 3079
2833 buf->st_dev = info.dwVolumeSerialNumber; 3080 buf->st_dev = info.dwVolumeSerialNumber;
2834 buf->st_rdev = info.dwVolumeSerialNumber; 3081 buf->st_rdev = info.dwVolumeSerialNumber;
2835 3082
2836 buf->st_size = info.nFileSizeLow; 3083 buf->st_size = info.nFileSizeHigh;
3084 buf->st_size <<= 32;
3085 buf->st_size += info.nFileSizeLow;
2837 3086
2838 /* Convert timestamps to Unix format. */ 3087 /* Convert timestamps to Unix format. */
2839 buf->st_mtime = convert_time (info.ftLastWriteTime); 3088 buf->st_mtime = convert_time (info.ftLastWriteTime);
@@ -4350,11 +4599,18 @@ globals_of_w32 ()
4350 g_b_init_get_sid_identifier_authority = 0; 4599 g_b_init_get_sid_identifier_authority = 0;
4351 g_b_init_get_sid_sub_authority = 0; 4600 g_b_init_get_sid_sub_authority = 0;
4352 g_b_init_get_sid_sub_authority_count = 0; 4601 g_b_init_get_sid_sub_authority_count = 0;
4602 g_b_init_get_file_security = 0;
4603 g_b_init_get_security_descriptor_owner = 0;
4604 g_b_init_get_security_descriptor_group = 0;
4605 g_b_init_is_valid_sid = 0;
4353 /* The following sets a handler for shutdown notifications for 4606 /* The following sets a handler for shutdown notifications for
4354 console apps. This actually applies to Emacs in both console and 4607 console apps. This actually applies to Emacs in both console and
4355 GUI modes, since we had to fool windows into thinking emacs is a 4608 GUI modes, since we had to fool windows into thinking emacs is a
4356 console application to get console mode to work. */ 4609 console application to get console mode to work. */
4357 SetConsoleCtrlHandler(shutdown_handler, TRUE); 4610 SetConsoleCtrlHandler(shutdown_handler, TRUE);
4611
4612 /* "None" is the default group name on standalone workstations. */
4613 strcpy (dflt_group_name, "None");
4358} 4614}
4359 4615
4360/* end of w32.c */ 4616/* end of w32.c */