Mon Jun 20 14:26:41 1994 Bob Amstadt (bob@pooh) * [objects/bitmap.c] Allow negative bitmap sizes. Sun Jun 19 12:00:04 1994 David Metcalfe <david@prism.demon.co.uk> * [controls/edit.c] Improved selection display. Added processing for WM_SETFONT, EM_REPLACESEL, EM_LINELENGTH, EM_UNDO, EM_EMPTYUNDOBUFFER, EM_GETHANDLE, EM_SETHANDLE messages. Text buffer now stored on application's local heap. * [windows/graphics.c] Corrected bug in Rectangle(). XFillRectangle has the same width as Rectangle, but XDrawRectangle is one pixel wider for the same co-ordinates. * [memory/heap.c] [include/heap.h] Added HEAP_LocalSize function. * [windows/event.c] [windows/keyboard.c] Improvements to KeyStateTable and addition of AsyncKeyStateTable. Added supporting code to GetKeyState and GetAsyncKeyState and merged mouse button states into GetKeyboardState. * [loader/resource.c] [include/accel.h] Added recognition of SHIFT, CONTROL and ALT keys to TranslateAccelerator. * [objects/metafile.c] [objects/font.c] [objects/bitblt.c] A bit more metafile support. Sun Jun 19 17:29:00 MET DST 1994 Erik Bos (erik@hacktic.nl) * [loader/resource.c] SizeofResource() and AllocResource() added, AccessResource() updated. * [if1632/kernel.spec] FreeLibrary() used for FreeModule(). * [windows/graphics.c] Rectangle(): swap left & right corners when right < left, swap top & bottom when botton < top. Jun 19, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/combo.c] Fix bug in window style of the associated listbox. * [controls/menu.c] Skip separators in keyboard navigation by using new internal functions SelectPrevItem() & SelectNextItem(), * [misc/profile.c] Bug fix in GetPrivateProfileInt(), was limited to 4 digit, IntBuf must be alloc to (5+1)=6. char instead of 5. * [misc/main.c] Put code in functions SetEnvironment() & GetEnvironment(). * [misc/shell.c] Start putting some code in ExtractIcon() function. * [misc/mmsystem.c] Some code for MMTimer functions & timers list. * [miscemu/int31.c] Few stubs for DPMI interrupt calls. Nothing work yet. Mon Jun 20 07:37:43 EDT 1994 John Richardson (jrichard@cs.uml.edu) * include/win.h (tagWND): Added icon fields icon, hIcon and rectClientSave to the tagWND struct. * windows/Imakefile Added icon.c to the list of files to compile * windows/dce.c (GetDCEx): Added some checks for iconic mode and pass icon window as drawable, not the real window. * windows/defwnd.c (DefWindowProc) Added PAINTICON default windows procedure. * windows/event.c (EVENT_Expose) Added check for iconic window expose. If iconic window is exposed send a WM_PAINTICON message * windows/icon.c New file. ICON_Iconify, ICON_findIconFromPoint, ICON_Deiconify. * windows/mdi.c (DefMDIChildProc) Test for IsIconic during a SC_RESTORE, this doesn't work yet. * windows/message.c (hardware_event) Looks for icon as well as window now. * windows/nonclient.c (NC_HandleSysCommand, NC_DoNCPaintIcon) Added iconify/deiconify in NC_HandleSysCommand, new function NC_DoNCPaintIcon which paints an icon. * windows/painting.c (BeginPaint) Made a BeginPaint select the STOCK_BLACK_PEN, STOCK_WHITE_BRUSH, and STOCK_SYSTEM_FONT objects since this is (hopefully) default windows behavior. * windows/win.h (CreateWindowEx) Set the default background color of a window to be white. Create icon window, turn off MINIMIZE if it is on, since I don't know what to do with it as of yet... register the icon with the hwnd of its window so we can identify where icon messages are coming from. Mon Jun 20 10:15:59 1994 Miguel de Icaza (miguel@sphinx) * windows/event.c: Added a hack to define XPointer when using X11R4. * toolkit/hello.c: Test application for WineLib. To compile you'll need: gcc -Iinclude -DWINELIB -g hello.c -c, and to link you'll need: gcc hello.o libwine.a -lX11 -L/usr/openwin/lib -lm * toolkit/heap.c: Extended the size of the block size per chunk. * misc/stress.c (GetFreeFileHandles): Fixed typo. * misc/main.c (main): Changes to allow compilation under SunOS. * loader/library.c: Changed some ifdefs to compile WineLib.
399 lines
9.1 KiB
C
399 lines
9.1 KiB
C
static char RCSId[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
|
||
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <sys/types.h>
|
||
#include <sys/stat.h>
|
||
#include <fcntl.h>
|
||
#include <unistd.h>
|
||
#include <string.h>
|
||
#include <errno.h>
|
||
#ifdef linux
|
||
#include <linux/unistd.h>
|
||
#include <linux/head.h>
|
||
#include <linux/ldt.h>
|
||
#include <linux/segment.h>
|
||
#endif
|
||
#include "neexe.h"
|
||
#include "segmem.h"
|
||
#include "prototypes.h"
|
||
#include "dlls.h"
|
||
#include "wine.h"
|
||
#include "windows.h"
|
||
#include "wineopts.h"
|
||
#include "arch.h"
|
||
#include "options.h"
|
||
|
||
/* #define DEBUG_FIXUP */
|
||
|
||
extern HANDLE CreateNewTask(HINSTANCE hInst);
|
||
extern int CallToInit16(unsigned long csip, unsigned long sssp,
|
||
unsigned short ds);
|
||
extern void CallTo32();
|
||
|
||
char *GetDosFileName(char *unixfilename);
|
||
char *GetModuleName(struct w_files * wpnt, int index, char *buffer);
|
||
extern unsigned char ran_out;
|
||
extern char WindowsPath[256];
|
||
char *WIN_ProgramName;
|
||
|
||
unsigned short WIN_StackSize;
|
||
unsigned short WIN_HeapSize;
|
||
|
||
struct w_files * wine_files = NULL;
|
||
|
||
char **Argv;
|
||
int Argc;
|
||
HINSTANCE hSysRes;
|
||
|
||
static char *DLL_Extensions[] = { "dll", NULL };
|
||
static char *EXE_Extensions[] = { "exe", NULL };
|
||
|
||
/**********************************************************************
|
||
* myerror
|
||
*/
|
||
void
|
||
myerror(const char *s)
|
||
{
|
||
if (s == NULL)
|
||
perror("wine");
|
||
else
|
||
fprintf(stderr, "wine: %s\n", s);
|
||
|
||
exit(1);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* GetFilenameFromInstance
|
||
*/
|
||
char *
|
||
GetFilenameFromInstance(unsigned short instance)
|
||
{
|
||
register struct w_files *w = wine_files;
|
||
|
||
while (w && w->hinstance != instance)
|
||
w = w->next;
|
||
|
||
if (w)
|
||
return w->filename;
|
||
else
|
||
return NULL;
|
||
}
|
||
|
||
struct w_files *
|
||
GetFileInfo(unsigned short instance)
|
||
{
|
||
register struct w_files *w = wine_files;
|
||
|
||
while (w && w->hinstance != instance)
|
||
w = w->next;
|
||
|
||
return w;
|
||
}
|
||
|
||
#ifndef WINELIB
|
||
/**********************************************************************
|
||
*
|
||
* Load MZ Header
|
||
*/
|
||
void load_mz_header(int fd, struct mz_header_s *mz_header)
|
||
{
|
||
if (read(fd, mz_header, sizeof(struct mz_header_s)) !=
|
||
sizeof(struct mz_header_s))
|
||
{
|
||
myerror("Unable to read MZ header from file");
|
||
}
|
||
}
|
||
#endif
|
||
|
||
int IsDLLLoaded(char *name)
|
||
{
|
||
struct w_files *wpnt;
|
||
|
||
if(FindDLLTable(name))
|
||
return 1;
|
||
|
||
for(wpnt = wine_files; wpnt; wpnt = wpnt->next)
|
||
if(strcmp(wpnt->name, name) == 0)
|
||
return 1;
|
||
|
||
return 0;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* LoadImage
|
||
* Load one executable into memory
|
||
*/
|
||
HINSTANCE LoadImage(char *module, int filetype, int change_dir)
|
||
{
|
||
unsigned int read_size;
|
||
int i;
|
||
struct w_files * wpnt, *wpnt1;
|
||
unsigned int status;
|
||
char buffer[256], header[2], modulename[64], *fullname;
|
||
|
||
ExtractDLLName(module, modulename);
|
||
printf("%sLoadImage \n", module);
|
||
/* built-in one ? */
|
||
if (FindDLLTable(modulename)) {
|
||
return GetModuleHandle(modulename);
|
||
}
|
||
|
||
/* already loaded ? */
|
||
for (wpnt = wine_files ; wpnt ; wpnt = wpnt->next)
|
||
if (strcasecmp(wpnt->name, modulename) == 0)
|
||
return wpnt->hinstance;
|
||
|
||
/*
|
||
* search file
|
||
*/
|
||
fullname = FindFile(buffer, sizeof(buffer), module,
|
||
(filetype == EXE ? EXE_Extensions : DLL_Extensions),
|
||
WindowsPath);
|
||
if (fullname == NULL)
|
||
{
|
||
fprintf(stderr, "LoadImage: I can't find %s.dll | %s.exe !\n",
|
||
module, module);
|
||
return 2;
|
||
}
|
||
|
||
fullname = GetDosFileName(fullname);
|
||
WIN_ProgramName = strdup(fullname);
|
||
|
||
fprintf(stderr,"LoadImage: loading %s (%s)\n [%s]\n",
|
||
module, buffer, WIN_ProgramName);
|
||
|
||
if (change_dir && fullname)
|
||
{
|
||
char dirname[256];
|
||
char *p;
|
||
|
||
strcpy(dirname, fullname);
|
||
p = strrchr(dirname, '\\');
|
||
*p = '\0';
|
||
|
||
DOS_SetDefaultDrive(dirname[0] - 'A');
|
||
DOS_ChangeDir(dirname[0] - 'A', dirname + 2);
|
||
}
|
||
|
||
/* First allocate a spot to store the info we collect, and add it to
|
||
* our linked list.
|
||
*/
|
||
|
||
wpnt = (struct w_files *) malloc(sizeof(struct w_files));
|
||
if(wine_files == NULL)
|
||
wine_files = wpnt;
|
||
else {
|
||
wpnt1 = wine_files;
|
||
while(wpnt1->next) wpnt1 = wpnt1->next;
|
||
wpnt1->next = wpnt;
|
||
};
|
||
wpnt->next = NULL;
|
||
wpnt->resnamtab = (RESNAMTAB *) -1;
|
||
|
||
/*
|
||
* Open file for reading.
|
||
*/
|
||
wpnt->fd = open(buffer, O_RDONLY);
|
||
if (wpnt->fd < 0)
|
||
return 2;
|
||
|
||
/*
|
||
* Establish header pointers.
|
||
*/
|
||
wpnt->filename = strdup(buffer);
|
||
wpnt->name = strdup(modulename);
|
||
|
||
/* if(module) {
|
||
wpnt->name = strdup(module);
|
||
ToDos(wpnt->name);
|
||
}*/
|
||
|
||
/* read mz header */
|
||
wpnt->mz_header = (struct mz_header_s *) malloc(sizeof(struct mz_header_s));;
|
||
status = lseek(wpnt->fd, 0, SEEK_SET);
|
||
load_mz_header (wpnt->fd, wpnt->mz_header);
|
||
if (wpnt->mz_header->must_be_0x40 != 0x40 &&
|
||
wpnt->mz_header->must_be_0x40 != 0x1e)
|
||
myerror("This is not a Windows program");
|
||
|
||
/* read first two bytes to determine filetype */
|
||
status = lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
|
||
read(wpnt->fd, &header, sizeof(header));
|
||
|
||
if (header[0] == 'N' && header[1] == 'E')
|
||
return (LoadNEImage(wpnt));
|
||
|
||
if (header[0] == 'P' && header[1] == 'E') {
|
||
printf("win32 applications are not supported");
|
||
return 14;
|
||
}
|
||
|
||
fprintf(stderr, "wine: (%s) unknown fileformat !\n", wpnt->filename);
|
||
|
||
return 14;
|
||
}
|
||
|
||
#ifndef WINELIB
|
||
/**********************************************************************
|
||
* main
|
||
*/
|
||
int _WinMain(int argc, char **argv)
|
||
{
|
||
int segment;
|
||
char *p;
|
||
char *sysresname;
|
||
char filename[256];
|
||
HANDLE hTaskMain;
|
||
HINSTANCE hInstMain;
|
||
#ifdef WINESTAT
|
||
char * cp;
|
||
#endif
|
||
struct w_files * wpnt;
|
||
int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg;
|
||
int rv;
|
||
|
||
Argc = argc - 1;
|
||
Argv = argv + 1;
|
||
|
||
if (strchr(Argv[0], '\\') || strchr(Argv[0],'/')) {
|
||
for (p = Argv[0] + strlen(Argv[0]); *p != '\\' && *p !='/'; p--)
|
||
/* NOTHING */;
|
||
|
||
strncpy(filename, Argv[0], p - Argv[0]);
|
||
filename[p - Argv[0]] = '\0';
|
||
strcat(WindowsPath, ";");
|
||
strcat(WindowsPath, filename);
|
||
}
|
||
|
||
if ((hInstMain = LoadImage(Argv[0], EXE, 1)) < 32) {
|
||
fprintf(stderr, "wine: can't load %s!.\n", Argv[0]);
|
||
exit(1);
|
||
}
|
||
hTaskMain = CreateNewTask(hInstMain);
|
||
printf("_WinMain // hTaskMain=%04X hInstMain=%04X !\n", hTaskMain, hInstMain);
|
||
|
||
GetPrivateProfileString("wine", "SystemResources", "sysres.dll",
|
||
filename, sizeof(filename), WINE_INI);
|
||
|
||
hSysRes = LoadImage(filename, DLL, 0);
|
||
if (hSysRes < 32) {
|
||
fprintf(stderr, "wine: can't load %s!.\n", filename);
|
||
exit(1);
|
||
} else
|
||
printf("System Resources Loaded // hSysRes='%04X'\n", hSysRes);
|
||
|
||
/*
|
||
* Fixup references.
|
||
*/
|
||
/* wpnt = wine_files;
|
||
for(wpnt = wine_files; wpnt; wpnt = wpnt->next)
|
||
for (segment = 0; segment < wpnt->ne_header->n_segment_tab; segment++)
|
||
if (FixupSegment(wpnt, segment) < 0)
|
||
myerror("fixup failed.");
|
||
*/
|
||
|
||
#ifdef WINESTAT
|
||
cp = strrchr(argv[0], '/');
|
||
if(!cp) cp = argv[0];
|
||
else cp++;
|
||
if(strcmp(cp,"winestat") == 0) {
|
||
winestat();
|
||
exit(0);
|
||
};
|
||
#endif
|
||
|
||
/*
|
||
* Initialize signal handling.
|
||
*/
|
||
init_wine_signals();
|
||
|
||
/*
|
||
* Fixup stack and jump to start.
|
||
*/
|
||
WIN_StackSize = wine_files->ne_header->stack_length;
|
||
WIN_HeapSize = wine_files->ne_header->local_heap_length;
|
||
|
||
ds_reg = (wine_files->
|
||
selector_table[wine_files->ne_header->auto_data_seg-1].selector);
|
||
cs_reg = wine_files->selector_table[wine_files->ne_header->cs-1].selector;
|
||
ip_reg = wine_files->ne_header->ip;
|
||
ss_reg = wine_files->selector_table[wine_files->ne_header->ss-1].selector;
|
||
sp_reg = wine_files->ne_header->sp;
|
||
|
||
if (Options.debug) wine_debug(0, NULL);
|
||
|
||
rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg);
|
||
printf ("rv = %x\n", rv);
|
||
}
|
||
|
||
void InitDLL(struct w_files *wpnt)
|
||
{
|
||
int cs_reg, ds_reg, ip_reg, rv;
|
||
/*
|
||
* Is this a library?
|
||
*/
|
||
if (wpnt->ne_header->format_flags & 0x8000)
|
||
{
|
||
if (!(wpnt->ne_header->format_flags & 0x0001))
|
||
{
|
||
/* Not SINGLEDATA */
|
||
fprintf(stderr, "Library is not marked SINGLEDATA\n");
|
||
exit(1);
|
||
}
|
||
|
||
ds_reg = wpnt->selector_table[wpnt->
|
||
ne_header->auto_data_seg-1].selector;
|
||
cs_reg = wpnt->selector_table[wpnt->ne_header->cs-1].selector;
|
||
ip_reg = wpnt->ne_header->ip;
|
||
|
||
if (cs_reg) {
|
||
fprintf(stderr, "Initializing %s, cs:ip %04x:%04x, ds %04x\n",
|
||
wpnt->name, cs_reg, ip_reg, ds_reg);
|
||
|
||
rv = CallTo16(cs_reg << 16 | ip_reg, ds_reg);
|
||
printf ("rv = %x\n", rv);
|
||
} else
|
||
printf("%s skipped\n");
|
||
}
|
||
}
|
||
|
||
void InitializeLoadedDLLs(struct w_files *wpnt)
|
||
{
|
||
static flagReadyToRun = 0;
|
||
struct w_files *final_wpnt;
|
||
|
||
printf("InitializeLoadedDLLs %08X\n", wpnt);
|
||
|
||
if (wpnt == NULL)
|
||
{
|
||
flagReadyToRun = 1;
|
||
fprintf(stderr, "Initializing DLLs\n");
|
||
}
|
||
|
||
if (!flagReadyToRun)
|
||
return;
|
||
|
||
#if 1
|
||
if (wpnt != NULL)
|
||
fprintf(stderr, "Initializing %s\n", wpnt->name);
|
||
#endif
|
||
|
||
/*
|
||
* Initialize libraries
|
||
*/
|
||
if (!wpnt)
|
||
{
|
||
wpnt = wine_files;
|
||
final_wpnt = NULL;
|
||
}
|
||
else
|
||
{
|
||
final_wpnt = wpnt->next;
|
||
}
|
||
|
||
for( ; wpnt != final_wpnt; wpnt = wpnt->next)
|
||
InitDLL(wpnt);
|
||
}
|
||
#endif /* #ifndef WINELIB */
|