Release 970928

Sat Sep 27 12:36:56 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [if1632/relay.c]
	Made Catch and Throw also save %si and %di (untested).

	* [memory/selector.c]
	Added check for %fs and %gs in SELECTOR_FreeBlock.

	* [rc/winerc.c]
	Generated files no longer depend on Wine includes.
	Made .h generation optional.

	* [tools/build.c] [loader/task.c]
	Added CALL32_Init function.
	Added possibility to pass arguments when using CALLTO16_regs_.
	32-bit stack pointer is now saved on the 16-bit stack, instead of
	using IF1632_Saved32_esp.
	Removed CallTo32 callbacks.

	* [tools/makedep.c] [*/Makefile.in]
	Added support for directly generating dependencies for .y, .l and
	.rc files. Modified the makefiles to use this feature.

	* [windows/winproc.c] [if1632/thunk.c]
	Use CALLTO16_regs to call window procedures.

Thu Sep 25 12:18:57 1997  Kristian Nielsen <kristian.nielsen@risoe.dk>

	* [if1632/kernel.spec]
	Changed entry for SwitchStackBack to remove arguments from stack
	upon return (arguments left over from previous SwitchStackTo()).
	Borland C++ 4.0 now compiles "Hello World" (but crashes after
	outputting the .exe).

Wed Sep 24 13:54:44 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [files/directory.c]
	SearchPath might get NULL buffer (empty LRU list in wordpad).

	* [memory/selector.c]
	Added SUnMapLS*.

	* [loader/pe_image.c]
	Be able to run executeables from non mmap()ble filesystems.
	PE_LoadLibrary adds librarys loaded by another process to
	its own modref list too.

	* [windows/keyboard.c][include/accel.h][loader/resource.c]
	Fixed accelerator leakage, use SDK defines/names.

	* [graphics/env.c][misc/main.c]
	Set/GetEnvironemnt have nothing to do with environment vars,
	but with Printer Environment.

	* [graphics/escape.c]
	Escape32: map args back to segmented pointers.

	* [windows/win.c]
	WS_POPUP|WS_CHILD windows don't need a parent window (SDK).

Tue Sep 16 14:40:16 1997  Robert Wilhelm  <robert@physiol.med.tu-muenchen.de>

	* [if1632/crtdll.spec] [misc/crtdll.c]
	Added signal().
diff --git a/memory/global.c b/memory/global.c
index ce11ed2..6a2b86b 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -395,7 +395,7 @@
  */
 HGLOBAL16 WINAPI GlobalFree16( HGLOBAL16 handle )
 {
-    void *ptr = GlobalLock16( handle );
+    void *ptr = (void *)GET_ARENA_PTR(handle)->base;
 
     dprintf_global( stddeb, "GlobalFree16: %04x\n", handle );
     if (!GLOBAL_FreeBlock( handle )) return handle;  /* failed */
@@ -426,6 +426,7 @@
 #endif  /* CONFIG_IPC */
 
 	if (!GET_ARENA_PTR(handle)->base) return (SEGPTR)0;
+        GET_ARENA_PTR(handle)->lockCount++;
 	return PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel(handle), 0 );
 	/* FIXME: put segment value in CX as well */
     }
@@ -441,6 +442,7 @@
 LPVOID WINAPI GlobalLock16( HGLOBAL16 handle )
 {
     if (!handle) return 0;
+    GET_ARENA_PTR(handle)->lockCount++;
 #ifdef CONFIG_IPC
     if (is_dde_handle(handle)) return DDE_AttachHandle(handle, NULL);
 #endif
@@ -453,8 +455,10 @@
  */
 BOOL16 WINAPI GlobalUnlock16( HGLOBAL16 handle )
 {
+    GLOBALARENA *pArena = GET_ARENA_PTR(handle);
     dprintf_global( stddeb, "GlobalUnlock16: %04x\n", handle );
-    return 0;
+    if (pArena->lockCount) pArena->lockCount--;
+    return pArena->lockCount;
 }
 
 
@@ -558,7 +562,7 @@
  */
 BOOL16 WINAPI GlobalUnWire16( HGLOBAL16 handle )
 {
-    return GlobalUnlock16( handle );
+    return !GlobalUnlock16( handle );
 }
 
 
diff --git a/memory/local.c b/memory/local.c
index c0062dc..5a75d1e 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -1236,7 +1236,7 @@
     if (!hmem)
     {
         /* Remove the block from the heap and try again */
-        LPSTR buffer = HeapAlloc( SystemHeap, 0, oldsize );
+        LPSTR buffer = HeapAlloc( GetProcessHeap(), 0, oldsize );
         if (!buffer) return 0;
         memcpy( buffer, ptr + arena + ARENA_HEADER_SIZE, oldsize );
         LOCAL_FreeArena( ds, arena );
@@ -1245,14 +1245,14 @@
             if (!(hmem = LOCAL_GetBlock( ds, oldsize, flags )))
             {
                 fprintf( stderr, "LocalRealloc: can't restore saved block\n" );
-                HeapFree( SystemHeap, 0, buffer );
+                HeapFree( GetProcessHeap(), 0, buffer );
                 return 0;
             }
             size = oldsize;
         }
         ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );  /* Reload ptr */
         memcpy( ptr + hmem, buffer, oldsize );
-        HeapFree( SystemHeap, 0, buffer );
+        HeapFree( GetProcessHeap(), 0, buffer );
     }
     else
     {
diff --git a/memory/selector.c b/memory/selector.c
index 421cd99..bf4f829 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -138,6 +138,25 @@
     dprintf_selector( stddeb, "SELECTOR_FreeBlock(%04x,%d)\n", sel, count );
     sel &= ~(__AHINCR - 1);  /* clear bottom bits of selector */
     nextsel = sel + (count << __AHSHIFT);
+
+#ifdef __i386__
+    {
+        /* Check if we are freeing current %fs or %gs selector */
+
+        WORD fs, gs;
+
+        __asm__("movw %%fs,%w0":"=r" (fs));
+        if ((fs >= sel) && (fs < nextsel))
+        {
+            fprintf( stderr, "SELECTOR_FreeBlock: freeing %%fs selector (%04x), not good.\n", fs );
+            __asm__("movw %w0,%%fs"::"r" (0));
+        }
+        __asm__("movw %%gs,%w0":"=r" (gs));
+        if ((gs >= sel) && (gs < nextsel))
+            __asm__("movw %w0,%%gs"::"r" (0));
+    }
+#endif  /* __i386__ */
+
     memset( &entry, 0, sizeof(entry) );  /* clear the LDT entries */
     for (i = SELECTOR_TO_ENTRY(sel); count; i++, count--)
     {
@@ -563,7 +582,7 @@
 void WINAPI SMapLS_IP_EBP_36(CONTEXT *context) {x_SMapLS_IP_EBP_x(context,36);}
 void WINAPI SMapLS_IP_EBP_40(CONTEXT *context) {x_SMapLS_IP_EBP_x(context,40);}
 
-void WINAPI SMapLS(CONTEXT *context,int argoff)
+void WINAPI SMapLS(CONTEXT *context)
 {
     if (EAX_reg(context)>=0x10000) {
 	EAX_reg(context) = MapLS((LPVOID)EAX_reg(context));
@@ -573,6 +592,28 @@
     }
 }
 
+void WINAPI SUnMapLS(CONTEXT *context)
+{
+    if (EAX_reg(context)>=0x10000)
+	UnMapLS((SEGPTR)EAX_reg(context));
+}
+
+static void
+x_SUnMapLS_IP_EBP_x(CONTEXT *context,int argoff) {
+	if (*(DWORD*)(EBP_reg(context)+argoff))
+		UnMapLS(*(DWORD*)(EBP_reg(context)+argoff));
+	*(DWORD*)(EBP_reg(context)+argoff)=0;
+}
+void WINAPI SUnMapLS_IP_EBP_8(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,12); }
+void WINAPI SUnMapLS_IP_EBP_12(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,12); }
+void WINAPI SUnMapLS_IP_EBP_16(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,16); }
+void WINAPI SUnMapLS_IP_EBP_20(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,20); }
+void WINAPI SUnMapLS_IP_EBP_24(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,24); }
+void WINAPI SUnMapLS_IP_EBP_28(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,28); }
+void WINAPI SUnMapLS_IP_EBP_32(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,32); }
+void WINAPI SUnMapLS_IP_EBP_36(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,36); }
+void WINAPI SUnMapLS_IP_EBP_40(CONTEXT *context) { x_SUnMapLS_IP_EBP_x(context,40); }
+
 /**********************************************************************
  *           WOWGetVDMPointer	(KERNEL32.55)
  * Get linear from segmented pointer. (MSDN lib)
diff --git a/memory/string.c b/memory/string.c
index 60194a3..88b72c4 100644
--- a/memory/string.c
+++ b/memory/string.c
@@ -281,7 +281,7 @@
     dprintf_string(stddeb,"strcpyn '%s' for %d chars\n",
 		 (src)?src:"NULL",n);
     while ((n-- > 1) && *src) *p++ = *src++;
-    *p = 0;
+    if (n >= 0) *p = 0;
     return dst;
 }
 
@@ -293,7 +293,7 @@
 {
     LPWSTR p = dst;
     while ((n-- > 1) && *src) *p++ = *src++;
-    *p = 0;
+    if (n >= 0) *p = 0;
     return dst;
 }
 
@@ -421,7 +421,7 @@
 {
     LPWSTR p = dst;
     while ((n-- > 1) && *src) *p++ = (WCHAR)(unsigned char)*src++;
-    *p = 0;
+    if (n >= 0) *p = 0;
     return dst;
 }
 
@@ -433,7 +433,7 @@
 {
     LPSTR p = dst;
     while ((n-- > 1) && *src) *p++ = (CHAR)*src++;
-    *p = 0;
+    if (n >= 0) *p = 0;
     return dst;
 }
 
@@ -560,9 +560,10 @@
  */
 BOOL32 WINAPI OemToChar32A( LPCSTR s, LPSTR d )
 {
+    LPSTR oldd = d;
     dprintf_string(stddeb,"OemToChar '%s'\n", (s)?s:"NULL");
     while ((*d++ = OEM_TO_ANSI(*s++)));
-    dprintf_string(stddeb," to '%s'\n", (d)?d:"NULL");
+    dprintf_string(stddeb," to '%s'\n", oldd);
     return TRUE;
 }