Mercurial > emacs
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); |