LockDIBSection problem

Rein Klazes wijn at wanadoo.nl
Sun May 8 14:43:22 CDT 2005


On 06 May 2005 16:01:06 +0200, you wrote:

> Rein Klazes <wijn at wanadoo.nl> writes:
> 
> > I managed to fixed it in two ways:
> > 
> > 1. put a 
> >     X11DRV_CoerceDIBSection( physDevDst, DIB_Status_InSync, FALSE );
> > at the end of X11DRV_BitBlt. This probably defeats the whole purpose of
> > these protections so:
> > 
> > 2. Add a "IsBadReadPtr( buffer, bytesToWrite)" in the top of WriteFile
> > to force an exception and everything works.
> > 
> > Would that be an acceptable fix?
> 
> We don't want that at the top of WriteFile, but it could be OK to add
> special handling of the INVALID_USER_BUFFER error, with a big FIXME
> comment...

Special handling: try again after an IsBadReadPtr call.

Changelog:

dlls/kernel	: file.c

Work around a problem where WriteFile is asked to write memory protected
by DIBSection code.

Rein.
-------------- next part --------------
--- wine/dlls/kernel/file.c	2005-04-01 13:31:42.000000000 +0200
+++ mywine/dlls/kernel/file.c	2005-05-08 19:43:38.000000000 +0200
@@ -431,6 +431,7 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPC
     NTSTATUS status;
     IO_STATUS_BLOCK iosb;
     PIO_STATUS_BLOCK piosb = &iosb;
+    int FIUBflag = 0; /* Failed Invalid User Buffer flag */
 
     TRACE("%p %p %ld %p %p\n", hFile, buffer, bytesToWrite, bytesWritten, overlapped );
 
@@ -448,8 +449,18 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPC
     piosb->u.Status = STATUS_PENDING;
     piosb->Information = 0;
 
-    status = NtWriteFile(hFile, hEvent, NULL, NULL, piosb,
-                         buffer, bytesToWrite, poffset, NULL);
+    while(1)
+    {
+        status = NtWriteFile(hFile, hEvent, NULL, NULL, piosb,
+                             buffer, bytesToWrite, poffset, NULL);
+        if( status != STATUS_INVALID_USER_BUFFER || FIUBflag)
+            break;
+        FIUBflag = 1;
+        /* NtWriteFile does not always cause page faults, generate them now */
+        IsBadReadPtr( buffer, bytesToWrite);
+    }
+    if( FIUBflag && !status) /* failed first, but succeeded after access */
+        FIXME("Could not access memory (%p,%ld) at first, now OK. Protected by DIBSection code?\n", buffer, bytesToWrite);
 
     if (status != STATUS_PENDING && bytesWritten)
         *bytesWritten = piosb->Information;


More information about the wine-devel mailing list