From a cursory look at the problem, it seems we can turn things
upside down. Right now LOCAL_*() functions (Wine specific) are equivalent to the Local*16() functions (Windows exports), with the exception that they take a selector as first argument (which makes them more general). As a result, Local*16() functions are implemented on top of the LOCAL_*() ones.
This is only half of the story. In fact, the Local*16() functions do take the segment as input, but in a more awkward manner: as the value of the DS register. So we can actually implement the LOCAL_*() functions on top of the Local*16() ones by messing with the DS register. Doing so would hopefully get rid of the LOCAL_*() exports from kernel.
I've taken a stab (prototype level) at the LOCAL_Alloc() function (patch included below). Would such an approach be acceptable?
Index: include/local.h =================================================================== RCS file: /var/cvs/wine/include/local.h,v retrieving revision 1.6 diff -u -p -r1.6 local.h --- include/local.h 28 Aug 2003 21:43:35 -0000 1.6 +++ include/local.h 10 May 2005 18:20:03 -0000 @@ -23,12 +23,22 @@
#include <windef.h> #include <wine/windef16.h> +#include <stackframe.h>
/* These function are equivalent to the Local* API functions, */ /* excepted that they need DS as the first parameter. This */ /* allows managing several heaps from the emulation library. */ +static inline HLOCAL16 LOCAL_Alloc( HANDLE16 ds, UINT16 flags, WORD size ) +{ + HANDLE16 oldDS = CURRENT_DS; + HLOCAL16 ret; + + CURRENT_DS = ds; + ret = LocalAlloc16 (flags, size); + CURRENT_DS = oldDS; + return ret; +}
-extern HLOCAL16 LOCAL_Alloc( HANDLE16 ds, UINT16 flags, WORD size ); extern HLOCAL16 LOCAL_ReAlloc( HANDLE16 ds, HLOCAL16 handle, WORD size, UINT16 flags ); extern HLOCAL16 LOCAL_Free( HANDLE16 ds, HLOCAL16 handle ); Index: dlls/kernel/kernel32.spec =================================================================== RCS file: /var/cvs/wine/dlls/kernel/kernel32.spec,v retrieving revision 1.148 diff -u -p -r1.148 kernel32.spec --- dlls/kernel/kernel32.spec 10 May 2005 15:22:10 -0000 1.148 +++ dlls/kernel/kernel32.spec 10 May 2005 18:22:10 -0000 @@ -1167,7 +1167,6 @@ # Wine dll separation hacks, these will go away, don't use them # @ cdecl DOSMEM_AllocSelector(long) -@ cdecl LOCAL_Alloc(long long long) @ cdecl LOCAL_Compact(long long long) @ cdecl LOCAL_CountFree(long) @ cdecl LOCAL_Free(long long) Index: dlls/kernel/local16.c =================================================================== RCS file: /var/cvs/wine/dlls/kernel/local16.c,v retrieving revision 1.10 diff -u -p -r1.10 local16.c --- dlls/kernel/local16.c 24 Mar 2005 21:01:38 -0000 1.10 +++ dlls/kernel/local16.c 10 May 2005 17:56:15 -0000 @@ -1150,15 +1150,13 @@ HLOCAL16 LOCAL_Free( HANDLE16 ds, HLOCAL
/*********************************************************************** - * LOCAL_Alloc - * - * Implementation of LocalAlloc(). - * + * LocalAlloc (KERNEL.5) */ -HLOCAL16 LOCAL_Alloc( HANDLE16 ds, WORD flags, WORD size ) +HLOCAL16 WINAPI LocalAlloc16( UINT16 flags, WORD size ) { + HANDLE16 ds = CURRENT_DS; + HLOCAL16 handle = 0; char *ptr; - HLOCAL16 handle;
TRACE("%04x %d ds=%04x\n", flags, size, ds );
@@ -1171,7 +1169,7 @@ HLOCAL16 LOCAL_Alloc( HANDLE16 ds, WORD if(size) { if (!(hmem = LOCAL_GetBlock( ds, size + MOVEABLE_PREFIX, flags ))) - return 0; + goto exit; } else /* We just need to allocate a discarded handle */ hmem = 0; @@ -1180,7 +1178,7 @@ HLOCAL16 LOCAL_Alloc( HANDLE16 ds, WORD WARN("Couldn't get handle.\n"); if(hmem) LOCAL_FreeArena( ds, ARENA_HEADER(hmem) ); - return 0; + goto exit; } ptr = MapSL( MAKESEGPTR( ds, 0 ) ); plhe = (LOCALHANDLEENTRY *)(ptr + handle); @@ -1199,10 +1197,11 @@ HLOCAL16 LOCAL_Alloc( HANDLE16 ds, WORD } else /* FIXED */ { - if(!size) - return 0; - handle = LOCAL_GetBlock( ds, size, flags ); + if(size) handle = LOCAL_GetBlock( ds, size, flags ); } + +exit: + CURRENT_STACK16->ecx = handle; /* must be returned in cx too */ return handle; }
@@ -1595,17 +1594,6 @@ HLOCAL16 LOCAL_Handle( HANDLE16 ds, WORD
/*********************************************************************** - * LocalAlloc (KERNEL.5) - */ -HLOCAL16 WINAPI LocalAlloc16( UINT16 flags, WORD size ) -{ - HLOCAL16 ret = LOCAL_Alloc( CURRENT_DS, flags, size ); - CURRENT_STACK16->ecx = ret; /* must be returned in cx too */ - return ret; -} - - -/*********************************************************************** * LocalReAlloc (KERNEL.6) */ HLOCAL16 WINAPI LocalReAlloc16( HLOCAL16 handle, WORD size, UINT16 flags )
Dimi Paun dimi@lattica.com writes:
I've taken a stab (prototype level) at the LOCAL_Alloc() function (patch included below). Would such an approach be acceptable?
Yes, that should be OK.