Release 960324

Sun Mar 24 13:13:11 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [include/win.h] [windows/*.c]
	Replaced next, parent, child and owner handles by pointers in WND
	structure. This should improve performance, and should be
	reasonably safe since Microsoft did the same in Win95.

	* [include/wintypes.h] [*/*]
	Redefined HANDLE to be UINT instead of a pointer for Winelib. This
	allows removing a lot of unnecessary casts and NPFMTs.

	* [windows/caret.c]
	Create the caret brush upon CreateCaret(); use the bitmap
	dimensions for the caret.
	Fixed CARET_DisplayCaret() to use PatBlt().

Fri Mar 22 16:00:00 1996  Anand Kumria <akumria@ozemail.com.au>

	* [misc/winsocket.c]
	More sanity checks, fixup some erroneous return codes.

	* [documentation/winsock]
	Description of how compatible the winsock is currently.

Fri Mar 22 13:05:34 1996  Ulrich Schmid  <uschmid@mail.hh.provi.de>

	* [library/winmain.c]
	Set `lpszCmdParam' by concatenating arguments.

	* [loader/module.c]
	WinExec: accept Unix commands, use Wine emulator.

Mon Mar 18 12:16:27 1996  Martin von Loewis <loewis@informatik.hu-berlin.de>

	* [if1632/kernel32.spec][win32/thread.c][include/kernel32.h]
	DeleteCriticalSection, EnterCriticalSection,
 	InitializeCriticalSection, LeaveCriticalSection, TlsAlloc,
 	TlsFree, TlsGetValue, TlsSetValue: new functions.
	CRITICAL_SECTION: new structure.

	* [if1632/kernel32.spec][win32/code_page.c]
	WideCharToMultiByte: new function.

	* [if1632/kernel32.spec][win32/file.c]
	GetFileAttributesA: new function.

	* [if1632/kernel32.spec][misc/main.c]
	GetEnvironmentStringsW, FreeEnvironmentStringsA,
 	FreeEnvironmentStringsW: new functions.
	
	* [if1632/user.spec][win32/cursoricon32.c][win32/Makefile.in]
	cursoricon32.c: new file.
	LoadCursorA, LoadCursorW: modified implementation from LoadCursor
 	to WIN32_*.
	LoadIconA, LoadIconW: modified implementation from LoadIconA32
	to WIN32_*.

	* [include/struct32.h]
	pragma pack inserted.
	CURSORICON32 structures added.

	* [include/winnls.h]
	Constants CP_* and WC_* added.

	* [loader/pe_image.c]
	PE_LoadModule: call PE_InitDLL with hModule rather than wpnt.

Sun Mar 17 16:59:12 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [misc/commdlg.c]
	Introduced hook function handling in file dialog.
	Removed an unnecessary ShowWindow call in FILEDLG_WMCommand().

Thu Mar 14 10:50:00 1996  Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>

	* [if1632/gdi32.spec]
	Added GetNearestColor.

	* [if1632/kernel32.spec]
	Added GlobalAddAtomA.

	* [win32/param32.c]
	Added stackframe.h to includes.
	WIN32_GlobalAddAtomA() - new function.
diff --git a/loader/module.c b/loader/module.c
index a18f1da..7cece76 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -134,7 +134,7 @@
 
       /* Dump the module info */
 
-    printf( "Module "NPFMT":\n", hmodule );
+    printf( "Module %04x:\n", hmodule );
     printf( "count=%d flags=%04x heap=%d stack=%d\n",
             pModule->count, pModule->flags,
             pModule->heap_size, pModule->stack_size );
@@ -154,7 +154,7 @@
     printf( "\nSegment table:\n" );
     pSeg = NE_SEG_TABLE( pModule );
     for (i = 0; i < pModule->seg_count; i++, pSeg++)
-        printf( "%02x: pos=%d size=%d flags=%04x minsize=%d sel="NPFMT"\n",
+        printf( "%02x: pos=%d size=%d flags=%04x minsize=%d sel=%04x\n",
                 i + 1, pSeg->filepos, pSeg->size, pSeg->flags,
                 pSeg->minsize, pSeg->selector );
 
@@ -264,7 +264,7 @@
     static int cachedfd = -1;
 
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
-    dprintf_module( stddeb, "MODULE_OpenFile("NPFMT") cache: mod="NPFMT" fd=%d\n",
+    dprintf_module( stddeb, "MODULE_OpenFile(%04x) cache: mod=%04x fd=%d\n",
                     hModule, hCachedModule, cachedfd );
     if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return -1;
     if (hCachedModule == hModule) return cachedfd;
@@ -273,7 +273,7 @@
     name = NE_MODULE_NAME( pModule );
     if (!(unixName = DOSFS_GetUnixFileName( name, TRUE )) ||
         (cachedfd = open( unixName, O_RDONLY )) == -1)
-        fprintf( stderr, "MODULE_OpenFile: can't open file '%s' for module "NPFMT"\n",
+        fprintf( stderr, "MODULE_OpenFile: can't open file '%s' for module %04x\n",
                  name, hModule );
     dprintf_module( stddeb, "MODULE_OpenFile: opened '%s' -> %d\n",
                     name, cachedfd );
@@ -461,7 +461,7 @@
 
     hModule = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, size );
     if (!hModule) return (HMODULE)11;  /* invalid exe */
-    FarSetOwner( hModule, (WORD)(DWORD)hModule );
+    FarSetOwner( hModule, hModule );
     pModule = (NE_MODULE *)GlobalLock( hModule );
     memcpy( pModule, &ne_header, sizeof(NE_MODULE) );
     pModule->count = 0;
@@ -609,7 +609,7 @@
 
     if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
 
-    dprintf_module( stddeb, "MODULE_GetOrdinal("NPFMT",'%s')\n",
+    dprintf_module( stddeb, "MODULE_GetOrdinal(%04x,'%s')\n",
                     hModule, name );
 
       /* First handle names of the form '#xxxx' */
@@ -1162,11 +1162,7 @@
  */
 HMODULE WIN16_GetModuleHandle( SEGPTR name )
 {
-#ifdef WINELIB32
-    if (HIWORD(name) == 0) return GetExePtr( name );
-#else
-    if (HIWORD(name) == 0) return GetExePtr( LOWORD(name) );
-#endif
+    if (HIWORD(name) == 0) return GetExePtr( (HANDLE)name );
     return MODULE_FindModule( PTR_SEG_TO_LIN(name) );
 }
 
@@ -1185,7 +1181,7 @@
 
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
     if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
-    dprintf_module( stddeb, "GetModuleUsage("NPFMT"): returning %d\n",
+    dprintf_module( stddeb, "GetModuleUsage(%04x): returning %d\n",
                     hModule, pModule->count );
     return pModule->count;
 }
@@ -1243,7 +1239,7 @@
  */
 void FreeLibrary( HANDLE handle )
 {
-    dprintf_module( stddeb,"FreeLibrary: "NPFMT"\n", handle );
+    dprintf_module( stddeb,"FreeLibrary: %04x\n", handle );
     FreeModule( handle );
 }
 
@@ -1258,6 +1254,7 @@
     HANDLE handle;
     WORD *cmdShowPtr;
     char *p, *cmdline, filename[256];
+    static int use_load_module = 1;
 
     if (!(cmdShowHandle = GlobalAlloc( 0, 2 * sizeof(WORD) ))) return 0;
     if (!(cmdLineHandle = GlobalAlloc( 0, 256 ))) return 0;
@@ -1271,36 +1268,97 @@
       /* Build the filename and command-line */
 
     cmdline = (char *)GlobalLock( cmdLineHandle );
-    strncpy( filename, lpCmdLine, 256 );
-    filename[255] = '\0';
+    lstrcpyn( filename, lpCmdLine, sizeof(filename) - 4 /* for extension */ );
     for (p = filename; *p && (*p != ' ') && (*p != '\t'); p++);
-    if (*p)
-    {
-        strncpy( cmdline, p + 1, 128 );
-        cmdline[127] = '\0';
-    }
+    if (*p) lstrcpyn( cmdline, p + 1, 128 );
     else cmdline[0] = '\0';
     *p = '\0';
 
       /* Now load the executable file */
 
-#ifdef WINELIB32
-    params.hEnvironment = (HANDLE)GetDOSEnvironment();
-#else
-    params.hEnvironment = (HANDLE)SELECTOROF( GetDOSEnvironment() );
-#endif
-    params.cmdLine  = (SEGPTR)WIN16_GlobalLock( cmdLineHandle );
-    params.showCmd  = (SEGPTR)WIN16_GlobalLock( cmdShowHandle );
-    params.reserved = 0;
-    handle = LoadModule( filename, &params );
-    if (handle == (HANDLE)2)  /* file not found */
+    if (use_load_module)
     {
-	/* Check that the original file name did not have a suffix */
-	p = strrchr(filename, '.');
-        if (p && !(strchr(p, '/') || strchr(p, '\\')))
-            return handle;  /* filename already includes a suffix! */
-        strcat( filename, ".exe" );
-        handle = LoadModule( filename, &params );
+#ifdef WINELIB
+        /* WINELIB: Use LoadModule() only for the program itself */
+        use_load_module = 0;
+	params.hEnvironment = (HANDLE)GetDOSEnvironment();
+#else
+	params.hEnvironment = (HANDLE)SELECTOROF( GetDOSEnvironment() );
+#endif  /* WINELIB */
+	params.cmdLine  = (SEGPTR)WIN16_GlobalLock( cmdLineHandle );
+	params.showCmd  = (SEGPTR)WIN16_GlobalLock( cmdShowHandle );
+	params.reserved = 0;
+	handle = LoadModule( filename, &params );
+	if (handle == 2)  /* file not found */
+	{
+	    /* Check that the original file name did not have a suffix */
+	    p = strrchr(filename, '.');
+	    if (!p || (strchr(p, '/') && strchr(p, '\\')))
+            {
+                p = filename + strlen(filename);
+                strcpy( p, ".exe" );
+                handle = LoadModule( filename, &params );
+                *p = '\0';  /* Remove extension */
+            }
+	}
+    }
+    else handle = 2;
+
+    if (handle < 32)
+    {
+        /* Try to start it as a unix program */
+        if (!fork())
+	{
+            /* Child process */
+            const char *unixfilename;
+            const char *argv[256], **argptr;
+            int iconic = (nCmdShow == SW_SHOWMINIMIZED ||
+                          nCmdShow == SW_SHOWMINNOACTIVE);
+
+            /* get unixfilename */
+            if (strchr(filename, '/') ||
+                strchr(filename, ':') ||
+                strchr(filename, '\\'))
+                unixfilename = DOSFS_GetUnixFileName(filename, 1);
+            else unixfilename = filename;
+
+            if (unixfilename)
+            {
+                /* build argv */
+                argptr = argv;
+                if (iconic) *argptr++ = "-iconic";
+                *argptr++ = unixfilename;
+                p = cmdline;
+                while (1)
+                {
+                    while (*p && (*p == ' ' || *p == '\t')) *p++ = '\0';
+                    if (!*p) break;
+                    *argptr++ = p;
+                    while (*p && *p != ' ' && *p != '\t') p++;
+                }
+                *argptr++ = 0;
+
+                /* Execute */
+                execvp(argv[0], (char**)argv);
+            }
+
+	    /* Failed ! */
+#ifdef WINELIB
+	    /* build argv */
+	    argptr = argv;
+	    *argptr++ = "wine";
+	    if (iconic) *argptr++ = "-iconic";
+	    *argptr++ = lpCmdLine;
+	    *argptr++ = 0;
+
+	    /* Execute */
+	    execvp(argv[0] , (char**)argv);
+
+	    /* Failed ! */
+	    fprintf(stderr, "WinExec: can't exec 'wine %s'\n", lpCmdLine);
+#endif
+	    exit(1);
+	}
     }
 
     GlobalFree( cmdShowHandle );
@@ -1335,20 +1393,20 @@
     if (HIWORD(name) != 0)
     {
         ordinal = MODULE_GetOrdinal( hModule, (LPSTR)PTR_SEG_TO_LIN(name) );
-        dprintf_module( stddeb, "GetProcAddress: "NPFMT" '%s'\n",
+        dprintf_module( stddeb, "GetProcAddress: %04x '%s'\n",
                         hModule, (LPSTR)PTR_SEG_TO_LIN(name) );
     }
     else
     {
         ordinal = LOWORD(name);
-        dprintf_module( stddeb, "GetProcAddress: "NPFMT" %04x\n",
+        dprintf_module( stddeb, "GetProcAddress: %04x %04x\n",
                         hModule, ordinal );
     }
     if (!ordinal) return (FARPROC)0;
 
     ret = MODULE_GetEntryPoint( hModule, ordinal );
 
-    dprintf_module( stddeb, "GetProcAddress: returning "SPFMT"\n", ret );
+    dprintf_module( stddeb, "GetProcAddress: returning %08lx\n", (DWORD)ret );
     return (FARPROC)ret;
 }