>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(a)lattica.com>
Lattica, Inc.