99 |
#include "w32heap.h" |
#include "w32heap.h" |
100 |
#include "systime.h" |
#include "systime.h" |
101 |
|
|
102 |
|
void globals_of_w32 (); |
103 |
|
|
104 |
extern Lisp_Object Vw32_downcase_file_names; |
extern Lisp_Object Vw32_downcase_file_names; |
105 |
extern Lisp_Object Vw32_generate_fake_inodes; |
extern Lisp_Object Vw32_generate_fake_inodes; |
106 |
extern Lisp_Object Vw32_get_true_file_attributes; |
extern Lisp_Object Vw32_get_true_file_attributes; |
107 |
extern Lisp_Object Vw32_num_mouse_buttons; |
extern Lisp_Object Vw32_num_mouse_buttons; |
108 |
|
|
109 |
|
|
110 |
|
/* |
111 |
|
Initialization states |
112 |
|
*/ |
113 |
|
static BOOL g_b_init_is_windows_9x; |
114 |
|
static BOOL g_b_init_open_process_token; |
115 |
|
static BOOL g_b_init_get_token_information; |
116 |
|
static BOOL g_b_init_lookup_account_sid; |
117 |
|
static BOOL g_b_init_get_sid_identifier_authority; |
118 |
|
|
119 |
|
/* |
120 |
|
BEGIN: Wrapper functions around OpenProcessToken |
121 |
|
and other functions in advapi32.dll that are only |
122 |
|
supported in Windows NT / 2k / XP |
123 |
|
*/ |
124 |
|
/* ** Function pointer typedefs ** */ |
125 |
|
typedef BOOL (WINAPI * OpenProcessToken_Proc) ( |
126 |
|
HANDLE ProcessHandle, |
127 |
|
DWORD DesiredAccess, |
128 |
|
PHANDLE TokenHandle); |
129 |
|
typedef BOOL (WINAPI * GetTokenInformation_Proc) ( |
130 |
|
HANDLE TokenHandle, |
131 |
|
TOKEN_INFORMATION_CLASS TokenInformationClass, |
132 |
|
LPVOID TokenInformation, |
133 |
|
DWORD TokenInformationLength, |
134 |
|
PDWORD ReturnLength); |
135 |
|
#ifdef _UNICODE |
136 |
|
const char * const LookupAccountSid_Name = "LookupAccountSidW"; |
137 |
|
#else |
138 |
|
const char * const LookupAccountSid_Name = "LookupAccountSidA"; |
139 |
|
#endif |
140 |
|
typedef BOOL (WINAPI * LookupAccountSid_Proc) ( |
141 |
|
LPCTSTR lpSystemName, |
142 |
|
PSID Sid, |
143 |
|
LPTSTR Name, |
144 |
|
LPDWORD cbName, |
145 |
|
LPTSTR DomainName, |
146 |
|
LPDWORD cbDomainName, |
147 |
|
PSID_NAME_USE peUse); |
148 |
|
typedef PSID_IDENTIFIER_AUTHORITY (WINAPI * GetSidIdentifierAuthority_Proc) ( |
149 |
|
PSID pSid); |
150 |
|
|
151 |
|
/* ** A utility function ** */ |
152 |
|
static BOOL is_windows_9x () |
153 |
|
{ |
154 |
|
static BOOL s_b_ret=0; |
155 |
|
OSVERSIONINFO os_ver; |
156 |
|
if (g_b_init_is_windows_9x == 0) |
157 |
|
{ |
158 |
|
g_b_init_is_windows_9x = 1; |
159 |
|
ZeroMemory(&os_ver, sizeof(OSVERSIONINFO)); |
160 |
|
os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
161 |
|
if (GetVersionEx (&os_ver)) |
162 |
|
{ |
163 |
|
s_b_ret = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); |
164 |
|
} |
165 |
|
} |
166 |
|
return s_b_ret; |
167 |
|
} |
168 |
|
|
169 |
|
/* ** The wrapper functions ** */ |
170 |
|
|
171 |
|
BOOL WINAPI open_process_token ( |
172 |
|
HANDLE ProcessHandle, |
173 |
|
DWORD DesiredAccess, |
174 |
|
PHANDLE TokenHandle) |
175 |
|
{ |
176 |
|
static OpenProcessToken_Proc s_pfn_Open_Process_Token = NULL; |
177 |
|
HMODULE hm_advapi32 = NULL; |
178 |
|
if (is_windows_9x () == TRUE) |
179 |
|
{ |
180 |
|
return FALSE; |
181 |
|
} |
182 |
|
if (g_b_init_open_process_token == 0) |
183 |
|
{ |
184 |
|
g_b_init_open_process_token = 1; |
185 |
|
hm_advapi32 = LoadLibrary ("Advapi32.dll"); |
186 |
|
s_pfn_Open_Process_Token = |
187 |
|
(OpenProcessToken_Proc) GetProcAddress (hm_advapi32, "OpenProcessToken"); |
188 |
|
} |
189 |
|
if (s_pfn_Open_Process_Token == NULL) |
190 |
|
{ |
191 |
|
return FALSE; |
192 |
|
} |
193 |
|
return ( |
194 |
|
s_pfn_Open_Process_Token ( |
195 |
|
ProcessHandle, |
196 |
|
DesiredAccess, |
197 |
|
TokenHandle) |
198 |
|
); |
199 |
|
} |
200 |
|
|
201 |
|
BOOL WINAPI get_token_information ( |
202 |
|
HANDLE TokenHandle, |
203 |
|
TOKEN_INFORMATION_CLASS TokenInformationClass, |
204 |
|
LPVOID TokenInformation, |
205 |
|
DWORD TokenInformationLength, |
206 |
|
PDWORD ReturnLength) |
207 |
|
{ |
208 |
|
static GetTokenInformation_Proc s_pfn_Get_Token_Information = NULL; |
209 |
|
HMODULE hm_advapi32 = NULL; |
210 |
|
if (is_windows_9x () == TRUE) |
211 |
|
{ |
212 |
|
return FALSE; |
213 |
|
} |
214 |
|
if (g_b_init_get_token_information == 0) |
215 |
|
{ |
216 |
|
g_b_init_get_token_information = 1; |
217 |
|
hm_advapi32 = LoadLibrary ("Advapi32.dll"); |
218 |
|
s_pfn_Get_Token_Information = |
219 |
|
(GetTokenInformation_Proc) GetProcAddress (hm_advapi32, "GetTokenInformation"); |
220 |
|
} |
221 |
|
if (s_pfn_Get_Token_Information == NULL) |
222 |
|
{ |
223 |
|
return FALSE; |
224 |
|
} |
225 |
|
return ( |
226 |
|
s_pfn_Get_Token_Information ( |
227 |
|
TokenHandle, |
228 |
|
TokenInformationClass, |
229 |
|
TokenInformation, |
230 |
|
TokenInformationLength, |
231 |
|
ReturnLength) |
232 |
|
); |
233 |
|
} |
234 |
|
|
235 |
|
BOOL WINAPI lookup_account_sid ( |
236 |
|
LPCTSTR lpSystemName, |
237 |
|
PSID Sid, |
238 |
|
LPTSTR Name, |
239 |
|
LPDWORD cbName, |
240 |
|
LPTSTR DomainName, |
241 |
|
LPDWORD cbDomainName, |
242 |
|
PSID_NAME_USE peUse) |
243 |
|
{ |
244 |
|
static LookupAccountSid_Proc s_pfn_Lookup_Account_Sid = NULL; |
245 |
|
HMODULE hm_advapi32 = NULL; |
246 |
|
if (is_windows_9x () == TRUE) |
247 |
|
{ |
248 |
|
return FALSE; |
249 |
|
} |
250 |
|
if (g_b_init_lookup_account_sid == 0) |
251 |
|
{ |
252 |
|
g_b_init_lookup_account_sid = 1; |
253 |
|
hm_advapi32 = LoadLibrary ("Advapi32.dll"); |
254 |
|
s_pfn_Lookup_Account_Sid = |
255 |
|
(LookupAccountSid_Proc) GetProcAddress (hm_advapi32, LookupAccountSid_Name); |
256 |
|
} |
257 |
|
if (s_pfn_Lookup_Account_Sid == NULL) |
258 |
|
{ |
259 |
|
return FALSE; |
260 |
|
} |
261 |
|
return ( |
262 |
|
s_pfn_Lookup_Account_Sid ( |
263 |
|
lpSystemName, |
264 |
|
Sid, |
265 |
|
Name, |
266 |
|
cbName, |
267 |
|
DomainName, |
268 |
|
cbDomainName, |
269 |
|
peUse) |
270 |
|
); |
271 |
|
} |
272 |
|
|
273 |
|
PSID_IDENTIFIER_AUTHORITY WINAPI get_sid_identifier_authority ( |
274 |
|
PSID pSid) |
275 |
|
{ |
276 |
|
static GetSidIdentifierAuthority_Proc s_pfn_Get_Sid_Identifier_Authority = NULL; |
277 |
|
HMODULE hm_advapi32 = NULL; |
278 |
|
if (is_windows_9x () == TRUE) |
279 |
|
{ |
280 |
|
return NULL; |
281 |
|
} |
282 |
|
if (g_b_init_get_sid_identifier_authority == 0) |
283 |
|
{ |
284 |
|
g_b_init_get_sid_identifier_authority = 1; |
285 |
|
hm_advapi32 = LoadLibrary ("Advapi32.dll"); |
286 |
|
s_pfn_Get_Sid_Identifier_Authority = |
287 |
|
(GetSidIdentifierAuthority_Proc) GetProcAddress ( |
288 |
|
hm_advapi32, "GetSidIdentifierAuthority"); |
289 |
|
} |
290 |
|
if (s_pfn_Get_Sid_Identifier_Authority == NULL) |
291 |
|
{ |
292 |
|
return NULL; |
293 |
|
} |
294 |
|
return (s_pfn_Get_Sid_Identifier_Authority (pSid)); |
295 |
|
} |
296 |
|
|
297 |
|
/* |
298 |
|
END: Wrapper functions around OpenProcessToken |
299 |
|
and other functions in advapi32.dll that are only |
300 |
|
supported in Windows NT / 2k / XP |
301 |
|
*/ |
302 |
|
|
303 |
|
|
304 |
/* Equivalent of strerror for W32 error codes. */ |
/* Equivalent of strerror for W32 error codes. */ |
305 |
char * |
char * |
306 |
w32_strerror (int error_no) |
w32_strerror (int error_no) |
343 |
int |
int |
344 |
gethostname (char *buffer, int size) |
gethostname (char *buffer, int size) |
345 |
{ |
{ |
346 |
/* NT only allows small host names, so the buffer is |
/* NT only allows small host names, so the buffer is |
347 |
certainly large enough. */ |
certainly large enough. */ |
348 |
return !GetComputerName (buffer, &size); |
return !GetComputerName (buffer, &size); |
349 |
} |
} |
356 |
int i; |
int i; |
357 |
|
|
358 |
/* A faithful emulation is going to have to be saved for a rainy day. */ |
/* A faithful emulation is going to have to be saved for a rainy day. */ |
359 |
for (i = 0; i < nelem; i++) |
for (i = 0; i < nelem; i++) |
360 |
{ |
{ |
361 |
loadavg[i] = 0.0; |
loadavg[i] = 0.0; |
362 |
} |
} |
373 |
static char the_passwd_dir[PASSWD_FIELD_SIZE]; |
static char the_passwd_dir[PASSWD_FIELD_SIZE]; |
374 |
static char the_passwd_shell[PASSWD_FIELD_SIZE]; |
static char the_passwd_shell[PASSWD_FIELD_SIZE]; |
375 |
|
|
376 |
static struct passwd the_passwd = |
static struct passwd the_passwd = |
377 |
{ |
{ |
378 |
the_passwd_name, |
the_passwd_name, |
379 |
the_passwd_passwd, |
the_passwd_passwd, |
385 |
the_passwd_shell, |
the_passwd_shell, |
386 |
}; |
}; |
387 |
|
|
388 |
int |
int |
389 |
getuid () |
getuid () |
390 |
{ |
{ |
391 |
return the_passwd.pw_uid; |
return the_passwd.pw_uid; |
392 |
} |
} |
393 |
|
|
394 |
int |
int |
395 |
geteuid () |
geteuid () |
396 |
{ |
{ |
397 |
/* I could imagine arguing for checking to see whether the user is |
/* I could imagine arguing for checking to see whether the user is |
398 |
in the Administrators group and returning a UID of 0 for that |
in the Administrators group and returning a UID of 0 for that |
399 |
case, but I don't know how wise that would be in the long run. */ |
case, but I don't know how wise that would be in the long run. */ |
400 |
return getuid (); |
return getuid (); |
401 |
} |
} |
402 |
|
|
403 |
int |
int |
404 |
getgid () |
getgid () |
405 |
{ |
{ |
406 |
return the_passwd.pw_gid; |
return the_passwd.pw_gid; |
407 |
} |
} |
408 |
|
|
409 |
int |
int |
410 |
getegid () |
getegid () |
411 |
{ |
{ |
412 |
return getgid (); |
return getgid (); |
413 |
} |
} |
414 |
|
|
424 |
getpwnam (char *name) |
getpwnam (char *name) |
425 |
{ |
{ |
426 |
struct passwd *pw; |
struct passwd *pw; |
427 |
|
|
428 |
pw = getpwuid (getuid ()); |
pw = getpwuid (getuid ()); |
429 |
if (!pw) |
if (!pw) |
430 |
return pw; |
return pw; |
450 |
HANDLE token = NULL; |
HANDLE token = NULL; |
451 |
SID_NAME_USE user_type; |
SID_NAME_USE user_type; |
452 |
|
|
453 |
if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token) |
if ( |
454 |
&& GetTokenInformation (token, TokenUser, |
open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token) |
455 |
|
&& get_token_information ( |
456 |
|
token, TokenUser, |
457 |
(PVOID) user_sid, sizeof (user_sid), &trash) |
(PVOID) user_sid, sizeof (user_sid), &trash) |
458 |
&& LookupAccountSid (NULL, *((PSID *) user_sid), name, &length, |
&& lookup_account_sid ( |
459 |
domain, &dlength, &user_type)) |
NULL, *((PSID *) user_sid), name, &length, |
460 |
|
domain, &dlength, &user_type) |
461 |
|
) |
462 |
{ |
{ |
463 |
strcpy (the_passwd.pw_name, name); |
strcpy (the_passwd.pw_name, name); |
464 |
/* Determine a reasonable uid value. */ |
/* Determine a reasonable uid value. */ |
471 |
{ |
{ |
472 |
SID_IDENTIFIER_AUTHORITY * pSIA; |
SID_IDENTIFIER_AUTHORITY * pSIA; |
473 |
|
|
474 |
pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid)); |
pSIA = get_sid_identifier_authority (*((PSID *) user_sid)); |
475 |
/* I believe the relative portion is the last 4 bytes (of 6) |
/* I believe the relative portion is the last 4 bytes (of 6) |
476 |
with msb first. */ |
with msb first. */ |
477 |
the_passwd.pw_uid = ((pSIA->Value[2] << 24) + |
the_passwd.pw_uid = ((pSIA->Value[2] << 24) + |
482 |
the_passwd.pw_uid = the_passwd.pw_uid % 60001; |
the_passwd.pw_uid = the_passwd.pw_uid % 60001; |
483 |
|
|
484 |
/* Get group id */ |
/* Get group id */ |
485 |
if (GetTokenInformation (token, TokenPrimaryGroup, |
if (get_token_information (token, TokenPrimaryGroup, |
486 |
(PVOID) user_sid, sizeof (user_sid), &trash)) |
(PVOID) user_sid, sizeof (user_sid), &trash)) |
487 |
{ |
{ |
488 |
SID_IDENTIFIER_AUTHORITY * pSIA; |
SID_IDENTIFIER_AUTHORITY * pSIA; |
489 |
|
|
490 |
pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid)); |
pSIA = get_sid_identifier_authority (*((PSID *) user_sid)); |
491 |
the_passwd.pw_gid = ((pSIA->Value[2] << 24) + |
the_passwd.pw_gid = ((pSIA->Value[2] << 24) + |
492 |
(pSIA->Value[3] << 16) + |
(pSIA->Value[3] << 16) + |
493 |
(pSIA->Value[4] << 8) + |
(pSIA->Value[4] << 8) + |
782 |
|
|
783 |
/* Routines that are no-ops on NT but are defined to get Emacs to compile. */ |
/* Routines that are no-ops on NT but are defined to get Emacs to compile. */ |
784 |
|
|
785 |
int |
int |
786 |
sigsetmask (int signal_mask) |
sigsetmask (int signal_mask) |
787 |
{ |
{ |
788 |
return 0; |
return 0; |
789 |
} |
} |
790 |
|
|
791 |
int |
int |
792 |
sigmask (int sig) |
sigmask (int sig) |
793 |
{ |
{ |
794 |
return 0; |
return 0; |
795 |
} |
} |
796 |
|
|
797 |
int |
int |
798 |
sigblock (int sig) |
sigblock (int sig) |
799 |
{ |
{ |
800 |
return 0; |
return 0; |
801 |
} |
} |
802 |
|
|
803 |
int |
int |
804 |
sigunblock (int sig) |
sigunblock (int sig) |
805 |
{ |
{ |
806 |
return 0; |
return 0; |
807 |
} |
} |
808 |
|
|
809 |
int |
int |
810 |
setpgrp (int pid, int gid) |
setpgrp (int pid, int gid) |
811 |
{ |
{ |
812 |
return 0; |
return 0; |
813 |
} |
} |
814 |
|
|
815 |
int |
int |
816 |
alarm (int seconds) |
alarm (int seconds) |
817 |
{ |
{ |
818 |
return 0; |
return 0; |
819 |
} |
} |
820 |
|
|
821 |
void |
void |
822 |
unrequest_sigio (void) |
unrequest_sigio (void) |
823 |
{ |
{ |
824 |
return; |
return; |
825 |
} |
} |
826 |
|
|
827 |
void |
void |
828 |
request_sigio (void) |
request_sigio (void) |
829 |
{ |
{ |
830 |
return; |
return; |
831 |
} |
} |
832 |
|
|
833 |
#define REG_ROOT "SOFTWARE\\GNU\\Emacs" |
#define REG_ROOT "SOFTWARE\\GNU\\Emacs" |
834 |
|
|
835 |
LPBYTE |
LPBYTE |
836 |
w32_get_resource (key, lpdwtype) |
w32_get_resource (key, lpdwtype) |
837 |
char *key; |
char *key; |
838 |
LPDWORD lpdwtype; |
LPDWORD lpdwtype; |
841 |
HKEY hrootkey = NULL; |
HKEY hrootkey = NULL; |
842 |
DWORD cbData; |
DWORD cbData; |
843 |
BOOL ok = FALSE; |
BOOL ok = FALSE; |
844 |
|
|
845 |
/* Check both the current user and the local machine to see if |
/* Check both the current user and the local machine to see if |
846 |
we have any resources. */ |
we have any resources. */ |
847 |
|
|
848 |
if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS) |
if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS) |
849 |
{ |
{ |
850 |
lpvalue = NULL; |
lpvalue = NULL; |
851 |
|
|
852 |
if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS |
if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS |
853 |
&& (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL |
&& (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL |
854 |
&& RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS) |
&& RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS) |
855 |
{ |
{ |
856 |
return (lpvalue); |
return (lpvalue); |
857 |
} |
} |
858 |
|
|
859 |
if (lpvalue) xfree (lpvalue); |
if (lpvalue) xfree (lpvalue); |
860 |
|
|
861 |
RegCloseKey (hrootkey); |
RegCloseKey (hrootkey); |
862 |
} |
} |
863 |
|
|
864 |
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS) |
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS) |
865 |
{ |
{ |
866 |
lpvalue = NULL; |
lpvalue = NULL; |
867 |
|
|
868 |
if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS |
if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS |
869 |
&& (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL |
&& (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL |
870 |
&& RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS) |
&& RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS) |
871 |
{ |
{ |
872 |
return (lpvalue); |
return (lpvalue); |
873 |
} |
} |
874 |
|
|
875 |
if (lpvalue) xfree (lpvalue); |
if (lpvalue) xfree (lpvalue); |
876 |
|
|
877 |
RegCloseKey (hrootkey); |
RegCloseKey (hrootkey); |
878 |
} |
} |
879 |
|
|
880 |
return (NULL); |
return (NULL); |
881 |
} |
} |
882 |
|
|
933 |
{ |
{ |
934 |
char * name; |
char * name; |
935 |
char * def_value; |
char * def_value; |
936 |
} env_vars[] = |
} env_vars[] = |
937 |
{ |
{ |
938 |
{"HOME", "C:/"}, |
{"HOME", "C:/"}, |
939 |
{"PRELOAD_WINSOCK", NULL}, |
{"PRELOAD_WINSOCK", NULL}, |
942 |
{"SHELL", "%emacs_dir%/bin/cmdproxy.exe"}, |
{"SHELL", "%emacs_dir%/bin/cmdproxy.exe"}, |
943 |
{"EMACSDATA", "%emacs_dir%/etc"}, |
{"EMACSDATA", "%emacs_dir%/etc"}, |
944 |
{"EMACSPATH", "%emacs_dir%/bin"}, |
{"EMACSPATH", "%emacs_dir%/bin"}, |
|
{"EMACSLOCKDIR", "%emacs_dir%/lock"}, |
|
945 |
/* We no longer set INFOPATH because Info-default-directory-list |
/* We no longer set INFOPATH because Info-default-directory-list |
946 |
is then ignored. */ |
is then ignored. */ |
947 |
/* {"INFOPATH", "%emacs_dir%/info"}, */ |
/* {"INFOPATH", "%emacs_dir%/info"}, */ |
987 |
*p = 0; |
*p = 0; |
988 |
for (p = modname; *p; p++) |
for (p = modname; *p; p++) |
989 |
if (*p == '\\') *p = '/'; |
if (*p == '\\') *p = '/'; |
990 |
|
|
991 |
_snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname); |
_snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname); |
992 |
_putenv (strdup (buf)); |
_putenv (strdup (buf)); |
993 |
} |
} |
1019 |
else if (dwType == REG_SZ) |
else if (dwType == REG_SZ) |
1020 |
{ |
{ |
1021 |
char buf[SET_ENV_BUF_SIZE]; |
char buf[SET_ENV_BUF_SIZE]; |
1022 |
|
|
1023 |
_snprintf (buf, sizeof(buf)-1, "%s=%s", env_vars[i].name, lpval); |
_snprintf (buf, sizeof(buf)-1, "%s=%s", env_vars[i].name, lpval); |
1024 |
_putenv (strdup (buf)); |
_putenv (strdup (buf)); |
1025 |
} |
} |
1113 |
static char configuration_buffer[32]; |
static char configuration_buffer[32]; |
1114 |
|
|
1115 |
/* Determine the processor type. */ |
/* Determine the processor type. */ |
1116 |
switch (get_processor_type ()) |
switch (get_processor_type ()) |
1117 |
{ |
{ |
1118 |
|
|
1119 |
#ifdef PROCESSOR_INTEL_386 |
#ifdef PROCESSOR_INTEL_386 |
1230 |
#include <sys/timeb.h> |
#include <sys/timeb.h> |
1231 |
|
|
1232 |
/* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */ |
/* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */ |
1233 |
void |
void |
1234 |
gettimeofday (struct timeval *tv, struct timezone *tz) |
gettimeofday (struct timeval *tv, struct timezone *tz) |
1235 |
{ |
{ |
1236 |
struct timeb tb; |
struct timeb tb; |
1238 |
|
|
1239 |
tv->tv_sec = tb.time; |
tv->tv_sec = tb.time; |
1240 |
tv->tv_usec = tb.millitm * 1000L; |
tv->tv_usec = tb.millitm * 1000L; |
1241 |
if (tz) |
if (tz) |
1242 |
{ |
{ |
1243 |
tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */ |
tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */ |
1244 |
tz->tz_dsttime = tb.dstflag; /* type of dst correction */ |
tz->tz_dsttime = tb.dstflag; /* type of dst correction */ |
1250 |
/* ------------------------------------------------------------------------- */ |
/* ------------------------------------------------------------------------- */ |
1251 |
|
|
1252 |
/* Place a wrapper around the MSVC version of ctime. It returns NULL |
/* Place a wrapper around the MSVC version of ctime. It returns NULL |
1253 |
on network directories, so we handle that case here. |
on network directories, so we handle that case here. |
1254 |
(Ulrich Leodolter, 1/11/95). */ |
(Ulrich Leodolter, 1/11/95). */ |
1255 |
char * |
char * |
1256 |
sys_ctime (const time_t *t) |
sys_ctime (const time_t *t) |
1356 |
tell whether they are or not. Also, the UNC association of drive |
tell whether they are or not. Also, the UNC association of drive |
1357 |
letters mapped to remote volumes can be changed at any time (even |
letters mapped to remote volumes can be changed at any time (even |
1358 |
by other processes) without notice. |
by other processes) without notice. |
1359 |
|
|
1360 |
As a compromise, so we can benefit from caching info for remote |
As a compromise, so we can benefit from caching info for remote |
1361 |
volumes, we use a simple expiry mechanism to invalidate cache |
volumes, we use a simple expiry mechanism to invalidate cache |
1362 |
entries that are more than ten seconds old. */ |
entries that are more than ten seconds old. */ |
1462 |
|
|
1463 |
if (pPath) |
if (pPath) |
1464 |
*pPath = name; |
*pPath = name; |
1465 |
|
|
1466 |
info = GetCachedVolumeInformation (rootname); |
info = GetCachedVolumeInformation (rootname); |
1467 |
if (info != NULL) |
if (info != NULL) |
1468 |
{ |
{ |
1600 |
stricmp (p, ".cmd") == 0)); |
stricmp (p, ".cmd") == 0)); |
1601 |
} |
} |
1602 |
|
|
1603 |
/* Emulate the Unix directory procedures opendir, closedir, |
/* Emulate the Unix directory procedures opendir, closedir, |
1604 |
and readdir. We can't use the procedures supplied in sysdep.c, |
and readdir. We can't use the procedures supplied in sysdep.c, |
1605 |
so we provide them here. */ |
so we provide them here. */ |
1606 |
|
|
1673 |
{ |
{ |
1674 |
if (wnet_enum_handle != INVALID_HANDLE_VALUE) |
if (wnet_enum_handle != INVALID_HANDLE_VALUE) |
1675 |
{ |
{ |
1676 |
if (!read_unc_volume (wnet_enum_handle, |
if (!read_unc_volume (wnet_enum_handle, |
1677 |
dir_find_data.cFileName, |
dir_find_data.cFileName, |
1678 |
MAX_PATH)) |
MAX_PATH)) |
1679 |
return NULL; |
return NULL; |
1680 |
} |
} |
1700 |
if (!FindNextFile (dir_find_handle, &dir_find_data)) |
if (!FindNextFile (dir_find_handle, &dir_find_data)) |
1701 |
return NULL; |
return NULL; |
1702 |
} |
} |
1703 |
|
|
1704 |
/* Emacs never uses this value, so don't bother making it match |
/* Emacs never uses this value, so don't bother making it match |
1705 |
value returned by stat(). */ |
value returned by stat(). */ |
1706 |
dir_static.d_ino = 1; |
dir_static.d_ino = 1; |
1707 |
|
|
1708 |
dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 + |
dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 + |
1709 |
dir_static.d_namlen - dir_static.d_namlen % 4; |
dir_static.d_namlen - dir_static.d_namlen % 4; |
1710 |
|
|
1711 |
dir_static.d_namlen = strlen (dir_find_data.cFileName); |
dir_static.d_namlen = strlen (dir_find_data.cFileName); |
1712 |
strcpy (dir_static.d_name, dir_find_data.cFileName); |
strcpy (dir_static.d_name, dir_find_data.cFileName); |
1713 |
if (dir_is_fat) |
if (dir_is_fat) |
1721 |
if (!*p) |
if (!*p) |
1722 |
_strlwr (dir_static.d_name); |
_strlwr (dir_static.d_name); |
1723 |
} |
} |
1724 |
|
|
1725 |
return &dir_static; |
return &dir_static; |
1726 |
} |
} |
1727 |
|
|
1728 |
HANDLE |
HANDLE |
1729 |
open_unc_volume (char *path) |
open_unc_volume (char *path) |
1730 |
{ |
{ |
1731 |
NETRESOURCE nr; |
NETRESOURCE nr; |
1732 |
HANDLE henum; |
HANDLE henum; |
1733 |
int result; |
int result; |
1734 |
|
|
1735 |
nr.dwScope = RESOURCE_GLOBALNET; |
nr.dwScope = RESOURCE_GLOBALNET; |
1736 |
nr.dwType = RESOURCETYPE_DISK; |
nr.dwType = RESOURCETYPE_DISK; |
1737 |
nr.dwDisplayType = RESOURCEDISPLAYTYPE_SERVER; |
nr.dwDisplayType = RESOURCEDISPLAYTYPE_SERVER; |
1738 |
nr.dwUsage = RESOURCEUSAGE_CONTAINER; |
nr.dwUsage = RESOURCEUSAGE_CONTAINER; |
1739 |
nr.lpLocalName = NULL; |
nr.lpLocalName = NULL; |
1740 |
nr.lpRemoteName = map_w32_filename (path, NULL); |
nr.lpRemoteName = map_w32_filename (path, NULL); |
1741 |
nr.lpComment = NULL; |
nr.lpComment = NULL; |
1742 |
nr.lpProvider = NULL; |
nr.lpProvider = NULL; |
1743 |
|
|
1744 |
result = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, |
result = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, |
1745 |
RESOURCEUSAGE_CONNECTABLE, &nr, &henum); |
RESOURCEUSAGE_CONNECTABLE, &nr, &henum); |
1746 |
|
|
1747 |
if (result == NO_ERROR) |
if (result == NO_ERROR) |
1802 |
|
|
1803 |
/* Shadow some MSVC runtime functions to map requests for long filenames |
/* Shadow some MSVC runtime functions to map requests for long filenames |
1804 |
to reasonable short names if necessary. This was originally added to |
to reasonable short names if necessary. This was originally added to |
1805 |
permit running Emacs on NT 3.1 on a FAT partition, which doesn't support |
permit running Emacs on NT 3.1 on a FAT partition, which doesn't support |
1806 |
long file names. */ |
long file names. */ |
1807 |
|
|
1808 |
int |
int |
2406 |
{ |
{ |
2407 |
/* Don't bother to make this information more accurate. */ |
/* Don't bother to make this information more accurate. */ |
2408 |
buf->st_mode = (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? |
buf->st_mode = (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? |
2409 |
_S_IFREG : _S_IFDIR; |
_S_IFDIR : _S_IFREG; |
2410 |
buf->st_nlink = 1; |
buf->st_nlink = 1; |
2411 |
fake_inode = 0; |
fake_inode = 0; |
2412 |
} |
} |
2452 |
permission = _S_IREAD; |
permission = _S_IREAD; |
2453 |
else |
else |
2454 |
permission = _S_IREAD | _S_IWRITE; |
permission = _S_IREAD | _S_IWRITE; |
2455 |
|
|
2456 |
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
2457 |
permission |= _S_IEXEC; |
permission |= _S_IEXEC; |
2458 |
else if (is_exec (name)) |
else if (is_exec (name)) |
2536 |
permission = _S_IREAD; |
permission = _S_IREAD; |
2537 |
else |
else |
2538 |
permission = _S_IREAD | _S_IWRITE; |
permission = _S_IREAD | _S_IWRITE; |
2539 |
|
|
2540 |
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
2541 |
permission |= _S_IEXEC; |
permission |= _S_IEXEC; |
2542 |
else |
else |
2788 |
WSAEFAULT , "Bad address", |
WSAEFAULT , "Bad address", |
2789 |
WSAEINVAL , "Invalid argument", |
WSAEINVAL , "Invalid argument", |
2790 |
WSAEMFILE , "Too many open files", |
WSAEMFILE , "Too many open files", |
2791 |
|
|
2792 |
WSAEWOULDBLOCK , "Resource temporarily unavailable", |
WSAEWOULDBLOCK , "Resource temporarily unavailable", |
2793 |
WSAEINPROGRESS , "Operation now in progress", |
WSAEINPROGRESS , "Operation now in progress", |
2794 |
WSAEALREADY , "Operation already in progress", |
WSAEALREADY , "Operation already in progress", |
2826 |
WSAEDQUOT , "Double quote in host name", /* really not sure */ |
WSAEDQUOT , "Double quote in host name", /* really not sure */ |
2827 |
WSAESTALE , "Data is stale", /* not sure */ |
WSAESTALE , "Data is stale", /* not sure */ |
2828 |
WSAEREMOTE , "Remote error", /* not sure */ |
WSAEREMOTE , "Remote error", /* not sure */ |
2829 |
|
|
2830 |
WSASYSNOTREADY , "Network subsystem is unavailable", |
WSASYSNOTREADY , "Network subsystem is unavailable", |
2831 |
WSAVERNOTSUPPORTED , "WINSOCK.DLL version out of range", |
WSAVERNOTSUPPORTED , "WINSOCK.DLL version out of range", |
2832 |
WSANOTINITIALISED , "Winsock not initialized successfully", |
WSANOTINITIALISED , "Winsock not initialized successfully", |
2844 |
WSA_E_CANCELLED , "Operation already cancelled", /* really not sure */ |
WSA_E_CANCELLED , "Operation already cancelled", /* really not sure */ |
2845 |
WSAEREFUSED , "Operation refused", /* not sure */ |
WSAEREFUSED , "Operation refused", /* not sure */ |
2846 |
#endif |
#endif |
2847 |
|
|
2848 |
WSAHOST_NOT_FOUND , "Host not found", |
WSAHOST_NOT_FOUND , "Host not found", |
2849 |
WSATRY_AGAIN , "Authoritative host not found during name lookup", |
WSATRY_AGAIN , "Authoritative host not found during name lookup", |
2850 |
WSANO_RECOVERY , "Non-recoverable error during name lookup", |
WSANO_RECOVERY , "Non-recoverable error during name lookup", |
2899 |
|
|
2900 |
/* call the real socket function */ |
/* call the real socket function */ |
2901 |
s = pfn_socket (af, type, protocol); |
s = pfn_socket (af, type, protocol); |
2902 |
|
|
2903 |
if (s != INVALID_SOCKET) |
if (s != INVALID_SOCKET) |
2904 |
return socket_to_fd (s); |
return socket_to_fd (s); |
2905 |
|
|
2972 |
{ |
{ |
2973 |
CloseHandle (new_s); |
CloseHandle (new_s); |
2974 |
} |
} |
2975 |
} |
} |
2976 |
} |
} |
2977 |
} |
} |
2978 |
fd_info[fd].hnd = (HANDLE) s; |
fd_info[fd].hnd = (HANDLE) s; |
3185 |
return rc; |
return rc; |
3186 |
} |
} |
3187 |
h_errno = ENOTSOCK; |
h_errno = ENOTSOCK; |
3188 |
return SOCKET_ERROR; |
return SOCKET_ERROR; |
3189 |
} |
} |
3190 |
|
|
3191 |
int |
int |
3206 |
return rc; |
return rc; |
3207 |
} |
} |
3208 |
h_errno = ENOTSOCK; |
h_errno = ENOTSOCK; |
3209 |
return SOCKET_ERROR; |
return SOCKET_ERROR; |
3210 |
} |
} |
3211 |
|
|
3212 |
int |
int |
3227 |
return rc; |
return rc; |
3228 |
} |
} |
3229 |
h_errno = ENOTSOCK; |
h_errno = ENOTSOCK; |
3230 |
return SOCKET_ERROR; |
return SOCKET_ERROR; |
3231 |
} |
} |
3232 |
|
|
3233 |
int |
int |
3425 |
/* make sure we close the destination first if it's a pipe or socket */ |
/* make sure we close the destination first if it's a pipe or socket */ |
3426 |
if (src != dst && fd_info[dst].flags != 0) |
if (src != dst && fd_info[dst].flags != 0) |
3427 |
sys_close (dst); |
sys_close (dst); |
3428 |
|
|
3429 |
rc = _dup2 (src, dst); |
rc = _dup2 (src, dst); |
3430 |
if (rc == 0) |
if (rc == 0) |
3431 |
{ |
{ |
3485 |
DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd)); |
DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd)); |
3486 |
abort (); |
abort (); |
3487 |
} |
} |
3488 |
|
|
3489 |
cp->status = STATUS_READ_IN_PROGRESS; |
cp->status = STATUS_READ_IN_PROGRESS; |
3490 |
|
|
3491 |
if (fd_info[fd].flags & FILE_PIPE) |
if (fd_info[fd].flags & FILE_PIPE) |
3492 |
{ |
{ |
3493 |
rc = _read (fd, &cp->chr, sizeof (char)); |
rc = _read (fd, &cp->chr, sizeof (char)); |
3529 |
} |
} |
3530 |
} |
} |
3531 |
#endif |
#endif |
3532 |
|
|
3533 |
if (rc == sizeof (char)) |
if (rc == sizeof (char)) |
3534 |
cp->status = STATUS_READ_SUCCEEDED; |
cp->status = STATUS_READ_SUCCEEDED; |
3535 |
else |
else |
3728 |
next[0] = '\n'; |
next[0] = '\n'; |
3729 |
dst = next + 1; |
dst = next + 1; |
3730 |
count++; |
count++; |
3731 |
} |
} |
3732 |
else |
else |
3733 |
/* copied remaining partial line -> now finished */ |
/* copied remaining partial line -> now finished */ |
3734 |
break; |
break; |
3740 |
#ifdef HAVE_SOCKETS |
#ifdef HAVE_SOCKETS |
3741 |
if (fd_info[fd].flags & FILE_SOCKET) |
if (fd_info[fd].flags & FILE_SOCKET) |
3742 |
{ |
{ |
3743 |
|
unsigned long nblock = 0; |
3744 |
if (winsock_lib == NULL) abort (); |
if (winsock_lib == NULL) abort (); |
3745 |
|
|
3746 |
|
/* TODO: implement select() properly so non-blocking I/O works. */ |
3747 |
|
/* For now, make sure the write blocks. */ |
3748 |
|
if (fd_info[fd].flags & FILE_NDELAY) |
3749 |
|
pfn_ioctlsocket (SOCK_HANDLE (fd), FIONBIO, &nblock); |
3750 |
|
|
3751 |
nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0); |
nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0); |
3752 |
|
|
3753 |
|
/* Set the socket back to non-blocking if it was before, |
3754 |
|
for other operations that support it. */ |
3755 |
|
if (fd_info[fd].flags & FILE_NDELAY) |
3756 |
|
{ |
3757 |
|
nblock = 1; |
3758 |
|
pfn_ioctlsocket (SOCK_HANDLE (fd), FIONBIO, &nblock); |
3759 |
|
} |
3760 |
|
|
3761 |
if (nchars == SOCKET_ERROR) |
if (nchars == SOCKET_ERROR) |
3762 |
{ |
{ |
3763 |
DebPrint(("sys_read.send failed with error %d on socket %ld\n", |
DebPrint(("sys_write.send failed with error %d on socket %ld\n", |
3764 |
pfn_WSAGetLastError (), SOCK_HANDLE (fd))); |
pfn_WSAGetLastError (), SOCK_HANDLE (fd))); |
3765 |
set_errno (); |
set_errno (); |
3766 |
} |
} |
3781 |
it cannot find the Windows installation file. If this file does |
it cannot find the Windows installation file. If this file does |
3782 |
not exist in the expected place, tell the user. */ |
not exist in the expected place, tell the user. */ |
3783 |
|
|
3784 |
if (!noninteractive && !inhibit_window_system) |
if (!noninteractive && !inhibit_window_system) |
3785 |
{ |
{ |
3786 |
extern Lisp_Object Vwindow_system, Vload_path, Qfile_exists_p; |
extern Lisp_Object Vwindow_system, Vload_path, Qfile_exists_p; |
3787 |
Lisp_Object objs[2]; |
Lisp_Object objs[2]; |
3794 |
full_load_path = Fappend (2, objs); |
full_load_path = Fappend (2, objs); |
3795 |
init_file = build_string ("term/w32-win"); |
init_file = build_string ("term/w32-win"); |
3796 |
fd = openp (full_load_path, init_file, Vload_suffixes, NULL, Qnil); |
fd = openp (full_load_path, init_file, Vload_suffixes, NULL, Qnil); |
3797 |
if (fd < 0) |
if (fd < 0) |
3798 |
{ |
{ |
3799 |
Lisp_Object load_path_print = Fprin1_to_string (full_load_path, Qnil); |
Lisp_Object load_path_print = Fprin1_to_string (full_load_path, Qnil); |
3800 |
char *init_file_name = XSTRING (init_file)->data; |
char *init_file_name = SDATA (init_file); |
3801 |
char *load_path = XSTRING (load_path_print)->data; |
char *load_path = SDATA (load_path_print); |
3802 |
char *buffer = alloca (1024); |
char *buffer = alloca (1024); |
3803 |
|
|
3804 |
sprintf (buffer, |
sprintf (buffer, |
3805 |
"The Emacs Windows initialization file \"%s.el\" " |
"The Emacs Windows initialization file \"%s.el\" " |
3806 |
"could not be found in your Emacs installation. " |
"could not be found in your Emacs installation. " |
3807 |
"Emacs checked the following directories for this file:\n" |
"Emacs checked the following directories for this file:\n" |
3866 |
|
|
3867 |
/* ignore errors when duplicating and closing; typically the |
/* ignore errors when duplicating and closing; typically the |
3868 |
handles will be invalid when running as a gui program. */ |
handles will be invalid when running as a gui program. */ |
3869 |
DuplicateHandle (parent, |
DuplicateHandle (parent, |
3870 |
GetStdHandle (STD_INPUT_HANDLE), |
GetStdHandle (STD_INPUT_HANDLE), |
3871 |
parent, |
parent, |
3872 |
&stdin_save, |
&stdin_save, |
3873 |
0, |
0, |
3874 |
FALSE, |
FALSE, |
3875 |
DUPLICATE_SAME_ACCESS); |
DUPLICATE_SAME_ACCESS); |
3876 |
|
|
3877 |
DuplicateHandle (parent, |
DuplicateHandle (parent, |
3878 |
GetStdHandle (STD_OUTPUT_HANDLE), |
GetStdHandle (STD_OUTPUT_HANDLE), |
3879 |
parent, |
parent, |
3881 |
0, |
0, |
3882 |
FALSE, |
FALSE, |
3883 |
DUPLICATE_SAME_ACCESS); |
DUPLICATE_SAME_ACCESS); |
3884 |
|
|
3885 |
DuplicateHandle (parent, |
DuplicateHandle (parent, |
3886 |
GetStdHandle (STD_ERROR_HANDLE), |
GetStdHandle (STD_ERROR_HANDLE), |
3887 |
parent, |
parent, |
3889 |
0, |
0, |
3890 |
FALSE, |
FALSE, |
3891 |
DUPLICATE_SAME_ACCESS); |
DUPLICATE_SAME_ACCESS); |
3892 |
|
|
3893 |
fclose (stdin); |
fclose (stdin); |
3894 |
fclose (stdout); |
fclose (stdout); |
3895 |
fclose (stderr); |
fclose (stderr); |
3926 |
while (*drive <= 'Z') |
while (*drive <= 'Z') |
3927 |
{ |
{ |
3928 |
/* Record if this drive letter refers to a fixed drive. */ |
/* Record if this drive letter refers to a fixed drive. */ |
3929 |
fixed_drives[DRIVE_INDEX (*drive)] = |
fixed_drives[DRIVE_INDEX (*drive)] = |
3930 |
(GetDriveType (drive) == DRIVE_FIXED); |
(GetDriveType (drive) == DRIVE_FIXED); |
3931 |
|
|
3932 |
(*drive)++; |
(*drive)++; |
3935 |
/* Reset the volume info cache. */ |
/* Reset the volume info cache. */ |
3936 |
volume_cache = NULL; |
volume_cache = NULL; |
3937 |
} |
} |
3938 |
|
|
3939 |
/* Check to see if Emacs has been installed correctly. */ |
/* Check to see if Emacs has been installed correctly. */ |
3940 |
check_windows_init_file (); |
check_windows_init_file (); |
3941 |
} |
} |
3942 |
|
|
3943 |
|
/* |
3944 |
|
globals_of_w32 is used to initialize those global variables that |
3945 |
|
must always be initialized on startup even when the global variable |
3946 |
|
initialized is non zero (see the function main in emacs.c). |
3947 |
|
*/ |
3948 |
|
void globals_of_w32 () |
3949 |
|
{ |
3950 |
|
g_b_init_is_windows_9x = 0; |
3951 |
|
g_b_init_open_process_token = 0; |
3952 |
|
g_b_init_get_token_information = 0; |
3953 |
|
g_b_init_lookup_account_sid = 0; |
3954 |
|
g_b_init_get_sid_identifier_authority = 0; |
3955 |
|
} |
3956 |
|
|
3957 |
/* end of nt.c */ |
/* end of nt.c */ |