#include <stdlib.h>
#include <stdio.h>
-#include <windows.h>
-#ifndef __MINGW32__
-#include <mmsystem.h>
-#else
-typedef void (CALLBACK TIMECALLBACK)(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
-
-typedef TIMECALLBACK FAR *LPTIMECALLBACK;
-DWORD WINAPI timeGetTime(void);
-MMRESULT WINAPI timeSetEvent(UINT uDelay, UINT uResolution,
- LPTIMECALLBACK fptc, DWORD dwUser, UINT fuEvent);
-MMRESULT WINAPI timeKillEvent(UINT uTimerID);
-MMRESULT WINAPI timeGetDevCaps(TIMECAPS* ptc, UINT cbtc);
-MMRESULT WINAPI timeBeginPeriod(UINT uPeriod);
-MMRESULT WINAPI timeEndPeriod(UINT uPeriod);
-#endif
+#include "syswindows.h"
#include "nt.h"
#include <sys/dir.h>
};
uid_t
-getuid ()
+getuid (void)
{
return nt_fake_unix_uid;
}
uid_t
-geteuid ()
+geteuid (void)
{
return nt_fake_unix_uid;
}
gid_t
-getgid ()
+getgid (void)
{
return the_passwd.pw_gid;
}
gid_t
-getegid ()
+getegid (void)
{
return getgid ();
}
}
void
-init_user_info ()
+init_user_info (void)
{
/* This code is pretty much of ad hoc nature. There is no unix-like
UIDs under Windows NT. There is no concept of root user, because
putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd");
/* Set dir and shell from environment variables. */
- strcpy (the_passwd.pw_dir, get_home_directory());
+ strcpy (the_passwd.pw_dir, (char *)get_home_directory());
strcpy (the_passwd.pw_shell, getenv ("SHELL"));
}
case path name components to lower case. */
static void
-normalize_filename (fp, path_sep)
- REGISTER char *fp;
- char path_sep;
+normalize_filename (char *fp, char path_sep)
{
char sep;
char *elem;
/* Destructively turn backslashes into slashes. */
void
-dostounix_filename (p)
- REGISTER char *p;
+dostounix_filename (char *p)
{
normalize_filename (p, '/');
}
/* Destructively turn slashes into backslashes. */
void
-unixtodos_filename (p)
- REGISTER char *p;
+unixtodos_filename (char *p)
{
normalize_filename (p, '\\');
}
(From msdos.c...probably should figure out a way to share it,
although this code isn't going to ever change.) */
int
-crlf_to_lf (n, buf, lf_count)
- REGISTER int n;
- REGISTER unsigned char *buf;
- REGISTER unsigned *lf_count;
+crlf_to_lf (int n, unsigned char *buf, unsigned *lf_count)
{
unsigned char *np = buf;
unsigned char *startp = buf;
#define REG_ROOT "SOFTWARE\\GNU\\XEmacs"
LPBYTE
-nt_get_resource (key, lpdwtype)
- char *key;
- LPDWORD lpdwtype;
+nt_get_resource (char *key, LPDWORD lpdwtype)
{
LPBYTE lpvalue;
HKEY hrootkey = NULL;
}
void
-init_environment ()
+init_environment (void)
{
/* Check for environment variables and use registry if they don't exist */
{
"EMACSLOCKDIR",
"INFOPATH"
};
-#ifdef HEAP_IN_DATA
+#if defined (HEAP_IN_DATA) && !defined(PDUMP)
cache_system_info ();
#endif
for (i = 0; i < countof (env_vars); i++)
}
#else
+#if defined(__MINGW32__) && CYGWIN_VERSION_DLL_MAJOR <= 21
+#define LowPart u.LowPart
+#define HighPart u.HighPart
+#endif
+
static LARGE_INTEGER utc_base_li;
time_t
return ret;
}
#endif
+#if defined(__MINGW32__) && CYGWIN_VERSION_DLL_MAJOR <= 21
+#undef LowPart
+#undef HighPart
+#endif
#if 0
/* in case we ever have need of this */
Oh, and do not encapsulater stat for non-MS compilers, too */
/* #### popineau@ese-metz.fr says they still might be broken.
Oh well... Let's add that `1 ||' condition.... --kkm */
+/* #### aichner@ecf.teradyne.com reported that with the library
+ provided stat/fstat, (file-exist "d:\\tmp\\") =>> nil,
+ (file-exist "d:\\tmp") =>> t, when d:\tmp exists. Whenever
+ we opt to use non-encapsulated stat(), this should serve as
+ a compatibility test. --kkm */
+
#if 1 || defined(_MSC_VER) && _MSC_VER < 1100
/* Since stat is encapsulated on Windows NT, we need to encapsulate
len = strlen (name);
rootdir = (path >= name + len - 1
&& (IS_DIRECTORY_SEP (*path) || *path == 0));
- name = strcpy (alloca (len + 2), name);
+ name = strcpy ((char *)alloca (len + 2), name);
if (rootdir)
{
}
void
-init_ntproc ()
+init_ntproc (void)
{
/* Initial preparation for subprocess support: replace our standard
handles with non-inheritable versions. */
return errno = EINVAL;
}
+\f
+/*--------------------------------------------------------------------*/
+/* Memory-mapped files */
+/*--------------------------------------------------------------------*/
+
int
-open_input_file (file_data *p_file, CONST char *filename)
+open_input_file (file_data *p_file, const char *filename)
{
+ /* Synched with FSF 20.6. We fixed some warnings. */
HANDLE file;
HANDLE file_mapping;
void *file_base;
if (file_base == 0)
return FALSE;
- p_file->name = (char*)filename;
+ p_file->name = (char *)filename;
+ p_file->size = size;
+ p_file->file = file;
+ p_file->file_mapping = file_mapping;
+ p_file->file_base = (char *)file_base;
+
+ return TRUE;
+}
+
+int
+open_output_file (file_data *p_file, const char *filename, unsigned long size)
+{
+ /* Synched with FSF 20.6. We fixed some warnings. */
+ HANDLE file;
+ HANDLE file_mapping;
+ void *file_base;
+
+ file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (file == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE,
+ 0, size, NULL);
+ if (!file_mapping)
+ return FALSE;
+
+ file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size);
+ if (file_base == NULL)
+ return FALSE;
+
+ p_file->name = filename;
p_file->size = size;
p_file->file = file;
p_file->file_mapping = file_mapping;
- p_file->file_base = file_base;
+ p_file->file_base = (char*) file_base;
return TRUE;
}
+#if 1 /* !defined(__MINGW32__) */
+/* Return pointer to section header for section containing the given
+ relative virtual address. */
+static IMAGE_SECTION_HEADER *
+rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header)
+{
+ /* Synched with FSF 20.6. We added MINGW32 stuff. */
+ PIMAGE_SECTION_HEADER section;
+ int i;
+
+ section = IMAGE_FIRST_SECTION (nt_header);
+
+ for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
+ {
+ /* Some linkers (eg. the NT SDK linker I believe) swapped the
+ meaning of these two values - or rather, they ignored
+ VirtualSize entirely and always set it to zero. This affects
+ some very old exes (eg. gzip dated Dec 1993). Since
+ mswindows_executable_type relies on this function to work reliably,
+ we need to cope with this. */
+ DWORD real_size = max (section->SizeOfRawData,
+ section->Misc.VirtualSize);
+ if (rva >= section->VirtualAddress
+ && rva < section->VirtualAddress + real_size)
+ return section;
+ section++;
+ }
+ return NULL;
+}
+#endif
+
+void
+mswindows_executable_type (const char * filename, int * is_dos_app,
+ int * is_cygnus_app)
+{
+ /* Synched with FSF 20.6. We added MINGW32 stuff and casts. */
+ file_data executable;
+ char * p;
+
+ /* Default values in case we can't tell for sure. */
+ *is_dos_app = FALSE;
+ *is_cygnus_app = FALSE;
+
+ if (!open_input_file (&executable, filename))
+ return;
+
+ p = strrchr (filename, '.');
+
+ /* We can only identify DOS .com programs from the extension. */
+ if (p && stricmp (p, ".com") == 0)
+ *is_dos_app = TRUE;
+ else if (p && (stricmp (p, ".bat") == 0 ||
+ stricmp (p, ".cmd") == 0))
+ {
+ /* A DOS shell script - it appears that CreateProcess is happy to
+ accept this (somewhat surprisingly); presumably it looks at
+ COMSPEC to determine what executable to actually invoke.
+ Therefore, we have to do the same here as well. */
+ /* Actually, I think it uses the program association for that
+ extension, which is defined in the registry. */
+ p = egetenv ("COMSPEC");
+ if (p)
+ mswindows_executable_type (p, is_dos_app, is_cygnus_app);
+ }
+ else
+ {
+ /* Look for DOS .exe signature - if found, we must also check that
+ it isn't really a 16- or 32-bit Windows exe, since both formats
+ start with a DOS program stub. Note that 16-bit Windows
+ executables use the OS/2 1.x format. */
+
+#if 0 /* defined( __MINGW32__ ) */
+ /* mingw32 doesn't have enough headers to detect cygwin
+ apps, just do what we can. */
+ FILHDR * exe_header;
+
+ exe_header = (FILHDR*) executable.file_base;
+ if (exe_header->e_magic != DOSMAGIC)
+ goto unwind;
+
+ if ((char*) exe_header->e_lfanew > (char*) executable.size)
+ {
+ /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
+ *is_dos_app = TRUE;
+ }
+ else if (exe_header->nt_signature != NT_SIGNATURE)
+ {
+ *is_dos_app = TRUE;
+ }
+#else
+ IMAGE_DOS_HEADER * dos_header;
+ IMAGE_NT_HEADERS * nt_header;
+
+ dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
+ if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
+ goto unwind;
+
+ nt_header = (PIMAGE_NT_HEADERS) ((char*) dos_header + dos_header->e_lfanew);
+
+ if ((char*) nt_header > (char*) dos_header + executable.size)
+ {
+ /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
+ *is_dos_app = TRUE;
+ }
+ else if (nt_header->Signature != IMAGE_NT_SIGNATURE &&
+ LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
+ {
+ *is_dos_app = TRUE;
+ }
+ else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
+ {
+ /* Look for cygwin.dll in DLL import list. */
+ IMAGE_DATA_DIRECTORY import_dir =
+ nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+ IMAGE_IMPORT_DESCRIPTOR * imports;
+ IMAGE_SECTION_HEADER * section;
+
+ section = rva_to_section (import_dir.VirtualAddress, nt_header);
+ imports = (IMAGE_IMPORT_DESCRIPTOR *) RVA_TO_PTR (import_dir.VirtualAddress,
+ section, executable);
+
+ for ( ; imports->Name; imports++)
+ {
+ char *dllname = (char*) RVA_TO_PTR (imports->Name, section, executable);
+
+ /* The exact name of the cygwin dll has changed with
+ various releases, but hopefully this will be reasonably
+ future proof. */
+ if (strncmp (dllname, "cygwin", 6) == 0)
+ {
+ *is_cygnus_app = TRUE;
+ break;
+ }
+ }
+ }
+#endif
+ }
+
+ unwind:
+ close_file_data (&executable);
+}
+
/* Close the system structures associated with the given file. */
void
close_file_data (file_data *p_file)