/* Utility and Unix shadow routines for GNU Emacs on Windows NT.
- Copyright (C) 1994 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
- This file is part of GNU Emacs.
+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 1, or (at your option) any later
- version.
+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)
+any later version.
- GNU Emacs is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with GNU Emacs; see the file COPYING. If not, write to the Free Software
- Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
Geoff Voelker (voelker@cs.washington.edu) 7-29-94
*/
+/* Define stat before including config.h. */
+#include <string.h>
+#include <sys/stat.h>
+int
+nt_stat (char *filename, struct stat *statbuf)
+{
+ int r, l = strlen (filename);
+ char *str = NULL;
+ extern long *xmalloc ();
+ extern void xfree ();
+
+ /* stat has a bug when passed a name of a directory with a trailing
+ backslash (but a trailing forward slash works fine). */
+ if (filename[l - 1] == '\\')
+ {
+ str = (char *) xmalloc (l + 1);
+ strcpy (str, filename);
+ str[l - 1] = '/';
+ r = stat (str, statbuf);
+ xfree (str);
+ return r;
+ }
+ else
+ return stat (filename, statbuf);
+}
+
+/* Place a wrapper around the NT version of ctime. It returns NULL
+ on network directories, so we handle that case here.
+ Define it before including config.h. (Ulrich Leodolter, 1/11/95). */
+char *
+nt_ctime (const time_t *t)
+{
+ char *str = (char *) ctime (t);
+ return (str ? str : "Sun Jan 01 00:00:00 1970");
+}
+
+#include <config.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
-#include "config.h"
#define getwd _getwd
#include "lisp.h"
#undef getwd
return NULL;
}
- /* Don't return . or .. since it doesn't look like any of the
- readdir calling code expects them. */
- while (strcmp (find_data.cFileName, ".") == 0
- || strcmp (find_data.cFileName, "..") == 0)
- {
- if (!FindNextFile (dir_find_handle, &find_data))
- return 0;
- }
-
/* NT's unique ID for a file is 64 bits, so we have to fake it here.
This should work as long as we never use 0. */
dir_static.d_ino = 1;
int getuid (); /* forward declaration */
-static char the_passwd_name[256];
-static char the_passwd_passwd[256];
-static char the_passwd_gecos[256];
-static char the_passwd_dir[256];
-static char the_passwd_shell[256];
+#define PASSWD_FIELD_SIZE 256
+
+static char the_passwd_name[PASSWD_FIELD_SIZE];
+static char the_passwd_passwd[PASSWD_FIELD_SIZE];
+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 struct passwd the_passwd =
{
struct passwd *
getpwuid (int uid)
{
- int size = 256;
+ int size = PASSWD_FIELD_SIZE;
if (!GetUserName (the_passwd.pw_name, &size))
return NULL;
user enter it, so we define EMACS_CONFIGURATION to invoke this runtime
routine. */
-static char configuration_buffer[16];
+static char configuration_buffer[32];
char *
get_emacs_configuration (void)
{
- char *arch, *oem;
+ char *arch, *oem, *os;
- /* Determine the processor type. */
- switch (get_processor_type ())
- {
- case PROCESSOR_INTEL_386:
- case PROCESSOR_INTEL_486:
- case PROCESSOR_INTEL_PENTIUM:
- arch = "i386";
- break;
- case PROCESSOR_INTEL_860:
- arch = "i860";
- break;
- case PROCESSOR_MIPS_R2000:
- case PROCESSOR_MIPS_R3000:
- case PROCESSOR_MIPS_R4000:
- arch = "mips";
- break;
- case PROCESSOR_ALPHA_21064:
- arch = "alpha";
- break;
- default:
- arch = "unknown";
- break;
- }
-
- /* Let oem be "*" until we figure out how to decode the OEM field. */
- oem = "*";
-
- sprintf (configuration_buffer, "%s-%s-nt%d.%d", arch, oem,
- get_nt_major_version (), get_nt_minor_version ());
- return configuration_buffer;
+ /* Determine the processor type. */
+ switch (get_processor_type ())
+ {
+
+#ifdef PROCESSOR_INTEL_386
+ case PROCESSOR_INTEL_386:
+ case PROCESSOR_INTEL_486:
+ case PROCESSOR_INTEL_PENTIUM:
+ arch = "i386";
+ break;
+#endif
+
+#ifdef PROCESSOR_INTEL_860
+ case PROCESSOR_INTEL_860:
+ arch = "i860";
+ break;
+#endif
+
+#ifdef PROCESSOR_MIPS_R2000
+ case PROCESSOR_MIPS_R2000:
+ case PROCESSOR_MIPS_R3000:
+ case PROCESSOR_MIPS_R4000:
+ arch = "mips";
+ break;
+#endif
+
+#ifdef PROCESSOR_ALPHA_21064
+ case PROCESSOR_ALPHA_21064:
+ arch = "alpha";
+ break;
+#endif
+
+ default:
+ arch = "unknown";
+ break;
+ }
+
+ /* Let oem be "*" until we figure out how to decode the OEM field. */
+ oem = "*";
+
+#ifdef WINDOWS95
+ os = "win";
+#else
+ os = "nt";
+#endif
+
+ sprintf (configuration_buffer, "%s-%s-%s%d.%d", arch, oem, os,
+ get_nt_major_version (), get_nt_minor_version ());
+ return configuration_buffer;
}
/* Conjure up inode and device numbers that will serve the purpose
HANDLE handle;
BOOL result;
+ DWORD attrs;
BY_HANDLE_FILE_INFORMATION info;
+ /* We have to stat files and directories differently, so check
+ to see what filename references. */
+ attrs = GetFileAttributes (XSTRING (filename)->data);
+ if (attrs == 0xFFFFFFFF) {
+ return 0;
+ }
+ if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
+ /* Conjure up bogus, but unique, values. */
+ attrs = GetTickCount ();
+ *p_inode = make_number (attrs);
+ *p_device = make_number (attrs);
+ return 1;
+ }
+
/* FIXME: It shouldn't be opened without READ access, but NT on x86
doesn't allow GetFileInfo in that case (NT on mips does). */
prepare_standard_handles (int in, int out, int err, HANDLE handles[4])
{
HANDLE parent, stdin_save, stdout_save, stderr_save, err_handle;
-
+
+#ifdef WINDOWS95
+ /* The Win95 beta doesn't set the standard handles correctly.
+ Handicap subprocesses until we get a version that works correctly.
+ Undefining the subprocesses macro reveals other incompatibilities,
+ so, since we're expecting subprocs to work in the near future,
+ disable them here. */
+ report_file_error ("Subprocesses currently disabled on Win95", Qnil);
+#endif
+
parent = GetCurrentProcess ();
+ stdin_save = GetStdHandle (STD_INPUT_HANDLE);
+ stdout_save = GetStdHandle (STD_OUTPUT_HANDLE);
+ stderr_save = GetStdHandle (STD_ERROR_HANDLE);
+
+#ifndef HAVE_NTGUI
if (!DuplicateHandle (parent,
GetStdHandle (STD_INPUT_HANDLE),
parent,
FALSE,
DUPLICATE_SAME_ACCESS))
report_file_error ("Duplicating parent's error handle", Qnil);
+#endif /* !HAVE_NTGUI */
if (!SetStdHandle (STD_INPUT_HANDLE, (HANDLE) _get_osfhandle (in)))
report_file_error ("Changing stdin handle", Qnil);
HANDLE stdout_save = handles[1];
HANDLE stderr_save = handles[2];
HANDLE err_handle = handles[3];
-
+ int i;
+
+#ifndef HAVE_NTGUI
if (!SetStdHandle (STD_INPUT_HANDLE, stdin_save))
report_file_error ("Resetting input handle", Qnil);
if (!SetStdHandle (STD_OUTPUT_HANDLE, stdout_save))
- report_file_error ("Resetting output handle", Qnil);
+ {
+ i = GetLastError ();
+ report_file_error ("Resetting output handle", Qnil);
+ }
if (!SetStdHandle (STD_ERROR_HANDLE, stderr_save))
report_file_error ("Resetting error handle", Qnil);
+#endif /* !HAVE_NTGUI */
if (out == err)
{
}
}
+int
+random ()
+{
+ /* rand () on NT gives us 15 random bits...hack together 30 bits. */
+ return ((rand () << 15) | rand ());
+}
+
+void
+srandom (int seed)
+{
+ srand (seed);
+}
+
/* Destructively turn backslashes into slashes. */
void
dostounix_filename (p)
int
getuid ()
{
- return 0;
+ char buffer[256];
+ int size = 256;
+
+ if (!GetUserName (buffer, &size))
+ /* Assume all powers upon failure. */
+ return 0;
+
+ if (!stricmp ("administrator", buffer))
+ return 0;
+ else
+ /* A complete fabrication...is there anything to base it on? */
+ return 123;
}
int
geteuid ()
{
- return 0;
+ /* 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 ();
}
/* Remove all CR's that are followed by a LF.
return np - startp;
}
+#define REG_ROOT "SOFTWARE\\GNU\\Emacs\\"
+
+LPBYTE
+nt_get_resource (key, lpdwtype)
+ char *key;
+ LPDWORD lpdwtype;
+{
+ LPBYTE lpvalue;
+ HKEY hrootkey = NULL;
+ DWORD cbData;
+ BOOL ok = FALSE;
+
+ /* Check both the current user and the local machine to see if
+ we have any resources. */
+
+ 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
+ && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
+ {
+ return (lpvalue);
+ }
+
+ if (lpvalue) xfree (lpvalue);
+
+ RegCloseKey (hrootkey);
+ }
+
+ 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 (lpvalue) xfree (lpvalue);
+
+ RegCloseKey (hrootkey);
+ }
+
+ return (NULL);
+}
+
+void
+init_environment ()
+{
+ /* Open a console window to display messages during dumping. */
+ if (!initialized)
+ AllocConsole ();
+
+ /* Check for environment variables and use registry if they don't exist */
+ {
+ int i;
+ LPBYTE lpval;
+ DWORD dwType;
+
+ static char * env_vars[] =
+ {
+ "emacs_path",
+ "EMACSLOADPATH",
+ "SHELL",
+ "EMACSDATA",
+ "EMACSPATH",
+ "EMACSLOCKDIR",
+ "INFOPATH",
+ "EMACSDOC",
+ "TERM",
+ };
+
+ for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
+ {
+ if (!getenv (env_vars[i]) &&
+ (lpval = nt_get_resource (env_vars[i], &dwType)) != NULL)
+ {
+ if (dwType == REG_EXPAND_SZ)
+ {
+ char buf1[500], buf2[500];
+
+ ExpandEnvironmentStrings ((LPSTR) lpval, buf1, 500);
+ _snprintf (buf2, 499, "%s=%s", env_vars[i], buf1);
+ putenv (strdup (buf2));
+ }
+ else if (dwType == REG_SZ)
+ {
+ char buf[500];
+
+ _snprintf (buf, 499, "%s=%s", env_vars[i], lpval);
+ putenv (strdup (buf));
+ }
+
+ xfree (lpval);
+ }
+ }
+ }
+}
+
+#ifdef HAVE_TIMEVAL
+#include <sys/timeb.h>
+
+/* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
+void
+gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ struct _timeb tb;
+ _ftime (&tb);
+
+ tv->tv_sec = tb.time;
+ tv->tv_usec = tb.millitm * 1000L;
+ if (tz)
+ {
+ tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
+ tz->tz_dsttime = tb.dstflag; /* type of dst correction */
+ }
+}
+#endif /* HAVE_TIMEVAL */
+
#ifdef PIGSFLY
Keep this around...we might need it later.
SID_NAME_USE User;
if (1)
- Vuser_real_name = build_string ("foo");
+ Vuser_real_login_name = build_string ("foo");
else if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &Token))
{
- Vuser_real_name = build_string ("unknown");
+ Vuser_real_login_name = build_string ("unknown");
}
else if (!GetTokenInformation (Token, TokenUser, (PVOID)b, 256,
&trash))
{
CloseHandle (Token);
- Vuser_real_name = build_string ("unknown");
+ Vuser_real_login_name = build_string ("unknown");
}
else if (!LookupAccountSid ((void *)0, (PSID)b, Name, &length, RefD,
&rlength, &User))
{
CloseHandle (Token);
- Vuser_real_name = build_string ("unknown");
+ Vuser_real_login_name = build_string ("unknown");
}
else
- Vuser_real_name = build_string (Name);
+ Vuser_real_login_name = build_string (Name);
}
#else /* not WINDOWSNT */
#endif /* not WINDOWSNT */