PATCH: ole storage & NFS brokeness

Marcus Meissner marcus at jet.franken.de
Sun Jun 3 04:05:19 CDT 2001


Hi,

The NFS client on 2.4 is hopelessly broken in regard to the mmap() read/write
patterns our OLE32 Storage bigblockfile implementation is throwing at it.

Meaning, any write to a structured storage will corrupt it and crash WINE.

And the maintainer even admits it!

This changes the implemenation to use ReadFile and WriteFile, which
works way better.

... I can now debug Internet Explorer 5 setup better :/

Ciao, Marcus

Changelog:
	changed the bigblock implementation to use read/write instead of
	mmap, which is broken on Linux 2.4 NFS.

Index: stg_bigblockfile.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/stg_bigblockfile.c,v
retrieving revision 1.5
diff -u -r1.5 stg_bigblockfile.c
--- stg_bigblockfile.c	2000/11/27 23:54:27	1.5
+++ stg_bigblockfile.c	2001/06/03 10:01:52
@@ -207,17 +207,18 @@
 
   /* create the file mapping object
    */
+#ifdef NFS_DOESNT_SUCK
   This->hfilemap = CreateFileMappingA(This->hfile,
                                       NULL,
                                       This->flProtect,
                                       0, 0,
                                       NULL);
-
   if (!This->hfilemap)
   {
     CloseHandle(This->hfile);
     return FALSE;
   }
+#endif
 
   This->filesize.s.LowPart = GetFileSize(This->hfile,
 					 &This->filesize.s.HighPart);
@@ -278,7 +279,9 @@
 
   if (This->fileBased)
   {
+#ifdef NFS_DOESNT_SUCK
     CloseHandle(This->hfilemap);
+#endif
     CloseHandle(This->hfile);
   }
   else
@@ -398,14 +401,13 @@
   
   if (This->fileBased)
   {
+#ifdef NFS_DOESNT_SUCK
     char buf[10];
-
     /*
      * close file-mapping object, must be done before call to SetEndFile
      */
     CloseHandle(This->hfilemap);
     This->hfilemap = 0;
-
     /*
      * BEGIN HACK
      * This fixes a bug when saving through smbfs.
@@ -425,12 +427,14 @@
      * END HACK 
      */
 
+#endif
     /*
      * set the new end of file
      */
     SetFilePointer(This->hfile, newSize.s.LowPart, NULL, FILE_BEGIN);
     SetEndOfFile(This->hfile);
   
+#ifdef NFS_DOESNT_SUCK
     /*
      * re-create the file mapping object
      */
@@ -439,6 +443,7 @@
                                         This->flProtect,
                                         0, 0, 
                                         NULL);
+#endif
   }
   else
   {
@@ -642,7 +647,7 @@
 
     if (This->fileBased)
     {
-	DWORD numBytesToMap;
+	DWORD numBytesToMap, mappedbytes;
 	DWORD desired_access;
 
 	if (lowoffset + PAGE_SIZE > This->filesize.s.LowPart)
@@ -655,8 +660,25 @@
 	else
 	    desired_access = FILE_MAP_WRITE;
 
+#ifdef NFS_DOES_NOT_SUCK
 	page->lpBytes = MapViewOfFile(This->hfilemap, desired_access, 0,
 				      lowoffset, numBytesToMap);
+#else
+	page->lpBytes = HeapAlloc(GetProcessHeap(),0,PAGE_SIZE);
+	SetFilePointer(This->hfile,lowoffset,NULL,FILE_BEGIN);
+	if (!ReadFile(This->hfile,page->lpBytes,numBytesToMap,&mappedbytes,NULL)) {
+	    ERR("Failed reading from file?\n");
+	    HeapFree(GetProcessHeap(),0,page->lpBytes);
+	    page->lpBytes = NULL;
+	    return FALSE;
+	}
+	if (numBytesToMap != mappedbytes) {
+	    ERR("read bytes is %ld vs %ld?\n",mappedbytes,numBytesToMap);
+	    HeapFree(GetProcessHeap(),0,page->lpBytes);
+	    page->lpBytes = NULL;
+	    return FALSE;
+	}
+#endif
     }
     else
     {
@@ -697,9 +719,28 @@
     if (page->refcnt > 0)
 	ERR("unmapping inuse page %p\n", page->lpBytes);
 
-    if (This->fileBased && page->lpBytes)
+    if (This->fileBased && page->lpBytes) {
+#ifdef NFS_DOESNT_SUCK
 	UnmapViewOfFile(page->lpBytes);
-
+#else
+	if (This->flProtect != PAGE_READONLY) {
+	    DWORD written,bytesToWrite;
+	    DWORD lowoffset = PAGE_SIZE * page->page_index;
+
+	    if (lowoffset + PAGE_SIZE > This->filesize.s.LowPart)
+		bytesToWrite = This->filesize.s.LowPart - lowoffset;
+	    else
+		bytesToWrite = PAGE_SIZE;
+	    SetFilePointer(This->hfile,lowoffset,NULL,FILE_BEGIN);
+	    if (!WriteFile(This->hfile,page->lpBytes,bytesToWrite,&written,NULL) ||
+		bytesToWrite != written
+	    ) {
+		ERR("Writeout of %ld bytes failed!\n",written);
+	    }
+	}
+	HeapFree(GetProcessHeap(),0,page->lpBytes);
+#endif
+    }
     page->lpBytes = NULL;
 }
 




More information about the wine-patches mailing list