1/*$Header: /p/tcsh/cvsroot/tcsh/win32/globals.c,v 1.11 2008/09/10 20:34:21 amold Exp $*/ 2/*- 3 * Copyright (c) 1980, 1991 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the University nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30/* 31 * globals.c: The mem locations needed in the child are copied here. 32 * -amol 33 */ 34#define WIN32_LEAN_AND_MEAN 35#include <windows.h> 36#include <stdlib.h> 37#include <stdio.h> 38#define STRSAFE_LIB 39#define STRSAFE_NO_CCH_FUNCTIONS 40#include <strsafe.h> 41 42extern unsigned long bookend1,bookend2; 43extern char **environ; 44 45#define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224 46#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240 47 48#ifdef _WIN64 49#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 50#else 51#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 52#endif 53 54 55#undef dprintf 56void 57dprintf(char *format, ...) 58{ /* } */ 59 va_list vl; 60 char putbuf[2048]; 61 DWORD err; 62 63 err = GetLastError(); 64 { 65 va_start(vl, format); 66#pragma warning(disable:4995) 67 wvsprintf(putbuf,format, vl); 68#pragma warning(default:4995) 69 va_end(vl); 70 OutputDebugString(putbuf); 71 } 72 SetLastError(err); 73} 74/* 75 * This function is called by fork(). The process must copy 76 * whatever memory is needed in the child. hproc is a handle 77 * to the child process 78 * 79 */ 80int fork_copy_user_mem(HANDLE hproc) { 81 82 SIZE_T bytes,rc; 83 SIZE_T size; 84 void *low = &bookend1, *high= &bookend2; 85 86 if(&bookend1 > &bookend2) { 87 low = &bookend2; 88 high = &bookend1; 89 } 90 91 size =(char*)high - (char*)low; 92 93 94 rc =WriteProcessMemory(hproc,low,low, (DWORD)size, &bytes); 95 96 if (!rc) { 97 rc = GetLastError(); 98 return -1; 99 } 100 if (size != bytes) { 101 //dprintf("size %d , wrote %d\n",size,bytes); 102 } 103 return 0; 104} 105/* 106 * Inspired by Microsoft KB article ID: Q90493 107 * 108 * returns 0 (false) if app is non-gui, 1 otherwise. 109*/ 110#include <winnt.h> 111#include <ntport.h> 112 113__inline BOOL wait_for_io(HANDLE hi, OVERLAPPED *pO) { 114 115 DWORD bytes = 0; 116 if(GetLastError() != ERROR_IO_PENDING) 117 { 118 return FALSE; 119 } 120 121 return GetOverlappedResult(hi,pO,&bytes,TRUE); 122} 123#define CHECK_IO(h,o) if(!wait_for_io(h,o)) {goto done;} 124 125int is_gui(char *exename) { 126 127 HANDLE hImage; 128 129 DWORD bytes; 130 OVERLAPPED overlap; 131 132 ULONG ntSignature; 133 134 struct DosHeader{ 135 IMAGE_DOS_HEADER doshdr; 136 DWORD extra[16]; 137 }; 138 139 struct DosHeader dh; 140 IMAGE_OPTIONAL_HEADER optionalhdr; 141 142 int retCode = 0; 143 144 memset(&overlap,0,sizeof(overlap)); 145 146 147 hImage = CreateFile(exename, GENERIC_READ, FILE_SHARE_READ, NULL, 148 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_OVERLAPPED, NULL); 149 if (INVALID_HANDLE_VALUE == hImage) { 150 return 0; 151 } 152 153 ReadFile(hImage, &dh, sizeof(struct DosHeader), &bytes,&overlap); 154 CHECK_IO(hImage,&overlap); 155 156 157 if (IMAGE_DOS_SIGNATURE != dh.doshdr.e_magic) { 158 goto done; 159 } 160 161 // read from the coffheaderoffset; 162 overlap.Offset = dh.doshdr.e_lfanew; 163 164 ReadFile(hImage, &ntSignature, sizeof(ULONG), &bytes,&overlap); 165 CHECK_IO(hImage,&overlap); 166 167 if (IMAGE_NT_SIGNATURE != ntSignature) { 168 goto done; 169 } 170 overlap.Offset = dh.doshdr.e_lfanew + sizeof(ULONG) + 171 sizeof(IMAGE_FILE_HEADER); 172 173 ReadFile(hImage, &optionalhdr,IMAGE_SIZEOF_NT_OPTIONAL_HEADER, &bytes,&overlap); 174 CHECK_IO(hImage,&overlap); 175 176 if (optionalhdr.Subsystem ==IMAGE_SUBSYSTEM_WINDOWS_GUI) 177 retCode = 1; 178done: 179 CloseHandle(hImage); 180 return retCode; 181} 182int is_9x_gui(char *prog) { 183 184 char *progpath; 185 DWORD dwret; 186 char *pathbuf; 187 char *pext; 188 189 pathbuf=heap_alloc(MAX_PATH+1); 190 if(!pathbuf) 191 return 0; 192 193 progpath=heap_alloc((MAX_PATH<<1)+1); 194 if(!progpath) 195 return 0; 196 197 if (GetEnvironmentVariable("PATH",pathbuf,MAX_PATH) ==0) { 198 goto failed; 199 } 200 201 pathbuf[MAX_PATH]=0; 202 203 dwret = SearchPath(pathbuf,prog,".EXE",MAX_PATH<<1,progpath,&pext); 204 205 if ( (dwret == 0) || (dwret > (MAX_PATH<<1) ) ) 206 goto failed; 207 208 dprintf("progpath is %s\n",progpath); 209 dwret = is_gui(progpath); 210 211 heap_free(pathbuf); 212 heap_free(progpath); 213 214 return dwret; 215 216failed: 217 heap_free(pathbuf); 218 heap_free(progpath); 219 return 0; 220 221 222} 223