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