Index: wine/loader/pe_image.c
===================================================================
RCS file: /home/wine/wine/loader/pe_image.c,v
retrieving revision 1.67
diff -u -r1.67 pe_image.c
--- wine/loader/pe_image.c	2000/07/15 19:44:29	1.67
+++ wine/loader/pe_image.c	2000/07/27 22:53:01
@@ -40,6 +40,7 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#define __USE_UNIX98
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -685,26 +686,83 @@
         TRACE("%s: mmaping section %s at %p off %lx size %lx/%lx\n",
               filename, pe_sec->Name, (void*)RVA(pe_sec->VirtualAddress),
               pe_sec->PointerToRawData, pe_sec->SizeOfRawData, pe_sec->Misc.VirtualSize );
-        if (FILE_dommap( unix_handle, (void*)RVA(pe_sec->VirtualAddress),
-                         0, pe_sec->SizeOfRawData, 0, pe_sec->PointerToRawData,
-                         PROT_EXEC | PROT_WRITE | PROT_READ,
-                         MAP_PRIVATE | MAP_FIXED ) != (void*)RVA(pe_sec->VirtualAddress))
-        {
-            /* We failed to map to the right place (huh?) */
-            ERR_(win32)( "Critical Error: failed to map PE section to necessary address.\n");
-            goto error;
-        }
-        if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) &&
-            (pe_sec->SizeOfRawData & (page_size-1)))
-        {
-            DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size;
-            if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize;
-            TRACE("clearing %p - %p\n",
-                  RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData,
-                  RVA(pe_sec->VirtualAddress) + end );
-            memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0,
-                    end - pe_sec->SizeOfRawData );
-        }
+
+	if ( pe_sec->Characteristics & IMAGE_SCN_MEM_SHARED ) {
+	  HANDLE hMapping;
+	  DWORD size;
+	  BOOL exists;
+	  struct get_mapping_info_request *req_map = get_req_buffer();
+	  int unix_map_handle;
+	  LPSTR map_name = HeapAlloc ( GetProcessHeap(), 0, lstrlenA ( filename ) + lstrlenA ( pe_sec->Name ) + 5 );
+	  TRACE ( "Section %s shared\n", pe_sec->Name );
+	  if ( map_name == NULL ) 
+	    {
+	      ERR_(win32)("Out of memory.\n" );
+	      goto error;
+	    }
+	  wsprintfA ( map_name, "___%s@%s", filename, pe_sec->Name );
+	  size = ((pe_sec->SizeOfRawData-1) & ~(page_size-1)) + page_size;
+	  MESSAGE ( "opening/creating file mapping %s, raw_data: %ld, size: %ld\n", map_name, pe_sec->SizeOfRawData, size );
+	  hMapping = CreateFileMappingA ( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, size, map_name );
+	  HeapFree ( GetProcessHeap(), 0, map_name );
+	  if ( hMapping == (HANDLE )NULL ) {
+	    ERR_(win32)("CreateFileMappingA failed.\n" );
+	    goto error;
+	  }
+	  exists = ( GetLastError() == ERROR_ALREADY_EXISTS );
+
+	  req_map->handle = hMapping; 
+	  if (server_call_fd( REQ_GET_MAPPING_INFO, -1, &unix_map_handle )) {
+	    ERR_(win32)( "Couldn't get read mapping info.\n" );
+	    CloseHandle ( hMapping );
+	    goto error;
+	  }
+	  if ( FILE_dommap( unix_map_handle, (void *)RVA(pe_sec->VirtualAddress), 
+		       0, size, 0, 0,
+		       PROT_EXEC | PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED )
+	       != (void *)RVA(pe_sec->VirtualAddress ) ) {
+	    CloseHandle ( hMapping );
+	    ERR_(win32)( "Critical Error: failed to map shared PE section to necessary address.\n");
+	    goto error;
+	  }
+	  // CloseHandle ( hMapping );
+	  if ( ! exists ) {
+	    FIXME ( "mapping is newly created.\n" );
+	    /* Copy the section into memory */ 
+	    if ( pread ( unix_handle, (void *)RVA(pe_sec->VirtualAddress), 
+			 pe_sec->SizeOfRawData, pe_sec->PointerToRawData ) != pe_sec->SizeOfRawData ) {
+	      ERR_(win32)( "couldn't read section into mapping\n" );
+	      UnmapViewOfFile ( (void *)RVA(pe_sec->VirtualAddress ) );
+	      goto error;
+	    }
+	  }
+	  else {
+	    FIXME ( "mapping did already exist.\n" );
+	  }
+	}
+	else {  /* not a shared section */
+	  TRACE ( "Section %s not shared\n", pe_sec->Name );
+	  if (FILE_dommap( unix_handle, (void*)RVA(pe_sec->VirtualAddress),
+			   0, pe_sec->SizeOfRawData, 0, pe_sec->PointerToRawData,
+			   PROT_EXEC | PROT_WRITE | PROT_READ,
+			   MAP_FIXED | MAP_PRIVATE ) != (void*)RVA(pe_sec->VirtualAddress))
+	    {
+	      /* We failed to map to the right place (huh?) */
+	      ERR_(win32)( "Critical Error: failed to map PE section to necessary address.\n");
+	      goto error;
+	    }
+	  if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) &&
+	      (pe_sec->SizeOfRawData & (page_size-1)))
+	    {
+	      DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size;
+	      if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize;
+	      TRACE("clearing %p - %p\n",
+		    RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData,
+		    RVA(pe_sec->VirtualAddress) + end );
+	      memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0,
+		      end - pe_sec->SizeOfRawData );
+	    }
+	}
     }
 
     /* Perform base relocation, if necessary */
@@ -948,6 +1006,7 @@
 	/* Create 16-bit dummy module */
 	if ((hModule16 = MODULE_CreateDummyModule( filename, hModule32 )) < 32)
 	{
+		/* PE_UnloadImage() ?? */
                 CloseHandle( hFile );
 		SetLastError( (DWORD)hModule16 );	/* This should give the correct error */
 		return NULL;
@@ -958,6 +1017,7 @@
 	{
 		ERR( "can't load %s\n", filename );
 		FreeLibrary16( hModule16 );
+		/* PE_UnloadImage() ?? */
                 CloseHandle( hFile );
 		SetLastError( ERROR_OUTOFMEMORY );
 		return NULL;
@@ -971,7 +1031,7 @@
         req->dbg_size   = PE_HEADER(hModule32)->FileHeader.NumberOfSymbols;
         req->name       = &wm->filename;
         server_call_noerr( REQ_LOAD_DLL );
-        CloseHandle( hFile );
+	/*        CloseHandle( hFile ); */
 	return wm;
 }
 
