comparison src/nt.c @ 408:501cfd01ee6d r21-2-34

Import from CVS: tag r21-2-34
author cvs
date Mon, 13 Aug 2007 11:18:11 +0200
parents 2f8bb876ab1d
children de805c49cfc1
comparison
equal deleted inserted replaced
407:ed6218a7d4d3 408:501cfd01ee6d
45 #include <signal.h> 45 #include <signal.h>
46 #include <string.h> 46 #include <string.h>
47 #include <stdlib.h> 47 #include <stdlib.h>
48 #include <stdio.h> 48 #include <stdio.h>
49 49
50 #include <windows.h> 50 #include "syswindows.h"
51 #include <mmsystem.h>
52 51
53 #include "nt.h" 52 #include "nt.h"
54 #include <sys/dir.h> 53 #include <sys/dir.h>
55 #include "ntheap.h" 54 #include "ntheap.h"
56 55
2002 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF); 2001 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF);
2003 else 2002 else
2004 return errno = EINVAL; 2003 return errno = EINVAL;
2005 } 2004 }
2006 2005
2006
2007 /*--------------------------------------------------------------------*/
2008 /* Memory-mapped files */
2009 /*--------------------------------------------------------------------*/
2010
2007 int 2011 int
2008 open_input_file (file_data *p_file, const char *filename) 2012 open_input_file (file_data *p_file, const char *filename)
2009 { 2013 {
2014 /* Synched with FSF 20.6. We fixed some warnings. */
2010 HANDLE file; 2015 HANDLE file;
2011 HANDLE file_mapping; 2016 HANDLE file_mapping;
2012 void *file_base; 2017 void *file_base;
2013 DWORD size, upper_size; 2018 DWORD size, upper_size;
2014 2019
2032 p_file->file = file; 2037 p_file->file = file;
2033 p_file->file_mapping = file_mapping; 2038 p_file->file_mapping = file_mapping;
2034 p_file->file_base = (char *)file_base; 2039 p_file->file_base = (char *)file_base;
2035 2040
2036 return TRUE; 2041 return TRUE;
2042 }
2043
2044 int
2045 open_output_file (file_data *p_file, const char *filename, unsigned long size)
2046 {
2047 /* Synched with FSF 20.6. We fixed some warnings. */
2048 HANDLE file;
2049 HANDLE file_mapping;
2050 void *file_base;
2051
2052 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2053 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
2054 if (file == INVALID_HANDLE_VALUE)
2055 return FALSE;
2056
2057 file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE,
2058 0, size, NULL);
2059 if (!file_mapping)
2060 return FALSE;
2061
2062 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size);
2063 if (file_base == NULL)
2064 return FALSE;
2065
2066 p_file->name = filename;
2067 p_file->size = size;
2068 p_file->file = file;
2069 p_file->file_mapping = file_mapping;
2070 p_file->file_base = (char*) file_base;
2071
2072 return TRUE;
2073 }
2074
2075 #if 1 /* !defined(__MINGW32__) */
2076 /* Return pointer to section header for section containing the given
2077 relative virtual address. */
2078 static IMAGE_SECTION_HEADER *
2079 rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header)
2080 {
2081 /* Synched with FSF 20.6. We added MINGW32 stuff. */
2082 PIMAGE_SECTION_HEADER section;
2083 int i;
2084
2085 section = IMAGE_FIRST_SECTION (nt_header);
2086
2087 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
2088 {
2089 /* Some linkers (eg. the NT SDK linker I believe) swapped the
2090 meaning of these two values - or rather, they ignored
2091 VirtualSize entirely and always set it to zero. This affects
2092 some very old exes (eg. gzip dated Dec 1993). Since
2093 mswindows_executable_type relies on this function to work reliably,
2094 we need to cope with this. */
2095 DWORD real_size = max (section->SizeOfRawData,
2096 section->Misc.VirtualSize);
2097 if (rva >= section->VirtualAddress
2098 && rva < section->VirtualAddress + real_size)
2099 return section;
2100 section++;
2101 }
2102 return NULL;
2103 }
2104 #endif
2105
2106 void
2107 mswindows_executable_type (const char * filename, int * is_dos_app,
2108 int * is_cygnus_app)
2109 {
2110 /* Synched with FSF 20.6. We added MINGW32 stuff and casts. */
2111 file_data executable;
2112 char * p;
2113
2114 /* Default values in case we can't tell for sure. */
2115 *is_dos_app = FALSE;
2116 *is_cygnus_app = FALSE;
2117
2118 if (!open_input_file (&executable, filename))
2119 return;
2120
2121 p = strrchr (filename, '.');
2122
2123 /* We can only identify DOS .com programs from the extension. */
2124 if (p && stricmp (p, ".com") == 0)
2125 *is_dos_app = TRUE;
2126 else if (p && (stricmp (p, ".bat") == 0 ||
2127 stricmp (p, ".cmd") == 0))
2128 {
2129 /* A DOS shell script - it appears that CreateProcess is happy to
2130 accept this (somewhat surprisingly); presumably it looks at
2131 COMSPEC to determine what executable to actually invoke.
2132 Therefore, we have to do the same here as well. */
2133 /* Actually, I think it uses the program association for that
2134 extension, which is defined in the registry. */
2135 p = egetenv ("COMSPEC");
2136 if (p)
2137 mswindows_executable_type (p, is_dos_app, is_cygnus_app);
2138 }
2139 else
2140 {
2141 /* Look for DOS .exe signature - if found, we must also check that
2142 it isn't really a 16- or 32-bit Windows exe, since both formats
2143 start with a DOS program stub. Note that 16-bit Windows
2144 executables use the OS/2 1.x format. */
2145
2146 #if 0 /* defined( __MINGW32__ ) */
2147 /* mingw32 doesn't have enough headers to detect cygwin
2148 apps, just do what we can. */
2149 FILHDR * exe_header;
2150
2151 exe_header = (FILHDR*) executable.file_base;
2152 if (exe_header->e_magic != DOSMAGIC)
2153 goto unwind;
2154
2155 if ((char*) exe_header->e_lfanew > (char*) executable.size)
2156 {
2157 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
2158 *is_dos_app = TRUE;
2159 }
2160 else if (exe_header->nt_signature != NT_SIGNATURE)
2161 {
2162 *is_dos_app = TRUE;
2163 }
2164 #else
2165 IMAGE_DOS_HEADER * dos_header;
2166 IMAGE_NT_HEADERS * nt_header;
2167
2168 dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
2169 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
2170 goto unwind;
2171
2172 nt_header = (PIMAGE_NT_HEADERS) ((char*) dos_header + dos_header->e_lfanew);
2173
2174 if ((char*) nt_header > (char*) dos_header + executable.size)
2175 {
2176 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
2177 *is_dos_app = TRUE;
2178 }
2179 else if (nt_header->Signature != IMAGE_NT_SIGNATURE &&
2180 LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
2181 {
2182 *is_dos_app = TRUE;
2183 }
2184 else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
2185 {
2186 /* Look for cygwin.dll in DLL import list. */
2187 IMAGE_DATA_DIRECTORY import_dir =
2188 nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
2189 IMAGE_IMPORT_DESCRIPTOR * imports;
2190 IMAGE_SECTION_HEADER * section;
2191
2192 section = rva_to_section (import_dir.VirtualAddress, nt_header);
2193 imports = (IMAGE_IMPORT_DESCRIPTOR *) RVA_TO_PTR (import_dir.VirtualAddress,
2194 section, executable);
2195
2196 for ( ; imports->Name; imports++)
2197 {
2198 char *dllname = (char*) RVA_TO_PTR (imports->Name, section, executable);
2199
2200 /* The exact name of the cygwin dll has changed with
2201 various releases, but hopefully this will be reasonably
2202 future proof. */
2203 if (strncmp (dllname, "cygwin", 6) == 0)
2204 {
2205 *is_cygnus_app = TRUE;
2206 break;
2207 }
2208 }
2209 }
2210 #endif
2211 }
2212
2213 unwind:
2214 close_file_data (&executable);
2037 } 2215 }
2038 2216
2039 /* Close the system structures associated with the given file. */ 2217 /* Close the system structures associated with the given file. */
2040 void 2218 void
2041 close_file_data (file_data *p_file) 2219 close_file_data (file_data *p_file)