Use the HEAP_WINE_SEGPTR flag to specify allocations on the segptr heap.

Added a hack in MapLS to recognize such allocations and use the heap
selector in this case.
This commit is contained in:
Alexandre Julliard 2000-11-30 01:19:51 +00:00
parent e8e7d1eca5
commit 71d68bbae0
10 changed files with 90 additions and 120 deletions

View File

@ -156,7 +156,7 @@ static UTINFO *UTAlloc( HMODULE hModule, HMODULE16 hModule16,
if ( !UTGlue16_Segptr ) return NULL; if ( !UTGlue16_Segptr ) return NULL;
} }
ut = HeapAlloc( SegptrHeap, HEAP_ZERO_MEMORY, sizeof(UTINFO) ); ut = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_WINE_SEGPTR, sizeof(UTINFO) );
if ( !ut ) return NULL; if ( !ut ) return NULL;
ut->hModule = hModule; ut->hModule = hModule;
@ -196,7 +196,7 @@ static void UTFree( UTINFO *ut )
break; break;
} }
HeapFree( SegptrHeap, 0, ut ); HeapFree( GetProcessHeap(), HEAP_WINE_SEGPTR, ut );
} }
/**************************************************************************** /****************************************************************************

View File

@ -4,7 +4,6 @@ SRCDIR = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
MODULE = msvfw32 MODULE = msvfw32
ALTNAMES = msvideo ALTNAMES = msvideo
IMPORTS = ntdll
LDDLLFLAGS = @LDDLLFLAGS@ LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o SYMBOLFILE = $(MODULE).tmp.o

View File

@ -4,7 +4,6 @@ SRCDIR = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
MODULE = oleaut32 MODULE = oleaut32
ALTNAMES = ole2disp typelib ALTNAMES = ole2disp typelib
IMPORTS = ntdll
LDDLLFLAGS = @LDDLLFLAGS@ LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o SYMBOLFILE = $(MODULE).tmp.o

View File

@ -98,7 +98,7 @@ HFONT WIN16DRV_FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font)
&physDev->lf, 0, 0); &physDev->lf, 0, 0);
if( physDev->FontInfo && if( physDev->FontInfo &&
HeapSize( SegptrHeap, 0, physDev->FontInfo ) < nSize ) HeapSize( GetProcessHeap(), HEAP_WINE_SEGPTR, physDev->FontInfo ) < nSize )
{ {
SEGPTR_FREE( physDev->FontInfo ); SEGPTR_FREE( physDev->FontInfo );
physDev->FontInfo = NULL; physDev->FontInfo = NULL;

View File

@ -123,7 +123,7 @@ void THUNK_Free( FARPROC thunk )
|| t->magic != CALLTO16_THUNK_MAGIC ) || t->magic != CALLTO16_THUNK_MAGIC )
return; return;
if (HEAP_IsInsideHeap( GetProcessHeap(), 0, t )) if (HeapValidate( GetProcessHeap(), 0, t ))
{ {
THUNK **prev = &firstThunk; THUNK **prev = &firstThunk;
while (*prev && (*prev != t)) prev = &(*prev)->next; while (*prev && (*prev != t)) prev = &(*prev)->next;

View File

@ -15,29 +15,23 @@
#include "wine/windef16.h" /* for SEGPTR */ #include "wine/windef16.h" /* for SEGPTR */
extern HANDLE SystemHeap; extern HANDLE SystemHeap;
extern HANDLE SegptrHeap;
extern int HEAP_IsInsideHeap( HANDLE heap, DWORD flags, LPCVOID ptr );
extern SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr ); extern SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr );
extern BOOL HEAP_CreateSystemHeap(void); extern BOOL HEAP_CreateSystemHeap(void);
/* SEGPTR helper macros */ /* SEGPTR helper macros */
#define SEGPTR_ALLOC(size) \ #define SEGPTR_ALLOC(size) \
(HeapAlloc( SegptrHeap, 0, (size) )) (HeapAlloc( GetProcessHeap(), HEAP_WINE_SEGPTR, (size) ))
#define SEGPTR_NEW(type) \ #define SEGPTR_NEW(type) \
((type *)HeapAlloc( SegptrHeap, 0, sizeof(type) )) ((type *)HeapAlloc( GetProcessHeap(), HEAP_WINE_SEGPTR, sizeof(type) ))
#define SEGPTR_STRDUP(str) \ #define SEGPTR_STRDUP(str) \
(HIWORD(str) ? HEAP_strdupA( SegptrHeap, 0, (str) ) : (LPSTR)(str)) (HIWORD(str) ? HEAP_strdupA( GetProcessHeap(), HEAP_WINE_SEGPTR, (str) ) : (LPSTR)(str))
#define SEGPTR_STRDUP_WtoA(str) \ #define SEGPTR_STRDUP_WtoA(str) \
(HIWORD(str) ? HEAP_strdupWtoA( SegptrHeap, 0, (str) ) : (LPSTR)(str)) (HIWORD(str) ? HEAP_strdupWtoA( GetProcessHeap(), HEAP_WINE_SEGPTR, (str) ) : (LPSTR)(str))
/* define an inline function, a macro won't do */
static inline SEGPTR WINE_UNUSED SEGPTR_Get(LPCVOID ptr) {
return (HIWORD(ptr) ? HEAP_GetSegptr( SegptrHeap, 0, ptr ) : (SEGPTR)ptr);
}
#define SEGPTR_GET(ptr) SEGPTR_Get(ptr)
#define SEGPTR_FREE(ptr) \ #define SEGPTR_FREE(ptr) \
(HIWORD(ptr) ? HeapFree( SegptrHeap, 0, (ptr) ) : 0) (HIWORD(ptr) ? HeapFree( GetProcessHeap(), HEAP_WINE_SEGPTR, (ptr) ) : 0)
#define SEGPTR_GET(ptr) MapLS(ptr)
/* strdup macros */ /* strdup macros */

View File

@ -1883,7 +1883,7 @@ typedef struct tagSYSLEVEL
void WINAPI DisposeLZ32Handle(HANDLE); void WINAPI DisposeLZ32Handle(HANDLE);
HANDLE WINAPI DosFileHandleToWin32Handle(HFILE); HANDLE WINAPI DosFileHandleToWin32Handle(HFILE);
VOID WINAPI GetpWin16Lock(SYSLEVEL**); VOID WINAPI GetpWin16Lock(SYSLEVEL**);
DWORD WINAPI MapLS(LPVOID); DWORD WINAPI MapLS(LPCVOID);
LPVOID WINAPI MapSL(DWORD); LPVOID WINAPI MapSL(DWORD);
VOID WINAPI ReleaseThunkLock(DWORD*); VOID WINAPI ReleaseThunkLock(DWORD*);
VOID WINAPI RestoreThunkLock(DWORD); VOID WINAPI RestoreThunkLock(DWORD);

View File

@ -105,17 +105,17 @@ typedef struct tagHEAP
#define COMMIT_MASK 0xffff /* bitmask for commit/decommit granularity */ #define COMMIT_MASK 0xffff /* bitmask for commit/decommit granularity */
HANDLE SystemHeap = 0; HANDLE SystemHeap = 0;
HANDLE SegptrHeap = 0;
SYSTEM_HEAP_DESCR *SystemHeapDescr = 0; SYSTEM_HEAP_DESCR *SystemHeapDescr = 0;
static HEAP *processHeap; /* main process heap */ static HEAP *processHeap; /* main process heap */
static HEAP *segptrHeap; /* main segptr heap */
static HEAP *firstHeap; /* head of secondary heaps list */ static HEAP *firstHeap; /* head of secondary heaps list */
/* address where we try to map the system heap */ /* address where we try to map the system heap */
#define SYSTEM_HEAP_BASE ((void*)0x65430000) #define SYSTEM_HEAP_BASE ((void*)0x65430000)
static BOOL HEAP_IsRealArena( HANDLE heap, DWORD flags, LPCVOID block, BOOL quiet ); static BOOL HEAP_IsRealArena( HEAP *heapPtr, DWORD flags, LPCVOID block, BOOL quiet );
#ifdef __GNUC__ #ifdef __GNUC__
#define GET_EIP() (__builtin_return_address(0)) #define GET_EIP() (__builtin_return_address(0))
@ -220,7 +220,7 @@ static HEAP *HEAP_GetPtr(
SetLastError( ERROR_INVALID_HANDLE ); SetLastError( ERROR_INVALID_HANDLE );
return NULL; return NULL;
} }
if (TRACE_ON(heap) && !HEAP_IsRealArena( heap, 0, NULL, NOISY )) if (TRACE_ON(heap) && !HEAP_IsRealArena( heapPtr, 0, NULL, NOISY ))
{ {
HEAP_Dump( heapPtr ); HEAP_Dump( heapPtr );
assert( FALSE ); assert( FALSE );
@ -834,39 +834,6 @@ static BOOL HEAP_ValidateInUseArena( SUBHEAP *subheap, ARENA_INUSE *pArena, BOOL
} }
/***********************************************************************
* HEAP_IsInsideHeap
* Checks whether the pointer points to a block inside a given heap.
*
* NOTES
* Should this return BOOL32?
*
* RETURNS
* !0: Success
* 0: Failure
*/
int HEAP_IsInsideHeap(
HANDLE heap, /* [in] Heap */
DWORD flags, /* [in] Flags */
LPCVOID ptr /* [in] Pointer */
) {
HEAP *heapPtr = HEAP_GetPtr( heap );
SUBHEAP *subheap;
int ret;
/* Validate the parameters */
if (!heapPtr) return 0;
flags |= heapPtr->flags;
if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection );
ret = (((subheap = HEAP_FindSubHeap( heapPtr, ptr )) != NULL) &&
(((char *)ptr >= (char *)subheap + subheap->headerSize
+ sizeof(ARENA_INUSE))));
if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection );
return ret;
}
/*********************************************************************** /***********************************************************************
* HEAP_GetSegptr * HEAP_GetSegptr
* *
@ -877,7 +844,7 @@ SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr )
{ {
HEAP *heapPtr = HEAP_GetPtr( heap ); HEAP *heapPtr = HEAP_GetPtr( heap );
SUBHEAP *subheap; SUBHEAP *subheap;
SEGPTR ret; SEGPTR ret = 0;
/* Validate the parameters */ /* Validate the parameters */
@ -893,21 +860,60 @@ SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr )
/* Get the subheap */ /* Get the subheap */
if (!(subheap = HEAP_FindSubHeap( heapPtr, ptr ))) if ((subheap = HEAP_FindSubHeap( heapPtr, ptr )))
{ ret = PTR_SEG_OFF_TO_SEGPTR(subheap->selector, (char *)ptr - (char *)subheap);
ERR("%p is not inside heap %08x\n",
ptr, heap );
if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection );
return 0;
}
/* Build the SEGPTR */
ret = PTR_SEG_OFF_TO_SEGPTR(subheap->selector, (DWORD)ptr-(DWORD)subheap);
if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection ); if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection );
return ret; return ret;
} }
/***********************************************************************
* MapLS (KERNEL32.522)
*
* Maps linear pointer to segmented.
*/
SEGPTR WINAPI MapLS( LPCVOID ptr )
{
SUBHEAP *subheap;
SEGPTR ret = 0;
if (!HIWORD(ptr)) return (SEGPTR)ptr;
/* check if the pointer is inside the segptr heap */
EnterCriticalSection( &segptrHeap->critSection );
if ((subheap = HEAP_FindSubHeap( segptrHeap, ptr )))
ret = PTR_SEG_OFF_TO_SEGPTR( subheap->selector, (char *)ptr - (char *)subheap );
LeaveCriticalSection( &segptrHeap->critSection );
/* otherwise, allocate a brand-new selector */
if (!ret)
{
WORD sel = SELECTOR_AllocBlock( ptr, 0x10000, WINE_LDT_FLAGS_DATA );
ret = PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
}
return ret;
}
/***********************************************************************
* UnMapLS (KERNEL32.700)
*
* Free mapped selector.
*/
void WINAPI UnMapLS( SEGPTR sptr )
{
SUBHEAP *subheap;
if (!SELECTOROF(sptr)) return;
/* check if ptr is inside segptr heap */
EnterCriticalSection( &segptrHeap->critSection );
subheap = HEAP_FindSubHeap( segptrHeap, PTR_SEG_TO_LIN(sptr) );
if (subheap->selector != SELECTOROF(sptr)) subheap = NULL;
LeaveCriticalSection( &segptrHeap->critSection );
/* if not inside heap, free the selector */
if (!subheap) FreeSelector16( SELECTOROF(sptr) );
}
/*********************************************************************** /***********************************************************************
* HEAP_IsRealArena [Internal] * HEAP_IsRealArena [Internal]
* Validates a block is a valid arena. * Validates a block is a valid arena.
@ -916,20 +922,18 @@ SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr )
* TRUE: Success * TRUE: Success
* FALSE: Failure * FALSE: Failure
*/ */
static BOOL HEAP_IsRealArena( static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
HANDLE heap, /* [in] Handle to the heap */
DWORD flags, /* [in] Bit flags that control access during operation */ DWORD flags, /* [in] Bit flags that control access during operation */
LPCVOID block, /* [in] Optional pointer to memory block to validate */ LPCVOID block, /* [in] Optional pointer to memory block to validate */
BOOL quiet /* [in] Flag - if true, HEAP_ValidateInUseArena BOOL quiet ) /* [in] Flag - if true, HEAP_ValidateInUseArena
* does not complain */ * does not complain */
) { {
SUBHEAP *subheap; SUBHEAP *subheap;
HEAP *heapPtr = (HEAP *)(heap);
BOOL ret = TRUE; BOOL ret = TRUE;
if (!heapPtr || (heapPtr->magic != HEAP_MAGIC)) if (!heapPtr || (heapPtr->magic != HEAP_MAGIC))
{ {
ERR("Invalid heap %08x!\n", heap ); ERR("Invalid heap %p!\n", heapPtr );
return FALSE; return FALSE;
} }
@ -943,18 +947,14 @@ static BOOL HEAP_IsRealArena(
{ {
/* Only check this single memory block */ /* Only check this single memory block */
/* The following code is really HEAP_IsInsideHeap *
* with serialization already done. */
if (!(subheap = HEAP_FindSubHeap( heapPtr, block )) || if (!(subheap = HEAP_FindSubHeap( heapPtr, block )) ||
((char *)block < (char *)subheap + subheap->headerSize ((char *)block < (char *)subheap + subheap->headerSize
+ sizeof(ARENA_INUSE))) + sizeof(ARENA_INUSE)))
{ {
if (quiet == NOISY) if (quiet == NOISY)
ERR("Heap %08lx: block %08lx is not inside heap\n", ERR("Heap %p: block %p is not inside heap\n", heapPtr, block );
(DWORD)heap, (DWORD)block );
else if (WARN_ON(heap)) else if (WARN_ON(heap))
WARN("Heap %08lx: block %08lx is not inside heap\n", WARN("Heap %p: block %p is not inside heap\n", heapPtr, block );
(DWORD)heap, (DWORD)block );
ret = FALSE; ret = FALSE;
} else } else
ret = HEAP_ValidateInUseArena( subheap, (ARENA_INUSE *)block - 1, quiet ); ret = HEAP_ValidateInUseArena( subheap, (ARENA_INUSE *)block - 1, quiet );
@ -1038,9 +1038,16 @@ HANDLE WINAPI HeapCreate(
} }
else /* assume the first heap we create is the process main heap */ else /* assume the first heap we create is the process main heap */
{ {
SUBHEAP *segptr;
processHeap = subheap->heap; processHeap = subheap->heap;
/* create the SEGPTR heap */
if (!(segptr = HEAP_CreateSubHeap( NULL, flags|HEAP_WINE_SEGPTR|HEAP_GROWABLE, 0, 0 )))
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
segptrHeap = segptr->heap;
} }
return (HANDLE)subheap; return (HANDLE)subheap;
} }
@ -1109,6 +1116,7 @@ LPVOID WINAPI HeapAlloc(
/* Validate the parameters */ /* Validate the parameters */
if ((flags & HEAP_WINE_SEGPTR) && size < 0x10000) heapPtr = segptrHeap;
if (!heapPtr) return NULL; if (!heapPtr) return NULL;
flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY; flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY;
flags |= heapPtr->flags; flags |= heapPtr->flags;
@ -1178,18 +1186,14 @@ BOOL WINAPI HeapFree(
/* Validate the parameters */ /* Validate the parameters */
if (!ptr) return TRUE; /* freeing a NULL ptr is doesn't indicate an error in Win2k */
if (flags & HEAP_WINE_SEGPTR) heapPtr = segptrHeap;
if (!heapPtr) return FALSE; if (!heapPtr) return FALSE;
if (!ptr) /* Freeing a NULL ptr is doesn't indicate an error in Win2k */
{
WARN("(%08x,%08lx,%08lx): asked to free NULL\n",
heap, flags, (DWORD)ptr );
return TRUE;
}
flags &= HEAP_NO_SERIALIZE; flags &= HEAP_NO_SERIALIZE;
flags |= heapPtr->flags; flags |= heapPtr->flags;
if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection ); if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection );
if (!HEAP_IsRealArena( heap, HEAP_NO_SERIALIZE, ptr, QUIET )) if (!HEAP_IsRealArena( heapPtr, HEAP_NO_SERIALIZE, ptr, QUIET ))
{ {
if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection ); if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection );
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
@ -1230,6 +1234,7 @@ LPVOID WINAPI HeapReAlloc(
SUBHEAP *subheap; SUBHEAP *subheap;
if (!ptr) return HeapAlloc( heap, flags, size ); /* FIXME: correct? */ if (!ptr) return HeapAlloc( heap, flags, size ); /* FIXME: correct? */
if ((flags & HEAP_WINE_SEGPTR) && size < 0x10000) heapPtr = segptrHeap;
if (!(heapPtr = HEAP_GetPtr( heap ))) return FALSE; if (!(heapPtr = HEAP_GetPtr( heap ))) return FALSE;
/* Validate the parameters */ /* Validate the parameters */
@ -1241,7 +1246,7 @@ LPVOID WINAPI HeapReAlloc(
if (size < HEAP_MIN_BLOCK_SIZE) size = HEAP_MIN_BLOCK_SIZE; if (size < HEAP_MIN_BLOCK_SIZE) size = HEAP_MIN_BLOCK_SIZE;
if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection ); if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection );
if (!HEAP_IsRealArena( heap, HEAP_NO_SERIALIZE, ptr, QUIET )) if (!HEAP_IsRealArena( heapPtr, HEAP_NO_SERIALIZE, ptr, QUIET ))
{ {
if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection ); if (!(flags & HEAP_NO_SERIALIZE)) LeaveCriticalSection( &heapPtr->critSection );
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
@ -1395,11 +1400,12 @@ DWORD WINAPI HeapSize(
DWORD ret; DWORD ret;
HEAP *heapPtr = HEAP_GetPtr( heap ); HEAP *heapPtr = HEAP_GetPtr( heap );
if (flags & HEAP_WINE_SEGPTR) heapPtr = segptrHeap;
if (!heapPtr) return FALSE; if (!heapPtr) return FALSE;
flags &= HEAP_NO_SERIALIZE; flags &= HEAP_NO_SERIALIZE;
flags |= heapPtr->flags; flags |= heapPtr->flags;
if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection ); if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection );
if (!HEAP_IsRealArena( heap, HEAP_NO_SERIALIZE, ptr, QUIET )) if (!HEAP_IsRealArena( heapPtr, HEAP_NO_SERIALIZE, ptr, QUIET ))
{ {
SetLastError( ERROR_INVALID_PARAMETER ); SetLastError( ERROR_INVALID_PARAMETER );
ret = 0xffffffff; ret = 0xffffffff;
@ -1433,8 +1439,10 @@ BOOL WINAPI HeapValidate(
DWORD flags, /* [in] Bit flags that control access during operation */ DWORD flags, /* [in] Bit flags that control access during operation */
LPCVOID block /* [in] Optional pointer to memory block to validate */ LPCVOID block /* [in] Optional pointer to memory block to validate */
) { ) {
HEAP *heapPtr = HEAP_GetPtr( heap );
return HEAP_IsRealArena( heap, flags, block, QUIET ); if (flags & HEAP_WINE_SEGPTR) heapPtr = segptrHeap;
if (!heapPtr) return FALSE;
return HEAP_IsRealArena( heapPtr, flags, block, QUIET );
} }

View File

@ -551,33 +551,6 @@ void WINAPI UnMapSLFixArray( SEGPTR sptr[], INT length, CONTEXT86 *context )
/* Must not change EAX, hence defined as 'register' function */ /* Must not change EAX, hence defined as 'register' function */
} }
/***********************************************************************
* MapLS (KERNEL32.522)
*
* Maps linear pointer to segmented.
*/
SEGPTR WINAPI MapLS( LPVOID ptr )
{
if (!HIWORD(ptr))
return (SEGPTR)ptr;
else
{
WORD sel = SELECTOR_AllocBlock( ptr, 0x10000, WINE_LDT_FLAGS_DATA );
return PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
}
}
/***********************************************************************
* UnMapLS (KERNEL32.700)
*
* Free mapped selector.
*/
void WINAPI UnMapLS( SEGPTR sptr )
{
if (SELECTOROF(sptr)) FreeSelector16( SELECTOROF(sptr) );
}
/*********************************************************************** /***********************************************************************
* GetThreadSelectorEntry (KERNEL32) * GetThreadSelectorEntry (KERNEL32)
*/ */

View File

@ -217,9 +217,6 @@ static BOOL process_init( char *argv[] )
/* Copy the parent environment */ /* Copy the parent environment */
if (!ENV_BuildEnvironment()) return FALSE; if (!ENV_BuildEnvironment()) return FALSE;
/* Create the SEGPTR heap */
if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE;
/* Initialize the critical sections */ /* Initialize the critical sections */
InitializeCriticalSection( &current_process.crit_section ); InitializeCriticalSection( &current_process.crit_section );