comparison src/w32.c @ 97491:bb6b5c0fc1ba

(CopySid_Proc, EqualSid_Proc, GetLengthSid_Proc): New typedefs. (equal_sid, get_length_sid, copy_sid): New wrapper functions. (w32_cached_id, w32_add_to_cache): New functions. (get_name_and_id): Look account names in the cache before calling lookup_account_sid. (g_b_init_get_length_sid, g_b_init_equal_sid, g_b_init_copy_sid): New initialization flags. (globals_of_w32): Initialize them to zero. (w32_system_process_attributes): Use w32_cached_id and w32_add_to_cache.
author Eli Zaretskii <eliz@gnu.org>
date Fri, 15 Aug 2008 15:59:48 +0000
parents caf9103a3856
children 1f8e4a26957e
comparison
equal deleted inserted replaced
97490:f8337cc2c494 97491:bb6b5c0fc1ba
186 static BOOL g_b_init_revert_to_self; 186 static BOOL g_b_init_revert_to_self;
187 static BOOL g_b_init_get_process_memory_info; 187 static BOOL g_b_init_get_process_memory_info;
188 static BOOL g_b_init_get_process_working_set_size; 188 static BOOL g_b_init_get_process_working_set_size;
189 static BOOL g_b_init_global_memory_status; 189 static BOOL g_b_init_global_memory_status;
190 static BOOL g_b_init_global_memory_status_ex; 190 static BOOL g_b_init_global_memory_status_ex;
191 static BOOL g_b_init_get_length_sid;
192 static BOOL g_b_init_equal_sid;
193 static BOOL g_b_init_copy_sid;
191 194
192 /* 195 /*
193 BEGIN: Wrapper functions around OpenProcessToken 196 BEGIN: Wrapper functions around OpenProcessToken
194 and other functions in advapi32.dll that are only 197 and other functions in advapi32.dll that are only
195 supported in Windows NT / 2k / XP 198 supported in Windows NT / 2k / XP
279 DWORD * lpMaximumWorkingSetSize); 282 DWORD * lpMaximumWorkingSetSize);
280 typedef BOOL (WINAPI * GlobalMemoryStatus_Proc) ( 283 typedef BOOL (WINAPI * GlobalMemoryStatus_Proc) (
281 LPMEMORYSTATUS lpBuffer); 284 LPMEMORYSTATUS lpBuffer);
282 typedef BOOL (WINAPI * GlobalMemoryStatusEx_Proc) ( 285 typedef BOOL (WINAPI * GlobalMemoryStatusEx_Proc) (
283 LPMEMORY_STATUS_EX lpBuffer); 286 LPMEMORY_STATUS_EX lpBuffer);
287 typedef BOOL (WINAPI * CopySid_Proc) (
288 DWORD nDestinationSidLength,
289 PSID pDestinationSid,
290 PSID pSourceSid);
291 typedef BOOL (WINAPI * EqualSid_Proc) (
292 PSID pSid1,
293 PSID pSid2);
294 typedef DWORD (WINAPI * GetLengthSid_Proc) (
295 PSID pSid);
296
297
284 298
285 /* ** A utility function ** */ 299 /* ** A utility function ** */
286 static BOOL 300 static BOOL
287 is_windows_9x () 301 is_windows_9x ()
288 { 302 {
624 if (s_pfn_Is_Valid_Sid == NULL) 638 if (s_pfn_Is_Valid_Sid == NULL)
625 { 639 {
626 return FALSE; 640 return FALSE;
627 } 641 }
628 return (s_pfn_Is_Valid_Sid (sid)); 642 return (s_pfn_Is_Valid_Sid (sid));
643 }
644
645 BOOL WINAPI equal_sid (
646 PSID sid1,
647 PSID sid2)
648 {
649 static EqualSid_Proc s_pfn_Equal_Sid = NULL;
650 HMODULE hm_advapi32 = NULL;
651 if (is_windows_9x () == TRUE)
652 {
653 return FALSE;
654 }
655 if (g_b_init_equal_sid == 0)
656 {
657 g_b_init_equal_sid = 1;
658 hm_advapi32 = LoadLibrary ("Advapi32.dll");
659 s_pfn_Equal_Sid =
660 (EqualSid_Proc) GetProcAddress (
661 hm_advapi32, "EqualSid");
662 }
663 if (s_pfn_Equal_Sid == NULL)
664 {
665 return FALSE;
666 }
667 return (s_pfn_Equal_Sid (sid1, sid2));
668 }
669
670 DWORD WINAPI get_length_sid (
671 PSID sid)
672 {
673 static GetLengthSid_Proc s_pfn_Get_Length_Sid = NULL;
674 HMODULE hm_advapi32 = NULL;
675 if (is_windows_9x () == TRUE)
676 {
677 return 0;
678 }
679 if (g_b_init_get_length_sid == 0)
680 {
681 g_b_init_get_length_sid = 1;
682 hm_advapi32 = LoadLibrary ("Advapi32.dll");
683 s_pfn_Get_Length_Sid =
684 (GetLengthSid_Proc) GetProcAddress (
685 hm_advapi32, "GetLengthSid");
686 }
687 if (s_pfn_Get_Length_Sid == NULL)
688 {
689 return 0;
690 }
691 return (s_pfn_Get_Length_Sid (sid));
692 }
693
694 BOOL WINAPI copy_sid (
695 DWORD destlen,
696 PSID dest,
697 PSID src)
698 {
699 static CopySid_Proc s_pfn_Copy_Sid = NULL;
700 HMODULE hm_advapi32 = NULL;
701 if (is_windows_9x () == TRUE)
702 {
703 return FALSE;
704 }
705 if (g_b_init_copy_sid == 0)
706 {
707 g_b_init_copy_sid = 1;
708 hm_advapi32 = LoadLibrary ("Advapi32.dll");
709 s_pfn_Copy_Sid =
710 (CopySid_Proc) GetProcAddress (
711 hm_advapi32, "CopySid");
712 }
713 if (s_pfn_Copy_Sid == NULL)
714 {
715 return FALSE;
716 }
717 return (s_pfn_Copy_Sid (destlen, dest, src));
629 } 718 }
630 719
631 /* 720 /*
632 END: Wrapper functions around OpenProcessToken 721 END: Wrapper functions around OpenProcessToken
633 and other functions in advapi32.dll that are only 722 and other functions in advapi32.dll that are only
2778 if (n_subauthorities < 1) 2867 if (n_subauthorities < 1)
2779 return 0; /* the "World" RID */ 2868 return 0; /* the "World" RID */
2780 return *get_sid_sub_authority (sid, n_subauthorities - 1); 2869 return *get_sid_sub_authority (sid, n_subauthorities - 1);
2781 } 2870 }
2782 2871
2872 /* Caching SID and account values for faster lokup. */
2873
2874 #ifdef __GNUC__
2875 # define FLEXIBLE_ARRAY_MEMBER
2876 #else
2877 # define FLEXIBLE_ARRAY_MEMBER 1
2878 #endif
2879
2880 struct w32_id {
2881 int rid;
2882 struct w32_id *next;
2883 char name[GNLEN+1];
2884 unsigned char sid[FLEXIBLE_ARRAY_MEMBER];
2885 };
2886
2887 static struct w32_id *w32_idlist;
2888
2889 static int
2890 w32_cached_id (PSID sid, int *id, char *name)
2891 {
2892 struct w32_id *tail, *found;
2893
2894 for (found = NULL, tail = w32_idlist; tail; tail = tail->next)
2895 {
2896 if (equal_sid ((PSID)tail->sid, sid))
2897 {
2898 found = tail;
2899 break;
2900 }
2901 }
2902 if (found)
2903 {
2904 *id = found->rid;
2905 strcpy (name, found->name);
2906 return 1;
2907 }
2908 else
2909 return 0;
2910 }
2911
2912 static void
2913 w32_add_to_cache (PSID sid, int id, char *name)
2914 {
2915 DWORD sid_len;
2916 struct w32_id *new_entry;
2917
2918 /* We don't want to leave behind stale cache from when Emacs was
2919 dumped. */
2920 if (initialized)
2921 {
2922 sid_len = get_length_sid (sid);
2923 new_entry = xmalloc (offsetof (struct w32_id, sid) + sid_len);
2924 if (new_entry)
2925 {
2926 new_entry->rid = id;
2927 strcpy (new_entry->name, name);
2928 copy_sid (sid_len, (PSID)new_entry->sid, sid);
2929 new_entry->next = w32_idlist;
2930 w32_idlist = new_entry;
2931 }
2932 }
2933 }
2934
2783 #define UID 1 2935 #define UID 1
2784 #define GID 2 2936 #define GID 2
2785 2937
2786 static int 2938 static int
2787 get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname, 2939 get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname,
2806 else 2958 else
2807 result = 0; 2959 result = 0;
2808 2960
2809 if (!result || !is_valid_sid (sid)) 2961 if (!result || !is_valid_sid (sid))
2810 use_dflt = 1; 2962 use_dflt = 1;
2811 else 2963 else if (!w32_cached_id (sid, id, nm))
2812 { 2964 {
2813 /* If FNAME is a UNC, we need to lookup account on the 2965 /* If FNAME is a UNC, we need to lookup account on the
2814 specified machine. */ 2966 specified machine. */
2815 if (IS_DIRECTORY_SEP (fname[0]) && IS_DIRECTORY_SEP (fname[1]) 2967 if (IS_DIRECTORY_SEP (fname[0]) && IS_DIRECTORY_SEP (fname[1])
2816 && fname[2] != '\0') 2968 && fname[2] != '\0')
2831 use_dflt = 1; 2983 use_dflt = 1;
2832 else 2984 else
2833 { 2985 {
2834 *id = get_rid (sid); 2986 *id = get_rid (sid);
2835 strcpy (nm, name); 2987 strcpy (nm, name);
2988 w32_add_to_cache (sid, *id, name);
2836 } 2989 }
2837 } 2990 }
2838 return use_dflt; 2991 return use_dflt;
2839 } 2992 }
2840 2993
3746 } 3899 }
3747 } 3900 }
3748 if (h_proc 3901 if (h_proc
3749 && open_process_token (h_proc, TOKEN_QUERY, &token) 3902 && open_process_token (h_proc, TOKEN_QUERY, &token)
3750 && get_token_information (token, TokenUser, 3903 && get_token_information (token, TokenUser,
3751 (PVOID)buf, sizeof (buf), &trash) 3904 (PVOID)buf, sizeof (buf), &trash))
3752 && (memcpy (&user_token, buf, sizeof (user_token)), 3905 {
3906 memcpy (&user_token, buf, sizeof (user_token));
3907 if (w32_cached_id (user_token.User.Sid, &euid, uname))
3908 ulength = strlen (uname);
3909 else
3910 {
3753 lookup_account_sid (NULL, user_token.User.Sid, uname, &ulength, 3911 lookup_account_sid (NULL, user_token.User.Sid, uname, &ulength,
3754 domain, &dlength, &user_type))) 3912 domain, &dlength, &user_type);
3755 { 3913 euid = get_rid (user_token.User.Sid);
3914 w32_add_to_cache (user_token.User.Sid, euid, uname);
3915 }
3756 /* Determine a reasonable euid and gid values. */ 3916 /* Determine a reasonable euid and gid values. */
3757 if (xstrcasecmp ("administrator", uname) == 0) 3917 if (xstrcasecmp ("administrator", uname) == 0)
3758 { 3918 {
3759 euid = 500; /* well-known Administrator uid */ 3919 euid = 500; /* well-known Administrator uid */
3760 egid = 513; /* well-known None gid */ 3920 egid = 513; /* well-known None gid */
3761 } 3921 }
3762 else 3922 else
3763 { 3923 {
3764 /* Use the last sub-authority value of the RID, the relative
3765 portion of the SID, as user/group ID. */
3766 euid = get_rid (user_token.User.Sid);
3767
3768 /* Get group id and name. */ 3924 /* Get group id and name. */
3769 if (get_token_information (token, TokenPrimaryGroup, 3925 if (get_token_information (token, TokenPrimaryGroup,
3770 (PVOID)buf, sizeof (buf), &trash)) 3926 (PVOID)buf, sizeof (buf), &trash))
3771 { 3927 {
3772 memcpy (&group_token, buf, sizeof (group_token)); 3928 memcpy (&group_token, buf, sizeof (group_token));
3773 egid = get_rid (group_token.PrimaryGroup); 3929 if (w32_cached_id (group_token.PrimaryGroup, &egid, gname))
3774 dlength = sizeof (domain); 3930 glength = strlen (gname);
3775 lookup_account_sid (NULL, group_token.PrimaryGroup, 3931 else
3776 gname, &glength, NULL, &dlength, 3932 {
3777 &user_type); 3933 dlength = sizeof (domain);
3934 lookup_account_sid (NULL, group_token.PrimaryGroup,
3935 gname, &glength, NULL, &dlength,
3936 &user_type);
3937 egid = get_rid (group_token.PrimaryGroup);
3938 w32_add_to_cache (group_token.PrimaryGroup, egid, gname);
3939 }
3778 } 3940 }
3779 else 3941 else
3780 egid = euid; 3942 egid = euid;
3781 } 3943 }
3782 } 3944 }
5455 g_b_init_revert_to_self = 0; 5617 g_b_init_revert_to_self = 0;
5456 g_b_init_get_process_memory_info = 0; 5618 g_b_init_get_process_memory_info = 0;
5457 g_b_init_get_process_working_set_size = 0; 5619 g_b_init_get_process_working_set_size = 0;
5458 g_b_init_global_memory_status = 0; 5620 g_b_init_global_memory_status = 0;
5459 g_b_init_global_memory_status_ex = 0; 5621 g_b_init_global_memory_status_ex = 0;
5622 g_b_init_equal_sid = 0;
5623 g_b_init_copy_sid = 0;
5624 g_b_init_get_length_sid = 0;
5460 /* The following sets a handler for shutdown notifications for 5625 /* The following sets a handler for shutdown notifications for
5461 console apps. This actually applies to Emacs in both console and 5626 console apps. This actually applies to Emacs in both console and
5462 GUI modes, since we had to fool windows into thinking emacs is a 5627 GUI modes, since we had to fool windows into thinking emacs is a
5463 console application to get console mode to work. */ 5628 console application to get console mode to work. */
5464 SetConsoleCtrlHandler(shutdown_handler, TRUE); 5629 SetConsoleCtrlHandler(shutdown_handler, TRUE);