Release 940607
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()}
diff --git a/loader/main.c b/loader/main.c
new file mode 100644
index 0000000..119d00f
--- /dev/null
+++ b/loader/main.c
@@ -0,0 +1,396 @@
+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