Commit 808cb043 authored by Alexandre Julliard's avatar Alexandre Julliard

Release 950817

Thu Aug 17 19:30:14 1995 Alexandre Julliard <julliard@sunsite.unc.edu> * [*/Makefile.in] Removed winelibclean target, as it doesn't work anyway. * [controls/button.c] Avoid drawing the focus rectangle outside of the button. * [controls/widgets.c] Fixed bug with the size of the reserved bytes for the Edit control (caused Eudora to crash). * [debugger/*] [include/debugger.h] Unified debugger address handling. Segmented and linear addresses are no grouped in a single type DBG_ADDR. All commands now accept seg:off addresses. Module entry points are now loaded upon first entry to the debugger, so that entry points of the loaded executable also appear in the symbol table. * [include/registers.h] [miscemu/*.c] Register macros are now of the form 'AX_reg(context)' instead of 'AX'. This makes code less readable, but will prevent a lot of name clashes with other definitions. It also avoids a hidden reference to the 'context' variable. * [ipc/dde_atom.c] [misc/atom.c] All *AddAtom and *FindAtom functions now take a SEGPTR parameter, to allow supporting integer atoms. Moved atom.c to memory/ directory. * [loader/task.c] Fixed environment allocation to compute the size dynamically. Added 'windir' environment variable. Fixed GetDOSEnvironment() to return the current task environment. * [windows/message.c] Fixed bug in MSG_GetWindowForEvent(). Wed Aug 9 11:40:43 1995 Marcus Meissner <msmeissn@faui01.informatik.uni-erlangen.de> * [include/ole.h] Added a lot of structures from my Borland Manual. Neither complete, nor 100% right (check please) * [misc/shell.c] Fixed some of the Reg* functions. Enhanced ShellExecute. Please test: wine "regedit.exe /v" mplayer.exe soundrec.exe Do YOU know the format of \WINDOWS\REG.DAT? Mail me please :) * [misc/dos_fs.c] Make umsdos mounted windows dirs work again. * [miscemu/emulate.c] Added some comments, preimplementation of subfunction 7. * [multimedia/mmsystem.c] Implemented mciSendString. not complete, not clean, not necessarily working (only checked with a program which uses 'cdaudio' (one working program is cool.exe, a shareware waveditor with cdaudio play facilities.) * [multimedia/mcicda.c] Segptr fixes in DriverProc Default cdrom drive in Linux is /dev/cdrom ... usually a symbolic link to your real cdrom device. Tue Aug 8 19:41:50 CDT 1995 Daniel Schepler <dks2@cec.wustl.edu> * [loader/resource.c] Don't crash in a LoadString to NULL * [loader/resource.c] Fixed accelerators to work with modifiers. (ALT-x modifiers still won't work unless the ALT keypress exited the menu.) * [misc/file.c] Expand a file to the current offset with an _lwrite of size zero. * [misc/file.c] Set a newly created file to read-write instead of write-only. Sun Aug 6 20:28:35 1995 Anand Kumria <akumria@ozemail.com.au> * [misc/main.c] [include/msdos.h] Fixed to return DOS version 6.22, and the correct byte order for Windows programs. Wed Aug 2 12:36:33 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [include/options.h] [memory/global.c] [misc/main.c] Make the new IPC run-time selectible, disabling it by default. (I think it's only useful for libwine, anyway.) * [loader/task.c] [memory/selector.c] In FreeSelector(), walk up the stack and fix the frames. * [objects/dib.c] Missing break statement in DIB_SetImageBits_RLE8(). In GetDIBits(), set the compression flag in the bitmap info to zero. * [windows/dialog.c] GetNextDlgGroupItem() needs to treat the first child as if it had an implicit WS_GROUP bit set. Mon Jul 31 15:44:47 EDT 1995 Louis-D. Dubeau <ldd@step.polymtl.ca> * [misc/dos_fs.c] Quick'n dirty fix for the initialisation of the Z: information structure.
parent e2991ea7
This is release 950727 of Wine the MS Windows emulator. This is still a
This is release 950817 of Wine the MS Windows emulator. This is still a
developer's only release. There are many bugs and many unimplemented API
features. Most applications still do not work.
Patches should be submitted to "wine-new@amscons.com". Please don't forget
to include a ChangeLog entry. I'll make a new release every other Sunday.
WHAT'S NEW with Wine-950727: (see ChangeLog for details)
- New configuration scheme based on autoconf (please test it).
- DDE communication between separate Wine processes.
- Lots of file handling fixes.
- Fixes to built-in WINSOCK.DLL.
WHAT'S NEW with Wine-950817: (see ChangeLog for details)
- Built-in debugger improvements.
- Multimedia fixes.
- IPC can be disabled at run-time.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
......@@ -18,11 +17,11 @@ Because of lags created by using mirror, this message may reach you before
the release is available at the ftp sites. The sources will be available
from the following locations:
sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950727.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950727.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950727.tar.gz
ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950727.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-950727.tar.gz
sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950817.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950817.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950817.tar.gz
ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950817.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-950817.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
......
----------------------------------------------------------------------
Thu Aug 17 19:30:14 1995 Alexandre Julliard <julliard@sunsite.unc.edu>
* [*/Makefile.in]
Removed winelibclean target, as it doesn't work anyway.
* [controls/button.c]
Avoid drawing the focus rectangle outside of the button.
* [controls/widgets.c]
Fixed bug with the size of the reserved bytes for the Edit
control (caused Eudora to crash).
* [debugger/*] [include/debugger.h]
Unified debugger address handling. Segmented and linear addresses
are no grouped in a single type DBG_ADDR.
All commands now accept seg:off addresses.
Module entry points are now loaded upon first entry to the
debugger, so that entry points of the loaded executable also
appear in the symbol table.
* [include/registers.h] [miscemu/*.c]
Register macros are now of the form 'AX_reg(context)' instead of 'AX'.
This makes code less readable, but will prevent a lot of name
clashes with other definitions. It also avoids a hidden reference
to the 'context' variable.
* [ipc/dde_atom.c] [misc/atom.c]
All *AddAtom and *FindAtom functions now take a SEGPTR parameter,
to allow supporting integer atoms.
Moved atom.c to memory/ directory.
* [loader/task.c]
Fixed environment allocation to compute the size dynamically.
Added 'windir' environment variable.
Fixed GetDOSEnvironment() to return the current task environment.
* [windows/message.c]
Fixed bug in MSG_GetWindowForEvent().
Wed Aug 9 11:40:43 1995 Marcus Meissner <msmeissn@faui01.informatik.uni-erlangen.de>
* [include/ole.h]
Added a lot of structures from my Borland Manual. Neither complete,
nor 100% right (check please)
* [misc/shell.c]
Fixed some of the Reg* functions.
Enhanced ShellExecute.
Please test: wine "regedit.exe /v" mplayer.exe soundrec.exe
Do YOU know the format of \WINDOWS\REG.DAT? Mail me please :)
* [misc/dos_fs.c]
Make umsdos mounted windows dirs work again.
* [miscemu/emulate.c]
Added some comments, preimplementation of subfunction 7.
* [multimedia/mmsystem.c]
Implemented mciSendString. not complete, not clean, not
necessarily working (only checked with a program which uses
'cdaudio' (one working program is cool.exe, a shareware waveditor
with cdaudio play facilities.)
* [multimedia/mcicda.c]
Segptr fixes in DriverProc
Default cdrom drive in Linux is /dev/cdrom ... usually a symbolic
link to your real cdrom device.
Tue Aug 8 19:41:50 CDT 1995 Daniel Schepler <dks2@cec.wustl.edu>
* [loader/resource.c]
Don't crash in a LoadString to NULL
* [loader/resource.c]
Fixed accelerators to work with modifiers. (ALT-x modifiers still
won't work unless the ALT keypress exited the menu.)
* [misc/file.c]
Expand a file to the current offset with an _lwrite of size zero.
* [misc/file.c]
Set a newly created file to read-write instead of write-only.
Sun Aug 6 20:28:35 1995 Anand Kumria <akumria@ozemail.com.au>
* [misc/main.c] [include/msdos.h]
Fixed to return DOS version 6.22, and the correct byte order
for Windows programs.
Wed Aug 2 12:36:33 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* [include/options.h] [memory/global.c] [misc/main.c]
Make the new IPC run-time selectible, disabling it by default.
(I think it's only useful for libwine, anyway.)
* [loader/task.c] [memory/selector.c]
In FreeSelector(), walk up the stack and fix the frames.
* [objects/dib.c]
Missing break statement in DIB_SetImageBits_RLE8().
In GetDIBits(), set the compression flag in the bitmap info to zero.
* [windows/dialog.c]
GetNextDlgGroupItem() needs to treat the first child as if it had
an implicit WS_GROUP bit set.
Mon Jul 31 15:44:47 EDT 1995 Louis-D. Dubeau <ldd@step.polymtl.ca>
* [misc/dos_fs.c]
Quick'n dirty fix for the initialisation of the Z: information
structure.
----------------------------------------------------------------------
Sat Jul 22 22:39:09 IDT 1995 Michael Veksler <e1678223@tochnapc2.technion.ac.il>
* [ipc/*]
......@@ -48,7 +161,7 @@ Sun Jul 16 18:17:17 1995 Gregory Trubetskoy <grisha@mira.com>
Added LoadIconHandler. It doesn't do anything yet, but now you
can use borland help files with winhelp.exe.
Sun Jul 16 11:58:45 1996 Anand Kumria <akumria@ozemail.com.au>
Sun Jul 16 11:58:45 1995 Anand Kumria <akumria@ozemail.com.au>
* [misc/main.c]
Fixed to return 386 Enhanced mode correctly. Also return the same
......
......@@ -5,8 +5,6 @@
# distclean: also remove all files created by configure
# countryclean: remove all files which have to be remade if
# a different LANGuage is selected
# winelibclean: remove all files which differ for the emulator
# and the library
# depend: create the dependencies
#
# Author: Michael Patra <micky@marie.physik.tu-berlin.de>
......@@ -41,47 +39,41 @@ EMUOBJS = debugger/debugger.o if1632/if1632.o memory/memory.o miscemu/miscemu.o
LIBOBJS = toolkit/toolkit.o
SUBDIRS = $(COMMONSUBDIRS) $(EMUSUBDIRS)
OBJS = $(COMMONOBJS) $(EMUOBJS)
all:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)' 'LANG=$(LANG)'); \
done
$(CC) -o wine $(OBJS) $(LDOPTIONS) $(XDIR) $(XPM_LIB) $(XLIB) $(LDLIBS)
all: wine wine.sym
wine.sym: wine
nm wine | grep -v _compiled | sort >wine.sym
wine: $(SUBDIRS) dummy
$(CC) -o wine $(OBJS) $(LDOPTIONS) $(XDIR) $(XPM_LIB) $(XLIB) $(LDLIBS)
$(SUBDIRS): dummy
@cd $@; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)' 'LANG=$(LANG)'
depend:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) depend); \
done
for i in $(SUBDIRS); do (cd $$i; $(MAKE) depend); done
etags:
etags `find . -name '*.[chS]' -print`
clean:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) clean); \
done
rm -f *.o \#*\# *~ wine wine.sym
for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done
rm -f *.o \#*\# *~ wine wine.sym TAGS
distclean:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) distclean); \
done
for i in $(SUBDIRS); do (cd $$i; $(MAKE) distclean); done
echo "/* autoconf.h generated automatically. Run Configure */" >autoconf.h
echo "#error You must run Configure before you can build the makefiles." >>autoconf.h
rm -f *.o \#*\# *~ wine wine.sym
rm -f stamp-config config.* include/config.h Makefile
countryclean:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) countryclean); \
done
for i in $(SUBDIRS); do (cd $$i; $(MAKE) countryclean); done
rm -f wine wine.sym
winelibclean:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) winelibclean); \
done
dummy:
......@@ -32,7 +32,6 @@ AC_SUBST(LDCOMBINEFLAGS)
AC_CHECK_FUNCS(tcgetattr)
AC_CHECK_HEADERS(stdlib.h)
AC_HEADER_DIRENT()
AC_HEADER_STAT()
AC_C_CONST()
AC_TYPE_SIZE_T()
......
......@@ -24,26 +24,16 @@ $(MODULE).o: $(OBJS)
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -313,14 +313,15 @@ static void PB_Paint( HWND hButton, HDC hDC, WORD action )
/* do we have the focus? */
if (infoPtr->state & BUTTON_HASFOCUS)
{
dwTextSize = GetTextExtent(hDC, text, strlen(text) );
delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
rc.left += delta;
rc.right -= delta;
GetTextMetrics(hDC, &tm);
delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
rc.top += delta; rc.bottom -= delta;
DrawFocusRect(hDC, &rc);
short xdelta, ydelta;
dwTextSize = GetTextExtent( hDC, text, strlen(text) );
GetTextMetrics( hDC, &tm );
xdelta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) / 2;
ydelta = ((rc.bottom - rc.top) - tm.tmHeight - 1) / 2;
if (xdelta < 0) xdelta = 0;
if (ydelta < 0) ydelta = 0;
InflateRect( &rc, -xdelta, -ydelta );
DrawFocusRect( hDC, &rc );
}
}
......@@ -378,10 +379,13 @@ static void CB_Paint( HWND hWnd, HDC hDC, WORD action )
((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS)))
{
GetTextExtentPoint(hDC, text, textlen, &size);
rc.top += delta - 1;
rc.bottom -= delta + 1;
if (delta > 1)
{
rc.top += delta - 1;
rc.bottom -= delta + 1;
}
rc.left--;
rc.right = rc.left + size.cx + 2;
rc.right = min( rc.left + size.cx + 2, rc.right );
DrawFocusRect(hDC, &rc);
}
}
......
......@@ -105,6 +105,8 @@ static LONG CBCreate(HWND hwnd, WORD wParam, LONG lParam)
LONG style = 0;
LONG cstyle = GetWindowLong(hwnd,GWL_STYLE);
RECT rect,lboxrect;
char className[] = "COMBOLBOX"; /* Hack so that class names are > 0x10000 */
char editName[] = "EDIT";
/* translate combo into listbox styles */
if (cstyle & CBS_OWNERDRAWFIXED) style |= LBS_OWNERDRAWFIXED;
......@@ -125,7 +127,7 @@ static LONG CBCreate(HWND hwnd, WORD wParam, LONG lParam)
dprintf_combo(stddeb,"CBS_SIMPLE\n");
SetRectEmpty(&lphc->RectButton);
lphc->LBoxTop = lphl->StdItemHeight;
lphc->hWndEdit = CreateWindow("EDIT", "",
lphc->hWndEdit = CreateWindow(editName, "",
WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
0, 0, rect.right, lphl->StdItemHeight,
hwnd, 1, GetWindowWord(hwnd,GWW_HINSTANCE), 0L);
......@@ -139,7 +141,7 @@ static LONG CBCreate(HWND hwnd, WORD wParam, LONG lParam)
SetWindowPos(hwnd, 0, 0, 0, rect.right - rect.left + 2*SYSMETRICS_CXBORDER,
lphl->StdItemHeight + 2*SYSMETRICS_CYBORDER,
SWP_NOMOVE | SWP_NOZORDER);
lphc->hWndEdit = CreateWindow("EDIT", "",
lphc->hWndEdit = CreateWindow(editName, "",
WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
0, 0, lphc->RectButton.left, lphl->StdItemHeight,
hwnd, 1, GetWindowWord(hwnd,GWW_HINSTANCE), 0L);
......@@ -159,7 +161,7 @@ static LONG CBCreate(HWND hwnd, WORD wParam, LONG lParam)
/* FIXME: WinSight says these should be CHILD windows with the TOPMOST flag
* set. Wine doesn't support TOPMOST, and simply setting the WS_CHILD
* flag doesn't work. */
lphc->hWndLBox = CreateWindow("COMBOLBOX", "",
lphc->hWndLBox = CreateWindow(className, "",
WS_POPUP | WS_BORDER | WS_VSCROLL,
lboxrect.left, lboxrect.top,
lboxrect.right - lboxrect.left,
......
......@@ -14,6 +14,7 @@
#include "local.h"
#include "win.h"
#include "class.h"
#include "stackframe.h" /* for MAKE_SEGPTR */
#include "user.h"
#include "stddebug.h"
#include "debug.h"
......@@ -2303,8 +2304,11 @@ static long EDIT_WM_Create(HWND hwnd, LONG lParam)
es->BlankLine[(es->ClientWidth / es->CharWidths[32]) + 1] = 0;
/* set up text cursor for edit class */
CLASS_FindClassByName("EDIT", 0, &classPtr);
classPtr->wc.hCursor = LoadCursor(0, IDC_IBEAM);
{
char editname[] = "EDIT";
CLASS_FindClassByName( MAKE_SEGPTR(editname), 0, &classPtr);
classPtr->wc.hCursor = LoadCursor(0, IDC_IBEAM);
}
/* paint background on first WM_PAINT */
es->PaintBkgd = TRUE;
......
......@@ -673,7 +673,7 @@ static BOOL MENU_ShowPopup(HWND hwndOwner, HMENU hmenu, WORD id, int x, int y)
{
WND *wndPtr = WIN_FindWndPtr( hwndOwner );
if (!wndPtr) return FALSE;
menu->hWnd = CreateWindow( POPUPMENU_CLASS_NAME, "",
menu->hWnd = CreateWindow( (LPSTR)POPUPMENU_CLASS_ATOM, "",
WS_POPUP | WS_BORDER, x, y,
menu->Width + 2*SYSMETRICS_CXBORDER,
menu->Height + 2*SYSMETRICS_CYBORDER,
......
......@@ -15,31 +15,30 @@
#include "selectors.h"
#include "stackframe.h"
static WNDCLASS WIDGETS_BuiltinClasses[] =
{
{ CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ButtonWndProc", 0,
sizeof(BUTTONINFO), 0, 0, 0, 0, NULL, "BUTTON" },
sizeof(BUTTONINFO), 0, 0, 0, 0, 0, (SEGPTR)"BUTTON" },
{ CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"StaticWndProc", 0,
sizeof(STATICINFO), 0, 0, 0, 0, NULL, "STATIC" },
sizeof(STATICINFO), 0, 0, 0, 0, 0, (SEGPTR)"STATIC" },
{ CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ScrollBarWndProc", 0,
sizeof(SCROLLINFO), 0, 0, 0, 0, NULL, "SCROLLBAR" },
sizeof(SCROLLINFO), 0, 0, 0, 0, 0, (SEGPTR)"SCROLLBAR" },
{ CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ListBoxWndProc", 0,
8, 0, 0, 0, 0, NULL, "LISTBOX" },
{ CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ComboBoxWndProc", 0,
8, 0, 0, 0, 0, NULL, "COMBOBOX" },
{ CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ComboLBoxWndProc", 0,
8, 0, 0, 0, 0, NULL, "COMBOLBOX" },
{ CS_GLOBALCLASS, (WNDPROC)"EditWndProc", 0,
sizeof(WORD), 0, 0, 0, 0, NULL, "EDIT" },
{ CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"PopupMenuWndProc", 0,
8, 0, 0, 0, 0, NULL, POPUPMENU_CLASS_NAME },
{ CS_GLOBALCLASS, (WNDPROC)"DesktopWndProc", 0,
sizeof(DESKTOPINFO), 0, 0, 0, 0, NULL, DESKTOP_CLASS_NAME },
{ CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"DefDlgProc", 0,
DLGWINDOWEXTRA, 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME },
{ CS_GLOBALCLASS, (WNDPROC)"MDIClientWndProc", 0,
sizeof(MDICLIENTINFO), 0, 0, 0, STOCK_LTGRAY_BRUSH, NULL, "MDICLIENT" }
8, 0, 0, 0, 0, 0, (SEGPTR)"LISTBOX" },
{ CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ComboBoxWndProc", 0, 8,
0, 0, 0, 0, 0, (SEGPTR)"COMBOBOX" },
{ CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ComboLBoxWndProc",
0, 8, 0, 0, 0, 0, 0, (SEGPTR)"COMBOLBOX" },
{ CS_GLOBALCLASS, (WNDPROC)"EditWndProc", 0, sizeof(DWORD),
0, 0, 0, 0, 0, (SEGPTR)"EDIT" },
{ CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"PopupMenuWndProc", 0, 8,
0, 0, 0, 0, 0, (SEGPTR)POPUPMENU_CLASS_NAME },
{ CS_GLOBALCLASS, (WNDPROC)"DesktopWndProc", 0, sizeof(DESKTOPINFO),
0, 0, 0, 0, 0, (SEGPTR)DESKTOP_CLASS_NAME },
{ CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"DefDlgProc", 0, DLGWINDOWEXTRA,
0, 0, 0, 0, 0, (SEGPTR)DIALOG_CLASS_NAME },
{ CS_GLOBALCLASS, (WNDPROC)"MDIClientWndProc", 0, sizeof(MDICLIENTINFO),
0, 0, 0, STOCK_LTGRAY_BRUSH, 0, (SEGPTR)"MDICLIENT" }
};
#define NB_BUILTIN_CLASSES \
......@@ -59,8 +58,8 @@ BOOL WIDGETS_Init(void)
for (i = 0; i < NB_BUILTIN_CLASSES; i++, class++)
{
strcpy( name, class->lpszClassName );
class->lpszClassName = (LPSTR)MAKE_SEGPTR(name);
strcpy( name, (char *)class->lpszClassName );
class->lpszClassName = MAKE_SEGPTR(name);
class->hCursor = LoadCursor( 0, IDC_ARROW );
class->lpfnWndProc = GetWndProcEntry16( (char *)class->lpfnWndProc );
if (!RegisterClass( class )) return FALSE;
......
......@@ -17,6 +17,7 @@ SRCS = \
hash.c \
info.c \
lex.yy.c \
memory.c \
registers.c \
stack.c
......
......@@ -13,53 +13,42 @@ LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
MODULE = debugger
SRCS = break.c db_disasm.c hash.c info.c registers.c stack.c
SRCS = break.c db_disasm.c hash.c info.c memory.c registers.c stack.c
OBJS = $(SRCS:.c=.o) dbg.tab.o lex.yy.o
all: $(MODULE).o dbg.tab.o lex.yy.o
dbg.tab.c: dbg.y
dbg.tab.c dbg.tab.h: dbg.y
$(BISON) -b dbg -d dbg.y
dbg.tab.h: dbg.y
$(BISON) -b dbg -d dbg.y
lex.yy.c: debug.l dbg.tab.h dbg.tab.h
lex.yy.c: debug.l dbg.tab.h
$(FLEX) -8 -I debug.l
.c.o:
$(COMPILE) -c -o $*.o $<
$(MODULE).o: $(OBJS)
(cd readline; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
$(MODULE).o: $(OBJS) readline
$(LD) $(LDCOMBINEFLAGS) $(OBJS) readline/readline.o -o $(MODULE).o
readline: dummy
cd readline; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)'
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
(cd readline; $(MAKE) clean)
rm -f *.o \#*\# *~ dbg.tab.c dbg.tab.h lex.yy.c y.tab.c y.tab.h tmp_make
distclean: clean
distclean:
(cd readline; $(MAKE) distclean)
rm Makefile
rm -f *.o \#*\# *~ dbg.tab.c dbg.tab.h lex.yy.c y.tab.c y.tab.h tmp_make Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dbg.tab.o: dbg.tab.c
lex.yy.o: lex.yy.c
......
......@@ -8,9 +8,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#ifdef linux
#include <sys/utsname.h>
#endif
#include "windows.h"
#include "debugger.h"
......@@ -21,15 +18,14 @@
typedef struct
{
unsigned int segment;
unsigned int addr;
BYTE addrlen;
BYTE opcode;
BOOL enabled;
BOOL in_use;
DBG_ADDR addr;
BYTE addrlen;
BYTE opcode;
BOOL enabled;
BOOL in_use;
} BREAKPOINT;
static BREAKPOINT breakpoints[MAX_BREAKPOINTS] = { { 0, }, };
static BREAKPOINT breakpoints[MAX_BREAKPOINTS];
static int next_bp = 1; /* breakpoint 0 is reserved for step-over */
......@@ -39,11 +35,11 @@ static int next_bp = 1; /* breakpoint 0 is reserved for step-over */
*
* Change the opcode at segment:addr.
*/
static void DEBUG_SetOpcode( unsigned int segment, unsigned int addr, BYTE op )
static void DEBUG_SetOpcode( const DBG_ADDR *addr, BYTE op )
{
if (segment)
if (addr->seg)
{
*(BYTE *)PTR_SEG_OFF_TO_LIN( segment, addr ) = op;
*(BYTE *)PTR_SEG_OFF_TO_LIN( addr->seg, addr->off ) = op;
}
else /* 32-bit code, so we have to change the protection first */
{
......@@ -56,14 +52,15 @@ static void DEBUG_SetOpcode( unsigned int segment, unsigned int addr, BYTE op )
Not that portability matters, this code is i386 only anyways...
How do I get the old protection in order to restore it later on?
*/
if (mprotect((caddr_t)(addr & (~4095)), 4096,
PROT_READ|PROT_WRITE|PROT_EXEC) == -1)
if (mprotect((caddr_t)(addr->off & (~4095)), 4096,
PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
{
perror( "Can't set break point" );
return;
}
*(BYTE *)addr = op;
mprotect((caddr_t)(addr & ~4095), 4096, PROT_READ|PROT_EXEC);
*(BYTE *)addr->off = op;
mprotect((caddr_t)(addr->off & ~4095), 4096,
PROT_READ | PROT_EXEC );
}
}
......@@ -80,7 +77,7 @@ void DEBUG_SetBreakpoints( BOOL set )
for (i = 0; i < MAX_BREAKPOINTS; i++)
{
if (breakpoints[i].in_use && breakpoints[i].enabled)
DEBUG_SetOpcode( breakpoints[i].segment, breakpoints[i].addr,
DEBUG_SetOpcode( &breakpoints[i].addr,
set ? INT3 : breakpoints[i].opcode );
}
}
......@@ -92,15 +89,15 @@ void DEBUG_SetBreakpoints( BOOL set )
* Find the breakpoint for a given address. Return the breakpoint
* number or -1 if none.
*/
int DEBUG_FindBreakpoint( unsigned int segment, unsigned int addr )
int DEBUG_FindBreakpoint( const DBG_ADDR *addr )
{
int i;
for (i = 0; i < MAX_BREAKPOINTS; i++)
{
if (breakpoints[i].in_use && breakpoints[i].enabled &&
breakpoints[i].segment == segment && breakpoints[i].addr == addr)
return i;
breakpoints[i].addr.seg == addr->seg &&
breakpoints[i].addr.off == addr->off) return i;
}
return -1;
}
......@@ -111,13 +108,13 @@ int DEBUG_FindBreakpoint( unsigned int segment, unsigned int addr )
*
* Add a breakpoint.
*/
void DEBUG_AddBreakpoint( unsigned int segment, unsigned int addr )
void DEBUG_AddBreakpoint( const DBG_ADDR *address )
{
DBG_ADDR addr = *address;
int num;
BYTE *p;
if (segment == 0xffffffff) segment = CS;
if (segment == WINE_CODE_SELECTOR) segment = 0;
DBG_FIX_ADDR_SEG( &addr, CS_reg(DEBUG_context) );
if (next_bp < MAX_BREAKPOINTS)
num = next_bp++;
......@@ -131,16 +128,15 @@ void DEBUG_AddBreakpoint( unsigned int segment, unsigned int addr )
return;
}
}
p = segment ? (BYTE *)PTR_SEG_OFF_TO_LIN( segment, addr ) : (BYTE *)addr;
breakpoints[num].segment = segment;
p = DBG_ADDR_TO_LIN( &addr );
breakpoints[num].addr = addr;
breakpoints[num].addrlen = !segment ? 32 :
(GET_SEL_FLAGS(segment) & LDT_FLAGS_32BIT) ? 32 : 16;
breakpoints[num].addrlen = !addr.seg ? 32 :
(GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
breakpoints[num].opcode = *p;
breakpoints[num].enabled = TRUE;
breakpoints[num].in_use = TRUE;
fprintf( stderr, "Breakpoint %d at ", num );
print_address( segment, addr, breakpoints[num].addrlen );
DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen );
fprintf( stderr, "\n" );
}
......@@ -193,8 +189,7 @@ void DEBUG_InfoBreakpoints(void)
if (breakpoints[i].in_use)
{
fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
print_address( breakpoints[i].segment, breakpoints[i].addr,
breakpoints[i].addrlen );
DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen );
fprintf( stderr, "\n" );
}
}
......@@ -210,22 +205,24 @@ void DEBUG_InfoBreakpoints(void)
BOOL DEBUG_ShouldContinue( struct sigcontext_struct *context,
enum exec_mode mode )
{
unsigned int segment, addr;
DBG_ADDR addr;
int bpnum;
/* If not single-stepping, back up over the int3 instruction */
if (!(EFL & STEP_FLAG)) EIP--;
if (!(EFL_reg(DEBUG_context) & STEP_FLAG)) EIP_reg(DEBUG_context)--;
segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
addr = EIP;
bpnum = DEBUG_FindBreakpoint( segment, addr );
addr.seg = (CS_reg(DEBUG_context) == WINE_CODE_SELECTOR) ?
0 : CS_reg(DEBUG_context);
addr.off = EIP_reg(DEBUG_context);
bpnum = DEBUG_FindBreakpoint( &addr );
breakpoints[0].enabled = 0; /* disable the step-over breakpoint */
if ((bpnum != 0) && (bpnum != -1))
{
fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
print_address( breakpoints[bpnum].segment, breakpoints[bpnum].addr,
breakpoints[bpnum].addrlen );
DEBUG_PrintAddress( &breakpoints[bpnum].addr,
breakpoints[bpnum].addrlen );
fprintf( stderr, "\n" );
return FALSE;
}
......@@ -243,34 +240,34 @@ BOOL DEBUG_ShouldContinue( struct sigcontext_struct *context,
void DEBUG_RestartExecution( struct sigcontext_struct *context,
enum exec_mode mode, int instr_len )
{
unsigned int segment, addr;
DBG_ADDR addr;
segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
addr = EIP;
addr.seg = (CS_reg(DEBUG_context) == WINE_CODE_SELECTOR) ?
0 : CS_reg(DEBUG_context);
addr.off = EIP_reg(DEBUG_context);
if (DEBUG_FindBreakpoint( segment, addr ) != -1)
if (DEBUG_FindBreakpoint( &addr ) != -1)
mode = EXEC_STEP_INSTR; /* If there's a breakpoint, skip it */
switch(mode)
{
case EXEC_CONT: /* Continuous execution */
EFL &= ~STEP_FLAG;
EFL_reg(DEBUG_context) &= ~STEP_FLAG;
DEBUG_SetBreakpoints( TRUE );
break;
case EXEC_STEP_OVER: /* Stepping over a call */
EFL &= ~STEP_FLAG;
breakpoints[0].segment = segment;
breakpoints[0].addr = addr + instr_len;
EFL_reg(DEBUG_context) &= ~STEP_FLAG;
addr.off += instr_len;
breakpoints[0].addr = addr;
breakpoints[0].enabled = TRUE;
breakpoints[0].in_use = TRUE;
breakpoints[0].opcode = segment ?
*(BYTE *)PTR_SEG_OFF_TO_LIN(segment,addr+instr_len) : *(BYTE *)addr;
breakpoints[0].opcode = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
DEBUG_SetBreakpoints( TRUE );
break;
case EXEC_STEP_INSTR: /* Single-stepping an instruction */
EFL |= STEP_FLAG;
EFL_reg(DEBUG_context) |= STEP_FLAG;
break;
}
}
......@@ -64,7 +64,7 @@
#include <stdio.h>
#include "windows.h"
#include "ldt.h"
#include "debugger.h"
/*
* Switch to disassemble 16-bit code.
......@@ -881,52 +881,46 @@ static int db_lengths[] = {
10, /* EXTR */
};
static unsigned int db_get_task_value( unsigned int segment, unsigned int loc,
int size, int is_signed)
static unsigned int db_get_task_value( const DBG_ADDR *addr,
int size, int is_signed )
{
unsigned int result;
if (segment) loc = (unsigned int)PTR_SEG_OFF_TO_LIN( segment, loc );
switch(size)
unsigned int result;
unsigned char *p = DBG_ADDR_TO_LIN( addr );
switch(size)
{
case 4:
if (is_signed)
result = (unsigned int) *((int *) loc);
else
result = (unsigned int) *((unsigned int *) loc);
break;
if (is_signed) result = (unsigned int) *(int *)p;
else result = *(unsigned int *)p;
break;
case 2:
if (is_signed)
result = (unsigned int) *((short int *) loc);
else
result = *((unsigned short int *) loc);
break;
if (is_signed) result = (unsigned int) *(short int *)p;
else result = *(unsigned short int *)p;
break;
case 1:
if (is_signed)
result = (unsigned int) *((char *) loc);
else
result = *((unsigned char *) loc);
break;
if (is_signed) result = (unsigned int) *(char *)p;
else result = *(unsigned char *)p;
break;
default:
fprintf(stderr, "Illegal size specified\n");
result = 0;
break;
fprintf(stderr, "Illegal size specified\n");
result = 0;
break;
}
return result;
return result;
}
#define get_value_inc(result, segment, loc, size, is_signed) \
result = db_get_task_value((segment), (loc), (size), (is_signed)); \
if (!db_disasm_16) (loc) += (size); \
else (loc) = ((loc) & 0xffff0000) | (((loc) + (size)) & 0xffff);
#define get_value_inc(result, addr, size, is_signed) \
result = db_get_task_value((addr), (size), (is_signed)); \
if (!db_disasm_16) (addr)->off += (size); \
else (addr)->off = ((addr)->off + (size)) & 0xffff;
/*
* Read address at location and return updated location.
*/
unsigned int db_read_address( unsigned int segment, unsigned int loc,
int short_addr, int regmodrm,
struct i_addr *addrp )
void db_read_address( DBG_ADDR *addr, int short_addr, int regmodrm,
struct i_addr *addrp )
{
int mod, rm, sib, index, disp;
int mod, rm, sib, index, disp;
mod = f_mod(regmodrm);
rm = f_rm(regmodrm);
......@@ -934,7 +928,7 @@ unsigned int db_read_address( unsigned int segment, unsigned int loc,
if (mod == 3) {
addrp->is_reg = TRUE;
addrp->disp = rm;
return (loc);
return;
}
addrp->is_reg = FALSE;
addrp->index = 0;
......@@ -945,7 +939,7 @@ unsigned int db_read_address( unsigned int segment, unsigned int loc,
switch (mod) {
case 0:
if (rm == 6) {
get_value_inc(disp, segment, loc, 2, TRUE);
get_value_inc(disp, addr, 2, TRUE);
addrp->disp = disp;
addrp->base = 0;
}
......@@ -955,12 +949,12 @@ unsigned int db_read_address( unsigned int segment, unsigned int loc,
}
break;
case 1:
get_value_inc(disp, segment, loc, 1, TRUE);
get_value_inc(disp, addr, 1, TRUE);
addrp->disp = disp;
addrp->base = db_index_reg_16[rm];
break;
case 2:
get_value_inc(disp, segment, loc, 2, TRUE);
get_value_inc(disp, addr, 2, TRUE);
addrp->disp = disp;
addrp->base = db_index_reg_16[rm];
break;
......@@ -968,7 +962,7 @@ unsigned int db_read_address( unsigned int segment, unsigned int loc,
}
else {
if (mod != 3 && rm == 4) {
get_value_inc(sib, segment, loc, 1, FALSE);
get_value_inc(sib, addr, 1, FALSE);
rm = sib_base(sib);
index = sib_index(sib);
if (index != 4)
......@@ -979,7 +973,7 @@ unsigned int db_read_address( unsigned int segment, unsigned int loc,
switch (mod) {
case 0:
if (rm == 5) {
get_value_inc(addrp->disp, segment, loc, 4, FALSE);
get_value_inc(addrp->disp, addr, 4, FALSE);
addrp->base = 0;
}
else {
......@@ -989,19 +983,18 @@ unsigned int db_read_address( unsigned int segment, unsigned int loc,
break;
case 1:
get_value_inc(disp, segment, loc, 1, TRUE);
get_value_inc(disp, addr, 1, TRUE);
addrp->disp = disp;
addrp->base = db_reg[LONG][rm];
break;
case 2:
get_value_inc(disp, segment, loc, 4, FALSE);
get_value_inc(disp, addr, 4, FALSE);
addrp->disp = disp;
addrp->base = db_reg[LONG][rm];
break;
}
}
return (loc);
}
static void db_task_printsym(unsigned int addr, int size)
......@@ -1015,7 +1008,10 @@ static void db_task_printsym(unsigned int addr, int size)
fprintf(stderr, "0x%4.4x", addr & 0xffff );
break;
case LONG:
print_address(0, addr, db_disasm_16 ? 16 : 32);
{
DBG_ADDR address = { 0, addr };
DEBUG_PrintAddress( &address, db_disasm_16 ? 16 : 32 );
}
break;
}
}
......@@ -1051,8 +1047,8 @@ db_print_address(seg, size, addrp)
* Disassemble floating-point ("escape") instruction
* and return updated location.
*/
unsigned int db_disasm_esc( unsigned int segment, unsigned int loc,
int inst, int short_addr, int size, char *seg )
void db_disasm_esc( DBG_ADDR *addr, int inst, int short_addr,
int size, char *seg )
{
int regmodrm;
struct finst *fp;
......@@ -1060,14 +1056,14 @@ unsigned int db_disasm_esc( unsigned int segment, unsigned int loc,
struct i_addr address;
char * name;
get_value_inc(regmodrm, segment, loc, 1, FALSE);
get_value_inc(regmodrm, addr, 1, FALSE);
fp = &db_Esc_inst[inst - 0xd8][f_reg(regmodrm)];
mod = f_mod(regmodrm);
if (mod != 3) {
/*
* Normal address modes.
*/
loc = db_read_address(segment,loc, short_addr, regmodrm, &address);
db_read_address( addr, short_addr, regmodrm, &address);
fprintf(stderr,fp->f_name);
switch(fp->f_size) {
case SNGL:
......@@ -1123,15 +1119,16 @@ unsigned int db_disasm_esc( unsigned int segment, unsigned int loc,
break;
}
}
return (loc);
}
/*
* Disassemble instruction at 'loc'. Return address of start of
* next instruction.
/***********************************************************************
* DEBUG_Disasm
*
* Disassemble instruction at 'addr'. addr is changed to point to the
* start of the next instruction.
*/
unsigned int db_disasm( unsigned int segment, unsigned int loc )
void DEBUG_Disasm( DBG_ADDR *addr )
{
int inst;
int size;
......@@ -1146,14 +1143,13 @@ unsigned int db_disasm( unsigned int segment, unsigned int loc )
int displ;
int prefix;
int imm;
int imm2;
int len;
struct i_addr address;
if (!segment) db_disasm_16 = FALSE;
else db_disasm_16 = !(GET_SEL_FLAGS(segment) & LDT_FLAGS_32BIT);
if (!addr->seg) db_disasm_16 = FALSE;
else db_disasm_16 = !(GET_SEL_FLAGS(addr->seg) & LDT_FLAGS_32BIT);
get_value_inc(inst, segment, loc, 1, FALSE);
get_value_inc( inst, addr, 1, FALSE );
if (db_disasm_16) {
short_addr = TRUE;
......@@ -1212,18 +1208,18 @@ unsigned int db_disasm( unsigned int segment, unsigned int loc )
break;
}
if (prefix) {
get_value_inc(inst, segment, loc, 1, FALSE);
get_value_inc(inst, addr, 1, FALSE);
}
} while (prefix);
if (inst >= 0xd8 && inst <= 0xdf) {
loc = db_disasm_esc(segment, loc, inst, short_addr, size, seg);
fprintf(stderr,"\n");
return (loc);
}
if (inst >= 0xd8 && inst <= 0xdf)
{
db_disasm_esc( addr, inst, short_addr, size, seg);
return;
}
if (inst == 0x0f) {
get_value_inc(inst, segment, loc, 1, FALSE);
get_value_inc(inst, addr, 1, FALSE);
ip = db_inst_0f[inst>>4];
if (ip == 0) {
ip = &db_bad_inst;
......@@ -1236,8 +1232,8 @@ unsigned int db_disasm( unsigned int segment, unsigned int loc )
ip = &db_inst_table[inst];
if (ip->i_has_modrm) {
get_value_inc(regmodrm, segment, loc, 1, FALSE);
loc = db_read_address(segment,loc, short_addr, regmodrm, &address);
get_value_inc(regmodrm, addr, 1, FALSE);
db_read_address( addr, short_addr, regmodrm, &address);
}
i_name = ip->i_name;
......@@ -1378,42 +1374,42 @@ unsigned int db_disasm( unsigned int segment, unsigned int loc )
case I:
len = db_lengths[size];
get_value_inc(imm, segment, loc, len, FALSE);/* unsigned */
get_value_inc(imm, addr, len, FALSE);/* unsigned */
fprintf(stderr,"$0x%x", imm);
break;
case Is:
len = db_lengths[size];
get_value_inc(imm, segment, loc, len, TRUE); /* signed */
get_value_inc(imm, addr, len, TRUE); /* signed */
fprintf(stderr,"$%d", imm);
break;
case Ib:
get_value_inc(imm, segment, loc, 1, FALSE); /* unsigned */
get_value_inc(imm, addr, 1, FALSE); /* unsigned */
fprintf(stderr,"$0x%x", imm);
break;
case Ibs:
get_value_inc(imm, segment, loc, 1, TRUE); /* signed */
get_value_inc(imm, addr, 1, TRUE); /* signed */
fprintf(stderr,"$%d", imm);
break;
case Iw:
get_value_inc(imm, segment, loc, 2, FALSE); /* unsigned */
get_value_inc(imm, addr, 2, FALSE); /* unsigned */
fprintf(stderr,"$0x%x", imm);
break;
case Il:
get_value_inc(imm, segment, loc, 4, FALSE);
get_value_inc(imm, addr, 4, FALSE);
fprintf(stderr,"$0x%x", imm);
break;
case O:
if (short_addr) {
get_value_inc(displ, segment, loc, 2, TRUE);
get_value_inc(displ, addr, 2, TRUE);
}
else {
get_value_inc(displ, segment, loc, 4, TRUE);
get_value_inc(displ, addr, 4, TRUE);
}
if (seg)
fprintf(stderr,"%s:%d",seg, displ);
......@@ -1422,27 +1418,26 @@ unsigned int db_disasm( unsigned int segment, unsigned int loc )
break;
case Db:
get_value_inc(displ, segment, loc, 1, TRUE);
get_value_inc(displ, addr, 1, TRUE);
if (short_addr) {
/* offset only affects low 16 bits */
displ = (loc & 0xffff0000)
| ((loc + displ) & 0xffff);
displ = (addr->off & 0xffff0000)
| ((addr->off + displ) & 0xffff);
}
else
displ = displ + loc;
else displ += addr->off;
db_task_printsym(displ, short_addr ? WORD : LONG);
break;
case Dl:
if (short_addr) {
get_value_inc(displ, segment, loc, 2, TRUE);
get_value_inc(displ, addr, 2, TRUE);
/* offset only affects low 16 bits */
displ = (loc & 0xffff0000)
| ((loc + displ) & 0xffff);
displ = (addr->off & 0xffff0000)
| ((addr->off + displ) & 0xffff);
}
else {
get_value_inc(displ, segment, loc, 4, TRUE);
displ = displ + loc;
get_value_inc(displ, addr, 4, TRUE);
displ += addr->off;
}
db_task_printsym( displ, short_addr ? WORD : LONG);
break;
......@@ -1456,18 +1451,15 @@ unsigned int db_disasm( unsigned int segment, unsigned int loc )
break;
case OS:
if (short_addr) {
get_value_inc(imm, segment, loc, 2, FALSE);/* offset */
}
else {
get_value_inc(imm, segment, loc, 4, FALSE);/* offset */
}
get_value_inc(imm2, segment, loc, 2, FALSE); /* segment */
print_address( imm2, imm, short_addr ? 16 : 32 );
{
DBG_ADDR address;
get_value_inc( address.off, addr, /* offset */
short_addr ? 2 : 4, FALSE );
get_value_inc( address.seg, addr, /* segment */
2, FALSE );
DEBUG_PrintAddress( &address, short_addr ? 16 : 32 );
}
break;
}
}
return (loc);
}
%{
/* Parser for command lines in the Wine debugger
/*
* Parser for command lines in the Wine debugger
*
* Version 1.0
* Eric Youngdale
* 9/93
* Copyright 1993 Eric Youngdale
*/
#include <stdio.h>
......@@ -14,8 +12,6 @@
#include "windows.h"
#include "debugger.h"
#define YYSTYPE int
extern FILE * yyin;
unsigned int dbg_mode = 0;
......@@ -23,35 +19,31 @@ static enum exec_mode dbg_exec_mode = EXEC_CONT;
void issue_prompt(void);
void mode_command(int);
void flush_symbols(void);
int yylex(void);
int yyerror(char *);
%}
%union
{
DBG_ADDR address;
enum debug_regs reg;
char * string;
int integer;
}
%token CONT
%token STEP
%token NEXT
%token QUIT
%token HELP
%token BACKTRACE
%token INFO
%token STACK
%token SEGMENTS
%token REG
%token REGS
%token NUM
%token ENABLE
%token DISABLE
%token BREAK
%token DELETE
%token SET
%token MODE
%token PRINT
%token EXAM
%token IDENTIFIER
%token FORMAT
%token CONT STEP NEXT QUIT HELP BACKTRACE INFO STACK SEGMENTS REGS
%token ENABLE DISABLE BREAK DELETE SET MODE PRINT EXAM DEFINE ABORT
%token NO_SYMBOL
%token SYMBOLFILE
%token DEFINE
%token ABORT
%token <string> IDENTIFIER
%token <integer> NUM FORMAT
%token <reg> REG
%type <integer> expr
%type <address> addr symbol
%%
......@@ -62,19 +54,21 @@ void mode_command(int);
| infocmd '\n'
| error '\n' { yyerrok; }
| QUIT '\n' { exit(0); }
| HELP '\n' { dbg_help(); }
| HELP '\n' { DEBUG_Help(); }
| CONT '\n' { dbg_exec_mode = EXEC_CONT; return 0; }
| STEP '\n' { dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
| NEXT '\n' { dbg_exec_mode = EXEC_STEP_OVER; return 0; }
| ABORT '\n' { kill(getpid(), SIGABRT); }
| SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); }
| DEFINE IDENTIFIER expr '\n' { add_hash($2, 0, $3); }
| SYMBOLFILE IDENTIFIER '\n' { DEBUG_ReadSymbolTable( $2 ); }
| DEFINE IDENTIFIER addr '\n' { DEBUG_AddSymbol( $2, &$3 ); }
| MODE NUM '\n' { mode_command($2); }
| ENABLE NUM '\n' { DEBUG_EnableBreakpoint( $2, TRUE ); }
| DISABLE NUM '\n' { DEBUG_EnableBreakpoint( $2, FALSE ); }
| BREAK '*' expr '\n' { DEBUG_AddBreakpoint( 0xffffffff, $3 ); }
| BREAK '*' expr ':' expr '\n' { DEBUG_AddBreakpoint( $3, $5); }
| BREAK '\n' { DEBUG_AddBreakpoint( 0xffffffff, EIP ); }
| BREAK '*' addr '\n' { DEBUG_AddBreakpoint( &$3 ); }
| BREAK '\n' { DBG_ADDR addr = { CS_reg(DEBUG_context),
EIP_reg(DEBUG_context) };
DEBUG_AddBreakpoint( &addr );
}
| DELETE BREAK NUM '\n' { DEBUG_DelBreakpoint( $3 ); }
| BACKTRACE '\n' { DEBUG_BackTrace(); }
| x_command
......@@ -82,38 +76,41 @@ void mode_command(int);
| deposit_command
deposit_command:
SET REG '=' expr '\n' { DEBUG_SetRegister( $2, $4 ); }
| SET '*' expr '=' expr '\n' { *((unsigned int *) $3) = $5; }
| SET symbol '=' expr '\n' { *((unsigned int *) $2) = $4; }
SET REG '=' expr '\n' { DEBUG_SetRegister( $2, $4 ); }
| SET '*' addr '=' expr '\n' { DEBUG_WriteMemory( &$3, $5 ); }
| SET IDENTIFIER '=' addr '\n' { if (!DEBUG_SetSymbolValue( $2, &$4 ))
{
fprintf( stderr, "Symbol %s not found\n", $2 );
YYERROR;
}
}
x_command:
EXAM expr '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
| EXAM FORMAT expr '\n' { examine_memory( 0xffffffff, $3,
$2 >> 8, $2 & 0xff ); }
| EXAM expr ':' expr '\n' { examine_memory( $2, $4, 1, 'x' ); }
| EXAM FORMAT expr ':' expr'\n' { examine_memory( $3, $5,
$2 >> 8, $2 & 0xff ); }
EXAM addr '\n' { DEBUG_ExamineMemory( &$2, 1, 'x'); }
| EXAM FORMAT addr '\n' { DEBUG_ExamineMemory( &$3, $2>>8, $2&0xff ); }
print_command:
PRINT expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1,'x'); }
| PRINT FORMAT expr '\n' { examine_memory( 0, (unsigned int)&$3,
$2 >> 8, $2 & 0xff ); }
PRINT addr '\n' { DEBUG_Print( &$2, 1, 'x' ); }
| PRINT FORMAT addr '\n' { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff ); }
symbol: IDENTIFIER { if (($$ = find_hash($1)) == 0xffffffff)
symbol: IDENTIFIER { if (!DEBUG_GetSymbolValue( $1, &$$ ))
{
fprintf(stderr,"Symbol %s not found\n", (char *)$1);
fprintf( stderr, "Symbol %s not found\n", $1 );
YYERROR;
}
}
addr: expr { $$.seg = 0xffffffff; $$.off = $1; }
| expr ':' expr { $$.seg = $1; $$.off = $3; }
| symbol { $$ = $1; }
expr: NUM { $$ = $1; }
| REG { $$ = DEBUG_GetRegister($1); }
| symbol { $$ = $1; }
| expr '+' NUM { $$ = $1 + $3; }
| expr '-' NUM { $$ = $1 - $3; }
| '(' expr ')' { $$ = $2; }
| '*' expr { $$ = *((unsigned int *) $2); }
| '*' addr { $$ = DEBUG_ReadMemory( &$2 ); }
infocmd: INFO REGS { DEBUG_InfoRegisters(); }
| INFO STACK { DEBUG_InfoStack(); }
......@@ -147,33 +144,39 @@ void wine_debug( int signal, struct sigcontext_struct *regs )
#endif
yyin = stdin;
context = (struct sigcontext_struct *)regs;
DEBUG_context = (struct sigcontext_struct *)regs;
if (CS == WINE_CODE_SELECTOR) newmode = 32;
else newmode = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) ? 32 : 16;
if (newmode != dbg_mode)
fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode);
DEBUG_SetBreakpoints( FALSE );
if(dbg_mode == 32 && !loaded_symbols)
if (!loaded_symbols)
{
loaded_symbols++;
GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym",
SymbolTableFile, sizeof(SymbolTableFile), WINE_INI);
read_symboltable(SymbolTableFile);
DEBUG_ReadSymbolTable( SymbolTableFile );
DEBUG_LoadEntryPoints();
}
DEBUG_SetBreakpoints( FALSE );
if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( regs, dbg_exec_mode ))
{
unsigned int segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
DBG_ADDR addr;
addr.seg = (CS_reg(DEBUG_context) == WINE_CODE_SELECTOR) ?
0 : CS_reg(DEBUG_context);
addr.off = EIP_reg(DEBUG_context);
if (!addr.seg) newmode = 32;
else newmode = (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
if (newmode != dbg_mode)
fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode);
/* Show where we crashed */
print_address( segment, EIP, dbg_mode );
DEBUG_PrintAddress( &addr, dbg_mode );
fprintf(stderr,": ");
instr_len = db_disasm( segment, EIP ) - EIP;
DEBUG_Disasm( &addr );
fprintf(stderr,"\n");
instr_len = addr.off - EIP_reg(DEBUG_context);
issue_prompt();
yyparse();
......
......@@ -9,8 +9,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dbg.tab.h"
#include "debugger.h"
#include "dbg.tab.h"
#ifdef USE_READLINE
#undef YY_INPUT
......@@ -25,7 +25,6 @@ static int dbg_read(char * buf, int size);
static char * make_symbol(char *);
void flush_symbols();
static int syntax_error;
extern int yylval;
%}
DIGIT [0-9]
......@@ -39,37 +38,39 @@ IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]*
[-+=()*:] { return *yytext; }
"0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &yylval); return NUM; }
{DIGIT}+ { sscanf(yytext, "%d", &yylval); return NUM; }
"/"{DIGIT}+{FORMAT} { char *last; yylval = strtol( yytext+1, &last, NULL );
yylval = (yylval << 8) | *last; return FORMAT; }
"/"{FORMAT} { yylval = (1 << 8) | yytext[1]; return FORMAT; }
$pc { yylval = REG_EIP; return REG; }
$flags { yylval = REG_EFL; return REG; }
$eip { yylval = REG_EIP; return REG; }
$ip { yylval = REG_IP; return REG; }
$esp { yylval = REG_ESP; return REG; }
$sp { yylval = REG_SP; return REG; }
$eax { yylval = REG_EAX; return REG; }
$ebx { yylval = REG_EBX; return REG; }
$ecx { yylval = REG_ECX; return REG; }
$edx { yylval = REG_EDX; return REG; }
$esi { yylval = REG_ESI; return REG; }
$edi { yylval = REG_EDI; return REG; }
$ebp { yylval = REG_EBP; return REG; }
$ax { yylval = REG_AX; return REG; }
$bx { yylval = REG_BX; return REG; }
$cx { yylval = REG_CX; return REG; }
$dx { yylval = REG_DX; return REG; }
$si { yylval = REG_SI; return REG; }
$di { yylval = REG_DI; return REG; }
$bp { yylval = REG_BP; return REG; }
$es { yylval = REG_ES; return REG; }
$ds { yylval = REG_DS; return REG; }
$cs { yylval = REG_CS; return REG; }
$ss { yylval = REG_SS; return REG; }
"0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &yylval.integer); return NUM; }
{DIGIT}+ { sscanf(yytext, "%d", &yylval.integer); return NUM; }
"/"{DIGIT}+{FORMAT} { char * last;
yylval.integer = strtol( yytext+1, &last, NULL );
yylval.integer = (yylval.integer << 8) | *last;
return FORMAT; }
"/"{FORMAT} { yylval.integer = (1 << 8) | yytext[1]; return FORMAT; }
$pc { yylval.reg = REG_EIP; return REG; }
$flags { yylval.reg = REG_EFL; return REG; }
$eip { yylval.reg = REG_EIP; return REG; }
$ip { yylval.reg = REG_IP; return REG; }
$esp { yylval.reg = REG_ESP; return REG; }
$sp { yylval.reg = REG_SP; return REG; }
$eax { yylval.reg = REG_EAX; return REG; }
$ebx { yylval.reg = REG_EBX; return REG; }
$ecx { yylval.reg = REG_ECX; return REG; }
$edx { yylval.reg = REG_EDX; return REG; }
$esi { yylval.reg = REG_ESI; return REG; }
$edi { yylval.reg = REG_EDI; return REG; }
$ebp { yylval.reg = REG_EBP; return REG; }
$ax { yylval.reg = REG_AX; return REG; }
$bx { yylval.reg = REG_BX; return REG; }
$cx { yylval.reg = REG_CX; return REG; }
$dx { yylval.reg = REG_DX; return REG; }
$si { yylval.reg = REG_SI; return REG; }
$di { yylval.reg = REG_DI; return REG; }
$bp { yylval.reg = REG_BP; return REG; }
$es { yylval.reg = REG_ES; return REG; }
$ds { yylval.reg = REG_DS; return REG; }
$cs { yylval.reg = REG_CS; return REG; }
$ss { yylval.reg = REG_SS; return REG; }
info|inf|in { return INFO; }
segments|segm { return SEGMENTS; }
......@@ -103,14 +104,14 @@ registers|regs|reg|re { return REGS; }
stack|stac|sta|st { return STACK; }
{IDENTIFIER} {yylval = (int) make_symbol(yytext);
return IDENTIFIER;
}
{IDENTIFIER} { yylval.string = make_symbol(yytext); return IDENTIFIER; }
[ \t]+ /* Eat up whitespace */
. { if(syntax_error == 0) {
syntax_error ++; fprintf(stderr, "Syntax Error\n"); }
. { if (syntax_error == 0)
{
syntax_error ++; fprintf(stderr, "Syntax Error\n");
}
}
%%
......@@ -124,11 +125,6 @@ int yywrap(void) { return 1; }
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif
#if 0
/* Used only with GNU readline */
#include "readline/readline.h"
#include "readline/chardefs.h"
#endif
/* Strip whitespace from the start and end of STRING. */
static void stripwhite (char *string)
......@@ -161,18 +157,22 @@ static int dbg_read(char * buf, int size)
line = readline ("Wine-dbg>");
if (!line) exit(0);
/* Remove leading and trailing whitespace from the line.
Then, if there is anything left, add it to the history list
and execute it. */
/* Remove leading and trailing whitespace from the line */
stripwhite (line);
/* If there is anything left, add it to the history list
and execute it. Otherwise, re-execute last command. */
if (*line)
{
add_history( line );
strncpy( last_line, line, 255 );
last_line[255] = '\0';
}
else line = last_line; /* Repeat previous command */
free( line );
line = last_line;
if ((len = strlen(line)) > 0)
{
......@@ -184,7 +184,6 @@ static int dbg_read(char * buf, int size)
strcpy(buf, line);
buf[len] = '\n';
buf[len+1] = 0;
free(line);
return len + 1;
}
}
......
......@@ -12,182 +12,248 @@
#include <neexe.h>
#include "module.h"
#include "selectors.h"
#include "wine.h"
#include "debugger.h"
#include "toolhelp.h"
struct name_hash{
struct name_hash * next;
unsigned int segment;
unsigned int address;
char * name;
struct name_hash
{
struct name_hash * next;
char * name;
DBG_ADDR addr;
};
#define NR_NAME_HASH 128
static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,};
static unsigned int name_hash(const char * name){
unsigned int hash = 0;
const char * p;
p = name;
static unsigned int name_hash( const char * name )
{
unsigned int hash = 0;
const char * p;
while (*p) hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
return hash % NR_NAME_HASH;
p = name;
while (*p) hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
return hash % NR_NAME_HASH;
}
void add_hash(char * name, unsigned int segment, unsigned int address)
/***********************************************************************
* DEBUG_AddSymbol
*
* Add a symbol to the table.
*/
void DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr )
{
struct name_hash * new;
int hash;
new = (struct name_hash *) malloc(sizeof(struct name_hash));
new->segment = segment;
new->address = address;
new->name = strdup(name);
new->next = NULL;
hash = name_hash(name);
/* Now insert into the hash table */
new->next = name_hash_table[hash];
name_hash_table[hash] = new;
struct name_hash * new;
int hash;
new = (struct name_hash *) malloc(sizeof(struct name_hash));
new->addr = *addr;
new->name = strdup(name);
new->next = NULL;
hash = name_hash(name);
/* Now insert into the hash table */
new->next = name_hash_table[hash];
name_hash_table[hash] = new;
}
unsigned int find_hash(char * name)
{
char buffer[256];
struct name_hash * nh;
for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
if(strcmp(nh->name, name) == 0) return nh->address;
/***********************************************************************
* DEBUG_GetSymbolValue
*
* Get the address of a named symbol.
*/
BOOL DEBUG_GetSymbolValue( const char * name, DBG_ADDR *addr )
{
char buffer[256];
struct name_hash *nh;
if(name[0] != '_'){
buffer[0] = '_';
strcpy(buffer+1, name);
for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
if(strcmp(nh->name, buffer) == 0) return nh->address;
};
for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
if (!strcmp(nh->name, name)) break;
if (!nh && (name[0] != '_'))
{
buffer[0] = '_';
strcpy(buffer+1, name);
for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
if (!strcmp(nh->name, buffer)) break;
}
return 0xffffffff;
if (!nh) return FALSE;
*addr = nh->addr;
return TRUE;
}
static char name_buffer[256];
char * find_nearest_symbol(unsigned int segment, unsigned int address)
/***********************************************************************
* DEBUG_SetSymbolValue
*
* Set the address of a named symbol.
*/
BOOL DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr )
{
struct name_hash * nearest;
struct name_hash * nh;
unsigned int nearest_address;
int i;
nearest = NULL;
nearest_address = 0;
for(i=0; i<NR_NAME_HASH; i++) {
for(nh = name_hash_table[i]; nh; nh = nh->next)
if (nh->segment == segment &&
nh->address <= address &&
nh->address >= nearest_address)
{
nearest_address = nh->address;
nearest = nh;
}
}
if (!nearest) return NULL;
if (address == nearest->address)
sprintf( name_buffer, "%s", nearest->name );
else
sprintf( name_buffer, "%s+0x%x", nearest->name,
address - nearest->address );
return name_buffer;
}
char buffer[256];
struct name_hash *nh;
for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
if (!strcmp(nh->name, name)) break;
void
read_symboltable(char * filename){
FILE * symbolfile;
unsigned int addr;
int nargs;
char type;
char * cpnt;
char buffer[256];
char name[256];
if (!nh && (name[0] != '_'))
{
buffer[0] = '_';
strcpy(buffer+1, name);
for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
if (!strcmp(nh->name, buffer)) break;
}
symbolfile = fopen(filename, "r");
if(!symbolfile) {
fprintf(stderr,"Unable to open symbol table %s\n", filename);
return;
};
if (!nh) return FALSE;
nh->addr = *addr;
DBG_FIX_ADDR_SEG( &nh->addr, DS_reg(DEBUG_context) );
return TRUE;
}
fprintf(stderr,"Reading symbols from file %s\n", filename);
/***********************************************************************
* DEBUG_FindNearestSymbol
*
* Find the symbol nearest to a given address.
*/
const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr )
{
static char name_buffer[256];
struct name_hash * nearest = NULL;
struct name_hash * nh;
unsigned int nearest_address = 0;
int i;
while (1)
{
fgets(buffer, sizeof(buffer), symbolfile);
if (feof(symbolfile)) break;
/* Strip any text after a # sign (i.e. comments) */
cpnt = buffer;
while(*cpnt){
if(*cpnt == '#') {*cpnt = 0; break; };
cpnt++;
};
/* Quietly ignore any lines that have just whitespace */
cpnt = buffer;
while(*cpnt){
if(*cpnt != ' ' && *cpnt != '\t') break;
cpnt++;
};
if (!(*cpnt) || *cpnt == '\n') {
continue;
};
nargs = sscanf(buffer, "%x %c %s", &addr, &type, name);
add_hash(name, 0, addr);
};
fclose(symbolfile);
for(i=0; i<NR_NAME_HASH; i++)
{
for (nh = name_hash_table[i]; nh; nh = nh->next)
if (nh->addr.seg == addr->seg &&
nh->addr.off <= addr->off &&
nh->addr.off >= nearest_address)
{
nearest_address = nh->addr.off;
nearest = nh;
}
}
if (!nearest) return NULL;
if (addr->off == nearest->addr.off)
sprintf( name_buffer, "%s", nearest->name );
else
sprintf( name_buffer, "%s+0x%lx", nearest->name,
addr->off - nearest->addr.off );
return name_buffer;
}
void load_entrypoints( HMODULE hModule )
/***********************************************************************
* DEBUG_ReadSymbolTable
*
* Read a symbol file into the hash table.
*/
void DEBUG_ReadSymbolTable( const char * filename )
{
FILE * symbolfile;
DBG_ADDR addr = { 0, 0 };
int nargs;
char type;
char * cpnt;
char buffer[256];
unsigned char *cpnt, *name;
NE_MODULE *pModule;
unsigned int address;
char name[256];
if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return;
name = (unsigned char *)pModule + pModule->name_table;
if (!(symbolfile = fopen(filename, "r")))
{
fprintf( stderr, "Unable to open symbol table %s\n", filename );
return;
}
/* First search the resident names */
fprintf( stderr, "Reading symbols from file %s\n", filename );
cpnt = (unsigned char *)pModule + pModule->name_table;
while (*cpnt)
while (1)
{
cpnt += *cpnt + 1 + sizeof(WORD);
sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
*cpnt, *cpnt, cpnt + 1 );
address = MODULE_GetEntryPoint( hModule, *(WORD *)(cpnt + *cpnt + 1) );
if (address) add_hash( buffer, HIWORD(address), LOWORD(address) );
fgets( buffer, sizeof(buffer), symbolfile );
if (feof(symbolfile)) break;
/* Strip any text after a # sign (i.e. comments) */
cpnt = buffer;
while (*cpnt)
if(*cpnt++ == '#') { *cpnt = 0; break; }
/* Quietly ignore any lines that have just whitespace */
cpnt = buffer;
while(*cpnt)
{
if(*cpnt != ' ' && *cpnt != '\t') break;
cpnt++;
}
if (!(*cpnt) || *cpnt == '\n') continue;
nargs = sscanf(buffer, "%lx %c %s", &addr.off, &type, name);
DEBUG_AddSymbol( name, &addr );
}
fclose(symbolfile);
}
/* Now search the non-resident names table */
/***********************************************************************
* DEBUG_LoadEntryPoints
*
* Load the entry points of all the modules into the hash table.
*/
void DEBUG_LoadEntryPoints(void)
{
MODULEENTRY entry;
NE_MODULE *pModule;
DBG_ADDR addr;
char buffer[256];
unsigned char *cpnt, *name;
unsigned int address;
BOOL ok;
if (!pModule->nrname_handle) return; /* No non-resident table */
cpnt = (char *)GlobalLock( pModule->nrname_handle );
while (*cpnt)
fprintf( stderr, "Adding symbols from loaded modules\n" );
for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry))
{
cpnt += *cpnt + 1 + sizeof(WORD);
sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
*cpnt, *cpnt, cpnt + 1 );
address = MODULE_GetEntryPoint( hModule, *(WORD *)(cpnt + *cpnt + 1) );
if (address) add_hash( buffer, HIWORD(address), LOWORD(address) );
if (!(pModule = (NE_MODULE *)GlobalLock( entry.hModule ))) continue;
name = (unsigned char *)pModule + pModule->name_table;
/* First search the resident names */
cpnt = (unsigned char *)pModule + pModule->name_table;
while (*cpnt)
{
cpnt += *cpnt + 1 + sizeof(WORD);
sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
*cpnt, *cpnt, cpnt + 1 );
if ((address = MODULE_GetEntryPoint( entry.hModule,
*(WORD *)(cpnt + *cpnt + 1) )))
{
addr.seg = HIWORD(address);
addr.off = LOWORD(address);
DEBUG_AddSymbol( buffer, &addr );
}
}
/* Now search the non-resident names table */
if (!pModule->nrname_handle) continue; /* No non-resident table */
cpnt = (char *)GlobalLock( pModule->nrname_handle );
while (*cpnt)
{
cpnt += *cpnt + 1 + sizeof(WORD);
sprintf( buffer, "%*.*s.%*.*s", *name, *name, name + 1,
*cpnt, *cpnt, cpnt + 1 );
if ((address = MODULE_GetEntryPoint( entry.hModule,
*(WORD *)(cpnt + *cpnt + 1) )))
{
addr.seg = HIWORD(address);
addr.off = LOWORD(address);
DEBUG_AddSymbol( buffer, &addr );
}
}
}
}
/*
* Wine debugger utility routines
* Eric Youngdale
* 9/93
*
* Copyright 1993 Eric Youngdale
* Copyright 1995 Alexandre Julliard
*/
#include <stdio.h>
#include <stdlib.h>
#include "debugger.h"
extern char * find_nearest_symbol( unsigned int seg, unsigned int addr );
void print_address( unsigned int segment, unsigned int addr, int addrlen )
/***********************************************************************
* DEBUG_Print
*
* Implementation of the 'print' command.
*/
void DEBUG_Print( const DBG_ADDR *addr, int count, char format )
{
char *name = find_nearest_symbol( segment, addr );
if (count != 1)
{
fprintf( stderr, "Count other than 1 is meaningless in 'print' command\n" );
return;
}
if (segment) fprintf( stderr, "0x%04x:", segment );
if (addrlen == 16) fprintf( stderr, "0x%04x", addr );
else fprintf( stderr, "0x%08x", addr );
if (name) fprintf( stderr, " (%s)", name );
}
if (addr->seg && (addr->seg != 0xffffffff))
{
switch(format)
{
case 'x':
fprintf( stderr, "0x%04lx:", addr->seg );
break;
case 'd':
fprintf( stderr, "%ld:", addr->seg );
break;
void examine_memory( unsigned int segment, unsigned int addr,
int count, char format )
{
char * pnt;
unsigned int * dump;
unsigned short int * wdump;
int i;
case 'c':
break; /* No segment to print */
if (segment == 0xffffffff) segment = (format == 'i' ? CS : DS);
if ((segment == WINE_CODE_SELECTOR) || (segment == WINE_DATA_SELECTOR))
segment = 0;
case 'i':
case 's':
case 'w':
case 'b':
break; /* Meaningless format */
}
}
if (format != 'i' && count > 1)
switch(format)
{
print_address( segment, addr, dbg_mode );
fprintf(stderr,": ");
case 'x':
if (addr->seg) fprintf( stderr, "0x%04lx\n", addr->off );
else fprintf( stderr, "0x%08lx\n", addr->off );
break;
case 'd':
fprintf( stderr, "%ld\n", addr->off );
break;
case 'c':
fprintf( stderr, "%d = '%c'\n",
(char)(addr->off & 0xff), (char)(addr->off & 0xff) );
break;
case 'i':
case 's':
case 'w':
case 'b':
fprintf( stderr, "Format specifier '%c' is meaningless in 'print' command\n", format );
break;
}
}
pnt = segment ? (char *)PTR_SEG_OFF_TO_LIN(segment,addr) : (char *)addr;
switch(format)
{
case 's':
if (count == 1) count = 256;
while(*pnt && count) {
fputc( *pnt++, stderr);
count--;
};
fprintf(stderr,"\n");
return;
/***********************************************************************
* DEBUG_PrintAddress
*
* Print an 16- or 32-bit address, with the nearest symbol if any.
*/
void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen )
{
const char *name = DEBUG_FindNearestSymbol( addr );
case 'i':
for(i=0; i<count; i++) {
print_address( segment, addr, dbg_mode );
fprintf(stderr,": ");
addr = db_disasm( segment, addr );
fprintf(stderr,"\n");
};
return;
case 'x':
dump = (unsigned int *)pnt;
for(i=0; i<count; i++)
{
fprintf(stderr," %8.8x", *dump++);
addr += 4;
if ((i % 8) == 7) {
fprintf(stderr,"\n");
print_address( segment, addr, dbg_mode );
fprintf(stderr,": ");
};
}
fprintf(stderr,"\n");
return;
case 'd':
dump = (unsigned int *)pnt;
for(i=0; i<count; i++)
{
fprintf(stderr," %d", *dump++);
addr += 4;
if ((i % 8) == 7) {
fprintf(stderr,"\n");
print_address( segment, addr, dbg_mode );
fprintf(stderr,": ");
};
}
fprintf(stderr,"\n");
return;
case 'w':
wdump = (unsigned short *)pnt;
for(i=0; i<count; i++)
{
fprintf(stderr," %04x", *wdump++);
addr += 2;
if ((i % 10) == 7) {
fprintf(stderr,"\n");
print_address( segment, addr, dbg_mode );
fprintf(stderr,": ");
};
}
fprintf(stderr,"\n");
return;
case 'c':
for(i=0; i<count; i++)
{
if(*pnt < 0x20) {
fprintf(stderr," ");
pnt++;
} else
fprintf(stderr," %c", *pnt++);
addr++;
if ((i % 32) == 7) {
fprintf(stderr,"\n");
print_address( segment, addr, dbg_mode );
fprintf(stderr,": ");
};
}
fprintf(stderr,"\n");
return;
case 'b':
for(i=0; i<count; i++)
{
fprintf(stderr," %02x", (*pnt++) & 0xff);
addr++;
if ((i % 32) == 7) {
fprintf(stderr,"\n");
print_address( segment, addr, dbg_mode );
fprintf(stderr,": ");
};
}
fprintf(stderr,"\n");
return;
};
/* The rest are fairly straightforward */
fprintf(stderr,"examine mem: %x %d %c\n", addr, count, format);
if (addr->seg) fprintf( stderr, "0x%04lx:", addr->seg );
if (addrlen == 16) fprintf( stderr, "0x%04lx", addr->off );
else fprintf( stderr, "0x%08lx", addr->off );
if (name) fprintf( stderr, " (%s)", name );
}
char * helptext[] = {
/***********************************************************************
* DEBUG_Help
*
* Implementation of the 'help' command.
*/
void DEBUG_Help(void)
{
int i = 0;
static const char * helptext[] =
{
"The commands accepted by the Wine debugger are a small subset",
"of the commands that gdb would accept. The commands currently",
"are:\n",
" break [*<addr>] delete break bpnum",
" disable bpnum enable bpnum",
" help quit",
" x <expr> cont",
" x <addr> cont",
" step next",
" mode [16,32] print <expr>",
" set <reg> = <expr> set *<expr> = <expr>",
" set <reg> = <expr> set *<addr> = <expr>",
" info [reg,stack,break,segments] bt",
" symbolfile <filename> define <identifier> <expr>",
" symbolfile <filename> define <identifier> <addr>",
"",
"The 'x' command accepts repeat counts and formats (including 'i') in the",
"same way that gdb does.",
......@@ -166,10 +120,8 @@ char * helptext[] = {
" symbolfile command. Symbols can also be defined individually with",
" the define command.",
"",
NULL};
NULL
};
void dbg_help(){
int i;
i = 0;
while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
}
/*
* Debugger memory handling
*
* Copyright 1993 Eric Youngdale
* Copyright 1995 Alexandre Julliard
*/
#include <stdio.h>
#include <stdlib.h>
#include "debugger.h"
/***********************************************************************
* DEBUG_ReadMemory
*
* Read a memory value.
*/
int DEBUG_ReadMemory( const DBG_ADDR *address )
{
DBG_ADDR addr = *address;
DBG_FIX_ADDR_SEG( &addr, DS_reg(DEBUG_context) );
return *(int *)DBG_ADDR_TO_LIN( &addr );
}
/***********************************************************************
* DEBUG_WriteMemory
*
* Store a value in memory.
*/
void DEBUG_WriteMemory( const DBG_ADDR *address, int value )
{
DBG_ADDR addr = *address;
DBG_FIX_ADDR_SEG( &addr, DS_reg(DEBUG_context) );
*(int *)DBG_ADDR_TO_LIN( &addr ) = value;
}
/***********************************************************************
* DEBUG_ExamineMemory
*
* Implementation of the 'x' command.
*/
void DEBUG_ExamineMemory( const DBG_ADDR *address, int count, char format )
{
DBG_ADDR addr = *address;
unsigned char * pnt;
unsigned int * dump;
unsigned short int * wdump;
int i;
DBG_FIX_ADDR_SEG( &addr, (format == 'i') ?
CS_reg(DEBUG_context) : DS_reg(DEBUG_context) );
if (format != 'i' && count > 1)
{
DEBUG_PrintAddress( &addr, dbg_mode );
fprintf(stderr,": ");
}
pnt = DBG_ADDR_TO_LIN( &addr );
switch(format)
{
case 's':
if (count == 1) count = 256;
while(*pnt && count--) fputc( *pnt++, stderr );
fprintf(stderr,"\n");
return;
case 'i':
while (count--)
{
DEBUG_PrintAddress( &addr, dbg_mode );
fprintf(stderr,": ");
DEBUG_Disasm( &addr );
fprintf(stderr,"\n");
}
return;
case 'x':
dump = (unsigned int *)pnt;
for(i=0; i<count; i++)
{
fprintf(stderr," %8.8x", *dump++);
addr.off += 4;
if ((i % 8) == 7) {
fprintf(stderr,"\n");
DEBUG_PrintAddress( &addr, dbg_mode );
fprintf(stderr,": ");
};
}
fprintf(stderr,"\n");
return;
case 'd':
dump = (unsigned int *)pnt;
for(i=0; i<count; i++)
{
fprintf(stderr," %d", *dump++);
addr.off += 4;
if ((i % 8) == 7) {
fprintf(stderr,"\n");
DEBUG_PrintAddress( &addr, dbg_mode );
fprintf(stderr,": ");
};
}
fprintf(stderr,"\n");
return;
case 'w':
wdump = (unsigned short *)pnt;
for(i=0; i<count; i++)
{
fprintf(stderr," %04x", *wdump++);
addr.off += 2;
if ((i % 10) == 7) {
fprintf(stderr,"\n");
DEBUG_PrintAddress( &addr, dbg_mode );
fprintf(stderr,": ");
};
}
fprintf(stderr,"\n");
return;
case 'c':
for(i=0; i<count; i++)
{
if(*pnt < 0x20) {
fprintf(stderr," ");
pnt++;
} else
fprintf(stderr," %c", *pnt++);
addr.off++;
if ((i % 32) == 7) {
fprintf(stderr,"\n");
DEBUG_PrintAddress( &addr, dbg_mode );
fprintf(stderr,": ");
};
}
fprintf(stderr,"\n");
return;
case 'b':
for(i=0; i<count; i++)
{
fprintf(stderr," %02x", (*pnt++) & 0xff);
addr.off++;
if ((i % 32) == 7) {
fprintf(stderr,"\n");
DEBUG_PrintAddress( &addr, dbg_mode );
fprintf(stderr,": ");
};
}
fprintf(stderr,"\n");
return;
}
}
......@@ -5,7 +5,7 @@ TOPSRC = @top_srcdir@
DIVINCL = -I$(TOPSRC)/include
LD = @LD@
LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
DIVDEFS = -DHIDE -DANSI_ARROWS
DIVDEFS = @DEFS@ -DHIDE -DANSI_ARROWS
MODULE = readline
......@@ -25,26 +25,16 @@ $(MODULE).o: $(OBJS)
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -3,7 +3,10 @@
** Unix system-dependant routines for editline library.
*/
#include "editline.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if defined(HAVE_TCGETATTR)
#include <termios.h>
......
......@@ -8,7 +8,7 @@
#include "debugger.h"
struct sigcontext_struct *context;
struct sigcontext_struct *DEBUG_context;
......@@ -21,30 +21,30 @@ void DEBUG_SetRegister( enum debug_regs reg, int val )
{
switch(reg)
{
case REG_EAX: EAX = val; break;
case REG_EBX: EBX = val; break;
case REG_ECX: ECX = val; break;
case REG_EDX: EDX = val; break;
case REG_ESI: ESI = val; break;
case REG_EDI: EDI = val; break;
case REG_EBP: EBP = val; break;
case REG_EFL: EFL = val; break;
case REG_EIP: EIP = val; break;
case REG_ESP: ESP = val; break;
case REG_AX: AX = val; break;
case REG_BX: BX = val; break;
case REG_CX: CX = val; break;
case REG_DX: DX = val; break;
case REG_SI: SI = val; break;
case REG_DI: DI = val; break;
case REG_BP: BP = val; break;
case REG_FL: FL = val; break;
case REG_IP: IP = val; break;
case REG_SP: SP = val; break;
case REG_CS: CS = val; break;
case REG_DS: DS = val; break;
case REG_ES: ES = val; break;
case REG_SS: SS = val; break;
case REG_EAX: EAX_reg(DEBUG_context) = val; break;
case REG_EBX: EBX_reg(DEBUG_context) = val; break;
case REG_ECX: ECX_reg(DEBUG_context) = val; break;
case REG_EDX: EDX_reg(DEBUG_context) = val; break;
case REG_ESI: ESI_reg(DEBUG_context) = val; break;
case REG_EDI: EDI_reg(DEBUG_context) = val; break;
case REG_EBP: EBP_reg(DEBUG_context) = val; break;
case REG_EFL: EFL_reg(DEBUG_context) = val; break;
case REG_EIP: EIP_reg(DEBUG_context) = val; break;
case REG_ESP: ESP_reg(DEBUG_context) = val; break;
case REG_AX: AX_reg(DEBUG_context) = val; break;
case REG_BX: BX_reg(DEBUG_context) = val; break;
case REG_CX: CX_reg(DEBUG_context) = val; break;
case REG_DX: DX_reg(DEBUG_context) = val; break;
case REG_SI: SI_reg(DEBUG_context) = val; break;
case REG_DI: DI_reg(DEBUG_context) = val; break;
case REG_BP: BP_reg(DEBUG_context) = val; break;
case REG_FL: FL_reg(DEBUG_context) = val; break;
case REG_IP: IP_reg(DEBUG_context) = val; break;
case REG_SP: SP_reg(DEBUG_context) = val; break;
case REG_CS: CS_reg(DEBUG_context) = val; break;
case REG_DS: DS_reg(DEBUG_context) = val; break;
case REG_ES: ES_reg(DEBUG_context) = val; break;
case REG_SS: SS_reg(DEBUG_context) = val; break;
}
}
......@@ -58,30 +58,30 @@ int DEBUG_GetRegister( enum debug_regs reg )
{
switch(reg)
{
case REG_EAX: return EAX;
case REG_EBX: return EBX;
case REG_ECX: return ECX;
case REG_EDX: return EDX;
case REG_ESI: return ESI;
case REG_EDI: return EDI;
case REG_EBP: return EBP;
case REG_EFL: return EFL;
case REG_EIP: return EIP;
case REG_ESP: return ESP;
case REG_AX: return AX;
case REG_BX: return BX;
case REG_CX: return CX;
case REG_DX: return DX;
case REG_SI: return SI;
case REG_DI: return DI;
case REG_BP: return BP;
case REG_FL: return FL;
case REG_IP: return IP;
case REG_SP: return SP;
case REG_CS: return CS;
case REG_DS: return DS;
case REG_ES: return ES;
case REG_SS: return SS;
case REG_EAX: return EAX_reg(DEBUG_context);
case REG_EBX: return EBX_reg(DEBUG_context);
case REG_ECX: return ECX_reg(DEBUG_context);
case REG_EDX: return EDX_reg(DEBUG_context);
case REG_ESI: return ESI_reg(DEBUG_context);
case REG_EDI: return EDI_reg(DEBUG_context);
case REG_EBP: return EBP_reg(DEBUG_context);
case REG_EFL: return EFL_reg(DEBUG_context);
case REG_EIP: return EIP_reg(DEBUG_context);
case REG_ESP: return ESP_reg(DEBUG_context);
case REG_AX: return AX_reg(DEBUG_context);
case REG_BX: return BX_reg(DEBUG_context);
case REG_CX: return CX_reg(DEBUG_context);
case REG_DX: return DX_reg(DEBUG_context);
case REG_SI: return SI_reg(DEBUG_context);
case REG_DI: return DI_reg(DEBUG_context);
case REG_BP: return BP_reg(DEBUG_context);
case REG_FL: return FL_reg(DEBUG_context);
case REG_IP: return IP_reg(DEBUG_context);
case REG_SP: return SP_reg(DEBUG_context);
case REG_CS: return CS_reg(DEBUG_context);
case REG_DS: return DS_reg(DEBUG_context);
case REG_ES: return ES_reg(DEBUG_context);
case REG_SS: return SS_reg(DEBUG_context);
}
return 0; /* should not happen */
}
......@@ -98,22 +98,30 @@ void DEBUG_InfoRegisters(void)
fprintf(stderr,"Register dump:\n");
/* First get the segment registers out of the way */
fprintf( stderr," CS:%04x SS:%04x DS:%04x ES:%04x\n", CS, SS, DS, ES );
fprintf( stderr," CS:%04x SS:%04x DS:%04x ES:%04x\n",
CS_reg(DEBUG_context), SS_reg(DEBUG_context),
DS_reg(DEBUG_context), ES_reg(DEBUG_context) );
if (dbg_mode == 16)
{
fprintf( stderr," IP:%04x SP:%04x BP:%04x FLAGS:%04x\n",
IP, SP, BP, FL );
IP_reg(DEBUG_context), SP_reg(DEBUG_context),
BP_reg(DEBUG_context), FL_reg(DEBUG_context) );
fprintf( stderr," AX:%04x BX:%04x CX:%04x DX:%04x SI:%04x DI:%04x\n",
AX, BX, CX, DX, SI, DI );
AX_reg(DEBUG_context), BX_reg(DEBUG_context),
CX_reg(DEBUG_context), DX_reg(DEBUG_context),
SI_reg(DEBUG_context), DI_reg(DEBUG_context) );
}
else /* 32-bit mode */
{
fprintf( stderr, " EIP:%08lx ESP:%08lx EBP:%08lx EFLAGS:%08lx\n",
EIP, ESP, EBP, EFL );
EIP_reg(DEBUG_context), ESP_reg(DEBUG_context),
EBP_reg(DEBUG_context), EFL_reg(DEBUG_context) );
fprintf( stderr, " EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n",
EAX, EBX, ECX, EDX);
fprintf( stderr, " ESI:%08lx EDI:%08lx\n", ESI, EDI);
EAX_reg(DEBUG_context), EBX_reg(DEBUG_context),
ECX_reg(DEBUG_context), EDX_reg(DEBUG_context) );
fprintf( stderr, " ESI:%08lx EDI:%08lx\n",
ESI_reg(DEBUG_context), EDI_reg(DEBUG_context) );
}
}
......@@ -32,15 +32,21 @@ typedef struct
*/
void DEBUG_InfoStack(void)
{
DBG_ADDR addr;
fprintf(stderr,"Stack dump:\n");
if ((SS == WINE_DATA_SELECTOR) ||
(GET_SEL_FLAGS(SS) & LDT_FLAGS_32BIT)) /* 32-bit mode */
{
examine_memory( 0, ESP, 10, 'x' );
if ((SS_reg(DEBUG_context) == WINE_DATA_SELECTOR) ||
(GET_SEL_FLAGS(SS_reg(DEBUG_context)) & LDT_FLAGS_32BIT))
{ /* 32-bit mode */
addr.seg = 0;
addr.off = ESP_reg(DEBUG_context);
DEBUG_ExamineMemory( &addr, 10, 'x' );
}
else /* 16-bit mode */
{
examine_memory( SS, SP, 10, 'w' );
addr.seg = SS_reg(DEBUG_context);
addr.off = SP_reg(DEBUG_context);
DEBUG_ExamineMemory( &addr, 10, 'w' );
}
fprintf(stderr,"\n");
}
......@@ -53,25 +59,29 @@ void DEBUG_InfoStack(void)
*/
void DEBUG_BackTrace(void)
{
int frameno = 0;
DBG_ADDR addr;
int frameno = 0;
fprintf(stderr,"Backtrace:\n");
if (SS == WINE_DATA_SELECTOR) /* 32-bit mode */
if (SS_reg(DEBUG_context) == WINE_DATA_SELECTOR) /* 32-bit mode */
{
FRAME32 *frame = (FRAME32 *)EBP;
FRAME32 *frame = (FRAME32 *)EBP_reg(DEBUG_context);
addr.seg = 0;
while (frame->ip)
{
fprintf(stderr,"%d ",frameno++);
print_address( 0, frame->ip, 32 );
addr.off = frame->ip;
DEBUG_PrintAddress( &addr, 32 );
fprintf( stderr, "\n" );
frame = (FRAME32 *)frame->bp;
}
}
else /* 16-bit mode */
{
FRAME16 *frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS, BP & ~1 );
WORD cs = CS;
if (GET_SEL_FLAGS(SS) & LDT_FLAGS_32BIT)
FRAME16 *frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS_reg(DEBUG_context),
BP_reg(DEBUG_context) & ~1 );
WORD cs = CS_reg(DEBUG_context);
if (GET_SEL_FLAGS(SS_reg(DEBUG_context)) & LDT_FLAGS_32BIT)
{
fprintf( stderr, "Not implemented: 32-bit backtrace on a different stack segment.\n" );
return;
......@@ -80,9 +90,12 @@ void DEBUG_BackTrace(void)
{
if (frame->bp & 1) cs = frame->cs;
fprintf( stderr,"%d ", frameno++ );
print_address( cs, frame->ip, 16 );
addr.seg = cs;
addr.off = frame->ip;
DEBUG_PrintAddress( &addr, 16 );
fprintf( stderr, "\n" );
frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS, frame->bp & ~1 );
frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS_reg(DEBUG_context),
frame->bp & ~1 );
}
}
fprintf( stderr, "\n" );
......
......@@ -31,31 +31,21 @@ SFILES = $(DLLS16:.spec=.S)
.c.o:
$(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
.spec.S:
$(BUILD) -spec16 $< > $*.S
.S.o:
$(CC) -c -o $*.o $<
all: checkbuild $(MODULE).o
gdi32.c: gdi32.spec
$(BUILD) -spec32 gdi32.spec > gdi32.c
kernel32.c: kernel32.spec
$(BUILD) -spec32 kernel32.spec > kernel32.c
.spec.S:
$(BUILD) -spec16 $< > $*.S
shell32.c: shell32.spec
$(BUILD) -spec32 shell32.spec > shell32.c
.spec.c:
$(BUILD) -spec32 $< > $*.c
user32.c: user32.spec
$(BUILD) -spec32 user32.spec > user32.c
all: checkbuild $(MODULE).o
winprocs32.c: winprocs32.spec
$(BUILD) -spec32 winprocs32.spec > winprocs32.c
$(SFILES): $(TOPSRC)/tools/build
checkbuild:
(cd $(TOPSRC)/tools; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
cd $(TOPSRC)/tools; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)' build
call16.S: $(TOPSRC)/include/callback.h
$(TOPSRC)/tools/build -call16 `cat $(TOPSRC)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq` > call16.S
......@@ -63,26 +53,23 @@ call16.S: $(TOPSRC)/include/callback.h
call32.S: $(SFILES)
$(BUILD) -call32 `cat $(SFILES) | grep CallTo32_ | sed 's/.*CallTo32_\(.*\)/\1/' | sort | uniq` > call32.S
$(MODULE).o: $(OBJS)
$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM callback.c relay32.c relay.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM $(SRCS) >> tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ *.S gdi32.c kernel32.c shell32.c user32.c winprocs32.c tmp_make
rm -f *.o \#*\# *~ tmp_make
rm -f $(DLLS16:.spec=.S) $(DLLS32:.spec=.c) call32.S call16.S
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
winelibclean:
dummy:
### Dependencies:
......@@ -76,6 +76,7 @@ int Throw( LPCATCHBUF lpbuf, int retval )
pFrame->bp = lpbuf[6];
pFrame->ip = lpbuf[7];
pFrame->cs = lpbuf[8];
pFrame->es = 0;
return retval;
}
......
......@@ -64,8 +64,8 @@ id 1
66 pascal16 AllocResource(word word long) AllocResource
67 stub SetResourceHandler
68 pascal16 InitAtomTable(word) InitAtomTable
69 pascal16 FindAtom(ptr) FindAtom
70 pascal16 AddAtom(ptr) AddAtom
69 pascal16 FindAtom(segptr) FindAtom
70 pascal16 AddAtom(segptr) AddAtom
71 pascal16 DeleteAtom(word) DeleteAtom
72 pascal16 GetAtomName(word ptr word) GetAtomName
73 pascal16 GetAtomHandle(word) GetAtomHandle
......
......@@ -156,7 +156,9 @@ void RELAY_DebugCall32( int func_type, char *args )
{
struct sigcontext_struct *context = (struct sigcontext_struct *)args16;
printf( " AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
AX, BX, CX, DX, SI, DI, ES, EFL );
AX_reg(context), BX_reg(context), CX_reg(context),
DX_reg(context), SI_reg(context), DI_reg(context),
ES_reg(context), EFL_reg(context) );
}
}
......
......@@ -49,7 +49,7 @@ id 2
47 pascal16 IsWindow(word) IsWindow
48 pascal16 IsChild(word word) IsChild
49 pascal16 IsWindowVisible(word) IsWindowVisible
50 pascal16 FindWindow(ptr ptr) FindWindow
50 pascal16 FindWindow(segptr ptr) FindWindow
#51 BEAR51
52 pascal16 AnyPopup() AnyPopup
53 pascal16 DestroyWindow(word) DestroyWindow
......@@ -115,7 +115,7 @@ id 2
114 pascal DispatchMessage(ptr) DispatchMessage
115 stub ReplyMessage
116 pascal16 PostAppMessage(word word word long) PostAppMessage
118 pascal16 RegisterWindowMessage(ptr) RegisterWindowMessage
118 pascal16 RegisterWindowMessage(long) RegisterWindowMessage
119 pascal GetMessagePos() GetMessagePos
120 pascal GetMessageTime() GetMessageTime
121 pascal SetWindowsHook(s_word segptr) SetWindowsHook
......@@ -269,9 +269,9 @@ id 2
265 pascal16 ShowOwnedPopups(word word) ShowOwnedPopups
266 pascal16 SetMessageQueue(word) SetMessageQueue
267 pascal16 ShowScrollBar(word word word) ShowScrollBar
268 pascal16 GlobalAddAtom(ptr) GlobalAddAtom
268 pascal16 GlobalAddAtom(segptr) GlobalAddAtom
269 pascal16 GlobalDeleteAtom(word) GlobalDeleteAtom
270 pascal16 GlobalFindAtom(ptr) GlobalFindAtom
270 pascal16 GlobalFindAtom(segptr) GlobalFindAtom
271 pascal16 GlobalGetAtomName(word ptr s_word) GlobalGetAtomName
272 pascal16 IsZoomed(word) IsZoomed
273 stub ControlPanelInfo
......@@ -334,7 +334,7 @@ id 2
400 stub FinalUserInit
402 pascal16 GetPriorityClipboardFormat(word ptr s_word)
GetPriorityClipboardFormat
403 pascal16 UnregisterClass(ptr word) UnregisterClass
403 pascal16 UnregisterClass(segptr word) UnregisterClass
404 pascal16 GetClassInfo(word segptr ptr) GetClassInfo
406 pascal16 CreateCursor(word word word word word ptr ptr) CreateCursor
407 pascal16 CreateIcon(word word word byte byte ptr ptr) CreateIcon
......
......@@ -25,20 +25,10 @@ typedef struct
HANDLE entries[1];
} ATOMTABLE;
#ifdef WINELIB
#define LocalAlign(flags,bytes) LocalAlloc (flags|LMEM_WINE_ALIGN,bytes)
#else
#define LocalAlign(flags,bytes) LocalAlloc((flags),(bytes))
#endif
ATOM LocalAddAtom( LPCSTR str );
ATOM LocalAddAtom( SEGPTR str );
ATOM LocalDeleteAtom( ATOM atom );
ATOM LocalFindAtom( LPCSTR str );
WORD LocalGetAtomName( ATOM atom, LPSTR buffer, short count );
ATOM LocalAddAtom( LPCSTR str );
ATOM LocalDeleteAtom( ATOM atom );
ATOM LocalFindAtom( LPCSTR str );
ATOM LocalFindAtom( SEGPTR str );
WORD LocalGetAtomName( ATOM atom, LPSTR buffer, short count );
#endif /* ATOM_H */
......@@ -32,7 +32,7 @@ typedef struct tagCLASS
#endif
HCLASS CLASS_FindClassByName( char * name, WORD hinstance, CLASS **ptr );
HCLASS CLASS_FindClassByName( SEGPTR name, WORD hinstance, CLASS **ptr );
CLASS * CLASS_FindClassPtr( HCLASS hclass );
......
#undef HAVE_STDLIB_H
#undef HAVE_TCGETATTR
#undef HAVE_DIRENT_H
#undef HAVE_SYS_NDIR_H
#undef HAVE_NDIR_H
#undef STAT_MACROS_BROKEN
......@@ -11,6 +11,20 @@
#include "registers.h"
#include "wine.h"
typedef struct
{
DWORD seg; /* 0xffffffff means current default segment (cs or ds) */
DWORD off;
} DBG_ADDR;
#define DBG_FIX_ADDR_SEG(addr,default) \
{ if ((addr)->seg == 0xffffffff) (addr)->seg = (default); \
if (((addr)->seg == WINE_CODE_SELECTOR) || \
(addr)->seg == WINE_DATA_SELECTOR) (addr)->seg = 0; }
#define DBG_ADDR_TO_LIN(addr) \
((addr)->seg ? (char *)PTR_SEG_OFF_TO_LIN((addr)->seg,(addr)->off) \
: (char *)(addr)->off)
enum debug_regs
{
......@@ -29,13 +43,13 @@ enum exec_mode
EXEC_STEP_INSTR /* Single-stepping an instruction */
};
extern struct sigcontext_struct *context; /* debugger/registers.c */
extern struct sigcontext_struct *DEBUG_context; /* debugger/registers.c */
extern unsigned int dbg_mode;
/* debugger/break.c */
extern void DEBUG_SetBreakpoints( BOOL set );
extern int DEBUG_FindBreakpoint( unsigned int segment, unsigned int addr );
extern void DEBUG_AddBreakpoint( unsigned int segment, unsigned int addr );
extern int DEBUG_FindBreakpoint( const DBG_ADDR *addr );
extern void DEBUG_AddBreakpoint( const DBG_ADDR *addr );
extern void DEBUG_DelBreakpoint( int num );
extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
extern void DEBUG_InfoBreakpoints(void);
......@@ -45,6 +59,27 @@ extern BOOL DEBUG_ShouldContinue( struct sigcontext_struct *context,
extern void DEBUG_RestartExecution( struct sigcontext_struct *context,
enum exec_mode mode, int instr_len );
/* debugger/db_disasm.c */
extern void DEBUG_Disasm( DBG_ADDR *addr );
/* debugger/hash.c */
extern void DEBUG_AddSymbol( const char *name, const DBG_ADDR *addr );
extern BOOL DEBUG_GetSymbolValue( const char * name, DBG_ADDR *addr );
extern BOOL DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr );
extern const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr );
extern void DEBUG_ReadSymbolTable( const char * filename );
extern void DEBUG_LoadEntryPoints(void);
/* debugger/info.c */
extern void DEBUG_Print( const DBG_ADDR *addr, int count, char format );
extern void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen );
extern void DEBUG_Help(void);
/* debugger/memory.c */
extern int DEBUG_ReadMemory( const DBG_ADDR *address );
extern void DEBUG_WriteMemory( const DBG_ADDR *address, int value );
extern void DEBUG_ExamineMemory( const DBG_ADDR *addr, int count, char format);
/* debugger/registers.c */
extern void DEBUG_SetRegister( enum debug_regs reg, int val );
extern int DEBUG_GetRegister( enum debug_regs reg );
......@@ -57,7 +92,4 @@ extern void DEBUG_BackTrace(void);
/* debugger/dbg.y */
extern void wine_debug( int signal, struct sigcontext_struct * regs );
extern void print_address( unsigned int seg, unsigned int addr, int addrlen );
extern unsigned int db_disasm( unsigned int segment, unsigned int loc );
#endif /* DEBUGGER_H */
......@@ -2,7 +2,7 @@
#define __WINE_MISCEMU_H
#include "wintypes.h"
#include "wine.h"
#include "registers.h"
extern BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context );
......@@ -16,10 +16,12 @@ extern void INT_SetHandler( BYTE intnum, SEGPTR handler );
extern void INT21_Init(void);
#define INT_BARF(num) \
#define INT_BARF(context,num) \
fprintf( stderr, "int%x: unknown/not implemented parameters:\n" \
"int%x: AX %04x, BX %04x, CX %04x, DX %04x, " \
"SI %04x, DI %04x, DS %04x, ES %04x\n", \
(num), (num), AX, BX, CX, DX, SI, DI, DS, ES )
(num), (num), AX_reg(context), BX_reg(context), CX_reg(context), \
DX_reg(context), SI_reg(context), DI_reg(context), \
DS_reg(context), ES_reg(context) )
#endif /* __WINE_MISCEMU_H */
......@@ -31,7 +31,9 @@ struct fcb {
BYTE dummy2[9];
};
#define DOSVERSION 0x0005 /* Major version in low byte: DOS 5.00 */
#define DOSVERSION 0x1606 /* Major version in low byte: DOS 6.22 */
#define WINDOSVER 0x0616 /* Windows reports the DOS version reversed */
#define WINVERSION 0x0a03 /* Windows version 3.10 */
#define MAX_DOS_DRIVES 26
......
......@@ -2,9 +2,11 @@
* ole.h - Declarations for OLESVR and OLECLI
*/
typedef LPCSTR OLE_LPCSTR;
typedef enum
{
OLE_OK,
OLE_OK=0, /* Yes Sir! */
OLE_WAIT_FOR_RELEASE,
OLE_BUSY,
OLE_ERROR_PROTECT_ONLY,
......@@ -66,19 +68,141 @@ typedef enum
typedef enum{
OLE_SERVER_MULTI,
OLE_SERVER_SINGLE
}OLE_SERVER_USE;
} OLE_SERVER_USE;
/* dunno if the values are correct, somebody please check */
typedef enum {
OLE_CHANGED,
OLE_CLOSED,
OLE_QUERY_PAINT,
OLE_QUERY_RETRY,
OLE_RELEASE,
OLE_RENAMED,
OLE_SAVED
} OLE_NOTIFICATION;
typedef LONG LHSERVER;
typedef LONG LHSERVERDOC;
typedef LONG LHCLIENTDOC;
typedef LONG OLECLIPFORMAT;/* dunno about this type, please change/add */
typedef LONG OLEOPT_UPDATE;/* dunno about this type, please change/add */
typedef OLEOPT_UPDATE* LPOLEOPT_UPDATE;/* dunno about this type, please change/add */
typedef LONG *OLE_RELEASE_METHOD;/* dunno */
typedef struct _OLESERVER* LPOLESERVER;
typedef struct _OLETARGETDEVICE {
UINT otdDeviceNameOffset;
UINT otdDriverNameOffset;
UINT otdPortNameOffset;
UINT otdExtDevmodeOffset;
UINT otdExtDevmodeSize;
UINT otdEnvironmentOffset;
UINT otdEnvironmentSize;
BYTE otdData[1];
/* ... */
} OLETARGETDEVICE;
typedef struct _OLESTREAM* LPOLESTREAM;
typedef struct _OLESTREAMVTBL {
DWORD (CALLBACK* Get)(LPOLESTREAM,LPSTR,DWORD);
DWORD (CALLBACK* Put)(LPOLESTREAM,LPSTR,DWORD);
} OLESTREAMVTBL;
typedef OLESTREAMVTBL* LPOLESTREAMVTBL;
typedef struct _OLESTREAM {
LPOLESTREAMVTBL lpstbl;
} OLESTREAM;
typedef struct _OLESERVERDOC* LPOLESERVERDOC;
typedef struct _OLEOBJECT* LPOLEOBJECT;
typedef struct _OLECLIENT* LPOLECLIENT;
typedef struct _OLESERVERDOCVTBL {
OLESTATUS (CALLBACK* Save)(LPOLESERVERDOC);
OLESTATUS (CALLBACK* Close)(LPOLESERVERDOC);
OLESTATUS (CALLBACK* SetHostNames)(LPOLESERVERDOC,OLE_LPCSTR,OLE_LPCSTR);
OLESTATUS (CALLBACK* SetDocDimensions)(LPOLESERVERDOC,LPRECT);
OLESTATUS (CALLBACK* GetObject)(LPOLESERVERDOC,OLE_LPCSTR,LPOLEOBJECT*,LPOLECLIENT);
OLESTATUS (CALLBACK* Release)(LPOLESERVERDOC);
OLESTATUS (CALLBACK* SetColorScheme)(LPOLESERVERDOC,LPLOGPALETTE);
OLESTATUS (CALLBACK* Execute)(LPOLESERVERDOC,HGLOBAL);
} OLESERVERDOCVTBL;
typedef OLESERVERDOCVTBL* LPOLESERVERDOCVTBL;
typedef struct _OLESERVERDOC {
LPOLESERVERDOCVTBL lpvtbl;
/* server provided state info */
} OLESERVERDOC;
typedef struct _OLESERVER* LPOLESERVER;
typedef struct _OLESERVERVTBL {
OLESTATUS (CALLBACK* Open)(LPOLESERVER,LHSERVERDOC,OLE_LPCSTR,LPOLESERVERDOC *);
OLESTATUS (CALLBACK* Create)(LPOLESERVER,LHSERVERDOC,OLE_LPCSTR,OLE_LPCSTR,LPOLESERVERDOC FAR*);
OLESTATUS (CALLBACK* CreateFromTemplate)(LPOLESERVER,LHSERVERDOC,OLE_LPCSTR,OLE_LPCSTR,OLE_LPCSTR,LPOLESERVERDOC *);
OLESTATUS (CALLBACK* Edit)(LPOLESERVER,LHSERVERDOC,OLE_LPCSTR,OLE_LPCSTR,LPOLESERVERDOC *);
OLESTATUS (CALLBACK* Exit)(LPOLESERVER);
OLESTATUS (CALLBACK* Release)(LPOLESERVER);
OLESTATUS (CALLBACK* Execute)(LPOLESERVER);
} OLESERVERVTBL;
typedef OLESERVERVTBL *LPOLESERVERVTBL;
typedef struct _OLESERVER {
LPOLESERVERVTBL lpvtbl;
/* server specific data */
} OLESERVER;
typedef struct _OLECLIENTVTBL {
int (CALLBACK* CallBack)(LPOLECLIENT,OLE_NOTIFICATION,LPOLEOBJECT);
} OLECLIENTVTBL;
typedef OLECLIENTVTBL *LPOLECLIENTVTBL;
typedef struct _OLECLIENT {
LPOLECLIENTVTBL lpvtbl;
/* client data... */
} OLECLIENT;
typedef struct _OLEOBJECTVTBL {
void * (CALLBACK* QueryProtocol)(LPOLEOBJECT,OLE_LPCSTR);
OLESTATUS (CALLBACK* Release)(LPOLEOBJECT);
OLESTATUS (CALLBACK* Show)(LPOLEOBJECT,BOOL);
OLESTATUS (CALLBACK* DoVerb)(LPOLEOBJECT,UINT,BOOL,BOOL);
OLESTATUS (CALLBACK* GetData)(LPOLEOBJECT,OLECLIPFORMAT,HANDLE *);
OLESTATUS (CALLBACK* SetData)(LPOLEOBJECT,OLECLIPFORMAT,HANDLE);
OLESTATUS (CALLBACK* SetTargetDevice)(LPOLEOBJECT,HGLOBAL);
OLESTATUS (CALLBACK* SetBounds)(LPOLEOBJECT,LPRECT);
OLESTATUS (CALLBACK* EnumFormats)(LPOLEOBJECT,OLECLIPFORMAT);
OLESTATUS (CALLBACK* SetColorScheme)(LPOLEOBJECT,LPLOGPALETTE);
OLESTATUS (CALLBACK* Delete)(LPOLEOBJECT);
OLESTATUS (CALLBACK* SetHostNames)(LPOLEOBJECT,OLE_LPCSTR,OLE_LPCSTR);
OLESTATUS (CALLBACK* SaveToStream)(LPOLEOBJECT,LPOLESTREAM);
OLESTATUS (CALLBACK* Clone)(LPOLEOBJECT,LPOLECLIENT,LHCLIENTDOC,OLE_LPCSTR,LPOLEOBJECT *);
OLESTATUS (CALLBACK* CopyFromLink)(LPOLEOBJECT,LPOLECLIENT,LHCLIENTDOC,OLE_LPCSTR,LPOLEOBJECT *);
OLESTATUS (CALLBACK* Equal)(LPOLEOBJECT,LPOLEOBJECT);
OLESTATUS (CALLBACK* CopyToClipBoard)(LPOLEOBJECT);
OLESTATUS (CALLBACK* Draw)(LPOLEOBJECT,HDC,LPRECT,LPRECT,HDC);
OLESTATUS (CALLBACK* Activate)(LPOLEOBJECT,UINT,BOOL,BOOL,HWND,LPRECT);
OLESTATUS (CALLBACK* Execute)(LPOLEOBJECT,HGLOBAL,UINT);
OLESTATUS (CALLBACK* Close)(LPOLEOBJECT);
OLESTATUS (CALLBACK* Update)(LPOLEOBJECT);
OLESTATUS (CALLBACK* Reconnect)(LPOLEOBJECT);
OLESTATUS (CALLBACK* ObjectConvert)(LPOLEOBJECT,OLE_LPCSTR,LPOLECLIENT,LHCLIENTDOC,OLE_LPCSTR,LPOLEOBJECT*);
OLESTATUS (CALLBACK* GetLinkUpdateOptions)(LPOLEOBJECT,LPOLEOPT_UPDATE);
OLESTATUS (CALLBACK* SetLinkUpdateOptions)(LPOLEOBJECT,OLEOPT_UPDATE);
OLESTATUS (CALLBACK* Rename)(LPOLEOBJECT,OLE_LPCSTR);
OLESTATUS (CALLBACK* QueryName)(LPOLEOBJECT,LPSTR,LPUINT);
OLESTATUS (CALLBACK* QueryType)(LPOLEOBJECT,LPLONG);
OLESTATUS (CALLBACK* QueryBounds)(LPOLEOBJECT,LPRECT);
OLESTATUS (CALLBACK* QuerySize)(LPOLEOBJECT,LPDWORD);
OLESTATUS (CALLBACK* QueryOpen)(LPOLEOBJECT);
OLESTATUS (CALLBACK* QueryOutOfDate)(LPOLEOBJECT);
OLESTATUS (CALLBACK* QueryReleaseStatus)(LPOLEOBJECT);
OLESTATUS (CALLBACK* QueryReleaseError)(LPOLEOBJECT);
OLE_RELEASE_METHOD (CALLBACK* QueryReleaseMethod)(LPOLEOBJECT);
OLESTATUS (CALLBACK* RequestData)(LPOLEOBJECT,OLECLIPFORMAT);
OLESTATUS (CALLBACK* ObjectLong)(LPOLEOBJECT,UINT,LPLONG);
} OLEOBJECTVTBL;
typedef OLEOBJECTVTBL* LPOLEOBJECTVTBL;
typedef struct _OLEOBJECT {
LPOLEOBJECTVTBL lpvtbl;
} OLEOBJECT;
OLESTATUS WINAPI OleRegisterServer(LPCSTR,LPOLESERVER,LHSERVER FAR*,HINSTANCE,OLE_SERVER_USE);
OLESTATUS WINAPI OleUnblockServer(LHSERVER,BOOL FAR*);
OLESTATUS WINAPI OleRegisterServerDoc(LHSERVER,LPCSTR,LPOLESERVERDOC,LHSERVERDOC FAR*);
OLESTATUS WINAPI OleRegisterClientDoc(LPCSTR,LPCSTR,LONG,LHCLIENTDOC FAR*);
OLESTATUS WINAPI OleRegisterServer(LPCSTR,LPOLESERVER,LHSERVER *,HINSTANCE,OLE_SERVER_USE);
OLESTATUS WINAPI OleUnblockServer(LHSERVER,BOOL *);
OLESTATUS WINAPI OleRegisterServerDoc(LHSERVER,LPCSTR,LPOLESERVERDOC,LHSERVERDOC *);
OLESTATUS WINAPI OleRegisterClientDoc(LPCSTR,LPCSTR,LONG,LHCLIENTDOC *);
OLESTATUS WINAPI OleRenameClientDoc(LHCLIENTDOC,LPCSTR);
OLESTATUS WINAPI OleRevokeServerDoc(LHSERVERDOC);
OLESTATUS WINAPI OleRevokeClientDoc(LHCLIENTDOC);
......
......@@ -18,7 +18,8 @@ struct options
int debug;
int allowReadOnly; /* Opening a read only file will succeed even
if write access is requested */
int enhanced; /* Start Wine in enhanced mode */
int enhanced; /* Start Wine in enhanced mode */
int ipc; /* Use IPC mechanisms */
};
extern struct options Options;
......
/*
* Register definitions
*
* Copyright 1995 Alexandre Julliard
*/
#ifndef __WINE_REGISTERS_H
#define __WINE_REGISTERS_H
#include <windows.h>
#ifndef PROCEMU
#include "wine.h"
#define EAX (context->sc_eax)
#define EBX (context->sc_ebx)
#define ECX (context->sc_ecx)
#define EDX (context->sc_edx)
#define ESI (context->sc_esi)
#define EDI (context->sc_edi)
#define EBP (context->sc_ebp)
#define AX (*(WORD*)&context->sc_eax)
#define BX (*(WORD*)&context->sc_ebx)
#define CX (*(WORD*)&context->sc_ecx)
#define DX (*(WORD*)&context->sc_edx)
#define SI (*(WORD*)&context->sc_esi)
#define DI (*(WORD*)&context->sc_edi)
#define BP (*(WORD*)&context->sc_ebp)
#define AL (*(BYTE*)&context->sc_eax)
#define AH (*(((BYTE*)&context->sc_eax)+1))
#define BL (*(BYTE*)&context->sc_ebx)
#define BH (*(((BYTE*)&context->sc_ebx)+1))
#define CL (*(BYTE*)&context->sc_ecx)
#define CH (*(((BYTE*)&context->sc_ecx)+1))
#define DL (*(BYTE*)&context->sc_edx)
#define DH (*(((BYTE*)&context->sc_edx)+1))
#define CS (context->sc_cs)
#define DS (context->sc_ds)
#define ES (context->sc_es)
#define SS (context->sc_ss)
#ifdef linux
#define FS (context->sc_fs)
#define GS (context->sc_gs)
#define EAX_reg(context) ((context)->sc_eax)
#define EBX_reg(context) ((context)->sc_ebx)
#define ECX_reg(context) ((context)->sc_ecx)
#define EDX_reg(context) ((context)->sc_edx)
#define ESI_reg(context) ((context)->sc_esi)
#define EDI_reg(context) ((context)->sc_edi)
#define EBP_reg(context) ((context)->sc_ebp)
#define AX_reg(context) (*(WORD*)&((context)->sc_eax))
#define BX_reg(context) (*(WORD*)&((context)->sc_ebx))
#define CX_reg(context) (*(WORD*)&((context)->sc_ecx))
#define DX_reg(context) (*(WORD*)&((context)->sc_edx))
#define SI_reg(context) (*(WORD*)&((context)->sc_esi))
#define DI_reg(context) (*(WORD*)&((context)->sc_edi))
#define BP_reg(context) (*(WORD*)&((context)->sc_ebp))
#define AL_reg(context) (*(BYTE*)(&(context)->sc_eax))
#define AH_reg(context) (*(((BYTE*)(&(context)->sc_eax)+1)))
#define BL_reg(context) (*(BYTE*)(&(context)->sc_ebx))
#define BH_reg(context) (*(((BYTE*)(&(context)->sc_ebx)+1)))
#define CL_reg(context) (*(BYTE*)(&(context)->sc_ecx))
#define CH_reg(context) (*(((BYTE*)(&(context)->sc_ecx)+1)))
#define DL_reg(context) (*(BYTE*)(&(context)->sc_edx))
#define DH_reg(context) (*(((BYTE*)(&(context)->sc_edx)+1)))
#define CS_reg(context) ((context)->sc_cs)
#define DS_reg(context) ((context)->sc_ds)
#define ES_reg(context) ((context)->sc_es)
#define SS_reg(context) ((context)->sc_ss)
#ifdef linux
#define FS_reg(context) ((context)->sc_fs)
#define GS_reg(context) ((context)->sc_gs)
#else /* FIXME: are fs and gs supported under *BSD? */
#define FS 0
#define GS 0
#endif
#ifndef __FreeBSD__
#define EFL (context->sc_eflags)
#define FL (*(WORD*)&context->sc_eflags)
#else
#define EFL (context->sc_efl)
#define FL (*(WORD*)&context->sc_efl)
#endif
#define EIP (context->sc_eip)
#define ESP (context->sc_esp)
#define IP (*(WORD*)&context->sc_eip)
#define SP (*(WORD*)&context->sc_esp)
#define SetCflag (EFL |= 0x00000001)
#define ResetCflag (EFL &= 0xfffffffe)
#else
#include "bx_bochs.h"
#define SetCflag bx_STC()
#define ResetCflag bx_CLC()
#define FS_reg(context) 0
#define GS_reg(context) 0
#endif
#ifndef __FreeBSD__
#define EFL_reg(context) ((context)->sc_eflags)
#define FL_reg(context) (*(WORD*)(&(context)->sc_eflags))
#else
#define EFL_reg(context) ((context)->sc_efl)
#define FL_reg(context) (*(WORD*)(&(context)->sc_efl))
#endif
#define EIP_reg(context) ((context)->sc_eip)
#define ESP_reg(context) ((context)->sc_esp)
#define IP_reg(context) (*(WORD*)(&(context)->sc_eip))
#define SP_reg(context) (*(WORD*)(&(context)->sc_esp))
#define SET_CFLAG(context) (EFL_reg(context) |= 0x0001)
#define RESET_CFLAG(context) (EFL_reg(context) &= 0xfffffffe)
#endif /* PROCEMU */
#endif /* __WINE_REGISTERS_H */
......@@ -21,6 +21,12 @@
#define WINSWITCH_CLASS_NAME "#32771" /* WinSwitch */
#define ICONTITLE_CLASS_NAME "#32772" /* IconTitle */
#define POPUPMENU_CLASS_ATOM MAKEINTATOM(32768) /* PopupMenu */
#define DESKTOP_CLASS_ATOM MAKEINTATOM(32769) /* Desktop */
#define DIALOG_CLASS_ATOM MAKEINTATOM(32770) /* Dialog */
#define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771) /* WinSwitch */
#define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772) /* IconTitle */
typedef struct tagWND
{
HWND hwndNext; /* Next sibling */
......
......@@ -56,8 +56,8 @@ typedef struct {
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPSTR lpszMenuName WINE_PACKED;
LPSTR lpszClassName WINE_PACKED;
SEGPTR lpszMenuName WINE_PACKED;
SEGPTR lpszClassName WINE_PACKED;
} WNDCLASS, *LPWNDCLASS;
#define CS_VREDRAW 0x0001
......@@ -429,8 +429,7 @@ typedef struct tagMSG
typedef WORD ATOM;
#define MAKEINTATOM(i) ((LPCSTR)MAKELP(0, (i)))
#define MAKEINTATOM(i) ((SEGPTR)MAKELONG((i),0))
/* Raster operations */
......@@ -2399,12 +2398,12 @@ F(void,SwitchStackBack)
F(void,ValidateCodeSegments)
F(void,WaitMessage)
F(void,Yield)
Fa(ATOM,AddAtom,LPCSTR,a)
Fa(ATOM,AddAtom,SEGPTR,a)
Fa(ATOM,DeleteAtom,ATOM,a)
Fa(ATOM,FindAtom,LPCSTR,a)
Fa(ATOM,GlobalAddAtom,LPCSTR,a)
Fa(ATOM,FindAtom,SEGPTR,a)
Fa(ATOM,GlobalAddAtom,SEGPTR,a)
Fa(ATOM,GlobalDeleteAtom,ATOM,a)
Fa(ATOM,GlobalFindAtom,LPCSTR,a)
Fa(ATOM,GlobalFindAtom,SEGPTR,a)
Fa(ATOM,RegisterClass,LPWNDCLASS,a)
Fa(BOOL,BringWindowToTop,HWND,a)
Fa(BOOL,DeleteDC,HDC,a)
......@@ -2559,7 +2558,7 @@ Fa(WORD,LocalLock,HLOCAL,a)
Fa(WORD,LocalSize,HLOCAL,a)
Fa(WORD,RealizeDefaultPalette,HDC,a)
Fa(WORD,RegisterClipboardFormat,LPCSTR,a)
Fa(WORD,RegisterWindowMessage,LPCSTR,a)
Fa(WORD,RegisterWindowMessage,SEGPTR,a)
Fa(WORD,SetHandleCount,WORD,a)
Fa(WORD,VkKeyScan,WORD,a)
Fa(int,AddFontResource,LPSTR,a)
......@@ -2651,7 +2650,7 @@ Fb(BOOL,SetWindowPlacement,HWND,a,LPWINDOWPLACEMENT,b)
Fb(BOOL,ShowWindow,HWND,a,int,b)
Fb(BOOL,TranslateMDISysAccel,HWND,a,LPMSG,b)
Fb(BOOL,UnhookWindowsHook,short,a,FARPROC,b)
Fb(BOOL,UnregisterClass,LPSTR,a,HANDLE,b)
Fb(BOOL,UnregisterClass,SEGPTR,a,HANDLE,b)
Fb(DWORD,GetNearestColor,HDC,a,DWORD,b)
Fb(DWORD,SetBkColor,HDC,a,COLORREF,b)
Fb(DWORD,SetMapperFlags,HDC,a,DWORD,b)
......@@ -2683,7 +2682,7 @@ Fb(HMENU,LoadMenu,HANDLE,a,SEGPTR,b)
Fb(HMENU,LookupMenuHandle,HMENU,a,INT,b)
Fb(HPALETTE,GDISelectPalette,HDC,a,HPALETTE,b)
Fb(HWND,ChildWindowFromPoint,HWND,a,POINT,b)
Fb(HWND,FindWindow,LPSTR,a,LPSTR,b)
Fb(HWND,FindWindow,SEGPTR,a,LPSTR,b)
Fb(HWND,GetDlgItem,HWND,a,WORD,b)
Fb(HWND,GetNextWindow,HWND,a,WORD,b)
Fb(HWND,GetWindow,HWND,a,WORD,b)
......
......@@ -32,26 +32,16 @@ $(MODULE).o: $(OBJS)
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -29,8 +29,9 @@
#include <assert.h>
#include "bit_array.h"
#if defined(HAS_BITOPS)
# include <asm/bitops.h>
#ifdef HAS_BITOPS
#define inline __inline__ /* So we can compile with -ansi */
#include <asm/bitops.h>
#else
static __inline__ int clear_bit(int bit, int *mem);
static __inline__ int set_bit(int bit, int *mem);
......
......@@ -14,6 +14,7 @@
#include "dde_atom.h"
#include "shm_main_blk.h"
#include "shm_fragment.h"
#include "ldt.h"
#include "stddebug.h"
#include "debug.h"
......@@ -109,20 +110,25 @@ void ATOM_GlobalInit(void)
*/
/* important! don't forget to unlock semaphores before return */
ATOM GlobalAddAtom( LPCSTR str )
ATOM GlobalAddAtom( SEGPTR name )
{
int atom_idx;
int atom_ofs;
AtomData_ptr ptr;
ATOM atom;
char *str;
dprintf_atom(stddeb,"GlobalAddAtom(%p)\n", str);
if ((unsigned) str < MIN_STR_ATOM) /* MS-windows convention */
return (ATOM) (unsigned) str;
if (str[0] == '#') { /* wine convention */
atom= (ATOM) atoi(&str[1]);
/* First check for integer atom */
if (!HIWORD(name)) return (ATOM)LOWORD(name);
str = (char *)PTR_SEG_TO_LIN( name );
if (str[0] == '#')
{
ATOM atom= (ATOM) atoi(&str[1]);
return (atom<MIN_STR_ATOM) ? atom : 0;
}
dprintf_atom(stddeb,"GlobalAddAtom(\"%s\")\n",str);
DDE_IPC_init(); /* will initialize only if needed */
......@@ -199,15 +205,21 @@ ATOM GlobalDeleteAtom( ATOM atom )
/***********************************************************************
* GlobalFindAtom (USER.270)
*/
ATOM GlobalFindAtom( LPCSTR str )
ATOM GlobalFindAtom( SEGPTR name )
{
int atom_idx;
int atom_ofs;
char *str;
dprintf_atom(stddeb,"GlobalFindAtom(%08lx)\n", name );
/* First check for integer atom */
if (!HIWORD(name)) return (ATOM)LOWORD(name);
dprintf_atom(stddeb,"GlobalFindAtom(%p)\n", str );
if ((unsigned) str < MIN_STR_ATOM) /* MS-windows convention */
return (ATOM) (unsigned) str;
if (str[0] == '#') { /* wine convention */
str = (char *)PTR_SEG_TO_LIN( name );
if (str[0] == '#')
{
ATOM atom= (ATOM) atoi(&str[1]);
return (atom<MIN_STR_ATOM) ? atom : 0;
}
......
......@@ -5,6 +5,7 @@
* Purpose : dynamically growing hash, may use shared or local memory.
***************************************************************************
*/
#include <sys/types.h>
#include <stdlib.h>
#include <assert.h>
#include "generic_hash.h"
......
......@@ -9,6 +9,7 @@
*/
#define inline __inline__
#include <sys/types.h>
#include <sys/sem.h>
#include <stdio.h>
#include <assert.h>
......
......@@ -8,6 +8,7 @@
***************************************************************************
*/
#define inline __inline__
#include <sys/types.h>
#include <sys/sem.h>
#include <stdio.h>
#include <time.h>
......@@ -62,7 +63,7 @@ static void print_shm_info(int shm_id)
}
int proc_exist(__pid_t pid)
int proc_exist(pid_t pid)
{
if ( kill(pid,0) == 0) /* dummy signal to test existence */
return 1;
......@@ -189,7 +190,9 @@ static int shm_locate_MainBlock(key_t shm_key)
}
} else {
switch(errno) {
#ifdef EIDRM
case EIDRM: /* segment destroyed */
#endif
case EACCES: /* no user permision */
break;
......
......@@ -9,7 +9,6 @@ SRCS = \
ne_resource.c \
pe_image.c \
pe_resource.c \
selector.c \
signal.c \
resource.c \
task.c
......
......@@ -10,7 +10,7 @@ LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
MODULE = loader
SRCS = main.c module.c ne_image.c ne_resource.c pe_image.c \
pe_resource.c selector.c signal.c resource.c task.c
pe_resource.c signal.c resource.c task.c
OBJS = $(SRCS:.c=.o)
......@@ -25,26 +25,16 @@ $(MODULE).o: $(OBJS)
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -57,18 +57,15 @@ int MAIN_Init(void)
/* Create built-in modules */
if (!MODULE_Init()) return 0;
/* Initialize the DOS file system */
DOS_InitFS();
/* Initialize tasks */
if (!TASK_Init()) return 0;
/* Initialize interrupt vectors */
if (!INT_Init()) return 0;
/* Initialize the DOS file system */
DOS_InitFS();
/* Create DOS environment */
CreateSelectors();
/* Initialize signal handling */
init_wine_signals();
......
......@@ -35,8 +35,6 @@ static HMODULE hCachedModule = 0; /* Module cached by MODULE_OpenFile */
*/
BOOL MODULE_Init(void)
{
extern void load_entrypoints( HMODULE );
HMODULE hModule;
NE_MODULE *pModule;
SEGTABLEENTRY *pSegTable;
......@@ -82,7 +80,6 @@ BOOL MODULE_Init(void)
pModule->next = hFirstModule;
hFirstModule = hModule;
load_entrypoints( hModule );
}
/* Initialize some KERNEL exported values */
......@@ -1169,6 +1166,22 @@ FARPROC GetProcAddress( HANDLE hModule, SEGPTR name )
}
/***********************************************************************
* GetWndProcEntry16 (not a Windows API function)
*
* Return an entry point from the WINPROCS dll.
*/
WNDPROC GetWndProcEntry16( char *name )
{
WORD ordinal;
static HMODULE hModule = 0;
if (!hModule) hModule = GetModuleHandle( "WINPROCS" );
ordinal = MODULE_GetOrdinal( hModule, name );
return MODULE_GetEntryPoint( hModule, ordinal );
}
/**********************************************************************
* ModuleFirst (TOOLHELP.59)
*/
......
......@@ -549,36 +549,33 @@ int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg)
if (hAccel == 0 || msg == NULL) return 0;
if (msg->message != WM_KEYDOWN &&
msg->message != WM_KEYUP &&
msg->message != WM_SYSKEYDOWN &&
msg->message != WM_SYSKEYUP &&
msg->message != WM_CHAR) return 0;
dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04X !\n", hAccel);
lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
for (i = 0; i < lpAccelTbl->wCount; i++) {
if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
msg->message == WM_KEYDOWN) {
if ((lpAccelTbl->tbl[i].type & SHIFT_ACCEL) &&
!(GetKeyState(VK_SHIFT) & 0xf)) {
GlobalUnlock(hAccel);
return 0;
}
if ((lpAccelTbl->tbl[i].type & CONTROL_ACCEL) &&
!(GetKeyState(VK_CONTROL) & 0xf)) {
if(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
if(msg->wParam == lpAccelTbl->tbl[i].wEvent &&
(msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)) {
INT mask = 0;
if(GetKeyState(VK_SHIFT) & 0xf) mask |= SHIFT_ACCEL;
if(GetKeyState(VK_CONTROL) & 0xf) mask |= CONTROL_ACCEL;
if(GetKeyState(VK_MENU) & 0xf) mask |= ALT_ACCEL;
if(mask == (lpAccelTbl->tbl[i].type &
(SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL))) {
SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval,
0x00010000L);
GlobalUnlock(hAccel);
return 0;
}
if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) &&
!(GetKeyState(VK_MENU) & 0xf)) {
GlobalUnlock(hAccel);
return 0;
}
SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
GlobalUnlock(hAccel);
return 1;
}
if (msg->message == WM_KEYUP) return 1;
return 1;
}
if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
return 1;
}
}
else {
if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
msg->message == WM_CHAR) {
......@@ -619,6 +616,8 @@ LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
i = min(buflen - 1, *p);
if (buffer == NULL)
return i;
if (i > 0) {
memcpy(buffer, p + 1, i);
buffer[i] = '\0';
......
/*
* Selector manipulation functions
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef WINELIB
#include "windows.h"
#include "global.h"
#include "module.h"
#include "stddebug.h"
/* #define DEBUG_SELECTORS */
#include "debug.h"
#define MAX_ENV_SIZE 16384 /* Max. environment size (ought to be dynamic) */
static HANDLE EnvironmentHandle = 0;
extern char WindowsPath[256];
extern char **environ;
WNDPROC GetWndProcEntry16( char *name )
{
WORD ordinal;
static HMODULE hModule = 0;
if (!hModule) hModule = GetModuleHandle( "WINPROCS" );
ordinal = MODULE_GetOrdinal( hModule, name );
return MODULE_GetEntryPoint( hModule, ordinal );
}
/***********************************************************************
* GetDOSEnvironment (KERNEL.131)
*/
SEGPTR GetDOSEnvironment(void)
{
return WIN16_GlobalLock( EnvironmentHandle );
}
/**********************************************************************
* CreateEnvironment
*/
static HANDLE CreateEnvironment(void)
{
HANDLE handle;
char **e;
char *p;
handle = GlobalAlloc( GMEM_MOVEABLE, MAX_ENV_SIZE );
if (!handle) return 0;
p = (char *) GlobalLock( handle );
/*
* Fill environment with Windows path, the Unix environment,
* and program name.
*/
strcpy(p, "PATH=");
strcat(p, WindowsPath);
p += strlen(p) + 1;
for (e = environ; *e; e++)
{
if (strncasecmp(*e, "path", 4))
{
strcpy(p, *e);
p += strlen(p) + 1;
}
}
*p++ = '\0';
/*
* Display environment
*/
p = (char *) GlobalLock( handle );
dprintf_selectors(stddeb, "Environment at %p\n", p);
for (; *p; p += strlen(p) + 1) dprintf_selectors(stddeb, " %s\n", p);
return handle;
}
/**********************************************************************
* CreateSelectors
*/
void CreateSelectors(void)
{
if(!EnvironmentHandle) EnvironmentHandle = CreateEnvironment();
}
#endif /* ifndef WINELIB */
......@@ -55,13 +55,15 @@ static void win_fault(int signal, int code, struct sigcontext *context)
#endif
if (signal != SIGTRAP)
{
if (CS == WINE_CODE_SELECTOR)
if (CS_reg(context) == WINE_CODE_SELECTOR)
{
fprintf(stderr, "Segmentation fault in Wine program (%x:%lx)."
" Please debug\n", CS, EIP );
" Please debug\n",
CS_reg(context), EIP_reg(context) );
}
else if (INSTR_EmulateInstruction( context )) return;
fprintf(stderr,"In win_fault %x:%lx\n", CS, EIP );
fprintf( stderr,"In win_fault %x:%lx\n",
CS_reg(context), EIP_reg(context) );
}
XUngrabPointer(display, CurrentTime);
XUngrabServer(display);
......
......@@ -10,6 +10,7 @@
#include "windows.h"
#include "task.h"
#include "callback.h"
#include "dos_fs.h"
#include "debugger.h"
#include "global.h"
#include "instance.h"
......@@ -36,6 +37,7 @@ static HTASK hCurrentTask = 0;
static HTASK hTaskToKill = 0;
static HTASK hLockedTask = 0;
static WORD nTaskCount = 0;
static HANDLE hDOSEnvironment = 0;
/* TASK_Reschedule() 16-bit entry point */
static FARPROC TASK_RescheduleProc;
......@@ -43,13 +45,122 @@ static FARPROC TASK_RescheduleProc;
#define TASK_SCHEDULE() CallTo16_word_(TASK_RescheduleProc,0)
static HANDLE TASK_CreateDOSEnvironment(void);
/***********************************************************************
* TASK_Init
*/
BOOL TASK_Init(void)
{
TASK_RescheduleProc = (FARPROC)GetWndProcEntry16( "TASK_Reschedule" );
return TRUE;
if (!(hDOSEnvironment = TASK_CreateDOSEnvironment()))
fprintf( stderr, "Not enough memory for DOS Environment\n" );
return (hDOSEnvironment != 0);
}
/***********************************************************************
* TASK_CreateDOSEnvironment
*
* Create the original DOS environment.
*/
static HANDLE TASK_CreateDOSEnvironment(void)
{
static const char program_name[] = "KRNL386.EXE";
char **e, *p;
int initial_size, size;
HANDLE handle;
extern char **environ;
extern char WindowsDirectory[], SystemDirectory[];
/* DOS environment format:
* ASCIIZ string 1
* ASCIIZ string 2
* ...
* ASCIIZ string n
* ASCIIZ PATH=xxx
* ASCIIZ windir=xxx
* BYTE 0
* WORD 1
* ASCIIZ program name (e.g. C:\WINDOWS\SYSTEM\KRNL386.EXE)
*/
/* First compute the size of the fixed part of the environment */
initial_size = 5 + /* PATH= */
strlen(WindowsPath) + 1 + /* path value */
7 + /* windir= */
strlen(WindowsDirectory) + 1 + /* windir value */
1 + /* BYTE 0 at end */
sizeof(WORD) + /* WORD 1 */
strlen(SystemDirectory) + 1 + /* program directory */
strlen(program_name) + 1; /* program name */
/* Compute the total size of the Unix environment (except path) */
for (e = environ, size = initial_size; *e; e++)
{
if (strncasecmp(*e, "path=", 5))
{
int len = strlen(*e) + 1;
if (size + len >= 32767)
{
fprintf( stderr, "Warning: environment larger than 32k.\n" );
break;
}
size += len;
}
}
/* Now allocate the environment */
if (!(handle = GlobalAlloc( GMEM_FIXED, size ))) return 0;
p = (char *)GlobalLock( handle );
/* And fill it with the Unix environment */
for (e = environ, size = initial_size; *e; e++)
{
if (strncasecmp(*e, "path=", 5))
{
int len = strlen(*e) + 1;
if (size + len >= 32767) break;
strcpy( p, *e );
size += len;
p += len;
}
}
/* Now add the path and Windows directory */
strcpy( p, "PATH=" );
strcat( p, WindowsPath );
p += strlen(p) + 1;
strcpy( p, "windir=" );
strcat( p, WindowsDirectory );
p += strlen(p) + 1;
/* Now add the program name */
*p++ = '\0';
*(WORD *)p = 1;
p += sizeof(WORD);
strcpy( p, SystemDirectory );
strcat( p, "\\" );
strcat( p, program_name );
/* Display it */
p = (char *) GlobalLock( handle );
dprintf_task(stddeb, "Master DOS environment at %p\n", p);
for (; *p; p += strlen(p) + 1) dprintf_task(stddeb, " %s\n", p);
dprintf_task( stddeb, "Progname: %s\n", p+3 );
return handle;
}
......@@ -229,7 +340,7 @@ static void TASK_CallToStart(void)
0 /*dx*/, 0 /*si*/, ds_reg /*di*/ );
/* This should never return */
fprintf( stderr, "TASK_CallToStart: Main program returned!\n" );
exit(1);
TASK_KillCurrentTask( 1 );
}
......@@ -241,6 +352,7 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
{
HTASK hTask;
TDB *pTask;
HANDLE hParentEnv;
NE_MODULE *pModule;
SEGTABLEENTRY *pSegTable;
LPSTR name;
......@@ -260,7 +372,24 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
if (!hTask) return 0;
pTask = (TDB *)GlobalLock( hTask );
/* get current directory */
/* Allocate the new environment block */
if (!(hParentEnv = hEnvironment))
{
TDB *pParent = (TDB *)GlobalLock( hCurrentTask );
hParentEnv = pParent ? pParent->pdb.environment : hDOSEnvironment;
}
/* FIXME: do we really need to make a copy also when */
/* we don't use the parent environment? */
if (!(hEnvironment = GlobalAlloc( GMEM_FIXED, GlobalSize( hParentEnv ) )))
{
GlobalFree( hTask );
return 0;
}
memcpy( GlobalLock( hEnvironment ), GlobalLock( hParentEnv ),
GlobalSize( hParentEnv ) );
/* Get current directory */
GetModuleFileName( hModule, filename, sizeof(filename) );
name = strrchr(filename, '\\');
......@@ -355,8 +484,8 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
pSegTable[pModule->ss-1].minsize + pModule->stack_size) & ~1;
stack16Top = (char *)PTR_SEG_OFF_TO_LIN( pTask->ss, pTask->sp );
frame16 = (STACK16FRAME *)stack16Top - 1;
frame16->saved_ss = pTask->ss;
frame16->saved_sp = pTask->sp;
frame16->saved_ss = 0; /*pTask->ss;*/
frame16->saved_sp = 0; /*pTask->sp;*/
frame16->ds = frame16->es = pTask->hInstance;
frame16->entry_point = 0;
frame16->ordinal_number = 24; /* WINPROCS.24 is TASK_Reschedule */
......@@ -380,8 +509,9 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
if (Options.debug)
{
DBG_ADDR addr = { pSegTable[pModule->cs-1].selector, pModule->ip };
fprintf( stderr, "Task '%s': ", name );
DEBUG_AddBreakpoint( pSegTable[pModule->cs-1].selector, pModule->ip );
DEBUG_AddBreakpoint( &addr );
}
/* Add the task to the linked list */
......@@ -844,6 +974,18 @@ int GetInstanceData( HANDLE instance, WORD buffer, int len )
/***********************************************************************
* GetDOSEnvironment (KERNEL.131)
*/
SEGPTR GetDOSEnvironment(void)
{
TDB *pTask;
if (!(pTask = (TDB *)GlobalLock( hCurrentTask ))) return 0;
return WIN16_GlobalLock( pTask->pdb.environment );
}
/***********************************************************************
* GetNumTasks (KERNEL.152)
*/
WORD GetNumTasks(void)
......
......@@ -3,10 +3,11 @@
MODULE = memory
SRCS = \
selector.c \
atom.c \
global.c \
ldt.c \
local.c
local.c \
selector.c
OBJS = $(SRCS:.c=.o)
......
......@@ -9,7 +9,12 @@ LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
MODULE = memory
SRCS = selector.c global.c ldt.c local.c
SRCS = \
atom.c \
global.c \
ldt.c \
local.c \
selector.c
OBJS = $(SRCS:.c=.o)
......@@ -24,26 +29,16 @@ $(MODULE).o: $(OBJS)
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -5,22 +5,10 @@
*/
/*
* Current limitations:
*
* - The code assumes that LocalAlloc() returns a block aligned on a
* 4-bytes boundary (because of the shifting done in HANDLETOATOM).
* If this is not the case, the allocation code will have to be changed.
*
* - Integer atoms created with MAKEINTATOM are not supported. This is
* because they can't generally be differentiated from string constants
* located below 0x10000 in the emulation library. If you need
* integer atoms, use the "#1234" form.
*
* 13/Feb, miguel
* Changed the calls to LocalAlloc to LocalAlign. When compiling WINELIB
* you call a special version of LocalAlloc that would do the alignement.
* When compiling the emulator we depend on LocalAlloc returning the
* aligned block. Needed to test the Library.
* Warning: The code assumes that LocalAlloc() returns a block aligned
* on a 4-bytes boundary (because of the shifting done in
* HANDLETOATOM). If this is not the case, the allocation code will
* have to be changed.
*/
#include <stdlib.h>
......@@ -130,20 +118,22 @@ static WORD ATOM_Hash( WORD entries, LPCSTR str, WORD len )
/***********************************************************************
* ATOM_AddAtom
*/
static ATOM ATOM_AddAtom( WORD selector, LPCSTR str )
static ATOM ATOM_AddAtom( WORD selector, SEGPTR name )
{
WORD hash;
HANDLE entry;
ATOMENTRY * entryPtr;
ATOMTABLE * table;
int len;
if ((len = strlen( str )) > 255) len = 255;
char *str;
/* Check for integer atom */
/* Check for integer atom */
/* if (!((int)str & 0xffff0000)) return (ATOM)((int)str & 0xffff); */
if (!HIWORD(name)) return (ATOM)LOWORD(name);
str = PTR_SEG_TO_LIN( name );
if (str[0] == '#') return atoi( &str[1] );
if ((len = strlen( str )) > 255) len = 255;
if (!(table = ATOM_GetTable( selector, TRUE ))) return 0;
hash = ATOM_Hash( table->size, str, len );
entry = table->entries[hash];
......@@ -210,19 +200,21 @@ static ATOM ATOM_DeleteAtom( WORD selector, ATOM atom )
/***********************************************************************
* ATOM_FindAtom
*/
static ATOM ATOM_FindAtom( WORD selector, LPCSTR str )
static ATOM ATOM_FindAtom( WORD selector, SEGPTR name )
{
ATOMTABLE * table;
WORD hash;
HANDLE entry;
int len;
if ((len = strlen( str )) > 255) len = 255;
/* Check for integer atom */
/* if (!((int)str & 0xffff0000)) return (ATOM)((int)str & 0xffff); */
char *str;
/* Check for integer atom */
if (!HIWORD(name)) return (ATOM)LOWORD(name);
str = PTR_SEG_TO_LIN( name );
if (str[0] == '#') return atoi( &str[1] );
if ((len = strlen( str )) > 255) len = 255;
if (!(table = ATOM_GetTable( selector, FALSE ))) return 0;
hash = ATOM_Hash( table->size, str, len );
entry = table->entries[hash];
......@@ -295,7 +287,7 @@ HANDLE GetAtomHandle( ATOM atom )
/***********************************************************************
* AddAtom (KERNEL.70)
*/
ATOM AddAtom( LPCSTR str )
ATOM AddAtom( SEGPTR str )
{
return ATOM_AddAtom( CURRENT_DS, str );
}
......@@ -313,7 +305,7 @@ ATOM DeleteAtom( ATOM atom )
/***********************************************************************
* FindAtom (KERNEL.69)
*/
ATOM FindAtom( LPCSTR str )
ATOM FindAtom( SEGPTR str )
{
return ATOM_FindAtom( CURRENT_DS, str );
}
......@@ -331,7 +323,7 @@ WORD GetAtomName( ATOM atom, LPSTR buffer, short count )
/***********************************************************************
* LocalAddAtom (USER.268)
*/
ATOM LocalAddAtom( LPCSTR str )
ATOM LocalAddAtom( SEGPTR str )
{
return ATOM_AddAtom( USER_HeapSel, str );
}
......@@ -349,7 +341,7 @@ ATOM LocalDeleteAtom( ATOM atom )
/***********************************************************************
* LocalFindAtom (USER.270)
*/
ATOM LocalFindAtom( LPCSTR str )
ATOM LocalFindAtom( SEGPTR str )
{
return ATOM_FindAtom( USER_HeapSel, str );
}
......
......@@ -4,6 +4,7 @@
* Copyright 1995 Alexandre Julliard
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
......@@ -13,6 +14,7 @@
#include "selectors.h"
#include "dde_mem.h"
#include "stackframe.h"
#include "options.h"
#include "stddebug.h"
#include "debug.h"
......@@ -128,7 +130,7 @@ HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size,
pArena->base = (DWORD)ptr;
pArena->size = GET_SEL_LIMIT(sel) + 1;
if (flags & GMEM_DDESHARE)
if ((flags & GMEM_DDESHARE) && Options.ipc)
{
pArena->handle = shmdata->handle;
pArena->shmid = shmdata->shmid;
......@@ -194,7 +196,7 @@ HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner,
/* Allocate the linear memory */
if (flags & GMEM_DDESHARE)
if ((flags & GMEM_DDESHARE) && Options.ipc)
ptr= DDE_malloc(flags, size, &shmdata);
else
ptr = malloc( size );
......@@ -266,7 +268,7 @@ HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags )
handle, size, flags );
if (!handle) return 0;
if (flags & GMEM_DDESHARE || is_dde_handle(handle)) {
if (Options.ipc && (flags & GMEM_DDESHARE || is_dde_handle(handle))) {
fprintf(stdnimp,
"GlobalReAlloc: shared memory reallocating unimplemented\n");
return 0;
......
......@@ -66,6 +66,7 @@ WORD FreeSelector( WORD sel )
{
WORD i, count;
ldt_entry entry;
STACK16FRAME *frame;
dprintf_selector( stddeb, "FreeSelector(%04x)\n", sel );
if (IS_SELECTOR_FREE(sel)) return sel; /* error */
......@@ -80,11 +81,12 @@ WORD FreeSelector( WORD sel )
/* Clear the saved 16-bit selector */
#ifndef WINELIB
if (CURRENT_STACK16)
frame = CURRENT_STACK16;
while (frame)
{
/* FIXME: maybe we ought to walk up the stack and fix all frames */
if (CURRENT_STACK16->ds == sel) CURRENT_STACK16->ds = 0;
if (CURRENT_STACK16->es == sel) CURRENT_STACK16->es = 0;
if (frame->ds == sel) frame->ds = 0;
if (frame->es == sel) frame->es = 0;
frame = PTR_SEG_OFF_TO_LIN(frame->saved_ss, frame->saved_sp);
}
#endif
return 0;
......
......@@ -3,7 +3,6 @@
MODULE = misc
SRCS = \
atom.c \
clipboard.c \
comm.c \
commdlg.c \
......
......@@ -11,7 +11,7 @@ LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
MODULE = misc
SRCS = atom.c clipboard.c comm.c commdlg.c compobj.c dos_fs.c \
SRCS = clipboard.c comm.c commdlg.c compobj.c dos_fs.c \
driver.c exec.c escape.c file.c keyboard.c kernel32.c lstr.c \
main.c ole2.c ole2disp.c ole2nls.c olecli.c olesvr.c network.c \
profile.c rect.c shell.c sound.c spy.c stress.c user.c \
......@@ -24,8 +24,8 @@ OBJS = $(SRCS:.c=.o)
all: checkrc $(MODULE).o
checkrc:
(cd $(TOPSRC)/rc; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
checkrc: dummy
cd $(TOPSRC)/rc; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)'
$(MODULE).o: $(OBJS)
$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
......@@ -33,27 +33,17 @@ $(MODULE).o: $(OBJS)
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
rm -f ole2nls.o shell.o commdlg.o
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -368,7 +368,7 @@ static LONG FILEDLG_WMInitDialog(HWND hWnd, WORD wParam, LONG lParam)
else
*tmpstr = 0;
if (!FILEDLG_ScanDir(hWnd, tmpstr))
fprintf(stderr, "FileDlg: couldn't read initial directory!\n");
fprintf(stderr, "FileDlg: couldn't read initial directory %s!\n", tmpstr);
/* select current drive in combo 2 */
n = DOS_GetDefaultDrive();
SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, n - 1, 0);
......
......@@ -124,6 +124,7 @@ void ToUnix(char *s)
{
while(*s){
if (*s == '\\') *s = '/';
*s=tolower(*s); /* umsdos fs can't read files without :( */
s++;
}
}
......@@ -188,7 +189,6 @@ void DOS_InitFS(void)
DosDrives[x].disabled = 0;
}
DosDrives[25].rootdir = "/";
strcpy(DosDrives[25].cwd, "/");
strcpy(DosDrives[25].label, "UNIX-FS");
DosDrives[25].serialnumber = 0x12345678;
DosDrives[25].disabled = 0;
......@@ -206,6 +206,7 @@ void DOS_InitFS(void)
getcwd(temp, 254);
strcat(temp, "/"); /* For DOS_GetDosFileName */
strcpy(DosDrives[25].cwd, temp );
strcpy(temp, DOS_GetDosFileName(temp));
if(temp[0] != 'Z')
{
......
......@@ -72,8 +72,8 @@ INT _lread (INT hFile, LPSTR lpBuffer, WORD wBytes)
{
int result;
dprintf_file(stddeb, "_lread: handle %d, buffer = %ld, length = %d\n",
hFile, (long) lpBuffer, wBytes);
dprintf_file(stddeb, "_lread: handle %d, buffer = %p, length = %d\n",
hFile, lpBuffer, wBytes);
result = wBytes == 0 ? 0 : read (hFile, lpBuffer, wBytes);
......@@ -90,10 +90,28 @@ INT _lwrite (INT hFile, LPCSTR lpBuffer, WORD wBytes)
{
int result;
dprintf_file(stddeb, "_lwrite: handle %d, buffer = %ld, length = %d\n",
hFile, (long) lpBuffer, wBytes);
dprintf_file(stddeb, "_lwrite: handle %d, buffer = %p, length = %d\n",
hFile, lpBuffer, wBytes);
result = wBytes == 0 ? 0 : write (hFile, lpBuffer, wBytes);
if(wBytes == 0) { /* Expand the file size if necessary */
char toWrite = 0;
off_t prev, end;
prev = lseek(hFile, 0, SEEK_CUR);
if(prev == -1) return HFILE_ERROR;
end = lseek(hFile, 0, SEEK_END);
if(end == -1) return HFILE_ERROR;
if(prev > end) {
lseek(hFile, prev-1, SEEK_SET);
result = write(hFile, &toWrite, 1) - 1;
if(result == -2) ++result;
}
else {
lseek(hFile, prev, SEEK_SET);
result = 0;
}
}
else result = write (hFile, lpBuffer, wBytes);
if (result == -1)
return HFILE_ERROR;
......@@ -325,7 +343,7 @@ INT _lcreat (LPSTR lpszFilename, INT fnAttribute)
lpszFilename, fnAttribute);
if ((UnixFileName = DOS_GetUnixFileName(lpszFilename)) == NULL)
return HFILE_ERROR;
handle = open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY, 0666);
handle = open (UnixFileName, O_CREAT | O_TRUNC | O_RDWR, 0666);
if (handle == -1)
return HFILE_ERROR;
......
......@@ -109,7 +109,7 @@ BOOL IsCharAlpha(char ch)
/* IsCharAlphanumeric USER 434 */
BOOL IsCharAlphanumeric(char ch)
{
return (ch<'0')?0:(ch<'9');
return (ch < '0') ? 0 : (ch <= '9');
}
/* IsCharUpper USER 435 */
......
......@@ -69,7 +69,8 @@ struct options Options =
SW_SHOWNORMAL, /* cmdShow */
FALSE,
FALSE, /* AllowReadOnly */
FALSE /* Enhanced mode */
FALSE, /* Enhanced mode */
FALSE /* IPC enabled */
};
......@@ -80,6 +81,7 @@ static XrmOptionDescRec optionsTable[] =
{ "-depth", ".depth", XrmoptionSepArg, (caddr_t)NULL },
{ "-display", ".display", XrmoptionSepArg, (caddr_t)NULL },
{ "-iconic", ".iconic", XrmoptionNoArg, (caddr_t)"on" },
{ "-ipc", ".ipc", XrmoptionNoArg, (caddr_t)"off"},
{ "-name", ".name", XrmoptionSepArg, (caddr_t)NULL },
{ "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" },
{ "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" },
......@@ -100,6 +102,7 @@ static XrmOptionDescRec optionsTable[] =
" -desktop geom Use a desktop window of the given geometry\n" \
" -display name Use the specified display\n" \
" -iconic Start as an icon\n" \
" -ipc Enable IPC facilities\n" \
" -debug Enter debugger before starting application\n" \
" -name name Set the application name\n" \
" -privatemap Use a private color map\n" \
......@@ -309,6 +312,8 @@ static void MAIN_ParseOptions( int *argc, char *argv[] )
Options.allowReadOnly = TRUE;
if (MAIN_GetResource( db, ".enhanced", &value ))
Options.enhanced = TRUE;
if (MAIN_GetResource( db, ".ipc", &value ))
Options.ipc = TRUE;
if (MAIN_GetResource( db, ".depth", &value))
screenDepth = atoi( value.addr );
if (MAIN_GetResource( db, ".desktop", &value))
......@@ -558,7 +563,7 @@ void MessageBeep(WORD i)
*/
LONG GetVersion(void)
{
return MAKELONG( WINVERSION, DOSVERSION );
return MAKELONG( WINVERSION, WINDOSVER );
}
/***********************************************************************
......
......@@ -134,6 +134,7 @@ static TSecHeader *load (char *filename, char **pfullname)
state = FirstBrace;
next = CharBuffer;
while ((c = fgetc (f)) != EOF){
if (c == '\r') /* Ignore Carriage Return */
continue;
......
......@@ -5,6 +5,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "windows.h"
#include "shell.h"
#include "neexe.h"
......@@ -17,7 +18,7 @@
LPKEYSTRUCT lphRootKey = NULL,lphTopKey = NULL;
static char RootKeyName[]=".classes", TopKeyName[] = "(null)";
static char RootKeyName[]=".classes", TopKeyName[] = "[top-null]";
/*************************************************************************
* SHELL_RegCheckForRoot() internal use only
......@@ -62,7 +63,7 @@ static LONG SHELL_RegCheckForRoot()
*/
LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
{
LPKEYSTRUCT lpKey;
LPKEYSTRUCT lpKey,lpNextKey;
LPCSTR ptr;
char str[128];
LONG dwRet;
......@@ -71,18 +72,21 @@ LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
if (dwRet != ERROR_SUCCESS) return dwRet;
dprintf_reg(stddeb, "RegOpenKey(%08lX, %p='%s', %p)\n",
hKey, lpSubKey, lpSubKey, lphKey);
if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
switch(hKey) {
case 0:
lpKey = lphTopKey; break;
case HKEY_CLASSES_ROOT: /* == 1 */
case 0x80000000:
lpKey = lphRootKey; break;
default:
dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", hKey);
lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
}
if (!*lpSubKey) { *lphKey = hKey; return ERROR_SUCCESS; }
if (lpSubKey == NULL || !*lpSubKey) {
*lphKey = hKey;
return ERROR_SUCCESS;
}
while(*lpSubKey) {
ptr = strchr(lpSubKey,'\\');
if (!ptr) ptr = lpSubKey + strlen(lpSubKey);
......@@ -91,8 +95,11 @@ LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
lpSubKey = ptr;
if (*lpSubKey) lpSubKey++;
lpKey = lpKey->lpSubLvl;
while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) { lpKey = lpKey->lpNextKey; }
lpNextKey = lpKey->lpSubLvl;
while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) {
lpKey = lpNextKey;
if (lpKey) lpNextKey = lpKey->lpNextKey;
}
if (lpKey == NULL) {
dprintf_reg(stddeb,"RegOpenKey: key %s not found!\n",str);
return ERROR_BADKEY;
......@@ -119,18 +126,21 @@ LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
dwRet = SHELL_RegCheckForRoot();
if (dwRet != ERROR_SUCCESS) return dwRet;
dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n", hKey, lpSubKey, lphKey);
if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
switch(hKey) {
case 0:
lpKey = lphTopKey; break;
case HKEY_CLASSES_ROOT: /* == 1 */
case 0x80000000:
lpKey = lphRootKey; break;
default:
dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", hKey);
lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
}
if (!*lpSubKey) { *lphKey = hKey; return ERROR_SUCCESS; }
if (lpSubKey == NULL || !*lpSubKey) {
*lphKey = hKey;
return ERROR_SUCCESS;
}
while (*lpSubKey) {
dprintf_reg(stddeb, "RegCreateKey: Looking for subkey %s\n", lpSubKey);
ptr = strchr(lpSubKey,'\\');
......@@ -210,7 +220,7 @@ LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType,
LONG dwRet;
dprintf_reg(stddeb, "RegSetValue(%08lX, '%s', %08lX, '%s', %08lX);\n",
hKey, lpSubKey, dwType, lpVal, dwIgnored);
if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
/*if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;*/
if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n");
......@@ -240,7 +250,7 @@ LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LONG FAR *lpcb)
int size;
dprintf_reg(stddeb, "RegQueryValue(%08lX, '%s', %p, %p);\n",
hKey, lpSubKey, lpVal, lpcb);
if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
/*if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;*/
if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
if (lpcb == NULL) return ERROR_INVALID_PARAMETER;
if (!*lpcb) return ERROR_INVALID_PARAMETER;
......@@ -285,12 +295,12 @@ LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize)
case 0:
lpKey = lphTopKey; break;
case HKEY_CLASSES_ROOT: /* == 1 */
case 0x80000000:
lpKey = lphRootKey; break;
default:
dprintf_reg(stddeb,"RegEnumKey // specific key = %08lX !\n", hKey);
lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
}
lpKey = lpKey->lpSubLvl;
while(lpKey != NULL){
if (!dwSubKey){
......@@ -301,7 +311,7 @@ LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize)
return ERROR_SUCCESS;
}
dwSubKey--;
lpKey = lpKey->lpNextKey;
lpKey = lpKey->lpNextKey;
}
dprintf_reg(stddeb, "RegEnumKey: key not found!\n");
return ERROR_INVALID_PARAMETER;
......@@ -351,30 +361,75 @@ BOOL DragQueryPoint(HDROP h, POINT FAR *p)
HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int iShowCmd)
{
char cmd[400];
char *p,*x;
long len;
char subclass[200];
/* OK. We are supposed to lookup the program associated with lpFile,
* then to execute it using that program. If lpFile is a program,
* we have to pass the parameters. If an instance is already running,
* we might have to send DDE commands.
*/
dprintf_exec(stddeb, "ShellExecute(%4X,'%s','%s','%s','%s',%x)\n",
hWnd, lpOperation ? lpOperation:"<null>", lpFile ? lpFile:"<null>",
lpParameters ? lpParameters : "<null>",
lpDirectory ? lpDirectory : "<null>", iShowCmd);
if(lpOperation && !strcasecmp(lpOperation,"print"))
{
fprintf(stderr, "Shell print %s: not supported\n", lpFile);
return 2; /* file not found */
}
if(lpOperation && !strcasecmp(lpOperation,"open"))
{
fprintf(stderr, "ShellExecute: Unknown operation %s\n",lpOperation);
return 2;
if (lpFile==NULL) return 0; /* should not happen */
if (lpOperation==NULL) /* default is open */
lpOperation="open";
p=strrchr(lpFile,'.');
if (p!=NULL) {
x=p; /* the suffixes in the register database are lowercased */
while (*x) {*x=tolower(*x);x++;}
}
/* OK. We are supposed to lookup the program associated with lpFile,
then to execute it using that program. If lpFile is a program,
we have to pass the parameters. If an instance is already running,
we might have to send DDE commands.
This implementation does none of that. It assumes lpFile is a program.
Plain WinExec will do what we need */
if(lpParameters)
if (p==NULL || !strcmp(p,".exe")) {
p=".exe";
if (lpParameters) {
sprintf(cmd,"%s %s",lpFile,lpParameters);
else
} else {
strcpy(cmd,lpFile);
}
} else {
len=200;
if (RegQueryValue(HKEY_CLASSES_ROOT,p,subclass,&len)==ERROR_SUCCESS) {
if (len>20)
fprintf(stddeb,"ShellExecute:subclass with len %ld? (%s), please report.\n",len,subclass);
subclass[len]='\0';
strcat(subclass,"\\shell\\");
strcat(subclass,lpOperation);
strcat(subclass,"\\command");
dprintf_exec(stddeb,"ShellExecute:looking for %s.\n",subclass);
len=400;
if (RegQueryValue(HKEY_CLASSES_ROOT,subclass,cmd,&len)==ERROR_SUCCESS) {
char *t;
dprintf_exec(stddeb,"ShellExecute:...got %s\n",cmd);
cmd[len]='\0';
t=strstr(cmd,"%1");
if (t==NULL) {
strcat(cmd," ");
strcat(cmd,lpFile);
} else {
char *s;
s=malloc(len+strlen(lpFile)+10);
strncpy(s,cmd,t-cmd);
strcat(s,lpFile);
strcat(s,t+2);
strcpy(cmd,s);
free(s);
}
/* does this use %x magic too? */
if (lpParameters) {
strcat(cmd," ");
strcat(cmd,lpParameters);
}
} else {
fprintf(stddeb,"ShellExecute: No %s\\shell\\%s\\command found for \"%s\" suffix.\n",subclass,lpOperation,p);
return 14; /* unknown type */
}
} else {
fprintf(stddeb,"ShellExecute: No operation found for \"%s\" suffix.\n",p);
return 14; /* file not found */
}
}
return WinExec(cmd,iShowCmd);
}
......
......@@ -26,26 +26,16 @@ $(MODULE).o: $(OBJS)
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -22,147 +22,153 @@
*
* Handler for int 31h (DPMI).
*/
void INT_Int31Handler( struct sigcontext_struct sigcontext )
void INT_Int31Handler( struct sigcontext_struct context )
{
#define context (&sigcontext)
DWORD dw;
BYTE *ptr;
ResetCflag;
switch(AX)
RESET_CFLAG(&context);
switch(AX_reg(&context))
{
case 0x0000: /* Allocate LDT descriptors */
if (!(AX = AllocSelectorArray( CX )))
if (!(AX_reg(&context) = AllocSelectorArray( CX_reg(&context) )))
{
AX = 0x8011; /* descriptor unavailable */
SetCflag;
AX_reg(&context) = 0x8011; /* descriptor unavailable */
SET_CFLAG(&context);
}
break;
case 0x0001: /* Free LDT descriptor */
if (FreeSelector( BX ))
if (FreeSelector( BX_reg(&context) ))
{
AX = 0x8022; /* invalid selector */
SetCflag;
AX_reg(&context) = 0x8022; /* invalid selector */
SET_CFLAG(&context);
}
break;
case 0x0003: /* Get next selector increment */
AX = __AHINCR;
AX_reg(&context) = __AHINCR;
break;
case 0x0004: /* Lock selector (not supported) */
AX = 0; /* FIXME: is this a correct return value? */
AX_reg(&context) = 0; /* FIXME: is this a correct return value? */
break;
case 0x0005: /* Unlock selector (not supported) */
AX = 0; /* FIXME: is this a correct return value? */
AX_reg(&context) = 0; /* FIXME: is this a correct return value? */
break;
case 0x0006: /* Get selector base address */
if (!(dw = GetSelectorBase( BX )))
if (!(dw = GetSelectorBase( BX_reg(&context) )))
{
AX = 0x8022; /* invalid selector */
SetCflag;
AX_reg(&context) = 0x8022; /* invalid selector */
SET_CFLAG(&context);
}
else
{
CX = HIWORD(dw);
DX = LOWORD(dw);
CX_reg(&context) = HIWORD(dw);
DX_reg(&context) = LOWORD(dw);
}
break;
case 0x0007: /* Set selector base address */
SetSelectorBase( BX, MAKELONG( DX, CX ) );
SetSelectorBase( BX_reg(&context),
MAKELONG( DX_reg(&context), CX_reg(&context) ) );
break;
case 0x0008: /* Set selector limit */
SetSelectorLimit( BX, MAKELONG( DX, CX ) );
SetSelectorLimit( BX_reg(&context),
MAKELONG( DX_reg(&context), CX_reg(&context) ) );
break;
case 0x0009: /* Set selector access rights */
SelectorAccessRights( BX, 1, CX );
SelectorAccessRights( BX_reg(&context), 1, CX_reg(&context) );
case 0x000a: /* Allocate selector alias */
if (!(AX = AllocCStoDSAlias( BX )))
if (!(AX_reg(&context) = AllocCStoDSAlias( BX_reg(&context) )))
{
AX = 0x8011; /* descriptor unavailable */
SetCflag;
AX_reg(&context) = 0x8011; /* descriptor unavailable */
SET_CFLAG(&context);
}
break;
case 0x000b: /* Get descriptor */
{
ldt_entry entry;
LDT_GetEntry( SELECTOR_TO_ENTRY(BX), &entry );
LDT_GetEntry( SELECTOR_TO_ENTRY( BX_reg(&context) ), &entry );
/* FIXME: should use ES:EDI for 32-bit clients */
LDT_EntryToBytes( PTR_SEG_OFF_TO_LIN( ES, DI ), &entry );
LDT_EntryToBytes( PTR_SEG_OFF_TO_LIN( ES_reg(&context),
DI_reg(&context) ), &entry );
}
break;
case 0x000c: /* Set descriptor */
{
ldt_entry entry;
LDT_BytesToEntry( PTR_SEG_OFF_TO_LIN( ES, DI ), &entry );
LDT_GetEntry( SELECTOR_TO_ENTRY(BX), &entry );
LDT_BytesToEntry( PTR_SEG_OFF_TO_LIN( ES_reg(&context),
DI_reg(&context) ), &entry );
LDT_GetEntry( SELECTOR_TO_ENTRY( BX_reg(&context) ), &entry );
}
break;
case 0x000d: /* Allocate specific LDT descriptor */
AX = 0x8011; /* descriptor unavailable */
SetCflag;
AX_reg(&context) = 0x8011; /* descriptor unavailable */
SET_CFLAG(&context);
break;
case 0x0204: /* Get protected mode interrupt vector */
dw = (DWORD)INT_GetHandler( BL );
CX = HIWORD(dw);
DX = LOWORD(dw);
dw = (DWORD)INT_GetHandler( BL_reg(&context) );
CX_reg(&context) = HIWORD(dw);
DX_reg(&context) = LOWORD(dw);
break;
case 0x0205: /* Set protected mode interrupt vector */
INT_SetHandler( BL, (SEGPTR)MAKELONG( DX, CX ) );
INT_SetHandler( BL_reg(&context),
(SEGPTR)MAKELONG( DX_reg(&context), CX_reg(&context) ));
break;
case 0x0400: /* Get DPMI version */
AX = 0x005a; /* DPMI version 0.90 */
BX = 0x0005; /* Flags: 32-bit, virtual memory */
CL = 3; /* CPU type: 386 */
DX = 0x0102; /* Master and slave interrupt controller base */
AX_reg(&context) = 0x005a; /* DPMI version 0.90 */
BX_reg(&context) = 0x0005; /* Flags: 32-bit, virtual memory */
CL_reg(&context) = 3; /* CPU type: 386 */
DX_reg(&context) = 0x0102; /* Master/slave interrupt controller base*/
break;
case 0x0500: /* Get free memory information */
ptr = (BYTE *)PTR_SEG_OFF_TO_LIN( ES, DI );
ptr = (BYTE *)PTR_SEG_OFF_TO_LIN( ES_reg(&context), DI_reg(&context) );
*(DWORD *)ptr = 0x00ff0000; /* Largest block available */
memset( ptr + 4, 0xff, 0x2c ); /* No other information supported */
break;
case 0x0501: /* Allocate memory block */
if (!(ptr = (BYTE *)malloc( MAKELONG( CX, BX ) )))
if (!(ptr = (BYTE *)malloc( MAKELONG( CX_reg(&context),
BX_reg(&context) ) )))
{
AX = 0x8012; /* linear memory not available */
SetCflag;
AX_reg(&context) = 0x8012; /* linear memory not available */
SET_CFLAG(&context);
}
else
{
BX = SI = HIWORD(ptr);
CX = DI = LOWORD(ptr);
BX_reg(&context) = SI_reg(&context) = HIWORD(ptr);
CX_reg(&context) = DI_reg(&context) = LOWORD(ptr);
}
break;
case 0x0502: /* Free memory block */
free( (void *)MAKELONG( DI, SI ) );
free( (void *)MAKELONG( DI_reg(&context), SI_reg(&context) ) );
break;
case 0x0503: /* Resize memory block */
if (!(ptr = (BYTE *)realloc( (void *)MAKELONG(DI,SI),MAKELONG(CX,BX))))
if (!(ptr = (BYTE *)realloc( (void *)MAKELONG(DI_reg(&context),SI_reg(&context)),
MAKELONG(CX_reg(&context),BX_reg(&context)))))
{
AX = 0x8012; /* linear memory not available */
SetCflag;
AX_reg(&context) = 0x8012; /* linear memory not available */
SET_CFLAG(&context);
}
else
{
BX = SI = HIWORD(ptr);
CX = DI = LOWORD(ptr);
BX_reg(&context) = SI_reg(&context) = HIWORD(ptr);
CX_reg(&context) = DI_reg(&context) = LOWORD(ptr);
}
break;
......@@ -173,10 +179,9 @@ void INT_Int31Handler( struct sigcontext_struct sigcontext )
break; /* Just ignore it */
default:
INT_BARF( 0x31 );
AX = 0x8001; /* unsupported function */
SetCflag;
INT_BARF( &context, 0x31 );
AX_reg(&context) = 0x8001; /* unsupported function */
SET_CFLAG(&context);
break;
}
#undef context
}
#include <stdlib.h>
#include <stdio.h>
#include "wine.h"
#include "miscemu.h"
#include "registers.h"
#include "stddebug.h"
/* #define DEBUG_INT */
#include "debug.h"
struct Win87EmInfoStruct {
unsigned short Version;
unsigned short SizeSaveArea;
unsigned short WinDataSeg;
unsigned short WinCodeSeg;
unsigned short Have80x87;
unsigned short Unused;
struct Win87EmInfoStruct
{
unsigned short Version;
unsigned short SizeSaveArea;
unsigned short WinDataSeg;
unsigned short WinCodeSeg;
unsigned short Have80x87;
unsigned short Unused;
};
void
WIN87_fpmath( struct sigcontext_struct sigcontext )
{
/* Declare a context pointer so that registers macros work */
struct sigcontext_struct *context = &sigcontext;
/* Implementing this is easy cause Linux and *BSD* ALWAYS have a numerical
* coprocessor. (either real or emulated on kernellevel)
*/
/* win87em.dll also sets interrupt vectors: 2 (NMI), 0x34 - 0x3f (emulator
* calls of standard libraries, see Ralph Browns interrupt list), 0x75
* (int13 error reporting of coprocessor)
*/
/* have a look at /usr/src/linux/arch/i386/math-emu/ *.[ch] for more info
* especially control_w.h and status_w.h
*/
/* FIXME: Only skeletal implementation for now */
dprintf_int(stddeb, "_fpmath: (%x:%lx %x %x)\n", CS, EIP, ES, BX );
void WIN87_fpmath( struct sigcontext_struct context )
{
dprintf_int(stddeb, "_fpmath: (cs:eip=%x:%lx es=%x bx=%04x ax=%04x dx==%04x)\n",
CS_reg(&context), EIP_reg(&context),
ES_reg(&context), BX_reg(&context),
AX_reg(&context), DX_reg(&context) );
switch(BX)
switch(BX_reg(&context))
{
case 11:
AX = 1;
case 0: /* install (increase instanceref) emulator, install NMI vector */
AX_reg(&context) = 0;
break;
case 1: /* Init Emulator */
AX_reg(&context) = 0;
break;
case 2: /* deinstall emulator (decrease instanceref), deinstall NMI vector
* if zero. Every '0' call should have a matching '2' call.
*/
AX_reg(&context) = 0;
break;
case 3:
/*INT_SetHandler(0x3E,MAKELONG(AX,DX));*/
break;
case 4: /* set control word (& ~(CW_Denormal|CW_Invalid)) */
/* OUT: newset control word in AX */
break;
case 5: /* return internal control word in AX */
break;
default:
AX = 0;
case 6: /* round top of stack to integer using method AX & 0x0C00 */
/* returns current controlword */
break;
case 7: /* POP top of stack as integer into DX:AX */
/* IN: AX&0x0C00 rounding protocol */
/* OUT: DX:AX variable popped */
{
DWORD dw,junk;
/* I don't know much about asm() programming. This could be
* wrong.
*/
__asm__("fistp %1\nwait":"=m" (junk):"m" (dw):"memory");
dprintf_int(stddeb,"emulate.c:On top of stack was %ld\n",dw);
AX_reg(&context) = LOWORD(dw);
DX_reg(&context) = HIWORD(dw);
}
break;
case 8: /* restore internal control words from emulator control word */
break;
case 9: /* clear emu control word and some other things */
break;
case 10: /* dunno. but looks like returning nr. of things on stack in AX */
break;
case 11: /* just returns the installed flag in DX:AX */
DX_reg(&context) = 0;
AX_reg(&context) = 1;
break;
case 12: /* save AX in some internal state var */
break;
default: /* error. Say that loud and clear */
AX_reg(&context) = DX_reg(&context) = 0xFFFF;
break;
}
}
void
WIN87_WinEm87Info(struct Win87EmInfoStruct *pWIS, int cbWin87EmInfoStruct)
{
......
......@@ -21,8 +21,8 @@ BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context )
int prefix, segprefix, repX, long_op, long_addr;
BYTE *instr;
long_op = long_addr = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) != 0;
instr = (BYTE *) PTR_SEG_OFF_TO_LIN( CS, long_op ? EIP : IP );
long_op = long_addr = (GET_SEL_FLAGS(CS_reg(context)) & LDT_FLAGS_32BIT) != 0;
instr = (BYTE *) PTR_SEG_OFF_TO_LIN( CS_reg(context), EIP_reg(context) );
/* First handle any possible prefix */
......@@ -34,22 +34,22 @@ BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context )
switch(*instr)
{
case 0x2e:
segprefix = CS;
segprefix = CS_reg(context);
break;
case 0x36:
segprefix = SS;
segprefix = SS_reg(context);
break;
case 0x3e:
segprefix = DS;
segprefix = DS_reg(context);
break;
case 0x26:
segprefix = ES;
segprefix = ES_reg(context);
break;
case 0x64:
segprefix = FS;
segprefix = FS_reg(context);
break;
case 0x65:
segprefix = GS;
segprefix = GS_reg(context);
break;
case 0x66:
long_op = !long_op; /* opcode size prefix */
......@@ -72,7 +72,7 @@ BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context )
if (prefix)
{
instr++;
EIP++;
EIP_reg(context)++;
}
}
......@@ -90,15 +90,16 @@ BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context )
{
SEGPTR addr = INT_GetHandler( instr[1] );
/* FIXME: should check the stack 'big' bit */
WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS_reg(context),
SP_reg(context) );
/* Push the flags and return address on the stack */
*(--stack) = FL;
*(--stack) = CS;
*(--stack) = IP + 2;
SP -= 3 * sizeof(WORD);
*(--stack) = FL_reg(context);
*(--stack) = CS_reg(context);
*(--stack) = IP_reg(context) + 2;
SP_reg(context) -= 3 * sizeof(WORD);
/* Jump to the interrupt handler */
CS = HIWORD(addr);
EIP = LOWORD(addr);
CS_reg(context) = HIWORD(addr);
EIP_reg(context) = LOWORD(addr);
}
break;
......@@ -106,73 +107,75 @@ BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context )
if (long_op)
{
/* FIXME: should check the stack 'big' bit */
DWORD *stack = (DWORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
EIP = *stack++;
CS = *stack++;
EFL = *stack;
SP += 3*sizeof(DWORD); /* Pop the return address and flags */
DWORD *stack = (DWORD *)PTR_SEG_OFF_TO_LIN( SS_reg(context),
SP_reg(context) );
EIP_reg(context) = *stack++;
CS_reg(context) = *stack++;
EFL_reg(context) = *stack;
SP_reg(context) += 3*sizeof(DWORD); /* Pop the return address and flags */
}
else
{
/* FIXME: should check the stack 'big' bit */
WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
EIP = *stack++;
CS = *stack++;
FL = *stack;
SP += 3*sizeof(WORD); /* Pop the return address and flags */
WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS_reg(context),
SP_reg(context) );
EIP_reg(context) = *stack++;
CS_reg(context) = *stack++;
FL_reg(context) = *stack;
SP_reg(context) += 3*sizeof(WORD); /* Pop the return address and flags */
}
break;
case 0xe4: /* inb al,XX */
AL = inport( instr[1], 1 );
EIP += 2;
AL_reg(context) = inport( instr[1], 1 );
EIP_reg(context) += 2;
break;
case 0xe5: /* in (e)ax,XX */
if (long_op) EAX = inport( instr[1], 4 );
else AX = inport( instr[1], 2 );
EIP += 2;
if (long_op) EAX_reg(context) = inport( instr[1], 4 );
else AX_reg(context) = inport( instr[1], 2 );
EIP_reg(context) += 2;
break;
case 0xe6: /* outb XX,al */
outport( instr[1], 1, AL );
EIP += 2;
outport( instr[1], 1, AL_reg(context) );
EIP_reg(context) += 2;
break;
case 0xe7: /* out XX,(e)ax */
if (long_op) outport( instr[1], 4, EAX );
else outport( instr[1], 2, AX );
EIP += 2;
if (long_op) outport( instr[1], 4, EAX_reg(context) );
else outport( instr[1], 2, AX_reg(context) );
EIP_reg(context) += 2;
break;
case 0xec: /* inb al,dx */
AL = inport( DX, 1 );
EIP++;
AL_reg(context) = inport( DX_reg(context), 1 );
EIP_reg(context)++;
break;
case 0xed: /* in (e)ax,dx */
if (long_op) EAX = inport( DX, 4 );
else AX = inport( DX, 2 );
EIP++;
if (long_op) EAX_reg(context) = inport( DX_reg(context), 4 );
else AX_reg(context) = inport( DX_reg(context), 2 );
EIP_reg(context)++;
break;
case 0xee: /* outb dx,al */
outport( DX, 1, AL );
EIP++;
outport( DX_reg(context), 1, AL_reg(context) );
EIP_reg(context)++;
break;
case 0xef: /* out dx,(e)ax */
if (long_op) outport( DX, 4, EAX );
else outport( DX, 2, AX );
EIP++;
if (long_op) outport( DX_reg(context), 4, EAX_reg(context) );
else outport( DX_reg(context), 2, AX_reg(context) );
EIP_reg(context)++;
break;
case 0xfa: /* cli, ignored */
EIP++;
EIP_reg(context)++;
break;
case 0xfb: /* sti, ignored */
EIP++;
EIP_reg(context)++;
break;
case 0x6c: /* insb */
......@@ -182,11 +185,12 @@ BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context )
{
int typ = *instr; /* Just in case it's overwritten. */
int outp = (typ >= 0x6e);
unsigned long count = repX ? (long_addr ? ECX : CX) : 1;
unsigned long count = repX ?
(long_addr ? ECX_reg(context) : CX_reg(context)) : 1;
int opsize = (typ & 1) ? (long_op ? 4 : 2) : 1;
int step = (EFL & 0x400) ? -opsize : +opsize;
/* FIXME: Check this, please. */
int seg = outp ? (segprefix >= 0 ? segprefix : DS) : ES;
int step = (EFL_reg(context) & 0x400) ? -opsize : +opsize;
int seg = outp ? (segprefix >= 0 ? segprefix : DS_reg(context))
: ES_reg(context);
if (outp)
/* FIXME: Check segment readable. */
......@@ -197,53 +201,51 @@ BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context )
if (repX)
if (long_addr)
ECX = 0;
ECX_reg(context) = 0;
else
CX = 0;
CX_reg(context) = 0;
while (count-- > 0)
{
void *data;
if (outp)
{
data = PTR_SEG_OFF_TO_LIN (seg, long_addr ? ESI : SI);
if (long_addr)
ESI += step;
else
SI += step;
}
{
data = PTR_SEG_OFF_TO_LIN (seg,
long_addr ? ESI_reg(context) : SI_reg(context));
if (long_addr) ESI_reg(context) += step;
else SI_reg(context) += step;
}
else
{
data = PTR_SEG_OFF_TO_LIN (seg, long_addr ? EDI : DI);
if (long_addr)
EDI += step;
else
DI += step;
}
{
data = PTR_SEG_OFF_TO_LIN (seg,
long_addr ? EDI_reg(context) : DI_reg(context));
if (long_addr) EDI_reg(context) += step;
else DI_reg(context) += step;
}
switch (typ)
{
{
case 0x6c:
*((BYTE *)data) = inport (DX, 1);
*((BYTE *)data) = inport( DX_reg(context), 1);
break;
case 0x6d:
if (long_op)
*((DWORD *)data) = inport (DX, 4);
*((DWORD *)data) = inport( DX_reg(context), 4);
else
*((WORD *)data) = inport (DX, 2);
*((WORD *)data) = inport( DX_reg(context), 2);
break;
case 0x6e:
outport (DX, 1, *((BYTE *)data));
outport( DX_reg(context), 1, *((BYTE *)data));
break;
case 0x6f:
if (long_op)
outport (DX, 4, *((DWORD *)data));
outport( DX_reg(context), 4, *((DWORD *)data));
else
outport (DX, 2, *((WORD *)data));
outport( DX_reg(context), 2, *((WORD *)data));
break;
}
}
EIP++;
EIP_reg(context)++;
break;
}
......
......@@ -13,29 +13,27 @@
*
* Handler for int 10h (video).
*/
void INT_Int10Handler( struct sigcontext_struct sigcontext )
void INT_Int10Handler( struct sigcontext_struct context )
{
#define context (&sigcontext)
switch(AH)
switch(AH_reg(&context))
{
case 0x0f:
AL = 0x5b;
AL_reg(&context) = 0x5b;
break;
case 0x12:
if (BL == 0x10)
if (BL_reg(&context) == 0x10)
{
BX = 0x0003;
CX = 0x0009;
BX_reg(&context) = 0x0003;
CX_reg(&context) = 0x0009;
}
break;
case 0x1a:
BX = 0x0008;
BX_reg(&context) = 0x0008;
break;
default:
INT_BARF( 0x10 );
INT_BARF( &context, 0x10 );
}
#undef context
}
......@@ -13,29 +13,28 @@
*
* Handler for int 13h (disk I/O).
*/
void INT_Int13Handler( struct sigcontext_struct sigcontext )
void INT_Int13Handler( struct sigcontext_struct context )
{
#define context (&sigcontext)
switch(AH)
switch(AH_reg(&context))
{
case 0x00: /* RESET DISK SYSTEM */
case 0x04: /* VERIFY DISK SECTOR(S) */
AH = 0;
AH_reg(&context) = 0;
break;
case 0x05: /* FORMAT TRACK */
AH = 0x0c;
SetCflag;
AH_reg(&context) = 0x0c;
SET_CFLAG(&context);
break;
case 0x06: /* FORMAT TRACK AND SET BAD SECTOR FLAGS */
case 0x07: /* FORMAT DRIVE STARTING AT GIVEN TRACK */
AH = 0x0c;
AH_reg(&context) = 0x0c;
break;
case 0x08: /* GET DRIVE PARAMETERS */
AH = (DL & 0x80) ? 0x07 : 0x01;
SetCflag;
AH_reg(&context) = (DL_reg(&context) & 0x80) ? 0x07 : 0x01;
SET_CFLAG(&context);
break;
case 0x09: /* INITIALIZE CONTROLLER WITH DRIVE PARAMETERS */
......@@ -44,19 +43,18 @@ void INT_Int13Handler( struct sigcontext_struct sigcontext )
case 0x10: /* CHECK IF DRIVE READY */
case 0x11: /* RECALIBRATE DRIVE */
case 0x14: /* CONTROLLER INTERNAL DIAGNOSTIC */
AH = 0;
AH_reg(&context) = 0;
break;
case 0x0e: /* READ SECTOR BUFFER (XT only) */
case 0x0f: /* WRITE SECTOR BUFFER (XT only) */
case 0x12: /* CONTROLLER RAM DIAGNOSTIC (XT,PS) */
case 0x13: /* DRIVE DIAGNOSTIC (XT,PS) */
AH = 0x01;
SetCflag;
AH_reg(&context) = 0x01;
SET_CFLAG(&context);
break;
default:
INT_BARF( 0x13 );
INT_BARF( &context, 0x13 );
}
#undef context
}
......@@ -19,15 +19,15 @@
*
* Handler for int 1ah (date and time).
*/
void INT_Int1aHandler( struct sigcontext_struct sigcontext )
void INT_Int1aHandler( struct sigcontext_struct context )
{
#define context (&sigcontext)
time_t ltime;
DWORD ticks;
struct tm *bdtime;
struct timeval tvs;
time_t ltime;
DWORD ticks;
struct tm *bdtime;
struct timeval tvs;
switch(AH) {
switch(AH_reg(&context))
{
case 0:
/* This should give us the (approximately) correct
* 18.206 clock ticks per second since midnight
......@@ -38,9 +38,9 @@ void INT_Int1aHandler( struct sigcontext_struct sigcontext )
ticks = (((bdtime->tm_hour * 3600 + bdtime->tm_min * 60 +
bdtime->tm_sec) * 18206) / 1000) +
(tvs.tv_usec / 54927);
CX = ticks >> 16;
DX = ticks & 0x0000FFFF;
AX = 0; /* No midnight rollover */
CX_reg(&context) = HIWORD(ticks);
DX_reg(&context) = LOWORD(ticks);
AX_reg(&context) = 0; /* No midnight rollover */
dprintf_int(stddeb,"int1a_00 // ticks=%ld\n", ticks);
break;
......@@ -48,14 +48,17 @@ void INT_Int1aHandler( struct sigcontext_struct sigcontext )
ltime = time(NULL);
bdtime = localtime(&ltime);
CX = (BIN_TO_BCD(bdtime->tm_hour)<<8) | BIN_TO_BCD(bdtime->tm_min);
DX = (BIN_TO_BCD(bdtime->tm_sec)<<8);
CX_reg(&context) = (BIN_TO_BCD(bdtime->tm_hour)<<8) |
BIN_TO_BCD(bdtime->tm_min);
DX_reg(&context) = (BIN_TO_BCD(bdtime->tm_sec)<<8);
case 4:
ltime = time(NULL);
bdtime = localtime(&ltime);
CX = (BIN_TO_BCD(bdtime->tm_year/100)<<8) | BIN_TO_BCD((bdtime->tm_year-1900)%100);
DX = (BIN_TO_BCD(bdtime->tm_mon)<<8) | BIN_TO_BCD(bdtime->tm_mday);
CX_reg(&context) = (BIN_TO_BCD(bdtime->tm_year/100)<<8) |
BIN_TO_BCD((bdtime->tm_year-1900)%100);
DX_reg(&context) = (BIN_TO_BCD(bdtime->tm_mon)<<8) |
BIN_TO_BCD(bdtime->tm_mday);
break;
/* setting the time,date or RTC is not allow -EB */
......@@ -72,7 +75,6 @@ void INT_Int1aHandler( struct sigcontext_struct sigcontext )
break;
default:
INT_BARF( 0x1a );
}
#undef context
INT_BARF( &context, 0x1a );
}
}
......@@ -178,28 +178,26 @@ static void GetFreeDiskSpace(struct sigcontext_struct *context)
int drive;
long size,available;
if (DL == 0)
drive = DOS_GetDefaultDrive();
else
drive = DL - 1;
if (DL_reg(context) == 0) drive = DOS_GetDefaultDrive();
else drive = DL_reg(context) - 1;
if (!DOS_ValidDrive(drive)) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
AX = 0xffff;
AX_reg(context) = 0xffff;
return;
}
if (!DOS_GetFreeSpace(drive, &size, &available)) {
Error(GeneralFailure, EC_MediaError , EL_Disk);
AX = 0xffff;
AX_reg(context) = 0xffff;
return;
}
AX = (drive < 2) ? 1 : 64; /* 64 for hard-disks, 1 for diskettes */
CX = 512;
AX_reg(context) = (drive < 2) ? 1 : 64; /* 64 for hard-disks, 1 for diskettes */
CX_reg(context) = 512;
BX = (available / (CX * AX));
DX = (size / (CX * AX));
BX_reg(context) = (available / (CX_reg(context) * AX_reg(context)));
DX_reg(context) = (size / (CX_reg(context) * AX_reg(context)));
Error (0,0,0);
}
......@@ -208,33 +206,32 @@ static void GetDriveAllocInfo(struct sigcontext_struct *context)
int drive;
long size, available;
if (DL == 0)
drive = DOS_GetDefaultDrive();
else
drive = DL - 1;
if (DL_reg(context) == 0) drive = DOS_GetDefaultDrive();
else drive = DL_reg(context) - 1;
if (!DOS_ValidDrive(DL)) {
AX = 4;
CX = 512;
DX = 0;
if (!DOS_ValidDrive(drive))
{
AX_reg(context) = 4;
CX_reg(context) = 512;
DX_reg(context) = 0;
Error (InvalidDrive, EC_MediaError, EL_Disk);
return;
}
if (!DOS_GetFreeSpace(DL, &size, &available)) {
if (!DOS_GetFreeSpace(drive, &size, &available)) {
Error(GeneralFailure, EC_MediaError , EL_Disk);
AX = 0xffff;
AX_reg(context) = 0xffff;
return;
}
AX = (drive < 2) ? 1 : 64; /* 64 for hard-disks, 1 for diskettes */
CX = 512;
DX = (size / (CX * AX));
AX_reg(context) = (drive < 2) ? 1 : 64; /* 64 for hard-disks, 1 for diskettes */
CX_reg(context) = 512;
DX_reg(context) = (size / (CX_reg(context) * AX_reg(context)));
heap->mediaID = 0xf0;
DS = DosHeapHandle;
BX = (int)&heap->mediaID - (int)heap;
DS_reg(context) = DosHeapHandle;
BX_reg(context) = (int)&heap->mediaID - (int)heap;
Error (0,0,0);
}
......@@ -243,7 +240,7 @@ static void GetDrivePB(struct sigcontext_struct *context, int drive)
if(!DOS_ValidDrive(drive))
{
Error (InvalidDrive, EC_MediaError, EL_Disk);
AX = 0x00ff;
AX_reg(context) = 0x00ff;
}
else
{
......@@ -274,9 +271,9 @@ static void GetDrivePB(struct sigcontext_struct *context, int drive)
dpb->free_search = 0;
dpb->free_clusters = 0xFFFF; /* unknown */
AL = 0x00;
DS = SELECTOROF(dpbsegptr);
BX = OFFSETOF(dpbsegptr);
AL_reg(context) = 0x00;
DS_reg(context) = SELECTOROF(dpbsegptr);
BX_reg(context) = OFFSETOF(dpbsegptr);
}
}
......@@ -286,38 +283,37 @@ static void ReadFile(struct sigcontext_struct *context)
int size;
/* can't read from stdout / stderr */
if ((BX == 1) || (BX == 2)) {
if ((BX_reg(context) == 1) || (BX_reg(context) == 2)) {
Error (InvalidHandle, EL_Unknown, EC_Unknown);
AX = InvalidHandle;
SetCflag;
dprintf_int(stddeb,
"int21: read (%d, void *, 0x%x) = EBADF\n", BX, CX);
AX_reg(context) = InvalidHandle;
SET_CFLAG(context);
dprintf_int(stddeb, "int21: read (%d, void *, 0x%x) = EBADF\n",
BX_reg(context), CX_reg(context));
return;
}
ptr = PTR_SEG_OFF_TO_LIN (DS,DX);
if (BX == 0) {
ptr = PTR_SEG_OFF_TO_LIN (DS_reg(context),DX_reg(context));
if (BX_reg(context) == 0) {
*ptr = EOF;
Error (0,0,0);
AX = 1;
ResetCflag;
dprintf_int(stddeb,
"int21: read (%d, void *, 0x%x) = EOF\n", BX, CX);
AX_reg(context) = 1;
RESET_CFLAG(context);
dprintf_int(stddeb, "int21: read (%d, void *, 0x%x) = EOF\n",
BX_reg(context), CX_reg(context));
return;
} else {
size = read(BX, ptr, CX);
dprintf_int(stddeb,
"int21: read (%d, void *, 0x%x) = 0x%x\n",
BX, CX, size);
size = read(BX_reg(context), ptr, CX_reg(context));
dprintf_int(stddeb, "int21: read (%d, void *, 0x%x) = 0x%x\n",
BX_reg(context), CX_reg(context), size);
if (size == -1) {
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(context) = ExtendedError;
SET_CFLAG(context);
return;
}
Error (0,0,0);
AX = size;
ResetCflag;
AX_reg(context) = size;
RESET_CFLAG(context);
}
}
......@@ -326,41 +322,41 @@ static void WriteFile(struct sigcontext_struct *context)
char *ptr;
int x,size;
ptr = PTR_SEG_OFF_TO_LIN (DS,DX);
ptr = PTR_SEG_OFF_TO_LIN (DS_reg(context),DX_reg(context));
if (BX == 0) {
if (BX_reg(context) == 0) {
Error (InvalidHandle, EC_Unknown, EL_Unknown);
EAX = InvalidHandle;
SetCflag;
EAX_reg(context) = InvalidHandle;
SET_CFLAG(context);
return;
}
if (BX < 3) {
for (x = 0;x != CX;x++) {
if (BX_reg(context) < 3) {
for (x = 0;x != CX_reg(context);x++) {
dprintf_int(stddeb, "%c", *ptr++);
}
fflush(stddeb);
Error (0,0,0);
AX = CX;
ResetCflag;
AX_reg(context) = CX_reg(context);
RESET_CFLAG(context);
} else {
size = write(BX, ptr , CX);
size = write(BX_reg(context), ptr , CX_reg(context));
if (size == 0) {
Error (WriteFault, EC_Unknown, EL_Unknown);
AX = ExtendedError;
AX_reg(context) = ExtendedError;
return;
}
if (size == -1) {
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(context) = ExtendedError;
SET_CFLAG(context);
return;
}
Error (0,0,0);
AX = size;
ResetCflag;
AX_reg(context) = size;
RESET_CFLAG(context);
}
}
......@@ -368,7 +364,8 @@ static void SeekFile(struct sigcontext_struct *context)
{
off_t status, fileoffset;
switch (AL) {
switch (AL_reg(context))
{
case 1: fileoffset = SEEK_CUR;
break;
case 2: fileoffset = SEEK_END;
......@@ -376,77 +373,79 @@ static void SeekFile(struct sigcontext_struct *context)
default:
case 0: fileoffset = SEEK_SET;
break;
}
status = lseek(BX, (CX << 16) + DX, fileoffset);
}
status = lseek(BX_reg(context), (CX_reg(context) << 16) + DX_reg(context), fileoffset);
dprintf_int (stddeb, "int21: seek (%d, 0x%x, %d) = 0x%lx\n",
BX, (CX << 16) + DX, AL, status);
BX_reg(context), (CX_reg(context) << 16) + DX_reg(context), AL_reg(context), status);
if (status == -1) {
if (status == -1)
{
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(context) = ExtendedError;
SET_CFLAG(context);
return;
}
Error (0,0,0);
AX = LOWORD(status);
DX = HIWORD(status);
ResetCflag;
AX_reg(context) = LOWORD(status);
DX_reg(context) = HIWORD(status);
RESET_CFLAG(context);
}
static void ioctlGetDeviceInfo(struct sigcontext_struct *context)
{
dprintf_int (stddeb, "int21: ioctl (%d, GetDeviceInfo)\n", BX);
dprintf_int (stddeb, "int21: ioctl (%d, GetDeviceInfo)\n", BX_reg(context));
switch (BX) {
switch (BX_reg(context))
{
case 0:
case 1:
case 2:
DX = 0x80d0 | (1 << (BX != 0));
ResetCflag;
DX_reg(context) = 0x80d0 | (1 << (BX_reg(context) != 0));
RESET_CFLAG(context);
break;
default:
{
struct stat sbuf;
if (fstat(BX, &sbuf) < 0)
if (fstat(BX_reg(context), &sbuf) < 0)
{
INT_BARF( 0x21 );
SetCflag;
INT_BARF( context, 0x21 );
SET_CFLAG(context);
return;
}
/* This isn't the right answer, but should be close enough. */
DX = 0x0943;
DX_reg(context) = 0x0943;
}
}
ResetCflag;
RESET_CFLAG(context);
}
static void ioctlGenericBlkDevReq(struct sigcontext_struct *context)
{
BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, DX);
BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
int drive;
if (BL == 0)
drive = DOS_GetDefaultDrive();
else
drive = BL - 1;
if (BL_reg(context) == 0) drive = DOS_GetDefaultDrive();
else drive = BL_reg(context) - 1;
if (!DOS_ValidDrive(drive)) {
if (!DOS_ValidDrive(drive))
{
Error( FileNotFound, EC_NotFound, EL_Disk );
AX = FileNotFound;
SetCflag;
AX_reg(context) = FileNotFound;
SET_CFLAG(context);
return;
}
if (CH != 0x08) {
INT_BARF( 0x21 );
if (CH_reg(context) != 0x08)
{
INT_BARF( context, 0x21 );
return;
}
switch (CL) {
switch (CL_reg(context)) {
case 0x60: /* get device parameters */
/* used by w4wgrp's winfile */
memset(dataptr, 0, 0x26);
......@@ -465,10 +464,10 @@ static void ioctlGenericBlkDevReq(struct sigcontext_struct *context)
setword(&dataptr[4], 80); /* # of cylinders */
}
CreateBPB(drive, &dataptr[7]);
ResetCflag;
RESET_CFLAG(context);
return;
default:
INT_BARF( 0x21 );
INT_BARF( context, 0x21 );
}
}
......@@ -480,9 +479,9 @@ static void GetSystemDate(struct sigcontext_struct *context)
ltime = time(NULL);
now = localtime(&ltime);
CX = now->tm_year + 1900;
DX = ((now->tm_mon + 1) << 8) | now->tm_mday;
AX = now->tm_wday;
CX_reg(context) = now->tm_year + 1900;
DX_reg(context) = ((now->tm_mon + 1) << 8) | now->tm_mday;
AX_reg(context) = now->tm_wday;
}
static void GetSystemTime(struct sigcontext_struct *context)
......@@ -493,32 +492,33 @@ static void GetSystemTime(struct sigcontext_struct *context)
gettimeofday(&tv,NULL); /* Note use of gettimeofday(), instead of time() */
now = localtime(&tv.tv_sec);
CX = (now->tm_hour<<8) | now->tm_min;
DX = (now->tm_sec<<8) | tv.tv_usec/10000;
CX_reg(context) = (now->tm_hour<<8) | now->tm_min;
DX_reg(context) = (now->tm_sec<<8) | tv.tv_usec/10000;
/* Note hundredths of seconds */
}
static void GetExtendedErrorInfo(struct sigcontext_struct *context)
{
AX = ExtendedError;
BX = (ErrorClass << 8) | Action;
CH = ErrorLocus;
AX_reg(context) = ExtendedError;
BX_reg(context) = (ErrorClass << 8) | Action;
CH_reg(context) = ErrorLocus;
}
static void CreateFile(struct sigcontext_struct *context)
{
int handle;
handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)),
handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),
DX_reg(context))),
O_CREAT | O_TRUNC | O_RDWR, 0666 );
if (handle == -1) {
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(context) = ExtendedError;
SET_CFLAG(context);
return;
}
Error (0,0,0);
AX = handle;
ResetCflag;
AX_reg(context) = handle;
RESET_CFLAG(context);
}
void OpenExistingFile(struct sigcontext_struct *context)
......@@ -527,7 +527,7 @@ void OpenExistingFile(struct sigcontext_struct *context)
int mode;
int lock;
switch (AX & 0x0007)
switch (AX_reg(context) & 0x0007)
{
case 0:
mode = O_RDONLY;
......@@ -542,27 +542,28 @@ void OpenExistingFile(struct sigcontext_struct *context)
break;
}
if ((handle = open(DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)),
if ((handle = open(DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context))),
mode)) == -1)
{
if( Options.allowReadOnly )
handle = open( DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)),
handle = open( DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context))),
O_RDONLY );
if( handle == -1 )
{
dprintf_int (stddeb, "int21: open (%s, %d) = -1\n",
DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)), mode);
DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context))), mode);
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(context) = ExtendedError;
SET_CFLAG(context);
return;
}
}
dprintf_int (stddeb, "int21: open (%s, %d) = %d\n",
DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)), mode, handle);
DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),
DX_reg(context))), mode, handle);
switch (AX & 0x0070)
switch (AX_reg(context) & 0x0070)
{
case 0x00: /* compatability mode */
case 0x40: /* DENYNONE */
......@@ -572,7 +573,7 @@ void OpenExistingFile(struct sigcontext_struct *context)
case 0x30: /* DENYREAD */
dprintf_int(stddeb,
"OpenExistingFile (%s): DENYREAD changed to DENYALL\n",
(char *)PTR_SEG_OFF_TO_LIN(DS,DX));
(char *)PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)));
case 0x10: /* DENYALL */
lock = LOCK_EX;
break;
......@@ -605,32 +606,33 @@ void OpenExistingFile(struct sigcontext_struct *context)
if(result)
{
errno_to_doserr();
AX = ExtendedError;
AX_reg(context) = ExtendedError;
close(handle);
SetCflag;
SET_CFLAG(context);
return;
}
}
Error (0,0,0);
AX = handle;
ResetCflag;
AX_reg(context) = handle;
RESET_CFLAG(context);
}
static void CloseFile(struct sigcontext_struct *context)
{
dprintf_int (stddeb, "int21: close (%d)\n", BX);
dprintf_int (stddeb, "int21: close (%d)\n", BX_reg(context));
if (close(BX) == -1) {
if (close(BX_reg(context)) == -1)
{
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(context) = ExtendedError;
SET_CFLAG(context);
return;
}
Error (0,0,0);
AX = NoError;
ResetCflag;
AX_reg(context) = NoError;
RESET_CFLAG(context);
}
static void RenameFile(struct sigcontext_struct *context)
......@@ -639,13 +641,16 @@ static void RenameFile(struct sigcontext_struct *context)
/* FIXME: should not rename over an existing file */
dprintf_int(stddeb,"int21: renaming %s to %s\n",
(char *)PTR_SEG_OFF_TO_LIN(DS,DX), (char *)PTR_SEG_OFF_TO_LIN(ES,DI) );
(char *)PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)),
(char *)PTR_SEG_OFF_TO_LIN(ES_reg(context),DI_reg(context)));
oldname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) );
newname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(ES,DI) );
oldname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),
DX_reg(context)) );
newname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(ES_reg(context),
DI_reg(context)) );
rename( oldname, newname);
ResetCflag;
RESET_CFLAG(context);
}
......@@ -653,28 +658,30 @@ static void MakeDir(struct sigcontext_struct *context)
{
char *dirname;
dprintf_int(stddeb,"int21: makedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS,DX) );
dprintf_int(stddeb,"int21: makedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)) );
if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ))== NULL) {
if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),
DX_reg(context)) ))== NULL) {
Error( CanNotMakeDir, EC_AccessDenied, EL_Disk );
AX = CanNotMakeDir;
SetCflag;
AX_reg(context) = CanNotMakeDir;
SET_CFLAG(context);
return;
}
if (mkdir(dirname,0) == -1) {
if (mkdir(dirname,0) == -1)
{
Error( CanNotMakeDir, EC_AccessDenied, EL_Disk );
AX = CanNotMakeDir;
SetCflag;
AX_reg(context) = CanNotMakeDir;
SET_CFLAG(context);
return;
}
ResetCflag;
RESET_CFLAG(context);
}
static void ChangeDir(struct sigcontext_struct *context)
{
int drive;
char *dirname = PTR_SEG_OFF_TO_LIN(DS,DX);
char *dirname = PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context));
drive = DOS_GetDefaultDrive();
dprintf_int(stddeb,"int21: changedir %s\n", dirname);
if (dirname != NULL && dirname[1] == ':') {
......@@ -683,8 +690,8 @@ static void ChangeDir(struct sigcontext_struct *context)
}
if (!DOS_ChangeDir(drive, dirname))
{
SetCflag;
AX=0x03;
SET_CFLAG(context);
AX_reg(context)=0x03;
}
}
......@@ -692,28 +699,28 @@ static void RemoveDir(struct sigcontext_struct *context)
{
char *dirname;
dprintf_int(stddeb,"int21: removedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS,DX) );
dprintf_int(stddeb,"int21: removedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)) );
if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ))== NULL) {
if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)) ))== NULL) {
Error( PathNotFound, EC_NotFound, EL_Disk );
AX = PathNotFound;
SetCflag;
AX_reg(context) = PathNotFound;
SET_CFLAG(context);
return;
}
/*
if (strcmp(unixname,DosDrives[drive].CurrentDirectory)) {
AL = CanNotRemoveCwd;
SetCflag;
SET_CFLAG(context);
}
*/
if (rmdir(dirname) == -1) {
Error( AccessDenied, EC_AccessDenied, EL_Disk );
AX = AccessDenied;
SetCflag;
AX_reg(context) = AccessDenied;
SET_CFLAG(context);
return;
}
ResetCflag;
RESET_CFLAG(context);
}
static void FindNext(struct sigcontext_struct *context)
......@@ -728,8 +735,8 @@ static void FindNext(struct sigcontext_struct *context)
do {
if ((dp = DOS_readdir(dp)) == NULL) {
Error(NoMoreFiles, EC_MediaError , EL_Disk);
AX = NoMoreFiles;
SetCflag;
AX_reg(context) = NoMoreFiles;
SET_CFLAG(context);
return;
}
} /* while (*(dta + 0x0c) != dp->attribute);*/
......@@ -746,8 +753,8 @@ static void FindNext(struct sigcontext_struct *context)
setdword(&dta[0x1a], dp->filesize);
strncpy(dta + 0x1e, dp->filename, 13);
AX = 0;
ResetCflag;
AX_reg(context) = 0;
RESET_CFLAG(context);
dprintf_int(stddeb, "int21: FindNext -- (%s) index=%d size=%ld\n", dp->filename, dp->entnum, dp->filesize);
return;
......@@ -755,7 +762,8 @@ static void FindNext(struct sigcontext_struct *context)
static void FindFirst(struct sigcontext_struct *context)
{
BYTE drive, *path = PTR_SEG_OFF_TO_LIN(DS, DX);
BYTE drive, *path = PTR_SEG_OFF_TO_LIN(DS_reg(context),
DX_reg(context));
struct dosdirent *dp;
BYTE *dta = GetCurrentDTA();
......@@ -767,8 +775,8 @@ static void FindFirst(struct sigcontext_struct *context)
if (!DOS_ValidDrive(drive)) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
AX = InvalidDrive;
SetCflag;
AX_reg(context) = InvalidDrive;
SET_CFLAG(context);
return;
}
} else
......@@ -776,16 +784,16 @@ static void FindFirst(struct sigcontext_struct *context)
*dta = drive;
memset(dta + 1 , '?', 11);
*(dta + 0x0c) = ECX & (FA_LABEL | FA_DIREC);
*(dta + 0x0c) = ECX_reg(context) & (FA_LABEL | FA_DIREC);
if ((dp = DOS_opendir(path)) == NULL) {
Error(PathNotFound, EC_MediaError, EL_Disk);
AX = FileNotFound;
SetCflag;
AX_reg(context) = FileNotFound;
SET_CFLAG(context);
return;
}
dp->search_attribute = ECX & (FA_LABEL | FA_DIREC);
dp->search_attribute = ECX_reg(context) & (FA_LABEL | FA_DIREC);
memcpy(dta + 0x11, &dp, sizeof(dp));
FindNext(context);
}
......@@ -795,14 +803,14 @@ static void GetFileDateTime(struct sigcontext_struct *context)
struct stat filestat;
struct tm *now;
fstat( BX, &filestat );
fstat( BX_reg(context), &filestat );
now = localtime (&filestat.st_mtime);
CX = ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2);
DX = (((now->tm_year + 1900 - 1980) * 0x200) +
CX_reg(context) = ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2);
DX_reg(context) = (((now->tm_year + 1900 - 1980) * 0x200) +
(now->tm_mon * 0x20) + now->tm_mday);
ResetCflag;
RESET_CFLAG(context);
}
static void SetFileDateTime(struct sigcontext_struct *context)
......@@ -812,13 +820,14 @@ static void SetFileDateTime(struct sigcontext_struct *context)
/* FIXME: Argument isn't the name of the file in DS:DX,
but the file handle in BX */
filename = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) );
filename = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),
DX_reg(context)) );
filetime.actime = 0L;
filetime.modtime = filetime.actime;
utime(filename, &filetime);
ResetCflag;
RESET_CFLAG(context);
}
static void CreateTempFile(struct sigcontext_struct *context)
......@@ -834,67 +843,68 @@ static void CreateTempFile(struct sigcontext_struct *context)
if (handle == -1) {
Error( WriteProtected, EC_AccessDenied, EL_Disk );
AX = WriteProtected;
SetCflag;
AX_reg(context) = WriteProtected;
SET_CFLAG(context);
return;
}
strcpy(PTR_SEG_OFF_TO_LIN(DS,DX), temp);
strcpy(PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)), temp);
AX = handle;
ResetCflag;
AX_reg(context) = handle;
RESET_CFLAG(context);
}
static void CreateNewFile(struct sigcontext_struct *context)
{
int handle;
if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ), O_CREAT | O_EXCL | O_RDWR, 0666)) == -1) {
if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(context),DX_reg(context)) ),
O_CREAT | O_EXCL | O_RDWR, 0666)) == -1)
{
Error( WriteProtected, EC_AccessDenied, EL_Disk );
AX = WriteProtected;
SetCflag;
AX_reg(context) = WriteProtected;
SET_CFLAG(context);
return;
}
AX = handle;
ResetCflag;
AX_reg(context) = handle;
RESET_CFLAG(context);
}
static void GetCurrentDirectory(struct sigcontext_struct *context)
{
int drive;
if (DL == 0)
drive = DOS_GetDefaultDrive();
else
drive = DL - 1;
if (DL_reg(context) == 0) drive = DOS_GetDefaultDrive();
else drive = DL_reg(context) - 1;
if (!DOS_ValidDrive(drive)) {
if (!DOS_ValidDrive(drive))
{
Error( InvalidDrive, EC_NotFound, EL_Disk );
AX = InvalidDrive;
SetCflag;
AX_reg(context) = InvalidDrive;
SET_CFLAG(context);
return;
}
strcpy(PTR_SEG_OFF_TO_LIN(DS,SI), DOS_GetCurrentDir(drive) );
ResetCflag;
strcpy(PTR_SEG_OFF_TO_LIN(DS_reg(context),SI_reg(context)),
DOS_GetCurrentDir(drive) );
RESET_CFLAG(context);
}
static void GetDiskSerialNumber(struct sigcontext_struct *context)
{
int drive;
BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, DX);
BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
DWORD serialnumber;
if (BL == 0)
drive = DOS_GetDefaultDrive();
else
drive = BL - 1;
if (BL_reg(context) == 0) drive = DOS_GetDefaultDrive();
else drive = BL_reg(context) - 1;
if (!DOS_ValidDrive(drive)) {
if (!DOS_ValidDrive(drive))
{
Error( InvalidDrive, EC_NotFound, EL_Disk );
AX = InvalidDrive;
SetCflag;
AX_reg(context) = InvalidDrive;
SET_CFLAG(context);
return;
}
......@@ -905,25 +915,24 @@ static void GetDiskSerialNumber(struct sigcontext_struct *context)
strncpy(dataptr + 6, DOS_GetVolumeLabel(drive), 8);
strncpy(dataptr + 0x11, "FAT16 ", 8);
AX = 0;
ResetCflag;
AX_reg(context) = 0;
RESET_CFLAG(context);
}
static void SetDiskSerialNumber(struct sigcontext_struct *context)
{
int drive;
BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, DX);
BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
DWORD serialnumber;
if (BL == 0)
drive = DOS_GetDefaultDrive();
else
drive = BL - 1;
if (BL_reg(context) == 0) drive = DOS_GetDefaultDrive();
else drive = BL_reg(context) - 1;
if (!DOS_ValidDrive(drive)) {
if (!DOS_ValidDrive(drive))
{
Error( InvalidDrive, EC_NotFound, EL_Disk );
AX = InvalidDrive;
SetCflag;
AX_reg(context) = InvalidDrive;
SET_CFLAG(context);
return;
}
......@@ -931,8 +940,8 @@ static void SetDiskSerialNumber(struct sigcontext_struct *context)
(dataptr[4] << 24);
DOS_SetSerialNumber(drive, serialnumber);
AX = 1;
ResetCflag;
AX_reg(context) = 1;
RESET_CFLAG(context);
}
static void DumpFCB(BYTE *fcb)
......@@ -953,7 +962,7 @@ static void DumpFCB(BYTE *fcb)
static void FindFirstFCB(struct sigcontext_struct *context)
{
BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS, DX);
BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
struct fcb *standard_fcb;
struct fcb *output_fcb;
int drive;
......@@ -981,7 +990,7 @@ static void FindFirstFCB(struct sigcontext_struct *context)
if (!DOS_ValidDrive(drive))
{
Error (InvalidDrive, EC_MediaError, EL_Disk);
AX = 0xff;
AX_reg(context) = 0xff;
return;
}
}
......@@ -999,7 +1008,7 @@ static void FindFirstFCB(struct sigcontext_struct *context)
if (DOS_GetVolumeLabel(drive) != NULL)
{
strncpy(output_fcb->name, DOS_GetVolumeLabel(drive), 11);
AX = 0x00;
AX_reg(context) = 0x00;
return;
}
}
......@@ -1013,7 +1022,7 @@ static void FindFirstFCB(struct sigcontext_struct *context)
if ((output_fcb->directory = DOS_opendir(path))==NULL)
{
Error (PathNotFound, EC_MediaError, EL_Disk);
AX = 0xff;
AX_reg(context) = 0xff;
return;
}
......@@ -1022,7 +1031,7 @@ static void FindFirstFCB(struct sigcontext_struct *context)
static void DeleteFileFCB(struct sigcontext_struct *context)
{
BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS, DX);
BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
int drive;
struct dosdirent *dp;
char temp[256], *ptr;
......@@ -1043,7 +1052,7 @@ static void DeleteFileFCB(struct sigcontext_struct *context)
if ((dp = DOS_opendir(temp)) == NULL) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
AX = 0xff;
AX_reg(context) = 0xff;
return;
}
......@@ -1059,12 +1068,12 @@ static void DeleteFileFCB(struct sigcontext_struct *context)
/* unlink(DOS_GetUnixFileName(temp)); */
}
DOS_closedir(dp);
AX = 0;
AX_reg(context) = 0;
}
static void RenameFileFCB(struct sigcontext_struct *context)
{
BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS, DX);
BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context));
int drive;
struct dosdirent *dp;
char temp[256], oldname[256], newname[256], *oldnameptr, *newnameptr;
......@@ -1085,7 +1094,7 @@ static void RenameFileFCB(struct sigcontext_struct *context)
if ((dp = DOS_opendir(temp)) == NULL) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
AX = 0xff;
AX_reg(context) = 0xff;
return;
}
......@@ -1105,7 +1114,7 @@ static void RenameFileFCB(struct sigcontext_struct *context)
oldname, newname);
}
DOS_closedir(dp);
AX = 0;
AX_reg(context) = 0;
}
......@@ -1115,12 +1124,12 @@ static void fLock (struct sigcontext_struct * context)
struct flock f;
int result,retries=sharing_retries;
f.l_start = MAKELONG(DX,CX);
f.l_len = MAKELONG(DI,SI);
f.l_start = MAKELONG(DX_reg(context),CX_reg(context));
f.l_len = MAKELONG(DI_reg(context),SI_reg(context));
f.l_whence = 0;
f.l_pid = 0;
switch ( AX & 0xff )
switch ( AX_reg(context) & 0xff )
{
case 0x00: /* LOCK */
f.l_type = F_WRLCK;
......@@ -1131,13 +1140,13 @@ static void fLock (struct sigcontext_struct * context)
break;
default:
AX = 0x0001;
SetCflag;
AX_reg(context) = 0x0001;
SET_CFLAG(context);
return;
}
{
result = fcntl(BX,F_SETLK,&f);
result = fcntl(BX_reg(context),F_SETLK,&f);
if ( retries && (!result) )
{
int i;
......@@ -1152,19 +1161,19 @@ static void fLock (struct sigcontext_struct * context)
if(result)
{
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(context) = ExtendedError;
SET_CFLAG(context);
return;
}
Error (0,0,0);
ResetCflag;
RESET_CFLAG(context);
}
static void GetFileAttribute (struct sigcontext_struct * context)
{
char *filename = PTR_SEG_OFF_TO_LIN (DS,DX);
char *filename = PTR_SEG_OFF_TO_LIN (DS_reg(context),DX_reg(context));
struct stat s;
int res;
......@@ -1172,21 +1181,21 @@ static void GetFileAttribute (struct sigcontext_struct * context)
if (res==-1)
{
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(context) = ExtendedError;
SET_CFLAG(context);
return;
}
CX = 0;
CX_reg(context) = 0;
if (S_ISDIR(s.st_mode))
CX |= 0x10;
CX_reg(context) |= 0x10;
if ((S_IWRITE & s.st_mode) != S_IWRITE)
CX |= 0x01;
CX_reg(context) |= 0x01;
dprintf_int (stddeb, "int21: GetFileAttributes (%s) = 0x%x\n",
filename, CX );
filename, CX_reg(context) );
ResetCflag;
RESET_CFLAG(context);
Error (0,0,0);
}
......@@ -1196,20 +1205,19 @@ extern void LOCAL_PrintHeap (WORD ds);
/***********************************************************************
* DOS3Call (KERNEL.102)
*/
void DOS3Call( struct sigcontext_struct sigcontext )
void DOS3Call( struct sigcontext_struct context )
{
#define context (&sigcontext)
int drive;
if (AH == 0x59)
if (AH_reg(&context) == 0x59)
{
GetExtendedErrorInfo(context);
GetExtendedErrorInfo(&context);
return;
}
else
{
Error (0,0,0);
switch(AH)
switch(AH_reg(&context))
{
case 0x00: /* TERMINATE PROGRAM */
TASK_KillCurrentTask( 0 );
......@@ -1242,16 +1250,14 @@ void DOS3Call( struct sigcontext_struct sigcontext )
case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */
case 0x29: /* PARSE FILENAME INTO FCB */
case 0x2e: /* SET VERIFY FLAG */
INT_BARF( 0x21 );
INT_BARF( &context, 0x21 );
break;
case 0x2b: /* SET SYSTEM DATE */
case 0x2d: /* SET SYSTEM TIME */
case 0x37: /* "SWITCHAR" - GET SWITCH CHARACTER
"SWITCHAR" - SET SWITCH CHARACTER
"AVAILDEV" - SPECIFY \DEV\ PREFIX USE */
case 0x54: /* GET VERIFY FLAG */
INT_BARF( 0x21 );
INT_BARF( &context, 0x21 );
break;
case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */
......@@ -1259,473 +1265,494 @@ void DOS3Call( struct sigcontext_struct sigcontext )
case 0x1e:
case 0x20:
case 0x6b: /* NULL FUNCTION */
AL = 0;
AL_reg(&context) = 0;
break;
case 0x5c: /* "FLOCK" - RECORD LOCKING */
fLock(context);
fLock(&context);
break;
case 0x0d: /* DISK BUFFER FLUSH */
ResetCflag; /* dos 6+ only */
RESET_CFLAG(&context); /* dos 6+ only */
break;
case 0x0e: /* SELECT DEFAULT DRIVE */
if (!DOS_ValidDrive(DL))
if (!DOS_ValidDrive(DL_reg(&context)))
Error (InvalidDrive, EC_MediaError, EL_Disk);
else
{
DOS_SetDefaultDrive(DL);
DOS_SetDefaultDrive(DL_reg(&context));
Error(0,0,0);
}
AL = MAX_DOS_DRIVES;
AL_reg(&context) = MAX_DOS_DRIVES;
break;
case 0x11: /* FIND FIRST MATCHING FILE USING FCB */
FindFirstFCB(context);
FindFirstFCB(&context);
break;
case 0x13: /* DELETE FILE USING FCB */
DeleteFileFCB(context);
DeleteFileFCB(&context);
break;
case 0x17: /* RENAME FILE USING FCB */
RenameFileFCB(context);
RenameFileFCB(&context);
break;
case 0x19: /* GET CURRENT DEFAULT DRIVE */
AL = DOS_GetDefaultDrive();
AL_reg(&context) = DOS_GetDefaultDrive();
Error (0,0,0);
break;
case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */
{
TDB *pTask = (TDB *)GlobalLock( GetCurrentTask() );
pTask->dta = MAKELONG( DX, DS );
pTask->dta = MAKELONG( DX_reg(&context), DS_reg(&context) );
dprintf_int(stddeb, "int21: Set DTA: %08lx\n", pTask->dta);
}
break;
case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
DL = 0;
GetDriveAllocInfo(context);
DL_reg(&context) = 0;
GetDriveAllocInfo(&context);
break;
case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */
GetDriveAllocInfo(context);
GetDriveAllocInfo(&context);
break;
case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */
GetDrivePB(context, DOS_GetDefaultDrive());
GetDrivePB(&context, DOS_GetDefaultDrive());
break;
case 0x25: /* SET INTERRUPT VECTOR */
INT_SetHandler( AL, MAKELONG( DX, DS ) );
INT_SetHandler( AL_reg(&context),
MAKELONG( DX_reg(&context), DS_reg(&context) ) );
break;
case 0x2a: /* GET SYSTEM DATE */
GetSystemDate(context);
GetSystemDate(&context);
break;
case 0x2b: /* SET SYSTEM DATE */
fprintf( stdnimp, "SetSystemDate(%02d/%02d/%04d): not allowed\n",
DL_reg(&context), DH_reg(&context), CX_reg(&context) );
AL_reg(&context) = 0; /* Let's pretend we succeeded */
break;
case 0x2c: /* GET SYSTEM TIME */
GetSystemTime(context);
GetSystemTime(&context);
break;
case 0x2d: /* SET SYSTEM TIME */
fprintf( stdnimp, "SetSystemTime(%02d:%02d:%02d.%02d): not allowed\n",
CH_reg(&context), CL_reg(&context),
DH_reg(&context), DL_reg(&context) );
AL_reg(&context) = 0; /* Let's pretend we succeeded */
break;
case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
{
TDB *pTask = (TDB *)GlobalLock( GetCurrentTask() );
ES = SELECTOROF( pTask->dta );
BX = OFFSETOF( pTask->dta );
ES_reg(&context) = SELECTOROF( pTask->dta );
BX_reg(&context) = OFFSETOF( pTask->dta );
}
break;
case 0x30: /* GET DOS VERSION */
AX = DOSVERSION;
BX = 0x0012; /* 0x123456 is Wine's serial # */
CX = 0x3456;
AX_reg(&context) = DOSVERSION;
BX_reg(&context) = 0x0012; /* 0x123456 is Wine's serial # */
CX_reg(&context) = 0x3456;
break;
case 0x31: /* TERMINATE AND STAY RESIDENT */
INT_BARF( 0x21 );
INT_BARF( &context, 0x21 );
break;
case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
GetDrivePB(context, (DL == 0) ? (DOS_GetDefaultDrive()) : (DL-1));
GetDrivePB(&context, (DL_reg(&context) == 0) ?
(DOS_GetDefaultDrive()) : (DL_reg(&context)-1));
break;
case 0x33: /* MULTIPLEXED */
switch (AL) {
switch (AL_reg(&context))
{
case 0x00: /* GET CURRENT EXTENDED BREAK STATE */
DL = 0;
DL_reg(&context) = 0;
break;
case 0x01: /* SET EXTENDED BREAK STATE */
break;
case 0x02: /* GET AND SET EXTENDED CONTROL-BREAK CHECKING STATE*/
DL = 0;
DL_reg(&context) = 0;
break;
case 0x05: /* GET BOOT DRIVE */
DL = 2;
DL_reg(&context) = 2;
/* c: is Wine's bootdrive */
break;
case 0x06: /* GET TRUE VERSION NUMBER */
BX = DOSVERSION;
DX = 0x00;
BX_reg(&context) = DOSVERSION;
DX_reg(&context) = 0x00;
break;
default:
INT_BARF( 0x21 );
INT_BARF( &context, 0x21 );
break;
}
break;
case 0x34: /* GET ADDRESS OF INDOS FLAG */
ES = DosHeapHandle;
BX = (int)&heap->InDosFlag - (int)heap;
ES_reg(&context) = DosHeapHandle;
BX_reg(&context) = (int)&heap->InDosFlag - (int)heap;
break;
case 0x35: /* GET INTERRUPT VECTOR */
{
SEGPTR addr = INT_GetHandler( AL );
ES = SELECTOROF(addr);
BX = OFFSETOF(addr);
SEGPTR addr = INT_GetHandler( AL_reg(&context) );
ES_reg(&context) = SELECTOROF(addr);
BX_reg(&context) = OFFSETOF(addr);
}
break;
case 0x36: /* GET FREE DISK SPACE */
GetFreeDiskSpace(context);
GetFreeDiskSpace(&context);
break;
case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */
AX = 0x02; /* no country support available */
SetCflag;
AX_reg(&context) = 0x02; /* no country support available */
SET_CFLAG(&context);
break;
case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
MakeDir(context);
MakeDir(&context);
break;
case 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */
RemoveDir(context);
RemoveDir(&context);
break;
case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
ChangeDir(context);
ChangeDir(&context);
break;
case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */
CreateFile(context);
CreateFile(&context);
break;
case 0x3d: /* "OPEN" - OPEN EXISTING FILE */
OpenExistingFile(context);
OpenExistingFile(&context);
break;
case 0x3e: /* "CLOSE" - CLOSE FILE */
CloseFile(context);
CloseFile(&context);
break;
case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */
ReadFile(context);
ReadFile(&context);
break;
case 0x40: /* "WRITE" - WRITE TO FILE OR DEVICE */
WriteFile(context);
WriteFile(&context);
break;
case 0x41: /* "UNLINK" - DELETE FILE */
if (unlink( DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)) ) == -1) {
if (unlink( DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS_reg(&context),DX_reg(&context))) ) == -1) {
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(&context) = ExtendedError;
SET_CFLAG(&context);
break;
}
Error(0,0,0);
ResetCflag;
RESET_CFLAG(&context);
break;
case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */
SeekFile(context);
SeekFile(&context);
break;
case 0x43: /* FILE ATTRIBUTES */
switch (AL)
switch (AL_reg(&context))
{
case 0x00:
GetFileAttribute(context);
GetFileAttribute(&context);
break;
case 0x01:
ResetCflag;
RESET_CFLAG(&context);
break;
}
break;
case 0x44: /* IOCTL */
switch (AL)
switch (AL_reg(&context))
{
case 0x00:
ioctlGetDeviceInfo(context);
ioctlGetDeviceInfo(&context);
break;
case 0x08: /* Check if drive is removable. */
drive = BL ? (BL - 1) : DOS_GetDefaultDrive();
drive = BL_reg(&context) ? (BL_reg(&context) - 1)
: DOS_GetDefaultDrive();
if(!DOS_ValidDrive(drive))
{
Error( InvalidDrive, EC_NotFound, EL_Disk );
AX = InvalidDrive;
SetCflag;
AX_reg(&context) = InvalidDrive;
SET_CFLAG(&context);
}
else
{
if (drive > 1)
AX = 1; /* not removable */
AX_reg(&context) = 1; /* not removable */
else
AX = 0; /* removable */
ResetCflag;
AX_reg(&context) = 0; /* removable */
RESET_CFLAG(&context);
}
break;
case 0x09: /* CHECK IF BLOCK DEVICE REMOTE */
drive = BL ? (BL - 1) : DOS_GetDefaultDrive();
drive = BL_reg(&context) ? (BL_reg(&context) - 1)
: DOS_GetDefaultDrive();
if(!DOS_ValidDrive(drive))
{
Error( InvalidDrive, EC_NotFound, EL_Disk );
AX = InvalidDrive;
SetCflag;
AX_reg(&context) = InvalidDrive;
SET_CFLAG(&context);
}
else
{
DX = (1<<9) | (1<<12) | (1<<15);
ResetCflag;
DX_reg(&context) = (1<<9) | (1<<12) | (1<<15);
RESET_CFLAG(&context);
}
break;
case 0x0b: /* SET SHARING RETRY COUNT */
if (!CX)
if (!CX_reg(&context))
{
AX = 1;
SetCflag;
AX_reg(&context) = 1;
SET_CFLAG(&context);
break;
}
sharing_pause = CX;
if (!DX)
sharing_retries = DX;
ResetCflag;
sharing_pause = CX_reg(&context);
if (!DX_reg(&context))
sharing_retries = DX_reg(&context);
RESET_CFLAG(&context);
break;
case 0x0d:
ioctlGenericBlkDevReq(context);
ioctlGenericBlkDevReq(&context);
break;
case 0x0F: /* Set logical drive mapping */
/* FIXME: Not implemented at the moment, always returns error
*/
AX = 0x0001; /* invalid function */
SetCflag;
AX_reg(&context) = 0x0001; /* invalid function */
SET_CFLAG(&context);
break;
default:
INT_BARF( 0x21 );
INT_BARF( &context, 0x21 );
break;
}
break;
case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */
if ((AX = dup(BX)) == 0xffff)
if ((AX_reg(&context) = dup(BX_reg(&context))) == 0xffff)
{
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(&context) = ExtendedError;
SET_CFLAG(&context);
}
else ResetCflag;
else RESET_CFLAG(&context);
break;
case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
if (dup2( BX, CX ) == -1)
if (dup2( BX_reg(&context), CX_reg(&context) ) == -1)
{
errno_to_doserr();
AX = ExtendedError;
SetCflag;
AX_reg(&context) = ExtendedError;
SET_CFLAG(&context);
}
else ResetCflag;
else RESET_CFLAG(&context);
break;
case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
GetCurrentDirectory(context);
AX = 0x0100;
GetCurrentDirectory(&context);
AX_reg(&context) = 0x0100;
/* intlist: many Microsoft products for Windows rely on this */
break;
case 0x48: /* ALLOCATE MEMORY */
case 0x49: /* FREE MEMORY */
case 0x4a: /* RESIZE MEMORY BLOCK */
INT_BARF( 0x21 );
INT_BARF( &context, 0x21 );
break;
case 0x4b: /* "EXEC" - LOAD AND/OR EXECUTE PROGRAM */
WinExec( PTR_SEG_OFF_TO_LIN(DS,DX), SW_NORMAL );
WinExec( PTR_SEG_OFF_TO_LIN(DS_reg(&context),DX_reg(&context)),
SW_NORMAL );
break;
case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */
TASK_KillCurrentTask( AL );
TASK_KillCurrentTask( AL_reg(&context) );
break;
case 0x4d: /* GET RETURN CODE */
AX = NoError; /* normal exit */
AX_reg(&context) = NoError; /* normal exit */
break;
case 0x4e: /* "FINDFIRST" - FIND FIRST MATCHING FILE */
FindFirst(context);
FindFirst(&context);
break;
case 0x4f: /* "FINDNEXT" - FIND NEXT MATCHING FILE */
FindNext(context);
FindNext(&context);
break;
case 0x51: /* GET PSP ADDRESS */
case 0x62: /* GET PSP ADDRESS */
/* FIXME: should we return the original DOS PSP upon */
/* Windows startup ? */
BX = GetCurrentPDB();
BX_reg(&context) = GetCurrentPDB();
break;
case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
ES = 0x0;
BX = 0x0;
INT_BARF( 0x21 );
ES_reg(&context) = 0x0;
BX_reg(&context) = 0x0;
INT_BARF( &context, 0x21 );
break;
case 0x56: /* "RENAME" - RENAME FILE */
RenameFile(context);
RenameFile(&context);
break;
case 0x57: /* FILE DATE AND TIME */
switch (AL)
switch (AL_reg(&context))
{
case 0x00:
GetFileDateTime(context);
GetFileDateTime(&context);
break;
case 0x01:
SetFileDateTime(context);
SetFileDateTime(&context);
break;
}
break;
case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */
switch (AL)
switch (AL_reg(&context))
{
case 0x00:
AX = 1;
AX_reg(&context) = 1;
break;
case 0x02:
AX = 0;
AX_reg(&context) = 0;
break;
case 0x01:
case 0x03:
break;
}
ResetCflag;
RESET_CFLAG(&context);
break;
case 0x5a: /* CREATE TEMPORARY FILE */
CreateTempFile(context);
CreateTempFile(&context);
break;
case 0x5b: /* CREATE NEW FILE */
CreateNewFile(context);
CreateNewFile(&context);
break;
case 0x5d: /* NETWORK */
case 0x5e:
/* network software not installed */
AX = NoNetwork;
SetCflag;
AX_reg(&context) = NoNetwork;
SET_CFLAG(&context);
break;
case 0x5f: /* NETWORK */
switch (AL)
switch (AL_reg(&context))
{
case 0x07: /* ENABLE DRIVE */
if (!DOS_EnableDrive(DL))
if (!DOS_EnableDrive(DL_reg(&context)))
{
Error(InvalidDrive, EC_MediaError , EL_Disk);
AX = InvalidDrive;
SetCflag;
AX_reg(&context) = InvalidDrive;
SET_CFLAG(&context);
break;
}
else
{
ResetCflag;
RESET_CFLAG(&context);
break;
}
case 0x08: /* DISABLE DRIVE */
if (!DOS_DisableDrive(DL))
if (!DOS_DisableDrive(DL_reg(&context)))
{
Error(InvalidDrive, EC_MediaError , EL_Disk);
AX = InvalidDrive;
SetCflag;
AX_reg(&context) = InvalidDrive;
SET_CFLAG(&context);
break;
}
else
{
ResetCflag;
RESET_CFLAG(&context);
break;
}
default:
/* network software not installed */
AX = NoNetwork;
SetCflag;
AX_reg(&context) = NoNetwork;
SET_CFLAG(&context);
break;
}
break;
case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */
strncpy(PTR_SEG_OFF_TO_LIN(ES,DI), PTR_SEG_OFF_TO_LIN(DS,SI), strlen(PTR_SEG_OFF_TO_LIN(DS,SI)) & 0x7f);
ResetCflag;
strncpy(PTR_SEG_OFF_TO_LIN(ES_reg(&context),DI_reg(&context)),
PTR_SEG_OFF_TO_LIN(DS_reg(&context),SI_reg(&context)),
strlen(PTR_SEG_OFF_TO_LIN(DS_reg(&context),SI_reg(&context))) & 0x7f);
RESET_CFLAG(&context);
break;
case 0x61: /* UNUSED */
case 0x63: /* UNUSED */
case 0x64: /* OS/2 DOS BOX */
case 0x65: /* GET EXTENDED COUNTRY INFORMATION */
INT_BARF( 0x21 );
INT_BARF( &context, 0x21 );
break;
case 0x66: /* GLOBAL CODE PAGE TABLE */
switch (AL) {
switch (AL_reg(&context))
{
case 0x01:
BX = CodePage;
DX = BX;
ResetCflag;
DX_reg(&context) = BX_reg(&context) = CodePage;
RESET_CFLAG(&context);
break;
case 0x02:
CodePage = BX;
ResetCflag;
CodePage = BX_reg(&context);
RESET_CFLAG(&context);
break;
}
break;
case 0x67: /* SET HANDLE COUNT */
ResetCflag;
RESET_CFLAG(&context);
break;
case 0x68: /* "FFLUSH" - COMMIT FILE */
case 0x6a: /* COMMIT FILE */
fsync( BX );
ResetCflag;
fsync( BX_reg(&context) );
RESET_CFLAG(&context);
break;
case 0x69: /* DISK SERIAL NUMBER */
switch (AL)
switch (AL_reg(&context))
{
case 0x00:
GetDiskSerialNumber(context);
GetDiskSerialNumber(&context);
break;
case 0x01:
SetDiskSerialNumber(context);
SetDiskSerialNumber(&context);
break;
}
break;
......@@ -1734,15 +1761,15 @@ void DOS3Call( struct sigcontext_struct sigcontext )
break;
default:
INT_BARF( 0x21 );
INT_BARF( &context, 0x21 );
break;
}
}
dprintf_int(stddeb,"ret21: AX %04x, BX %04x, CX %04x, DX %04x, "
"SI %04x, DI %04x, DS %04x, ES %04x EFL %08lx\n",
AX, BX, CX, DX, SI, DI, DS, ES, EFL);
#undef context
"SI %04x, DI %04x, DS %04x, ES %04x EFL %08lx\n",
AX_reg(&context), BX_reg(&context), CX_reg(&context),
DX_reg(&context), SI_reg(&context), DI_reg(&context),
DS_reg(&context), ES_reg(&context), EFL_reg(&context));
}
......
......@@ -16,39 +16,38 @@
*
* Handler for int 25h (absolute disk read).
*/
void INT_Int25Handler( struct sigcontext_struct sigcontext )
void INT_Int25Handler( struct sigcontext_struct context )
{
#define context (&sigcontext)
BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, BX);
DWORD begin, length;
BYTE *dataptr = PTR_SEG_OFF_TO_LIN( DS_reg(&context), BX_reg(&context) );
DWORD begin, length;
if(!DOS_ValidDrive(AL))
{
SetCflag;
AX = 0x0101; /* unknown unit */
return;
}
if (!DOS_ValidDrive(AL_reg(&context)))
{
SET_CFLAG(&context);
AX_reg(&context) = 0x0101; /* unknown unit */
return;
}
if (CX == 0xffff) {
begin = getdword(dataptr);
length = getword(&dataptr[4]);
dataptr = (BYTE *) PTR_SEG_TO_LIN(getdword(&dataptr[6]));
} else {
begin = DX;
length = CX;
}
dprintf_int(stdnimp, "int25: abs diskread, drive %d, sector %ld, "
"count %ld, buffer %d\n", AL, begin, length, (int) dataptr);
if (CX_reg(&context) == 0xffff)
{
begin = getdword(dataptr);
length = getword(&dataptr[4]);
dataptr = (BYTE *) PTR_SEG_TO_LIN(getdword(&dataptr[6]));
}
else
{
begin = DX_reg(&context);
length = CX_reg(&context);
}
dprintf_int( stdnimp, "int25: abs diskread, drive %d, sector %ld, "
"count %ld, buffer %d\n",
AL_reg(&context), begin, length, (int) dataptr);
memset(dataptr, 0, length * 512);
memset(dataptr, 0, length * 512);
if (begin == 0 && length > 1)
*(dataptr + 512) = 0xf8;
if (begin == 0 && length > 1) *(dataptr + 512) = 0xf8;
if (begin == 1)
*dataptr = 0xf8;
if (begin == 1) *dataptr = 0xf8;
ResetCflag;
#undef context
RESET_CFLAG(&context);
}
......@@ -15,32 +15,33 @@
*
* Handler for int 26h (absolute disk read).
*/
void INT_Int26Handler( struct sigcontext_struct sigcontext )
void INT_Int26Handler( struct sigcontext_struct context )
{
#define context (&sigcontext)
BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, BX);
DWORD begin, length;
BYTE *dataptr = PTR_SEG_OFF_TO_LIN( DS_reg(&context), BX_reg(&context) );
DWORD begin, length;
if(!DOS_ValidDrive(AL))
{
SetCflag;
AX = 0x0101; /* unknown unit */
return;
}
if (!DOS_ValidDrive(AL_reg(&context)))
{
SET_CFLAG(&context);
AX_reg(&context) = 0x0101; /* unknown unit */
return;
}
if (CX == 0xffff) {
begin = getdword(dataptr);
length = getword(&dataptr[4]);
dataptr = (BYTE *) PTR_SEG_TO_LIN(getdword(&dataptr[6]));
} else {
begin = DX;
length = CX;
}
if (CX_reg(&context) == 0xffff)
{
begin = getdword(dataptr);
length = getword(&dataptr[4]);
dataptr = (BYTE *) PTR_SEG_TO_LIN(getdword(&dataptr[6]));
}
else
{
begin = DX_reg(&context);
length = CX_reg(&context);
}
dprintf_int(stdnimp,"int26: abs diskwrite, drive %d, sector %ld, "
"count %ld, buffer %d\n", AL, begin, length, (int) dataptr);
dprintf_int( stdnimp,"int26: abs diskwrite, drive %d, sector %ld, "
"count %ld, buffer %d\n",
AL_reg(&context), begin, length, (int) dataptr );
ResetCflag;
#undef context
RESET_CFLAG(&context);
}
......@@ -13,16 +13,14 @@
*
* Handler for int 2ah (network).
*/
void INT_Int2aHandler( struct sigcontext_struct sigcontext )
void INT_Int2aHandler( struct sigcontext_struct context )
{
#define context (&sigcontext)
switch(AH)
switch(AH_reg(&context))
{
case 0x00: /* NETWORK INSTALLATION CHECK */
break;
default:
INT_BARF( 0x2a );
INT_BARF( &context, 0x2a );
}
#undef context
}
......@@ -16,13 +16,12 @@ static void do_int2f_16(struct sigcontext_struct *context);
*
* Handler for int 2fh (multiplex).
*/
void INT_Int2fHandler( struct sigcontext_struct sigcontext )
void INT_Int2fHandler( struct sigcontext_struct context )
{
#define context (&sigcontext)
switch(AH)
switch(AH_reg(&context))
{
case 0x10:
AL = 0xff; /* share is installed */
AL_reg(&context) = 0xff; /* share is installed */
break;
case 0x15: /* mscdex */
......@@ -30,48 +29,47 @@ void INT_Int2fHandler( struct sigcontext_struct sigcontext )
break;
case 0x16:
do_int2f_16( context );
do_int2f_16( &context );
break;
default:
INT_BARF( 0x2f );
INT_BARF( &context, 0x2f );
}
#undef context
}
static void do_int2f_16(struct sigcontext_struct *context)
{
switch(AL)
switch(AL_reg(context))
{
case 0x00: /* Windows enhanced mode installation check */
AX = Options.enhanced ? WINVERSION : 0;
AX_reg(context) = Options.enhanced ? WINVERSION : 0;
break;
case 0x0a: /* Get Windows version and type */
AX = 0;
BX = (WINVERSION >> 8) | ((WINVERSION << 8) & 0xff00);
CX = Options.enhanced ? 3 : 2;
AX_reg(context) = 0;
BX_reg(context) = (WINVERSION >> 8) | ((WINVERSION << 8) & 0xff00);
CX_reg(context) = Options.enhanced ? 3 : 2;
break;
case 0x80: /* Release time-slice */
break; /* nothing to do */
case 0x86: /* DPMI detect mode */
AX = 0; /* Running under DPMI */
AX_reg(context) = 0; /* Running under DPMI */
break;
case 0x87: /* DPMI installation check */
AX = 0x0000; /* DPMI Installed */
BX = 0x0001; /* 32bits available */
CL = 0x03; /* processor 386 */
DX = 0x005a; /* DPMI major/minor 0.90 */
SI = 0; /* # of para. of DOS extended private data */
ES = 0; /* ES:DI is DPMI switch entry point */
DI = 0;
AX_reg(context) = 0x0000; /* DPMI Installed */
BX_reg(context) = 0x0001; /* 32bits available */
CL_reg(context) = 0x03; /* processor 386 */
DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
SI_reg(context) = 0; /* # of para. of DOS extended private data */
ES_reg(context) = 0; /* ES:DI is DPMI switch entry point */
DI_reg(context) = 0;
break;
default:
INT_BARF( 0x2f );
INT_BARF( context, 0x2f );
}
}
......
......@@ -17,9 +17,7 @@
*
* Also handler for interrupt 5c.
*/
void NetBIOSCall( struct sigcontext_struct sigcontext )
void NetBIOSCall( struct sigcontext_struct context )
{
#define context (&sigcontext)
INT_BARF( 0x5c );
#undef context
INT_BARF( &context, 0x5c );
}
......@@ -67,11 +67,10 @@ void INT_SetHandler( BYTE intnum, SEGPTR handler )
/**********************************************************************
* INT_DummyHandler
*/
void INT_DummyHandler( struct sigcontext_struct sigcontext )
void INT_DummyHandler( struct sigcontext_struct context )
{
#define context (&sigcontext)
INT_BARF( CURRENT_STACK16->ordinal_number - FIRST_INTERRUPT_ORDINAL );
#undef context
INT_BARF( &context,
CURRENT_STACK16->ordinal_number - FIRST_INTERRUPT_ORDINAL );
}
......@@ -80,11 +79,9 @@ void INT_DummyHandler( struct sigcontext_struct sigcontext )
*
* Handler for int 11h (get equipment list).
*/
void INT_Int11Handler( struct sigcontext_struct sigcontext )
void INT_Int11Handler( struct sigcontext_struct context )
{
#define context (&sigcontext)
AX = DOS_GetEquipment();
#undef context
AX_reg(&context) = DOS_GetEquipment();
}
......@@ -93,11 +90,9 @@ void INT_Int11Handler( struct sigcontext_struct sigcontext )
*
* Handler for int 12h (get memory size).
*/
void INT_Int12Handler( struct sigcontext_struct sigcontext )
void INT_Int12Handler( struct sigcontext_struct context )
{
#define context (&sigcontext)
AX = 640;
#undef context
AX_reg(&context) = 640;
}
......@@ -106,11 +101,9 @@ void INT_Int12Handler( struct sigcontext_struct sigcontext )
*
* Handler for int 15h.
*/
void INT_Int15Handler( struct sigcontext_struct sigcontext )
void INT_Int15Handler( struct sigcontext_struct context )
{
#define context (&sigcontext)
INT_BARF( 0x15 );
#undef context
INT_BARF( &context, 0x15 );
}
......@@ -119,9 +112,7 @@ void INT_Int15Handler( struct sigcontext_struct sigcontext )
*
* Handler for int 16h (keyboard).
*/
void INT_Int16Handler( struct sigcontext_struct sigcontext )
void INT_Int16Handler( struct sigcontext_struct context )
{
#define context (&sigcontext)
INT_BARF( 0x16 );
#undef context
INT_BARF( &context, 0x16 );
}
......@@ -26,26 +26,16 @@ $(MODULE).o: $(OBJS)
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -29,7 +29,7 @@
#endif
#define SOUND_DEV "/dev/dsp"
#define CDAUDIO_DEV "/dev/sbpcd"
#define CDAUDIO_DEV "/dev/cdrom"
#ifdef SOUND_VERSION
#define IOCTL(a,b,c) ioctl(a,b,&c)
......@@ -566,7 +566,7 @@ static DWORD CDAUDIO_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lp
lpParms->dwReturn = CDADev[wDevID].lpdwTrackPos[lpParms->dwTrack - 1];
dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // get MCI_TRACK #%lu !\n", lpParms->dwTrack);
}
lpParms->dwReturn = CDAUDIO_CalcTime(wDevID,
lpParms->dwReturn = CDAUDIO_CalcTime(wDevID,
CDADev[wDevID].dwTimeFormat, lpParms->dwReturn);
dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // MCI_STATUS_POSITION=%08lX !\n",
lpParms->dwReturn);
......@@ -577,14 +577,14 @@ static DWORD CDAUDIO_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lp
return 0;
case MCI_STATUS_TIME_FORMAT:
dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
lpParms->dwReturn = CDADev[wDevID].dwTimeFormat;
return 0;
default:
dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // unknown command %08lX !\n", lpParms->dwItem);
return MCIERR_UNRECOGNIZED_COMMAND;
}
}
dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // not MCI_STATUS_ITEM !\n");
dprintf_cdaudio(stddeb,"CDAUDIO_mciStatus // not MCI_STATUS_ITEM !\n");
return 0;
#else
return MMSYSERR_NOTENABLED;
......@@ -842,12 +842,11 @@ LONG CDAUDIO_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
case DRV_OPEN:
case MCI_OPEN_DRIVER:
case MCI_OPEN:
return CDAUDIO_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
return CDAUDIO_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
case DRV_CLOSE:
case MCI_CLOSE_DRIVER:
case MCI_CLOSE:
return CDAUDIO_mciClose(dwDevID, dwParam1,
(LPMCI_GENERIC_PARMS)dwParam2);
return CDAUDIO_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
case DRV_ENABLE:
return 1;
case DRV_DISABLE:
......
......@@ -3,6 +3,9 @@
*
* Copyright 1993 Martin Ayotte
*/
/* FIXME: I think there are some segmented vs. linear pointer weirdnesses
* and long term pointers to 16 bit space in here
*/
#ifndef WINELIB
......@@ -26,6 +29,10 @@ static int InstalledListLen;
static LPSTR lpInstallNames = NULL;
static MCI_OPEN_DRIVER_PARMS mciDrv[MAXMCIDRIVERS];
/* FIXME: I need to remember the aliasname of a spec. driver.
* and this is the easiest way. *sigh*
*/
static MCI_OPEN_PARMS mciOpenDrv[MAXMCIDRIVERS];
UINT midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
UINT waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
......@@ -47,6 +54,7 @@ LONG ANIM_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
int MMSYSTEM_WEP(HANDLE hInstance, WORD wDataSeg,
WORD cbHeapSize, LPSTR lpCmdLine)
{
/* isn't WEP the Windows Exit Procedure ? */
printf("MMSYSTEM DLL INIT ... hInst=%04X \n", hInstance);
return(TRUE);
}
......@@ -790,15 +798,774 @@ UINT mciGetDeviceID (LPCSTR lpstrName)
return 0;
}
/* someone was just short of a crisis seeing me putting xxx lines of code
* in a single define. Well. What does the code hope for if not for the
* care of the optimizer? (Stolen by Terry Pratchett, ok ;)
*/
#define _MCI_STR(s) do {\
int __l__;\
dprintf_mci(stddeb,"->returns \"%s\"",s);\
if (lpstrReturnString) {\
__l__=strlen(s);\
if(__l__>uReturnLength) {\
strncpy(lpstrReturnString,s,uReturnLength-1);\
lpstrReturnString[uReturnLength-1]='\0';\
} else\
strcpy(lpstrReturnString,s);\
dprintf_mci(stddeb,"-->\"%s\"\n",lpstrReturnString);\
}\
} while(0)
/* calling DriverProc. We need to pass the struct as SEGMENTED POINTER. */
#define _MCI_CALL_DRIVER(cmd,params) {\
DWORD xparams;\
xparams=MAKE_SEGPTR(&params);\
switch(uDevTyp) {\
case MCI_DEVTYPE_CD_AUDIO:\
res=CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags, xparams);\
break;\
case MCI_DEVTYPE_WAVEFORM_AUDIO:\
res=WAVE_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,xparams);\
break;\
case MCI_DEVTYPE_SEQUENCER:\
res=MIDI_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,xparams);\
break;\
case MCI_DEVTYPE_ANIMATION:\
res=ANIM_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,xparams);\
break;\
case MCI_DEVTYPE_DIGITAL_VIDEO:\
dprintf_mci(stddeb,"_MCI_CALL_DRIVER //No DIGITAL_VIDEO yet !\n");\
res=MCIERR_DEVICE_NOT_INSTALLED;\
break;\
default:\
dprintf_mci(stddeb,"_MCI_CALL_DRIVER //Invalid Device Name '%s' !\n",dev);\
res=MCIERR_INVALID_DEVICE_NAME;\
break;\
}\
}
/* yeah, I know this is BAD. but we have to do that for MCI_OPEN_PARMS
* strings.
*/
#define _MCI_STRDUP_TO_SEG(dest,source) {\
HANDLE x;\
x=USER_HEAP_ALLOC(strlen(source));\
dest=(LPSTR)MAKELONG(x,USER_HeapSel);\
strcpy(PTR_SEG_TO_LIN(dest),source);\
}
/**************************************************************************
* mciSendString [MMSYSTEM.702]
*/
DWORD mciSendString (LPCSTR lpstrCommand,
LPSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback)
{
dprintf_mci(stddeb, "mciSendString('%s', %p, %u, %X)\n",
lpstrCommand, lpstrReturnString,
uReturnLength, hwndCallback);
/* Well, it's easy. The usercode sends a string with a command (and flags)
* expressed in words in it... We do our best to call approbiate drivers,
* and return a errorcode AND a readable string (if lpstrRS!=NULL)
* Info taken by watching cool134.exe and from Borland's mcistrwh.hlp
*/
DWORD mciSendString (LPCSTR lpstrCommand, LPSTR lpstrReturnString,
UINT uReturnLength, HWND hwndCallback)
{
char *cmd,*dev,*args,**keywords;
WORD uDevTyp,wDevID;
DWORD dwFlags;
int track,i,nrofkeywords,res,timef;
dprintf_mci(stdnimp,"mciSendString('%s', %p, %d, %X)\n", lpstrCommand,
lpstrReturnString, uReturnLength, hwndCallback
);
/* format is <command> <device> <optargs> */
cmd=strdup(lpstrCommand);
dev=strchr(cmd,' ');
if (dev==NULL) {
free(cmd);
return MCIERR_MISSING_DEVICE_NAME;
}
*dev++='\0';
args=strchr(dev,' ');
if (args!=NULL) *args++='\0';
AnsiUpper(dev);
AnsiUpper(cmd);
if (args!=NULL) {
char *s;
AnsiUpper(args);
i=1;/* nrofkeywords = nrofspaces+1 */
s=args;
while ((s=strchr(s,' '))!=NULL) i++,s++;
keywords=(char**)malloc(sizeof(char*)*(i+2));
nrofkeywords=i;
s=args;i=0;
while (s && i<nrofkeywords) {
keywords[i++]=s;
s=strchr(s,' ');
if (s) *s++='\0';
}
keywords[i]=NULL;
} else {
nrofkeywords=0;
keywords=(char**)malloc(sizeof(char*));
}
dwFlags = 0; /* default flags */
i=0;
while (i<nrofkeywords) {
if (!strcmp(keywords[i],"WAIT")) {
dwFlags |= MCI_WAIT;
i++;
continue;
}
if (!strcmp(keywords[i],"NOTIFY")) {
/* how should we callback? I don't know. */
/*dwFlags |= MCI_NOTIFY;*/
i++;
continue;
}
if (!strcmp(keywords[i],"TRACK")) {
if (i+1<nrofkeywords) {
sscanf(keywords[i+1],"%d",&track);
dwFlags |= MCI_TRACK;
i++;
/*FALLTHROUGH*/
}
i++;
continue;
}
i++;
}
if (!strcmp(cmd,"OPEN")) {
char *s;
MCI_OPEN_PARMS openParams;
openParams.lpstrElementName = NULL;
s=strchr(dev,'!');
if (s!=NULL) {
*s++='\0';
_MCI_STRDUP_TO_SEG(openParams.lpstrElementName,s);
}
if (!strcmp(dev,"CDAUDIO")) {
uDevTyp=MCI_DEVTYPE_CD_AUDIO;
} else if (!strcmp(dev,"WAVEAUDIO")) {
uDevTyp=MCI_DEVTYPE_WAVEFORM_AUDIO;
} else if (!strcmp(dev,"SEQUENCER")) {
uDevTyp=MCI_DEVTYPE_SEQUENCER;
} else if (!strcmp(dev,"ANIMATION1")) {
uDevTyp=MCI_DEVTYPE_ANIMATION;
} else if (!strcmp(dev,"AVIVIDEO")) {
uDevTyp=MCI_DEVTYPE_DIGITAL_VIDEO;
} else {
free(keywords);free(cmd);
return MCIERR_INVALID_DEVICE_NAME;
}
wDevID=0;
while(mciDrv[wDevID].wType) {
if (++wDevID>=MAXMCIDRIVERS) {
dprintf_mci(stddeb, "MCI_OPEN // MAXMCIDRIVERS reached !\n");
free(keywords);free(cmd);
return MCIERR_INTERNAL;
}
}
mciDrv[wDevID].wType = uDevTyp;
mciDrv[wDevID].wDeviceID = wDevID;
openParams.dwCallback = 0;
openParams.wDeviceID = wDevID;
/* all strings must be copied */
_MCI_STRDUP_TO_SEG(openParams.lpstrDeviceType,dev);
openParams.lpstrAlias = NULL;
dwFlags |= MCI_OPEN_TYPE;
i=0;
while (i<nrofkeywords) {
if (!strcmp(keywords[i],"SHAREABLE")) {
dwFlags|=MCI_OPEN_SHAREABLE;
i++;
continue;
}
if (!strcmp(keywords[i],"ALIAS") && (i+1<nrofkeywords)) {
dwFlags|=MCI_OPEN_ALIAS;
_MCI_STRDUP_TO_SEG(openParams.lpstrAlias,keywords[i]);
i+=2;
continue;
}
if (!strcmp(keywords[i],"ELEMENT") && (i+1<nrofkeywords)) {
dwFlags|=MCI_OPEN_ELEMENT;
_MCI_STRDUP_TO_SEG(openParams.lpstrElementName,keywords[i]);
i+=2;
continue;
}
i++;
}
_MCI_CALL_DRIVER(MCI_OPEN,openParams);
if (res==0)
memcpy(&mciOpenDrv[wDevID],&openParams,sizeof(MCI_OPEN_PARMS));
free(keywords);free(cmd);
return res;
}
/* all other commands use the alias set in MCI_OPEN or (if not set)
* the devicetype
*/
wDevID=0;
while(1) {
SEGPTR dname;
dname=(SEGPTR)mciOpenDrv[wDevID].lpstrAlias;
if (dname==NULL)
dname=(SEGPTR)mciOpenDrv[wDevID].lpstrDeviceType;
if (!strcasecmp(PTR_SEG_TO_LIN(dname),dev))
break;
if (++wDevID >= MAXMCIDRIVERS) {
dprintf_mci(stddeb, "mciSendString // MAXMCIDRIVERS reached !\n");
free(keywords);free(cmd);
return MCIERR_INTERNAL;
}
}
uDevTyp=mciDrv[wDevID].wType;
if (!strcmp(cmd,"STATUS")) {
MCI_STATUS_PARMS statusParams;
if (args==NULL) {
free(keywords);free(cmd);
return MCIERR_MISSING_STRING_ARGUMENT;
}
statusParams.dwCallback = 0;
if (dwFlags & MCI_TRACK)
statusParams.dwTrack = track;
dwFlags |= MCI_STATUS_ITEM;
/* we need that later for printing... */
statusParams.dwItem = MCI_STATUS_TIME_FORMAT;
_MCI_CALL_DRIVER(MCI_STATUS,statusParams);
timef=statusParams.dwReturn;
statusParams.dwReturn=0;
statusParams.dwItem=0;
i=0;
while (i<nrofkeywords) {
if ( !strcmp(keywords[i],"CURRENT") &&
(i+1<nrofkeywords) &&
!strcmp(keywords[i+1],"TRACK")
) {
statusParams.dwItem=MCI_STATUS_CURRENT_TRACK;
i+=2;
continue;
}
if ( !strcmp(keywords[i],"TIME") &&
(i+1<nrofkeywords) &&
!strcmp(keywords[i+1],"FORMAT")
) {
statusParams.dwItem=MCI_STATUS_TIME_FORMAT;
i+=2;
continue;
}
if (!strcmp(keywords[i],"READY")) {
statusParams.dwItem=MCI_STATUS_READY;
i++;
continue;
}
if (!strcmp(keywords[i],"MODE")) {
statusParams.dwItem=MCI_STATUS_MODE;
i++;
continue;
}
if ( !strcmp(keywords[i],"NUMBER") &&
(i+2<nrofkeywords) &&
!strcmp(keywords[i+1],"OF") &&
!strcmp(keywords[i+2],"TRACKS")
) {
statusParams.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
i+=3;
continue;
}
if (!strcmp(keywords[i],"LENGTH")) {
statusParams.dwItem = MCI_STATUS_LENGTH;
i++;
continue;
}
if (!strcmp(keywords[i],"POSITION")) {
statusParams.dwItem = MCI_STATUS_POSITION;
i++;
continue;
}
if ( !strcmp(keywords[i],"MEDIA") &&
(i+1<nrofkeywords) &&
!strcmp(keywords[i+1],"PRESENT")
) {
statusParams.dwItem = MCI_STATUS_MEDIA_PRESENT;
i+=2;
continue;
}
i++;
}
_MCI_CALL_DRIVER(MCI_STATUS,statusParams);
if (res==0) {
switch (statusParams.dwItem) {
case MCI_STATUS_MODE:
switch (statusParams.dwReturn) {
case MCI_MODE_NOT_READY:_MCI_STR("not ready");break;
case MCI_MODE_STOP:_MCI_STR("stopped");break;
case MCI_MODE_PLAY:_MCI_STR("playing");break;
case MCI_MODE_RECORD:_MCI_STR("recording");break;
case MCI_MODE_SEEK:_MCI_STR("seeking");break;
case MCI_MODE_PAUSE:_MCI_STR("paused");break;
case MCI_MODE_OPEN:_MCI_STR("open");break;
default:break;
}
break;
case MCI_STATUS_MEDIA_PRESENT:
if (statusParams.dwReturn)
_MCI_STR("true");
else
_MCI_STR("false");
break;
case MCI_STATUS_NUMBER_OF_TRACKS:
case MCI_STATUS_CURRENT_TRACK:
{ char buf[16];
sprintf(buf,"%ld",statusParams.dwReturn);
_MCI_STR(buf);
break;
}
case MCI_STATUS_POSITION:
case MCI_STATUS_LENGTH:
{ char buf[100];
switch (timef) {
case MCI_FORMAT_MILLISECONDS:
case MCI_FORMAT_FRAMES:
case MCI_FORMAT_BYTES:
case MCI_FORMAT_SAMPLES:
sprintf(buf,"%ld",statusParams.dwReturn);
_MCI_STR(buf);
break;
case MCI_FORMAT_HMS:
/* well, the macros have the same content*/
/*FALLTRHOUGH*/
case MCI_FORMAT_MSF:
sprintf(buf,"%d:%d:%d",
MCI_HMS_HOUR(statusParams.dwReturn),
MCI_HMS_MINUTE(statusParams.dwReturn),
MCI_HMS_SECOND(statusParams.dwReturn)
);
_MCI_STR(buf);
break;
case MCI_FORMAT_TMSF:
sprintf(buf,"%d:%d:%d:%d",
MCI_TMSF_TRACK(statusParams.dwReturn),
MCI_TMSF_MINUTE(statusParams.dwReturn),
MCI_TMSF_SECOND(statusParams.dwReturn),
MCI_TMSF_FRAME(statusParams.dwReturn)
);
_MCI_STR(buf);
break;
default:
fprintf(stdnimp,"mciSendString:STATUS:missing timeformat for %d, report.\n",timef);
break;
}
break;
}
case MCI_STATUS_TIME_FORMAT:
switch (timef) {
case MCI_FORMAT_MILLISECONDS:_MCI_STR("milliseconds");break;
case MCI_FORMAT_FRAMES:_MCI_STR("frames");break;
case MCI_FORMAT_BYTES:_MCI_STR("bytes");break;
case MCI_FORMAT_SAMPLES:_MCI_STR("samples");break;
case MCI_FORMAT_HMS:_MCI_STR("hms");break;
case MCI_FORMAT_MSF:_MCI_STR("msf");break;
case MCI_FORMAT_TMSF:_MCI_STR("tmsf");break;
default:
fprintf(stdnimp,"mciSendString:STATUS:missing timeformat for %d, report.\n",timef);
break;
}
break;
default:
fprintf(stdnimp,"mciSendString:STATUS:missing result for %ld, report.\n",statusParams.dwItem);
break;
}
}
free(keywords);free(cmd);
return res;
}
if (!strcmp(cmd,"SET")) {
MCI_SET_PARMS setParams;
if (args==NULL) {
free(keywords);free(cmd);
return MCIERR_MISSING_STRING_ARGUMENT;
}
setParams.dwCallback = 0;
i=0;
while (i<nrofkeywords) {
if (!strcmp(keywords[i],"DOOR") && i+1<nrofkeywords) {
if (!strcmp(keywords[i+1],"OPEN"))
dwFlags |= MCI_SET_DOOR_OPEN;
if (!strcmp(keywords[i+1],"CLOSED"))
dwFlags |= MCI_SET_DOOR_CLOSED;
i+=2;
continue;
}
if ( !strcmp(keywords[i],"TIME") &&
(i+2<nrofkeywords) &&
!strcmp(keywords[i+1],"FORMAT")
) {
dwFlags |= MCI_SET_TIME_FORMAT;
if (!strcmp(keywords[i+2],"MS"))
setParams.dwTimeFormat = MCI_FORMAT_MSF;
if (!strcmp(keywords[i+2],"MILLISECONDS"))
setParams.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
if (!strcmp(keywords[i+2],"MSF"))
setParams.dwTimeFormat = MCI_FORMAT_MSF;
if (!strcmp(keywords[i+2],"HMS")) /* untested */
setParams.dwTimeFormat = MCI_FORMAT_HMS;
if (!strcmp(keywords[i+2],"FRAMES")) /* untested */
setParams.dwTimeFormat = MCI_FORMAT_FRAMES;
if (!strcmp(keywords[i+2],"BYTES")) /* untested */
setParams.dwTimeFormat = MCI_FORMAT_BYTES;
if (!strcmp(keywords[i+2],"SAMPLES")) /* untested */
setParams.dwTimeFormat = MCI_FORMAT_SAMPLES;
if (!strcmp(keywords[i+2],"TMSF")) /* untested */
setParams.dwTimeFormat = MCI_FORMAT_TMSF;
if (!strcmp(keywords[i+2],"SMPTE") && (i+3<nrofkeywords)) {
/* all untested */
if (!strcmp(keywords[i+3],"24"))
setParams.dwTimeFormat = MCI_FORMAT_SMPTE_24;
if (!strcmp(keywords[i+3],"25"))
setParams.dwTimeFormat = MCI_FORMAT_SMPTE_25;
if (!strcmp(keywords[i+3],"30"))
setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30;
if (!strcmp(keywords[i+3],"30DROP"))
setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30DROP;
i++;
/*FALLTHROUGH*/
}
i+=3;
continue;
}
if (!strcmp(args,"AUDIO") && (i+1<nrofkeywords)) {
dwFlags |= MCI_SET_AUDIO;
/* I'm not sure if those belong to the flags...
* they could belong to setParams.dwAudio
*/
if (!strcmp(args,"ALL"))
dwFlags |= MCI_SET_AUDIO_ALL;
if (!strcmp(args,"LEFT"))
dwFlags |= MCI_SET_AUDIO_LEFT;
if (!strcmp(args,"RIGHT"))
dwFlags |= MCI_SET_AUDIO_RIGHT;
i++;
continue;
}
if (!strcmp(args,"VIDEO")) {
/* how to handle those? */
i++;
continue;
}
if (!strcmp(args,"ON")) {
dwFlags |= MCI_SET_ON;
i++;
continue;
}
if (!strcmp(args,"OFF")) {
dwFlags |= MCI_SET_ON;
i++;
continue;
}
i++;
}
_MCI_CALL_DRIVER(MCI_SET,setParams);
if (res==0) { /* does set return data? */ }
free(keywords);free(cmd);
return res;
}
if (!strcmp(cmd,"CAPABILITY")) {
MCI_GETDEVCAPS_PARMS gdcParams;
gdcParams.dwCallback = 0;
if (args==NULL) {
free(keywords);free(cmd);
return MCIERR_MISSING_STRING_ARGUMENT;
}
dwFlags |= MCI_GETDEVCAPS_ITEM;
gdcParams.dwItem = 0;
i=0;
while (i<nrofkeywords) {
if ( !strcmp(keywords[i],"DEVICE") &&
(i+1<nrofkeywords) &&
!strcmp(keywords[i+1],"TYPE")
) {
gdcParams.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;
i+=2;
continue;
}
if ( !strcmp(keywords[i],"HAS") &&
(i+1<nrofkeywords) &&
!strcmp(keywords[i+1],"AUDIO")
) {
gdcParams.dwItem = MCI_GETDEVCAPS_HAS_AUDIO;
i+=2;
continue;
}
if ( !strcmp(keywords[i],"HAS") &&
(i+1<nrofkeywords) &&
!strcmp(keywords[i+1],"VIDEO")
) {
gdcParams.dwItem = MCI_GETDEVCAPS_HAS_VIDEO;
i+=2;
continue;
}
if ( !strcmp(keywords[i],"USES") &&
(i+1<nrofkeywords) &&
!strcmp(keywords[i+1],"FILES")
) {
gdcParams.dwItem = MCI_GETDEVCAPS_HAS_VIDEO;
i+=2;
continue;
}
if ( !strcmp(keywords[i],"COMPOUND") &&
(i+1<nrofkeywords) &&
!strcmp(keywords[i+1],"DEVICE")
) {
gdcParams.dwItem = MCI_GETDEVCAPS_COMPOUND_DEVICE;
i+=2;
continue;
}
if (!strcmp(keywords[i],"CAN") && (i+1<nrofkeywords)) {
if (!strcmp(keywords[i+1],"RECORD"))
gdcParams.dwItem = MCI_GETDEVCAPS_CAN_RECORD;
if (!strcmp(keywords[i+1],"PLAY"))
gdcParams.dwItem = MCI_GETDEVCAPS_CAN_PLAY;
if (!strcmp(keywords[i+1],"EJECT"))
gdcParams.dwItem = MCI_GETDEVCAPS_CAN_EJECT;
if (!strcmp(keywords[i+1],"SAVE"))
gdcParams.dwItem = MCI_GETDEVCAPS_CAN_SAVE;
i+=2;
continue;
}
i++;
}
res=-1;
_MCI_CALL_DRIVER(MCI_GETDEVCAPS,gdcParams);
fprintf(stderr,"GETDEVCAPS returned res=%d\n",res);
if (res==0) {
switch (gdcParams.dwItem) {
case MCI_GETDEVCAPS_DEVICE_TYPE:
switch (gdcParams.dwReturn) {
case MCI_DEVTYPE_VCR:_MCI_STR("vcr");break;
case MCI_DEVTYPE_VIDEODISC:_MCI_STR("videodisc");break;
case MCI_DEVTYPE_CD_AUDIO:_MCI_STR("cd audio");break;
case MCI_DEVTYPE_OVERLAY:_MCI_STR("overlay");break;
case MCI_DEVTYPE_DAT:_MCI_STR("dat");break;
case MCI_DEVTYPE_SCANNER:_MCI_STR("scanner");break;
case MCI_DEVTYPE_ANIMATION:_MCI_STR("animation");break;
case MCI_DEVTYPE_DIGITAL_VIDEO:_MCI_STR("digital video");break;
case MCI_DEVTYPE_OTHER:_MCI_STR("other");break;
case MCI_DEVTYPE_WAVEFORM_AUDIO:_MCI_STR("waveform audio");break;
case MCI_DEVTYPE_SEQUENCER:_MCI_STR("sequencer");break;
default:fprintf(stdnimp,"mciSendString:GETCAPS_DEVTYPE:unknown type %ld, report.\n",gdcParams.dwReturn);break;
}
break;
case MCI_GETDEVCAPS_CAN_PLAY:
case MCI_GETDEVCAPS_CAN_EJECT:
case MCI_GETDEVCAPS_CAN_RECORD:
case MCI_GETDEVCAPS_CAN_SAVE:
case MCI_GETDEVCAPS_HAS_AUDIO:
case MCI_GETDEVCAPS_HAS_VIDEO:
case MCI_GETDEVCAPS_COMPOUND_DEVICE:
case MCI_GETDEVCAPS_USES_FILES:
/* well, is this right? no example here */
if (gdcParams.dwReturn)
_MCI_STR("true");
else
_MCI_STR("false");
break;
default:fprintf(stdnimp,"mciSendString:GETDEVCAPS:unknown type %ld, report.\n",gdcParams.dwItem);break;
}
}
free(keywords);free(cmd);
return res;
}
if (!strcmp(cmd,"PAUSE")) {
MCI_GENERIC_PARMS genParams;
genParams.dwCallback=0;
_MCI_CALL_DRIVER(MCI_PAUSE,genParams);
free(keywords);free(cmd);
return res;
}
if (!strcmp(cmd,"PLAY")) {
int nrargs,j,k,a[4];
char *parsestr;
MCI_PLAY_PARMS playParams;
MCI_STATUS_PARMS statusParams;
statusParams.dwCallback=0;
statusParams.dwItem=MCI_STATUS_TIME_FORMAT;
dwFlags |= MCI_STATUS_ITEM;
_MCI_CALL_DRIVER(MCI_STATUS,statusParams);
dwFlags &= ~MCI_STATUS_ITEM;
timef=statusParams.dwReturn;
switch (timef) {
case MCI_FORMAT_MILLISECONDS:
case MCI_FORMAT_FRAMES:
case MCI_FORMAT_BYTES:
case MCI_FORMAT_SAMPLES:
nrargs=1;
parsestr="%d";
break;
case MCI_FORMAT_HMS:
case MCI_FORMAT_MSF:
parsestr="%d:%d:%d";
nrargs=3;
break;
case MCI_FORMAT_TMSF:
parsestr="%d:%d:%d:%d";
nrargs=4;
break;
default:fprintf(stdnimp,"mciSendString:PLAY:unknown timeformat %d, please report.\n",timef);
parsestr="%d";
nrargs=1;
break;
}
playParams.dwCallback=0;
i=0;
while (i<nrofkeywords) {
if ( !strcmp(keywords[i],"TO") &&
(i+1<nrofkeywords)
) {
dwFlags |= MCI_TO;
a[0]=a[1]=a[2]=a[3]=0;
j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
/* add up all integers we got, if we have more
* shift them. (Well I should use the macros in
* mmsystem.h, right).
*/
playParams.dwTo=0;
for (k=0;k<j;k++)
playParams.dwTo+=a[k]<<(8*(nrargs-k));
i+=2;
continue;
}
if ( !strcmp(keywords[i],"FROM") &&
(i+1<nrofkeywords)
) {
dwFlags |= MCI_FROM;
a[0]=a[1]=a[2]=a[3]=0;
j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
/* dito. */
playParams.dwFrom=0;
for (k=0;k<j;k++)
playParams.dwFrom+=a[k]<<(8*(nrargs-k));
i+=2;
continue;
}
i++;
}
_MCI_CALL_DRIVER(MCI_PLAY,playParams);
free(keywords);free(cmd);
return res;
}
if (!strcmp(cmd,"STOP")) {
MCI_GENERIC_PARMS genParams;
genParams.dwCallback=0;
_MCI_CALL_DRIVER(MCI_STOP,genParams);
free(keywords);free(cmd);
return res;
}
if (!strcmp(cmd,"SEEK")) {
int nrargs,j,k,a[4];
char *parsestr;
MCI_STATUS_PARMS statusParams;
MCI_SEEK_PARMS seekParams;
statusParams.dwCallback=0;
statusParams.dwItem=MCI_STATUS_TIME_FORMAT;
dwFlags |= MCI_STATUS_ITEM;
_MCI_CALL_DRIVER(MCI_STATUS,statusParams);
dwFlags &= ~MCI_STATUS_ITEM;
timef=statusParams.dwReturn;
switch (timef) {
case MCI_FORMAT_MILLISECONDS:
case MCI_FORMAT_FRAMES:
case MCI_FORMAT_BYTES:
case MCI_FORMAT_SAMPLES:
nrargs=1;
parsestr="%d";
break;
case MCI_FORMAT_HMS:
case MCI_FORMAT_MSF:
parsestr="%d:%d:%d";
nrargs=3;
break;
case MCI_FORMAT_TMSF:
parsestr="%d:%d:%d:%d";
nrargs=4;
break;
default:fprintf(stdnimp,"mciSendString:SEEK:unknown timeformat %d, please report.\n",timef);
parsestr="%d";
nrargs=1;
break;
}
seekParams.dwCallback=0;
i=0;
while (i<nrofkeywords) {
if ( !strcmp(keywords[i],"TO") &&
(i+1<nrofkeywords)
) {
if (!strcmp(keywords[i+1],"START")) {
dwFlags=MCI_SEEK_TO_START;
seekParams.dwTo=0;
i+=2;
continue;
}
if (!strcmp(keywords[i+1],"END")) {
dwFlags=MCI_SEEK_TO_END;
seekParams.dwTo=0;
i+=2;
continue;
}
dwFlags=MCI_TO;
i+=2;
a[0]=a[1]=a[2]=a[3]=0;
j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
seekParams.dwTo=0;
for (k=0;k<j;k++)
seekParams.dwTo+=a[k]<<(8*(nrargs-k));
continue;
}
i++;
}
_MCI_CALL_DRIVER(MCI_SEEK,seekParams);
free(keywords);free(cmd);
return res;
}
if (!strcmp(cmd,"CLOSE")) {
MCI_GENERIC_PARMS closeParams;
closeParams.dwCallback=0;
_MCI_CALL_DRIVER(MCI_CLOSE,closeParams);
free(keywords);free(cmd);
return res;
}
if (!strcmp(cmd,"INFO")) {
MCI_INFO_PARMS infoParams;
dwFlags=-1;
while (i<nrofkeywords) {
if (!strcmp(keywords[i],"PRODUCT")) {
dwFlags=MCI_INFO_PRODUCT;
i++;
continue;
}
if (!strcmp(keywords[i],"FILE")) {
dwFlags=MCI_INFO_FILE;
i++;
continue;
}
i++;
}
if (dwFlags==-1) {
free(keywords);free(cmd);
return MCIERR_MISSING_STRING_ARGUMENT;
}
_MCI_CALL_DRIVER(MCI_INFO,infoParams);
if (res==0) {
_MCI_STR(infoParams.lpstrReturn);
}
free(cmd);free(keywords);
return res;
}
fprintf(stdnimp, "mciSendString('%s', %p, %u, %X) // unimplemented, please report.\n", lpstrCommand,
lpstrReturnString, uReturnLength, hwndCallback
);
free(keywords);free(cmd);
return MCIERR_MISSING_COMMAND_STRING;
}
......
......@@ -26,26 +26,14 @@ $(MODULE).o: $(OBJS)
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -347,6 +347,7 @@ static void DIB_SetImageBits_RLE8(WORD lines,
* fail. [JAY]
*/
line=0; /* Cause exit from do loop. */
break;
}
case RleDelta: /* =2, a delta */
......@@ -666,6 +667,7 @@ int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
XDestroyImage( dibImage );
XDestroyImage( bmpImage );
}
info->bmiHeader.biCompression = 0;
return lines;
}
......
......@@ -9,10 +9,7 @@ COMPILE = $(CC) $(CFLAGS) $(DIVINCL) $(LANG)
all: rc.o
y.tab.c: parser.y
$(BISON) -d -t parser.y
y.tab.h: parser.y
y.tab.c y.tab.h: parser.y
$(BISON) -d -t parser.y
lex.yy.c: parser.l parser.h y.tab.h
......@@ -26,11 +23,7 @@ sysres.rct: sysres.rc
echo WINDOWS_H_ENDS_HERE >>sysres.rct
cat sysres.rc >>sysres.rct
sysres.c: sysres.rct winerc
$(COMPILE) -E -x c -P sysres.rct > sysres.tmp
cat sysres.tmp | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | ./winerc -o sysres -v -p sysres
sysres.h: sysres.rct winerc
sysres.c sysres.h: sysres.rct winerc
$(COMPILE) -E -x c -P sysres.rct > sysres.tmp
cat sysres.tmp | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | ./winerc -o sysres -v -p sysres
......@@ -45,12 +38,10 @@ clean:
y.tab.h sysres.c sysres.h tmp_make
distclean: clean
rm Makefile
rm -f Makefile
countryclean:
winelibclean: clean
depend: sysres.h
y.tab.o: y.tab.c
......
......@@ -16,8 +16,7 @@ build: build.o
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ build tmp_make
......@@ -27,15 +26,6 @@ distclean: clean
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -29,8 +29,7 @@ $(MODULE).o: $(OBJS)
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
mv tmp_make Makefile
clean:
rm -f *.o \#*\# *~ tmp_make
......@@ -40,15 +39,6 @@ distclean: clean
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:
......@@ -12,6 +12,7 @@
#include "win.h"
#include "dce.h"
#include "atom.h"
#include "ldt.h"
#include "toolhelp.h"
#include "stddebug.h"
/* #define DEBUG_CLASS */
......@@ -27,7 +28,7 @@ static HCLASS firstClass = 0;
* Return a handle and a pointer to the class.
* 'ptr' can be NULL if the pointer is not needed.
*/
HCLASS CLASS_FindClassByName( char * name, WORD hinstance, CLASS **ptr )
HCLASS CLASS_FindClassByName( SEGPTR name, WORD hinstance, CLASS **ptr )
{
ATOM atom;
HCLASS class;
......@@ -90,17 +91,21 @@ ATOM RegisterClass( LPWNDCLASS class )
CLASS * newClass, * prevClassPtr;
HCLASS handle, prevClass;
int classExtra;
char *name = PTR_SEG_TO_LIN( class->lpszClassName );
dprintf_class(stddeb, "RegisterClass: wndproc=%08lx hinst=%04x name='%s' background %04x\n",
(DWORD)class->lpfnWndProc, class->hInstance, name, class->hbrBackground );
dprintf_class(stddeb, " style %04x\n",class->style);
dprintf_class( stddeb, "RegisterClass: wndproc=%08lx hinst=%04x name='%s' background %04x\n",
(DWORD)class->lpfnWndProc, class->hInstance,
HIWORD(class->lpszClassName) ?
(char *)PTR_SEG_TO_LIN(class->lpszClassName) : "(int)",
class->hbrBackground );
dprintf_class(stddeb," style=%04x clsExtra=%d winExtra=%d\n",
class->style, class->cbClsExtra, class->cbWndExtra );
/* Window classes are owned by modules, not instances */
class->hInstance = GetExePtr( class->hInstance );
/* Check if a class with this name already exists */
prevClass = CLASS_FindClassByName( name, class->hInstance, &prevClassPtr );
prevClass = CLASS_FindClassByName( class->lpszClassName,
class->hInstance, &prevClassPtr );
if (prevClass)
{
/* Class can be created only if it is local and */
......@@ -123,8 +128,8 @@ ATOM RegisterClass( LPWNDCLASS class )
newClass->wc.cbWndExtra = (class->cbWndExtra < 0) ? 0 : class->cbWndExtra;
newClass->wc.cbClsExtra = classExtra;
newClass->atomName = LocalAddAtom( name );
newClass->wc.lpszClassName = NULL;
newClass->atomName = LocalAddAtom( class->lpszClassName );
newClass->wc.lpszClassName = 0;
if (newClass->wc.style & CS_CLASSDC)
newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC );
......@@ -132,13 +137,13 @@ ATOM RegisterClass( LPWNDCLASS class )
/* Make a copy of the menu name (only if it is a string) */
if ((int)class->lpszMenuName & 0xffff0000)
if (HIWORD(class->lpszMenuName))
{
char *menuname = PTR_SEG_TO_LIN( class->lpszMenuName );
HANDLE hname = USER_HEAP_ALLOC( strlen(menuname)+1 );
if (hname)
{
newClass->wc.lpszMenuName = (char *)USER_HEAP_SEG_ADDR( hname );
newClass->wc.lpszMenuName = USER_HEAP_SEG_ADDR( hname );
strcpy( USER_HEAP_LIN_ADDR( hname ), menuname );
}
}
......@@ -152,7 +157,7 @@ ATOM RegisterClass( LPWNDCLASS class )
/***********************************************************************
* UnregisterClass (USER.403)
*/
BOOL UnregisterClass( LPSTR className, HANDLE hinstance )
BOOL UnregisterClass( SEGPTR className, HANDLE hinstance )
{
HANDLE class, prevClass;
CLASS * classPtr, * prevClassPtr;
......@@ -186,8 +191,8 @@ BOOL UnregisterClass( LPSTR className, HANDLE hinstance )
if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
/*if (classPtr->wc.style & CS_GLOBALCLASS)*/ LocalDeleteAtom( classPtr->atomName );
/*else DeleteAtom( classPtr->atomName );*/
if ((int)classPtr->wc.lpszMenuName & 0xffff0000)
USER_HEAP_FREE( (int)classPtr->wc.lpszMenuName & 0xffff );
if (HIWORD(classPtr->wc.lpszMenuName))
USER_HEAP_FREE( LOWORD(classPtr->wc.lpszMenuName) );
USER_HEAP_FREE( class );
return TRUE;
}
......@@ -272,36 +277,17 @@ int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount)
/***********************************************************************
* GetClassInfo (USER.404)
*/
BOOL GetClassInfo(HANDLE hInstance, SEGPTR ClassName,
LPWNDCLASS lpWndClass)
BOOL GetClassInfo( HANDLE hInstance, SEGPTR name, LPWNDCLASS lpWndClass )
{
CLASS *classPtr;
LPSTR lpClassName = 0;
char temp[10];
if (HIWORD(ClassName)) {
lpClassName = PTR_SEG_TO_LIN(ClassName);
} else {
sprintf(temp,"#%d",(int)LOWORD(ClassName));
lpClassName = temp;
}
dprintf_class(stddeb, "GetClassInfo hInstance=%04x lpClassName=%s\n",
hInstance, lpClassName);
hInstance = GetExePtr(hInstance);
/* if (!(CLASS_FindClassByName(lpClassName, &classPtr))) return FALSE; */
if (!(CLASS_FindClassByName(lpClassName, hInstance, &classPtr)))
{
/* if (!HIWORD(lpClassName))
{
char temp[10];
sprintf(temp, "#%d", (int)lpClassName);
if (!(CLASS_FindClassByName(temp, hInstance, &classPtr))) return FALSE;
}
else */return FALSE;
}
dprintf_class( stddeb, "GetClassInfo: hInstance=%04x className=%s\n",
hInstance,
HIWORD(name) ? (char *)PTR_SEG_TO_LIN(name) : "(int)" );
hInstance = GetExePtr( hInstance );
if (!(CLASS_FindClassByName( name, hInstance, &classPtr))) return FALSE;
if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE;
memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS));
......
......@@ -819,20 +819,6 @@ HWND GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious )
if (!(wndPtr->dwStyle & WS_GROUP)) return ctrlPtr->hwndNext;
}
if (ctrlPtr->dwStyle & WS_GROUP) /* Control is the first of the group */
{
if (!fPrevious) return hwndCtrl; /* Control is alone in his group */
hwnd = ctrlPtr->hwndNext;
while(hwnd) /* Find last control of the group */
{
wndPtr = WIN_FindWndPtr( hwnd );
if (wndPtr->dwStyle & WS_GROUP) break;
hwndCtrl = hwnd;
hwnd = wndPtr->hwndNext;
}
return hwndCtrl;
}
/* Now we will have to find the start of the group */
hwndStart = hwnd = dlgPtr->hwndChild;
......@@ -840,22 +826,26 @@ HWND GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious )
{
wndPtr = WIN_FindWndPtr( hwnd );
if (wndPtr->dwStyle & WS_GROUP) hwndStart = hwnd; /*Start of a group*/
if (hwnd == hwndCtrl)
{
/* We found the control -> hwndStart is the first of the group */
if (!fPrevious) return hwndStart;
if (hwnd == hwndCtrl) break;
hwnd = wndPtr->hwndNext;
}
while(hwndStart) /* Find the control placed before hwndCtrl */
{
wndPtr = WIN_FindWndPtr( hwndStart );
if (wndPtr->hwndNext == hwndCtrl) return hwndStart;
hwndStart = wndPtr->hwndNext;
}
break;
}
if (!hwnd) fprintf(stderr, "GetNextDlgGroupItem: hwnd not in dialog!\n");
/* only case left for forward search: wraparound */
if (!fPrevious) return hwndStart;
hwnd = hwndStart;
wndPtr = WIN_FindWndPtr( hwnd );
hwnd = wndPtr->hwndNext;
while (hwnd && (hwnd != hwndCtrl))
{
wndPtr = WIN_FindWndPtr( hwnd );
if (wndPtr->dwStyle & WS_GROUP) break;
hwndStart = hwnd;
hwnd = wndPtr->hwndNext;
}
return hwndCtrl; /* Not found -> return original control */
return hwndStart;
}
......
......@@ -539,6 +539,7 @@ HWND SetCapture( HWND hwnd )
GrabModeAsync, GrabModeAsync,
None, None, CurrentTime ) == GrabSuccess)
{
dprintf_win(stddeb, "SetCapture: %04x\n", hwnd);
captureWnd = hwnd;
return old_capture_wnd;
}
......@@ -554,6 +555,7 @@ void ReleaseCapture()
if (captureWnd == 0) return;
XUngrabPointer( display, CurrentTime );
captureWnd = 0;
dprintf_win(stddeb, "ReleaseCapture\n");
}
/**********************************************************************
......
......@@ -236,6 +236,11 @@ static INT MSG_GetWindowForEvent( POINT pt, HWND *phwnd )
else hwnd = wndPtr->hwndNext;
}
/* Make point relative to parent again */
wndPtr = WIN_FindWndPtr( *phwnd );
x += wndPtr->rectClient.left;
y += wndPtr->rectClient.top;
/* Send the WM_NCHITTEST message */
......@@ -249,18 +254,18 @@ static INT MSG_GetWindowForEvent( POINT pt, HWND *phwnd )
hwnd = wndPtr->hwndNext;
while (hwnd)
{
wndPtr = WIN_FindWndPtr( hwnd );
if ((wndPtr->dwStyle & WS_VISIBLE) &&
(x >= wndPtr->rectWindow.left) &&
(x < wndPtr->rectWindow.right) &&
(y >= wndPtr->rectWindow.top) &&
(y < wndPtr->rectWindow.bottom)) break;
hwnd = wndPtr->hwndNext;
WND *nextPtr = WIN_FindWndPtr( hwnd );
if ((nextPtr->dwStyle & WS_VISIBLE) &&
(x >= nextPtr->rectWindow.left) &&
(x < nextPtr->rectWindow.right) &&
(y >= nextPtr->rectWindow.top) &&
(y < nextPtr->rectWindow.bottom)) break;
hwnd = nextPtr->hwndNext;
}
if (hwnd) *phwnd = hwnd; /* Found a suitable sibling */
else /* Go back to the parent */
{
*phwnd = WIN_FindWndPtr( *phwnd )->hwndParent;
if (!(*phwnd = wndPtr->hwndParent)) break;
wndPtr = WIN_FindWndPtr( *phwnd );
x += wndPtr->rectClient.left;
y += wndPtr->rectClient.top;
......@@ -1189,12 +1194,10 @@ LONG GetMessageExtraInfo(void)
/***********************************************************************
* RegisterWindowMessage (USER.118)
*/
WORD RegisterWindowMessage( LPCSTR str )
WORD RegisterWindowMessage( SEGPTR str )
{
WORD wRet;
dprintf_msg(stddeb, "RegisterWindowMessage: '%s'\n", str );
wRet = LocalAddAtom( str );
return wRet;
dprintf_msg(stddeb, "RegisterWindowMessage: '%08lx'\n", str );
return LocalAddAtom( str );
}
......
......@@ -224,7 +224,7 @@ BOOL WIN_CreateDesktopWindow(void)
CLASS *classPtr;
HDC hdc;
if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_NAME, 0, &classPtr )))
if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_ATOM, 0, &classPtr )))
return FALSE;
hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+classPtr->wc.cbWndExtra );
......@@ -302,17 +302,23 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
int wmcreate;
XSetWindowAttributes win_attr;
if (windowName != NULL && HIWORD(windowName) == 0) {
dprintf_win(stddeb,"CreateWindowEx: %04x ", LOWORD(windowName));
} else {
dprintf_win(stddeb,"CreateWindowEx: '%s' ", windowName);
}
dprintf_win(stddeb, "%08lX '%s' %08lX %d,%d %dx%d %04X %04X %04X %08lx\n",
exStyle, className, style, x, y, width, height,
/* FIXME: windowName and className should be SEGPTRs */
if (HIWORD(windowName))
dprintf_win( stddeb, "CreateWindowEx: '%s' ", windowName );
else
dprintf_win( stddeb, "CreateWindowEx: %04x ", LOWORD(windowName) );
if (HIWORD(className))
dprintf_win( stddeb, "'%s' ", className );
else
dprintf_win( stddeb, "%04x ", LOWORD(className) );
dprintf_win(stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %08lx\n",
exStyle, style, x, y, width, height,
parent, menu, instance, data);
/* 'soundrec.exe' has negative position !
Why ? For now, here a patch : */
if (!strcmp(className, "SoundRec"))
if (HIWORD(className) && !strcmp(className, "SoundRec"))
{
if (x < 0) x = 0;
if (y < 0) y = 0;
......@@ -330,7 +336,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
{
/* Make sure parent is valid */
if (!IsWindow( parent )) {
dprintf_win(stddeb,"CreateWindowEx: Parent %x is not a windows\n", parent);
dprintf_win(stddeb,"CreateWindowEx: Parent %x is not a window\n", parent);
return 0;
}
}
......@@ -342,9 +348,15 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
}
}
if (!(class = CLASS_FindClassByName( className, GetExePtr( instance ), &classPtr ))) {
fprintf(stderr,"CreateWindow BAD CLASSNAME '%s' !\n", className);
return 0;
{
/* FIXME!! */
char buff[256];
if (HIWORD(className)) strcpy( buff, className );
if (!(class = CLASS_FindClassByName( HIWORD(className) ? MAKE_SEGPTR(buff) : (SEGPTR)className,
GetExePtr( instance ), &classPtr ))) {
fprintf(stderr,"CreateWindow BAD CLASSNAME '%s' !\n", className);
return 0;
}
}
/* Correct the window style */
......@@ -457,14 +469,12 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
{
if (menu) SetMenu(hwnd, menu);
else if (classPtr->wc.lpszMenuName)
SetMenu(hwnd,LoadMenu(instance,(SEGPTR)classPtr->wc.lpszMenuName));
SetMenu( hwnd, LoadMenu( instance, classPtr->wc.lpszMenuName ) );
}
else wndPtr->wIDmenu = menu;
/* Send the WM_CREATE message */
hclassName = USER_HEAP_ALLOC( strlen(className)+1 );
strcpy( USER_HEAP_LIN_ADDR(hclassName), className );
createStruct.lpCreateParams = (LPSTR)data;
createStruct.hInstance = instance;
createStruct.hMenu = menu;
......@@ -474,24 +484,29 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
createStruct.x = x;
createStruct.y = y;
createStruct.style = style;
createStruct.lpszClass = (LPSTR)USER_HEAP_SEG_ADDR(hclassName);
createStruct.dwExStyle = 0;
if (windowName)
if (HIWORD(className))
{
if (HIWORD(windowName) == 0) {
/* Hack for SS_ICON controls */
createStruct.lpszName = windowName;
hwinName = 0;
} else {
hwinName = USER_HEAP_ALLOC( strlen(windowName)+1 );
strcpy( USER_HEAP_LIN_ADDR(hwinName), windowName );
createStruct.lpszName = (LPSTR)USER_HEAP_SEG_ADDR(hwinName);
}
hclassName = USER_HEAP_ALLOC( strlen(className)+1 );
strcpy( USER_HEAP_LIN_ADDR(hclassName), className );
createStruct.lpszClass = (LPSTR)USER_HEAP_SEG_ADDR(hclassName);
}
else
{
hclassName = 0;
createStruct.lpszClass = className;
}
if (HIWORD(windowName))
{
hwinName = USER_HEAP_ALLOC( strlen(windowName)+1 );
strcpy( USER_HEAP_LIN_ADDR(hwinName), windowName );
createStruct.lpszName = (LPSTR)USER_HEAP_SEG_ADDR(hwinName);
}
else
{
hwinName = 0;
createStruct.lpszName = NULL;
createStruct.lpszName = windowName;
}
wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, MAKE_SEGPTR(&createStruct) );
......@@ -506,7 +521,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
wmcreate = SendMessage(hwnd, WM_CREATE, 0, MAKE_SEGPTR(&createStruct));
}
USER_HEAP_FREE( hclassName );
if (hclassName) USER_HEAP_FREE( hclassName );
if (hwinName) USER_HEAP_FREE( hwinName );
if (wmcreate == -1)
......@@ -609,7 +624,7 @@ BOOL OpenIcon(HWND hWnd)
/***********************************************************************
* FindWindow (USER.50)
*/
HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch)
HWND FindWindow( SEGPTR ClassMatch, LPSTR TitleMatch )
{
HCLASS hclass;
CLASS *classPtr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment