aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32.c
diff options
context:
space:
mode:
authorEli Zaretskii2008-08-15 16:00:19 +0000
committerEli Zaretskii2008-08-15 16:00:19 +0000
commitf8b35b24ae6fa411f0dad2fb04c25ecd7dfc4f52 (patch)
tree9223165d90b38f04ea64fe8c90fc6242d8e73804 /src/w32.c
parenta644b2e42cf86022603ecfa15c59a637f311a95d (diff)
downloademacs-f8b35b24ae6fa411f0dad2fb04c25ecd7dfc4f52.tar.gz
emacs-f8b35b24ae6fa411f0dad2fb04c25ecd7dfc4f52.zip
(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.
Diffstat (limited to 'src/w32.c')
-rw-r--r--src/w32.c193
1 files changed, 179 insertions, 14 deletions
diff --git a/src/w32.c b/src/w32.c
index ddb48981c58..483375dc0df 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -188,6 +188,9 @@ static BOOL g_b_init_get_process_memory_info;
188static BOOL g_b_init_get_process_working_set_size; 188static BOOL g_b_init_get_process_working_set_size;
189static BOOL g_b_init_global_memory_status; 189static BOOL g_b_init_global_memory_status;
190static BOOL g_b_init_global_memory_status_ex; 190static BOOL g_b_init_global_memory_status_ex;
191static BOOL g_b_init_get_length_sid;
192static BOOL g_b_init_equal_sid;
193static BOOL g_b_init_copy_sid;
191 194
192/* 195/*
193 BEGIN: Wrapper functions around OpenProcessToken 196 BEGIN: Wrapper functions around OpenProcessToken
@@ -281,6 +284,17 @@ typedef BOOL (WINAPI * GlobalMemoryStatus_Proc) (
281 LPMEMORYSTATUS lpBuffer); 284 LPMEMORYSTATUS lpBuffer);
282typedef BOOL (WINAPI * GlobalMemoryStatusEx_Proc) ( 285typedef BOOL (WINAPI * GlobalMemoryStatusEx_Proc) (
283 LPMEMORY_STATUS_EX lpBuffer); 286 LPMEMORY_STATUS_EX lpBuffer);
287typedef BOOL (WINAPI * CopySid_Proc) (
288 DWORD nDestinationSidLength,
289 PSID pDestinationSid,
290 PSID pSourceSid);
291typedef BOOL (WINAPI * EqualSid_Proc) (
292 PSID pSid1,
293 PSID pSid2);
294typedef DWORD (WINAPI * GetLengthSid_Proc) (
295 PSID pSid);
296
297
284 298
285 /* ** A utility function ** */ 299 /* ** A utility function ** */
286static BOOL 300static BOOL
@@ -628,6 +642,81 @@ BOOL WINAPI is_valid_sid (
628 return (s_pfn_Is_Valid_Sid (sid)); 642 return (s_pfn_Is_Valid_Sid (sid));
629} 643}
630 644
645BOOL 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
670DWORD 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
694BOOL 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));
718}
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
@@ -2780,6 +2869,69 @@ get_rid (PSID sid)
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
2880struct w32_id {
2881 int rid;
2882 struct w32_id *next;
2883 char name[GNLEN+1];
2884 unsigned char sid[FLEXIBLE_ARRAY_MEMBER];
2885};
2886
2887static struct w32_id *w32_idlist;
2888
2889static int
2890w32_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
2912static void
2913w32_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
@@ -2808,7 +2960,7 @@ get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname,
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. */
@@ -2833,6 +2985,7 @@ get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname,
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;
@@ -3748,11 +3901,18 @@ w32_system_process_attributes (pid)
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)),
3753 lookup_account_sid (NULL, user_token.User.Sid, uname, &ulength,
3754 domain, &dlength, &user_type)))
3755 { 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 {
3911 lookup_account_sid (NULL, user_token.User.Sid, uname, &ulength,
3912 domain, &dlength, &user_type);
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 {
@@ -3761,20 +3921,22 @@ w32_system_process_attributes (pid)
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;
@@ -5457,6 +5619,9 @@ globals_of_w32 ()
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