Skip to content
Snippets Groups Projects
Commit 9ea19e54 authored by Alexandre Julliard's avatar Alexandre Julliard
Browse files

Release 970101

Wed Jan  1 15:36:17 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/listbox.c]
	Use FindFirstFile/FindNextFile in LISTBOX_Directory.

	* [files/dos_fs.c]
	Rewrote FindFirstFile/FindNextFile to use DOSFS_FindNext().

	* [files/file.c] [files/directory.c]
	Use Win32 kernel objects and handles for file handles.
	Unified SearchPath() and OpenFile().

	* [loader/builtin.c]
	Moved to if1632/ directory.

	* [tools/build.c] [debugger/*] [miscemu/*]
	Win16 register functions now receive the same CONTEXT * structure
	as Win32 functions.

	* [include/sigcontext.h] [miscemu/instr.c]
	Added new macros to get register values from the SIGCONTEXT
	structure (only used for instruction emulation now).

	* [scheduler/process.c] [scheduler/thread.c] (New files)
	Allocate process and thread structures.

	* [scheduler/process.c] [win32/k32obj.c]
	Added Win32 kernel objects and handles management.

	* [loader/task.c]
	Create a Win32 process and thread for every Win16 task.

	* [misc/commdlg.c] [misc/shell.c] [windows/msgbox.c]
	Built-in resources are now in Win32 format. This also avoids
	16-bit callbacks for built-in dialogs.

	* [misc/lzexpand.c]
	Differentiate between 16-bit and 32-bit file handles.

	* [miscemu/int*.c]
	Moved all int emulation to msdos/ directory.

	* [msdos/*]
	New directory msdos/ contains all MS-DOS emulation code that can
	also be used for Winelib; this should enable Winelib apps to use
	DOS3Call and related functions.

	* [rc/winerc.c]
	A few bug fixes for Win32 resource format.

	* [windows/winpos.c]
	Hack in WINPOS_ReorderOwnerPopups() to avoid X crashed (still not
	right though).

Sun Dec 29 17:47:55 1996  O. Flebbe <flebbe@science-computing.uni-tuebingen.de>

	* [loader/pe_image.c]
	Make sure BSS of a PE_Image is zero.

Sat Dec 28 22:15:34 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [windows/scroll.c]
	ScrollWindowEx() rewrite, ScrollDC() fix.

	* [windows/nonclient.c] [controls/menu.c]
	Fixed Alt-Space crashes in dialogs.

	* [windows/event.c] [windows/message.c]
	Some changes in mouse message generation.

Thu Dec 26 09:25:24 1996  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [debugger/stabs.c]
	Dummy DEBUG_ReadExecutableDbgInfo provided for !__ELF__ case.

Tue Dec 24 00:59:05 MET 1996  Martin Buck <martin-2.buck@student.uni-ulm.de>

	* [windows/event.c]
	Changed XK_Page_{Up,Down} to XK_{Prior,Next} for X11R5
	compatibility.
parent 7ebe1a41
No related branches found
Tags wine-970101
No related merge requests found
This is release 961222 of Wine, the MS Windows emulator. This is still a
This is release 970101 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 correctly.
Patches should be submitted to "julliard@lrc.epfl.ch". Please don't
forget to include a ChangeLog entry.
WHAT'S NEW with Wine-961222: (see ChangeLog for details)
- Lots of improvements to the built-in debugger
- Yet more Win32 stuff.
WHAT'S NEW with Wine-970101: (see ChangeLog for details)
- Win32 handle management and related stuff.
- Several files moved around, new directories created.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
......@@ -16,10 +16,10 @@ 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:
ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-961222.tar.gz
ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-961222.tar.gz
ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-961222.tar.gz
ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-961222.tar.gz
ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-970101.tar.gz
ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-970101.tar.gz
ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-970101.tar.gz
ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-970101.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
......
----------------------------------------------------------------------
Wed Jan 1 15:36:17 1997 Alexandre Julliard <julliard@lrc.epfl.ch>
* [controls/listbox.c]
Use FindFirstFile/FindNextFile in LISTBOX_Directory.
* [files/dos_fs.c]
Rewrote FindFirstFile/FindNextFile to use DOSFS_FindNext().
* [files/file.c] [files/directory.c]
Use Win32 kernel objects and handles for file handles.
Unified SearchPath() and OpenFile().
* [loader/builtin.c]
Moved to if1632/ directory.
* [tools/build.c] [debugger/*] [miscemu/*]
Win16 register functions now receive the same CONTEXT * structure
as Win32 functions.
* [include/sigcontext.h] [miscemu/instr.c]
Added new macros to get register values from the SIGCONTEXT
structure (only used for instruction emulation now).
* [scheduler/process.c] [scheduler/thread.c] (New files)
Allocate process and thread structures.
* [scheduler/process.c] [win32/k32obj.c]
Added Win32 kernel objects and handles management.
* [loader/task.c]
Create a Win32 process and thread for every Win16 task.
* [misc/commdlg.c] [misc/shell.c] [windows/msgbox.c]
Built-in resources are now in Win32 format. This also avoids
16-bit callbacks for built-in dialogs.
* [misc/lzexpand.c]
Differentiate between 16-bit and 32-bit file handles.
* [miscemu/int*.c]
Moved all int emulation to msdos/ directory.
* [msdos/*]
New directory msdos/ contains all MS-DOS emulation code that can
also be used for Winelib; this should enable Winelib apps to use
DOS3Call and related functions.
* [rc/winerc.c]
A few bug fixes for Win32 resource format.
* [windows/winpos.c]
Hack in WINPOS_ReorderOwnerPopups() to avoid X crashed (still not
right though).
Sun Dec 29 17:47:55 1996 O. Flebbe <flebbe@science-computing.uni-tuebingen.de>
* [loader/pe_image.c]
Make sure BSS of a PE_Image is zero.
Sat Dec 28 22:15:34 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu>
* [windows/scroll.c]
ScrollWindowEx() rewrite, ScrollDC() fix.
* [windows/nonclient.c] [controls/menu.c]
Fixed Alt-Space crashes in dialogs.
* [windows/event.c] [windows/message.c]
Some changes in mouse message generation.
Thu Dec 26 09:25:24 1996 Philippe De Muyter <phdm@info.ucl.ac.be>
* [debugger/stabs.c]
Dummy DEBUG_ReadExecutableDbgInfo provided for !__ELF__ case.
Tue Dec 24 00:59:05 MET 1996 Martin Buck <martin-2.buck@student.uni-ulm.de>
* [windows/event.c]
Changed XK_Page_{Up,Down} to XK_{Prior,Next} for X11R5
compatibility.
----------------------------------------------------------------------
Sun Dec 22 13:30:18 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
......
......@@ -53,9 +53,11 @@ COMMONSUBDIRS = \
loader \
memory \
misc \
msdos \
multimedia \
objects \
resources \
scheduler \
win32 \
windows
......@@ -82,9 +84,11 @@ COMMONOBJS = \
loader/loader.o \
memory/memory.o \
misc/misc.o \
msdos/msdos.o \
multimedia/multimedia.o \
objects/objects.o \
resources/resources.o \
scheduler/scheduler.o \
win32/win32.o \
windows/windows.o
......
......@@ -2489,6 +2489,7 @@ loader/Makefile
memory/Makefile
misc/Makefile
miscemu/Makefile
msdos/Makefile
multimedia/Makefile
objects/Makefile
programs/Makefile
......@@ -2496,6 +2497,7 @@ programs/progman/Makefile
programs/winhelp/Makefile
rc/Makefile
resources/Makefile
scheduler/Makefile
tools/Makefile
win32/Makefile
windows/Makefile include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
......@@ -2604,6 +2606,7 @@ loader/Makefile
memory/Makefile
misc/Makefile
miscemu/Makefile
msdos/Makefile
multimedia/Makefile
objects/Makefile
programs/Makefile
......@@ -2611,6 +2614,7 @@ programs/progman/Makefile
programs/winhelp/Makefile
rc/Makefile
resources/Makefile
scheduler/Makefile
tools/Makefile
win32/Makefile
windows/Makefile "}
......
......@@ -131,6 +131,7 @@ loader/Makefile
memory/Makefile
misc/Makefile
miscemu/Makefile
msdos/Makefile
multimedia/Makefile
objects/Makefile
programs/Makefile
......@@ -138,6 +139,7 @@ programs/progman/Makefile
programs/winhelp/Makefile
rc/Makefile
resources/Makefile
scheduler/Makefile
tools/Makefile
win32/Makefile
windows/Makefile ])
......
......@@ -10,7 +10,6 @@
#include <unistd.h>
#include "win.h"
#include "desktop.h"
#include "directory.h"
#include "graphics.h"
#include "heap.h"
......@@ -25,13 +24,13 @@ static HBITMAP32 DESKTOP_LoadBitmap( HDC32 hdc, const char *filename )
BITMAPFILEHEADER *fileHeader;
BITMAPINFO *bitmapInfo;
HBITMAP32 hbitmap;
HFILE file;
HFILE32 file;
LPSTR buffer;
LONG size;
/* Read all the file into memory */
if ((file = _lopen( filename, OF_READ )) == HFILE_ERROR)
if ((file = _lopen32( filename, OF_READ )) == HFILE_ERROR32)
{
UINT32 len = GetWindowsDirectory32A( NULL, 0 );
if (!(buffer = HeapAlloc( SystemHeap, 0, len + strlen(filename) + 2 )))
......@@ -39,19 +38,19 @@ static HBITMAP32 DESKTOP_LoadBitmap( HDC32 hdc, const char *filename )
GetWindowsDirectory32A( buffer, len + 1 );
strcat( buffer, "\\" );
strcat( buffer, filename );
file = _lopen( buffer, OF_READ );
file = _lopen32( buffer, OF_READ );
HeapFree( SystemHeap, 0, buffer );
}
if (file == HFILE_ERROR) return 0;
size = _llseek( file, 0, 2 );
if (file == HFILE_ERROR32) return 0;
size = _llseek32( file, 0, 2 );
if (!(buffer = HeapAlloc( SystemHeap, 0, size )))
{
_lclose( file );
_lclose32( file );
return 0;
}
_llseek( file, 0, 0 );
_llseek32( file, 0, 0 );
size = _lread32( file, buffer, size );
_lclose( file );
_lclose32( file );
fileHeader = (BITMAPFILEHEADER *)buffer;
bitmapInfo = (BITMAPINFO *)(buffer + sizeof(BITMAPFILEHEADER));
......@@ -157,7 +156,7 @@ LRESULT DesktopWndProc( HWND32 hwnd, UINT32 message,
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) != SC_CLOSE) return 0;
ExitWindows( 0, 0 );
ExitWindows16( 0, 0 );
case WM_SETCURSOR:
return (LRESULT)SetCursor( LoadCursor16( 0, IDC_ARROW ) );
......
......@@ -8,9 +8,8 @@
#include <string.h>
#include <stdio.h>
#include "windows.h"
#include "winerror.h"
#include "drive.h"
#include "dos_fs.h"
#include "msdos.h"
#include "heap.h"
#include "spy.h"
#include "win.h"
......@@ -478,7 +477,7 @@ static void LISTBOX_PaintItem( WND *wnd, LB_DESCR *descr, HDC32 hdc,
else
SetTextColor( hdc, GetSysColor( COLOR_WINDOWTEXT ) );
}
dprintf_listbox( stddeb, "Listbox %04x: painting %d (%s) action=%02x"
dprintf_listbox( stddeb, "Listbox %04x: painting %d (%s) action=%02x "
"rect=%d,%d-%d,%d\n",
wnd->hwndSelf, index, item ? item->str : "", action,
rect->left, rect->top, rect->right, rect->bottom );
......@@ -1455,55 +1454,45 @@ static LRESULT LISTBOX_SetCount( WND *wnd, LB_DESCR *descr, INT32 count )
LRESULT LISTBOX_Directory( WND *wnd, LB_DESCR *descr, UINT32 attrib,
LPCSTR filespec, BOOL32 long_names )
{
char mask[13];
const char *ptr;
char *path, *p;
int count, skip, pos;
LRESULT ret;
DOS_DIRENT entry;
/* FIXME: should use FindFirstFile/FindNextFile */
HANDLE32 handle;
LRESULT ret = LB_OKAY;
WIN32_FIND_DATA32A entry;
int pos;
if (!filespec) return LB_ERR;
if (!(ptr = DOSFS_GetUnixFileName( filespec, FALSE ))) return LB_ERR;
path = HEAP_strdupA( SystemHeap, 0, ptr );
p = strrchr( path, '/' );
*p++ = '\0';
if (!(ptr = DOSFS_ToDosFCBFormat( p )))
if ((handle = FindFirstFile32A(filespec,&entry)) == INVALID_HANDLE_VALUE32)
{
HeapFree( SystemHeap, 0, path );
return LB_ERR;
if (GetLastError() != ERROR_NO_MORE_FILES) return LB_ERR;
}
strcpy( mask, ptr );
skip = 0;
ret = LB_OKAY;
attrib &= ~FA_LABEL;
while ((count = DOSFS_FindNext( path, mask, NULL, 0,
attrib, skip, &entry )) > 0)
else
{
char buffer[260];
skip += count;
if (entry.attr & FA_DIRECTORY)
do
{
if (!(attrib & DDL_DIRECTORY) || !strcmp(entry.name,". "))
continue;
if (long_names) sprintf( buffer, "[%s]", entry.unixname );
else sprintf( buffer, "[%s]", DOSFS_ToDosDTAFormat( entry.name ) );
}
else /* not a directory */
{
if ((attrib & DDL_EXCLUSIVE) &&
((attrib & (FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_ARCHIVE)) !=
(entry.attr & (FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_ARCHIVE))))
continue;
if (long_names) strcpy( buffer, entry.unixname );
else strcpy( buffer, DOSFS_ToDosDTAFormat( entry.name ) );
}
if (!long_names) AnsiLower( buffer );
pos = LISTBOX_FindFileStrPos( wnd, descr, buffer );
if ((ret = LISTBOX_InsertString( wnd, descr, pos, buffer )) < 0)
break;
char buffer[270];
if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (!(attrib & DDL_DIRECTORY) ||
!strcmp( entry.cAlternateFileName, "." )) continue;
if (long_names) sprintf( buffer, "[%s]", entry.cFileName );
else sprintf( buffer, "[%s]", entry.cAlternateFileName );
}
else /* not a directory */
{
#define ATTRIBS (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE)
if ((attrib & DDL_EXCLUSIVE) &&
((attrib & ATTRIBS) != (entry.dwFileAttributes & ATTRIBS)))
continue;
#undef ATTRIBS
if (long_names) strcpy( buffer, entry.cFileName );
else strcpy( buffer, entry.cAlternateFileName );
}
if (!long_names) AnsiLower( buffer );
pos = LISTBOX_FindFileStrPos( wnd, descr, buffer );
if ((ret = LISTBOX_InsertString( wnd, descr, pos, buffer )) < 0)
break;
} while (FindNextFile32A( handle, &entry ));
FindClose32( handle );
}
if ((ret == LB_OKAY) && (attrib & DDL_DRIVES))
......@@ -1517,8 +1506,6 @@ LRESULT LISTBOX_Directory( WND *wnd, LB_DESCR *descr, UINT32 attrib,
break;
}
}
HeapFree( SystemHeap, 0, path );
return ret;
}
......@@ -1744,6 +1731,7 @@ static LRESULT LISTBOX_HandleTimer( WND *wnd, LB_DESCR *descr,
break;
case LB_TIMER_DOWN:
index = descr->top_item + LISTBOX_GetCurrentPageSize( wnd, descr );
if (index == descr->focus_item) index++;
if (index >= descr->nb_items) index = descr->nb_items - 1;
break;
case LB_TIMER_RIGHT:
......
......@@ -88,7 +88,6 @@ static BOOL fEndMenuCalled = FALSE;
extern void NC_DrawSysButton(HWND hwnd, HDC32 hdc, BOOL down); /*nonclient.c*/
extern BOOL NC_GetSysPopupPos(WND* wndPtr, RECT16* rect);
extern HTASK16 TASK_GetNextTask(HTASK16);
static HBITMAP16 hStdCheck = 0;
static HBITMAP16 hStdMnArrow = 0;
......@@ -111,13 +110,9 @@ static UINT uSubPWndLevel = 0;
static HMENU16 MENU_CopySysMenu(void)
{
HMENU16 hMenu;
HGLOBAL16 handle;
POPUPMENU *menu;
if (!(handle = SYSRES_LoadResource( SYSRES_MENU_SYSMENU ))) return 0;
hMenu = LoadMenuIndirect16( GlobalLock16( handle ) );
SYSRES_FreeResource( handle );
if (!hMenu)
if (!(hMenu = LoadMenuIndirect32A( SYSRES_GetResPtr(SYSRES_MENU_SYSMENU))))
{
dprintf_menu(stddeb,"No SYSMENU\n");
return 0;
......@@ -1644,8 +1639,8 @@ static void MENU_KeyRight( HWND* hwndOwner, HMENU16* hmenu,
* If 'x' and 'y' are not 0, we simulate a button-down event at (x,y)
* before beginning tracking. This is to help menu-bar tracking.
*/
static BOOL MENU_TrackMenu( HMENU16 hmenu, UINT wFlags, int x, int y,
HWND hwnd, const RECT16 *lprect )
static BOOL32 MENU_TrackMenu( HMENU16 hmenu, UINT32 wFlags, int x, int y,
HWND16 hwnd, const RECT16 *lprect )
{
MSG16 msg;
POPUPMENU *menu;
......@@ -1660,10 +1655,17 @@ static BOOL MENU_TrackMenu( HMENU16 hmenu, UINT wFlags, int x, int y,
POINT16 pt = { x, y };
MENU_ButtonDown( hwnd, hmenu, &hmenuCurrent, pt );
}
SetCapture32( hwnd );
EVENT_Capture( hwnd, HTMENU );
while (!fClosed)
{
if (!MSG_InternalGetMessage( &msg, 0, hwnd, MSGF_MENU, 0, TRUE ))
/* we have to keep the message in the queue until it's
* clear that menu loop is not over yet.
*/
if (!MSG_InternalGetMessage( &msg, 0, hwnd, MSGF_MENU,
PM_NOREMOVE, TRUE ))
break;
TranslateMessage( &msg );
......@@ -1672,26 +1674,29 @@ static BOOL MENU_TrackMenu( HMENU16 hmenu, UINT wFlags, int x, int y,
if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
{
/* Find the sub-popup for this mouse event (if any) */
HMENU16 hsubmenu = MENU_FindMenuByCoords( hmenu, msg.pt );
switch(msg.message)
{
/* no WM_NC... messages in captured state */
case WM_RBUTTONDBLCLK:
case WM_RBUTTONDOWN:
case WM_NCRBUTTONDOWN:
if (!(wFlags & TPM_RIGHTBUTTON)) break;
/* fall through */
case WM_LBUTTONDBLCLK:
case WM_LBUTTONDOWN:
case WM_NCLBUTTONDOWN:
fClosed = !MENU_ButtonDown( hwnd, hsubmenu,
&hmenuCurrent, msg.pt );
break;
case WM_RBUTTONUP:
case WM_NCRBUTTONUP:
if (!(wFlags & TPM_RIGHTBUTTON)) break;
/* fall through */
case WM_LBUTTONUP:
case WM_NCLBUTTONUP:
/* If outside all menus but inside lprect, ignore it */
if (!hsubmenu && lprect && PtInRect16(lprect, msg.pt)) break;
fClosed = !MENU_ButtonUp( hwnd, hsubmenu,
......@@ -1700,7 +1705,6 @@ static BOOL MENU_TrackMenu( HMENU16 hmenu, UINT wFlags, int x, int y,
break;
case WM_MOUSEMOVE:
case WM_NCMOUSEMOVE:
if ((msg.wParam & MK_LBUTTON) ||
((wFlags & TPM_RIGHTBUTTON) && (msg.wParam & MK_RBUTTON)))
{
......@@ -1814,22 +1818,63 @@ static BOOL MENU_TrackMenu( HMENU16 hmenu, UINT wFlags, int x, int y,
return TRUE;
}
/***********************************************************************
* MENU_TrackSysPopup
*/
static void MENU_TrackSysPopup( WND* pWnd )
{
RECT16 rect;
HMENU16 hMenu = pWnd->hSysMenu;
HDC16 hDC = 0;
/* track the system menu like a normal popup menu */
if( IsMenu(hMenu) )
{
HWND16 hWnd = pWnd->hwndSelf;
if (!(pWnd->dwStyle & WS_MINIMIZE))
{
hDC = GetWindowDC32( hWnd );
NC_DrawSysButton( hWnd, hDC, TRUE );
}
NC_GetSysPopupPos( pWnd, &rect );
MENU_InitSysMenuPopup( hMenu, pWnd->dwStyle,
pWnd->class->style);
TrackPopupMenu16( hMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
rect.left, rect.bottom, 0, hWnd, &rect );
if (!(pWnd->dwStyle & WS_MINIMIZE))
{
NC_DrawSysButton( hWnd, hDC, FALSE );
ReleaseDC32( hWnd, hDC );
}
}
}
/***********************************************************************
* MENU_TrackMouseMenuBar
*
* Menu-bar tracking upon a mouse event. Called from NC_HandleSysCommand().
*/
void MENU_TrackMouseMenuBar( HWND hwnd, POINT16 pt )
void MENU_TrackMouseMenuBar( WND* wndPtr, INT16 ht, POINT16 pt )
{
WND *wndPtr = WIN_FindWndPtr( hwnd );
HideCaret(0);
SendMessage16( hwnd, WM_ENTERMENULOOP, 0, 0 );
SendMessage16( hwnd, WM_INITMENU, wndPtr->wIDmenu, 0 );
MENU_TrackMenu( (HMENU16)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
pt.x, pt.y, hwnd, NULL );
SendMessage16( hwnd, WM_EXITMENULOOP, 0, 0 );
ShowCaret(0);
BOOL32 bTrackSys = ((ht == HTSYSMENU && !wndPtr->wIDmenu) ||
(wndPtr->dwStyle & (WS_MINIMIZE | WS_CHILD)));
HWND16 hWnd = wndPtr->hwndSelf;
HMENU16 hMenu = (bTrackSys) ? wndPtr->hSysMenu : wndPtr->wIDmenu;
if( IsMenu(hMenu) )
{
HideCaret(0);
SendMessage16( hWnd, WM_ENTERMENULOOP, 0, 0 );
SendMessage16( hWnd, WM_INITMENU, hMenu, 0 );
if( bTrackSys )
MENU_TrackSysPopup( wndPtr );
else
MENU_TrackMenu( hMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
pt.x, pt.y, hWnd, NULL );
SendMessage16( hWnd, WM_EXITMENULOOP, 0, 0 );
ShowCaret(0);
}
}
......@@ -1838,64 +1883,67 @@ void MENU_TrackMouseMenuBar( HWND hwnd, POINT16 pt )
*
* Menu-bar tracking upon a keyboard event. Called from NC_HandleSysCommand().
*/
void MENU_TrackKbdMenuBar( WND* wndPtr, UINT wParam, INT vkey)
void MENU_TrackKbdMenuBar( WND* wndPtr, UINT16 wParam, INT16 vkey)
{
UINT uItem = NO_SELECTED_ITEM;
INT16 htMenu;
UINT16 uItem = NO_SELECTED_ITEM;
HMENU16 hTrackMenu;
/* find window that has a menu
*/
/* find window that has a menu */
if( !(wndPtr->dwStyle & WS_CHILD) )
{
wndPtr = WIN_FindWndPtr( GetActiveWindow() );
if( !wndPtr ) return;
}
else
while( wndPtr->dwStyle & WS_CHILD &&
!(wndPtr->dwStyle & WS_SYSMENU) )
if( !(wndPtr = wndPtr->parent) ) return;
while( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwStyle & WS_SYSMENU) )
if( !(wndPtr = wndPtr->parent) ) return;
if( wndPtr->dwStyle & WS_CHILD || !wndPtr->wIDmenu )
if( !(wndPtr->dwStyle & WS_SYSMENU) )
return;
if( !wndPtr->wIDmenu && !(wndPtr->dwStyle & WS_SYSMENU) ) return;
hTrackMenu = ( IsMenu( wndPtr->wIDmenu ) )? wndPtr->wIDmenu:
wndPtr->hSysMenu;
htMenu = ((wndPtr->dwStyle & (WS_CHILD | WS_MINIMIZE)) ||
!wndPtr->wIDmenu) ? HTSYSMENU : HTMENU;
hTrackMenu = ( htMenu == HTSYSMENU ) ? wndPtr->hSysMenu : wndPtr->wIDmenu;
HideCaret(0);
SendMessage16( wndPtr->hwndSelf, WM_ENTERMENULOOP, 0, 0 );
SendMessage16( wndPtr->hwndSelf, WM_INITMENU, wndPtr->wIDmenu, 0 );
if( IsMenu( hTrackMenu ) )
{
HideCaret(0);
SendMessage16( wndPtr->hwndSelf, WM_ENTERMENULOOP, 0, 0 );
SendMessage16( wndPtr->hwndSelf, WM_INITMENU, hTrackMenu, 0 );
/* find suitable menu entry
*/
/* find suitable menu entry */
if( vkey == VK_SPACE )
uItem = SYSMENU_SELECTED;
else if( vkey )
{
uItem = MENU_FindItemByKey( wndPtr->hwndSelf, wndPtr->wIDmenu, vkey );
if( uItem >= 0xFFFE )
{
if( uItem == 0xFFFF )
MessageBeep(0);
SendMessage16( wndPtr->hwndSelf, WM_EXITMENULOOP, 0, 0 );
ShowCaret(0);
return;
}
}
if( vkey == VK_SPACE )
uItem = SYSMENU_SELECTED;
else if( vkey )
{
uItem = ( htMenu == HTSYSMENU )
? 0xFFFE /* only VK_SPACE in this case */
: MENU_FindItemByKey( wndPtr->hwndSelf, wndPtr->wIDmenu, vkey );
if( uItem >= 0xFFFE )
{
if( uItem == 0xFFFF ) MessageBeep(0);
htMenu = 0;
}
}
MENU_SelectItem( wndPtr->hwndSelf, hTrackMenu, uItem, TRUE );
if( uItem == NO_SELECTED_ITEM )
MENU_SelectItemRel( wndPtr->hwndSelf, hTrackMenu, ITEM_NEXT );
else
PostMessage( wndPtr->hwndSelf, WM_KEYDOWN, VK_DOWN, 0L );
switch( htMenu )
{
case HTMENU:
MENU_SelectItem( wndPtr->hwndSelf, hTrackMenu, uItem, TRUE );
if( uItem == NO_SELECTED_ITEM )
MENU_SelectItemRel( wndPtr->hwndSelf, hTrackMenu, ITEM_NEXT );
else
PostMessage( wndPtr->hwndSelf, WM_KEYDOWN, VK_DOWN, 0L );
MENU_TrackMenu( hTrackMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
0, 0, wndPtr->hwndSelf, NULL );
break;
MENU_TrackMenu( hTrackMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
0, 0, wndPtr->hwndSelf, NULL );
case HTSYSMENU:
MENU_TrackSysPopup( wndPtr );
SendMessage16( wndPtr->hwndSelf, WM_EXITMENULOOP, 0, 0 );
ShowCaret(0);
default:
}
SendMessage16( wndPtr->hwndSelf, WM_EXITMENULOOP, 0, 0 );
ShowCaret(0);
}
}
......@@ -1927,6 +1975,20 @@ BOOL32 TrackPopupMenu32( HMENU32 hMenu, UINT32 wFlags, INT32 x, INT32 y,
return TrackPopupMenu16(hMenu,wFlags,x,y,nReserved,hWnd,lpRect?&r:NULL);
}
/**********************************************************************
* TrackPopupMenuEx (USER32.549)
*/
BOOL32 TrackPopupMenuEx( HMENU32 hMenu, UINT32 wFlags, INT32 x, INT32 y,
HWND32 hWnd, LPTPMPARAMS lpTpm )
{
RECT16 r;
fprintf( stderr, "TrackPopupMenuEx: not fully implemented\n" );
if (lpTpm)
CONV_RECT32TO16( &lpTpm->rcExclude, &r );
return TrackPopupMenu16(hMenu,wFlags,x,y,0,hWnd,lpTpm?&r:NULL);
}
/***********************************************************************
* PopupMenuWndProc
......@@ -2709,7 +2771,7 @@ HMENU16 LoadMenuIndirect16( LPCVOID template )
WORD version, offset;
LPCSTR p = (LPCSTR)template;
dprintf_menu(stddeb,"LoadMenuIndirect32A: %p\n", template );
dprintf_menu(stddeb,"LoadMenuIndirect16: %p\n", template );
version = GET_WORD(p);
p += sizeof(WORD);
if (version)
......@@ -2738,7 +2800,7 @@ HMENU32 LoadMenuIndirect32A( LPCVOID template )
WORD version, offset;
LPCSTR p = (LPCSTR)template;
dprintf_menu(stddeb,"LoadMenuIndirect32A: %p\n", template );
dprintf_menu(stddeb,"LoadMenuIndirect16: %p\n", template );
version = GET_WORD(p);
p += sizeof(WORD);
if (version)
......
......@@ -27,7 +27,6 @@
#include "listbox.h"
#include "dos_fs.h"
#include "drive.h"
#include "file.h"
#include "heap.h"
#include "stddebug.h"
#include "debug.h"
......@@ -699,6 +698,7 @@ int ListBoxSetCurSel(LPHEADLIST lphl, WORD wIndex)
LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec)
{
#if 0
char mask[13];
char* temp = NULL;
const char* ptr;
......@@ -772,6 +772,8 @@ LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec)
SEGPTR_FREE( temp );
return ret;
#endif
return 0;
}
/* ------------------------- dimensions ------------------------- */
......
......@@ -65,9 +65,10 @@ static void DEBUG_SetOpcode( const DBG_ADDR *addr, BYTE op )
* Determine if the instruction at CS:EIP is an instruction that
* we need to step over (like a call or a repetitive string move).
*/
static BOOL32 DEBUG_IsStepOverInstr( SIGCONTEXT *context )
static BOOL32 DEBUG_IsStepOverInstr(void)
{
BYTE *instr = (BYTE *)PTR_SEG_OFF_TO_LIN(CS_reg(context),EIP_reg(context));
BYTE *instr = (BYTE *)PTR_SEG_OFF_TO_LIN( CS_reg(&DEBUG_context),
EIP_reg(&DEBUG_context) );
for (;;)
{
......@@ -182,7 +183,7 @@ void DEBUG_AddBreakpoint( const DBG_ADDR *address )
int num;
BYTE *p;
DBG_FIX_ADDR_SEG( &addr, CS_reg(DEBUG_context) );
DBG_FIX_ADDR_SEG( &addr, CS_reg(&DEBUG_context) );
if (next_bp < MAX_BREAKPOINTS)
num = next_bp++;
......@@ -273,17 +274,17 @@ void DEBUG_InfoBreakpoints(void)
* Determine if we should continue execution after a SIGTRAP signal when
* executing in the given mode.
*/
BOOL32 DEBUG_ShouldContinue( SIGCONTEXT *context, enum exec_mode mode )
BOOL32 DEBUG_ShouldContinue( enum exec_mode mode )
{
DBG_ADDR addr;
int bpnum;
/* If not single-stepping, back up over the int3 instruction */
if (!(EFL_reg(DEBUG_context) & STEP_FLAG)) EIP_reg(DEBUG_context)--;
if (!(EFL_reg(&DEBUG_context) & STEP_FLAG)) EIP_reg(&DEBUG_context)--;
addr.seg = (CS_reg(DEBUG_context) == WINE_CODE_SELECTOR) ?
0 : CS_reg(DEBUG_context);
addr.off = EIP_reg(DEBUG_context);
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 */
......@@ -299,8 +300,8 @@ BOOL32 DEBUG_ShouldContinue( SIGCONTEXT *context, enum exec_mode mode )
/* If there's no breakpoint and we are not single-stepping, then we */
/* must have encountered an int3 in the Windows program; let's skip it. */
if ((bpnum == -1) && !(EFL_reg(DEBUG_context) & STEP_FLAG))
EIP_reg(DEBUG_context)++;
if ((bpnum == -1) && !(EFL_reg(&DEBUG_context) & STEP_FLAG))
EIP_reg(&DEBUG_context)++;
/* no breakpoint, continue if in continuous mode */
return (mode == EXEC_CONT);
......@@ -313,14 +314,13 @@ BOOL32 DEBUG_ShouldContinue( SIGCONTEXT *context, enum exec_mode mode )
* Set the breakpoints to the correct state to restart execution
* in the given mode.
*/
void DEBUG_RestartExecution( SIGCONTEXT *context, enum exec_mode mode,
int instr_len )
void DEBUG_RestartExecution( enum exec_mode mode, int instr_len )
{
DBG_ADDR addr;
addr.seg = (CS_reg(DEBUG_context) == WINE_CODE_SELECTOR) ?
0 : CS_reg(DEBUG_context);
addr.off = EIP_reg(DEBUG_context);
addr.seg = (CS_reg(&DEBUG_context) == WINE_CODE_SELECTOR) ?
0 : CS_reg(&DEBUG_context);
addr.off = EIP_reg(&DEBUG_context);
if (DEBUG_FindBreakpoint( &addr ) != -1)
mode = EXEC_STEP_INSTR; /* If there's a breakpoint, skip it */
......@@ -328,14 +328,14 @@ void DEBUG_RestartExecution( SIGCONTEXT *context, enum exec_mode mode,
switch(mode)
{
case EXEC_CONT: /* Continuous execution */
EFL_reg(DEBUG_context) &= ~STEP_FLAG;
EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
DEBUG_SetBreakpoints( TRUE );
break;
case EXEC_STEP_OVER: /* Stepping over a call */
if (DEBUG_IsStepOverInstr(DEBUG_context))
if (DEBUG_IsStepOverInstr())
{
EFL_reg(DEBUG_context) &= ~STEP_FLAG;
EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
addr.off += instr_len;
breakpoints[0].addr = addr;
breakpoints[0].enabled = TRUE;
......@@ -347,7 +347,7 @@ void DEBUG_RestartExecution( SIGCONTEXT *context, enum exec_mode mode,
/* else fall through to single-stepping */
case EXEC_STEP_INSTR: /* Single-stepping an instruction */
EFL_reg(DEBUG_context) |= STEP_FLAG;
EFL_reg(&DEBUG_context) |= STEP_FLAG;
break;
}
}
......@@ -134,8 +134,8 @@ break_command:
addr.off += $4;
DEBUG_AddBreakpoint( &addr );
}
| tBREAK tEOL { DBG_ADDR addr = { CS_reg(DEBUG_context),
EIP_reg(DEBUG_context) };
| tBREAK tEOL { DBG_ADDR addr = { CS_reg(&DEBUG_context),
EIP_reg(&DEBUG_context) };
DEBUG_AddBreakpoint( &addr );
}
......@@ -239,32 +239,15 @@ void mode_command(int newmode)
}
/***********************************************************************
* DEBUG_EnterDebugger
* DEBUG_Main
*
* Force an entry into the debugger.
*/
void DEBUG_EnterDebugger(void)
{
kill( getpid(), SIGHUP );
}
/***********************************************************************
* DebugBreak16 (KERNEL.203)
* Debugger main loop.
*/
void DebugBreak16( SIGCONTEXT *regs )
{
const char *module = MODULE_GetModuleName( GetExePtr(GetCurrentTask()) );
fprintf( stderr, "%s called DebugBreak\n", module ? module : "???" );
wine_debug( SIGTRAP, regs );
}
void wine_debug( int signal, SIGCONTEXT *regs )
static void DEBUG_Main( int signal )
{
static int loaded_symbols = 0;
static BOOL32 in_debugger = FALSE;
char SymbolTableFile[256];
int instr_len = 0, newmode;
BOOL32 ret_ok;
......@@ -272,8 +255,13 @@ void wine_debug( int signal, SIGCONTEXT *regs )
yydebug = 0;
#endif
if (in_debugger)
{
fprintf( stderr, "Segmentation fault inside debugger, exiting.\n" );
exit(1);
}
in_debugger = TRUE;
yyin = stdin;
DEBUG_context = regs;
DEBUG_SetBreakpoints( FALSE );
......@@ -306,12 +294,12 @@ void wine_debug( int signal, SIGCONTEXT *regs )
DEBUG_LoadEntryPoints();
}
if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( regs, dbg_exec_mode ))
if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( dbg_exec_mode ))
{
DBG_ADDR addr;
addr.seg = CS_reg(DEBUG_context);
addr.off = EIP_reg(DEBUG_context);
addr.seg = CS_reg(&DEBUG_context);
addr.off = EIP_reg(&DEBUG_context);
DBG_FIX_ADDR_SEG( &addr, 0 );
/* Put the display in a correct state */
......@@ -332,9 +320,9 @@ void wine_debug( int signal, SIGCONTEXT *regs )
DEBUG_InfoStack();
if (dbg_mode == 16)
{
LDT_Print( SELECTOR_TO_ENTRY(DS_reg(DEBUG_context)), 1 );
if (ES_reg(DEBUG_context) != DS_reg(DEBUG_context))
LDT_Print( SELECTOR_TO_ENTRY(ES_reg(DEBUG_context)), 1 );
LDT_Print( SELECTOR_TO_ENTRY(DS_reg(&DEBUG_context)), 1 );
if (ES_reg(&DEBUG_context) != DS_reg(&DEBUG_context))
LDT_Print( SELECTOR_TO_ENTRY(ES_reg(&DEBUG_context)), 1 );
}
DEBUG_BackTrace();
}
......@@ -347,7 +335,7 @@ void wine_debug( int signal, SIGCONTEXT *regs )
{
DEBUG_Disasm( &addr );
fprintf(stderr,"\n");
instr_len = addr.off - EIP_reg(DEBUG_context);
instr_len = addr.off - EIP_reg(&DEBUG_context);
}
ret_ok = 0;
......@@ -356,18 +344,48 @@ void wine_debug( int signal, SIGCONTEXT *regs )
issue_prompt();
yyparse();
flush_symbols();
addr.seg = CS_reg(DEBUG_context);
addr.off = EIP_reg(DEBUG_context);
addr.seg = CS_reg(&DEBUG_context);
addr.off = EIP_reg(&DEBUG_context);
DBG_FIX_ADDR_SEG( &addr, 0 );
ret_ok = DEBUG_ValidateRegisters();
if (ret_ok) ret_ok = DBG_CHECK_READ_PTR( &addr, 1 );
} while (!ret_ok);
}
DEBUG_RestartExecution( regs, dbg_exec_mode, instr_len );
DEBUG_RestartExecution( dbg_exec_mode, instr_len );
in_debugger = FALSE;
}
/***********************************************************************
* DEBUG_EnterDebugger
*
* Force an entry into the debugger.
*/
void DEBUG_EnterDebugger(void)
{
kill( getpid(), SIGHUP );
}
/***********************************************************************
* DebugBreak16 (KERNEL.203)
*/
void DebugBreak16( CONTEXT *regs )
{
const char *module = MODULE_GetModuleName( GetExePtr(GetCurrentTask()) );
fprintf( stderr, "%s called DebugBreak\n", module ? module : "???" );
DEBUG_Main( SIGTRAP );
}
void wine_debug( int signal, SIGCONTEXT *regs )
{
DEBUG_SetSigContext( regs );
DEBUG_Main( signal );
DEBUG_GetSigContext( regs );
}
int yyerror(char * s)
{
fprintf(stderr,"%s\n", s);
......
......@@ -34,7 +34,7 @@ static int syntax_error;
DIGIT [0-9]
HEXDIGIT [0-9a-fA-F]
FORMAT [bcdiswx]
IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]*
IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~@]*
%%
......
......@@ -164,7 +164,7 @@ BOOL32 DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr )
if (!nh) return FALSE;
nh->addr = *addr;
DBG_FIX_ADDR_SEG( &nh->addr, DS_reg(DEBUG_context) );
DBG_FIX_ADDR_SEG( &nh->addr, DS_reg(&DEBUG_context) );
return TRUE;
}
......
......@@ -166,7 +166,7 @@ void DEBUG_List( DBG_ADDR *addr, int count )
static DBG_ADDR lasttime = { 0xffffffff, 0 };
if (addr == NULL) addr = &lasttime;
DBG_FIX_ADDR_SEG( addr, CS_reg(DEBUG_context) );
DBG_FIX_ADDR_SEG( addr, CS_reg(&DEBUG_context) );
while (count-- > 0)
{
DEBUG_PrintAddress( addr, dbg_mode, FALSE );
......
......@@ -114,7 +114,7 @@ int DEBUG_ReadMemory( const DBG_ADDR *address )
{
DBG_ADDR addr = *address;
DBG_FIX_ADDR_SEG( &addr, DS_reg(DEBUG_context) );
DBG_FIX_ADDR_SEG( &addr, DS_reg(&DEBUG_context) );
if (!DBG_CHECK_READ_PTR( &addr, sizeof(int) )) return 0;
return *(int *)DBG_ADDR_TO_LIN( &addr );
}
......@@ -129,7 +129,7 @@ void DEBUG_WriteMemory( const DBG_ADDR *address, int value )
{
DBG_ADDR addr = *address;
DBG_FIX_ADDR_SEG( &addr, DS_reg(DEBUG_context) );
DBG_FIX_ADDR_SEG( &addr, DS_reg(&DEBUG_context) );
if (!DBG_CHECK_WRITE_PTR( &addr, sizeof(int) )) return;
*(int *)DBG_ADDR_TO_LIN( &addr ) = value;
}
......@@ -149,7 +149,7 @@ void DEBUG_ExamineMemory( const DBG_ADDR *address, int count, char format )
int i;
DBG_FIX_ADDR_SEG( &addr, (format == 'i') ?
CS_reg(DEBUG_context) : DS_reg(DEBUG_context) );
CS_reg(&DEBUG_context) : DS_reg(&DEBUG_context) );
if (format != 'i' && count > 1)
{
......
......@@ -7,7 +7,7 @@
#include <stdio.h>
#include "debugger.h"
SIGCONTEXT *DEBUG_context;
CONTEXT DEBUG_context;
/***********************************************************************
* DEBUG_SetRegister
......@@ -18,44 +18,32 @@ void DEBUG_SetRegister( enum debug_regs reg, int val )
{
switch(reg)
{
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;
#ifdef FS_reg
case REG_FS: FS_reg(DEBUG_context) = val; break;
#else
case REG_FS:
fprintf( stderr, "Register %%fs not supported on this system\n" );
break;
#endif
#ifdef GS_reg
case REG_GS: GS_reg(DEBUG_context) = val; break;
#else
case REG_GS:
fprintf( stderr, "Register %%gs not supported on this system\n" );
break;
#endif
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;
case REG_FS: FS_reg(&DEBUG_context) = val; break;
case REG_GS: GS_reg(&DEBUG_context) = val; break;
}
}
......@@ -69,49 +57,106 @@ int DEBUG_GetRegister( enum debug_regs reg )
{
switch(reg)
{
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);
#ifdef FS_reg
case REG_FS: return FS_reg(DEBUG_context);
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);
case REG_FS: return FS_reg(&DEBUG_context);
case REG_GS: return GS_reg(&DEBUG_context);
}
return 0; /* should not happen */
}
/***********************************************************************
* DEBUG_SetSigContext
*
* Set the register values from a sigcontext.
*/
extern void DEBUG_SetSigContext( const SIGCONTEXT *sigcontext )
{
EAX_reg(&DEBUG_context) = EAX_sig(sigcontext);
EBX_reg(&DEBUG_context) = EBX_sig(sigcontext);
ECX_reg(&DEBUG_context) = ECX_sig(sigcontext);
EDX_reg(&DEBUG_context) = EDX_sig(sigcontext);
ESI_reg(&DEBUG_context) = ESI_sig(sigcontext);
EDI_reg(&DEBUG_context) = EDI_sig(sigcontext);
EBP_reg(&DEBUG_context) = EBP_sig(sigcontext);
EFL_reg(&DEBUG_context) = EFL_sig(sigcontext);
EIP_reg(&DEBUG_context) = EIP_sig(sigcontext);
ESP_reg(&DEBUG_context) = ESP_sig(sigcontext);
CS_reg(&DEBUG_context) = LOWORD(CS_sig(sigcontext));
DS_reg(&DEBUG_context) = LOWORD(DS_sig(sigcontext));
ES_reg(&DEBUG_context) = LOWORD(ES_sig(sigcontext));
SS_reg(&DEBUG_context) = LOWORD(SS_sig(sigcontext));
#ifdef FS_sig
FS_reg(&DEBUG_context) = LOWORD(FS_sig(sigcontext));
#else
case REG_FS:
fprintf( stderr, "Register %%fs not supported on this system\n" );
return 0;
__asm__("movw %%fs,%w0":"=r" (FS_reg(&DEBUG_context)));
FS_reg(&DEBUG_context) &= 0xffff;
#endif
#ifdef GS_reg
case REG_GS: return GS_reg(DEBUG_context);
#ifdef GS_sig
GS_reg(&DEBUG_context) = LOWORD(GS_sig(sigcontext));
#else
case REG_GS:
fprintf( stderr, "Register %%gs not supported on this system\n" );
return 0;
__asm__("movw %%gs,%w0":"=r" (GS_reg(&DEBUG_context)));
GS_reg(&DEBUG_context) &= 0xffff;
#endif
}
return 0; /* should not happen */
}
/***********************************************************************
* DEBUG_GetSigContext
*
* Build a sigcontext from the register values.
*/
extern void DEBUG_GetSigContext( SIGCONTEXT *sigcontext )
{
EAX_sig(sigcontext) = EAX_reg(&DEBUG_context);
EBX_sig(sigcontext) = EBX_reg(&DEBUG_context);
ECX_sig(sigcontext) = ECX_reg(&DEBUG_context);
EDX_sig(sigcontext) = EDX_reg(&DEBUG_context);
ESI_sig(sigcontext) = ESI_reg(&DEBUG_context);
EDI_sig(sigcontext) = EDI_reg(&DEBUG_context);
EBP_sig(sigcontext) = EBP_reg(&DEBUG_context);
EFL_sig(sigcontext) = EFL_reg(&DEBUG_context);
EIP_sig(sigcontext) = EIP_reg(&DEBUG_context);
ESP_sig(sigcontext) = ESP_reg(&DEBUG_context);
CS_sig(sigcontext) = CS_reg(&DEBUG_context);
DS_sig(sigcontext) = DS_reg(&DEBUG_context);
ES_sig(sigcontext) = ES_reg(&DEBUG_context);
SS_sig(sigcontext) = SS_reg(&DEBUG_context);
#ifdef FS_sig
FS_sig(sigcontext) = FS_reg(&DEBUG_context);
#else
__asm__("movw %w0,%%fs"::"r" (FS_reg(&DEBUG_context)));
#endif
#ifdef GS_sig
GS_sig(sigcontext) = GS_reg(&DEBUG_context);
#else
__asm__("movw %w0,%%gs"::"r" (FS_reg(&DEBUG_context)));
#endif
}
/***********************************************************************
* DEBUG_InfoRegisters
......@@ -123,35 +168,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",
CS_reg(DEBUG_context), SS_reg(DEBUG_context),
DS_reg(DEBUG_context), ES_reg(DEBUG_context) );
#ifdef FS_reg
fprintf( stderr, " FS:%04x", FS_reg(DEBUG_context) );
#endif
#ifdef GS_reg
fprintf( stderr, " GS:%04x", GS_reg(DEBUG_context) );
#endif
fprintf( stderr," CS:%04x SS:%04x DS:%04x ES:%04x FS:%04x GS:%04x",
(WORD)CS_reg(&DEBUG_context), (WORD)SS_reg(&DEBUG_context),
(WORD)DS_reg(&DEBUG_context), (WORD)ES_reg(&DEBUG_context),
(WORD)FS_reg(&DEBUG_context), (WORD)GS_reg(&DEBUG_context) );
if (dbg_mode == 16)
{
fprintf( stderr,"\n IP:%04x SP:%04x BP:%04x FLAGS:%04x\n",
IP_reg(DEBUG_context), SP_reg(DEBUG_context),
BP_reg(DEBUG_context), FL_reg(DEBUG_context) );
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_reg(DEBUG_context), BX_reg(DEBUG_context),
CX_reg(DEBUG_context), DX_reg(DEBUG_context),
SI_reg(DEBUG_context), DI_reg(DEBUG_context) );
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, "\n EIP:%08lx ESP:%08lx EBP:%08lx EFLAGS:%08lx\n",
EIP_reg(DEBUG_context), ESP_reg(DEBUG_context),
EBP_reg(DEBUG_context), EFL_reg(DEBUG_context) );
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_reg(DEBUG_context), EBX_reg(DEBUG_context),
ECX_reg(DEBUG_context), EDX_reg(DEBUG_context) );
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) );
ESI_reg(&DEBUG_context), EDI_reg(&DEBUG_context) );
}
}
......@@ -170,39 +210,35 @@ BOOL32 DEBUG_ValidateRegisters(void)
((((seg) & 7) != 7) || IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(seg)))) \
{ \
fprintf( stderr, "*** Invalid value for %s register: %04x\n", \
(name), (seg) ); \
(name), (WORD)(seg) ); \
return FALSE; \
}
if (CS_reg(DEBUG_context) != WINE_CODE_SELECTOR)
CHECK_SEG( CS_reg(DEBUG_context), "CS" );
if (SS_reg(DEBUG_context) != WINE_DATA_SELECTOR)
CHECK_SEG( SS_reg(DEBUG_context), "SS" );
if (DS_reg(DEBUG_context) != WINE_DATA_SELECTOR)
CHECK_SEG( DS_reg(DEBUG_context), "DS" );
if (ES_reg(DEBUG_context) != WINE_DATA_SELECTOR)
CHECK_SEG( ES_reg(DEBUG_context), "ES" );
#ifdef FS_reg
if (FS_reg(DEBUG_context) != WINE_DATA_SELECTOR)
CHECK_SEG( FS_reg(DEBUG_context), "FS" );
#endif
#ifdef GS_reg
if (GS_reg(DEBUG_context) != WINE_DATA_SELECTOR)
CHECK_SEG( GS_reg(DEBUG_context), "GS" );
#endif
if (CS_reg(&DEBUG_context) != WINE_CODE_SELECTOR)
CHECK_SEG( CS_reg(&DEBUG_context), "CS" );
if (SS_reg(&DEBUG_context) != WINE_DATA_SELECTOR)
CHECK_SEG( SS_reg(&DEBUG_context), "SS" );
if (DS_reg(&DEBUG_context) != WINE_DATA_SELECTOR)
CHECK_SEG( DS_reg(&DEBUG_context), "DS" );
if (ES_reg(&DEBUG_context) != WINE_DATA_SELECTOR)
CHECK_SEG( ES_reg(&DEBUG_context), "ES" );
if (FS_reg(&DEBUG_context) != WINE_DATA_SELECTOR)
CHECK_SEG( FS_reg(&DEBUG_context), "FS" );
if (GS_reg(&DEBUG_context) != WINE_DATA_SELECTOR)
CHECK_SEG( GS_reg(&DEBUG_context), "GS" );
/* Check that CS and SS are not NULL */
if (!(CS_reg(DEBUG_context) & ~3))
if (!(CS_reg(&DEBUG_context) & ~3))
{
fprintf( stderr, "*** Invalid value for CS register: %04x\n",
CS_reg(DEBUG_context) );
(WORD)CS_reg(&DEBUG_context) );
return FALSE;
}
if (!(SS_reg(DEBUG_context) & ~3))
if (!(SS_reg(&DEBUG_context) & ~3))
{
fprintf( stderr, "*** Invalid value for SS register: %04x\n",
SS_reg(DEBUG_context) );
(WORD)SS_reg(&DEBUG_context) );
return FALSE;
}
return TRUE;
......
......@@ -372,4 +372,12 @@ leave:
}
#else /* !__ELF__ */
int
DEBUG_ReadExecutableDbgInfo(void)
{
return FALSE;
}
#endif /* __ELF__ */
......@@ -57,17 +57,17 @@ void DEBUG_InfoStack(void)
DBG_ADDR addr;
fprintf(stderr,"Stack dump:\n");
if ((SS_reg(DEBUG_context) == WINE_DATA_SELECTOR) ||
(GET_SEL_FLAGS(SS_reg(DEBUG_context)) & LDT_FLAGS_32BIT))
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);
addr.off = ESP_reg(&DEBUG_context);
DEBUG_ExamineMemory( &addr, 24, 'x' );
}
else /* 16-bit mode */
{
addr.seg = SS_reg(DEBUG_context);
addr.off = SP_reg(DEBUG_context);
addr.seg = SS_reg(&DEBUG_context);
addr.off = SP_reg(&DEBUG_context);
DEBUG_ExamineMemory( &addr, 24, 'w' );
}
fprintf(stderr,"\n");
......@@ -85,40 +85,28 @@ void DEBUG_BackTrace(void)
int frameno = 0;
fprintf(stderr,"Backtrace:\n");
if (SS_reg(DEBUG_context) == WINE_DATA_SELECTOR) /* 32-bit mode */
if (SS_reg(&DEBUG_context) == WINE_DATA_SELECTOR) /* 32-bit mode */
{
addr.seg = 0;
addr.off = EBP_reg(DEBUG_context);
nframe = 1;
while (addr.off)
{
FRAME32 *frame = (FRAME32 *)addr.off;
if (!DBG_CHECK_READ_PTR( &addr, sizeof(FRAME32) )) return;
if (!frame->ip) break;
addr.off = frame->bp;
nframe++;
}
if( frames != NULL )
{
free(frames);
}
frames = (struct bt_info *) xmalloc(nframe
* sizeof(struct bt_info) );
nframe = 1;
if (frames) free( frames );
frames = (struct bt_info *) xmalloc( sizeof(struct bt_info) );
fprintf(stderr,"%s%d ",(curr_frame == 0 ? "=>" : " "), frameno++);
addr.off = EIP_reg(DEBUG_context);
addr.seg = 0;
addr.off = EIP_reg(&DEBUG_context);
frames[0].eip = addr.off;
frames[0].frame = DEBUG_PrintAddress( &addr, 32, TRUE );
fprintf( stderr, "\n" );
addr.off = EBP_reg(DEBUG_context);
frames[0].ebp = addr.off;
frames[0].ebp = addr.off = EBP_reg(&DEBUG_context);
while (addr.off)
{
FRAME32 *frame = (FRAME32 *)addr.off;
if (!DBG_CHECK_READ_PTR( &addr, sizeof(FRAME32) )) return;
if (!frame->ip) break;
nframe++;
frames = (struct bt_info *)xrealloc(frames,
nframe*sizeof(struct bt_info));
fprintf(stderr,"%s%d ", (frameno == curr_frame ? "=>" : " "),
frameno);
addr.off = frame->ip;
......@@ -133,7 +121,7 @@ void DEBUG_BackTrace(void)
}
else /* 16-bit mode */
{
WORD ss = SS_reg(DEBUG_context), cs = CS_reg(DEBUG_context);
WORD ss = SS_reg(&DEBUG_context), cs = CS_reg(&DEBUG_context);
if (GET_SEL_FLAGS(ss) & LDT_FLAGS_32BIT)
{
fprintf( stderr, "Not implemented: 32-bit backtrace on a different stack segment.\n" );
......@@ -141,11 +129,11 @@ void DEBUG_BackTrace(void)
}
fprintf( stderr,"%d ", frameno++ );
addr.seg = cs;
addr.off = IP_reg(DEBUG_context);
addr.off = IP_reg(&DEBUG_context);
DEBUG_PrintAddress( &addr, 16, TRUE );
fprintf( stderr, "\n" );
addr.seg = ss;
addr.off = BP_reg(DEBUG_context) & ~1;
addr.off = BP_reg(&DEBUG_context) & ~1;
for (;;)
{
FRAME16 *frame = (FRAME16 *)DBG_ADDR_TO_LIN(&addr);
......
prefix = @prefix@
sysconfdir = @sysconfdir@
DEFS = -D__WINE__ -DETCDIR=\"$(sysconfdir)\"
DEFS = -D__WINE__ -DNO_TRANSITION_TYPES -DETCDIR=\"$(sysconfdir)\"
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ..
SRCDIR = @srcdir@
......
......@@ -6,16 +6,18 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include "windows.h"
#include "winerror.h"
#include "dos_fs.h"
#include "drive.h"
#include "file.h"
#include "heap.h"
#include "msdos.h"
#include "options.h"
#include "xmalloc.h"
#include "stddebug.h"
#include "debug.h"
......@@ -42,12 +44,12 @@ static int DIR_GetPath( const char *keyname, const char *defval,
{
char path[MAX_PATHNAME_LEN];
const char *dos_name ,*unix_name;
BYTE attr;
BY_HANDLE_FILE_INFORMATION info;
PROFILE_GetWineIniString( "wine", keyname, defval, path, sizeof(path) );
if (!(unix_name = DOSFS_GetUnixFileName( path, TRUE )) ||
!FILE_Stat( unix_name, &attr, NULL, NULL, NULL ) ||
!(attr & FA_DIRECTORY))
!FILE_Stat( unix_name, &info ) ||
!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
fprintf(stderr, "Invalid path '%s' for %s directory\n", path, keyname);
return 0;
......@@ -58,8 +60,8 @@ static int DIR_GetPath( const char *keyname, const char *defval,
keyname, unix_name );
return 0;
}
*unix_path = xstrdup( unix_name );
*dos_path = xstrdup( dos_name );
*unix_path = HEAP_strdupA( SystemHeap, 0, unix_name );
*dos_path = HEAP_strdupA( SystemHeap, 0, dos_name );
return 1;
}
......@@ -71,7 +73,7 @@ void DIR_ParseWindowsPath( char *path )
{
char *p;
const char *dos_name ,*unix_name;
BYTE attr;
BY_HANDLE_FILE_INFORMATION info;
int i;
for ( ; path && *path; path = p)
......@@ -86,8 +88,8 @@ void DIR_ParseWindowsPath( char *path )
break;
}
if (!(unix_name = DOSFS_GetUnixFileName( path, TRUE )) ||
!FILE_Stat( unix_name, &attr, NULL, NULL, NULL ) ||
!(attr & FA_DIRECTORY))
!FILE_Stat( unix_name, &info ) ||
!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
fprintf(stderr,"Warning: invalid dir '%s' in path, deleting it.\n",
path );
......@@ -99,8 +101,8 @@ void DIR_ParseWindowsPath( char *path )
unix_name );
continue;
}
DIR_UnixPath[DIR_PathElements] = xstrdup( unix_name );
DIR_DosPath[DIR_PathElements] = xstrdup( dos_name );
DIR_UnixPath[DIR_PathElements] = HEAP_strdupA(SystemHeap,0,unix_name);
DIR_DosPath[DIR_PathElements] = HEAP_strdupA(SystemHeap,0,dos_name);
DIR_PathElements++;
}
......@@ -171,11 +173,11 @@ int DIR_Init(void)
/* Put the temp and Windows directories into the environment */
env_p = (char *)xmalloc( strlen(DIR_TempDosDir) + 6 );
env_p = HEAP_xalloc( SystemHeap, 0, strlen(DIR_TempDosDir) + 6 );
strcpy( env_p, "TEMP=" );
strcpy( env_p + 5, DIR_TempDosDir );
putenv( env_p );
env_p = (char *)xmalloc( strlen(DIR_WindowsDosDir) + 8 );
env_p = HEAP_xalloc( SystemHeap, 0, strlen(DIR_WindowsDosDir) + 8 );
strcpy( env_p, "windir=" );
strcpy( env_p + 7, DIR_WindowsDosDir );
putenv( env_p );
......@@ -325,3 +327,303 @@ UINT32 GetSystemDirectory32W( LPWSTR path, UINT32 count )
if (path) lstrcpynAtoW( path, DIR_SystemDosDir, count );
return strlen( DIR_SystemDosDir );
}
/***********************************************************************
* CreateDirectory16 (KERNEL.144)
*/
BOOL16 CreateDirectory16( LPCSTR path, LPVOID dummy )
{
dprintf_file( stddeb,"CreateDirectory16(%s,%p)\n", path, dummy );
return (BOOL16)CreateDirectory32A( path, NULL );
}
/***********************************************************************
* CreateDirectory32A (KERNEL32.39)
*/
BOOL32 CreateDirectory32A( LPCSTR path, LPSECURITY_ATTRIBUTES lpsecattribs )
{
const char *unixName;
dprintf_file( stddeb, "CreateDirectory32A(%s,%p)\n", path, lpsecattribs );
if ((unixName = DOSFS_IsDevice( path )) != NULL)
{
dprintf_file(stddeb, "CreateDirectory: device '%s'!\n", unixName);
DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk );
return FALSE;
}
if (!(unixName = DOSFS_GetUnixFileName( path, FALSE ))) return 0;
if ((mkdir( unixName, 0777 ) == -1) && (errno != EEXIST))
{
FILE_SetDosError();
return FALSE;
}
return TRUE;
}
/***********************************************************************
* CreateDirectory32W (KERNEL32.42)
*/
BOOL32 CreateDirectory32W( LPCWSTR path, LPSECURITY_ATTRIBUTES lpsecattribs )
{
LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
BOOL32 ret = CreateDirectory32A( xpath, lpsecattribs );
HeapFree( GetProcessHeap(), 0, xpath );
return ret;
}
/***********************************************************************
* CreateDirectoryEx32A (KERNEL32.40)
*/
BOOL32 CreateDirectoryEx32A( LPCSTR template, LPCSTR path,
LPSECURITY_ATTRIBUTES lpsecattribs)
{
return CreateDirectory32A(path,lpsecattribs);
}
/***********************************************************************
* CreateDirectoryEx32W (KERNEL32.41)
*/
BOOL32 CreateDirectoryEx32W( LPCWSTR template, LPCWSTR path,
LPSECURITY_ATTRIBUTES lpsecattribs)
{
return CreateDirectory32W(path,lpsecattribs);
}
/***********************************************************************
* RemoveDirectory16 (KERNEL)
*/
BOOL16 RemoveDirectory16( LPCSTR path )
{
return (BOOL16)RemoveDirectory32A( path );
}
/***********************************************************************
* RemoveDirectory32A (KERNEL32.437)
*/
BOOL32 RemoveDirectory32A( LPCSTR path )
{
const char *unixName;
dprintf_file(stddeb, "RemoveDirectory: '%s'\n", path );
if ((unixName = DOSFS_IsDevice( path )) != NULL)
{
dprintf_file(stddeb, "RemoveDirectory: device '%s'!\n", unixName);
DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
return FALSE;
}
if (!(unixName = DOSFS_GetUnixFileName( path, TRUE ))) return FALSE;
if (rmdir( unixName ) == -1)
{
FILE_SetDosError();
return FALSE;
}
return TRUE;
}
/***********************************************************************
* RemoveDirectory32W (KERNEL32.438)
*/
BOOL32 RemoveDirectory32W( LPCWSTR path )
{
LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
BOOL32 ret = RemoveDirectory32A( xpath );
HeapFree( GetProcessHeap(), 0, xpath );
return ret;
}
/***********************************************************************
* DIR_SearchPath
*
* Implementation of SearchPath32A. 'win32' specifies whether the search
* order is Win16 (module path last) or Win32 (module path first).
*
* FIXME: should return long path names.
*/
DWORD DIR_SearchPath( LPCSTR path, LPCSTR name, LPCSTR ext,
DWORD buflen, LPSTR buffer, LPSTR *lastpart,
BOOL32 win32 )
{
DWORD len;
LPSTR tmp;
int i;
/* First check the supplied parameters */
if (strchr( name, '.' )) ext = NULL; /* Ignore the specified extension */
if (path && !*path) path = NULL; /* Ignore empty path */
len = strlen(name);
if (ext) len += strlen(ext);
if (path) len += strlen(path) + 1;
/* Allocate a buffer for the file name and extension */
if (path || ext)
{
if (!(tmp = HeapAlloc( GetProcessHeap(), 0, len + 1 )))
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
if (path)
{
strcpy( tmp, path );
strcat( tmp, "\\" );
strcat( tmp, name );
}
else strcpy( tmp, name );
if (ext) strcat( tmp, ext );
}
else tmp = (LPSTR)name;
/* If we have an explicit path, everything's easy */
if (path || (*tmp && (tmp[1] == ':')) ||
strchr( tmp, '/' ) || strchr( tmp, '\\' ))
{
if (!DOSFS_GetUnixFileName( tmp, TRUE )) goto not_found;
lstrcpyn32A( buffer, tmp, buflen );
if (tmp != name) HeapFree( GetProcessHeap(), 0, tmp );
return len;
}
/* Try the path of the current executable (for Win32 search order) */
if (win32 && GetCurrentTask())
{
LPSTR p;
GetModuleFileName32A( GetCurrentTask(), buffer, buflen );
if ((p = strrchr( buffer, '\\' )))
{
lstrcpyn32A( p + 1, tmp, (INT32)buflen - (p - buffer) );
if (DOSFS_GetUnixFileName( buffer, TRUE ))
{
*p = '\0';
goto found;
}
}
}
/* Try the current directory */
if (DOSFS_GetUnixFileName( tmp, TRUE ))
{
GetCurrentDirectory32A( buflen, buffer );
goto found;
}
/* Try the Windows directory */
if (DOSFS_FindUnixName( DIR_WindowsUnixDir, name, NULL, 0,
DRIVE_GetFlags( DIR_WindowsDosDir[0] - 'A' ) ))
{
lstrcpyn32A( buffer, DIR_WindowsDosDir, buflen );
goto found;
}
/* Try the Windows system directory */
if (DOSFS_FindUnixName( DIR_SystemUnixDir, name, NULL, 0,
DRIVE_GetFlags( DIR_SystemDosDir[0] - 'A' ) ))
{
lstrcpyn32A( buffer, DIR_SystemDosDir, buflen );
goto found;
}
/* Try the path of the current executable (for Win16 search order) */
if (!win32 && GetCurrentTask())
{
LPSTR p;
GetModuleFileName32A( GetCurrentTask(), buffer, buflen );
if ((p = strrchr( buffer, '\\' )))
{
lstrcpyn32A( p + 1, tmp, (INT32)buflen - (p - buffer) );
if (DOSFS_GetUnixFileName( buffer, TRUE ))
{
*p = '\0';
goto found;
}
}
}
/* Try all directories in path */
for (i = 0; i < DIR_PathElements; i++)
{
if (DOSFS_FindUnixName( DIR_UnixPath[i], name, NULL, 0,
DRIVE_GetFlags( DIR_DosPath[i][0] - 'A' ) ))
{
lstrcpyn32A( buffer, DIR_DosPath[i], buflen );
goto found;
}
}
not_found:
if (tmp != name) HeapFree( GetProcessHeap(), 0, tmp );
SetLastError( ERROR_FILE_NOT_FOUND );
DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk );
return 0;
found:
len = strlen(buffer);
if (lastpart) *lastpart = buffer + len + 1;
if (len + 1 < buflen)
{
buffer += len;
*buffer++ = '\\';
buflen -= len + 1;
lstrcpyn32A( buffer, tmp, buflen );
}
len += strlen(tmp) + 1;
if (tmp != name) HeapFree( GetProcessHeap(), 0, tmp );
return len;
}
/***********************************************************************
* SearchPath32A (KERNEL32.447)
*/
DWORD SearchPath32A( LPCSTR path, LPCSTR name, LPCSTR ext, DWORD buflen,
LPSTR buffer, LPSTR *lastpart )
{
return DIR_SearchPath( path, name, ext, buflen, buffer, lastpart, TRUE );
}
/***********************************************************************
* SearchPath32W (KERNEL32.448)
*/
DWORD SearchPath32W( LPCWSTR path, LPCWSTR name, LPCWSTR ext, DWORD buflen,
LPWSTR buffer, LPWSTR *lastpart )
{
LPSTR pathA = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
LPSTR extA = HEAP_strdupWtoA( GetProcessHeap(), 0, ext );
LPSTR lastpartA;
LPSTR bufferA = HeapAlloc( GetProcessHeap(), 0, buflen + 1 );
DWORD ret = DIR_SearchPath( pathA, nameA, extA, buflen, bufferA,
&lastpartA, TRUE );
lstrcpyAtoW( buffer, bufferA );
if (lastpart)
{
if (lastpartA) *lastpart = buffer + (lastpartA - bufferA);
else *lastpart = NULL;
}
HeapFree( GetProcessHeap(), 0, bufferA );
HeapFree( GetProcessHeap(), 0, extA );
HeapFree( GetProcessHeap(), 0, nameA );
HeapFree( GetProcessHeap(), 0, pathA );
return ret;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment