/* Utility and Unix shadow routines for GNU Emacs on the Microsoft W32 API.
Copyright (C) 1994, 1995, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006 Free Software Foundation, Inc.
+ 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
#include <sys/file.h>
#include <sys/time.h>
#include <sys/utime.h>
+#include <mbstring.h> /* for _mbspbrk */
/* must include CRT headers *before* config.h */
\f
/*
- Initialization states
+ Initialization states
*/
static BOOL g_b_init_is_windows_9x;
static BOOL g_b_init_open_process_token;
LPVOID TokenInformation,
DWORD TokenInformationLength,
PDWORD ReturnLength);
+typedef BOOL (WINAPI * GetProcessTimes_Proc) (
+ HANDLE process_handle,
+ LPFILETIME creation_time,
+ LPFILETIME exit_time,
+ LPFILETIME kernel_time,
+ LPFILETIME user_time);
+
+GetProcessTimes_Proc get_process_times_fn = NULL;
+
#ifdef _UNICODE
const char * const LookupAccountSid_Name = "LookupAccountSidW";
#else
PSID pSid);
/* ** A utility function ** */
-static BOOL is_windows_9x ()
+static BOOL
+is_windows_9x ()
{
static BOOL s_b_ret=0;
OSVERSIONINFO os_ver;
return s_b_ret;
}
+/* Get total user and system times for get-internal-run-time.
+ Returns a list of three integers if the times are provided by the OS
+ (NT derivatives), otherwise it returns the result of current-time. */
+Lisp_Object
+w32_get_internal_run_time ()
+{
+ if (get_process_times_fn)
+ {
+ FILETIME create, exit, kernel, user;
+ HANDLE proc = GetCurrentProcess();
+ if ((*get_process_times_fn) (proc, &create, &exit, &kernel, &user))
+ {
+ LARGE_INTEGER user_int, kernel_int, total;
+ int microseconds;
+ user_int.LowPart = user.dwLowDateTime;
+ user_int.HighPart = user.dwHighDateTime;
+ kernel_int.LowPart = kernel.dwLowDateTime;
+ kernel_int.HighPart = kernel.dwHighDateTime;
+ total.QuadPart = user_int.QuadPart + kernel_int.QuadPart;
+ /* FILETIME is 100 nanosecond increments, Emacs only wants
+ microsecond resolution. */
+ total.QuadPart /= 10;
+ microseconds = total.QuadPart % 1000000;
+ total.QuadPart /= 1000000;
+
+ /* Sanity check to make sure we can represent the result. */
+ if (total.HighPart == 0)
+ {
+ int secs = total.LowPart;
+
+ return list3 (make_number ((secs >> 16) & 0xffff),
+ make_number (secs & 0xffff),
+ make_number (microseconds));
+ }
+ }
+ }
+
+ return Fcurrent_time ();
+}
+
/* ** The wrapper functions ** */
BOOL WINAPI open_process_token (
the user-sid as the user id value (same for group id using the
primary group sid from the process token). */
- char user_sid[256], name[256], domain[256];
- DWORD length = sizeof (name), dlength = sizeof (domain), trash;
- HANDLE token = NULL;
- SID_NAME_USE user_type;
-
- if (
- open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token)
- && get_token_information (
- token, TokenUser,
- (PVOID) user_sid, sizeof (user_sid), &trash)
- && lookup_account_sid (
- NULL, *((PSID *) user_sid), name, &length,
- domain, &dlength, &user_type)
- )
+ char user_sid[256], name[256], domain[256];
+ DWORD length = sizeof (name), dlength = sizeof (domain), trash;
+ HANDLE token = NULL;
+ SID_NAME_USE user_type;
+
+ if (open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token)
+ && get_token_information (token, TokenUser,
+ (PVOID) user_sid, sizeof (user_sid), &trash)
+ && lookup_account_sid (NULL, *((PSID *) user_sid), name, &length,
+ domain, &dlength, &user_type))
{
strcpy (the_passwd.pw_name, name);
/* Determine a reasonable uid value. */
/* Get group id */
if (get_token_information (token, TokenPrimaryGroup,
- (PVOID) user_sid, sizeof (user_sid), &trash))
+ (PVOID) user_sid, sizeof (user_sid), &trash))
{
SID_IDENTIFIER_AUTHORITY * pSIA;
}
}
/* If security calls are not supported (presumably because we
- are running under Windows 95), fallback to this. */
+ are running under Windows 95), fallback to this. */
else if (GetUserName (name, &length))
{
strcpy (the_passwd.pw_name, name);
int len = 0;
/* must be valid filename, no wild cards or other invalid characters */
- if (strpbrk (name, "*?|<>\""))
+ if (_mbspbrk (name, "*?|<>\""))
return 0;
dir_handle = FindFirstFile (name, &find_data);
if (!IS_DIRECTORY_SEP (ptr[0]) || !IS_DIRECTORY_SEP (ptr[1]) || !ptr[2])
return 0;
- if (strpbrk (ptr + 2, "*?|<>\"\\/"))
+ if (_mbspbrk (ptr + 2, "*?|<>\"\\/"))
return 0;
return 1;
return 0;
}
-void
-unrequest_sigio (void)
-{
- return;
-}
-
-void
-request_sigio (void)
-{
- return;
-}
-
#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
LPBYTE
{
int dont_free = 0;
- if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL)
+ if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL
+ /* Also ignore empty environment variables. */
+ || *lpval == 0)
{
lpval = env_vars[i].def_value;
dwType = REG_EXPAND_SZ;
}
name = (char *) map_w32_filename (path, &path);
- /* must be valid filename, no wild cards or other invalid characters */
- if (strpbrk (name, "*?|<>\""))
+ /* Must be valid filename, no wild cards or other invalid
+ characters. We use _mbspbrk to support multibyte strings that
+ might look to strpbrk as if they included literal *, ?, and other
+ characters mentioned below that are disallowed by Windows
+ filesystems. */
+ if (_mbspbrk (name, "*?|<>\""))
{
errno = ENOENT;
return -1;
!= INVALID_HANDLE_VALUE)
{
/* This is more accurate in terms of gettting the correct number
- of links, but is quite slow (it is noticable when Emacs is
+ of links, but is quite slow (it is noticeable when Emacs is
making a list of file name completions). */
BY_HANDLE_FILE_INFORMATION info;
/* function to set h_errno for compatability; map winsock error codes to
normal system codes where they overlap (non-overlapping definitions
are already in <sys/socket.h> */
-static void set_errno ()
+static void
+set_errno ()
{
if (winsock_lib == NULL)
h_errno = EINVAL;
errno = h_errno;
}
-static void check_errno ()
+static void
+check_errno ()
{
if (h_errno == 0 && winsock_lib != NULL)
pfn_WSASetLastError (0);
WSAEINVALIDPROCTABLE , "Invalid procedure table from service provider",
WSAEINVALIDPROVIDER , "Invalid service provider version number",
WSAEPROVIDERFAILEDINIT , "Unable to initialize a service provider",
- WSASYSCALLFAILURE , "System call failured",
+ WSASYSCALLFAILURE , "System call failure",
WSASERVICE_NOT_FOUND , "Service not found", /* not sure */
WSATYPE_NOT_FOUND , "Class type not found",
WSA_E_NO_MORE , "No more resources available", /* really not sure */
return cp->status;
}
-int _sys_wait_accept (int fd)
+int
+_sys_wait_accept (int fd)
{
HANDLE hEv;
child_process * cp;
{
rc = WaitForSingleObject (hEv, INFINITE);
pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0);
- pfn_WSACloseEvent (hEv);
if (rc == WAIT_OBJECT_0)
cp->status = STATUS_READ_SUCCEEDED;
}
+ pfn_WSACloseEvent (hEv);
return cp->status;
}
shut_down_emacs (0, 0, Qnil);
}
- /* Allow other handlers to handle this signal. */
+ /* Allow other handlers to handle this signal. */
return FALSE;
}
must always be initialized on startup even when the global variable
initialized is non zero (see the function main in emacs.c).
*/
-void globals_of_w32 ()
+void
+globals_of_w32 ()
{
+ HMODULE kernel32 = GetModuleHandle ("kernel32.dll");
+
+ get_process_times_fn = (GetProcessTimes_Proc)
+ GetProcAddress (kernel32, "GetProcessTimes");
+
g_b_init_is_windows_9x = 0;
g_b_init_open_process_token = 0;
g_b_init_get_token_information = 0;
SetConsoleCtrlHandler(shutdown_handler, TRUE);
}
-/* end of nt.c */
+/* end of w32.c */
/* arch-tag: 90442dd3-37be-482b-b272-ac752e3049f1
(do not change this comment) */