comparison src/nt.c @ 814:a634e3b7acc8

[xemacs-hg @ 2002-04-14 12:41:59 by ben] latest changes TODO.ben-mule-21-5: Update. make-docfile.c: Add basic support for handling ISO 2022 doc strings -- we parse the basic charset designation sequences so we know whether we're in ASCII and have to pay attention to end quotes and such. Reformat code according to coding standards. abbrev.el: Add `global-abbrev-mode', which turns on or off abbrev-mode in all buffers. Added `defining-abbrev-turns-on-abbrev-mode' -- if non-nil, defining an abbrev through an interactive function will automatically turn on abbrev-mode, either globally or locally depending on the command. This is the "what you'd expect" behavior. indent.el: general function for indenting a balanced expression in a mode-correct way. Works similar to indent-region in that a mode can specify a specific command to do the whole operation; if not, figure out the region using forward-sexp and indent each line using indent-according-to-mode. keydefs.el: Removed. Modify M-C-backslash to do indent-region-or-balanced-expression. Make S-Tab just insert a TAB char, like it's meant to do. make-docfile.el: Now that we're using the call-process-in-lisp, we need to load an extra file win32-native.el because we're running a bare temacs. menubar-items.el: Totally redo the Cmds menu so that most used commands appear directly on the menu and less used commands appear in submenus. The old way may have been very pretty, but rather impractical. process.el: Under Windows, don't ever use old-call-process-internal, even in batch mode. We can do processes in batch mode. subr.el: Someone recoded truncate-string-to-width, saying "the FSF version is too complicated and does lots of hard-to-understand stuff" but the resulting recoded version was *totally* wrong! it misunderstood the basic point of this function, which is work in *columns* not chars. i dumped ours and copied the version from FSF 21.1. Also added truncate-string-with-continuation-dots, since this idiom is used often. config.inc.samp, xemacs.mak: Separate out debug and optimize flags. Remove all vestiges of USE_MINIMAL_TAGBITS, USE_INDEXED_LRECORD_IMPLEMENTATION, and GUNG_HO, since those ifdefs have long been removed. Make error-checking support actually work. Some rearrangement of config.inc.samp to make it more logical. Remove callproc.c and ntproc.c from xemacs.mak, no longer used. Make pdump the default. lisp.h: Add support for strong type-checking of Bytecount, Bytebpos, Charcount, Charbpos, and others, by making them classes, overloading the operators to provide integer-like operation and carefully controlling what operations are allowed. Not currently enabled in C++ builds because there are still a number of compile errors, and it won't really work till we merge in my "8-bit-Mule" workspace, in which I make use of the new types Charxpos, Bytexpos, Memxpos, representing a "position" either in a buffer or a string. (This is especially important in the extent code.) abbrev.c, alloc.c, eval.c, buffer.c, buffer.h, editfns.c, fns.c, text.h: Warning fixes, some of them related to new C++ strict type checking of Bytecount, Charbpos, etc. dired.c: Caught an actual error due to strong type checking -- char len being passed when should be byte len. alloc.c, backtrace.h, bytecode.c, bytecode.h, eval.c, sysdep.c: Further optimize Ffuncall: -- process arg list at compiled-function creation time, converting into an array for extra-quick access at funcall time. -- rewrite funcall_compiled_function to use it, and inline this function. -- change the order of check for magic stuff in SPECBIND_FAST_UNSAFE to be faster. -- move the check for need to garbage collect into the allocation code, so only a single flag needs to be checked in funcall. buffer.c, symbols.c: add debug funs to check on mule optimization info in buffers and strings. eval.c, emacs.c, text.c, regex.c, scrollbar-msw.c, search.c: Fix evil crashes due to eistrings not properly reinitialized under pdump. Redo a bit some of the init routines; convert some complex_vars_of() into simple vars_of(), because they didn't need complex processing. callproc.c, emacs.c, event-stream.c, nt.c, process.c, process.h, sysdep.c, sysdep.h, syssignal.h, syswindows.h, ntproc.c: Delete. Hallelujah, praise the Lord, there is no god but Allah!!! fix so that processes can be invoked in bare temacs -- thereby eliminating any need for callproc.c. (currently only eliminated under NT.) remove all crufty and unnecessary old process code in ntproc.c and elsewhere. move non-callproc-specific stuff (mostly environment) into process.c, so callproc.c can be left out under NT. console-tty.c, doc.c, file-coding.c, file-coding.h, lstream.c, lstream.h: fix doc string handling so it works with Japanese, etc docs. change handling of "character mode" so callers don't have to manually set it (quite error-prone). event-msw.c: spacing fixes. lread.c: eliminate unused crufty vintage-19 "FSF defun hack" code. lrecord.h: improve pdump description docs. buffer.c, ntheap.c, unexnt.c, win32.c, emacs.c: Mule-ize some unexec and startup code. It was pseudo-Mule-ized before by simply always calling the ...A versions of functions, but that won't cut it -- eventually we want to be able to run properly even if XEmacs has been installed in a Japanese directory. (The current problem is the timing of the loading of the Unicode tables; this will eventually be fixed.) Go through and fix various other places where the code was not Mule-clean. Provide a function mswindows_get_module_file_name() to get our own name without resort to PATH_MAX and such. Add a big comment in main() about the problem with Unicode table load timing that I just alluded to. emacs.c: When error-checking is enabled (interpreted as "user is developing XEmacs"), don't ask user to "pause to read messages" when a fatal error has occurred, because it will wedge if we are in an inner modal loop (typically when a menu is popped up) and make us unable to get a useful stack trace in the debugger. text.c: Correct update_entirely_ascii_p_flag to actually work. lisp.h, symsinit.h: declarations for above changes.
author ben
date Sun, 14 Apr 2002 12:43:31 +0000
parents 2b676dc88c66
children 6504113e7c2d
comparison
equal deleted inserted replaced
813:9541922fb765 814:a634e3b7acc8
417 417
418 return (NULL); 418 return (NULL);
419 } 419 }
420 420
421 void 421 void
422 init_environment (void) 422 init_mswindows_environment (void)
423 { 423 {
424 /* Check for environment variables and use registry if they don't exist */ 424 /* Check for environment variables and use registry if they don't exist */
425 /* Emacs 20.6 sets default values for these; not necessary here because 425 /* Emacs 20.6 sets default values for these; not necessary here because
426 we already supply them. (except SHELL, which is set in init_user_info().) 426 we already supply them. (except SHELL, which is set in init_user_info().)
427 Emacs 20.6 messes with TMPDIR; not necessary here. */ 427 Emacs 20.6 messes with TMPDIR; not necessary here. */
1745 TSTR_TO_C_STRING_MALLOC (cwdext, cwd); 1745 TSTR_TO_C_STRING_MALLOC (cwdext, cwd);
1746 xfree (cwdext); 1746 xfree (cwdext);
1747 return cwd; 1747 return cwd;
1748 } 1748 }
1749 1749
1750
1751 /*--------------------------------------------------------------------*/
1752 /* Memory-mapped files */
1753 /*--------------------------------------------------------------------*/
1754
1755 int
1756 open_input_file (file_data *p_file, const Intbyte *filename)
1757 {
1758 /* Synched with FSF 20.6. We fixed some warnings. */
1759 HANDLE file;
1760 HANDLE file_mapping;
1761 void *file_base;
1762 DWORD size, upper_size;
1763 Extbyte *fileext;
1764
1765 C_STRING_TO_TSTR (filename, fileext);
1766
1767 file = qxeCreateFile (fileext, GENERIC_READ, FILE_SHARE_READ, NULL,
1768 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
1769 if (file == INVALID_HANDLE_VALUE)
1770 return FALSE;
1771
1772 size = GetFileSize (file, &upper_size);
1773 file_mapping = qxeCreateFileMapping (file, NULL, PAGE_READONLY,
1774 0, size, NULL);
1775 if (!file_mapping)
1776 return FALSE;
1777
1778 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size);
1779 if (file_base == 0)
1780 return FALSE;
1781
1782 p_file->name = filename;
1783 p_file->size = size;
1784 p_file->file = file;
1785 p_file->file_mapping = file_mapping;
1786 p_file->file_base = file_base;
1787
1788 return TRUE;
1789 }
1790
1791 int
1792 open_output_file (file_data *p_file, const Intbyte *filename,
1793 unsigned long size)
1794 {
1795 /* Synched with FSF 20.6. We fixed some warnings. */
1796 HANDLE file;
1797 HANDLE file_mapping;
1798 void *file_base;
1799 Extbyte *fileext;
1800
1801 C_STRING_TO_TSTR (filename, fileext);
1802
1803 file = qxeCreateFile (fileext, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1804 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
1805 if (file == INVALID_HANDLE_VALUE)
1806 return FALSE;
1807
1808 file_mapping = qxeCreateFileMapping (file, NULL, PAGE_READWRITE,
1809 0, size, NULL);
1810 if (!file_mapping)
1811 return FALSE;
1812
1813 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size);
1814 if (file_base == NULL)
1815 return FALSE;
1816
1817 p_file->name = filename;
1818 p_file->size = size;
1819 p_file->file = file;
1820 p_file->file_mapping = file_mapping;
1821 p_file->file_base = file_base;
1822
1823 return TRUE;
1824 }
1825
1826 #if 1 /* !defined(MINGW) */
1827 /* Return pointer to section header for section containing the given
1828 relative virtual address. */
1829 static IMAGE_SECTION_HEADER *
1830 rva_to_section (DWORD rva, IMAGE_NT_HEADERS *nt_header)
1831 {
1832 /* Synched with FSF 20.6. We added MINGW stuff. */
1833 PIMAGE_SECTION_HEADER section;
1834 int i;
1835
1836 section = IMAGE_FIRST_SECTION (nt_header);
1837
1838 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
1839 {
1840 /* Some linkers (eg. the NT SDK linker I believe) swapped the
1841 meaning of these two values - or rather, they ignored
1842 VirtualSize entirely and always set it to zero. This affects
1843 some very old exes (eg. gzip dated Dec 1993). Since
1844 mswindows_executable_type relies on this function to work reliably,
1845 we need to cope with this. */
1846 DWORD real_size = max (section->SizeOfRawData,
1847 section->Misc.VirtualSize);
1848 if (rva >= section->VirtualAddress
1849 && rva < section->VirtualAddress + real_size)
1850 return section;
1851 section++;
1852 }
1853 return NULL;
1854 }
1855 #endif
1856
1750 void 1857 void
1751 init_ntproc (void) 1858 mswindows_executable_type (const Intbyte *filename, int *is_dos_app,
1859 int *is_cygnus_app)
1860 {
1861 /* Synched with FSF 20.6. We added MINGW stuff and casts. */
1862 file_data executable;
1863 Intbyte *p;
1864
1865 /* Default values in case we can't tell for sure. */
1866 *is_dos_app = FALSE;
1867 *is_cygnus_app = FALSE;
1868
1869 if (!open_input_file (&executable, filename))
1870 return;
1871
1872 p = qxestrrchr (filename, '.');
1873
1874 /* We can only identify DOS .com programs from the extension. */
1875 if (p && qxestrcasecmp (p, ".com") == 0)
1876 *is_dos_app = TRUE;
1877 else if (p && (qxestrcasecmp (p, ".bat") == 0 ||
1878 qxestrcasecmp (p, ".cmd") == 0))
1879 {
1880 /* A DOS shell script - it appears that CreateProcess is happy to
1881 accept this (somewhat surprisingly); presumably it looks at
1882 COMSPEC to determine what executable to actually invoke.
1883 Therefore, we have to do the same here as well. */
1884 /* Actually, I think it uses the program association for that
1885 extension, which is defined in the registry. */
1886 p = egetenv ("COMSPEC");
1887 if (p)
1888 mswindows_executable_type (p, is_dos_app, is_cygnus_app);
1889 }
1890 else
1891 {
1892 /* Look for DOS .exe signature - if found, we must also check that
1893 it isn't really a 16- or 32-bit Windows exe, since both formats
1894 start with a DOS program stub. Note that 16-bit Windows
1895 executables use the OS/2 1.x format. */
1896
1897 #if 0 /* defined( MINGW ) */
1898 /* mingw doesn't have enough headers to detect cygwin
1899 apps, just do what we can. */
1900 FILHDR *exe_header;
1901
1902 exe_header = (FILHDR *) executable.file_base;
1903 if (exe_header->e_magic != DOSMAGIC)
1904 goto unwind;
1905
1906 if ((char *) exe_header->e_lfanew > (char *) executable.size)
1907 {
1908 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
1909 *is_dos_app = TRUE;
1910 }
1911 else if (exe_header->nt_signature != NT_SIGNATURE)
1912 {
1913 *is_dos_app = TRUE;
1914 }
1915 #else
1916 IMAGE_DOS_HEADER *dos_header;
1917 IMAGE_NT_HEADERS *nt_header;
1918
1919 dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
1920 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
1921 goto unwind;
1922
1923 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header +
1924 dos_header->e_lfanew);
1925
1926 if ((char *) nt_header > (char *) dos_header + executable.size)
1927 {
1928 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
1929 *is_dos_app = TRUE;
1930 }
1931 else if (nt_header->Signature != IMAGE_NT_SIGNATURE &&
1932 LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
1933 {
1934 *is_dos_app = TRUE;
1935 }
1936 else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
1937 {
1938 /* Look for cygwin.dll in DLL import list. */
1939 IMAGE_DATA_DIRECTORY import_dir =
1940 nt_header->OptionalHeader.
1941 DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
1942 IMAGE_IMPORT_DESCRIPTOR *imports;
1943 IMAGE_SECTION_HEADER *section;
1944
1945 section = rva_to_section (import_dir.VirtualAddress, nt_header);
1946 imports =
1947 (IMAGE_IMPORT_DESCRIPTOR *) RVA_TO_PTR (import_dir.VirtualAddress,
1948 section, executable);
1949
1950 for ( ; imports->Name; imports++)
1951 {
1952 Extbyte *dllname_ext =
1953 (Extbyte *) RVA_TO_PTR (imports->Name, section, executable);
1954 Intbyte *dllname;
1955
1956 EXTERNAL_TO_C_STRING (dllname_ext, dllname, Qbinary);
1957
1958 /* The exact name of the cygwin dll has changed with
1959 various releases, but hopefully this will be reasonably
1960 future proof. */
1961 if (qxestrncasecmp (dllname, (Intbyte *) "cygwin", 6) == 0)
1962 {
1963 *is_cygnus_app = TRUE;
1964 break;
1965 }
1966 }
1967 }
1968 #endif
1969 }
1970
1971 unwind:
1972 close_file_data (&executable);
1973 }
1974
1975 /* Close the system structures associated with the given file. */
1976 void
1977 close_file_data (file_data *p_file)
1978 {
1979 UnmapViewOfFile (p_file->file_base);
1980 CloseHandle (p_file->file_mapping);
1981 CloseHandle (p_file->file);
1982 }
1983
1984
1985 /* Some miscellaneous functions that are Windows specific, but not GUI
1986 specific (ie. are applicable in terminal or batch mode as well). */
1987
1988 DEFUN ("mswindows-short-file-name", Fmswindows_short_file_name, 1, 1, "", /*
1989 Return the short file name version (8.3) of the full path of FILENAME.
1990 If FILENAME does not exist, return nil.
1991 All path elements in FILENAME are converted to their short names.
1992 */
1993 (filename))
1994 {
1995 Extbyte shortname[MAX_PATH * MAX_XETCHAR_SIZE];
1996 Extbyte *fileext;
1997 Intbyte *shortint;
1998
1999 CHECK_STRING (filename);
2000
2001 /* first expand it. */
2002 filename = Fexpand_file_name (filename, Qnil);
2003
2004 LISP_STRING_TO_TSTR (filename, fileext);
2005 /* luckily, this returns the short version of each element in the path. */
2006 if (qxeGetShortPathName (fileext, shortname,
2007 sizeof (shortname) / XETCHAR_SIZE) == 0)
2008 return Qnil;
2009
2010 TSTR_TO_C_STRING (shortname, shortint);
2011 MSWINDOWS_NORMALIZE_FILENAME (shortint);
2012
2013 return build_string (shortint);
2014 }
2015
2016
2017 DEFUN ("mswindows-long-file-name", Fmswindows_long_file_name, 1, 1, "", /*
2018 Return the long file name version of the full path of FILENAME.
2019 If FILENAME does not exist, return nil.
2020 All path elements in FILENAME are converted to their long names.
2021 */
2022 (filename))
2023 {
2024 Intbyte *longname, *canon;
2025 Lisp_Object ret;
2026
2027 CHECK_STRING (filename);
2028
2029 /* first expand it. */
2030 filename = Fexpand_file_name (filename, Qnil);
2031
2032 if (!(longname = mswindows_get_long_filename (XSTRING_DATA (filename))))
2033 return Qnil;
2034
2035 canon = mswindows_canonicalize_filename (longname);
2036 ret = build_string (canon);
2037 xfree (canon);
2038 xfree (longname);
2039 return ret;
2040 }
2041
2042
2043 void
2044 init_nt (void)
1752 { 2045 {
1753 /* Initial preparation for subprocess support: replace our standard 2046 /* Initial preparation for subprocess support: replace our standard
1754 handles with non-inheritable versions. */ 2047 handles with non-inheritable versions.
2048
2049 #### Do we still need this? This is left over from the old process
2050 support. */
1755 { 2051 {
1756 HANDLE parent; 2052 HANDLE parent;
1757 HANDLE stdin_save = INVALID_HANDLE_VALUE; 2053 HANDLE stdin_save = INVALID_HANDLE_VALUE;
1758 HANDLE stdout_save = INVALID_HANDLE_VALUE; 2054 HANDLE stdout_save = INVALID_HANDLE_VALUE;
1759 HANDLE stderr_save = INVALID_HANDLE_VALUE; 2055 HANDLE stderr_save = INVALID_HANDLE_VALUE;
1831 /* Reset the volume info cache. */ 2127 /* Reset the volume info cache. */
1832 volume_cache = NULL; 2128 volume_cache = NULL;
1833 } 2129 }
1834 } 2130 }
1835 2131
1836
1837 /*--------------------------------------------------------------------*/
1838 /* Memory-mapped files */
1839 /*--------------------------------------------------------------------*/
1840
1841 int
1842 open_input_file (file_data *p_file, const Intbyte *filename)
1843 {
1844 /* Synched with FSF 20.6. We fixed some warnings. */
1845 HANDLE file;
1846 HANDLE file_mapping;
1847 void *file_base;
1848 DWORD size, upper_size;
1849 Extbyte *fileext;
1850
1851 C_STRING_TO_TSTR (filename, fileext);
1852
1853 file = qxeCreateFile (fileext, GENERIC_READ, FILE_SHARE_READ, NULL,
1854 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
1855 if (file == INVALID_HANDLE_VALUE)
1856 return FALSE;
1857
1858 size = GetFileSize (file, &upper_size);
1859 file_mapping = qxeCreateFileMapping (file, NULL, PAGE_READONLY,
1860 0, size, NULL);
1861 if (!file_mapping)
1862 return FALSE;
1863
1864 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size);
1865 if (file_base == 0)
1866 return FALSE;
1867
1868 p_file->name = filename;
1869 p_file->size = size;
1870 p_file->file = file;
1871 p_file->file_mapping = file_mapping;
1872 p_file->file_base = file_base;
1873
1874 return TRUE;
1875 }
1876
1877 int
1878 open_output_file (file_data *p_file, const Intbyte *filename,
1879 unsigned long size)
1880 {
1881 /* Synched with FSF 20.6. We fixed some warnings. */
1882 HANDLE file;
1883 HANDLE file_mapping;
1884 void *file_base;
1885 Extbyte *fileext;
1886
1887 C_STRING_TO_TSTR (filename, fileext);
1888
1889 file = qxeCreateFile (fileext, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1890 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
1891 if (file == INVALID_HANDLE_VALUE)
1892 return FALSE;
1893
1894 file_mapping = qxeCreateFileMapping (file, NULL, PAGE_READWRITE,
1895 0, size, NULL);
1896 if (!file_mapping)
1897 return FALSE;
1898
1899 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size);
1900 if (file_base == NULL)
1901 return FALSE;
1902
1903 p_file->name = filename;
1904 p_file->size = size;
1905 p_file->file = file;
1906 p_file->file_mapping = file_mapping;
1907 p_file->file_base = file_base;
1908
1909 return TRUE;
1910 }
1911
1912 #if 1 /* !defined(MINGW) */
1913 /* Return pointer to section header for section containing the given
1914 relative virtual address. */
1915 static IMAGE_SECTION_HEADER *
1916 rva_to_section (DWORD rva, IMAGE_NT_HEADERS *nt_header)
1917 {
1918 /* Synched with FSF 20.6. We added MINGW stuff. */
1919 PIMAGE_SECTION_HEADER section;
1920 int i;
1921
1922 section = IMAGE_FIRST_SECTION (nt_header);
1923
1924 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
1925 {
1926 /* Some linkers (eg. the NT SDK linker I believe) swapped the
1927 meaning of these two values - or rather, they ignored
1928 VirtualSize entirely and always set it to zero. This affects
1929 some very old exes (eg. gzip dated Dec 1993). Since
1930 mswindows_executable_type relies on this function to work reliably,
1931 we need to cope with this. */
1932 DWORD real_size = max (section->SizeOfRawData,
1933 section->Misc.VirtualSize);
1934 if (rva >= section->VirtualAddress
1935 && rva < section->VirtualAddress + real_size)
1936 return section;
1937 section++;
1938 }
1939 return NULL;
1940 }
1941 #endif
1942
1943 void
1944 mswindows_executable_type (const Intbyte *filename, int *is_dos_app,
1945 int *is_cygnus_app)
1946 {
1947 /* Synched with FSF 20.6. We added MINGW stuff and casts. */
1948 file_data executable;
1949 Intbyte *p;
1950
1951 /* Default values in case we can't tell for sure. */
1952 *is_dos_app = FALSE;
1953 *is_cygnus_app = FALSE;
1954
1955 if (!open_input_file (&executable, filename))
1956 return;
1957
1958 p = qxestrrchr (filename, '.');
1959
1960 /* We can only identify DOS .com programs from the extension. */
1961 if (p && qxestrcasecmp (p, ".com") == 0)
1962 *is_dos_app = TRUE;
1963 else if (p && (qxestrcasecmp (p, ".bat") == 0 ||
1964 qxestrcasecmp (p, ".cmd") == 0))
1965 {
1966 /* A DOS shell script - it appears that CreateProcess is happy to
1967 accept this (somewhat surprisingly); presumably it looks at
1968 COMSPEC to determine what executable to actually invoke.
1969 Therefore, we have to do the same here as well. */
1970 /* Actually, I think it uses the program association for that
1971 extension, which is defined in the registry. */
1972 p = egetenv ("COMSPEC");
1973 if (p)
1974 mswindows_executable_type (p, is_dos_app, is_cygnus_app);
1975 }
1976 else
1977 {
1978 /* Look for DOS .exe signature - if found, we must also check that
1979 it isn't really a 16- or 32-bit Windows exe, since both formats
1980 start with a DOS program stub. Note that 16-bit Windows
1981 executables use the OS/2 1.x format. */
1982
1983 #if 0 /* defined( MINGW ) */
1984 /* mingw doesn't have enough headers to detect cygwin
1985 apps, just do what we can. */
1986 FILHDR *exe_header;
1987
1988 exe_header = (FILHDR *) executable.file_base;
1989 if (exe_header->e_magic != DOSMAGIC)
1990 goto unwind;
1991
1992 if ((char *) exe_header->e_lfanew > (char *) executable.size)
1993 {
1994 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
1995 *is_dos_app = TRUE;
1996 }
1997 else if (exe_header->nt_signature != NT_SIGNATURE)
1998 {
1999 *is_dos_app = TRUE;
2000 }
2001 #else
2002 IMAGE_DOS_HEADER *dos_header;
2003 IMAGE_NT_HEADERS *nt_header;
2004
2005 dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
2006 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
2007 goto unwind;
2008
2009 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header +
2010 dos_header->e_lfanew);
2011
2012 if ((char *) nt_header > (char *) dos_header + executable.size)
2013 {
2014 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
2015 *is_dos_app = TRUE;
2016 }
2017 else if (nt_header->Signature != IMAGE_NT_SIGNATURE &&
2018 LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
2019 {
2020 *is_dos_app = TRUE;
2021 }
2022 else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
2023 {
2024 /* Look for cygwin.dll in DLL import list. */
2025 IMAGE_DATA_DIRECTORY import_dir =
2026 nt_header->OptionalHeader.
2027 DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
2028 IMAGE_IMPORT_DESCRIPTOR *imports;
2029 IMAGE_SECTION_HEADER *section;
2030
2031 section = rva_to_section (import_dir.VirtualAddress, nt_header);
2032 imports =
2033 (IMAGE_IMPORT_DESCRIPTOR *) RVA_TO_PTR (import_dir.VirtualAddress,
2034 section, executable);
2035
2036 for ( ; imports->Name; imports++)
2037 {
2038 Extbyte *dllname_ext =
2039 (Extbyte *) RVA_TO_PTR (imports->Name, section, executable);
2040 Intbyte *dllname;
2041
2042 EXTERNAL_TO_C_STRING (dllname_ext, dllname, Qbinary);
2043
2044 /* The exact name of the cygwin dll has changed with
2045 various releases, but hopefully this will be reasonably
2046 future proof. */
2047 if (qxestrncasecmp (dllname, (Intbyte *) "cygwin", 6) == 0)
2048 {
2049 *is_cygnus_app = TRUE;
2050 break;
2051 }
2052 }
2053 }
2054 #endif
2055 }
2056
2057 unwind:
2058 close_file_data (&executable);
2059 }
2060
2061 /* Close the system structures associated with the given file. */
2062 void
2063 close_file_data (file_data *p_file)
2064 {
2065 UnmapViewOfFile (p_file->file_base);
2066 CloseHandle (p_file->file_mapping);
2067 CloseHandle (p_file->file);
2068 }
2069
2070
2071 /* Some miscellaneous functions that are Windows specific, but not GUI
2072 specific (ie. are applicable in terminal or batch mode as well). */
2073
2074 DEFUN ("mswindows-short-file-name", Fmswindows_short_file_name, 1, 1, "", /*
2075 Return the short file name version (8.3) of the full path of FILENAME.
2076 If FILENAME does not exist, return nil.
2077 All path elements in FILENAME are converted to their short names.
2078 */
2079 (filename))
2080 {
2081 Extbyte shortname[MAX_PATH * MAX_XETCHAR_SIZE];
2082 Extbyte *fileext;
2083 Intbyte *shortint;
2084
2085 CHECK_STRING (filename);
2086
2087 /* first expand it. */
2088 filename = Fexpand_file_name (filename, Qnil);
2089
2090 LISP_STRING_TO_TSTR (filename, fileext);
2091 /* luckily, this returns the short version of each element in the path. */
2092 if (qxeGetShortPathName (fileext, shortname,
2093 sizeof (shortname) / XETCHAR_SIZE) == 0)
2094 return Qnil;
2095
2096 TSTR_TO_C_STRING (shortname, shortint);
2097 MSWINDOWS_NORMALIZE_FILENAME (shortint);
2098
2099 return build_string (shortint);
2100 }
2101
2102
2103 DEFUN ("mswindows-long-file-name", Fmswindows_long_file_name, 1, 1, "", /*
2104 Return the long file name version of the full path of FILENAME.
2105 If FILENAME does not exist, return nil.
2106 All path elements in FILENAME are converted to their long names.
2107 */
2108 (filename))
2109 {
2110 Intbyte *longname, *canon;
2111 Lisp_Object ret;
2112
2113 CHECK_STRING (filename);
2114
2115 /* first expand it. */
2116 filename = Fexpand_file_name (filename, Qnil);
2117
2118 if (!(longname = mswindows_get_long_filename (XSTRING_DATA (filename))))
2119 return Qnil;
2120
2121 canon = mswindows_canonicalize_filename (longname);
2122 ret = build_string (canon);
2123 xfree (canon);
2124 xfree (longname);
2125 return ret;
2126 }
2127
2128 void 2132 void
2129 syms_of_nt (void) 2133 syms_of_nt (void)
2130 { 2134 {
2131 DEFSUBR (Fmswindows_short_file_name); 2135 DEFSUBR (Fmswindows_short_file_name);
2132 DEFSUBR (Fmswindows_long_file_name); 2136 DEFSUBR (Fmswindows_long_file_name);