Commit a00b49f0 authored by Andreas Mohr's avatar Andreas Mohr Committed by Alexandre Julliard

- Several kernel.spec return type mismatch fixes

- [GS]etSelectorBase Win32s offset support by Ulrich Weigand (thanks v.m. !!) - Move AppToWine/WineToApp macros as W32S_APP2WINE etc. to ldt.h - LocalNotify() basic support - Fixes for local heap handling with heap handles created by Virtual*()
parent 94632fcd
......@@ -12,13 +12,13 @@ file krnl386.exe
5 pascal16 LocalAlloc(word word) LocalAlloc16
6 pascal16 LocalReAlloc(word word word) LocalReAlloc16
7 pascal16 LocalFree(word) LocalFree16
8 pascal16 LocalLock(word) LocalLock16
8 pascal LocalLock(word) LocalLock16
9 pascal16 LocalUnlock(word) LocalUnlock16
10 pascal16 LocalSize(word) LocalSize16
11 pascal16 LocalHandle(word) LocalHandle16
12 pascal16 LocalFlags(word) LocalFlags16
13 pascal16 LocalCompact(word) LocalCompact16
14 pascal16 LocalNotify(long) LocalNotify
14 pascal LocalNotify(long) LocalNotify
15 pascal16 GlobalAlloc(word long) GlobalAlloc16
16 pascal16 GlobalReAlloc(word long word) GlobalReAlloc16
17 pascal16 GlobalFree(word) GlobalFree16
......@@ -38,7 +38,7 @@ file krnl386.exe
31 pascal16 PostEvent(word) PostEvent
32 pascal16 SetPriority(word s_word) SetPriority
33 pascal16 LockCurrentTask(word) LockCurrentTask
34 pascal SetTaskQueue(word word) SetTaskQueue
34 pascal16 SetTaskQueue(word word) SetTaskQueue
35 pascal16 GetTaskQueue(word) GetTaskQueue
36 pascal GetCurrentTask() WIN16_GetCurrentTask
37 pascal GetCurrentPDB() GetCurrentPDB
......@@ -188,8 +188,8 @@ file krnl386.exe
183 equate __0000H 0
184 pascal GlobalDOSAlloc(long) GlobalDOSAlloc
185 pascal16 GlobalDOSFree(word) GlobalDOSFree
186 pascal GetSelectorBase(word) GetSelectorBase
187 pascal16 SetSelectorBase(word long) SetSelectorBase
186 pascal GetSelectorBase(word) WIN16_GetSelectorBase
187 pascal16 SetSelectorBase(word long) WIN16_SetSelectorBase
188 pascal GetSelectorLimit(word) GetSelectorLimit
189 pascal16 SetSelectorLimit(word long) SetSelectorLimit
190 equate __E000H 0
......
......@@ -156,6 +156,7 @@ static const CALLBACKS_TABLE CALLBACK_EmulatorTable =
(void *)CallTo16_word_lwww, /* CallWordBreakProc */
(void *)CallTo16_word_ww, /* CallBootAppProc */
(void *)CallTo16_word_www, /* CallLoadAppSegProc */
(void *)CallTo16_word_www, /* CallLocalNotifyFunc */
(void *)CallTo16_word_, /* CallSystemTimerProc */
(void *)CallTo16_word_www, /* CallResourceHandlerProc */
(void *)CallTo16_word_wwwl, /* CallPostAppMessageProc */
......
......@@ -36,6 +36,7 @@ typedef struct
INT16, INT16 );
VOID (CALLBACK *CallBootAppProc)( FARPROC16, HANDLE16, HFILE16 );
WORD (CALLBACK *CallLoadAppSegProc)( FARPROC16, HANDLE16, HFILE16, WORD );
WORD (CALLBACK *CallLocalNotifyFunc)( FARPROC16, WORD, HLOCAL16, WORD );
VOID (CALLBACK *CallSystemTimerProc)( FARPROC16 );
HGLOBAL16 (CALLBACK *CallResourceHandlerProc)( FARPROC16, HGLOBAL16, HMODULE16, HRSRC16 );
BOOL16 (CALLBACK *CallPostAppMessageProc)( FARPROC16, HTASK16, UINT16, WPARAM16, LPARAM );
......
......@@ -67,6 +67,11 @@ extern ldt_copy_entry ldt_copy[LDT_SIZE];
#define PTR_SEG_OFF_TO_HUGEPTR(seg,off) \
PTR_SEG_OFF_TO_SEGPTR( (seg) + (HIWORD(off) << __AHSHIFT), LOWORD(off) )
#define W32S_APPLICATION() (PROCESS_Current()->flags & PDB32_WIN32S_PROC)
#define W32S_OFFSET 0x10000
#define W32S_APP2WINE(addr, offset) ((addr)? (DWORD)(addr) + (DWORD)(offset) : 0)
#define W32S_WINE2APP(addr, offset) ((addr)? (DWORD)(addr) - (DWORD)(offset) : 0)
extern unsigned char ldt_flags_copy[LDT_SIZE];
#define LDT_FLAGS_TYPE 0x03 /* Mask for segment type */
......
......@@ -6616,7 +6616,7 @@ UINT16 WINAPI GetCommEventMask(INT16,UINT16);
HBRUSH16 WINAPI GetControlBrush(HWND16,HDC16,UINT16);
VOID WINAPI GetCodeInfo(FARPROC16,SEGINFO*);
HFONT16 WINAPI GetCurLogFont(HDC16);
HANDLE16 WINAPI GetCurrentPDB(void);
DWORD WINAPI GetCurrentPDB(void);
DWORD WINAPI GetCurrentPosition(HDC16);
HTASK16 WINAPI GetCurrentTask(void);
DWORD WINAPI GetDCHook(HDC16,FARPROC16*);
......
......@@ -1426,13 +1426,15 @@ DWORD WINAPI WIN16_GetCurrentTask(void)
/***********************************************************************
* GetCurrentPDB (KERNEL.37)
*
* UNDOC: returns PSP of KERNEL in high word
*/
HANDLE16 WINAPI GetCurrentPDB(void)
DWORD WINAPI GetCurrentPDB(void)
{
TDB *pTask;
if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
return pTask->hPDB;
return MAKELONG(pTask->hPDB, 0); /* FIXME */
}
......@@ -1596,6 +1598,9 @@ WORD WINAPI SetSigHandler( FARPROC16 newhandler, FARPROC16* oldhandler,
/***********************************************************************
* GlobalNotify (KERNEL.154)
*
* Note that GlobalNotify does _not_ return the old NotifyProc
* -- contrary to LocalNotify !!
*/
VOID WINAPI GlobalNotify( FARPROC16 proc )
{
......
......@@ -25,6 +25,7 @@
#include "stackframe.h"
#include "toolhelp.h"
#include "debug.h"
#include "callback.h"
typedef struct
{
......@@ -44,6 +45,12 @@ typedef struct
#define LOCAL_ARENA_FREE 0
#define LOCAL_ARENA_FIXED 1
/* LocalNotify() msgs */
#define LN_OUTOFMEM 0
#define LN_MOVE 1
#define LN_DISCARD 2
/* Layout of a handle entry table
*
* WORD count of entries
......@@ -426,24 +433,29 @@ BOOL16 WINAPI LocalInit( HANDLE16 selector, WORD start, WORD end )
/***********************************************************************
* LOCAL_GrowHeap
*/
static void LOCAL_GrowHeap( HANDLE16 ds )
static BOOL16 LOCAL_GrowHeap( HANDLE16 ds )
{
HANDLE16 hseg = GlobalHandle16( ds );
LONG oldsize = GlobalSize16( hseg );
HANDLE16 hseg;
LONG oldsize;
LONG end;
LOCALHEAPINFO *pHeapInfo;
WORD freeArena, lastArena;
LOCALARENA *pArena, *pLastArena;
char *ptr;
hseg = GlobalHandle16( ds );
/* maybe mem allocated by Virtual*() ? */
if (!hseg) return FALSE;
oldsize = GlobalSize16( hseg );
/* if nothing can be gained, return */
if (oldsize > 0xfff0) return;
if (oldsize > 0xfff0) return FALSE;
hseg = GlobalReAlloc16( hseg, 0x10000, GMEM_FIXED );
ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
pHeapInfo = LOCAL_GetHeap( ds );
if (pHeapInfo == NULL) {
ERR(local, "Heap not found\n" );
return;
return FALSE;
}
end = GlobalSize16( hseg );
lastArena = (end - sizeof(LOCALARENA)) & ~3;
......@@ -478,6 +490,7 @@ static void LOCAL_GrowHeap( HANDLE16 ds )
TRACE(local, "Heap expanded\n" );
LOCAL_PrintHeap( ds );
return TRUE;
}
......@@ -715,6 +728,9 @@ WORD LOCAL_Compact( HANDLE16 ds, UINT16 minfree, UINT16 flags )
movesize - ARENA_HEADER_SIZE );
/* Free the old location */
LOCAL_FreeArena(ds, movearena);
if (pInfo->notify)
Callbacks->CallLocalNotifyFunc(pInfo->notify, LN_MOVE,
(WORD)((char *)pEntry - ptr), pEntry->addr);
/* Update handle table entry */
pEntry->addr = finalarena + ARENA_HEADER_SIZE + sizeof(HLOCAL16) ;
}
......@@ -751,9 +767,11 @@ WORD LOCAL_Compact( HANDLE16 ds, UINT16 minfree, UINT16 flags )
TRACE(local, "Discarding handle %04x (block %04x).\n",
(char *)pEntry - ptr, pEntry->addr);
LOCAL_FreeArena(ds, ARENA_HEADER(pEntry->addr));
if (pInfo->notify)
Callbacks->CallLocalNotifyFunc(pInfo->notify, LN_DISCARD,
(char *)pEntry - ptr, pEntry->flags);
pEntry->addr = 0;
pEntry->flags = (LMEM_DISCARDED >> 8);
/* Call localnotify proc */
}
}
table = *(WORD *)pEntry;
......@@ -814,6 +832,9 @@ static HLOCAL16 LOCAL_GetBlock( HANDLE16 ds, WORD size, WORD flags )
size += ARENA_HEADER_SIZE;
size = LALIGN( MAX( size, sizeof(LOCALARENA) ) );
#if 0
notify_done:
#endif
/* Find a suitable free block */
arena = LOCAL_FindFreeBlock( ds, size );
if (arena == 0) {
......@@ -823,7 +844,15 @@ static HLOCAL16 LOCAL_GetBlock( HANDLE16 ds, WORD size, WORD flags )
}
if (arena == 0) {
/* still no space: try to grow the segment */
LOCAL_GrowHeap( ds );
if (!(LOCAL_GrowHeap( ds )))
{
#if 0
/* FIXME: doesn't work correctly yet */
if ((pInfo->notify) && (Callbacks->CallLocalNotifyFunc(pInfo->notify, LN_OUTOFMEM, ds - 20, size))) /* FIXME: "size" correct ? (should indicate bytes needed) */
goto notify_done;
#endif
return 0;
}
ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
pInfo = LOCAL_GetHeap( ds );
arena = LOCAL_FindFreeBlock( ds, size );
......@@ -839,6 +868,12 @@ static HLOCAL16 LOCAL_GetBlock( HANDLE16 ds, WORD size, WORD flags )
ERR(local, "not enough space in local heap "
"%04x for %d bytes\n", ds, size );
}
#if 0
if ((pInfo->notify) &&
/* FIXME: "size" correct ? (should indicate bytes needed) */
(Callbacks->CallLocalNotifyFunc(pInfo->notify, LN_OUTOFMEM, ds, size)))
goto notify_done;
#endif
return 0;
}
......@@ -1563,6 +1598,21 @@ UINT16 WINAPI LocalCompact16( UINT16 minfree )
/***********************************************************************
* LocalNotify (KERNEL.14)
*
* Installs a callback function that is called for local memory events
* Callback function prototype is
* BOOL16 NotifyFunc(WORD wMsg, HLOCAL16 hMem, WORD wArg)
* wMsg:
* - LN_OUTOFMEM
* NotifyFunc seems to be responsible for allocating some memory,
* returns TRUE for success.
* wArg = number of bytes needed additionally
* - LN_MOVE
* hMem = handle; wArg = old mem location
* - LN_DISCARD
* NotifyFunc seems to be strongly encouraged to return TRUE,
* otherwise LogError() gets called.
* hMem = handle; wArg = flags
*/
FARPROC16 WINAPI LocalNotify( FARPROC16 func )
{
......
......@@ -10,6 +10,7 @@
#include "miscemu.h"
#include "selectors.h"
#include "stackframe.h"
#include "process.h"
#include "debug.h"
......@@ -301,6 +302,17 @@ void WINAPI LongPtrAdd( DWORD ptr, DWORD add )
/***********************************************************************
* GetSelectorBase (KERNEL.186)
*/
DWORD WINAPI WIN16_GetSelectorBase( WORD sel )
{
/*
* Note: For Win32s processes, the whole linear address space is
* shifted by 0x10000 relative to the OS linear address space.
* See the comment in msdos/vxd.c.
*/
DWORD base = GetSelectorBase( sel );
return W32S_WINE2APP( base, W32S_APPLICATION() ? W32S_OFFSET : 0 );
}
DWORD WINAPI GetSelectorBase( WORD sel )
{
DWORD base = GET_SEL_BASE(sel);
......@@ -315,6 +327,18 @@ DWORD WINAPI GetSelectorBase( WORD sel )
/***********************************************************************
* SetSelectorBase (KERNEL.187)
*/
DWORD WINAPI WIN16_SetSelectorBase( WORD sel, DWORD base )
{
/*
* Note: For Win32s processes, the whole linear address space is
* shifted by 0x10000 relative to the OS linear address space.
* See the comment in msdos/vxd.c.
*/
SetSelectorBase( sel,
W32S_APP2WINE( base, W32S_APPLICATION() ? W32S_OFFSET : 0 ) );
return sel;
}
WORD WINAPI SetSelectorBase( WORD sel, DWORD base )
{
ldt_entry entry;
......
......@@ -110,6 +110,17 @@ static WORD WINAPI CALLBACK_CallLoadAppSegProc( FARPROC16 proc,
/**********************************************************************
* CALLBACK_CallLocalNotifyFunc
*/
static WORD WINAPI CALLBACK_CallLocalNotifyFunc( FARPROC16 proc,
WORD wMsg, HLOCAL16 hMem,
WORD wArg )
{
return proc( wMsg, hMem, wArg );
}
/**********************************************************************
* CALLBACK_CallSystemTimerProc
*/
static void WINAPI CALLBACK_CallSystemTimerProc( FARPROC16 proc )
......@@ -262,6 +273,7 @@ static const CALLBACKS_TABLE CALLBACK_WinelibTable =
CALLBACK_CallWordBreakProc, /* CallWordBreakProc */
CALLBACK_CallBootAppProc, /* CallBootAppProc */
CALLBACK_CallLoadAppSegProc, /* CallLoadAppSegProc */
CALLBACK_CallLocalNotifyFunc, /* CallLocalNotifyFunc */
CALLBACK_CallSystemTimerProc, /* CallSystemTimerProc */
CALLBACK_CallResourceHandlerProc, /* CallResourceHandlerProc */
NULL, /* CallPostAppMessageProc */
......
......@@ -486,9 +486,7 @@ void WINAPI INT_Int31Handler( CONTEXT *context )
* shifted by 0x10000 relative to the OS linear address space.
* See the comment in msdos/vxd.c.
*/
DWORD offset = PROCESS_Current()->flags & PDB32_WIN32S_PROC ? 0x10000 : 0;
#define AppToWine(addr) ((addr)? ((DWORD)(addr)) + offset : 0)
#define WineToApp(addr) ((addr)? ((DWORD)(addr)) - offset : 0)
DWORD offset = W32S_APPLICATION() ? W32S_OFFSET : 0;
DWORD dw;
BYTE *ptr;
......@@ -603,16 +601,16 @@ void WINAPI INT_Int31Handler( CONTEXT *context )
if ((dw >= base) && (dw < base + 0x110000)) dw -= base;
}
#endif
CX_reg(context) = HIWORD(WineToApp(dw));
DX_reg(context) = LOWORD(WineToApp(dw));
CX_reg(context) = HIWORD(W32S_WINE2APP(dw, offset));
DX_reg(context) = LOWORD(W32S_WINE2APP(dw, offset));
}
break;
case 0x0007: /* Set selector base address */
TRACE(int31, "set selector base address (0x%04x,0x%08lx)\n",
BX_reg(context),
AppToWine(MAKELONG(DX_reg(context),CX_reg(context))));
dw = AppToWine(MAKELONG(DX_reg(context), CX_reg(context)));
W32S_APP2WINE(MAKELONG(DX_reg(context),CX_reg(context)), offset));
dw = W32S_APP2WINE(MAKELONG(DX_reg(context), CX_reg(context)), offset);
#ifdef MZ_SUPPORTED
/* well, what else could we possibly do? */
if (pModule && pModule->lpDosTask) {
......@@ -657,7 +655,7 @@ void WINAPI INT_Int31Handler( CONTEXT *context )
{
ldt_entry entry;
LDT_GetEntry( SELECTOR_TO_ENTRY( BX_reg(context) ), &entry );
entry.base = WineToApp(entry.base);
entry.base = W32S_WINE2APP(entry.base, offset);
/* FIXME: should use ES:EDI for 32-bit clients */
LDT_EntryToBytes( PTR_SEG_OFF_TO_LIN( ES_reg(context),
......@@ -671,7 +669,7 @@ void WINAPI INT_Int31Handler( CONTEXT *context )
ldt_entry entry;
LDT_BytesToEntry( PTR_SEG_OFF_TO_LIN( ES_reg(context),
DI_reg(context) ), &entry );
entry.base = AppToWine(entry.base);
entry.base = W32S_APP2WINE(entry.base, offset);
LDT_SetEntry( SELECTOR_TO_ENTRY( BX_reg(context) ), &entry );
}
......@@ -784,31 +782,31 @@ void WINAPI INT_Int31Handler( CONTEXT *context )
AX_reg(context) = 0x8012; /* linear memory not available */
SET_CFLAG(context);
} else {
BX_reg(context) = SI_reg(context) = HIWORD(WineToApp(ptr));
CX_reg(context) = DI_reg(context) = LOWORD(WineToApp(ptr));
BX_reg(context) = SI_reg(context) = HIWORD(W32S_WINE2APP(ptr, offset));
CX_reg(context) = DI_reg(context) = LOWORD(W32S_WINE2APP(ptr, offset));
}
break;
case 0x0502: /* Free memory block */
TRACE(int31, "free memory block (0x%08lx)\n",
AppToWine(MAKELONG(DI_reg(context),SI_reg(context))));
DPMI_xfree( (void *)AppToWine(MAKELONG(DI_reg(context),
SI_reg(context))) );
W32S_APP2WINE(MAKELONG(DI_reg(context),SI_reg(context)), offset));
DPMI_xfree( (void *)W32S_APP2WINE(MAKELONG(DI_reg(context),
SI_reg(context)), offset) );
break;
case 0x0503: /* Resize memory block */
TRACE(int31, "resize memory block (0x%08lx,%ld)\n",
AppToWine(MAKELONG(DI_reg(context),SI_reg(context))),
W32S_APP2WINE(MAKELONG(DI_reg(context),SI_reg(context)), offset),
MAKELONG(CX_reg(context),BX_reg(context)));
if (!(ptr = (BYTE *)DPMI_xrealloc(
(void *)AppToWine(MAKELONG(DI_reg(context),SI_reg(context))),
(void *)W32S_APP2WINE(MAKELONG(DI_reg(context),SI_reg(context)), offset),
MAKELONG(CX_reg(context),BX_reg(context)))))
{
AX_reg(context) = 0x8012; /* linear memory not available */
SET_CFLAG(context);
} else {
BX_reg(context) = SI_reg(context) = HIWORD(WineToApp(ptr));
CX_reg(context) = DI_reg(context) = LOWORD(WineToApp(ptr));
BX_reg(context) = SI_reg(context) = HIWORD(W32S_WINE2APP(ptr, offset));
CX_reg(context) = DI_reg(context) = LOWORD(W32S_WINE2APP(ptr, offset));
}
break;
......@@ -855,8 +853,8 @@ void WINAPI INT_Int31Handler( CONTEXT *context )
}
else
{
BX_reg(context) = HIWORD(WineToApp(ptr));
CX_reg(context) = LOWORD(WineToApp(ptr));
BX_reg(context) = HIWORD(W32S_WINE2APP(ptr, offset));
CX_reg(context) = LOWORD(W32S_WINE2APP(ptr, offset));
RESET_CFLAG(context);
}
break;
......@@ -868,6 +866,4 @@ void WINAPI INT_Int31Handler( CONTEXT *context )
break;
}
#undef AppToWine
#undef WineToApp
}
......@@ -27,6 +27,7 @@ void WINAPI INT_Int41Handler( CONTEXT *context )
/* Protected-mode debugger services */
switch ( AX_reg(context) )
{
case 0x4f:
case 0x50:
case 0x150:
case 0x51:
......
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