Index: trunk/src/kernel32/makefile
===================================================================
--- trunk/src/kernel32/makefile	(revision 656)
+++ trunk/src/kernel32/makefile	(revision 657)
@@ -1,3 +1,3 @@
-# $Id: makefile,v 1.26 1999-08-23 13:54:43 sandervl Exp $
+# $Id: makefile,v 1.27 1999-08-24 12:23:24 sandervl Exp $
 
 #
@@ -20,18 +20,18 @@
 
 OBJS = KERNEL32.OBJ KOBJECTS.OBJ CONSOLE.OBJ CONIN.OBJ CONBUFFER.OBJ \
-       CONOUT.OBJ UNICODE.OBJ network.OBJ DEVIO.OBJ profile.obj \
-       THREAD.OBJ virtual.obj THUNK.OBJ OBSOLETE.OBJ COMM.OBJ \
-       MESSAGE.OBJ RESOURCE.OBJ NAMEID.OBJ WINRES.OBJ WINMOD.OBJ \
-       OS2NATIVE.OBJ EXCEPTIONS.OBJ LFILE.OBJ NPIPE.OBJ \
-       MISC.OBJ EXCEPTUTIL.OBJ LANG.OBJ ICCIO.OBJ MAP.OBJ \
-       WIN32UTIL.OBJ heap.OBJ heapstring.obj os2heap.OBJ \
-       vmutex.OBJ initterm.OBJ os2util.OBJ handlemanager.OBJ \
-       hmdevice.obj hmopen32.obj hmobjects.obj hmevent.obj \
-       hmmutex.obj hmsemaphore.obj wprocess.OBJ conprop.OBJ \
-       winimage.OBJ windll.OBJ winexe.OBJ time.obj \
-       pefile.OBJ winimgres.OBJ wintls.obj async.OBJ fileio.obj \
-       atom.obj disk.obj directory.obj cvtbitmap.obj \
-       cvtmenu.obj cvtaccel.obj cvticon.obj cvticongrp.obj \
-       cvtcursor.obj cvtcursorgrp.obj stubs.obj
+ CONOUT.OBJ UNICODE.OBJ network.OBJ DEVIO.OBJ profile.obj \
+ THREAD.OBJ virtual.obj THUNK.OBJ OBSOLETE.OBJ COMM.OBJ \
+ MESSAGE.OBJ RESOURCE.OBJ NAMEID.OBJ WINRES.OBJ WINMOD.OBJ \
+ OS2NATIVE.OBJ EXCEPTIONS.OBJ LFILE.OBJ NPIPE.OBJ \
+ MISC.OBJ EXCEPTUTIL.OBJ LANG.OBJ ICCIO.OBJ MAP.OBJ \
+ WIN32UTIL.OBJ heap.OBJ heapstring.obj os2heap.OBJ \
+ vmutex.OBJ initterm.OBJ os2util.OBJ handlemanager.OBJ \
+ hmdevice.obj hmopen32.obj hmobjects.obj hmevent.obj \
+ hmmutex.obj hmsemaphore.obj wprocess.OBJ conprop.OBJ \
+ winimage.OBJ windll.OBJ winexe.OBJ time.obj mmap.obj \
+ pefile.OBJ winimgres.OBJ wintls.obj async.OBJ fileio.obj \
+ atom.obj disk.obj directory.obj cvtbitmap.obj \
+ cvtmenu.obj cvtaccel.obj cvticon.obj cvticongrp.obj \
+ cvtcursor.obj cvtcursorgrp.obj stubs.obj 
 
 
@@ -296,5 +296,6 @@
         $(PDWIN32_INCLUDE)\unicode.h
 
-virtual.obj:   virtual.cpp $(PDWIN32_INCLUDE)\win\virtual.h
+virtual.obj:   virtual.cpp $(PDWIN32_INCLUDE)\win\virtual.h mmap.h
+mmap.obj:      mmap.cpp mmap.h $(PDWIN32_INCLUDE)\vmutex.h
 
 pefile.OBJ:    pefile.cpp $(PDWIN32_INCLUDE)\pefile.h
Index: trunk/src/kernel32/mmap.cpp
===================================================================
--- trunk/src/kernel32/mmap.cpp	(revision 657)
+++ trunk/src/kernel32/mmap.cpp	(revision 657)
@@ -0,0 +1,268 @@
+/* $Id: mmap.cpp,v 1.7 1999-08-24 12:23:54 sandervl Exp $ */
+
+/*
+ * Win32 Memory mapped file class
+ *
+ * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ * NOTE: Memory mapping DOES NOT work when kernel-mode code causes
+ *       a pagefault in the memory mapped object. (exceptions aren't
+ *       dispatched to our exception handler until after the kernel mode
+ *       call returns (too late))
+ *
+ * NOTE: There's no easy way to determine which pages were modified. Temporary
+ *       solution is to write all paged-in memory to disk.
+ *
+ * NOTE: Are apps allowed to change the protection flags of memory mapped pages?
+ *       I'm assuming they aren't for now.
+ *
+ * TODO: Handles returned should be usable by all apis that accept file handles
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#include <os2win.h>
+#include <stdlib.h>
+#include <string.h>
+#include <win\virtual.h>
+#include <vmutex.h>
+#include <handlemanager.h>
+#include "mmap.h"
+
+VMutex globalmapMutex;
+
+//******************************************************************************
+//TODO: sharing between processes
+//******************************************************************************
+Win32MemMap::Win32MemMap(HFILE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName)
+               : fMapped(FALSE), pMapping(NULL), mMapAccess(0)
+{
+  globalmapMutex.enter();
+  memmaps = this;
+  next    = memmaps;
+  globalmapMutex.leave();
+
+  hMemFile   = hfile;
+
+  mSize      = size;
+  mProtFlags = fdwProtect;
+
+  if(lpszName) {
+	lpszMapName = (char *)malloc(strlen(lpszName)+1);
+	strcpy(lpszMapName, lpszName);
+  }
+  else	lpszMapName = NULL;
+}
+//******************************************************************************
+//******************************************************************************
+HANDLE Win32MemMap::Init()
+{
+  mapMutex.enter();
+  if(hMemFile != -1) 
+  {
+     	if(DuplicateHandle(GetCurrentProcess(), hMemFile, GetCurrentProcess(),
+                           &hMemFile, 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE) 
+     	{
+		dprintf(("Win32MemMap::Init: DuplicateHandle failed!"));
+		goto fail;
+     	}
+  }
+  if(HMHandleAllocate(&hMemMap, (ULONG)this) != 0)
+  {
+	dprintf(("Win32MemMap::Init HMHandleAllocate failed!!"));
+	DebugInt3();
+	goto fail;
+  }
+  mapMutex.leave();
+  return hMemMap;
+fail:
+  mapMutex.leave();
+  return 0;
+}
+//******************************************************************************
+//******************************************************************************
+Win32MemMap::~Win32MemMap()
+{
+  unmapFileView();
+  if(lpszMapName) {
+	free(lpszMapName);
+  }
+  mapMutex.enter();
+  if(pMapping) {
+	VirtualFree(pMapping, mSize, MEM_RELEASE);
+	pMapping = NULL;
+  }
+  if(hMemFile != -1) {
+  	CloseHandle(hMemFile);
+	hMemFile = -1;
+  }
+  mapMutex.leave();
+
+  globalmapMutex.enter();
+  Win32MemMap *map = memmaps;
+
+  if(map == this) {
+	memmaps = next;
+  }
+  else {
+  	while(map->next) {
+		if(map->next == this)
+			break;
+		map = map->next;
+	}
+	if(map->next) {
+		map->next = next;
+	}
+	else	dprintf(("Win32MemMap::~Win32MemMap: map not found!! (%x)", this));
+  }
+  globalmapMutex.leave();
+}
+//******************************************************************************
+//******************************************************************************
+BOOL Win32MemMap::unmapFileView()
+{
+  if(fMapped == FALSE)
+	return FALSE;
+
+  flushView(pMapping, mSize);
+  mapMutex.enter();
+  if(pMapping) {
+	VirtualFree(pMapping, mSize, MEM_RELEASE);
+  }
+  pMapping = NULL;
+  fMapped = FALSE;
+  mapMutex.leave();
+  return TRUE;
+}
+//******************************************************************************
+//******************************************************************************
+LPVOID Win32MemMap::mapFileView(ULONG size, ULONG offset, ULONG fdwAccess)
+{
+  mapMutex.enter();
+  ULONG memFlags = (mProtFlags & (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY));
+  ULONG fAlloc   = 0;
+
+  if(fdwAccess & FILE_MAP_WRITE && mProtFlags & (PAGE_READONLY|PAGE_WRITECOPY)) 
+	goto parmfail;
+  if(fdwAccess & FILE_MAP_READ && mProtFlags & PAGE_WRITECOPY) 
+	goto parmfail;
+  if(fdwAccess & FILE_MAP_ALL_ACCESS && mProtFlags & (PAGE_READONLY|PAGE_WRITECOPY)) 
+	goto parmfail;
+  if(fdwAccess & FILE_MAP_COPY && mProtFlags & PAGE_WRITECOPY) 
+	goto parmfail;
+  
+  if(mProtFlags & SEC_COMMIT)
+	fAlloc |= MEM_COMMIT;
+  if(mProtFlags & SEC_RESERVE)
+ 	fAlloc |= MEM_RESERVE;
+
+  pMapping = VirtualAlloc(0, mSize, fAlloc, memFlags);
+  if(pMapping == NULL) {
+	dprintf(("Win32MemMap::mapFileView: VirtualAlloc %x %x %x failed!", mSize, fAlloc, memFlags));
+	goto fail;
+  }
+  mapMutex.leave();
+  return pMapping;
+
+parmfail:
+  dprintf(("Win32MemMap::mapFileView: ERROR_INVALID_PARAMETER"));
+  SetLastError(ERROR_INVALID_PARAMETER);
+fail:
+  mapMutex.leave();
+  return 0;
+}
+//******************************************************************************
+// NOTE: There's no easy way to determine which pages were modified. Temporary
+//       solution is to write all paged-in memory to disk.
+//TODO: Are apps allowed to change the protection flags of memory mapped pages?
+//      I'm assuming they aren't for now.
+//******************************************************************************
+BOOL Win32MemMap::flushView(LPVOID lpvBase, ULONG cbFlush)
+{
+ MEMORY_BASIC_INFORMATION memInfo;
+ ULONG nrpages, nrBytesWritten;
+ int   i;
+
+  mapMutex.enter();
+  if(fMapped == FALSE)
+	goto parmfail;
+
+  if(lpvBase < pMapping || (ULONG)lpvBase+cbFlush > (ULONG)pMapping+mSize)
+	goto parmfail;
+
+  if(mProtFlags & PAGE_READONLY)
+	goto parmfail;
+
+  nrpages = cbFlush/PAGE_SIZE;
+  if(cbFlush & 0xFFF)  nrpages++;
+
+  for(i=0;i<nrpages;i++) {
+	if(VirtualQuery((LPSTR)lpvBase+i*PAGE_SIZE, &memInfo, PAGE_SIZE) == 0) {
+		dprintf(("Win32MemMap::flushView: VirtualQuery (%x,%x) failed for %x", lpvBase, cbFlush, (ULONG)lpvBase+i*PAGE_SIZE));
+		goto fail;
+	}
+	//If a page is reserved or write protected, we won't bother flushing it to disk
+	if(memInfo.State & MEM_COMMIT && 
+           memInfo.AllocationProtect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)) 
+        {//committed and allowed for writing?
+		if(WriteFile(hMemFile, (LPSTR)lpvBase+i*PAGE_SIZE, PAGE_SIZE, &nrBytesWritten, NULL) == FALSE) {
+			dprintf(("Win32MemMap::flushView: WriteFile failed for %x", (ULONG)lpvBase+i*PAGE_SIZE));
+			goto fail;
+		}
+		if(nrBytesWritten != PAGE_SIZE) {
+			dprintf(("Win32MemMap::flushView: WriteFile didn't write all bytes for %x", (ULONG)lpvBase+i*PAGE_SIZE));
+			goto fail;
+		}
+	}
+  }
+  mapMutex.leave();
+  return TRUE;
+parmfail:
+  SetLastError(ERROR_INVALID_PARAMETER);
+  mapMutex.leave();
+  return FALSE;
+fail:
+  mapMutex.leave();
+  return FALSE;
+}
+//******************************************************************************
+//******************************************************************************
+Win32MemMap *Win32MemMap::findMap(LPSTR lpszName)
+{
+  globalmapMutex.enter();
+  Win32MemMap *map = memmaps;
+
+  if(map != NULL) {
+  	while(map) {
+		if(map->lpszMapName && !strcmp(map->lpszMapName, lpszName))
+			break;
+		map = map->next;
+	}
+  }
+  globalmapMutex.leave();
+  dprintf(("Win32MemMap::findMap: couldn't find map %s", lpszName));
+  return map;
+}
+//******************************************************************************
+//******************************************************************************
+Win32MemMap *Win32MemMap::findMap(ULONG address)
+{
+  globalmapMutex.enter();
+  Win32MemMap *map = memmaps;
+
+  if(map != NULL) {
+  	while(map) {
+		if(map->pMapping && (ULONG)map->pMapping <= address &&
+                   (ULONG)map->pMapping + map->mSize > address)
+		{
+			break;
+		}
+		map = map->next;
+	}
+  }
+  globalmapMutex.leave();
+  return map;
+}
+//******************************************************************************
+//******************************************************************************
+Win32MemMap *Win32MemMap::memmaps = NULL;
Index: trunk/src/kernel32/mmap.h
===================================================================
--- trunk/src/kernel32/mmap.h	(revision 657)
+++ trunk/src/kernel32/mmap.h	(revision 657)
@@ -0,0 +1,54 @@
+/* $Id: mmap.h,v 1.5 1999-08-24 12:23:54 sandervl Exp $ */
+
+/*
+ * Memory mapped class
+ *
+ * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#ifndef __MMAP_H__
+#define __MMAP_H__
+
+#include <vmutex.h>
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE   4096
+#endif
+
+class Win32MemMap
+{
+public:
+   Win32MemMap(HFILE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName);
+  ~Win32MemMap();
+
+   HANDLE Init();
+   BOOL   flushView(LPVOID lpvBase, ULONG cbFlush);
+   LPVOID mapFileView(ULONG size, ULONG offset, ULONG fdwAccess);
+   BOOL   unmapFileView();
+
+   HFILE  getMapHandle()                 { return hMemMap; };
+   LPSTR  getMemName()                   { return lpszMapName; };
+
+static Win32MemMap *findMap(LPSTR lpszName);
+static Win32MemMap *findMap(ULONG address);
+
+protected:
+   HFILE  hMemMap, hMemFile;
+   ULONG  mSize;
+   ULONG  mProtFlags;
+   ULONG  mMapAccess;
+   LPSTR  lpszMapName;
+   void  *pMapping;
+   BOOL   fMapped;
+
+   VMutex mapMutex;
+
+private:
+   static Win32MemMap *memmaps;
+	  Win32MemMap *next;
+};
+
+#endif //__MMAP_H__
Index: trunk/src/kernel32/os2native.cpp
===================================================================
--- trunk/src/kernel32/os2native.cpp	(revision 656)
+++ trunk/src/kernel32/os2native.cpp	(revision 657)
@@ -1,3 +1,3 @@
-/* $Id: os2native.cpp,v 1.5 1999-08-22 11:11:10 sandervl Exp $ */
+/* $Id: os2native.cpp,v 1.6 1999-08-24 12:23:24 sandervl Exp $ */
 
 /*
@@ -8,4 +8,8 @@
  * Copyright 1998 Peter FitzSimmons
  *
+ *
+ * TODO: VirtualProtectEx/VirtualQueryEx don't work for different processes!
+ * TODO: SetLastError should be called!
+ * TODO: WRITECOPY type not properly supported (never return as flag when queried)
  *
  * Project Odin Software License can be found in LICENSE.TXT
@@ -37,9 +41,23 @@
 #define PAGE_GUARD            0x100
 #define PAGE_NOCACHE          0x200
-#define MEM_COMMIT           0x1000
-#define MEM_RESERVE          0x2000
-#define MEM_DECOMMIT         0x4000
-#define MEM_RELEASE          0x8000
-#define MEM_TOP_DOWN       0x100000             //Ignored
+
+#define MEM_COMMIT              0x00001000
+#define MEM_RESERVE             0x00002000
+#define MEM_DECOMMIT            0x00004000
+#define MEM_RELEASE             0x00008000
+#define MEM_FREE                0x00010000
+#define MEM_PRIVATE             0x00020000
+#define MEM_MAPPED              0x00040000
+#define MEM_TOP_DOWN            0x00100000
+
+#define SEC_FILE                0x00800000
+#define SEC_IMAGE               0x01000000
+#define SEC_RESERVE             0x04000000
+#define SEC_COMMIT              0x08000000
+#define SEC_NOCACHE             0x10000000
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
 
 extern ULONG flAllocMem;    /* Tue 03.03.1998: knut */
@@ -81,10 +99,17 @@
   if(fdwProtect & PAGE_READONLY)     flag |= PAG_READ;
   if(fdwProtect & PAGE_READWRITE)    flag |= (PAG_READ | PAG_WRITE);
-  if(fdwProtect & PAGE_EXECUTE_READ) flag |= PAG_EXECUTE;
+  if(fdwProtect & PAGE_WRITECOPY)    flag |= (PAG_READ | PAG_WRITE);
+
+  if(fdwProtect & PAGE_EXECUTE_READWRITE) flag |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
+  if(fdwProtect & PAGE_EXECUTE_READ) flag |= (PAG_EXECUTE | PAG_READ);
+  if(fdwProtect & PAGE_EXECUTE)	     flag |= PAG_EXECUTE;
+
   if(fdwProtect & PAGE_GUARD)        flag |= PAG_GUARD;
 
   //just do this if other options are used
-  if(!(flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) || flag == 0)
+  if(!(flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) || flag == 0) {
+	dprintf(("VirtualAlloc: Unknown protection flags, default to read/write"));
         flag |= PAG_READ | PAG_WRITE;
+  }
 
   if(fdwAllocationType & MEM_COMMIT && lpvAddress != NULL) {
@@ -168,5 +193,5 @@
 //******************************************************************************
 BOOL WIN32API VirtualProtect(LPVOID lpvAddress, DWORD cbSize, DWORD fdwNewProtect,
-                                DWORD *pfdwOldProtect)
+                             DWORD *pfdwOldProtect)
 {
  APIRET rc;
@@ -188,8 +213,13 @@
   if(pageFlags & PAG_READ && !(pageFlags & PAG_WRITE))
         *pfdwOldProtect |= PAGE_READONLY;
-  if(pageFlags & (PAG_READ | PAG_WRITE))
+  if(pageFlags & (PAG_WRITE))
         *pfdwOldProtect |= PAGE_READWRITE;
+
+  if(pageFlags & (PAG_WRITE | PAG_EXECUTE))
+        *pfdwOldProtect |= PAGE_EXECUTE_READWRITE;
+  else
   if(pageFlags & PAG_EXECUTE)
         *pfdwOldProtect |= PAGE_EXECUTE_READ;
+
   if(pageFlags & PAG_GUARD)
         *pfdwOldProtect |= PAGE_GUARD;
@@ -198,7 +228,10 @@
   if(fdwNewProtect & PAGE_READONLY)     pageFlags |= PAG_READ;
   if(fdwNewProtect & PAGE_READWRITE)    pageFlags |= (PAG_READ | PAG_WRITE);
-  if(fdwNewProtect & PAGE_EXECUTE_READ) pageFlags |= PAG_EXECUTE;
+  if(fdwNewProtect & PAGE_WRITECOPY)    pageFlags |= (PAG_READ | PAG_WRITE);
+  if(fdwNewProtect & PAGE_EXECUTE_READ) pageFlags |= (PAG_EXECUTE | PAG_READ);
   if(fdwNewProtect & PAGE_EXECUTE_READWRITE)
-        pageFlags |= (PAG_EXECUTE | PAG_WRITE);
+        pageFlags |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
+  if(fdwNewProtect & PAGE_EXECUTE_WRITECOPY)
+        pageFlags |= (PAG_EXECUTE | PAG_WRITE | PAG_READ);
   if(fdwNewProtect & PAGE_GUARD)        pageFlags |= PAG_GUARD;
 //Not supported in OS/2??
@@ -224,11 +257,68 @@
 }
 //******************************************************************************
-#define PMEMORY_BASIC_INFORMATION void *
 //******************************************************************************
 DWORD WIN32API VirtualQuery(LPVOID lpvAddress, PMEMORY_BASIC_INFORMATION pmbiBuffer,
-                               DWORD cbLength)
-{
-  dprintf(("VirtualQuery - stub\n"));
-  return(0);
+                            DWORD cbLength)
+{
+ ULONG  cbRangeSize, dAttr;
+ APIRET rc;
+
+  if(lpvAddress == NULL || pmbiBuffer == NULL || cbLength == 0) {
+	return 0;
+  }
+  cbRangeSize = cbLength;
+  rc = DosQueryMem(lpvAddress, &cbRangeSize, &dAttr);
+  if(rc) {
+  	dprintf(("VirtualQuery - DosQueryMem %x %x returned %d\n", lpvAddress, cbLength, rc));
+	return 0;
+  }
+  memset(pmbiBuffer, 0, sizeof(MEMORY_BASIC_INFORMATION));
+  pmbiBuffer->BaseAddress = lpvAddress;
+  pmbiBuffer->RegionSize  = cbRangeSize;
+  if(dAttr & PAG_READ && !(dAttr & PAG_WRITE))
+        pmbiBuffer->Protect |= PAGE_READONLY;
+  if(dAttr & PAG_WRITE)
+        pmbiBuffer->Protect |= PAGE_READWRITE;
+
+  if(dAttr & (PAG_WRITE | PAG_EXECUTE))
+        pmbiBuffer->Protect |= PAGE_EXECUTE_READWRITE;
+  else
+  if(dAttr & PAG_EXECUTE)
+        pmbiBuffer->Protect |= PAGE_EXECUTE_READ;
+
+  if(dAttr & PAG_GUARD)
+        pmbiBuffer->Protect |= PAGE_GUARD;
+
+  if(dAttr & PAG_FREE)
+	pmbiBuffer->State = MEM_FREE;
+  else
+  if(dAttr & PAG_COMMIT)
+	pmbiBuffer->State = MEM_COMMIT;
+  else	pmbiBuffer->State = MEM_RESERVE;
+  
+  if(!(dAttr & PAG_SHARED))
+	pmbiBuffer->Type = MEM_PRIVATE;
+
+  //TODO: This is not correct: AllocationProtect should contain the protection
+  //      flags used in the initial call to VirtualAlloc
+  pmbiBuffer->AllocationProtect = pmbiBuffer->Protect;
+  if(dAttr & PAG_BASE) {
+	pmbiBuffer->AllocationBase = lpvAddress;
+  }
+  else {
+	while(lpvAddress > 0) {
+  		rc = DosQueryMem(lpvAddress, &cbRangeSize, &dAttr);
+  		if(rc) {
+  			dprintf(("VirtualQuery - DosQueryMem %x %x returned %d\n", lpvAddress, cbLength, rc));
+			break;
+  		}
+		if(dAttr & PAG_BASE) {
+			pmbiBuffer->AllocationBase = lpvAddress;
+			break;
+		}
+		lpvAddress = (LPVOID)((ULONG)lpvAddress - PAGE_SIZE);
+	}
+  }
+  return sizeof(MEMORY_BASIC_INFORMATION);
 }
 //******************************************************************************
@@ -307,5 +397,5 @@
                                   LPDWORD pfdwOldProtect)
 {
-  dprintf(("KERNEL32: VirtualProtectEx(%08x,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
+  dprintf(("KERNEL32: VirtualProtectEx(%08x,%08xh,%08xh,%08xh,%08xh) not implemented for different processes.\n",
            hProcess,
            lpvAddress,
@@ -314,5 +404,5 @@
            pfdwOldProtect));
 
-  return (FALSE);
+  return VirtualProtect(lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect);
 }
 
@@ -339,5 +429,5 @@
                                  DWORD   cbLength)
 {
-  dprintf(("KERNEL32: VirtualQueryEx(%08x,%08xh,%08xh,%08xh) not implemented.\n",
+  dprintf(("KERNEL32: VirtualQueryEx(%08x,%08xh,%08xh,%08xh) not implemented for different processes.\n",
            hProcess,
            lpvAddress,
@@ -345,5 +435,5 @@
            cbLength));
 
-  return (0);
-}
-
+  return VirtualQuery(lpvAddress, pmbiBuffer, cbLength);
+}
+
Index: trunk/src/kernel32/virtual.cpp
===================================================================
--- trunk/src/kernel32/virtual.cpp	(revision 656)
+++ trunk/src/kernel32/virtual.cpp	(revision 657)
@@ -1,13 +1,10 @@
-/* $Id: virtual.cpp,v 1.1 1999-08-21 16:30:31 sandervl Exp $ */
+/* $Id: virtual.cpp,v 1.2 1999-08-24 12:23:25 sandervl Exp $ */
 
 /*
  * Win32 virtual memory functions
  *
- * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl) (OS/2 Port)
- *
- * NOTE: Quick 'n dirty implementation (read entire file in memory)
- *       Not tested, nor complete (write mapping & protection)
- *
- * Based on Wine code (memory\virtual.c):
+ * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ * Parts (VIRTUAL_MapFileA/W) based on Wine code (memory\virtual.c):
  *
  * Copyright 1997 Alexandre Julliard
@@ -22,5 +19,5 @@
 #include <win\virtual.h>
 #include <heapstring.h>
-
+#include "mmap.h"
 
 /***********************************************************************
@@ -43,11 +40,20 @@
  HANDLE dupHandle;
 
-     if(DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(),
+   if((hFile == -1 && size_low == 0) || size_high ||
+       protect & (PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|SEC_COMMIT|SEC_IMAGE|SEC_RESERVE|SEC_NOCACHE) ||
+       ((protect & SEC_COMMIT) && (protect & SEC_RESERVE))) 
+   {
+
+	dprintf(("CreateFileMappingA: invalid parameter (combination)!"));
+	SetLastError(ERROR_INVALID_PARAMETER);
+	return 0;	
+   }
+   if(DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(),
                         &dupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE) 
-     {
-		dprintf(("CreateFileMappingA: DuplicateHandle failed!"));
-		return 0;
-     }
-     return 	dupHandle;
+   {
+	dprintf(("CreateFileMappingA: DuplicateHandle failed!"));
+	return 0;
+   }
+   return dupHandle;
 }
 
@@ -239,6 +245,6 @@
     LPVOID ptr = NULL;
 
-    hFile = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ, NULL, 
-                           OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
+    hFile = CreateFileA(name, GENERIC_READ, FILE_SHARE_READ, NULL, 
+                        OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
     if (hFile != INVALID_HANDLE_VALUE)
     {
Index: trunk/src/kernel32/vmutex.cpp
===================================================================
--- trunk/src/kernel32/vmutex.cpp	(revision 656)
+++ trunk/src/kernel32/vmutex.cpp	(revision 657)
@@ -1,13 +1,11 @@
-/* $Id: vmutex.cpp,v 1.4 1999-06-19 10:54:43 sandervl Exp $ */
+/* $Id: vmutex.cpp,v 1.5 1999-08-24 12:23:25 sandervl Exp $ */
 
-/*
- *
- * Project Odin Software License can be found in LICENSE.TXT
- *
- */
 /*
  * Mutex class
  *
  * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
  *
  */
@@ -20,5 +18,5 @@
 /******************************************************************************/
 /******************************************************************************/
-_Export VMutex::VMutex() : waiting(0)
+VMutex::VMutex() : waiting(0)
 {
  APIRET rc;
@@ -32,5 +30,5 @@
 /******************************************************************************/
 /******************************************************************************/
-_Export VMutex::~VMutex()
+VMutex::~VMutex()
 {
  int i;
@@ -45,5 +43,5 @@
 /******************************************************************************/
 /******************************************************************************/
-void _Export VMutex::enter(ULONG timeout)
+void VMutex::enter(ULONG timeout)
 {
   if(sem_handle) {
@@ -55,5 +53,5 @@
 /******************************************************************************/
 /******************************************************************************/
-void _Export VMutex::leave()
+void VMutex::leave()
 {
   DosReleaseMutexSem(sem_handle);
