]> code.delx.au - gnu-emacs/blobdiff - src/w32.c
(gnus-convert-old-newsrc): Assign
[gnu-emacs] / src / w32.c
index a608aad36f4ec335f83a9fe16c18f521ed900f7d..7b54924d73667474cc64b9b7ff84801b66a93898 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -66,6 +66,7 @@ Boston, MA 02111-1307, USA.
 #include "lisp.h"
 
 #include <pwd.h>
 #include "lisp.h"
 
 #include <pwd.h>
+#include <grp.h>
 
 #ifdef __GNUC__
 #define _ANONYMOUS_UNION
 
 #ifdef __GNUC__
 #define _ANONYMOUS_UNION
@@ -99,12 +100,23 @@ Boston, MA 02111-1307, USA.
 #include "w32heap.h"
 #include "systime.h"
 
 #include "w32heap.h"
 #include "systime.h"
 
+void globals_of_w32 ();
+
 extern Lisp_Object Vw32_downcase_file_names;
 extern Lisp_Object Vw32_generate_fake_inodes;
 extern Lisp_Object Vw32_get_true_file_attributes;
 extern Lisp_Object Vw32_downcase_file_names;
 extern Lisp_Object Vw32_generate_fake_inodes;
 extern Lisp_Object Vw32_get_true_file_attributes;
-extern Lisp_Object Vw32_num_mouse_buttons;
+extern int w32_num_mouse_buttons;
 
 \f
 
 \f
+/*
+       Initialization states
+ */
+static BOOL g_b_init_is_windows_9x;
+static BOOL g_b_init_open_process_token;
+static BOOL g_b_init_get_token_information;
+static BOOL g_b_init_lookup_account_sid;
+static BOOL g_b_init_get_sid_identifier_authority;
+
 /*
   BEGIN: Wrapper functions around OpenProcessToken
   and other functions in advapi32.dll that are only
 /*
   BEGIN: Wrapper functions around OpenProcessToken
   and other functions in advapi32.dll that are only
@@ -140,15 +152,19 @@ typedef PSID_IDENTIFIER_AUTHORITY (WINAPI * GetSidIdentifierAuthority_Proc) (
   /* ** A utility function ** */
 static BOOL is_windows_9x ()
 {
   /* ** A utility function ** */
 static BOOL is_windows_9x ()
 {
-  BOOL b_ret=0;
+  static BOOL s_b_ret=0;
   OSVERSIONINFO os_ver;
   OSVERSIONINFO os_ver;
-  ZeroMemory(&os_ver, sizeof(OSVERSIONINFO));
-  os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-  if (GetVersionEx (&os_ver))
+  if (g_b_init_is_windows_9x == 0)
     {
     {
-      b_ret = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
+      g_b_init_is_windows_9x = 1;
+      ZeroMemory(&os_ver, sizeof(OSVERSIONINFO));
+      os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+      if (GetVersionEx (&os_ver))
+        {
+          s_b_ret = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
+        }
     }
     }
-  return b_ret;
+  return s_b_ret;
 }
 
   /* ** The wrapper functions ** */
 }
 
   /* ** The wrapper functions ** */
@@ -158,21 +174,25 @@ BOOL WINAPI open_process_token (
     DWORD DesiredAccess,
     PHANDLE TokenHandle)
 {
     DWORD DesiredAccess,
     PHANDLE TokenHandle)
 {
-  OpenProcessToken_Proc pfn_Open_Process_Token = NULL;
+  static OpenProcessToken_Proc s_pfn_Open_Process_Token = NULL;
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return FALSE;
     }
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return FALSE;
     }
-  hm_advapi32 = LoadLibrary ("Advapi32.dll");
-  pfn_Open_Process_Token =
-    (OpenProcessToken_Proc) GetProcAddress (hm_advapi32, "OpenProcessToken");
-  if (pfn_Open_Process_Token == NULL)
+  if (g_b_init_open_process_token == 0)
+    {
+      g_b_init_open_process_token = 1;
+      hm_advapi32 = LoadLibrary ("Advapi32.dll");
+      s_pfn_Open_Process_Token =
+        (OpenProcessToken_Proc) GetProcAddress (hm_advapi32, "OpenProcessToken");
+    }
+  if (s_pfn_Open_Process_Token == NULL)
     {
       return FALSE;
     }
   return (
     {
       return FALSE;
     }
   return (
-      pfn_Open_Process_Token (
+      s_pfn_Open_Process_Token (
           ProcessHandle,
           DesiredAccess,
           TokenHandle)
           ProcessHandle,
           DesiredAccess,
           TokenHandle)
@@ -186,21 +206,25 @@ BOOL WINAPI get_token_information (
     DWORD TokenInformationLength,
     PDWORD ReturnLength)
 {
     DWORD TokenInformationLength,
     PDWORD ReturnLength)
 {
-  GetTokenInformation_Proc pfn_Get_Token_Information = NULL;
+  static GetTokenInformation_Proc s_pfn_Get_Token_Information = NULL;
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return FALSE;
     }
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return FALSE;
     }
-  hm_advapi32 = LoadLibrary ("Advapi32.dll");
-  pfn_Get_Token_Information =
-    (GetTokenInformation_Proc) GetProcAddress (hm_advapi32, "GetTokenInformation");
-  if (pfn_Get_Token_Information == NULL)
+  if (g_b_init_get_token_information == 0)
+    {
+      g_b_init_get_token_information = 1;
+      hm_advapi32 = LoadLibrary ("Advapi32.dll");
+      s_pfn_Get_Token_Information =
+        (GetTokenInformation_Proc) GetProcAddress (hm_advapi32, "GetTokenInformation");
+    }
+  if (s_pfn_Get_Token_Information == NULL)
     {
       return FALSE;
     }
   return (
     {
       return FALSE;
     }
   return (
-      pfn_Get_Token_Information (
+      s_pfn_Get_Token_Information (
           TokenHandle,
           TokenInformationClass,
           TokenInformation,
           TokenHandle,
           TokenInformationClass,
           TokenInformation,
@@ -218,21 +242,25 @@ BOOL WINAPI lookup_account_sid (
     LPDWORD cbDomainName,
     PSID_NAME_USE peUse)
 {
     LPDWORD cbDomainName,
     PSID_NAME_USE peUse)
 {
-  LookupAccountSid_Proc pfn_Lookup_Account_Sid = NULL;
+  static LookupAccountSid_Proc s_pfn_Lookup_Account_Sid = NULL;
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return FALSE;
     }
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return FALSE;
     }
-  hm_advapi32 = LoadLibrary ("Advapi32.dll");
-  pfn_Lookup_Account_Sid =
-    (LookupAccountSid_Proc) GetProcAddress (hm_advapi32, LookupAccountSid_Name);
-  if (pfn_Lookup_Account_Sid == NULL)
+  if (g_b_init_lookup_account_sid == 0)
+    {
+      g_b_init_lookup_account_sid = 1;
+      hm_advapi32 = LoadLibrary ("Advapi32.dll");
+      s_pfn_Lookup_Account_Sid =
+        (LookupAccountSid_Proc) GetProcAddress (hm_advapi32, LookupAccountSid_Name);
+    }
+  if (s_pfn_Lookup_Account_Sid == NULL)
     {
       return FALSE;
     }
   return (
     {
       return FALSE;
     }
   return (
-      pfn_Lookup_Account_Sid (
+      s_pfn_Lookup_Account_Sid (
           lpSystemName,
           Sid,
           Name,
           lpSystemName,
           Sid,
           Name,
@@ -246,21 +274,25 @@ BOOL WINAPI lookup_account_sid (
 PSID_IDENTIFIER_AUTHORITY WINAPI get_sid_identifier_authority (
     PSID pSid)
 {
 PSID_IDENTIFIER_AUTHORITY WINAPI get_sid_identifier_authority (
     PSID pSid)
 {
-  GetSidIdentifierAuthority_Proc pfn_Get_Sid_Identifier_Authority = NULL;
+  static GetSidIdentifierAuthority_Proc s_pfn_Get_Sid_Identifier_Authority = NULL;
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return NULL;
     }
   HMODULE hm_advapi32 = NULL;
   if (is_windows_9x () == TRUE)
     {
       return NULL;
     }
-  hm_advapi32 = LoadLibrary ("Advapi32.dll");
-  pfn_Get_Sid_Identifier_Authority =
-    (GetSidIdentifierAuthority_Proc) GetProcAddress (
-        hm_advapi32, "GetSidIdentifierAuthority");
-  if (pfn_Get_Sid_Identifier_Authority == NULL)
+  if (g_b_init_get_sid_identifier_authority == 0)
+    {
+      g_b_init_get_sid_identifier_authority = 1;
+      hm_advapi32 = LoadLibrary ("Advapi32.dll");
+      s_pfn_Get_Sid_Identifier_Authority =
+        (GetSidIdentifierAuthority_Proc) GetProcAddress (
+            hm_advapi32, "GetSidIdentifierAuthority");
+    }
+  if (s_pfn_Get_Sid_Identifier_Authority == NULL)
     {
       return NULL;
     }
     {
       return NULL;
     }
-  return (pfn_Get_Sid_Identifier_Authority (pSid));
+  return (s_pfn_Get_Sid_Identifier_Authority (pSid));
 }
 
 /*
 }
 
 /*
@@ -312,7 +344,7 @@ getwd (char *dir)
 int
 gethostname (char *buffer, int size)
 {
 int
 gethostname (char *buffer, int size)
 {
-  /* NT only allows small host names, so the buffer is 
+  /* NT only allows small host names, so the buffer is
      certainly large enough.  */
   return !GetComputerName (buffer, &size);
 }
      certainly large enough.  */
   return !GetComputerName (buffer, &size);
 }
@@ -325,7 +357,7 @@ getloadavg (double loadavg[], int nelem)
   int i;
 
   /* A faithful emulation is going to have to be saved for a rainy day.  */
   int i;
 
   /* A faithful emulation is going to have to be saved for a rainy day.  */
-  for (i = 0; i < nelem; i++) 
+  for (i = 0; i < nelem; i++)
     {
       loadavg[i] = 0.0;
     }
     {
       loadavg[i] = 0.0;
     }
@@ -342,7 +374,7 @@ static char the_passwd_gecos[PASSWD_FIELD_SIZE];
 static char the_passwd_dir[PASSWD_FIELD_SIZE];
 static char the_passwd_shell[PASSWD_FIELD_SIZE];
 
 static char the_passwd_dir[PASSWD_FIELD_SIZE];
 static char the_passwd_shell[PASSWD_FIELD_SIZE];
 
-static struct passwd the_passwd = 
+static struct passwd the_passwd =
 {
   the_passwd_name,
   the_passwd_passwd,
 {
   the_passwd_name,
   the_passwd_passwd,
@@ -354,30 +386,37 @@ static struct passwd the_passwd =
   the_passwd_shell,
 };
 
   the_passwd_shell,
 };
 
-int 
-getuid () 
-{ 
+static struct group the_group =
+{
+  /* There are no groups on NT, so we just return "root" as the
+     group name.  */
+  "root",
+};
+
+int
+getuid ()
+{
   return the_passwd.pw_uid;
 }
 
   return the_passwd.pw_uid;
 }
 
-int 
-geteuid () 
-{ 
+int
+geteuid ()
+{
   /* I could imagine arguing for checking to see whether the user is
      in the Administrators group and returning a UID of 0 for that
      case, but I don't know how wise that would be in the long run.  */
   /* I could imagine arguing for checking to see whether the user is
      in the Administrators group and returning a UID of 0 for that
      case, but I don't know how wise that would be in the long run.  */
-  return getuid (); 
+  return getuid ();
 }
 
 }
 
-int 
-getgid () 
-{ 
+int
+getgid ()
+{
   return the_passwd.pw_gid;
 }
 
   return the_passwd.pw_gid;
 }
 
-int 
-getegid () 
-{ 
+int
+getegid ()
+{
   return getgid ();
 }
 
   return getgid ();
 }
 
@@ -389,11 +428,17 @@ getpwuid (int uid)
   return NULL;
 }
 
   return NULL;
 }
 
+struct group *
+getgrgid (gid_t gid)
+{
+  return &the_group;
+}
+
 struct passwd *
 getpwnam (char *name)
 {
   struct passwd *pw;
 struct passwd *
 getpwnam (char *name)
 {
   struct passwd *pw;
-  
+
   pw = getpwuid (getuid ());
   if (!pw)
     return pw;
   pw = getpwuid (getuid ());
   if (!pw)
     return pw;
@@ -751,57 +796,57 @@ is_unc_volume (const char *filename)
 
 /* 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.  */
 
-int 
-sigsetmask (int signal_mask) 
-{ 
+int
+sigsetmask (int signal_mask)
+{
   return 0;
 }
 
   return 0;
 }
 
-int 
-sigmask (int sig) 
-{ 
+int
+sigmask (int sig)
+{
   return 0;
 }
 
   return 0;
 }
 
-int 
-sigblock (int sig) 
-{ 
+int
+sigblock (int sig)
+{
   return 0;
 }
 
   return 0;
 }
 
-int 
-sigunblock (int sig) 
-{ 
+int
+sigunblock (int sig)
+{
   return 0;
 }
 
   return 0;
 }
 
-int 
-setpgrp (int pid, int gid) 
-{ 
+int
+setpgrp (int pid, int gid)
+{
   return 0;
 }
 
   return 0;
 }
 
-int 
-alarm (int seconds) 
-{ 
+int
+alarm (int seconds)
+{
   return 0;
 }
 
   return 0;
 }
 
-void 
-unrequest_sigio (void) 
-{ 
+void
+unrequest_sigio (void)
+{
   return;
 }
 
 void
   return;
 }
 
 void
-request_sigio (void) 
-{ 
+request_sigio (void)
+{
   return;
 }
 
 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
 
   return;
 }
 
 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
 
-LPBYTE 
+LPBYTE
 w32_get_resource (key, lpdwtype)
     char *key;
     LPDWORD lpdwtype;
 w32_get_resource (key, lpdwtype)
     char *key;
     LPDWORD lpdwtype;
@@ -810,42 +855,42 @@ w32_get_resource (key, lpdwtype)
   HKEY hrootkey = NULL;
   DWORD cbData;
   BOOL ok = FALSE;
   HKEY hrootkey = NULL;
   DWORD cbData;
   BOOL ok = FALSE;
-  
-  /* Check both the current user and the local machine to see if 
+
+  /* Check both the current user and the local machine to see if
      we have any resources.  */
      we have any resources.  */
-  
+
   if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
     {
       lpvalue = NULL;
 
   if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
     {
       lpvalue = NULL;
 
-      if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS 
-         && (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL 
+      if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
+         && (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL
          && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
        {
          return (lpvalue);
        }
 
       if (lpvalue) xfree (lpvalue);
          && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
        {
          return (lpvalue);
        }
 
       if (lpvalue) xfree (lpvalue);
-       
+
       RegCloseKey (hrootkey);
       RegCloseKey (hrootkey);
-    } 
-  
+    }
+
   if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
     {
       lpvalue = NULL;
   if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
     {
       lpvalue = NULL;
-       
+
       if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
          && (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL
          && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
        {
          return (lpvalue);
        }
       if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
          && (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL
          && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
        {
          return (lpvalue);
        }
-       
+
       if (lpvalue) xfree (lpvalue);
       if (lpvalue) xfree (lpvalue);
-       
+
       RegCloseKey (hrootkey);
       RegCloseKey (hrootkey);
-    } 
-  
+    }
+
   return (NULL);
 }
 
   return (NULL);
 }
 
@@ -902,7 +947,7 @@ init_environment (char ** argv)
     {
       char * name;
       char * def_value;
     {
       char * name;
       char * def_value;
-    } env_vars[] = 
+    } env_vars[] =
     {
       {"HOME", "C:/"},
       {"PRELOAD_WINSOCK", NULL},
     {
       {"HOME", "C:/"},
       {"PRELOAD_WINSOCK", NULL},
@@ -956,10 +1001,36 @@ init_environment (char ** argv)
          *p = 0;
          for (p = modname; *p; p++)
            if (*p == '\\') *p = '/';
          *p = 0;
          for (p = modname; *p; p++)
            if (*p == '\\') *p = '/';
-                 
+
          _snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname);
          _putenv (strdup (buf));
        }
          _snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname);
          _putenv (strdup (buf));
        }
+      /* Handle running emacs from the build directory: src/oo-spd/i386/  */
+
+      /* FIXME: should use substring of get_emacs_configuration ().
+        But I don't think the Windows build supports alpha, mips etc
+         anymore, so have taken the easy option for now.  */
+      else if (p && stricmp (p, "\\i386") == 0)
+       {
+         *p = 0;
+         p = strrchr (modname, '\\');
+         if (p != NULL)
+           {
+             *p = 0;
+             p = strrchr (modname, '\\');
+             if (p && stricmp (p, "\\src") == 0)
+               {
+                 char buf[SET_ENV_BUF_SIZE];
+
+                 *p = 0;
+                 for (p = modname; *p; p++)
+                   if (*p == '\\') *p = '/';
+
+                 _snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname);
+                 _putenv (strdup (buf));
+               }
+           }
+       }
     }
 
     for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
     }
 
     for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
@@ -988,7 +1059,7 @@ init_environment (char ** argv)
                else if (dwType == REG_SZ)
                  {
                    char buf[SET_ENV_BUF_SIZE];
                else if (dwType == REG_SZ)
                  {
                    char buf[SET_ENV_BUF_SIZE];
-                 
+
                    _snprintf (buf, sizeof(buf)-1, "%s=%s", env_vars[i].name, lpval);
                    _putenv (strdup (buf));
                  }
                    _snprintf (buf, sizeof(buf)-1, "%s=%s", env_vars[i].name, lpval);
                    _putenv (strdup (buf));
                  }
@@ -1049,7 +1120,7 @@ init_environment (char ** argv)
   /* Determine if there is a middle mouse button, to allow parse_button
      to decide whether right mouse events should be mouse-2 or
      mouse-3. */
   /* Determine if there is a middle mouse button, to allow parse_button
      to decide whether right mouse events should be mouse-2 or
      mouse-3. */
-  XSETINT (Vw32_num_mouse_buttons, GetSystemMetrics (SM_CMOUSEBUTTONS));
+  w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS);
 
   init_user_info ();
 }
 
   init_user_info ();
 }
@@ -1082,7 +1153,7 @@ get_emacs_configuration (void)
   static char configuration_buffer[32];
 
   /* Determine the processor type.  */
   static char configuration_buffer[32];
 
   /* Determine the processor type.  */
-  switch (get_processor_type ()) 
+  switch (get_processor_type ())
     {
 
 #ifdef PROCESSOR_INTEL_386
     {
 
 #ifdef PROCESSOR_INTEL_386
@@ -1199,7 +1270,7 @@ get_emacs_configuration_options (void)
 #include <sys/timeb.h>
 
 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95).  */
 #include <sys/timeb.h>
 
 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95).  */
-void 
+void
 gettimeofday (struct timeval *tv, struct timezone *tz)
 {
   struct timeb tb;
 gettimeofday (struct timeval *tv, struct timezone *tz)
 {
   struct timeb tb;
@@ -1207,7 +1278,7 @@ gettimeofday (struct timeval *tv, struct timezone *tz)
 
   tv->tv_sec = tb.time;
   tv->tv_usec = tb.millitm * 1000L;
 
   tv->tv_sec = tb.time;
   tv->tv_usec = tb.millitm * 1000L;
-  if (tz) 
+  if (tz)
     {
       tz->tz_minuteswest = tb.timezone;        /* minutes west of Greenwich  */
       tz->tz_dsttime = tb.dstflag;     /* type of dst correction  */
     {
       tz->tz_minuteswest = tb.timezone;        /* minutes west of Greenwich  */
       tz->tz_dsttime = tb.dstflag;     /* type of dst correction  */
@@ -1219,7 +1290,7 @@ gettimeofday (struct timeval *tv, struct timezone *tz)
 /* ------------------------------------------------------------------------- */
 
 /* Place a wrapper around the MSVC version of ctime.  It returns NULL
 /* ------------------------------------------------------------------------- */
 
 /* Place a wrapper around the MSVC version of ctime.  It returns NULL
-   on network directories, so we handle that case here.  
+   on network directories, so we handle that case here.
    (Ulrich Leodolter, 1/11/95).  */
 char *
 sys_ctime (const time_t *t)
    (Ulrich Leodolter, 1/11/95).  */
 char *
 sys_ctime (const time_t *t)
@@ -1325,7 +1396,7 @@ GetCachedVolumeInformation (char * root_dir)
      tell whether they are or not.  Also, the UNC association of drive
      letters mapped to remote volumes can be changed at any time (even
      by other processes) without notice.
      tell whether they are or not.  Also, the UNC association of drive
      letters mapped to remote volumes can be changed at any time (even
      by other processes) without notice.
-   
+
      As a compromise, so we can benefit from caching info for remote
      volumes, we use a simple expiry mechanism to invalidate cache
      entries that are more than ten seconds old.  */
      As a compromise, so we can benefit from caching info for remote
      volumes, we use a simple expiry mechanism to invalidate cache
      entries that are more than ten seconds old.  */
@@ -1431,7 +1502,7 @@ get_volume_info (const char * name, const char ** pPath)
 
   if (pPath)
     *pPath = name;
 
   if (pPath)
     *pPath = name;
-    
+
   info = GetCachedVolumeInformation (rootname);
   if (info != NULL)
     {
   info = GetCachedVolumeInformation (rootname);
   if (info != NULL)
     {
@@ -1569,7 +1640,7 @@ is_exec (const char * name)
         stricmp (p, ".cmd") == 0));
 }
 
         stricmp (p, ".cmd") == 0));
 }
 
-/* Emulate the Unix directory procedures opendir, closedir, 
+/* Emulate the Unix directory procedures opendir, closedir,
    and readdir.  We can't use the procedures supplied in sysdep.c,
    so we provide them here.  */
 
    and readdir.  We can't use the procedures supplied in sysdep.c,
    so we provide them here.  */
 
@@ -1582,7 +1653,7 @@ static WIN32_FIND_DATA dir_find_data;
 /* Support shares on a network resource as subdirectories of a read-only
    root directory. */
 static HANDLE wnet_enum_handle = INVALID_HANDLE_VALUE;
 /* Support shares on a network resource as subdirectories of a read-only
    root directory. */
 static HANDLE wnet_enum_handle = INVALID_HANDLE_VALUE;
-HANDLE open_unc_volume (char *);
+HANDLE open_unc_volume (const char *);
 char  *read_unc_volume (HANDLE, char *, int);
 void   close_unc_volume (HANDLE);
 
 char  *read_unc_volume (HANDLE, char *, int);
 void   close_unc_volume (HANDLE);
 
@@ -1642,8 +1713,8 @@ readdir (DIR *dirp)
 {
   if (wnet_enum_handle != INVALID_HANDLE_VALUE)
     {
 {
   if (wnet_enum_handle != INVALID_HANDLE_VALUE)
     {
-      if (!read_unc_volume (wnet_enum_handle, 
-                             dir_find_data.cFileName, 
+      if (!read_unc_volume (wnet_enum_handle,
+                             dir_find_data.cFileName,
                              MAX_PATH))
        return NULL;
     }
                              MAX_PATH))
        return NULL;
     }
@@ -1669,14 +1740,14 @@ readdir (DIR *dirp)
       if (!FindNextFile (dir_find_handle, &dir_find_data))
        return NULL;
     }
       if (!FindNextFile (dir_find_handle, &dir_find_data))
        return NULL;
     }
-  
+
   /* Emacs never uses this value, so don't bother making it match
      value returned by stat().  */
   dir_static.d_ino = 1;
   /* Emacs never uses this value, so don't bother making it match
      value returned by stat().  */
   dir_static.d_ino = 1;
-  
+
   dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
     dir_static.d_namlen - dir_static.d_namlen % 4;
   dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
     dir_static.d_namlen - dir_static.d_namlen % 4;
-  
+
   dir_static.d_namlen = strlen (dir_find_data.cFileName);
   strcpy (dir_static.d_name, dir_find_data.cFileName);
   if (dir_is_fat)
   dir_static.d_namlen = strlen (dir_find_data.cFileName);
   strcpy (dir_static.d_name, dir_find_data.cFileName);
   if (dir_is_fat)
@@ -1690,27 +1761,27 @@ readdir (DIR *dirp)
       if (!*p)
        _strlwr (dir_static.d_name);
     }
       if (!*p)
        _strlwr (dir_static.d_name);
     }
-  
+
   return &dir_static;
 }
 
 HANDLE
   return &dir_static;
 }
 
 HANDLE
-open_unc_volume (char *path)
+open_unc_volume (const char *path)
 {
 {
-  NETRESOURCE nr; 
+  NETRESOURCE nr;
   HANDLE henum;
   int result;
 
   HANDLE henum;
   int result;
 
-  nr.dwScope = RESOURCE_GLOBALNET; 
-  nr.dwType = RESOURCETYPE_DISK; 
-  nr.dwDisplayType = RESOURCEDISPLAYTYPE_SERVER; 
-  nr.dwUsage = RESOURCEUSAGE_CONTAINER; 
-  nr.lpLocalName = NULL; 
+  nr.dwScope = RESOURCE_GLOBALNET;
+  nr.dwType = RESOURCETYPE_DISK;
+  nr.dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
+  nr.dwUsage = RESOURCEUSAGE_CONTAINER;
+  nr.lpLocalName = NULL;
   nr.lpRemoteName = map_w32_filename (path, NULL);
   nr.lpRemoteName = map_w32_filename (path, NULL);
-  nr.lpComment = NULL; 
-  nr.lpProvider = NULL;   
+  nr.lpComment = NULL;
+  nr.lpProvider = NULL;
 
 
-  result = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,  
+  result = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
                        RESOURCEUSAGE_CONNECTABLE, &nr, &henum);
 
   if (result == NO_ERROR)
                        RESOURCEUSAGE_CONNECTABLE, &nr, &henum);
 
   if (result == NO_ERROR)
@@ -1752,7 +1823,7 @@ close_unc_volume (HANDLE henum)
 }
 
 DWORD
 }
 
 DWORD
-unc_volume_file_attributes (char *path)
+unc_volume_file_attributes (const char *path)
 {
   HANDLE henum;
   DWORD attrs;
 {
   HANDLE henum;
   DWORD attrs;
@@ -1771,7 +1842,7 @@ unc_volume_file_attributes (char *path)
 
 /* Shadow some MSVC runtime functions to map requests for long filenames
    to reasonable short names if necessary.  This was originally added to
 
 /* Shadow some MSVC runtime functions to map requests for long filenames
    to reasonable short names if necessary.  This was originally added to
-   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
    long file names.  */
 
 int
    long file names.  */
 
 int
@@ -2421,7 +2492,7 @@ stat (const char * path, struct stat * buf)
     permission = _S_IREAD;
   else
     permission = _S_IREAD | _S_IWRITE;
     permission = _S_IREAD;
   else
     permission = _S_IREAD | _S_IWRITE;
-  
+
   if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
     permission |= _S_IEXEC;
   else if (is_exec (name))
   if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
     permission |= _S_IEXEC;
   else if (is_exec (name))
@@ -2505,7 +2576,7 @@ fstat (int desc, struct stat * buf)
     permission = _S_IREAD;
   else
     permission = _S_IREAD | _S_IWRITE;
     permission = _S_IREAD;
   else
     permission = _S_IREAD | _S_IWRITE;
-  
+
   if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
     permission |= _S_IEXEC;
   else
   if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
     permission |= _S_IEXEC;
   else
@@ -2757,7 +2828,7 @@ struct {
   WSAEFAULT               , "Bad address",
   WSAEINVAL               , "Invalid argument",
   WSAEMFILE               , "Too many open files",
   WSAEFAULT               , "Bad address",
   WSAEINVAL               , "Invalid argument",
   WSAEMFILE               , "Too many open files",
-                       
+
   WSAEWOULDBLOCK          , "Resource temporarily unavailable",
   WSAEINPROGRESS          , "Operation now in progress",
   WSAEALREADY             , "Operation already in progress",
   WSAEWOULDBLOCK          , "Resource temporarily unavailable",
   WSAEINPROGRESS          , "Operation now in progress",
   WSAEALREADY             , "Operation already in progress",
@@ -2795,7 +2866,7 @@ struct {
   WSAEDQUOT               , "Double quote in host name",    /* really not sure */
   WSAESTALE               , "Data is stale",               /* not sure */
   WSAEREMOTE              , "Remote error",                /* not sure */
   WSAEDQUOT               , "Double quote in host name",    /* really not sure */
   WSAESTALE               , "Data is stale",               /* not sure */
   WSAEREMOTE              , "Remote error",                /* not sure */
-                       
+
   WSASYSNOTREADY          , "Network subsystem is unavailable",
   WSAVERNOTSUPPORTED      , "WINSOCK.DLL version out of range",
   WSANOTINITIALISED       , "Winsock not initialized successfully",
   WSASYSNOTREADY          , "Network subsystem is unavailable",
   WSAVERNOTSUPPORTED      , "WINSOCK.DLL version out of range",
   WSANOTINITIALISED       , "Winsock not initialized successfully",
@@ -2813,7 +2884,7 @@ struct {
   WSA_E_CANCELLED         , "Operation already cancelled",  /* really not sure */
   WSAEREFUSED             , "Operation refused",           /* not sure */
 #endif
   WSA_E_CANCELLED         , "Operation already cancelled",  /* really not sure */
   WSAEREFUSED             , "Operation refused",           /* not sure */
 #endif
-                       
+
   WSAHOST_NOT_FOUND       , "Host not found",
   WSATRY_AGAIN            , "Authoritative host not found during name lookup",
   WSANO_RECOVERY          , "Non-recoverable error during name lookup",
   WSAHOST_NOT_FOUND       , "Host not found",
   WSATRY_AGAIN            , "Authoritative host not found during name lookup",
   WSANO_RECOVERY          , "Non-recoverable error during name lookup",
@@ -2868,7 +2939,7 @@ sys_socket(int af, int type, int protocol)
 
   /* call the real socket function */
   s = pfn_socket (af, type, protocol);
 
   /* call the real socket function */
   s = pfn_socket (af, type, protocol);
-  
+
   if (s != INVALID_SOCKET)
     return socket_to_fd (s);
 
   if (s != INVALID_SOCKET)
     return socket_to_fd (s);
 
@@ -2941,7 +3012,7 @@ socket_to_fd (SOCKET s)
                  {
                    CloseHandle (new_s);
                  }
                  {
                    CloseHandle (new_s);
                  }
-             } 
+             }
          }
       }
       fd_info[fd].hnd = (HANDLE) s;
          }
       }
       fd_info[fd].hnd = (HANDLE) s;
@@ -3154,7 +3225,7 @@ sys_setsockopt (int s, int level, int optname, const char * optval, int optlen)
       return rc;
     }
   h_errno = ENOTSOCK;
       return rc;
     }
   h_errno = ENOTSOCK;
-  return SOCKET_ERROR;      
+  return SOCKET_ERROR;
 }
 
 int
 }
 
 int
@@ -3175,7 +3246,7 @@ sys_listen (int s, int backlog)
       return rc;
     }
   h_errno = ENOTSOCK;
       return rc;
     }
   h_errno = ENOTSOCK;
-  return SOCKET_ERROR;      
+  return SOCKET_ERROR;
 }
 
 int
 }
 
 int
@@ -3196,7 +3267,7 @@ sys_getsockname (int s, struct sockaddr * name, int * namelen)
       return rc;
     }
   h_errno = ENOTSOCK;
       return rc;
     }
   h_errno = ENOTSOCK;
-  return SOCKET_ERROR;      
+  return SOCKET_ERROR;
 }
 
 int
 }
 
 int
@@ -3394,7 +3465,7 @@ sys_dup2 (int src, int dst)
   /* make sure we close the destination first if it's a pipe or socket */
   if (src != dst && fd_info[dst].flags != 0)
     sys_close (dst);
   /* make sure we close the destination first if it's a pipe or socket */
   if (src != dst && fd_info[dst].flags != 0)
     sys_close (dst);
-  
+
   rc = _dup2 (src, dst);
   if (rc == 0)
     {
   rc = _dup2 (src, dst);
   if (rc == 0)
     {
@@ -3419,18 +3490,29 @@ sys_pipe (int * phandles)
 
   if (rc == 0)
     {
 
   if (rc == 0)
     {
-      flags = FILE_PIPE | FILE_READ | FILE_BINARY;
-      fd_info[phandles[0]].flags = flags;
+      /* Protect against overflow, since Windows can open more handles than
+        our fd_info array has room for.  */
+      if (phandles[0] >= MAXDESC || phandles[1] >= MAXDESC)
+       {
+         _close (phandles[0]);
+         _close (phandles[1]);
+         rc = -1;
+       }
+      else
+       {
+         flags = FILE_PIPE | FILE_READ | FILE_BINARY;
+         fd_info[phandles[0]].flags = flags;
 
 
-      flags = FILE_PIPE | FILE_WRITE | FILE_BINARY;
-      fd_info[phandles[1]].flags = flags;
+         flags = FILE_PIPE | FILE_WRITE | FILE_BINARY;
+         fd_info[phandles[1]].flags = flags;
+       }
     }
 
   return rc;
 }
 
 /* From ntproc.c */
     }
 
   return rc;
 }
 
 /* From ntproc.c */
-extern Lisp_Object Vw32_pipe_read_delay;
+extern int w32_pipe_read_delay;
 
 /* Function to do blocking read of one byte, needed to implement
    select.  It is only allowed on sockets and pipes. */
 
 /* Function to do blocking read of one byte, needed to implement
    select.  It is only allowed on sockets and pipes. */
@@ -3454,9 +3536,9 @@ _sys_read_ahead (int fd)
       DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd));
       abort ();
     }
       DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd));
       abort ();
     }
-  
+
   cp->status = STATUS_READ_IN_PROGRESS;
   cp->status = STATUS_READ_IN_PROGRESS;
-  
+
   if (fd_info[fd].flags & FILE_PIPE)
     {
       rc = _read (fd, &cp->chr, sizeof (char));
   if (fd_info[fd].flags & FILE_PIPE)
     {
       rc = _read (fd, &cp->chr, sizeof (char));
@@ -3470,7 +3552,7 @@ _sys_read_ahead (int fd)
         shell on NT is very slow if we don't do this. */
       if (rc > 0)
        {
         shell on NT is very slow if we don't do this. */
       if (rc > 0)
        {
-         int wait = XINT (Vw32_pipe_read_delay);
+         int wait = w32_pipe_read_delay;
 
          if (wait > 0)
            Sleep (wait);
 
          if (wait > 0)
            Sleep (wait);
@@ -3498,7 +3580,7 @@ _sys_read_ahead (int fd)
        }
     }
 #endif
        }
     }
 #endif
-  
+
   if (rc == sizeof (char))
     cp->status = STATUS_READ_SUCCEEDED;
   else
   if (rc == sizeof (char))
     cp->status = STATUS_READ_SUCCEEDED;
   else
@@ -3697,7 +3779,7 @@ sys_write (int fd, const void * buffer, unsigned int count)
                  next[0] = '\n';
                  dst = next + 1;
                  count++;
                  next[0] = '\n';
                  dst = next + 1;
                  count++;
-               }           
+               }
              else
                /* copied remaining partial line -> now finished */
                break;
              else
                /* copied remaining partial line -> now finished */
                break;
@@ -3750,7 +3832,7 @@ check_windows_init_file ()
      it cannot find the Windows installation file.  If this file does
      not exist in the expected place, tell the user.  */
 
      it cannot find the Windows installation file.  If this file does
      not exist in the expected place, tell the user.  */
 
-  if (!noninteractive && !inhibit_window_system) 
+  if (!noninteractive && !inhibit_window_system)
     {
       extern Lisp_Object Vwindow_system, Vload_path, Qfile_exists_p;
       Lisp_Object objs[2];
     {
       extern Lisp_Object Vwindow_system, Vload_path, Qfile_exists_p;
       Lisp_Object objs[2];
@@ -3763,14 +3845,14 @@ check_windows_init_file ()
       full_load_path = Fappend (2, objs);
       init_file = build_string ("term/w32-win");
       fd = openp (full_load_path, init_file, Vload_suffixes, NULL, Qnil);
       full_load_path = Fappend (2, objs);
       init_file = build_string ("term/w32-win");
       fd = openp (full_load_path, init_file, Vload_suffixes, NULL, Qnil);
-      if (fd < 0) 
+      if (fd < 0)
        {
          Lisp_Object load_path_print = Fprin1_to_string (full_load_path, Qnil);
          char *init_file_name = SDATA (init_file);
          char *load_path = SDATA (load_path_print);
          char *buffer = alloca (1024);
 
        {
          Lisp_Object load_path_print = Fprin1_to_string (full_load_path, Qnil);
          char *init_file_name = SDATA (init_file);
          char *load_path = SDATA (load_path_print);
          char *buffer = alloca (1024);
 
-         sprintf (buffer, 
+         sprintf (buffer,
                   "The Emacs Windows initialization file \"%s.el\" "
                   "could not be found in your Emacs installation.  "
                   "Emacs checked the following directories for this file:\n"
                   "The Emacs Windows initialization file \"%s.el\" "
                   "could not be found in your Emacs installation.  "
                   "Emacs checked the following directories for this file:\n"
@@ -3835,14 +3917,14 @@ init_ntproc ()
 
     /* ignore errors when duplicating and closing; typically the
        handles will be invalid when running as a gui program. */
 
     /* ignore errors when duplicating and closing; typically the
        handles will be invalid when running as a gui program. */
-    DuplicateHandle (parent, 
-                    GetStdHandle (STD_INPUT_HANDLE), 
+    DuplicateHandle (parent,
+                    GetStdHandle (STD_INPUT_HANDLE),
                     parent,
                     parent,
-                    &stdin_save, 
-                    0, 
-                    FALSE, 
+                    &stdin_save,
+                    0,
+                    FALSE,
                     DUPLICATE_SAME_ACCESS);
                     DUPLICATE_SAME_ACCESS);
-    
+
     DuplicateHandle (parent,
                     GetStdHandle (STD_OUTPUT_HANDLE),
                     parent,
     DuplicateHandle (parent,
                     GetStdHandle (STD_OUTPUT_HANDLE),
                     parent,
@@ -3850,7 +3932,7 @@ init_ntproc ()
                     0,
                     FALSE,
                     DUPLICATE_SAME_ACCESS);
                     0,
                     FALSE,
                     DUPLICATE_SAME_ACCESS);
-    
+
     DuplicateHandle (parent,
                     GetStdHandle (STD_ERROR_HANDLE),
                     parent,
     DuplicateHandle (parent,
                     GetStdHandle (STD_ERROR_HANDLE),
                     parent,
@@ -3858,7 +3940,7 @@ init_ntproc ()
                     0,
                     FALSE,
                     DUPLICATE_SAME_ACCESS);
                     0,
                     FALSE,
                     DUPLICATE_SAME_ACCESS);
-    
+
     fclose (stdin);
     fclose (stdout);
     fclose (stderr);
     fclose (stdin);
     fclose (stdout);
     fclose (stderr);
@@ -3895,7 +3977,7 @@ init_ntproc ()
     while (*drive <= 'Z')
     {
       /* Record if this drive letter refers to a fixed drive. */
     while (*drive <= 'Z')
     {
       /* Record if this drive letter refers to a fixed drive. */
-      fixed_drives[DRIVE_INDEX (*drive)] = 
+      fixed_drives[DRIVE_INDEX (*drive)] =
        (GetDriveType (drive) == DRIVE_FIXED);
 
       (*drive)++;
        (GetDriveType (drive) == DRIVE_FIXED);
 
       (*drive)++;
@@ -3904,9 +3986,26 @@ init_ntproc ()
     /* Reset the volume info cache.  */
     volume_cache = NULL;
   }
     /* Reset the volume info cache.  */
     volume_cache = NULL;
   }
-  
+
   /* Check to see if Emacs has been installed correctly.  */
   check_windows_init_file ();
 }
 
   /* Check to see if Emacs has been installed correctly.  */
   check_windows_init_file ();
 }
 
+/*
+       globals_of_w32 is used to initialize those global variables that
+       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 ()
+{
+  g_b_init_is_windows_9x = 0;
+  g_b_init_open_process_token = 0;
+  g_b_init_get_token_information = 0;
+  g_b_init_lookup_account_sid = 0;
+  g_b_init_get_sid_identifier_authority = 0;
+}
+
 /* end of nt.c */
 /* end of nt.c */
+
+/* arch-tag: 90442dd3-37be-482b-b272-ac752e3049f1
+   (do not change this comment) */