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/BUGS b/BUGS
index 3d53722..f006749 100644
--- a/BUGS
+++ b/BUGS
@@ -3,3 +3,4 @@
- RegisterClass() with hbrBackground = COLOR_APPWORKSPACE+1 does not work.
- MDI does not send WM_GETMINMAX message.
- InitializeLoadedDLLs() can't init LZEXPAND.DLL. (cs:ip => 0:0)
+- LoadCursor does not correctly handle bitmap cursors
diff --git a/ChangeLog b/ChangeLog
index 5b0424f..407674d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,124 @@
+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/.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/winpos.c]
+ Bug fix in SetWindowPos(), (redraw was done if SWP_NOREDRAW set).
+
+ * [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()}
+
----------------------------------------------------------------------
Sat May 28 12:03:23 1994 Bob Amstadt (bob@pooh)
diff --git a/controls/edit.c b/controls/edit.c
index 7ff105f..8d43172 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -2084,6 +2084,7 @@
unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
if (off > strlen(text)) off = strlen(text);
+ cp1 = text;
for (lineno = 0; lineno < es->wlines; lineno++)
{
cp = text + *(textPtrs + lineno);
diff --git a/controls/listbox.c b/controls/listbox.c
index d18e785..522131a 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -462,8 +462,9 @@
printf("ListBox LB_SETTOPINDEX wParam=%x !\n", wParam);
lphl = ListBoxGetStorageHeader(hwnd);
lphl->FirstVisible = wParam;
+ wndPtr = WIN_FindWndPtr(hwnd);
if (wndPtr->dwStyle & WS_VSCROLL)
- SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+ SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
break;
diff --git a/controls/menu.c b/controls/menu.c
index dd9c880..6470497 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -103,7 +103,6 @@
#endif
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
if (lppop == NULL) break;
-/* if (!lppop->BarFlag) ShowWindow(hwnd, SW_HIDE); */
if (lppop->SysFlag) {
MenuHasFocus = FALSE;
if (wParam == SC_ABOUTWINE) {
@@ -112,12 +111,12 @@
DialogBox(hSysRes, MAKEINTRESOURCE(2),
GetParent(hwnd), (FARPROC)AboutWine_Proc);
}
- else
+ else {
#ifdef DEBUG_MENU
printf("PopupMenuWndProc // push to Owner WM_SYSCOMMAND !\n");
#endif
PostMessage(lppop->ownerWnd, WM_SYSCOMMAND, wParam, lParam);
-/* PostMessage(lppop->hWndParent, WM_SYSCOMMAND, wParam, lParam); */
+ }
break;
}
#ifdef DEBUG_MENU
@@ -125,7 +124,6 @@
#endif
MenuHasFocus = FALSE;
PostMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam);
-/* PostMessage(lppop->ownerWnd, WM_COMMAND, wParam, lParam); */
break;
case WM_SHOWWINDOW:
#ifdef DEBUG_MENU
@@ -152,7 +150,7 @@
hwnd, lppop->Width, lppop->Height);
#endif
SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height,
- SWP_NOZORDER | SWP_NOMOVE);
+ SWP_NOZORDER | SWP_NOMOVE);
#ifdef DEBUG_MENU
printf("PopupMenuWndProc // End of WM_SHOWWINDOW !\n");
#endif
@@ -414,11 +412,23 @@
hWnd, x, y, wRet, lpitem);
#endif
if (lpitem != NULL) {
+ if (lppop->FocusedItem != (WORD)-1 && wRet == lppop->FocusedItem) {
+ lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
+ if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) {
+ hSubMenu = (HMENU)lpitem2->item_id;
+ lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
+ if (lppop2 == NULL) return FALSE;
+ if (IsWindowVisible(lppop2->hWnd)) {
+ ShowWindow(lppop2->hWnd, SW_HIDE);
+ return TRUE;
+ }
+ }
+ }
MenuItemSelect(hWnd, lppop, wRet);
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
hSubMenu = (HMENU)lpitem->item_id;
lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
- if (lppop2 == NULL) return;
+ if (lppop2 == NULL) return FALSE;
lppop2->hWndParent = hWnd;
if (lppop->BarFlag) {
GetWindowRect(hWnd, &rect);
@@ -456,6 +466,7 @@
return TRUE;
}
printf("MenuButtonDown // x=%d y=%d // Not Found !\n", x, y);
+ if (GetCapture() != 0) ReleaseCapture();
MenuHasFocus = FALSE;
ShowWindow(lppop->hWnd, SW_HIDE);
return FALSE;
@@ -557,11 +568,14 @@
{
LPMENUITEM lpitem;
int i;
+#ifdef DEBUG_MENU
+ printf("ResetHiliteFlags lppop=%08X\n", lppop);
+#endif
if (lppop == NULL) return;
lpitem = lppop->firstItem;
for(i = 0; i < lppop->nItems; i++) {
if (lpitem == NULL) return;
- lpitem->item_flags &= MF_HILITE ^ 0xFFFF;
+ lpitem->item_flags &= 0xFFFF ^ MF_HILITE;
lpitem = (LPMENUITEM)lpitem->next;
}
}
@@ -1042,12 +1056,15 @@
void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop)
{
LPMENUITEM lpitem;
+ LPMENUITEM lpitem2;
RECT rect;
HBITMAP hBitMap;
BITMAP bm;
HFONT hOldFont;
- UINT i, OldHeight;
+ UINT i, j;
+ UINT OldHeight, LineHeight;
DWORD dwRet;
+ if (lprect == NULL) return;
if (lppop == NULL) return;
if (lppop->nItems == 0) return;
InitStdBitmaps();
@@ -1056,39 +1073,47 @@
lprect->left, lprect->top, lprect->right, lprect->bottom);
#endif
hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
- lppop->Height = lprect->bottom - lprect->top;
-CalcAGAIN:
- OldHeight = lppop->Height;
- SetRect(&rect, lprect->left, lprect->top, 0, lprect->top + OldHeight);
- lpitem = lppop->firstItem;
- for(i = 0; i < lppop->nItems; i++) {
- if (lpitem == NULL) break;
- rect.bottom = lprect->top + lppop->Height;
- if (rect.right > lprect->right)
- SetRect(&rect, lprect->left, rect.bottom,
- 0, rect.bottom + SYSMETRICS_CYMENU);
- if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
- hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
- GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
- rect.right = rect.left + bm.bmWidth;
- lppop->Height = max(lppop->Height, bm.bmHeight);
+ LineHeight = OldHeight = SYSMETRICS_CYMENU + 1;
+ SetRect(&rect, lprect->left, lprect->top, 0, lprect->top + LineHeight);
+ lpitem2 = lppop->firstItem;
+ while (lpitem != NULL) {
+ lpitem = lpitem2;
+ while(rect.right < lprect->right) {
+ if (lpitem == NULL) break;
+ if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
+ hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
+ GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
+ rect.right = rect.left + bm.bmWidth;
+ LineHeight = max(LineHeight, bm.bmHeight);
+ }
+ if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
+ ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
+ ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
+ dwRet = GetTextExtent(hDC, (char *)lpitem->item_text,
+ strlen((char *)lpitem->item_text));
+ rect.right = rect.left + LOWORD(dwRet) + 10;
+ dwRet = max(SYSMETRICS_CYMENU, (HIWORD(dwRet) + 6));
+ LineHeight = max(LineHeight, (WORD)dwRet);
+ }
+ CopyRect(&lpitem->rect, &rect);
+ rect.left = rect.right;
+ lpitem = (LPMENUITEM)lpitem->next;
}
- if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
- ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
- ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
- dwRet = GetTextExtent(hDC, (char *)lpitem->item_text,
- strlen((char *)lpitem->item_text));
- rect.right = rect.left + LOWORD(dwRet) + 10;
- dwRet = max(SYSMETRICS_CYMENU, (HIWORD(dwRet) + 6));
- lppop->Height = max(lppop->Height, (WORD)dwRet);
+ if (LineHeight == OldHeight) {
+ lpitem2 = lpitem;
+ LineHeight = OldHeight = SYSMETRICS_CYMENU + 1;
+ if (lpitem != NULL)
+ SetRect(&rect, lprect->left, rect.bottom,
+ 0, rect.bottom + LineHeight);
}
- CopyRect(&lpitem->rect, &rect);
- rect.left = rect.right;
- lpitem = (LPMENUITEM)lpitem->next;
+ else {
+ OldHeight = LineHeight;
+ SetRect(&rect, lprect->left, rect.top, 0, rect.top + LineHeight);
+ }
}
- if (OldHeight < lppop->Height) goto CalcAGAIN;
- lppop->Width = rect.right;
- lprect->bottom = lprect->top + lppop->Height;
+ lppop->Width = lprect->right - lprect->left;
+ lppop->Height = rect.bottom - lprect->top;
+ lprect->bottom = lprect->top + lppop->Height;
CopyRect(&lppop->rect, lprect);
#ifdef DEBUG_MENUCALC
printf("MenuBarCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height);
@@ -2074,8 +2099,7 @@
{
RECT rect;
LPPOPUPMENU lpmenu;
- NCCALCSIZE_PARAMS *params;
- HANDLE hparams;
+ WORD flags;
WND * wndPtr = WIN_FindWndPtr(hWnd);
if (wndPtr == NULL) {
printf("SetMenu(%04X, %04X) // Bad window handle !\n", hWnd, hMenu);
@@ -2085,20 +2109,17 @@
printf("SetMenu(%04X, %04X);\n", hWnd, hMenu);
#endif
if (GetCapture() == hWnd) ReleaseCapture();
- wndPtr->wIDmenu = hMenu;
- if (hMenu == 0) {
- printf("SetMenu(%04X, %04X) // Menu removed !\n", hWnd, hMenu);
- hparams = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(NCCALCSIZE_PARAMS));
- if (hparams) {
- params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR(hparams);
- params->rgrc[0] = wndPtr->rectWindow;
- params->lppos = NULL;
- SendMessage(hWnd, WM_NCCALCSIZE, FALSE, (LONG)params);
- wndPtr->rectClient = params->rgrc[0];
- USER_HEAP_FREE(hparams);
- }
- SendMessage(hWnd, WM_NCPAINT, 0, 0L);
- return TRUE;
+ if (wndPtr->window != 0) {
+ flags = SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED;
+ if (!IsWindowVisible(hWnd)) flags |= SWP_NOREDRAW;
+ if (hMenu == 0) {
+ wndPtr->wIDmenu = hMenu;
+ printf("SetMenu(%04X, %04X) // Menu removed, need NC recalc!\n", hWnd, hMenu);
+ SetWindowPos(hWnd, 0, 0, 0, 0, 0, flags);
+ return TRUE;
+ }
+ wndPtr->wIDmenu = hMenu;
+ SetWindowPos(hWnd, 0, 0, 0, 0, 0, flags);
}
lpmenu = (LPPOPUPMENU) GlobalLock(hMenu);
if (lpmenu == NULL) {
@@ -2222,9 +2243,9 @@
printf("CopySysMenu entry !\n");
#endif
if (hSysMenu == 0) {
- hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(1));
+/* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(1)); */
/* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(SC_SYSMENU));*/
-/* hSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU"); */
+ hSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU");
if (hSysMenu == 0) {
printf("SysMenu not found in system resources !\n");
return (HMENU)NULL;
diff --git a/debugger/hash.c b/debugger/hash.c
index a6d640f..97254af 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -13,6 +13,7 @@
#include <segmem.h>
#include <prototypes.h>
#include <wine.h>
+#include <dlls.h>
struct name_hash{
struct name_hash * next;
diff --git a/if1632/callback.c b/if1632/callback.c
index a4bd586..676fc7e 100644
--- a/if1632/callback.c
+++ b/if1632/callback.c
@@ -8,7 +8,7 @@
#include "wine.h"
#include "segmem.h"
#include <setjmp.h>
-
+#include "dlls.h"
extern SEGDESC Segments[];
extern unsigned short IF1632_Saved16_ss;
extern unsigned long IF1632_Saved16_ebp;
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 7c7e1d4..b63e283 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -50,7 +50,7 @@
StretchBlt(1 2 3 4 5 6 7 8 9 10 11)
36 pascal Polygon (word ptr word) Polygon (1 2 3)
37 pascal Polyline (word ptr word) Polyline (1 2 3)
-#38 pascal Escape
+38 pascal Escape(word word word ptr ptr) Escape(1 2 3 4 5)
39 pascal RestoreDC(word s_word) RestoreDC(1 2)
40 pascal FillRgn(word word word) FillRgn(1 2 3)
#41 pascal FrameRgn
@@ -278,7 +278,7 @@
CreatePolyPolygonRgn(1 2 3 4)
#452 pascal GDISEEGDIDO
#460 pascal GDITASKTERMINATION
-461 pascal SetObjectOwner(word) SetObjectOwner(1)
+461 return SetObjectOwner 4 0
#462 pascal ISGDIOBJECT
#463 pascal MAKEOBJECTPRIVATE
#464 pascal FIXUPBOGUSPUBLISHERMETAFILE
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index dc3076e..5f0ed34 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -143,7 +143,8 @@
135 pascal GetSystemDirectory(ptr word) GetSystemDirectory(1 2)
136 pascal GetDriveType(byte) GetDriveType(1)
137 pascal FatalAppExit(word ptr) FatalAppExit(1 2)
-#138 GETHEAPSPACES
+#138 GETHEAPSPACES - This is not correct but may fake out most apps
+138 return GetHeapSpaces 2 0x80004000
#139 DOSIGNAL
#140 SETSIGHANDLER
#141 INITTASK1
@@ -182,10 +183,10 @@
#183 __0000H
184 return GlobalDOSAlloc 4 0
185 return GlobalDOSFree 2 0
-#186 GETSELECTORBASE
-#187 SETSELECTORBASE
-#188 GETSELECTORLIMIT
-#189 SETSELECTORLIMIT
+186 pascal GetSelectorBase(word) GetSelectorBase(1)
+187 pascal SetSelectorBase(word long) SetSelectorBase(1 2)
+188 pascal GetSelectorLimit(word) GetSelectorLimit(1)
+189 pascal SetSelectorLimit(word long) SetSelectorLimit(1 2)
#190 __E000H
191 pascal GlobalPageLock(word) GlobalLock(1)
192 pascal GlobalPageUnlock(word) GlobalUnlock(1)
@@ -204,7 +205,7 @@
#205 CVWBREAK
#206 ALLOCSELECTORARRAY
207 return IsDBCSLeadByte 2 0
-#310 LOCALHANDLEDELTA
+310 pascal LocalHandleDelta(word) WIN16_LocalHandleDelta(1)
#311 GETSETKERNELDOSPROC
#314 DEBUGDEFINESEGMENT
315 pascal WriteOutProfiles() sync_profiles()
@@ -212,7 +213,7 @@
#318 FATALEXITHOOK
#319 FLUSHCACHEDFILEHANDLE
#320 ISTASK
-#323 ISROMMODULE
+323 pascal IsRomModule() IsRomModule()
#324 LOGERROR
#325 LOGPARAMERROR
#326 ISROMFILE
diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec
index 22bdf46..df33e6d 100644
--- a/if1632/mmsystem.spec
+++ b/if1632/mmsystem.spec
@@ -2,12 +2,25 @@
#
name mmsystem
id 11
-length 706
+length 1226
-1 pascal LIBMAIN(word word word ptr) MCI_LibMain(1 2 3 4)
+1 pascal MMSYSTEM_WEP(word word word ptr) MMSYSTEM_WEP(1 2 3 4)
2 pascal SNDPLAYSOUND(ptr word) sndPlaySound(1 2)
5 pascal MMSYSTEMGETVERSION() mmsystemGetVersion()
+6 pascal DriverProc(long word word long long) DriverProc(1 2 3 4 5)
30 pascal OUTPUTDEBUGSTR(ptr) OutputDebugStr(1)
+31 pascal DriverCallback(long word word word long long long) DriverCallback(1 2 3 4 5 6 7)
+#32 pascal STACKENTER()
+#33 pascal STACKLEAVE()
+#34 pascal MMDRVINSTALL()
+101 pascal JOYGETNUMDEVS() JoyGetNumDevs()
+102 pascal JOYGETDEVCAPS(word ptr word) JoyGetDevCaps(1 2 3)
+103 pascal JOYGETPOS(word ptr) JoyGetPos(1 2)
+104 pascal JOYGETTHRESHOLD(word ptr) JoyGetThreshold(1 2)
+105 pascal JOYRELEASECAPTURE(word) JoyReleaseCapture(1)
+106 pascal JOYSETCAPTURE(word word word word) JoySetCapture(1 2 3 4)
+107 pascal JOYSETTHRESHOLD(word word) JoySetThreshold(1 2)
+109 pascal JOYSETCALIBRATION(word) JoySetCalibration(1)
201 pascal MIDIOUTGETNUMDEVS() midiOutGetNumDevs()
202 pascal MIDIOUTGETDEVCAPS(word ptr word) midiOutGetDevCaps(1 2 3)
203 pascal MIDIOUTGETERRORTEXT(word ptr word) midiOutGetErrorText(1 2 3)
@@ -73,27 +86,32 @@
702 pascal MCISENDSTRING(ptr ptr word word) mciSendString(1 2 3 4)
703 pascal MCIGETDEVICEID(ptr) mciSendCommand(1)
706 pascal MCIGETERRORSTRING(long ptr word) mciGetErrorString(1 2 3)
-#1100 pascal DRVOPEN
-#1101 pascal DRVCLOSE
-#1102 pascal DRVSENDMESSAGE
-#1103 pascal DRVGETMODULEHANDLE
-#1104 pascal DRVDEFDRIVERPROC
-#1210 pascal MMIOOPEN
-#1211 pascal MMIOCLOSE
-#1212 pascal MMIOREAD
-#1213 pascal MMIOWRITE
-#1214 pascal MMIOSEEK
-#1215 pascal MMIOGETINFO
-#1216 pascal MMIOSETINFO
-#1217 pascal MMIOSETBUFFER
-#1218 pascal MMIOFLUSH
-#1219 pascal MMIOADVANCE
-#1220 pascal MMIOSTRINGTOFOURCC
-#1221 pascal MMIOINSTALLIOPROC
-#1222 pascal MMIOSENDMESSAGE
-#1223 pascal MMIODESCEND
-#1224 pascal MMIOASCEND
-#1225 pascal MMIOCREATECHUNK
-#1226 pascal MMIORENAME
+#900 pascal MMTASKCREATE()
+#902 pascal MMTASKBLOCK()
+#903 pascal MMTASKSIGNAL()
+#904 pascal MMGETCURRENTTASK()
+#905 pascal MMTASKYIELD()
+1100 pascal DRVOPEN(ptr ptr long) DrvOpen(1 2 3)
+1101 pascal DRVCLOSE(word long long) DrvClose(1 2 3)
+1102 pascal DRVSENDMESSAGE(word word long long) DrvSendMessage(1 2 3 4)
+1103 pascal DRVGETMODULEHANDLE(word) DrvGetModuleHandle(1)
+1104 pascal DRVDEFDRIVERPROC(long word word long long) DrvDefDriverProc(1 2 3 4 5)
+1210 pascal MMIOOPEN(ptr ptr long) mmioOpen(1 2 3)
+1211 pascal MMIOCLOSE(word word) mmioClose(1 2)
+1212 pascal MMIOREAD(word ptr long) mmioRead(1 2 3)
+1213 pascal MMIOWRITE(word ptr long) mmioWrite(1 2 3)
+1214 pascal MMIOSEEK(word long word) mmioSeek(1 2 3)
+1215 pascal MMIOGETINFO(word ptr word) mmioGetInfo(1 2 3)
+1216 pascal MMIOSETINFO(word ptr word) mmioSetInfo(1 2 3)
+1217 pascal MMIOSETBUFFER(word ptr long word) mmioSetBuffer(1 2 3 4)
+1218 pascal MMIOFLUSH(word word) mmioFlush(1 2)
+1219 pascal MMIOADVANCE(word ptr word) mmioAdvance(1 2 3)
+1220 pascal MMIOSTRINGTOFOURCC(ptr word) mmioStringToFOURCC(1 2)
+1221 pascal MMIOINSTALLIOPROC(long ptr long) mmioInstallIOProc(1 2 3)
+1222 pascal MMIOSENDMESSAGE(word word long long) mmioSendMessage(1 2 3 4)
+1223 pascal MMIODESCEND(word ptr ptr word) mmioDescend(1 2 3 4)
+1224 pascal MMIOASCEND(word ptr word) mmioAscend(1 2 3)
+1225 pascal MMIOCREATECHUNK(word ptr word) mmioCreateChunk(1 2 3)
+1226 pascal MMIORENAME(ptr ptr ptr long) mmioRename(1 2 3 4)
diff --git a/if1632/relay.c b/if1632/relay.c
index ddbf8c9..752fc37 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -36,7 +36,7 @@
{ "KEYBOARD",KEYBOARD_table,137, 8 },
{ "WINSOCK", WINSOCK_table, 155, 9 },
{ "STRESS", STRESS_table, 15, 10},
- { "MMSYSTEM",MMSYSTEM_table,1023,11},
+ { "MMSYSTEM",MMSYSTEM_table,1226,11},
{ "SYSTEM", SYSTEM_table, 20 ,12},
{ "TOOLHELP",TOOLHELP_table, 83, 13},
};
diff --git a/include/dlls.h b/include/dlls.h
index 574db1e..9796955 100644
--- a/include/dlls.h
+++ b/include/dlls.h
@@ -7,6 +7,35 @@
#ifndef DLLS_H
#define DLLS_H
+#define MAX_NAME_LENGTH 64
+
+typedef struct resource_name_table
+{
+ struct resource_name_table *next;
+ unsigned short type_ord;
+ unsigned short id_ord;
+ char id[MAX_NAME_LENGTH];
+} RESNAMTAB;
+
+struct w_files
+{
+ struct w_files * next;
+ char * name; /* Name, as it appears in the windows binaries */
+ char * filename; /* Actual name of the unix file that satisfies this */
+ int fd;
+ struct mz_header_s *mz_header;
+ struct ne_header_s *ne_header;
+ struct ne_segment_table_entry_s *seg_table;
+ struct segment_descriptor_s *selector_table;
+ char * lookup_table;
+ char * nrname_table;
+ char * rname_table;
+ unsigned short hinstance;
+ RESNAMTAB *resnamtab;
+};
+
+extern struct w_files *wine_files;
+
typedef struct dll_arg_relocation_s
{
unsigned short dst_arg; /* Offset to argument on stack */
diff --git a/include/heap.h b/include/heap.h
index 22fe129..7c389f1 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -27,6 +27,7 @@
MDESC *free_list;
ATOMTABLE *local_table;
unsigned short selector;
+ unsigned short delta; /* Number saved for Windows compat. */
} LHEAP;
extern void HEAP_Init(MDESC **free_list, void *start, int length);
diff --git a/include/prototypes.h b/include/prototypes.h
index a264ed5..cbeee0b 100644
--- a/include/prototypes.h
+++ b/include/prototypes.h
@@ -66,9 +66,6 @@
int *addr);
extern unsigned int GetEntryDLLOrdinal(char *dll_name, int ordinal, int *sel,
int *addr);
-extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt,
- int ordinal);
-extern SEGDESC *CreateSelectors(struct w_files * wpnt);
/* loader/signal.c */
@@ -81,16 +78,9 @@
extern void load_ne_header (int, struct ne_header_s *);
extern char *GetFilenameFromInstance(unsigned short instance);
-extern struct w_files *GetFileInfo(unsigned short instance);
extern HINSTANCE LoadImage(char *modulename, int filetype, int change_dir);
extern int _WinMain(int argc, char **argv);
extern void InitializeLoadedDLLs();
-extern int FixupSegment(struct w_files * wpnt, int segment_num);
-/*
-extern struct mz_header_s *CurrentMZHeader;
-extern struct ne_header_s *CurrentNEHeader;
-extern int CurrentNEFile;
-*/
/* if1632/relay.c */
diff --git a/include/toolhelp.h b/include/toolhelp.h
new file mode 100644
index 0000000..6941d1b
--- /dev/null
+++ b/include/toolhelp.h
@@ -0,0 +1,26 @@
+#ifndef __TOOLHELP_H
+#define __TOOLHELP_H
+
+#include "windows.h"
+
+DECLARE_HANDLE(HMODULE);
+
+#define MAX_MODULE_NAME 9
+#define MAX_PATH 255
+
+typedef struct {
+ DWORD dwSize;
+ char szModule[MAX_MODULE_NAME + 1];
+ HMODULE hModule;
+ WORD wcUsage;
+ char szExePath[MAX_PATH + 1];
+ WORD wNext;
+} MODULEENTRY;
+typedef MODULEENTRY *LPMODULEENTRY;
+
+BOOL ModuleFirst(MODULEENTRY *lpModule);
+BOOL ModuleNext(MODULEENTRY *lpModule);
+HMODULE ModuleFindName(MODULEENTRY *lpModule, LPCSTR lpstrName);
+HMODULE ModuleFindHandle(MODULEENTRY *lpModule, HMODULE hModule);
+
+#endif /* __TOOLHELP_H */
diff --git a/include/windows.h b/include/windows.h
index 96a29fe..e4ca0e2 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -11,22 +11,26 @@
typedef unsigned long DWORD;
typedef unsigned short BOOL;
typedef unsigned char BYTE;
-typedef char *LPSTR;
-typedef const char *LPCSTR;
-typedef char *NPSTR;
-typedef INT *LPINT;
-typedef void *LPVOID;
-typedef long (*FARPROC)();
-typedef FARPROC DLGPROC;
-typedef int CATCHBUF[9];
-typedef int *LPCATCHBUF;
-typedef FARPROC HOOKPROC;
typedef long LONG;
typedef UINT WPARAM;
typedef LONG LPARAM;
typedef LONG LRESULT;
typedef WORD HANDLE;
typedef DWORD HHOOK;
+typedef char *LPSTR;
+typedef const char *LPCSTR;
+typedef char *NPSTR;
+typedef INT *LPINT;
+typedef UINT *LPUINT;
+typedef WORD *LPWORD;
+typedef DWORD *LPDWORD;
+typedef LONG *LPLONG;
+typedef void *LPVOID;
+typedef long (*FARPROC)();
+typedef FARPROC DLGPROC;
+typedef int CATCHBUF[9];
+typedef int *LPCATCHBUF;
+typedef FARPROC HOOKPROC;
#define DECLARE_HANDLE(a) typedef HANDLE a;
DECLARE_HANDLE(HTASK);
diff --git a/include/wine.h b/include/wine.h
index 92e0f9b..5160386 100644
--- a/include/wine.h
+++ b/include/wine.h
@@ -1,37 +1,6 @@
#ifndef WINE_H
#define WINE_H
-#include "dlls.h"
-
-#define MAX_NAME_LENGTH 64
-
-typedef struct resource_name_table
-{
- struct resource_name_table *next;
- unsigned short type_ord;
- unsigned short id_ord;
- char id[MAX_NAME_LENGTH];
-} RESNAMTAB;
-
-struct w_files
-{
- struct w_files * next;
- char * name; /* Name, as it appears in the windows binaries */
- char * filename; /* Actual name of the unix file that satisfies this */
- int fd;
- struct mz_header_s *mz_header;
- struct ne_header_s *ne_header;
- struct ne_segment_table_entry_s *seg_table;
- struct segment_descriptor_s *selector_table;
- char * lookup_table;
- char * nrname_table;
- char * rname_table;
- unsigned short hinstance;
- RESNAMTAB *resnamtab;
-};
-
-extern struct w_files * wine_files;
-
extern char *WineIniFileName(void);
extern char *WinIniFileName(void);
diff --git a/loader/Imakefile b/loader/Imakefile
index 68297d2..b778667 100644
--- a/loader/Imakefile
+++ b/loader/Imakefile
@@ -6,12 +6,13 @@
dump.c \
ldt.c \
ldtlib.c \
+ main.c \
+ ne_image.c \
selector.c \
signal.c \
library.c \
resource.c \
- task.c \
- wine.c
+ task.c
OBJS = $(SRCS:.c=.o)
diff --git a/loader/library.c b/loader/library.c
index e99dd6e..02b74d2 100644
--- a/loader/library.c
+++ b/loader/library.c
@@ -21,23 +21,30 @@
#include "dlls.h"
#include "task.h"
-typedef struct {
- LPSTR ModuleName;
- LPSTR FileName;
- WORD Count;
- HANDLE hModule;
- HINSTANCE hInst;
- void *lpPrevModule;
- void *lpNextModule;
-} MODULEENTRY;
-typedef MODULEENTRY *LPMODULEENTRY;
-
-static LPMODULEENTRY lpModList = NULL;
-
-extern struct w_files * wine_files;
+extern struct w_files *wine_files;
extern struct dll_name_table_entry_s dll_builtin_table[];
-#define IS_BUILTIN_DLL(handle) ((handle >> 16) == 0xff)
+#define IS_BUILTIN_DLL(handle) ((handle >> 8) == 0xff)
+
+/**********************************************************************/
+
+void ExtractDLLName(char *libname, char *temp)
+{
+ int i;
+
+ strcpy(temp, libname);
+ if (strchr(temp, '\\') || strchr(temp, '/'))
+ for (i = strlen(temp) - 1; i ; i--)
+ if (temp[i] == '\\' || temp[i] == '/') {
+ strcpy(temp, temp + i + 1);
+ break;
+ }
+ for (i = strlen(temp) - 1; i ; i--)
+ if (temp[i] == '.') {
+ temp[i] = 0;
+ break;
+ }
+}
/**********************************************************************
* GetModuleHandle [KERNEL.47]
@@ -46,7 +53,28 @@
{
register struct w_files *w = wine_files;
int i;
- printf("GetModuleHandle('%x');\n", lpModuleName);
+ if ((int) lpModuleName & 0xffff0000)
+ printf("GetModuleHandle('%s');\n", lpModuleName);
+ else
+ printf("GetModuleHandle('%x');\n", lpModuleName);
+
+ printf("GetModuleHandle // searching in builtin libraries\n");
+ for (i = 0; i < N_BUILTINS; i++) {
+ if (dll_builtin_table[i].dll_name == NULL) break;
+ if (((int) lpModuleName & 0xffff0000) == 0) {
+ if (0xFF00 + i == (int) lpModuleName) {
+ printf("GetModuleHandle('%s') return %04X \n",
+ lpModuleName, 0xff00 + i);
+ return 0xFF00 + i;
+ }
+ }
+ else if (strcasecmp(dll_builtin_table[i].dll_name, lpModuleName) == 0) {
+ printf("GetModuleHandle('%x') return %04X \n",
+ lpModuleName, 0xFF00 + i);
+ return (0xFF00 + i);
+ }
+ }
+
printf("GetModuleHandle // searching in loaded modules\n");
while (w) {
/* printf("GetModuleHandle // '%x' \n", w->name); */
@@ -64,22 +92,6 @@
}
w = w->next;
}
- printf("GetModuleHandle // searching in builtin libraries\n");
- for (i = 0; i < N_BUILTINS; i++) {
- if (dll_builtin_table[i].dll_name == NULL) break;
- if (((int) lpModuleName & 0xffff0000) == 0) {
- if (0xFF00 + i == (int) lpModuleName) {
- printf("GetModuleHandle('%s') return %04X \n",
- lpModuleName, w->hinstance);
- return 0xFF + i;
- }
- }
- else if (strcasecmp(dll_builtin_table[i].dll_name, lpModuleName) == 0) {
- printf("GetModuleHandle('%x') return %04X \n",
- lpModuleName, 0xFF00 + i);
- return (0xFF00 + i);
- }
- }
printf("GetModuleHandle('%x') not found !\n", lpModuleName);
return 0;
}
@@ -91,7 +103,13 @@
int GetModuleUsage(HANDLE hModule)
{
struct w_files *w;
+
printf("GetModuleUsage(%04X);\n", hModule);
+
+ /* built-in dll ? */
+ if (IS_BUILTIN_DLL(hModule))
+ return 2;
+
w = GetFileInfo(hModule);
/* return w->Usage; */
return 1;
@@ -138,79 +156,15 @@
*/
HANDLE LoadLibrary(LPSTR libname)
{
- HANDLE hModule;
- LPMODULEENTRY lpMod = lpModList;
- LPMODULEENTRY lpNewMod;
- int i;
- char temp[64];
+ HANDLE h;
+
+ if ((h = LoadImage(libname, DLL, 0)) < 32)
+ return h;
- printf("LoadLibrary '%s'\n", libname);
-
- /* extract dllname */
- strcpy(temp, libname);
- if (strchr(temp, '\\') || strchr(temp, '/'))
- for (i = strlen(temp) - 1; i ; i--)
- if (temp[i] == '\\' || temp[i] == '/') {
- strcpy(temp, temp + i + 1);
- break;
- }
- for (i = strlen(temp) - 1; i ; i--)
- if (temp[i] == '.') {
- temp[i] = 0;
- break;
- }
-
- if (FindDLLTable(temp))
- {
- printf("Library was a builtin - \n");
- return GetModuleHandle(temp);
- }
-
- if (lpMod != NULL)
- {
- while (TRUE)
- {
- if (strcmp(libname, lpMod->FileName) == 0)
- {
- lpMod->Count++;
- printf("LoadLibrary // already loaded hInst=%04X\n",
- lpMod->hInst);
- return lpMod->hInst;
- }
- if (lpMod->lpNextModule == NULL) break;
- lpMod = lpMod->lpNextModule;
- }
- }
-
- hModule = GlobalAlloc(GMEM_MOVEABLE, sizeof(MODULEENTRY));
- lpNewMod = (LPMODULEENTRY) GlobalLock(hModule);
-#ifdef DEBUG_LIBRARY
- printf("LoadLibrary // creating new module entry %08X\n", lpNewMod);
-#endif
- if (lpNewMod == NULL)
- return 0;
- if (lpModList == NULL)
- {
- lpModList = lpNewMod;
- lpNewMod->lpPrevModule = NULL;
- }
- else
- {
- lpMod->lpNextModule = lpNewMod;
- lpNewMod->lpPrevModule = lpMod;
- }
-
- lpNewMod->lpNextModule = NULL;
- lpNewMod->hModule = hModule;
- lpNewMod->ModuleName = NULL;
- lpNewMod->FileName = (LPSTR) malloc(strlen(libname));
- if (lpNewMod->FileName != NULL)
- strcpy(lpNewMod->FileName, libname);
- lpNewMod->hInst = LoadImage(libname, DLL, 0);
- lpNewMod->Count = 1;
- printf("LoadLibrary returned Library hInst=%04X\n", lpNewMod->hInst);
- GlobalUnlock(hModule);
- return lpNewMod->hInst;
+ if (!IS_BUILTIN_DLL(h))
+ InitDLL(GetFileInfo(h));
+
+ return h;
}
@@ -219,14 +173,13 @@
*/
void FreeLibrary(HANDLE hLib)
{
- LPMODULEENTRY lpMod = lpModList;
-
printf("FreeLibrary(%04X);\n", hLib);
/* built-in dll ? */
if (IS_BUILTIN_DLL(hLib))
return;
+/*
while (lpMod != NULL) {
if (lpMod->hInst == hLib) {
if (lpMod->Count == 1) {
@@ -243,6 +196,7 @@
}
lpMod = lpMod->lpNextModule;
}
+*/
}
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
diff --git a/loader/ne_image.c b/loader/ne_image.c
new file mode 100644
index 0000000..98b3059
--- /dev/null
+++ b/loader/ne_image.c
@@ -0,0 +1,461 @@
+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>
+#ifdef linux
+#include <linux/unistd.h>
+#include <linux/head.h>
+#include <linux/ldt.h>
+#include <linux/segment.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#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 InitializeLoadedDLLs(struct w_files *wpnt);
+extern void FixupFunctionPrologs(struct w_files * wpnt);
+
+char * GetModuleName(struct w_files * wpnt, int index, char *buffer);
+extern char WindowsPath[256];
+char *WIN_ProgramName;
+
+HINSTANCE hSysRes;
+
+#ifndef WINELIB
+
+/**********************************************************************/
+
+void load_ne_header (int fd, struct ne_header_s *ne_header)
+{
+ if (read(fd, ne_header, sizeof(struct ne_header_s))
+ != sizeof(struct ne_header_s))
+ {
+ myerror("Unable to read NE header from file");
+ }
+}
+
+/**********************************************************************
+ * LoadNEImage
+ * Load one NE format executable into memory
+ */
+HINSTANCE LoadNEImage(struct w_files *wpnt)
+{
+ unsigned int read_size, status, segment;
+ int i;
+ char buffer[256];
+ char *fullname;
+ HANDLE t;
+
+ wpnt->ne_header = (struct ne_header_s *) malloc(sizeof(struct ne_header_s));
+ status = lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
+ load_ne_header (wpnt->fd, wpnt->ne_header);
+
+ /*
+ * Create segment selectors.
+ */
+ status = lseek(wpnt->fd, wpnt->mz_header->ne_offset +
+ wpnt->ne_header->segment_tab_offset,
+ SEEK_SET);
+ read_size = wpnt->ne_header->n_segment_tab *
+ sizeof(struct ne_segment_table_entry_s);
+ wpnt->seg_table = (struct ne_segment_table_entry_s *) malloc(read_size);
+ if (read(wpnt->fd, wpnt->seg_table, read_size) != read_size)
+ myerror("Unable to read segment table header from file");
+ wpnt->selector_table = CreateSelectors(wpnt);
+ wpnt->hinstance = (wpnt->
+ selector_table[wpnt->ne_header->auto_data_seg-1].
+ selector);
+
+ /* Get the lookup table. This is used for looking up the addresses
+ of functions that are exported */
+
+ read_size = wpnt->ne_header->entry_tab_length;
+ wpnt->lookup_table = (char *) malloc(read_size);
+ lseek(wpnt->fd, wpnt->mz_header->ne_offset +
+ wpnt->ne_header->entry_tab_offset, SEEK_SET);
+ if (read(wpnt->fd, wpnt->lookup_table, read_size) != read_size)
+ myerror("Unable to read lookup table header from file");
+
+ /* Get the iname table. This is used for looking up the names
+ of functions that are exported */
+
+ status = lseek(wpnt->fd, wpnt->ne_header->nrname_tab_offset, SEEK_SET);
+ read_size = wpnt->ne_header->nrname_tab_length;
+ wpnt->nrname_table = (char *) malloc(read_size);
+ if (read(wpnt->fd, wpnt->nrname_table, read_size) != read_size)
+ myerror("Unable to read nrname table header from file");
+
+ status = lseek(wpnt->fd, wpnt->mz_header->ne_offset +
+ wpnt->ne_header->rname_tab_offset, SEEK_SET);
+ read_size = wpnt->ne_header->moduleref_tab_offset -
+ wpnt->ne_header->rname_tab_offset;
+ wpnt->rname_table = (char *) malloc(read_size);
+ if (read(wpnt->fd, wpnt->rname_table, read_size) != read_size)
+ myerror("Unable to read rname table header from file");
+
+ /* Now get the module name, if the current one is a filename */
+/* nope, name by which dll is loaded is used !
+
+ if (strchr(wpnt->name, '\\') || strchr(wpnt->name, '/') ) {
+ wpnt->name = (char*) malloc(*wpnt->rname_table + 1);
+ memcpy(wpnt->name, wpnt->rname_table+1, *wpnt->rname_table);
+ }
+ wpnt->name[*wpnt->rname_table] = 0;
+*/
+ /*
+ * Now load any DLLs that this module refers to.
+ */
+ for(i=0; i<wpnt->ne_header->n_mod_ref_tab; i++)
+ {
+ char buff[14];
+ GetModuleName(wpnt, i + 1, buff);
+
+ if (strcasecmp(buff, wpnt->name) != 0 )
+ LoadImage(buff, DLL, 0);
+ }
+ /* fixup references */
+
+ for (segment = 0; segment < wpnt->ne_header->n_segment_tab; segment++)
+ if (FixupSegment(wpnt, segment) < 0)
+ myerror("fixup failed.");
+
+ FixupFunctionPrologs(wpnt);
+ InitializeLoadedDLLs(wpnt);
+
+ return(wpnt->hinstance);
+}
+
+/**********************************************************************
+ * GetImportedName
+ */
+char *
+GetImportedName(int fd, struct mz_header_s *mz_header,
+ struct ne_header_s *ne_header, int name_offset, char *buffer)
+{
+ int length;
+ int status;
+
+ status = lseek(fd, mz_header->ne_offset + ne_header->iname_tab_offset +
+ name_offset, SEEK_SET);
+ length = 0;
+ read(fd, &length, 1); /* Get the length byte */
+ length = CONV_CHAR_TO_LONG (length);
+ read(fd, buffer, length);
+ buffer[length] = 0;
+ return buffer;
+}
+
+/**********************************************************************
+ * GetModuleName
+ */
+char *
+GetModuleName(struct w_files * wpnt, int index, char *buffer)
+{
+ int fd = wpnt->fd;
+ struct mz_header_s *mz_header = wpnt->mz_header;
+ struct ne_header_s *ne_header = wpnt->ne_header;
+ int length;
+ WORD name_offset, status;
+ int i;
+
+ status = lseek(fd, mz_header->ne_offset + ne_header->moduleref_tab_offset +
+ 2*(index - 1), SEEK_SET);
+ name_offset = 0;
+ read(fd, &name_offset, 2);
+ name_offset = CONV_SHORT (name_offset);
+ status = lseek(fd, mz_header->ne_offset + ne_header->iname_tab_offset +
+ name_offset, SEEK_SET);
+ length = 0;
+ read(fd, &length, 1); /* Get the length byte */
+ length = CONV_CHAR_TO_LONG (length);
+ read(fd, buffer, length);
+ buffer[length] = 0;
+
+ /* Module names are always upper case */
+ for(i=0; i<length; i++)
+ if(buffer[i] >= 'a' && buffer[i] <= 'z') buffer[i] &= ~0x20;
+
+ return buffer;
+}
+
+
+/**********************************************************************
+ * FixupSegment
+ */
+int
+FixupSegment(struct w_files * wpnt, int segment_num)
+{
+ int fd = wpnt->fd;
+ struct mz_header_s * mz_header = wpnt->mz_header;
+ struct ne_header_s *ne_header = wpnt->ne_header;
+ struct ne_segment_table_entry_s *seg_table = wpnt->seg_table;
+ struct segment_descriptor_s *selector_table = wpnt->selector_table;
+ struct relocation_entry_s *rep, *rep1;
+ struct ne_segment_table_entry_s *seg;
+ struct segment_descriptor_s *sel;
+ struct dll_table_entry_s *dll_table;
+ int status;
+ unsigned short *sp;
+ unsigned int selector, address;
+ unsigned int next_addr;
+ int ordinal;
+ char dll_name[257];
+ char func_name[257];
+ int i, n_entries;
+ int additive;
+
+ seg = &seg_table[segment_num];
+ sel = &selector_table[segment_num];
+
+#ifdef DEBUG_FIXUP
+ printf("Segment fixups for %s, segment %d, selector %x\n",
+ wpnt->name, segment_num, (int) sel->base_addr >> 16);
+#endif
+
+ if ((seg->seg_data_offset == 0) ||
+ !(seg->seg_flags & NE_SEGFLAGS_RELOC_DATA))
+ return 0;
+
+ /*
+ * Go through the relocation table on entry at a time.
+ */
+ i = seg->seg_data_length;
+ if (i == 0)
+ i = 0x10000;
+
+ status = lseek(fd, seg->seg_data_offset *
+ (1 << ne_header->align_shift_count) + i, SEEK_SET);
+ n_entries = 0;
+ read(fd, &n_entries, sizeof(short int));
+ rep = (struct relocation_entry_s *)
+ malloc(n_entries * sizeof(struct relocation_entry_s));
+
+ if (read(fd,rep, n_entries * sizeof(struct relocation_entry_s)) !=
+ n_entries * sizeof(struct relocation_entry_s))
+ {
+ myerror("Unable to read relocation information");
+ }
+
+ rep1 = rep;
+
+ for (i = 0; i < n_entries; i++, rep++)
+ {
+ /*
+ * Get the target address corresponding to this entry.
+ */
+ additive = 0;
+
+ switch (rep->relocation_type)
+ {
+ case NE_RELTYPE_ORDINALADD:
+ additive = 1;
+
+ case NE_RELTYPE_ORDINAL:
+ if (GetModuleName(wpnt, rep->target1,
+ dll_name) == NULL)
+ {
+ fprintf(stderr, "NE_RELTYPE_ORDINAL failed");
+ return -1;
+ }
+
+ ordinal = rep->target2;
+
+ status = GetEntryDLLOrdinal(dll_name, ordinal, &selector,
+ &address);
+ if (status)
+ {
+ char s[80];
+
+ sprintf(s, "Bad DLL name '%s.%d'", dll_name, ordinal);
+ myerror(s);
+ return -1;
+ }
+
+#ifdef DEBUG_FIXUP
+ printf("%d: %s.%d: %04.4x:%04.4x\n", i + 1, dll_name, ordinal,
+ selector, address);
+#endif
+ break;
+
+ case NE_RELTYPE_NAMEADD:
+ additive = 1;
+
+ case NE_RELTYPE_NAME:
+ if (GetModuleName(wpnt, rep->target1, dll_name)
+ == NULL)
+ {
+ fprintf(stderr,"NE_RELTYPE_NAME failed");
+ return -1;
+ }
+
+ if (GetImportedName(fd, mz_header, ne_header,
+ rep->target2, func_name) == NULL)
+ {
+ fprintf(stderr,"getimportedname failed");
+ return -1;
+ }
+
+ status = GetEntryDLLName(dll_name, func_name, &selector,
+ &address);
+ if (status)
+ {
+ char s[80];
+
+ sprintf(s, "Bad DLL name '%s (%s)'", dll_name,func_name);
+ myerror(s);
+ return -1;
+ }
+
+#ifdef DEBUG_FIXUP
+ printf("%d: %s %s.%d: %04.4x:%04.4x\n", i + 1, func_name,
+ dll_name, ordinal, selector, address);
+#endif
+ break;
+
+ case NE_RELTYPE_INTERNAL:
+ case NE_RELTYPE_INT1:
+ if (rep->target1 == 0x00ff)
+ {
+ address = GetEntryPointFromOrdinal(wpnt, rep->target2);
+ selector = (address >> 16) & 0xffff;
+ address &= 0xffff;
+ }
+ else
+ {
+ selector = selector_table[rep->target1-1].selector;
+ address = rep->target2;
+ }
+
+#ifdef DEBUG_FIXUP
+ printf("%d: %04.4x:%04.4x\n", i + 1, selector, address);
+#endif
+ break;
+
+ case 7:
+ /* Relocation type 7:
+ *
+ * These appear to be used as fixups for the Windows
+ * floating point emulator. Let's just ignore them and
+ * try to use the hardware floating point. Linux should
+ * successfully emulate the coprocessor if it doesn't
+ * exist.
+ */
+#ifdef DEBUG_FIXUP
+ printf("%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ",
+ i + 1, rep->address_type, rep->relocation_type,
+ rep->offset);
+ printf("TARGET %04.4x %04.4x\n", rep->target1, rep->target2);
+#endif
+ continue;
+
+ default:
+ fprintf(stderr,"%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ",
+ i + 1, rep->address_type, rep->relocation_type,
+ rep->offset);
+ fprintf(stderr,"TARGET %04.4x %04.4x\n",
+ rep->target1, rep->target2);
+ free(rep1);
+ return -1;
+ }
+
+ /*
+ * Stuff the right size result in.
+ */
+ sp = (unsigned short *) ((char *) sel->base_addr + rep->offset);
+ if (additive)
+ {
+ if (FindDLLTable(dll_name) == NULL)
+ additive = 2;
+
+ fprintf(stderr,"%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ",
+ i + 1, rep->address_type, rep->relocation_type,
+ rep->offset);
+ fprintf(stderr,"TARGET %04.4x %04.4x\n",
+ rep->target1, rep->target2);
+ fprintf(stderr, " Additive = %d\n", additive);
+ }
+
+ switch (rep->address_type)
+ {
+ case NE_RADDR_OFFSET16:
+ do {
+#ifdef DEBUG_FIXUP
+ printf(" %04.4x:%04.4x:%04.4x OFFSET16\n",
+ (unsigned long) sp >> 16, (int) sp & 0xFFFF, *sp);
+#endif
+ next_addr = *sp;
+ *sp = (unsigned short) address;
+ if (additive == 2)
+ *sp += next_addr;
+ sp = (unsigned short *) ((char *) sel->base_addr + next_addr);
+ }
+ while (next_addr != 0xffff && !additive);
+
+ break;
+
+ case NE_RADDR_POINTER32:
+ do {
+#ifdef DEBUG_FIXUP
+ printf(" %04.4x:%04.4x:%04.4x POINTER32\n",
+ (unsigned long) sp >> 16, (int) sp & 0xFFFF, *sp);
+#endif
+ next_addr = *sp;
+ *sp = (unsigned short) address;
+ if (additive == 2)
+ *sp += next_addr;
+ *(sp+1) = (unsigned short) selector;
+ sp = (unsigned short *) ((char *) sel->base_addr + next_addr);
+ }
+ while (next_addr != 0xffff && !additive);
+
+ break;
+
+ case NE_RADDR_SELECTOR:
+ do {
+#ifdef DEBUG_FIXUP
+ printf(" %04.4x:%04.4x:%04.4x SELECTOR\n",
+ (unsigned long) sp >> 16, (int) sp & 0xFFFF, *sp);
+#endif
+ next_addr = *sp;
+ *sp = (unsigned short) selector;
+ sp = (unsigned short *) ((char *) sel->base_addr + next_addr);
+ if (rep->relocation_type == NE_RELTYPE_INT1)
+ break;
+ }
+ while (next_addr != 0xffff && !additive);
+
+ break;
+
+ default:
+ printf("%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ",
+ i + 1, rep->address_type, rep->relocation_type,
+ rep->offset);
+ printf("TARGET %04.4x %04.4x\n", rep->target1, rep->target2);
+ free(rep1);
+ return -1;
+ }
+ }
+
+ free(rep1);
+ return 0;
+}
+
+#endif
diff --git a/loader/resource.c b/loader/resource.c
index a4f9c1f..902242f 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -16,6 +16,7 @@
#include "wine.h"
#include "icon.h"
#include "accel.h"
+#include "dlls.h"
/* #define DEBUG_RESOURCE */
@@ -922,14 +923,14 @@
if (image_size_ret != NULL)
*image_size_ret = image_size;
hmem = GlobalAlloc(GMEM_MOVEABLE, image_size);
- image = GlobalLock(hmem);
+ image = GlobalLinearLock(hmem);
if (image == NULL || read(ResourceFd, image, image_size) != image_size)
{
GlobalFree(hmem);
return 0;
}
- GlobalUnlock(hmem);
+ GlobalLinearUnlock(hmem);
return hmem;
}
@@ -1021,7 +1022,7 @@
printf("LoadBitmap / BitMap %04X not Found !\n", bmp_name);
return 0;
}
- lp = (long *) GlobalLock(rsc_mem);
+ lp = (long *) GlobalLinearLock(rsc_mem);
if (lp == NULL)
{
GlobalFree(rsc_mem);
diff --git a/loader/selector.c b/loader/selector.c
index 9573c7a..b9b66bd 100644
--- a/loader/selector.c
+++ b/loader/selector.c
@@ -22,14 +22,14 @@
#include <sys/mman.h>
#include <machine/segments.h>
#endif
-
+#include "dlls.h"
#include "neexe.h"
#include "segmem.h"
#include "wine.h"
#include "windows.h"
#include "prototypes.h"
-/* #define DEBUG_SELECTORS */
+/* #define DEBUG_SELECTORS /* */
#ifdef linux
#define DEV_ZERO
@@ -579,7 +579,7 @@
/* We need a means of determining the ordinal for the function. */
/* Not a builtin symbol, look to see what the file has for us */
for(wpnt = wine_files; wpnt; wpnt = wpnt->next){
- if(strcmp(wpnt->name, dll_name)) continue;
+ if(strcasecmp(wpnt->name, dll_name)) continue;
cpnt = wpnt->nrname_table;
while(1==1){
if( ((int) cpnt) - ((int)wpnt->nrname_table) >
@@ -618,7 +618,7 @@
/* Not a builtin symbol, look to see what the file has for us */
for(wpnt = wine_files; wpnt; wpnt = wpnt->next){
- if(strcmp(wpnt->name, dll_name)) continue;
+ if(strcasecmp(wpnt->name, dll_name)) continue;
j = GetEntryPointFromOrdinal(wpnt, ordinal);
*addr = j & 0xffff;
j = j >> 16;
@@ -699,6 +699,73 @@
}
/**********************************************************************
+ */
+void
+FixupFunctionPrologs(struct w_files * wpnt)
+{
+ struct mz_header_s *mz_header = wpnt->mz_header;
+ struct ne_header_s *ne_header = wpnt->ne_header;
+ union lookup entry_tab_pointer;
+ struct entry_tab_header_s *eth;
+ struct entry_tab_movable_s *etm;
+ struct entry_tab_fixed_s *etf;
+ unsigned char *fixup_ptr;
+ int i;
+
+ if (!(ne_header->format_flags & 0x0001))
+ return;
+
+ entry_tab_pointer.cpnt = wpnt->lookup_table;
+ /*
+ * Let's walk through the table and fixup prologs as we go.
+ */
+ while (1)
+ {
+ /* Get bundle header */
+ eth = entry_tab_pointer.eth++;
+
+ /* Check for end of table */
+ if (eth->n_entries == 0)
+ return;
+
+ /* Check for empty bundle */
+ if (eth->seg_number == 0)
+ continue;
+
+ /* Examine each bundle */
+ for (i = 0; i < eth->n_entries; i++)
+ {
+ /* Moveable segment */
+ if (eth->seg_number >= 0xfe)
+ {
+ etm = entry_tab_pointer.etm++;
+ fixup_ptr = (wpnt->selector_table[etm->seg_number-1].base_addr
+ + etm->offset);
+ }
+ else
+ {
+ etf = entry_tab_pointer.etf++;
+ fixup_ptr = (wpnt->selector_table[eth->seg_number-1].base_addr
+ + (int) etf->offset[0]
+ + ((int) etf->offset[1] << 8));
+
+ }
+
+ /* Verify the signature */
+ if (((fixup_ptr[0] == 0x1e && fixup_ptr[1] == 0x58)
+ || (fixup_ptr[0] == 0x8c && fixup_ptr[1] == 0xd8))
+ && fixup_ptr[2] == 0x90)
+ {
+ fixup_ptr[0] = 0xb8; /* MOV AX, */
+ fixup_ptr[1] = wpnt->hinstance;
+ fixup_ptr[2] = (wpnt->hinstance >> 8);
+ }
+ }
+ }
+}
+
+
+/**********************************************************************
* GetDOSEnvironment
*/
LPSTR GetDOSEnvironment(void)
@@ -897,10 +964,21 @@
read_only = 1;
}
+#if 0
stmp = CreateNewSegments(!(s->flags & NE_SEGFLAGS_DATA), read_only,
s->length, 1);
s->base_addr = stmp->base_addr;
s->selector = stmp->selector;
+#endif
+ s->selector = GlobalAlloc(GMEM_FIXED, s->length);
+ if (s->selector == 0)
+ myerror("CreateSelectors: GlobalAlloc() failed");
+
+ s->base_addr = (void *) ((LONG) s->selector << 16);
+ if (!(s->flags & NE_SEGFLAGS_DATA))
+ PrestoChangoSelector(s->selector, s->selector);
+ else
+ memset(s->base_addr, 0, s->length);
if (seg_table[i].seg_data_offset != 0)
{
@@ -942,4 +1020,41 @@
return selectors;
}
+
+/***********************************************************************
+ * GetSelectorBase (KERNEL.186)
+ */
+DWORD GetSelectorBase(WORD wSelector)
+{
+ fprintf(stderr, "GetSelectorBase(selector %4X) stub!\n", wSelector);
+}
+
+/***********************************************************************
+ * SetSelectorBase (KERNEL.187)
+ */
+void SetSelectorBase(WORD wSelector, DWORD dwBase)
+{
+ fprintf(stderr, "SetSelectorBase(selector %4X, base %8X) stub!\n",
+ wSelector, dwBase);
+}
+
+/***********************************************************************
+ * GetSelectorLimit (KERNEL.188)
+ */
+DWORD GetSelectorLimit(WORD wSelector)
+{
+ fprintf(stderr, "GetSelectorLimit(selector %4X) stub!\n", wSelector);
+
+ return 0xffff;
+}
+
+/***********************************************************************
+ * SetSelectorLimit (KERNEL.189)
+ */
+void SetSelectorLimit(WORD wSelector, DWORD dwLimit)
+{
+ fprintf(stderr, "SetSelectorLimit(selector %4X, base %8X) stub!\n",
+ wSelector, dwLimit);
+}
+
#endif /* ifndef WINELIB */
diff --git a/loader/signal.c b/loader/signal.c
index 7de7064..7e8bc0f 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -42,6 +42,39 @@
return -1;
}
+int do_int(int intnum, struct sigcontext_struct *scp)
+{
+ switch(intnum)
+ {
+ case 0x10: return do_int10(scp);
+
+ case 0x11:
+ scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment();
+ return 1;
+
+ case 0x12:
+ scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L;
+ return 1; /* get base mem size */
+
+ case 0x15: return do_int15(scp);
+ case 0x1A: return do_int1A(scp);
+ case 0x21: return do_int21(scp);
+
+ case 0x22:
+ scp->sc_eax = 0x1234;
+ scp->sc_ebx = 0x5678;
+ scp->sc_ecx = 0x9abc;
+ scp->sc_edx = 0xdef0;
+ return 1;
+
+ case 0x25: return do_int25(scp);
+ case 0x26: return do_int26(scp);
+ case 0x2f: return do_int2f(scp);
+ case 0x31: return do_int31(scp);
+ }
+ return 0;
+}
+
#ifdef linux
static void win_fault(int signal, struct sigcontext_struct context)
{
@@ -90,54 +123,7 @@
{
case 0xcd: /* int <XX> */
instr++;
- switch(*instr)
- {
- case 0x10:
- if(!do_int10(scp))
- goto oops;
- break;
-
- case 0x11:
- scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment();
- break;
-
- case 0x12:
- scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L;
- break; /* get base mem size */
-
- case 0x1A:
- if(!do_int1A(scp))
- goto oops;
- break;
-
- case 0x21:
- if (!do_int21(scp))
- goto oops;
- break;
-
- case 0x22:
- scp->sc_eax = 0x1234;
- scp->sc_ebx = 0x5678;
- scp->sc_ecx = 0x9abc;
- scp->sc_edx = 0xdef0;
- break;
-
- case 0x25:
- if (!do_int25(scp))
- goto oops;
- break;
-
- case 0x26:
- if (!do_int26(scp))
- goto oops;
- break;
-
- case 0x2f:
- if (!do_int2f(scp))
- goto oops;
- break;
-
- default:
+ if (!do_int(*instr, scp)) {
fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr);
goto oops;
}
diff --git a/memory/global.c b/memory/global.c
index ef4e170..7509868 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -187,7 +187,7 @@
*/
if (size > 0x8000 || !(flags & GLOBAL_FLAGS_MOVEABLE))
{
- int segments = (size >> 16) + 1;
+ int segments = ((size - 1) >> 16) + 1;
g = GlobalGetFreeSegments(flags, segments);
if (g == NULL)
@@ -666,14 +666,25 @@
else if (n_segments < g->length)
{
GDESC *g_free;
+ int old_length = g->length;
g_free = g;
for (i = 0; i < n_segments; i++)
{
if (g_free->sequence != i + 1)
return 0;
+ g_free->length = n_segments;
g_free = g_free->next;
}
+
+ for ( ; i < old_length; i++)
+ {
+ g_free->length = 0x10000;
+ g_free->sequence = -1;
+ g_free = g_free->next;
+ }
+
+ return g->handle;
}
/*
diff --git a/memory/heap.c b/memory/heap.c
index d6535f3..ceaa85b 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -13,6 +13,16 @@
LHEAP *LocalHeaps = NULL;
+void
+HEAP_CheckHeap(MDESC **free_list)
+{
+ MDESC *m;
+
+ for (m = *free_list; m != NULL; m = m->next)
+ if (((int) m & 0xffff0000) != ((int) *free_list & 0xffff0000))
+ *(char *)0 = 0;
+}
+
/**********************************************************************
* HEAP_Init
*/
@@ -23,8 +33,8 @@
return;
*free_list = (MDESC *) start;
- (*free_list)->prev = NULL;
- (*free_list)->next = NULL;
+ (*free_list)->prev = NULL;
+ (*free_list)->next = NULL;
(*free_list)->length = length - sizeof(MDESC);
}
@@ -39,6 +49,7 @@
#ifdef DEBUG_HEAP
printf("HeapAlloc: free_list %08x, flags %x, bytes %d\n",
free_list, flags, bytes);
+ HEAP_CheckHeap(free_list);
#endif
/*
@@ -74,6 +85,7 @@
memset(m + 1, 0, bytes);
#ifdef DEBUG_HEAP
printf("HeapAlloc: returning %08x\n", (m + 1));
+ HEAP_CheckHeap(free_list);
#endif
return (void *) (m + 1);
}
@@ -97,12 +109,14 @@
memset(m + 1, 0, bytes);
#ifdef DEBUG_HEAP
printf("HeapAlloc: returning %08x\n", (m + 1));
+ HEAP_CheckHeap(free_list);
#endif
return (void *) (m + 1);
}
#ifdef DEBUG_HEAP
printf("HeapAlloc: returning %08x\n", 0);
+ HEAP_CheckHeap(free_list);
#endif
return 0;
}
@@ -133,6 +147,7 @@
printf("HEAP_ReAlloc m->prev=%08X !\n", m->prev);
printf("HEAP_ReAlloc m->next=%08X !\n", m->next);
printf("HEAP_ReAlloc *free_list=%08X !\n", *free_list);
+ HEAP_CheckHeap(free_list);
#endif
if (m->prev != m || m->next != m ||
@@ -141,6 +156,7 @@
#ifdef DEBUG_HEAP
printf("Attempt to resize bad pointer, m = %08x, *free_list = %08x\n",
m, free_list);
+ HEAP_CheckHeap(free_list);
#endif
return NULL;
}
@@ -164,6 +180,9 @@
return NULL;
memcpy(new_p, old_block, m->length);
HEAP_Free(free_list, old_block);
+#ifdef DEBUG_HEAP
+ HEAP_CheckHeap(free_list);
+#endif
return new_p;
}
@@ -199,6 +218,9 @@
HEAP_Free(free_list, m_free + 1);
}
+#ifdef DEBUG_HEAP
+ HEAP_CheckHeap(free_list);
+#endif
return old_block;
}
@@ -213,6 +235,12 @@
MDESC *m;
MDESC *m_prev;
+#ifdef DEBUG_HEAP
+ printf("HeapFree: free_list %08x, block %08x\n",
+ free_list, block);
+ HEAP_CheckHeap(free_list);
+#endif
+
/*
* Validate pointer.
*/
@@ -300,6 +328,9 @@
m_free->next = NULL;
}
+#ifdef DEBUG_HEAP
+ HEAP_CheckHeap(free_list);
+#endif
return 0;
}
@@ -347,6 +378,7 @@
lh->next = LocalHeaps;
lh->selector = owner;
lh->local_table = NULL;
+ lh->delta = 0x20;
HEAP_Init(&lh->free_list, start, length);
LocalHeaps = lh;
}
@@ -521,6 +553,24 @@
}
/**********************************************************************
+ * WIN16_LocalHandleDelta
+ */
+unsigned int
+WIN16_LocalHandleDelta(unsigned int new_delta)
+{
+ LHEAP *lh;
+
+ lh = HEAP_LocalFindHeap(HEAP_OWNER);
+ if (lh == NULL)
+ return 0;
+
+ if (new_delta)
+ lh->delta = new_delta;
+
+ return lh->delta;
+}
+
+/**********************************************************************
* GetFreeSystemResources (user.284)
*/
diff --git a/misc/Imakefile b/misc/Imakefile
index 6cfa02f..5967031 100644
--- a/misc/Imakefile
+++ b/misc/Imakefile
@@ -11,6 +11,7 @@
dos_fs.c \
driver.c \
exec.c \
+ escape.c \
file.c \
keyboard.c \
lstr.c \
diff --git a/misc/audio.c b/misc/audio.c
index 97a2e60..008029f 100644
--- a/misc/audio.c
+++ b/misc/audio.c
@@ -15,9 +15,9 @@
/**************************************************************************
-* DriverProc [sample driver]
+* AUDIO_DriverProc [sample driver]
*/
-LRESULT DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
+LRESULT AUDIO_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
DWORD dwParam1, DWORD dwParam2)
{
switch(wMsg) {
diff --git a/misc/cursor.c b/misc/cursor.c
index 15bc145..91e88ef 100644
--- a/misc/cursor.c
+++ b/misc/cursor.c
@@ -127,6 +127,13 @@
break;
}
}
+
+#if 1
+ lpcur->xcursor = XCreateFontCursor(XT_display, XC_top_left_arrow);
+ GlobalUnlock(hCursor);
+ return hCursor;
+#endif
+
if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR,
&image_size);
diff --git a/misc/dos_fs.c b/misc/dos_fs.c
index 83ed2b5..dc3b1bb 100644
--- a/misc/dos_fs.c
+++ b/misc/dos_fs.c
@@ -128,17 +128,13 @@
continue;
}
ExpandTildeString(temp);
- if ((ptr = (char *) malloc(strlen(temp)+1)) == NULL) {
- fprintf(stderr,"DOSFS: can't malloc for drive info!");
- continue;
- }
- ChopOffSlash(temp);
- DosDrives[x].rootdir = ptr;
- strcpy(DosDrives[x].rootdir, temp);
- strcpy(DosDrives[x].cwd, "/windows/");
- strcpy(DosDrives[x].label, "DRIVE-");
- strcat(DosDrives[x].label, drive);
- DosDrives[x].disabled = 0;
+ ChopOffSlash(temp);
+ DosDrives[x].rootdir = strdup(temp);
+ strcpy(DosDrives[x].rootdir, temp);
+ strcpy(DosDrives[x].cwd, "/windows/");
+ strcpy(DosDrives[x].label, "DRIVE-");
+ strcat(DosDrives[x].label, drive);
+ DosDrives[x].disabled = 0;
}
DOS_SetDefaultDrive(2);
@@ -393,19 +389,22 @@
char *GetDosFileName(char *unixfilename)
{
int i;
- static char temp[256];
+ static char temp[256], rootdir[256];
/* /dos/windows/system.ini => c:\windows\system.ini */
for (i = 0 ; i != MAX_DOS_DRIVES; i++) {
if (DosDrives[i].rootdir != NULL) {
- if (strncmp(DosDrives[i].rootdir, unixfilename, strlen(DosDrives[i].rootdir)) == 0) {
- sprintf(temp, "%c:\\%s", 'A' + i, unixfilename + strlen(DosDrives[i].rootdir) + 1);
- ToDos(temp);
- return temp;
- }
+ strcpy(rootdir, DosDrives[i].rootdir);
+ strcat(rootdir, "/");
+ ToUnix(rootdir);
+ if (strncmp(rootdir, unixfilename, strlen(rootdir)) == 0) {
+ sprintf(temp, "%c:\\%s", 'A' + i, unixfilename + strlen(rootdir));
+ ToDos(temp);
+ return temp;
+ }
}
}
- strcpy(temp, unixfilename);
+ sprintf(temp, "UNIX:%s", unixfilename);
ToDos(temp);
return(temp);
}
@@ -534,7 +533,11 @@
{
strncpy(buffer, GetUnixFileName(filename), buflen);
ToUnix(buffer);
- return buffer;
+ stat( buffer, &filestat);
+ if (S_ISREG(filestat.st_mode))
+ return buffer;
+ else
+ return NULL;
}
if (strchr(filename, '/') != NULL)
diff --git a/misc/driver.c b/misc/driver.c
index a3e4975..28888b5 100644
--- a/misc/driver.c
+++ b/misc/driver.c
@@ -6,10 +6,11 @@
static char Copyright[] = "Copyright Martin Ayotte, 1994";
-#include "stdio.h"
+#include <stdio.h>
#include "windows.h"
#include "win.h"
#include "user.h"
+#include "dlls.h"
#include "driver.h"
LPDRIVERITEM lpDrvItemList = NULL;
@@ -47,7 +48,7 @@
lpnewdrv = (LPDRIVERITEM) GlobalLock(hDrvr);
if (lpnewdrv == NULL) return 0;
lpnewdrv->dis.length = sizeof(DRIVERINFOSTRUCT);
- lpnewdrv->dis.hModule = LoadImage("DrvName", DLL);
+ lpnewdrv->dis.hModule = LoadImage("DrvName", DLL, 0);
if (lpnewdrv->dis.hModule == 0) {
GlobalUnlock(hDrvr);
GlobalFree(hDrvr);
diff --git a/misc/escape.c b/misc/escape.c
new file mode 100644
index 0000000..a4f6a6f
--- /dev/null
+++ b/misc/escape.c
@@ -0,0 +1,18 @@
+/*
+ * Escape() function.
+ *
+ * Copyright 1994 Bob Amstadt
+ */
+
+static char Copyright[] = "Copyright Bob Amstadt, 1994";
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "windows.h"
+
+int Escape(HDC hdc, int nEscape, int cbInput,
+ LPSTR lpszInData, LPSTR lpvOutData)
+{
+ fprintf(stderr, "Escape(nEscape = %04x)\n", nEscape);
+ return 0;
+}
diff --git a/misc/main.c b/misc/main.c
index fca16e6..ab3c2e7 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -342,6 +342,7 @@
MAIN_SaveSetup();
DOS_InitFS();
Comm_Init();
+ INT21_Init();
#ifndef sunos
atexit(called_at_exit);
@@ -557,3 +558,13 @@
return 0; /* don't swap */
}
+/***********************************************************************
+* ISROMMODULE (KERNEL.323)
+*/
+BOOL IsRomModule(HANDLE x)
+{
+ /* I don't know the prototype, I assume that it returns true
+ if the dll is located in rom */
+
+ return FALSE;
+}
diff --git a/misc/message.c b/misc/message.c
index 9d754e3..d9669b6 100644
--- a/misc/message.c
+++ b/misc/message.c
@@ -270,14 +270,21 @@
lpmb->rectStr.left += 64;
}
break;
+ case WM_SHOWWINDOW:
+ if (!(wParam == 0 && lParam == 0L)) {
+ InvalidateRect(hWnd, NULL, TRUE);
+ }
+ break;
case WM_PAINT:
#ifdef DEBUG_MSGBOX
- printf("MessageBox WM_PAINT !\n");
+ printf("MessageBox WM_PAINT hWnd=%04X !\n", hWnd);
#endif
lpmb = MsgBoxGetStorageHeader(hWnd);
if (lpmb == NULL) break;
- CopyRect(&rect, &lpmb->rectStr);
hDC = BeginPaint(hWnd, &ps);
+ GetClientRect(hWnd, &rect);
+ FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH));
+ CopyRect(&rect, &lpmb->rectStr);
OldTextColor = SetTextColor(hDC, 0x00000000);
if (lpmb->hIcon)
DrawIcon(hDC, lpmb->rectIcon.left,
diff --git a/misc/mmsystem.c b/misc/mmsystem.c
index 09304df..6e22c5c 100644
--- a/misc/mmsystem.c
+++ b/misc/mmsystem.c
@@ -8,6 +8,7 @@
#include "stdio.h"
#include "win.h"
+#include "driver.h"
#include "mmsystem.h"
static WORD mciActiveDev = 0;
@@ -17,7 +18,10 @@
UINT WINAPI waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
-int MCI_LibMain(HANDLE hInstance, WORD wDataSeg,
+/**************************************************************************
+* MMSYSTEM_WEP [MMSYSTEM.1]
+*/
+int MMSYSTEM_WEP(HANDLE hInstance, WORD wDataSeg,
WORD cbHeapSize, LPSTR lpCmdLine)
{
printf("MMSYSTEM DLL INIT ... hInst=%04X \n", hInstance);
@@ -29,7 +33,7 @@
*/
BOOL WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT uFlags)
{
- printf("sndPlaySound // lpszSoundName='%s' uFlags=%04X !\n",
+ printf("EMPTY STUB !!! sndPlaySound // SoundName='%s' uFlags=%04X !\n",
lpszSoundName, uFlags);
return 0;
}
@@ -44,14 +48,107 @@
}
/**************************************************************************
+* DriverProc [MMSYSTEM.6]
+*/
+LRESULT DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ return DrvDefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
+}
+
+/**************************************************************************
* OutputDebugStr [MMSYSTEM.30]
*/
void WINAPI OutputDebugStr(LPCSTR str)
{
- printf("OutputDebugStr('%s');\n", str);
+ printf("EMPTY STUB !!! OutputDebugStr('%s');\n", str);
}
/**************************************************************************
+* DriverCallback [MMSYSTEM.31]
+*/
+BOOL DriverCallback(DWORD dwCallBack, UINT uFlags, HANDLE hDev,
+ WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
+{
+ printf("EMPTY STUB !!! DriverCallback() !\n");
+}
+
+/**************************************************************************
+* JoyGetNumDevs [MMSYSTEM.101]
+*/
+WORD JoyGetNumDevs()
+{
+ printf("EMPTY STUB !!! JoyGetNumDevs();\n");
+ return 0;
+}
+
+/**************************************************************************
+* JoyGetDevCaps [MMSYSTEM.102]
+*/
+WORD JoyGetDevCaps(WORD wID, LPJOYCAPS lpCaps, WORD wSize)
+{
+ printf("EMPTY STUB !!! JoyGetDevCaps(%04X, %08X, %d);\n",
+ wID, lpCaps, wSize);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+* JoyGetPos [MMSYSTEM.103]
+*/
+WORD JoyGetPos(WORD wID, LPJOYINFO lpInfo)
+{
+ printf("EMPTY STUB !!! JoyGetPos(%04X, %08X);\n", wID, lpInfo);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+* JoyGetThreshold [MMSYSTEM.104]
+*/
+WORD JoyGetThreshold(WORD wID, LPWORD lpThreshold)
+{
+ printf("EMPTY STUB !!! JoyGetThreshold(%04X, %08X);\n", wID, lpThreshold);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+* JoyReleaseCapture [MMSYSTEM.105]
+*/
+WORD JoyReleaseCapture(WORD wID)
+{
+ printf("EMPTY STUB !!! JoyReleaseCapture(%04X);\n", wID);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+* JoySetCapture [MMSYSTEM.106]
+*/
+WORD JoySetCapture(HWND hWnd, WORD wID, WORD wPeriod, BOOL bChanged)
+{
+ printf("EMPTY STUB !!! JoySetCapture(%04X, %04X, %d, %d);\n",
+ hWnd, wID, wPeriod, bChanged);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+* JoySetThreshold [MMSYSTEM.107]
+*/
+WORD JoySetThreshold(WORD wID, WORD wThreshold)
+{
+ printf("EMPTY STUB !!! JoySetThreshold(%04X, %d);\n", wID, wThreshold);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+* JoySetCalibration [MMSYSTEM.109]
+*/
+WORD JoySetCalibration(WORD wID)
+{
+ printf("EMPTY STUB !!! JoySetCalibration(%04X);\n", wID);
+ return MMSYSERR_NODRIVER;
+}
+
+
+/**************************************************************************
* auxGetNumDevs [MMSYSTEM.350]
*/
UINT WINAPI auxGetNumDevs()
@@ -1511,6 +1608,17 @@
/**************************************************************************
+* mmioRename [MMSYSTEM.1226]
+*/
+UINT WINAPI mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
+ MMIOINFO FAR* lpmmioinfo, DWORD dwRenameFlags)
+{
+ printf("mmioRename('%s', '%s', %08X, %08X);\n",
+ szFileName, szNewFileName, lpmmioinfo, dwRenameFlags);
+ return 0;
+}
+
+/**************************************************************************
* DrvOpen [MMSYSTEM.1100]
*/
HDRVR DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
diff --git a/misc/property.c b/misc/property.c
index 18119c6..92f57a4 100644
--- a/misc/property.c
+++ b/misc/property.c
@@ -62,7 +62,7 @@
((LPPROPENTRY)lpProp->lpNextProp)->lpPrevProp =
lpProp->lpPrevProp;
if (lpProp->PropName != NULL) free(lpProp->PropName);
- free(lpProp);
+ GlobalFree(lpProp);
GlobalUnlock(wndPtr->hProp);
return hOldData;
}
diff --git a/misc/shell.c b/misc/shell.c
index 19977ca..d55368d 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -14,7 +14,6 @@
LPKEYSTRUCT lphRootKey = NULL;
-typedef FAR LONG *LPWORD;
DECLARE_HANDLE(HDROP);
extern HINSTANCE hSysRes;
diff --git a/misc/user.c b/misc/user.c
index ed0045b..cce820e 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -80,11 +80,9 @@
/* Create desktop window */
if (!WIN_CreateDesktopWindow()) return 0;
-#if 1
#ifndef WINELIB
/* Initialize DLLs */
- InitializeLoadedDLLs();
-#endif
+ InitializeLoadedDLLs(NULL);
#endif
return 1;
diff --git a/miscemu/Imakefile b/miscemu/Imakefile
index 4b258c4..65c043f 100644
--- a/miscemu/Imakefile
+++ b/miscemu/Imakefile
@@ -5,11 +5,13 @@
SRCS = \
emulate.c \
int10.c \
+ int15.c \
int1a.c \
int21.c \
int25.c \
int26.c \
int2f.c \
+ int31.c \
ioports.c \
kernel.c
diff --git a/miscemu/int10.c b/miscemu/int10.c
index 9ecc0d5..1d49f5e 100644
--- a/miscemu/int10.c
+++ b/miscemu/int10.c
@@ -3,12 +3,12 @@
#include "msdos.h"
#include "wine.h"
-static void Barf(struct sigcontext_struct *context)
+void IntBarf(int i, struct sigcontext_struct *context)
{
- fprintf(stderr, "int10: unknown/not implemented parameters:\n");
- fprintf(stderr, "int10: AX %04x, BX %04x, CX %04x, DX %04x, "
+ fprintf(stderr, "int%x: unknown/not implemented parameters:\n", i);
+ fprintf(stderr, "int%x: AX %04x, BX %04x, CX %04x, DX %04x, "
"SI %04x, DI %04x, DS %04x, ES %04x\n",
- AX, BX, CX, DX, SI, DI, DS, ES);
+ i, AX, BX, CX, DX, SI, DI, DS, ES);
}
int do_int10(struct sigcontext_struct *context)
@@ -31,7 +31,7 @@
break;
default:
- Barf(context);
+ IntBarf(0x10, context);
};
return 1;
}
diff --git a/miscemu/int15.c b/miscemu/int15.c
new file mode 100644
index 0000000..054a7e3
--- /dev/null
+++ b/miscemu/int15.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "msdos.h"
+#include "wine.h"
+
+int do_int15(struct sigcontext_struct *context)
+{
+ switch((context->sc_eax >> 8) & 0xff)
+ {
+ case 0xc0:
+
+ default:
+ IntBarf(0x15, context);
+ };
+ return 1;
+}
diff --git a/miscemu/int1a.c b/miscemu/int1a.c
index ee2f27f..235138e 100644
--- a/miscemu/int1a.c
+++ b/miscemu/int1a.c
@@ -53,7 +53,7 @@
break;
default:
- fprintf(stderr,"Unable to handle int 0x1A AX %04x\n", context->sc_eax & 0xffffL);
+ IntBarf(0x1a, context);
return 1;
};
return 1;
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 865bd49..3cc4080 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -1,3 +1,7 @@
+/*
+ * (c) 1993, 1994 Erik Bos
+ */
+
#include <time.h>
#include <fcntl.h>
#include <errno.h>
@@ -7,7 +11,6 @@
#include <sys/stat.h>
#include <unistd.h>
#include <utime.h>
-
#include "prototypes.h"
#include "regfunc.h"
#include "windows.h"
@@ -15,14 +18,17 @@
#include "msdos.h"
#include "options.h"
-/* #define DEBUG_FIND /* */
-
-static char Copyright[] = "copyright Erik Bos, 1993";
-
WORD ExtendedError, CodePage = 437;
BYTE ErrorClass, Action, ErrorLocus;
BYTE *dta;
+struct DosHeap {
+ BYTE dta[256];
+ BYTE InDosFlag;
+ BYTE biosdate[8];
+};
+static struct DosHeap *heap;
+
extern char TempDirectory[];
static int Error(int e, int class, int el)
@@ -35,6 +41,46 @@
return e;
}
+static void errno_to_doserr(void)
+{
+ switch (errno) {
+ case EAGAIN:
+ Error (ShareViolation, EC_Temporary, EL_Unknown);
+ break;
+ case EBADF:
+ Error (InvalidHandle, EC_AppError, EL_Unknown);
+ break;
+ case ENOSPC:
+ Error (DiskFull, EC_MediaError, EL_Disk);
+ break;
+ case EACCES:
+ case EPERM:
+ case EROFS:
+ Error (WriteProtected, EC_AccessDenied, EL_Unknown);
+ break;
+ case EBUSY:
+ Error (LockViolation, EC_AccessDenied, EL_Unknown);
+ break;
+ case ENOENT:
+ Error (FileNotFound, EC_NotFound, EL_Unknown);
+ break;
+ case EISDIR:
+ Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown);
+ break;
+ case ENFILE:
+ case EMFILE:
+ Error (NoMoreFiles, EC_MediaError, EL_Unknown);
+ break;
+ case EEXIST:
+ Error (FileExists, EC_Exists, EL_Disk);
+ break;
+ default:
+ fprintf(stderr, "int21: unknown errno %d!\n", errno);
+ Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
+ break;
+ }
+}
+
static void Barf(struct sigcontext_struct *context)
{
fprintf(stderr, "int21: unknown/not implemented parameters:\n");
@@ -92,10 +138,10 @@
int drive;
long size,available;
- if (!(EDX & 0xffL))
+ if (!(EDX & 0xff))
drive = DOS_GetDefaultDrive();
else
- drive = (EDX & 0xffL) - 1;
+ drive = (EDX & 0xff) - 1;
if (!DOS_ValidDrive(drive)) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
@@ -109,33 +155,11 @@
return;
}
- EAX = (EAX & 0xffff0000L) | 4;
- ECX = (ECX & 0xffff0000L) | 512;
+ EAX = (EAX & 0xffff0000) | 4;
+ ECX = (ECX & 0xffff0000) | 512;
- EBX = (EBX & 0xffff0000L) | (available / (CX * AX));
- EDX = (EDX & 0xffff0000L) | (size / (CX * AX));
- Error (0,0,0);
-}
-
-static void SetDefaultDrive(struct sigcontext_struct *context)
-{
- int drive;
-
- drive = EDX & 0xffL;
-
- if (!DOS_ValidDrive(drive)) {
- Error (InvalidDrive, EC_MediaError, EL_Disk);
- return;
- } else {
- DOS_SetDefaultDrive(drive);
- EAX = (EAX &0xffffff00L) | MAX_DOS_DRIVES;
- Error (0,0,0);
- }
-}
-
-static void GetDefaultDrive(struct sigcontext_struct *context)
-{
- EAX = (EAX & 0xffffff00L) | DOS_GetDefaultDrive();
+ EBX = (EBX & 0xffff0000) | (available / (CX * AX));
+ EDX = (EDX & 0xffff0000) | (size / (CX * AX));
Error (0,0,0);
}
@@ -148,9 +172,9 @@
drive = EDX & 0xffL;
if (!DOS_ValidDrive(drive)) {
- EAX = (EAX & 0xffff0000L) | 4;
- ECX = (ECX & 0xffff0000L) | 512;
- EDX = (EDX & 0xffff0000L);
+ EAX = (EAX & 0xffff0000) | 4;
+ ECX = (ECX & 0xffff0000) | 512;
+ EDX = (EDX & 0xffff0000);
Error (InvalidDrive, EC_MediaError, EL_Disk);
return;
}
@@ -161,9 +185,9 @@
return;
}
- EAX = (EAX & 0xffff0000L) | 4;
- ECX = (ECX & 0xffff0000L) | 512;
- EDX = (EDX & 0xffff0000L) | (size / (CX * AX));
+ EAX = (EAX & 0xffff0000) | 4;
+ ECX = (ECX & 0xffff0000) | 512;
+ EDX = (EDX & 0xffff0000) | (size / (CX * AX));
mediaID = 0xf0;
@@ -181,7 +205,7 @@
static void GetDrivePB(struct sigcontext_struct *context)
{
Error (InvalidDrive, EC_MediaError, EL_Disk);
- EAX = (EAX & 0xffff0000L) | 0xffL;
+ EAX = (EAX & 0xffff0000) | 0xffL;
/* I'm sorry but I only got networked drives :-) */
}
@@ -191,48 +215,30 @@
int size;
/* can't read from stdout / stderr */
-
if ((BX == 1) || (BX == 2)) {
Error (InvalidHandle, EL_Unknown, EC_Unknown);
- EAX = (EAX & 0xffff0000L) | InvalidHandle;
+ EAX = (EAX & 0xffff0000) | InvalidHandle;
SetCflag;
return;
}
ptr = pointer (DS,DX);
-
if (BX == 0) {
*ptr = EOF;
Error (0,0,0);
- EAX = (EAX & 0xffff0000L) | 1;
+ EAX = (EAX & 0xffff0000) | 1;
ResetCflag;
return;
} else {
size = read(BX, ptr, CX);
- if (size == 0) {
- Error (ReadFault, EC_Unknown, EL_Unknown);
- EAX = (EAX & 0xffffff00L) | ExtendedError;
- return;
- }
-
if (size == -1) {
- switch (errno) {
- case EAGAIN:
- Error (ShareViolation, EC_Temporary, EL_Unknown);
- break;
- case EBADF:
- Error (InvalidHandle, EC_AppError, EL_Unknown);
- break;
- default:
- Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
- break;
- }
- EAX = (EAX & 0xffffff00L) | ExtendedError;
+ errno_to_doserr();
+ EAX = (EAX & 0xffffff00) | ExtendedError;
SetCflag;
return;
}
Error (0,0,0);
- EAX = (EAX & 0xffff0000L) | size;
+ EAX = (EAX & 0xffff0000) | size;
ResetCflag;
}
}
@@ -258,75 +264,33 @@
fflush(stderr);
Error (0,0,0);
- EAX = (EAX & 0xffffff00L) | CX;
+ EAX = (EAX & 0xffffff00) | CX;
ResetCflag;
} else {
size = write(BX, ptr , CX);
if (size == 0) {
Error (WriteFault, EC_Unknown, EL_Unknown);
- EAX = (EAX & 0xffffff00L) | ExtendedError;
+ EAX = (EAX & 0xffffff00) | ExtendedError;
return;
}
if (size == -1) {
- switch (errno) {
- case EAGAIN:
- Error (ShareViolation, EC_Temporary, EL_Unknown);
- break;
- case EBADF:
- Error (InvalidHandle, EC_AppError, EL_Unknown);
- break;
- case ENOSPC:
- Error (DiskFull, EC_MediaError, EL_Disk);
- break;
- default:
- Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
- break;
- }
- EAX = (EAX & 0xffffff00L) | ExtendedError;
+ errno_to_doserr();
+ EAX = (EAX & 0xffffff00) | ExtendedError;
SetCflag;
return;
}
Error (0,0,0);
- EAX = (EAX & 0xffff0000L) | size;
+ EAX = (EAX & 0xffff0000) | size;
ResetCflag;
}
}
-static void UnlinkFile(struct sigcontext_struct *context)
-{
- if (unlink( GetUnixFileName( pointer(DS,DX)) ) == -1) {
- switch (errno) {
- case EACCES:
- case EPERM:
- case EROFS:
- Error (WriteProtected, EC_AccessDenied, EL_Unknown);
- break;
- case EBUSY:
- Error (LockViolation, EC_AccessDenied, EL_Unknown);
- break;
- case EAGAIN:
- Error (ShareViolation, EC_Temporary, EL_Unknown);
- break;
- case ENOENT:
- Error (FileNotFound, EC_NotFound, EL_Unknown);
- break;
- default:
- Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
- break;
- }
- EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag;
- return;
- }
- Error (0,0,0);
- ResetCflag;
-}
-
static void SeekFile(struct sigcontext_struct *context)
{
- int status, fileoffset;
+ off_t status, fileoffset;
- switch (EAX & 0xffL) {
+ switch (EAX & 0xff) {
case 1: fileoffset = SEEK_CUR;
break;
case 2: fileoffset = SEEK_END;
@@ -337,65 +301,45 @@
}
status = lseek(BX, (CX * 0x100) + DX, fileoffset);
if (status == -1) {
- switch (errno) {
- case EBADF:
- Error (InvalidHandle, EC_AppError, EL_Unknown);
- break;
- case EINVAL:
- Error (DataInvalid, EC_AppError, EL_Unknown);
- break;
- default:
- Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
- break;
- }
- EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag;
+ errno_to_doserr();
+ EAX = (EAX & 0xffffff00) | ExtendedError; SetCflag;
return;
}
Error (0,0,0);
- ResetCflag;
-}
-
-static void GetFileAttributes(struct sigcontext_struct *context)
-{
- EAX &= 0xfffff00L;
- ResetCflag;
-}
-
-static void SetFileAttributes(struct sigcontext_struct *context)
-{
+ EAX = (EAX & 0xffff0000L) | (status & 0xffff);
+ EDX = (EDX & 0xffff0000L) | ((status >> 16) & 0xffff);
+
ResetCflag;
}
static void ioctlGetDeviceInfo(struct sigcontext_struct *context)
{
- WORD handle = EBX & 0xffff;
-
- switch (handle)
- {
- case 0:
- case 1:
- case 2:
- EDX = (EDX & 0xffff0000) | 0x80d3;
- break;
-
- default:
- {
- struct stat sbuf;
+ WORD handle = EBX & 0xffff;
+
+ switch (handle) {
+ case 0:
+ case 1:
+ case 2:
+ EDX = (EDX & 0xffff0000) | 0x80d3;
+ break;
+
+ default:
+ {
+ struct stat sbuf;
- if (fstat(handle, &sbuf) < 0)
- {
- Barf(context);
- EDX = (EDX & 0xffff0000) | 0x50;
- SetCflag;
- return;
- }
+ if (fstat(handle, &sbuf) < 0)
+ {
+ IntBarf(0x21, context);
+ EDX = (EDX & 0xffff0000) | 0x50;
+ SetCflag;
+ return;
+ }
- /* This isn't the right answer, but should be close enough. */
- EDX = (EDX & 0xffff0000) | 0x0943;
+ /* This isn't the right answer, but should be close enough. */
+ EDX = (EDX & 0xffff0000) | 0x0943;
+ }
}
- }
-
- ResetCflag;
+ ResetCflag;
}
static void ioctlGenericBlkDevReq(struct sigcontext_struct *context)
@@ -403,16 +347,16 @@
BYTE *dataptr = pointer(DS, DX);
int drive;
- if (!(EBX & 0xffL))
+ if (!(EBX & 0xff))
drive = DOS_GetDefaultDrive();
else
- drive = (EBX & 0xffL) - 1;
+ drive = (EBX & 0xff) - 1;
- if ((ECX & 0xff00L) != 0x0800) {
- Barf(context);
+ if ((ECX & 0xff00) != 0x0800) {
+ IntBarf(0x21, context);
return;
}
- switch (ECX & 0xffL) {
+ switch (ECX & 0xff) {
case 0x60: /* get device parameters */
/* used by w4wgrp's winfile */
dataptr[0] = 0x04;
@@ -430,20 +374,14 @@
setword(&dataptr[4], 80); /* # of cylinders */
}
CreateBPB(drive, &dataptr[7]);
- EAX = (EAX & 0xfffff00L);
+ EAX = (EAX & 0xfffff00);
ResetCflag;
return;
default:
- Barf(context);
+ IntBarf(0x21, context);
}
}
-static void DupeFileHandle(struct sigcontext_struct *context)
-{
- EAX = (EAX & 0xffff0000L) | dup(BX);
- ResetCflag;
-}
-
static void GetSystemDate(struct sigcontext_struct *context)
{
struct tm *now;
@@ -452,9 +390,9 @@
ltime = time(NULL);
now = localtime(<ime);
- ECX = (ECX & 0xffff0000L) | (now->tm_year + 1900);
- EDX = (EDX & 0xffff0000L) | ((now->tm_mon + 1) << 8) | now->tm_mday;
- EAX = (EAX & 0xffff0000L) | now->tm_wday;
+ ECX = (ECX & 0xffff0000) | (now->tm_year + 1900);
+ EDX = (EDX & 0xffff0000) | ((now->tm_mon + 1) << 8) | now->tm_mday;
+ EAX = (EAX & 0xffff0000) | now->tm_wday;
}
static void GetSystemTime(struct sigcontext_struct *context)
@@ -465,23 +403,15 @@
ltime = time(NULL);
now = localtime(<ime);
- ECX = (ECX & 0xffffff00L) | (now->tm_hour << 8) | now->tm_min;
- EDX = (EDX & 0xffffff00L) | now->tm_sec << 8;
+ ECX = (ECX & 0xffffff00) | (now->tm_hour << 8) | now->tm_min;
+ EDX = (EDX & 0xffffff00) | now->tm_sec << 8;
}
static void GetExtendedErrorInfo(struct sigcontext_struct *context)
{
- EAX = (EAX & 0xffffff00L) | ExtendedError;
- EBX = (EBX & 0xffff0000L) | (0x100 * ErrorClass) | Action;
- ECX = (ECX & 0xffff00ffL) | (0x100 * ErrorLocus);
-}
-
-static void GetInDosFlag(struct sigcontext_struct *context)
-{
- const BYTE InDosFlag = 0;
-
- ES = (ES & 0xffff0000L) | segment(InDosFlag);
- EBX = (EBX & 0xffff0000L) | offset(InDosFlag);
+ EAX = (EAX & 0xffffff00) | ExtendedError;
+ EBX = (EBX & 0xffff0000) | (ErrorClass << 8) | Action;
+ ECX = (ECX & 0xffff00ff) | (ErrorLocus << 8);
}
static void CreateFile(struct sigcontext_struct *context)
@@ -489,96 +419,60 @@
int handle;
if ((handle = open(GetUnixFileName( pointer(DS,DX)), O_CREAT | O_TRUNC)) == -1) {
- switch (errno) {
- case EACCES:
- case EPERM:
- case EROFS:
- Error (WriteProtected, EC_AccessDenied, EL_Unknown);
- break;
- case EISDIR:
- Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown);
- break;
- case ENFILE:
- case EMFILE:
- Error (NoMoreFiles, EC_MediaError, EL_Unknown);
- case EEXIST:
- Error (FileExists, EC_Exists, EL_Disk);
- break;
- case ENOSPC:
- Error (DiskFull, EC_MediaError, EL_Disk);
- break;
- default:
- Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
- break;
- }
- EAX = (EAX & 0xffffff00L) | ExtendedError;
+ errno_to_doserr();
+ EAX = (EAX & 0xffffff00) | ExtendedError;
SetCflag;
return;
}
Error (0,0,0);
- EBX = (EBX & 0xffff0000L) | handle;
- EAX = (EAX & 0xffffff00L) | NoError;
+ EBX = (EBX & 0xffff0000) | handle;
+ EAX = (EAX & 0xffffff00) | NoError;
ResetCflag;
}
static void OpenExistingFile(struct sigcontext_struct *context)
{
int handle;
+ int mode;
+
+ switch (AX & 0x0007)
+ {
+ case 0:
+ mode = O_RDONLY;
+ break;
+
+ case 1:
+ mode = O_WRONLY;
+ break;
+
+ default:
+ mode = O_RDWR;
+ break;
+ }
fprintf(stderr,"OpenExistingFile (%s)\n", pointer(DS,DX));
- if ((handle = open(GetUnixFileName(pointer(DS,DX)), O_RDWR)) == -1) {
- switch (errno) {
- case EACCES:
- case EPERM:
- case EROFS:
- Error (WriteProtected, EC_AccessDenied, EL_Unknown);
- break;
- case EISDIR:
- Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown);
- break;
- case ENFILE:
- case EMFILE:
- Error (NoMoreFiles, EC_MediaError, EL_Unknown);
- case EEXIST:
- Error (FileExists, EC_Exists, EL_Disk);
- break;
- case ENOSPC:
- Error (DiskFull, EC_MediaError, EL_Disk);
- break;
- case ENOENT:
- Error (FileNotFound, EC_MediaError, EL_Disk);
- break;
- default:
- Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
- break;
- }
- EAX = (EAX & 0xffffff00L) | ExtendedError;
+ if ((handle = open(GetUnixFileName(pointer(DS,DX)), mode)) == -1) {
+ errno_to_doserr();
+ EAX = (EAX & 0xffffff00) | ExtendedError;
SetCflag;
return;
}
Error (0,0,0);
- EAX = (EAX & 0xffff0000L) | handle;
+ EAX = (EBX & 0xffff0000) | handle;
ResetCflag;
}
static void CloseFile(struct sigcontext_struct *context)
{
if (close(BX) == -1) {
- switch (errno) {
- case EBADF:
- Error (InvalidHandle, EC_AppError, EL_Unknown);
- break;
- default:
- Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
- break;
- }
- EAX = (EAX & 0xffffff00L) | ExtendedError;
+ errno_to_doserr();
+ EAX = (EAX & 0xffffff00) | ExtendedError;
SetCflag;
return;
- }
+ }
Error (0,0,0);
- EAX = (EAX & 0xffffff00L) | NoError;
+ EAX = (EAX & 0xffffff00) | NoError;
ResetCflag;
}
@@ -596,13 +490,6 @@
ResetCflag;
}
-static void GetTrueFileName(struct sigcontext_struct *context)
-{
- fprintf(stderr,"int21: GetTrueFileName of %s\n", pointer(DS,SI) );
-
- strncpy(pointer(ES,DI), pointer(DS,SI), strlen(pointer(DS,SI)) & 0x7f);
- ResetCflag;
-}
static void MakeDir(struct sigcontext_struct *context)
{
@@ -611,13 +498,13 @@
fprintf(stderr,"int21: makedir %s\n", pointer(DS,DX) );
if ((dirname = GetUnixFileName( pointer(DS,DX) ))== NULL) {
- EAX = (EAX & 0xffffff00L) | CanNotMakeDir;
+ EAX = (EAX & 0xffffff00) | CanNotMakeDir;
SetCflag;
return;
}
if (mkdir(dirname,0) == -1) {
- EAX = (EAX & 0xffffff00L) | CanNotMakeDir;
+ EAX = (EAX & 0xffffff00) | CanNotMakeDir;
SetCflag;
return;
}
@@ -644,96 +531,40 @@
fprintf(stderr,"int21: removedir %s\n", pointer(DS,DX) );
if ((dirname = GetUnixFileName( pointer(DS,DX) ))== NULL) {
- EAX = (EAX & 0xffffff00L) | CanNotMakeDir;
+ EAX = (EAX & 0xffffff00) | CanNotMakeDir;
SetCflag;
return;
}
/*
if (strcmp(unixname,DosDrives[drive].CurrentDirectory)) {
- EAX = (EAX & 0xffffff00L) | CanNotRemoveCwd;
+ EAX = (EAX & 0xffffff00) | CanNotRemoveCwd;
SetCflag;
}
*/
if (rmdir(dirname) == -1) {
- EAX = (EAX & 0xffffff00L) | CanNotMakeDir;
+ EAX = (EAX & 0xffffff00) | CanNotMakeDir;
SetCflag;
}
ResetCflag;
}
-static void AllocateMemory(struct sigcontext_struct *context)
-{
- char *ptr;
-
- fprintf(stderr,"int21: malloc %d bytes\n", BX * 0x10 );
-
-/* if ((ptr = (void *) memalign((size_t) (BX * 0x10), 0x10)) == NULL) {
- EAX = (EAX & 0xffffff00L) | OutOfMemory;
- EBX = (EBX & 0xffffff00L);
- SetCflag;
- }
- fprintf(stderr,"int21: malloc (ptr = %d)\n", ptr );
-
- EAX = (EAX & 0xffff0000L) | segment(ptr);
-*/
- Barf(context);
- SetCflag;
-}
-
-static void FreeMemory(struct sigcontext_struct *context)
-{
- fprintf(stderr,"int21: freemem (ptr = %d)\n", ES * 0x10 );
-/*
- free((void *)(ES * 0x10));
-*/ Barf(context);
- ResetCflag;
-}
-
-static void ResizeMemoryBlock(struct sigcontext_struct *context)
-{
- char *ptr;
-
- fprintf(stderr,"int21: realloc (ptr = %d)\n", ES * 0x10 );
-
-/* if ((ptr = (void *) realloc((void *)(ES * 0x10), (size_t) BX * 0x10)) == NULL) {
- EAX = (EAX & 0xffffff00L) | OutOfMemory;
- EBX = (EBX & 0xffffff00L);
- SetCflag;
- }
- EBX = (EBX & 0xffff0000L) | segment(ptr);
-*/ Barf(context);
- SetCflag;
-}
-
static void ExecProgram(struct sigcontext_struct *context)
{
execl("wine", GetUnixFileName( pointer(DS,DX)) );
}
-static void GetReturnCode(struct sigcontext_struct *context)
-{
- EAX = (EAX & 0xffffff00L) | NoError; /* normal exit */
-}
-
static void FindNext(struct sigcontext_struct *context)
{
struct dosdirent *dp;
-#ifdef DEBUG_FIND
- fprintf(stderr, "FindNext: ");
-#endif
-
- dp = *(struct dosdirent **)(dta + 0x0d);
+ dp = (struct dosdirent *)(dta + 0x0d);
do {
if ((dp = DOS_readdir(dp)) == NULL) {
Error(NoMoreFiles, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xffffff00L) | NoMoreFiles;
+ EAX = (EAX & 0xffffff00) | NoMoreFiles;
SetCflag;
-#ifdef DEBUG_FIND
- fprintf(stderr, "\n");
-#endif
return;
}
} while (*(dta + 0x0c) != dp->attribute);
@@ -743,14 +574,8 @@
setdword(&dta[0x1a], dp->filesize);
strncpy(dta + 0x1e, dp->filename, 13);
- EAX = (EAX & 0xffffff00L);
+ EAX = (EAX & 0xffffff00);
ResetCflag;
-
-#ifdef DEBUG_FIND
- fprintf(stderr,
- "DTA: drive %c, template %11.11s, size %d, name %-13.13s\n",
- dta[0] + 'A', &dta[1], *(LONG *)(&dta[0x1a]), &dta[0x1e]);
-#endif
return;
}
@@ -797,16 +622,6 @@
FindNext(context);
}
-static void GetSysVars(struct sigcontext_struct *context)
-{
- /* return a null pointer, to encourage anyone who tries to
- use the pointer */
-
- ES = 0x0;
- EBX = (EBX & 0xffff0000L);
- Barf(context);
-}
-
static void GetFileDateTime(struct sigcontext_struct *context)
{
char *filename;
@@ -814,7 +629,7 @@
struct tm *now;
if ((filename = GetUnixFileName( pointer(DS,DX) ))== NULL) {
- EAX = (EAX & 0xffffff00L) | FileNotFound;
+ EAX = (EAX & 0xffffff00) | FileNotFound;
SetCflag;
return;
}
@@ -822,8 +637,8 @@
now = localtime (&filestat.st_mtime);
- ECX = (ECX & 0xffff0000L) | ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2);
- EDX = (EDX & 0xffff0000L) | ((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday);
+ ECX = (ECX & 0xffff0000) | ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2);
+ EDX = (EDX & 0xffff0000) | ((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday);
ResetCflag;
}
@@ -854,14 +669,14 @@
handle = open(GetUnixFileName(temp), O_CREAT | O_TRUNC | O_RDWR);
if (handle == -1) {
- EAX = (EAX & 0xffffff00L) | WriteProtected;
+ EAX = (EAX & 0xffffff00) | WriteProtected;
SetCflag;
return;
}
strcpy(pointer(DS,DX), temp);
- EAX = (EAX & 0xffff0000L) | handle;
+ EAX = (EAX & 0xffff0000) | handle;
ResetCflag;
}
@@ -870,22 +685,12 @@
int handle;
if ((handle = open(GetUnixFileName( pointer(DS,DX) ), O_CREAT | O_TRUNC | O_RDWR)) == -1) {
- EAX = (EAX & 0xffffff00L) | WriteProtected;
+ EAX = (EAX & 0xffffff00) | WriteProtected;
SetCflag;
return;
}
- EAX = (EAX & 0xffff0000L) | handle;
- ResetCflag;
-}
-
-static void FileLock(struct sigcontext_struct *context)
-{
- fprintf(stderr, "int21: flock()\n");
-}
-
-static void GetExtendedCountryInfo(struct sigcontext_struct *context)
-{
+ EAX = (EAX & 0xffff0000) | handle;
ResetCflag;
}
@@ -893,13 +698,13 @@
{
int drive;
- if ((EDX & 0xffL) == 0)
+ if ((EDX & 0xff) == 0)
drive = DOS_GetDefaultDrive();
else
- drive = (EDX & 0xffL)-1;
+ drive = (EDX & 0xff)-1;
if (!DOS_ValidDrive(drive)) {
- EAX = (EAX & 0xffffff00L) | InvalidDrive;
+ EAX = (EAX & 0xffffff00) | InvalidDrive;
SetCflag;
return;
}
@@ -908,24 +713,19 @@
ResetCflag;
}
-static void GetCurrentPSP(struct sigcontext_struct *context)
-{
- Barf(context);
-}
-
static void GetDiskSerialNumber(struct sigcontext_struct *context)
{
int drive;
BYTE *dataptr = pointer(DS, DX);
DWORD serialnumber;
- if ((EBX & 0xffL) == 0)
+ if ((EBX & 0xff) == 0)
drive = DOS_GetDefaultDrive();
else
- drive = (EBX & 0xffL) - 1;
+ drive = (EBX & 0xff) - 1;
if (!DOS_ValidDrive(drive)) {
- EAX = (EAX & 0xffffff00L) |InvalidDrive;
+ EAX = (EAX & 0xffffff00) |InvalidDrive;
SetCflag;
return;
}
@@ -937,7 +737,7 @@
strncpy(dataptr + 6, DOS_GetVolumeLabel(drive), 8);
strncpy(dataptr + 0x11, "FAT16 ", 8);
- EAX = (EAX & 0xffffff00L);
+ EAX = (EAX & 0xffffff00);
ResetCflag;
}
@@ -947,13 +747,13 @@
BYTE *dataptr = pointer(DS, DX);
DWORD serialnumber;
- if ((EBX & 0xffL) == 0)
+ if ((EBX & 0xff) == 0)
drive = DOS_GetDefaultDrive();
else
- drive = (EBX & 0xffL) - 1;
+ drive = (EBX & 0xff) - 1;
if (!DOS_ValidDrive(drive)) {
- EAX = (EAX & 0xffffff00L) | InvalidDrive;
+ EAX = (EAX & 0xffffff00) | InvalidDrive;
SetCflag;
return;
}
@@ -962,7 +762,7 @@
(dataptr[4] << 24);
DOS_SetSerialNumber(drive, serialnumber);
- EAX = (EAX & 0xffffff00L) | 1L;
+ EAX = (EAX & 0xffffff00) | 1L;
ResetCflag;
}
@@ -1003,11 +803,11 @@
strncpy(dta, DOS_GetVolumeLabel(drive), 8);
*(dta + 0x0b) = FA_DIREC;
- EAX = (EAX & 0xffffff00L);
+ EAX = (EAX & 0xffffff00);
return;
}
}
- Barf(context);
+ IntBarf(0x21, context);
}
static void DeleteFileFCB(struct sigcontext_struct *context)
@@ -1033,7 +833,7 @@
if ((dp = DOS_opendir(temp)) == NULL) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xffffff00L) | 0xffL;
+ EAX = (EAX & 0xffffff00) | 0xffL;
return;
}
@@ -1049,7 +849,7 @@
/* unlink(GetUnixFileName(temp)); */
}
DOS_closedir(dp);
- EAX = (EAX & 0xffffff00L);
+ EAX = (EAX & 0xffffff00);
}
static void RenameFileFCB(struct sigcontext_struct *context)
@@ -1075,7 +875,7 @@
if ((dp = DOS_opendir(temp)) == NULL) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xffffff00L) | 0xffL;
+ EAX = (EAX & 0xffffff00) | 0xffL;
return;
}
@@ -1094,7 +894,7 @@
fprintf(stderr, "int21: renamefile %s -> %s\n", oldname, newname);
}
DOS_closedir(dp);
- EAX = (EAX & 0xffffff00L);
+ EAX = (EAX & 0xffffff00);
}
/************************************************************************/
@@ -1152,7 +952,7 @@
case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */
case 0x29: /* PARSE FILENAME INTO FCB */
case 0x2e: /* SET VERIFY FLAG */
- Barf(context);
+ IntBarf(0x21, context);
break;
case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */
@@ -1165,9 +965,8 @@
"SWITCHAR" - SET SWITCH CHARACTER
"AVAILDEV" - SPECIFY \DEV\ PREFIX USE */
case 0x54: /* GET VERIFY FLAG */
- case 0x61: /* UNUSED */
case 0x6b: /* NULL FUNCTION */
- Barf(context);
+ IntBarf(0x21, context);
EAX &= 0xff00;
break;
@@ -1176,8 +975,15 @@
break;
case 0x0e: /* SELECT DEFAULT DRIVE */
- SetDefaultDrive(context);
- break;
+ if (!DOS_ValidDrive(EDX & 0xff)) {
+ Error (InvalidDrive, EC_MediaError, EL_Disk);
+ return;
+ } else {
+ DOS_SetDefaultDrive(EDX & 0xff);
+ EAX = (EAX &0xffffff00) | MAX_DOS_DRIVES;
+ Error(0,0,0);
+ }
+ break;
case 0x11: /* FIND FIRST MATCHING FILE USING FCB */
FindFirstFCB(context);
@@ -1192,7 +998,8 @@
break;
case 0x19: /* GET CURRENT DEFAULT DRIVE */
- GetDefaultDrive(context);
+ EAX = (EAX & 0xffffff00) | DOS_GetDefaultDrive();
+ Error (0,0,0);
break;
case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */
@@ -1226,17 +1033,17 @@
case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
ES = segment(dta);
- EBX = (EBX & 0xffff0000L) | offset(dta);
+ EBX = (EBX & 0xffff0000) | offset(dta);
break;
case 0x30: /* GET DOS VERSION */
- EAX = (EAX & 0xffff0000L) | DOSVERSION;
- EBX = (EBX & 0xffff0000L) | 0x0012; /* 0x123456 is Wine's serial # */
- ECX = (ECX & 0xffff0000L) | 0x3456;
+ EAX = (EAX & 0xffff0000) | DOSVERSION;
+ EBX = (EBX & 0xffff0000) | 0x0012; /* 0x123456 is Wine's serial # */
+ ECX = (ECX & 0xffff0000) | 0x3456;
break;
case 0x31: /* TERMINATE AND STAY RESIDENT */
- Barf(context);
+ IntBarf(0x21, context);
break;
case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
@@ -1246,7 +1053,7 @@
case 0x33: /* MULTIPLEXED */
switch (EAX & 0xff) {
case 0x00: /* GET CURRENT EXTENDED BREAK STATE */
- if (!(EAX & 0xffL))
+ if (!(EAX & 0xff))
EDX &= 0xff00L;
break;
@@ -1258,7 +1065,7 @@
break;
case 0x05: /* GET BOOT DRIVE */
- EDX = (EDX & 0xff00L) | 2;
+ EDX = (EDX & 0xff00) | 2;
/* c: is Wine's bootdrive */
break;
@@ -1268,13 +1075,14 @@
break;
default:
- Barf(context);
+ IntBarf(0x21, context);
break;
}
break;
case 0x34: /* GET ADDRESS OF INDOS FLAG */
- GetInDosFlag(context);
+ ES = (ES & 0xffff0000) | segment(heap->InDosFlag);
+ EBX = (EBX & 0xffff0000) | offset(heap->InDosFlag);
break;
case 0x35: /* GET INTERRUPT VECTOR */
@@ -1328,21 +1136,29 @@
break;
case 0x41: /* "UNLINK" - DELETE FILE */
- UnlinkFile(context);
- break;
+ if (unlink( GetUnixFileName( pointer(DS,DX)) ) == -1) {
+ errno_to_doserr();
+ EAX = (EAX & 0xffffff00) | ExtendedError;
+ SetCflag;
+ return;
+ }
+ Error(0,0,0);
+ ResetCflag;
+ break;
case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */
SeekFile(context);
break;
case 0x43: /* FILE ATTRIBUTES */
- switch (EAX & 0xffL)
+ switch (EAX & 0xff)
{
case 0x00:
- GetFileAttributes(context);
+ EAX &= 0xfffff00L;
+ ResetCflag;
break;
case 0x01:
- SetFileAttributes(context);
+ ResetCflag;
break;
}
break;
@@ -1359,33 +1175,27 @@
break;
default:
- Barf(context);
+ IntBarf(0x21, context);
break;
}
break;
-
case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */
case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
- DupeFileHandle(context);
+ EAX = (EAX & 0xffff0000) | dup(BX);
+ ResetCflag;
break;
case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
GetCurrentDirectory(context);
- EAX = (EAX & 0xffff0000L) | 0x0100;
+ EAX = (EAX & 0xffff0000) | 0x0100;
/* intlist: many Microsoft products for Windows rely on this */
break;
case 0x48: /* ALLOCATE MEMORY */
- AllocateMemory(context);
- break;
-
case 0x49: /* FREE MEMORY */
- FreeMemory(context);
- break;
-
case 0x4a: /* RESIZE MEMORY BLOCK */
- ResizeMemoryBlock(context);
+ IntBarf(0x21, context);
break;
case 0x4b: /* "EXEC" - LOAD AND/OR EXECUTE PROGRAM */
@@ -1393,11 +1203,11 @@
break;
case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */
- exit(EAX & 0xffL);
+ exit(EAX & 0xff);
break;
case 0x4d: /* GET RETURN CODE */
- GetReturnCode(context);
+ EAX = (EAX & 0xffffff00) | NoError; /* normal exit */
break;
case 0x4e: /* "FINDFIRST" - FIND FIRST MATCHING FILE */
@@ -1409,7 +1219,9 @@
break;
case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
- GetSysVars(context);
+ ES = 0x0;
+ EBX = (EBX & 0xffff0000);
+ IntBarf(0x21, context);
break;
case 0x56: /* "RENAME" - RENAME FILE */
@@ -1417,7 +1229,7 @@
break;
case 0x57: /* FILE DATE AND TIME */
- switch (EAX & 0xffL)
+ switch (EAX & 0xff)
{
case 0x00:
GetFileDateTime(context);
@@ -1429,10 +1241,10 @@
break;
case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */
- switch (EAX & 0xffL)
+ switch (EAX & 0xff)
{
case 0x00:
- EAX = (EAX & 0xffffff00L) | 0x01L;
+ EAX = (EAX & 0xffffff00) | 0x01L;
break;
case 0x02:
EAX &= 0xff00L;
@@ -1453,24 +1265,24 @@
break;
case 0x5c: /* "FLOCK" - RECORD LOCKING */
- FileLock(context);
+ IntBarf(0x21, context);
break;
case 0x5d: /* NETWORK */
case 0x5e:
/* network software not installed */
- EAX = (EAX & 0xfffff00L) | NoNetwork;
+ EAX = (EAX & 0xfffff00) | NoNetwork;
SetCflag;
break;
case 0x5f: /* NETWORK */
- switch (EAX & 0xffL)
+ switch (EAX & 0xff)
{
case 0x07: /* ENABLE DRIVE */
- if (!DOS_EnableDrive(EDX & 0xffL))
+ if (!DOS_EnableDrive(EDX & 0xff))
{
Error(InvalidDrive, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xfffff00L) | InvalidDrive;
+ EAX = (EAX & 0xfffff00) | InvalidDrive;
SetCflag;
break;
}
@@ -1480,10 +1292,10 @@
break;
}
case 0x08: /* DISABLE DRIVE */
- if (!DOS_DisableDrive(EDX & 0xffL))
+ if (!DOS_DisableDrive(EDX & 0xff))
{
Error(InvalidDrive, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xfffff00L) | InvalidDrive;
+ EAX = (EAX & 0xfffff00) | InvalidDrive;
SetCflag;
break;
}
@@ -1494,26 +1306,27 @@
}
default:
/* network software not installed */
- EAX = (EAX & 0xfffff00L) | NoNetwork;
+ EAX = (EAX & 0xfffff00) | NoNetwork;
SetCflag;
break;
}
break;
case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */
- GetTrueFileName(context);
+ strncpy(pointer(ES,DI), pointer(DS,SI), strlen(pointer(DS,SI)) & 0x7f);
+ ResetCflag;
break;
+ case 0x61: /* UNUSED */
case 0x62: /* GET CURRENT PSP ADDRESS */
- GetCurrentPSP(context);
- break;
-
+ case 0x63: /* UNUSED */
+ case 0x64: /* OS/2 DOS BOX */
case 0x65: /* GET EXTENDED COUNTRY INFORMATION */
- GetExtendedCountryInfo(context);
+ IntBarf(0x21, context);
break;
case 0x66: /* GLOBAL CODE PAGE TABLE */
- switch (EAX & 0xffL)
+ switch (EAX & 0xff)
{
case 0x01:
EBX = CodePage;
@@ -1536,7 +1349,7 @@
break;
case 0x69: /* DISK SERIAL NUMBER */
- switch (EAX & 0xffL)
+ switch (EAX & 0xff)
{
case 0x00:
GetDiskSerialNumber(context);
@@ -1551,9 +1364,8 @@
ResetCflag;
break;
-
default:
- Barf(context);
+ IntBarf(0x21, context);
return 1;
}
}
@@ -1568,3 +1380,19 @@
do_int21((struct sigcontext_struct *) _CONTEXT);
ReturnFromRegisterFunc();
}
+
+void INT21_Init(void)
+{
+ int handle;
+ MDESC *DosHeapDesc;
+
+ if ((handle = GlobalAlloc(GMEM_FIXED,sizeof(struct DosHeap))) == 0)
+ myerror("out of memory");
+
+ heap = (struct DosHeap *) GlobalLock(handle);
+ HEAP_Init(&DosHeapDesc, heap, sizeof(struct DosHeap));
+
+ dta = heap->dta;
+ heap->InDosFlag = 0;
+ strcpy(heap->biosdate, "01/01/80");
+}
diff --git a/miscemu/int2f.c b/miscemu/int2f.c
index 4780766..8c50267 100644
--- a/miscemu/int2f.c
+++ b/miscemu/int2f.c
@@ -3,14 +3,6 @@
#include "msdos.h"
#include "wine.h"
-static void Barf(struct sigcontext_struct *context)
-{
- fprintf(stderr, "int2f: unknown/not implemented parameters:\n");
- fprintf(stderr, "int2f: AX %04x, BX %04x, CX %04x, DX %04x, "
- "SI %04x, DI %04x, DS %04x, ES %04x\n",
- AX, BX, CX, DX, SI, DI, DS, ES);
-}
-
int do_int2f(struct sigcontext_struct *context)
{
switch(context->sc_eax & 0xffff)
@@ -20,7 +12,7 @@
break;
default:
- Barf(context);
+ IntBarf(0x2f, context);
};
return 1;
}
diff --git a/miscemu/int31.c b/miscemu/int31.c
new file mode 100644
index 0000000..eaee326
--- /dev/null
+++ b/miscemu/int31.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "msdos.h"
+#include "wine.h"
+
+int do_int31(struct sigcontext_struct *context)
+{
+ switch((context->sc_eax >> 8) & 0xff)
+ {
+ default:
+ IntBarf(0x31, context);
+ };
+ return 1;
+}
diff --git a/miscemu/ioports.c b/miscemu/ioports.c
index bb2c877..35560a2 100644
--- a/miscemu/ioports.c
+++ b/miscemu/ioports.c
@@ -46,7 +46,7 @@
switch (EDX & 0xffff)
{
case 0x70:
- cmosaddress = EAX & 0xff;
+ cmosaddress = EAX & 0x7f;
break;
case 0x71:
cmosimage[cmosaddress & 0x3f] = EAX & 0xff;
diff --git a/objects/font.c b/objects/font.c
index 07e4d21..5963b96 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -586,6 +586,7 @@
if (lpFaceList[j] == NULL) break;
if (strcmp(lpFaceList[j], lpLogFontList[i]->lfFaceName) == 0) {
i++; j = 0;
+ if (lpLogFontList[i] == NULL) break;
}
}
if (lpLogFontList[i] == NULL) break;
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 9248c32..4f7fa67 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -553,13 +553,3 @@
printf("EnumObjects // End of enumeration !\n");
return 0;
}
-
-/***********************************************************************
- * SetObjectOwner (GDI.461)
- */
-int SetObjectOwner(HANDLE hObj)
-{
- printf("EMPTY STUB !!! SetObjectOwner() (I don't know its prototype !\n");
- return 0;
-}
-
diff --git a/objects/text.c b/objects/text.c
index e7d3cdb..d4448a9 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -62,14 +62,15 @@
return (&str[i]);
}
dest[j++] = str[i++];
- if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
+ if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
+ (format & DT_WORDBREAK))
{
if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
break;
-
+
case PREFIX:
if (!(format & DT_NOPREFIX))
{
@@ -79,7 +80,7 @@
else
{
dest[j++] = str[i++];
- if (!(format & DT_NOCLIP))
+ if (!(format & DT_NOCLIP) || (format & DT_WORDBREAK))
{
if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
return NULL;
@@ -87,7 +88,7 @@
}
}
break;
-
+
case TAB:
if (format & DT_EXPANDTABS)
{
@@ -108,7 +109,8 @@
else
{
dest[j++] = str[i++];
- if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
+ if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
+ (format & DT_WORDBREAK))
{
if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
return NULL;
@@ -119,7 +121,8 @@
case SPACE:
dest[j++] = str[i++];
- if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
+ if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
+ (format & DT_WORDBREAK))
{
wb_i = i;
wb_j = j - 1;
@@ -132,7 +135,8 @@
default:
dest[j++] = str[i++];
- if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
+ if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
+ (format & DT_WORDBREAK))
{
if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
return NULL;
@@ -148,7 +152,7 @@
if (format & DT_WORDBREAK)
{
*len = wb_j;
- *count = wb_count;
+ *count = wb_count - 1;
return (&str[wb_i]);
}
else
@@ -178,6 +182,11 @@
int x = rect->left, y = rect->top;
int width = rect->right - rect->left;
+#ifdef DEBUG_TEXT
+ printf( "DrawText: '%s', %d , [(%d,%d),(%d,%d)]\n", str, count,
+ rect->left, rect->top, rect->right, rect->bottom);
+#endif
+
if (count == -1) count = strlen(str);
strPtr = str;
@@ -423,5 +432,3 @@
return FALSE;
}
-
-
diff --git a/tools/build.c b/tools/build.c
index 85a4b20..096c1d6 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -27,7 +27,8 @@
#define EQUATETYPE_ABS 18
#define TYPE_RETURN 20
-#define MAX_ORDINALS 1024
+/*#define MAX_ORDINALS 1024*/
+#define MAX_ORDINALS 1299
#define PUSH_0 "\tpushl\t$0\n"
#define PUSH_SS "\tpushw\t$0\n\tpushw\t%%ss\n"
diff --git a/windows/mdi.c b/windows/mdi.c
index b2aadff..00c02f1 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -6,6 +6,7 @@
*/
#include <stdlib.h>
#include <stdio.h>
+#include <math.h>
#include "windows.h"
#include "win.h"
#include "mdi.h"
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 45ca0d8..d8fedc0 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -69,7 +69,6 @@
if ((style & WS_CAPTION) == WS_CAPTION)
rect->top -= SYSMETRICS_CYCAPTION - 1;
-
if (menu) rect->top -= SYSMETRICS_CYMENU + 1;
if (style & WS_VSCROLL) rect->right += SYSMETRICS_CXVSCROLL;
@@ -592,15 +591,24 @@
if (wndPtr->wIDmenu != 0 &&
(wndPtr->dwStyle & WS_CHILD) != WS_CHILD) {
- int oldbottom;
- CopyRect(&rect2, &rect);
- /* Default MenuBar height */
- oldbottom = rect2.bottom = rect2.top + SYSMETRICS_CYMENU;
- StdDrawMenuBar(hdc, &rect2, (LPPOPUPMENU)GlobalLock(wndPtr->wIDmenu),
- suppress_menupaint);
- GlobalUnlock(wndPtr->wIDmenu);
- /* Reduce ClientRect according to MenuBar height */
- rect.top += rect2.bottom - oldbottom;
+ LPPOPUPMENU lpMenu = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
+ if (lpMenu != NULL) {
+ int oldHeight;
+ CopyRect(&rect2, &rect);
+ /* Default MenuBar height */
+ if (lpMenu->Height == 0) lpMenu->Height = SYSMETRICS_CYMENU + 1;
+ oldHeight = lpMenu->Height;
+ rect2.bottom = rect2.top + oldHeight;
+/* printf("NC_DoNCPaint // menubar old Height=%d\n", oldHeight); */
+ StdDrawMenuBar(hdc, &rect2, lpMenu, suppress_menupaint);
+ GlobalUnlock(wndPtr->wIDmenu);
+/* printf("NC_DoNCPaint // menubar new Height=%d\n", lpMenu->Height); */
+ if (oldHeight != lpMenu->Height) {
+ /* Reduce ClientRect according to MenuBar height */
+ wndPtr->rectClient.top -= oldHeight;
+ wndPtr->rectClient.top += lpMenu->Height;
+ }
+ }
}
if (wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL)) {
@@ -611,7 +619,7 @@
rect.top, rect.right, bottom);
if (wndPtr->dwStyle & WS_CAPTION) rect.top += SYSMETRICS_CYSIZE;
if (wndPtr->wIDmenu != 0 && (wndPtr->dwStyle & WS_CHILD) != WS_CHILD)
- rect2.top += SYSMETRICS_CYMENU;
+ rect2.top += SYSMETRICS_CYMENU + 1;
StdDrawScrollBar(hwnd, hdc, SB_VERT, &rect2, (LPHEADSCROLL)wndPtr->VScroll);
}
if (wndPtr->dwStyle & WS_HSCROLL) {
diff --git a/windows/utility.c b/windows/utility.c
index a1e0d0e..32f1e59 100644
--- a/windows/utility.c
+++ b/windows/utility.c
@@ -301,10 +301,10 @@
/* skip width/precision */
while (*ptr == '-' || *ptr == '+' || *ptr == '.' ||
- *ptr == ' ' || isdigit(*ptr))
+ *ptr == ' ' || isdigit(*ptr) || *ptr == '#')
ptr++;
- switch (*ptr++) {
+ switch (*ptr) {
case 's':
*(DWORD*)stack_ptr = *(DWORD*)win_stack;
stack_ptr += 4;
diff --git a/windows/win.c b/windows/win.c
index 73b5ac1..1f0a8f7 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -290,6 +290,7 @@
wndPtr = (WND *) USER_HEAP_ADDR( hwnd );
wndPtr->hwndNext = 0;
wndPtr->hwndChild = 0;
+ wndPtr->window = 0;
wndPtr->dwMagic = WND_MAGIC;
wndPtr->hwndParent = (style & WS_CHILD) ? parent : hwndDesktop;
wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : parent;
@@ -312,22 +313,7 @@
wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
wndPtr->dwStyle = style;
wndPtr->dwExStyle = exStyle;
-#ifdef DEBUG_MENU
- printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n",
- menu, instance, classPtr->wc.lpszMenuName);
-#endif
- if ((style & WS_CAPTION) && (style & WS_CHILD) == 0) {
- if (menu != 0)
- SetMenu(hwnd, menu);
- else {
- if (classPtr->wc.lpszMenuName != NULL)
- SetMenu(hwnd, LoadMenu(instance, classPtr->wc.lpszMenuName));
- else
- wndPtr->wIDmenu = 0;
- }
- }
- else
- wndPtr->wIDmenu = menu;
+ wndPtr->wIDmenu = 0;
wndPtr->hText = 0;
wndPtr->flags = 0;
wndPtr->VScroll = NULL;
@@ -390,6 +376,21 @@
CWSaveUnder | CWBackingStore, &win_attr );
XStoreName( display, wndPtr->window, windowName );
+#ifdef DEBUG_MENU
+ printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n",
+ menu, instance, classPtr->wc.lpszMenuName);
+#endif
+ if ((style & WS_CAPTION) && (style & WS_CHILD) == 0) {
+ if (menu != 0)
+ SetMenu(hwnd, menu);
+ else {
+ if (classPtr->wc.lpszMenuName != NULL)
+ SetMenu(hwnd, LoadMenu(instance, classPtr->wc.lpszMenuName));
+ }
+ }
+ else
+ wndPtr->wIDmenu = menu;
+
/* Send the WM_CREATE message */
hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) );
diff --git a/windows/winpos.c b/windows/winpos.c
index 98cfa11..a9fe9a6 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -604,8 +604,8 @@
wndPtr->dwStyle |= WS_VISIBLE;
XMapWindow( display, wndPtr->window );
MSG_Synchronize();
- if (winPos->flags & SWP_NOREDRAW)
- RedrawWindow( hwnd, NULL, 0, RDW_VALIDATE );
+/* if (winPos->flags & SWP_NOREDRAW)
+ RedrawWindow( hwnd, NULL, 0, RDW_VALIDATE ); */
}
else if (winPos->flags & SWP_HIDEWINDOW)
{
@@ -639,6 +639,10 @@
(!(winPos->flags & SWP_NOACTIVATE)) ||
(!(winPos->flags & SWP_NOZORDER)))
SendMessage( hwnd, WM_NCPAINT, 1, 0L );
+ if ((winPos->flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) &&
+ (!(winPos->flags & SWP_NOREDRAW)) &&
+ (wndPtr->dwStyle & WS_VISIBLE) && IsWindowVisible(hwnd))
+ InvalidateRect(hwnd, NULL, TRUE);
/* Finally send the WM_WINDOWPOSCHANGED message */
wndPtr->rectWindow = newWindowRect;