/[emacs]/emacs/src/w32.c
ViewVC logotype

Diff of /emacs/src/w32.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.75 by jasonr, Fri May 3 20:40:03 2002 UTC revision 1.75.2.1 by miles, Fri Apr 4 06:21:03 2003 UTC
# Line 99  Boston, MA 02111-1307, USA. Line 99  Boston, MA 02111-1307, USA.
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)
# Line 147  getwd (char *dir) Line 343  getwd (char *dir)
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  }  }
# Line 160  getloadavg (double loadavg[], int nelem) Line 356  getloadavg (double loadavg[], int nelem)
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      }      }
# Line 177  static char the_passwd_gecos[PASSWD_FIEL Line 373  static char the_passwd_gecos[PASSWD_FIEL
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,
# Line 189  static struct passwd the_passwd = Line 385  static struct passwd the_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    
# Line 228  struct passwd * Line 424  struct passwd *
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;
# Line 254  init_user_info () Line 450  init_user_info ()
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. */
# Line 271  init_user_info () Line 471  init_user_info ()
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) +
# Line 282  init_user_info () Line 482  init_user_info ()
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)  +
# Line 582  is_unc_volume (const char *filename) Line 782  is_unc_volume (const char *filename)
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;
# Line 641  w32_get_resource (key, lpdwtype) Line 841  w32_get_resource (key, 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    
# Line 733  init_environment (char ** argv) Line 933  init_environment (char ** argv)
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},
# Line 742  init_environment (char ** argv) Line 942  init_environment (char ** argv)
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"},  */
# Line 788  init_environment (char ** argv) Line 987  init_environment (char ** argv)
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          }          }
# Line 820  init_environment (char ** argv) Line 1019  init_environment (char ** argv)
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                    }                    }
# Line 914  get_emacs_configuration (void) Line 1113  get_emacs_configuration (void)
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
# Line 1031  get_emacs_configuration_options (void) Line 1230  get_emacs_configuration_options (void)
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;
# Line 1039  gettimeofday (struct timeval *tv, struct Line 1238  gettimeofday (struct timeval *tv, struct
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  */
# Line 1051  gettimeofday (struct timeval *tv, struct Line 1250  gettimeofday (struct timeval *tv, struct
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)
# Line 1157  GetCachedVolumeInformation (char * root_ Line 1356  GetCachedVolumeInformation (char * root_
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.  */
# Line 1263  get_volume_info (const char * name, cons Line 1462  get_volume_info (const char * name, cons
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      {      {
# Line 1401  is_exec (const char * name) Line 1600  is_exec (const char * name)
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    
# Line 1474  readdir (DIR *dirp) Line 1673  readdir (DIR *dirp)
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      }      }
# Line 1501  readdir (DIR *dirp) Line 1700  readdir (DIR *dirp)
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)
# Line 1522  readdir (DIR *dirp) Line 1721  readdir (DIR *dirp)
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)
# Line 1603  unc_volume_file_attributes (char *path) Line 1802  unc_volume_file_attributes (char *path)
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
# Line 2207  stat (const char * path, struct stat * b Line 2406  stat (const char * path, struct stat * b
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      }      }
# Line 2253  stat (const char * path, struct stat * b Line 2452  stat (const char * path, struct stat * b
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))
# Line 2337  fstat (int desc, struct stat * buf) Line 2536  fstat (int desc, struct stat * buf)
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
# Line 2589  struct { Line 2788  struct {
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",
# Line 2627  struct { Line 2826  struct {
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",
# Line 2645  struct { Line 2844  struct {
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",
# Line 2700  sys_socket(int af, int type, int protoco Line 2899  sys_socket(int af, int type, int protoco
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    
# Line 2773  socket_to_fd (SOCKET s) Line 2972  socket_to_fd (SOCKET s)
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;
# Line 2986  sys_setsockopt (int s, int level, int op Line 3185  sys_setsockopt (int s, int level, int op
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
# Line 3007  sys_listen (int s, int backlog) Line 3206  sys_listen (int s, int backlog)
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
# Line 3028  sys_getsockname (int s, struct sockaddr Line 3227  sys_getsockname (int s, struct sockaddr
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
# Line 3226  sys_dup2 (int src, int dst) Line 3425  sys_dup2 (int src, int dst)
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      {      {
# Line 3286  _sys_read_ahead (int fd) Line 3485  _sys_read_ahead (int fd)
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));
# Line 3330  _sys_read_ahead (int fd) Line 3529  _sys_read_ahead (int fd)
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
# Line 3529  sys_write (int fd, const void * buffer, Line 3728  sys_write (int fd, const void * buffer,
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;
# Line 3541  sys_write (int fd, const void * buffer, Line 3740  sys_write (int fd, const void * buffer,
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          }          }
# Line 3566  check_windows_init_file () Line 3781  check_windows_init_file ()
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];
# Line 3579  check_windows_init_file () Line 3794  check_windows_init_file ()
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"
# Line 3651  init_ntproc () Line 3866  init_ntproc ()
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,
# Line 3666  init_ntproc () Line 3881  init_ntproc ()
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,
# Line 3674  init_ntproc () Line 3889  init_ntproc ()
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);
# Line 3711  init_ntproc () Line 3926  init_ntproc ()
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)++;
# Line 3720  init_ntproc () Line 3935  init_ntproc ()
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 */

Legend:
Removed from v.1.75  
changed lines
  Added in v.1.75.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26