mirror of
https://github.com/reactos/wine.git
synced 2024-12-13 22:58:37 +00:00
490a27e012
Tue Jun 7 08:41:27 1994 Bob Amstadt (bob@pooh) * loader/selector.c (FixupFunctionPrologs): New function to fixup loaded DLL function prologs. It replaces the do nothing code with code that loads DS with the appropriate data segment for the DLL. * misc/cursor.c (LoadCursor): Disabled cursor loading from .EXE or .DLL. The code needs to handle the possibility of multiple cursors in a single directory. Also, it should check to see if the cursor is the right size. * objects/font.c (EnumFonts): Checked for lpLogFontList[i] == NULL * objects/gdiobj.c (SetObjectOwner): Removed stub. Replaced with simple return in gdi.spec. This function is not defined for the retail version of Windows. * memory/heap.c (WIN16_LocalHandleDelta): New function. This is really a dummy that imitates the proper return values. * loader/library.c (GetProcAddress): Fixed definition of IS_BUILTIN_DLL() macro. Mon Jun 6 18:15:40 1994 Bob Amstadt (bob@pooh) * miscemu/int21.c (SeekFile): Needed to return current position in DX:AX. * windows/utility.c (windows_wsprintf): Added support for '#' in format, and fixed bug with "ptr" being incremented too many times. * miscemu/int21.c (OpenExistingFile): Add code to handle opening files read-only and write-only. * loader/wine.c: Segment fixups now done in LoadImage instead of _WinMain. This is necessary to support LoadLibrary(). Sun Jun 5 17:34:24 1994 Erik Bos (erik@hacktic.nl) * [loader/*] - fixed: GetModuleHandle() sometimes returned a wrong handle. - don't init dlls when cs == 0 (lzexpand, doesn't seem to have a init function) - LoadLibrary & LoadImage now return error instead of stopping wine. - moved most of NE-functions into one file. - LoadLibrary() uses w_files list instead of its own list. - NE exectables are now fixed-up and initialised when loaded instead of only once before calling InitTask. * [miscemu/int15.c] [miscemu/int31.c] Added. * [loader/selector.c] Stubs added for {Get|Set}SelectorLimit(), {Get|Set}SelectorBase(). * [misc/main.c] Stub added for IsRomModule(). * [miscemu/int21.c] Some cleanup, added heap for returning data. Jun 6, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [tools/build.c] Change MAX_ORDINALS define to higher value, 1299 entries. (MMSYSTEM doesn't have succesive numbers, some are around 1200). * [windows/utility.c] Bug fix in windows_wsprintf(), (twice increments ...). * [windows/winpos.c] Bug fix in SetWindowPos(), redraw was done if flag was set to SWP_NOREDRAW while SWP_SHOWWINDOW). * [misc/message.c] [controls/combo.c] Add an InvalidateRect() in WM_SHOWWINDOW to statisfy the new 'saveunder'. * [windows/win.c] In CreateWindowEx(), do SetMenu() calls after window creation, just before sending to WM_NCCALCSIZE. * [controls/menu.c] In function SetMenu(), now use SetWindowPos() with flags SWP_FRAMECHANGED to readjust menu area. Function MenuBarCalcSize() redone. Sun May 29 11:08:24 1994 David B. Thomas (dt@yenta.abq.nm.us) * [objects/text.c] Fixed problems associated with DT_WORDBREAK flag. String length was not being properly decremented when lines were folded, and wrapping was not performed when DT_NOCLIP and DT_NOPREFIX were both on in addition to DT_WORDBREAK. Windows does wrapping in this case, and now so does wine. Sun Jun 5 19:17:49 1994 Olaf Flebbe (olaf@dragon) * [edit.c] cp1 was uninitialized iff lineno == 0 * FindFile tests for existance of file even if a full filename was supplied. What about unix file names? * [controls/listbox ] wndPtr was uninitialized for LB_SETTOPINDEX * [misc/property.c] Do not free lpProp. Is it really allocated by malloc? {edited by Bob Amstadt: changed free() to GlobalFree()}
397 lines
8.9 KiB
C
397 lines
8.9 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;
|
||
}
|
||
|
||
/**********************************************************************
|
||
*
|
||
* 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");
|
||
}
|
||
}
|
||
|
||
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);
|
||
|
||
/* 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)
|
||
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;
|
||
struct w_files * 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
|