Commit 5efaf50e authored by Ulrich Weigand's avatar Ulrich Weigand Committed by Alexandre Julliard

Implemented (partially) the KERNEL Thunklet API and Callback Client

API (KERNEL.560-568,604-612,619-622). Added stubs for K228, K237, KERNEL.365, KERNEL.447.
parent f276a7d4
...@@ -234,7 +234,7 @@ file krnl386.exe ...@@ -234,7 +234,7 @@ file krnl386.exe
225 pascal RegQueryValueEx(long str ptr ptr ptr ptr) RegQueryValueEx16 225 pascal RegQueryValueEx(long str ptr ptr ptr ptr) RegQueryValueEx16
226 pascal RegSetValueEx(long str long long ptr long) RegSetValueEx16 226 pascal RegSetValueEx(long str long long ptr long) RegSetValueEx16
227 pascal RegFlushKey(long) RegFlushKey 227 pascal RegFlushKey(long) RegFlushKey
228 stub K228 228 pascal16 K228(word) GetExePtr
229 pascal16 K229(long) Local32GetSegment 229 pascal16 K229(long) Local32GetSegment
230 pascal GlobalSmartPageLock(word) GlobalPageLock #? 230 pascal GlobalSmartPageLock(word) GlobalPageLock #?
231 stub GlobalSmartPageUnlock 231 stub GlobalSmartPageUnlock
...@@ -243,7 +243,7 @@ file krnl386.exe ...@@ -243,7 +243,7 @@ file krnl386.exe
234 stub RegSaveKey 234 stub RegSaveKey
235 stub InvalidateNlsCache 235 stub InvalidateNlsCache
236 stub GetProductName 236 stub GetProductName
237 stub K237 237 return K237 0 0
# 262-274 are WinNT extensions; those are not present in Win95 # 262-274 are WinNT extensions; those are not present in Win95
...@@ -307,7 +307,7 @@ file krnl386.exe ...@@ -307,7 +307,7 @@ file krnl386.exe
360 pascal16 OpenFileEx(str ptr word) OpenFile16 360 pascal16 OpenFileEx(str ptr word) OpenFile16
361 return PIGLET_361 0 0 361 return PIGLET_361 0 0
362 stub ThunkTerminateProcess 362 stub ThunkTerminateProcess
365 stub KERNEL_365 365 register KERNEL_365(word word) KERNEL_365
# 403-404 are common to all versions # 403-404 are common to all versions
...@@ -351,13 +351,13 @@ file krnl386.exe ...@@ -351,13 +351,13 @@ file krnl386.exe
444 stub KERNEL_444 # Local32 ??? 444 stub KERNEL_444 # Local32 ???
445 stub KERNEL_445 # Local32 ??? 445 stub KERNEL_445 # Local32 ???
446 stub KERNEL_446 # Local32 ??? 446 stub KERNEL_446 # Local32 ???
447 stub KERNEL_447 447 return KERNEL_447 0 0
448 stub KERNEL_448 448 stub KERNEL_448
449 pascal GetpWin16Lock() GetpWin16Lock16 449 pascal GetpWin16Lock() GetpWin16Lock16
450 pascal VWin32_EventWait(long) VWin32_EventWait 450 pascal VWin32_EventWait(long) VWin32_EventWait
451 pascal VWin32_EventSet(long) VWin32_EventSet 451 pascal VWin32_EventSet(long) VWin32_EventSet
452 pascal LoadLibrary32(str) LoadLibrary32A 452 pascal LoadLibrary32(str) LoadLibrary32A
453 pascal GetProcAddress32(long str) GetProcAddress32 453 pascal GetProcAddress32(long str) WIN16_GetProcAddress32
454 equate __FLATCS 0 # initialized by BUILTIN_Init() 454 equate __FLATCS 0 # initialized by BUILTIN_Init()
455 equate __FLATDS 0 # initialized by BUILTIN_Init() 455 equate __FLATDS 0 # initialized by BUILTIN_Init()
456 pascal DefResourceHandler(word word word) NE_DefResourceHandler 456 pascal DefResourceHandler(word word word) NE_DefResourceHandler
...@@ -455,15 +455,14 @@ file krnl386.exe ...@@ -455,15 +455,14 @@ file krnl386.exe
#541 stub KERNEL_541 #541 stub KERNEL_541
542 stub KERNEL_542 542 stub KERNEL_542
543 stub KERNEL_543 543 stub KERNEL_543
560 stub KERNEL_560 # (thunklet) # InitThunkletHandler 560 pascal SetThunkletCallbackGlue(long segptr) SetThunkletCallbackGlue
561 stub KERNEL_561 # (thunklet) # AllocLSThunklet 561 pascal AllocLSThunkletCallback(segptr long) AllocLSThunkletCallback
562 stub KERNEL_562 # (thunklet) # AllocSLThunklet 562 pascal AllocSLThunkletCallback(long long) AllocSLThunkletCallback
563 stub KERNEL_563 # (thunklet) # FindSLThunklet 563 pascal FindLSThunkletCallback(segptr long) FindLSThunkletCallback
564 stub KERNEL_564 # (thunklet) # FindLSThunklet 564 pascal FindSLThunkletCallback(long long) FindSLThunkletCallback
565 stub KERNEL_565 # (thunklet) # AllocLSThunklet_Special 566 stub KERNEL_566 # (thunklet) FIXME!!!
566 stub KERNEL_566 # (thunklet) # AllocSLThunklet_Special 567 pascal AllocLSThunkletCallbackEx(segptr long word) AllocLSThunkletCallbackEx
567 stub KERNEL_567 # (thunklet) # AllocLSThunkletEx 568 pascal AllocSLThunkletCallbackEx(long long word) AllocSLThunkletCallbackEx
568 stub KERNEL_568 # (thunklet) # AllocSLThunkletEx
# 600-653 are Win95 only # 600-653 are Win95 only
...@@ -472,25 +471,25 @@ file krnl386.exe ...@@ -472,25 +471,25 @@ file krnl386.exe
601 stub KERNEL_601 # FreeSelector (?) 601 stub KERNEL_601 # FreeSelector (?)
602 stub GetCurrentHInstanceDS 602 stub GetCurrentHInstanceDS
603 stub KERNEL_603 # OutputDebugString (?) 603 stub KERNEL_603 # OutputDebugString (?)
604 stub KERNEL_604 # (cbclient) # Thunk_CBClient 604 register CBClientGlueSL() CBClientGlueSL
605 stub KERNEL_605 # (thunklet) # AllocSLThunklet 605 pascal AllocSLThunkletCallback(long long) AllocSLThunkletCallback
606 stub KERNEL_606 # (thunklet) # AllocLSThunklet 606 pascal AllocLSThunkletCallback(segptr long) AllocLSThunkletCallback
607 pascal KERNEL_607(long long long) _KERNEL_607 # AllocLSThunklet_Systhunk 607 pascal AllocLSThunkletSysthunk(segptr long long) AllocLSThunkletSysthunk
608 pascal KERNEL_608(long long long) _KERNEL_608 # AllocSLThunklet_Systhunk 608 pascal AllocSLThunkletSysthunk(long segptr long) AllocSLThunkletSysthunk
609 stub KERNEL_609 # (thunklet) # FindSLThunklet 609 pascal FindLSThunkletCallback(segptr long) FindLSThunkletCallback
610 stub KERNEL_610 # (thunklet) # FindLSThunklet 610 pascal FindSLThunkletCallback(long long) FindSLThunkletCallback
611 pascal16 KERNEL_611(long long) _KERNEL_611 # FreeThunklet 611 return FreeThunklet 8 0
612 pascal16 KERNEL_612(ptr) _KERNEL_612 # IsSLThunklet 612 pascal16 IsSLThunklet(ptr) IsSLThunklet
613 stub KERNEL_613 # (cbclient) 613 stub KERNEL_613 # (cbclient)
614 stub KERNEL_614 # (cbclient) 614 stub KERNEL_614 # (cbclient)
615 stub KERNEL_615 # (cbclient) 615 stub KERNEL_615 # (cbclient)
616 stub KERNEL_616 # (cbclient) 616 stub KERNEL_616 # (cbclient)
617 stub KERNEL_617 # (cbclient) 617 stub KERNEL_617 # (cbclient)
618 stub KERNEL_618 # (cbclient) 618 stub KERNEL_618 # (cbclient)
619 pascal16 RegisterCBClient(word long long) RegisterCBClient 619 pascal16 RegisterCBClient(word ptr long) RegisterCBClient
620 stub KERNEL_620 # (cbclient) 620 register CBClientThunkSL() CBClientThunkSL
621 stub KERNEL_621 # (cbclient) 621 stub KERNEL_621 # (cbclient)
622 stub UnRegisterCBClient 622 pascal16 UnRegisterCBClient(word ptr long) UnRegisterCBClient
623 pascal16 InitCBClient(long) InitCBClient 623 pascal16 InitCBClient(long) InitCBClient
624 pascal SetFastQueue(long long) SetFastQueue 624 pascal SetFastQueue(long long) SetFastQueue
625 pascal GetFastQueue() GetFastQueue 625 pascal GetFastQueue() GetFastQueue
......
...@@ -29,9 +29,11 @@ BOOL32 RELAY_Init(void) ...@@ -29,9 +29,11 @@ BOOL32 RELAY_Init(void)
extern void CALLTO16_Start(), CALLTO16_End(); extern void CALLTO16_Start(), CALLTO16_End();
extern void CALLTO16_Ret_word(), CALLTO16_Ret_long(); extern void CALLTO16_Ret_word(), CALLTO16_Ret_long();
extern void CALLTO16_Ret_eax(); extern void CALLTO16_Ret_eax();
extern void CALL32_CBClient_Ret();
extern DWORD CALLTO16_RetAddr_word; extern DWORD CALLTO16_RetAddr_word;
extern DWORD CALLTO16_RetAddr_long; extern DWORD CALLTO16_RetAddr_long;
extern DWORD CALLTO16_RetAddr_eax; extern DWORD CALLTO16_RetAddr_eax;
extern DWORD CALL32_CBClient_RetAddr;
codesel = GLOBAL_CreateBlock( GMEM_FIXED, (void *)CALLTO16_Start, codesel = GLOBAL_CreateBlock( GMEM_FIXED, (void *)CALLTO16_Start,
(int)CALLTO16_End - (int)CALLTO16_Start, (int)CALLTO16_End - (int)CALLTO16_Start,
...@@ -46,6 +48,8 @@ BOOL32 RELAY_Init(void) ...@@ -46,6 +48,8 @@ BOOL32 RELAY_Init(void)
codesel ); codesel );
CALLTO16_RetAddr_eax =MAKELONG( (int)CALLTO16_Ret_eax -(int)CALLTO16_Start, CALLTO16_RetAddr_eax =MAKELONG( (int)CALLTO16_Ret_eax -(int)CALLTO16_Start,
codesel ); codesel );
CALL32_CBClient_RetAddr =
MAKELONG( (int)CALL32_CBClient_Ret -(int)CALLTO16_Start, codesel );
/* Create built-in modules */ /* Create built-in modules */
if (!BUILTIN_Init()) return FALSE; if (!BUILTIN_Init()) return FALSE;
......
...@@ -2131,6 +2131,156 @@ static void BuildRet16Func( FILE *outfile ) ...@@ -2131,6 +2131,156 @@ static void BuildRet16Func( FILE *outfile )
fprintf( outfile, "\t.text\n" ); fprintf( outfile, "\t.text\n" );
} }
/*******************************************************************
* BuildCallTo32CBClient
*
* Call a CBClient relay stub from 32-bit code (KERNEL.620).
*
* Since the relay stub is itself 32-bit, this should not be a problem;
* unfortunately, the relay stubs are expected to switch back to a
* 16-bit stack (and 16-bit code) after completion :-(
*
* This would conflict with our 16- vs. 32-bit stack handling, so
* we simply switch *back* to our 32-bit stack before returning to
* the caller ...
*
* The CBClient relay stub expects to be called with:
* - ebp pointing to the 16-bit stack at ss:bp
* - ebx pointing to a buffer containing the saved 16-bit ss:sp
*
* After completion, the stub will load ss:sp from the buffer at ebx
* and perform a far return to 16-bit code.
*
* To trick the relay stub into returning to us, we push a 16-bit
* cs:ip pair pointing to out return entry point onto the 16-bit stack,
* followed by a ss:sp pair pointing to *that* cs:ip pair.
* Our return stub thus called will then reload the 32-bit ss:esp and
* return to 32-bit code (by using and ss:esp value that we have also
* pushed onto the 16-bit stack before and a cs:eip values found at
* that position on the 32-bit stack). The layout of our
* temporary area used on the 16-bit stack is thus as follows:
*
* (ebx+12) 32-bit ss (flat)
* (ebx+8) 32-bit sp (32-bit stack pointer)
* (ebx+6) 16-bit cs (this segment)
* (ebx+4) 16-bit ip ('16-bit' return entry point)
* (ebx+2) 16-bit ss (16-bit stack segment)
* (ebx+0) 16-bit sp (points to ebx+4)
*
* The stack layout of this function:
* (ebp+12) arg ebp value to be set for relay stub
* (ebp+8) func CBClient relay stub address
* (ebp+4) ret addr
* (ebp) ebp
*/
static void BuildCallTo32CBClient( FILE *outfile )
{
/* Function header */
fprintf( outfile, "\n\t.align 4\n" );
#ifdef USE_STABS
fprintf( outfile, ".stabs \"CALL32_CBClient:F1\",36,0,0," PREFIX "CALL32_CBClient\n" );
#endif
fprintf( outfile, "\t.globl " PREFIX "CALL32_CBClient\n" );
fprintf( outfile, PREFIX "CALL32_CBClient:\n" );
/* Entry code */
fprintf( outfile, "\tpushl %%ebp\n" );
fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
fprintf( outfile, "\tpushl %%edi\n" );
fprintf( outfile, "\tpushl %%esi\n" );
fprintf( outfile, "\tpushl %%ebx\n" );
/* Get the 16-bit stack */
fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%ebx\n", STACKOFFSET);
/* Convert it to a flat address */
fprintf( outfile, "\tshldl $16,%%ebx,%%eax\n" );
fprintf( outfile, "\tandl $0xfff8,%%eax\n" );
fprintf( outfile, "\tmovl " PREFIX "ldt_copy(%%eax),%%esi\n" );
fprintf( outfile, "\tmovw %%bx,%%ax\n" );
fprintf( outfile, "\taddl %%eax,%%esi\n" );
/* Allocate temporary area (simulate STACK16_PUSH) */
fprintf( outfile, "\tpushf\n" );
fprintf( outfile, "\tcld\n" );
fprintf( outfile, "\tleal -16(%%esi), %%edi\n" );
fprintf( outfile, "\tmovl $%d, %%ecx\n", sizeof(STACK16FRAME) );
fprintf( outfile, "\trep\n\tmovsb\n" );
fprintf( outfile, "\tpopf\n" );
fprintf( outfile, "\t.byte 0x64\n\tsubw $16,(%d)\n", STACKOFFSET );
fprintf( outfile, "\tpushl %%edi\n" ); /* remember address */
/* Set up temporary area */
fprintf( outfile, "\taddl $%d, %%ebx\n", sizeof(STACK16FRAME)-16+4 );
fprintf( outfile, "\tmovl %%ebx, (%%edi)\n" );
fprintf( outfile, "\tmovl " PREFIX "CALL32_CBClient_RetAddr, %%eax\n" );
fprintf( outfile, "\tmovl %%eax, 4(%%edi)\n" );
fprintf( outfile, "\tleal -8(%%esp), %%eax\n" );
fprintf( outfile, "\tmovl %%eax, 8(%%edi)\n" );
fprintf( outfile, "\tmovl %%ss, %%ax\n" );
fprintf( outfile, "\tandl $0x0000ffff, %%eax\n" );
fprintf( outfile, "\tmovl %%eax, 12(%%edi)\n" );
/* Setup registers and call CBClient relay stub (simulating a far call) */
fprintf( outfile, "\tmovl %%edi, %%ebx\n" );
fprintf( outfile, "\tmovl 8(%%ebp), %%eax\n" );
fprintf( outfile, "\tmovl 12(%%ebp), %%ebp\n" );
fprintf( outfile, "\tpushl %%cs\n" );
fprintf( outfile, "\tcall *%%eax\n" );
/* Cleanup temporary area (simulate STACK16_POP) */
fprintf( outfile, "\tpop %%esi\n" );
fprintf( outfile, "\tpushf\n" );
fprintf( outfile, "\tstd\n" );
fprintf( outfile, "\tdec %%esi\n" );
fprintf( outfile, "\tleal 16(%%esi), %%edi\n" );
fprintf( outfile, "\tmovl $%d, %%ecx\n", sizeof(STACK16FRAME) );
fprintf( outfile, "\trep\n\tmovsb\n" );
fprintf( outfile, "\tpopf\n" );
fprintf( outfile, "\t.byte 0x64\n\taddw $16,(%d)\n", STACKOFFSET );
/* Restore registers and return */
fprintf( outfile, "\tpopl %%ebx\n" );
fprintf( outfile, "\tpopl %%esi\n" );
fprintf( outfile, "\tpopl %%edi\n" );
fprintf( outfile, "\tpopl %%ebp\n" );
fprintf( outfile, "\tret\n" );
/* '16-bit' return stub */
fprintf( outfile, "\t.globl " PREFIX "CALL32_CBClient_Ret\n" );
fprintf( outfile, PREFIX "CALL32_CBClient_Ret:\n" );
fprintf( outfile, "\tmovzwl %%sp, %%ebx\n" );
fprintf( outfile, "\tlssl %%ss:(%%ebx), %%esp\n" );
fprintf( outfile, "\tlret\n" );
/* Declare the return address variable */
fprintf( outfile, "\t.data\n" );
fprintf( outfile, "\t.globl " PREFIX "CALL32_CBClient_RetAddr\n" );
fprintf( outfile, PREFIX "CALL32_CBClient_RetAddr:\t.long 0\n" );
fprintf( outfile, "\t.text\n" );
}
/******************************************************************* /*******************************************************************
* BuildCallTo32LargeStack * BuildCallTo32LargeStack
...@@ -2455,6 +2605,14 @@ static int BuildCallTo16( FILE *outfile, char * outname, int argc, char *argv[] ...@@ -2455,6 +2605,14 @@ static int BuildCallTo16( FILE *outfile, char * outname, int argc, char *argv[]
BuildRet16Func( outfile ); BuildRet16Func( outfile );
/* Output the CBClient callback function
* (while this does not really 'call to 16-bit' code, it is placed
* here so that its 16-bit return stub is defined within the CALLTO16
* 16-bit segment)
*/
BuildCallTo32CBClient( outfile );
fprintf( outfile, "\t.globl " PREFIX "CALLTO16_End\n" ); fprintf( outfile, "\t.globl " PREFIX "CALLTO16_End\n" );
fprintf( outfile, PREFIX "CALLTO16_End:\n" ); fprintf( outfile, PREFIX "CALLTO16_End:\n" );
......
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