diff -urN wine-20021031/files/file.c wine-20021031-patched/files/file.c
--- wine-20021031/files/file.c	Fri Oct 25 06:32:11 2002
+++ wine-20021031-patched/files/file.c	Tue Nov 12 21:44:01 2002
@@ -18,6 +18,8 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
+ * 10.11.2002 HKo
+ *	- Read-ahead buffered ReadFile
  * TODO:
  *    Fix the CopyFileEx methods to implement the "extended" functionality.
  *    Right now, they simply call the CopyFile method.
@@ -89,6 +91,15 @@
 
 mode_t FILE_umask;
 
+/* Buffers and pointers for buffered ReadFile */
+#define RFbufsize 0x200
+#define RFBuffers 4
+static HANDLE hRFBufferedFile[RFBuffers+1]={0,0,0,0,0};
+static char RFBuf[RFBuffers][RFbufsize];
+static WORD RFBufPtr[RFBuffers];
+static WORD RFBufEnd[RFBuffers];
+
+
 extern HANDLE WINAPI FILE_SmbOpen(LPCSTR name);
 
 /***********************************************************************
@@ -421,7 +432,7 @@
                         DWORD attributes, HANDLE template, BOOL fail_read_only,
                         UINT drive_type )
 {
-    unsigned int err;
+    unsigned int err,i;
     HANDLE ret;
 
     for (;;)
@@ -468,6 +479,12 @@
         }
 
         if (!ret) WARN("Unable to create file '%s' (GLE %ld)\n", filename, GetLastError());
+	for (i=0; i<RFBuffers; i++)
+	if (ret==hRFBufferedFile[i])
+	{
+	    //RFBufPtr[i]=RFBufEnd[i]=0;
+	    hRFBufferedFile[i]=0;
+	}
         return ret;
     }
 }
@@ -1514,6 +1531,7 @@
  */
 HFILE16 WINAPI _lclose16( HFILE16 hFile )
 {
+int i;
     if ((hFile >= DOS_TABLE_SIZE) || !dos_handles[hFile])
     {
         SetLastError( ERROR_INVALID_HANDLE );
@@ -1521,6 +1539,13 @@
     }
     TRACE("%d (handle32=%d)\n", hFile, dos_handles[hFile] );
     CloseHandle( dos_handles[hFile] );
+    for (i=0; i<RFBuffers; i++)
+    if (dos_handles[hFile]==hRFBufferedFile[i])
+    {
+    //RFBufPtr[i]=RFBufEnd[i]=0;
+        hRFBufferedFile[i]=0;
+    }
+
     dos_handles[hFile] = 0;
     return 0;
 }
@@ -1531,7 +1556,14 @@
  */
 HFILE WINAPI _lclose( HFILE hFile )
 {
+int i;
     TRACE("handle %d\n", hFile );
+    for (i=0; i<RFBuffers; i++)
+    if ((HANDLE)hFile==hRFBufferedFile[i])
+    {
+    //RFBufPtr[i]=RFBufEnd[i]=0;
+        hRFBufferedFile[i]=0;
+    }
     return CloseHandle( (HANDLE)hFile ) ? 0 : HFILE_ERROR;
 }
 
@@ -1774,9 +1806,10 @@
 }
 
 /***********************************************************************
- *              ReadFile                (KERNEL32.@)
+ *              ubReadFile                (KERNEL32.@)
+ *		unbuffered ReadFile
  */
-BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
+BOOL ubReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
                         LPDWORD bytesRead, LPOVERLAPPED overlapped )
 {
     int unix_handle, result, flags;
@@ -1875,6 +1908,104 @@
     return TRUE;
 }
 
+//Prototype for ubSetFilePointer needed for buffered ReadFile
+DWORD ubSetFilePointer( HANDLE hFile, LONG distance, LONG *highword,
+                             DWORD method );
+
+/***********************************************************************
+ *              ReadFile                (KERNEL32.@)
+ */
+
+BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
+                        LPDWORD bytesRead, LPOVERLAPPED overlapped )
+{
+
+DWORD BufRead;
+int iBufferID;
+	//return ubReadFile(hFile, buffer, bytesToRead, bytesRead, overlapped);
+	TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToRead,
+          bytesRead, overlapped );
+	if (bytesRead) *bytesRead = 0;  /* Do this before anything else */
+	for (iBufferID=0; iBufferID<RFBuffers; iBufferID++)
+	{
+	    	if (hFile==hRFBufferedFile[iBufferID])
+		break;
+	}
+	while (bytesToRead)
+	{
+	    	if (hFile==hRFBufferedFile[iBufferID])
+		{
+			if (RFBufPtr[iBufferID] == RFBufEnd[iBufferID])
+			{
+			        TRACE("RF Fill buffer %p\n",&RFBuf);
+				RFBufPtr[iBufferID]=0;
+				if (!ubReadFile(hFile, &RFBuf[iBufferID], RFbufsize, &BufRead, NULL)) return FALSE;
+				RFBufEnd[iBufferID]=(WORD)BufRead;
+				if (RFBufEnd[iBufferID]==0) return TRUE;
+			}
+			if ((RFBufEnd[iBufferID]-RFBufPtr[iBufferID])>=bytesToRead)
+			{
+			        TRACE("RF Use buffer %p <- %p %ld bytes\n",buffer,&RFBuf[iBufferID][RFBufPtr[iBufferID]],bytesToRead);
+				memcpy(buffer,&RFBuf[iBufferID][RFBufPtr[iBufferID]],bytesToRead);
+				RFBufPtr[iBufferID] += bytesToRead;
+				if (bytesRead) *bytesRead += bytesToRead;
+				//bytesToRead=0;
+				return TRUE;
+			}
+			else
+			{
+			        TRACE("RF Use buffer to the end\n");
+				memcpy(buffer,&RFBuf[iBufferID][RFBufPtr[iBufferID]],RFBufEnd[iBufferID]-RFBufPtr[iBufferID]);
+				if (bytesRead) *bytesRead += (RFBufEnd[iBufferID]-RFBufPtr[iBufferID]);
+				bytesToRead-=(RFBufEnd[iBufferID]-RFBufPtr[iBufferID]);
+				buffer+=(RFBufEnd[iBufferID]-RFBufPtr[iBufferID]);
+				RFBufPtr[iBufferID] = RFBufEnd[iBufferID];
+				hRFBufferedFile[iBufferID]=0;
+				if (bytesToRead)
+				{
+					if (ubReadFile(hFile, buffer, bytesToRead, &BufRead, NULL))
+					{
+						if (bytesRead) *bytesRead += BufRead;
+						return TRUE;
+					}
+					else
+						return FALSE;
+				}
+				else
+					return TRUE;
+			}
+		}
+		else
+		{
+			if ((bytesToRead>=RFbufsize)||overlapped)
+			{
+			        TRACE("RF NON_BUFFERED\n");
+				return ubReadFile(hFile, buffer, bytesToRead, bytesRead, overlapped);
+			}
+			else
+			{
+				for (iBufferID=0; iBufferID<RFBuffers; iBufferID++)
+				{
+	    				if (hRFBufferedFile[iBufferID]==0)
+					break;
+				}
+				if (iBufferID>=RFBuffers)
+				{
+				        TRACE("RF NO FREE BUFFERS\n");
+					return ubReadFile(hFile, buffer, bytesToRead, bytesRead, overlapped);
+				}
+				//if (hRFBufferedFile)
+				//{ // invalidate buffer
+				//    ubSetFilePointer(hRFBufferedFile, (long int)RFBufPtr-RFBufEnd, NULL,FILE_CURRENT);
+				//}
+				hRFBufferedFile[iBufferID]=hFile;
+			        TRACE("RF Assign buffer to %d\n",hRFBufferedFile[iBufferID]);
+				RFBufPtr[iBufferID]=RFBufEnd[iBufferID]=0;
+			}
+		}
+	}
+	return TRUE;
+}
 
 /***********************************************************************
  *             FILE_AsyncWriteService      (INTERNAL)
@@ -2177,7 +2308,7 @@
 /***********************************************************************
  *           SetFilePointer   (KERNEL32.@)
  */
-DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword,
+DWORD ubSetFilePointer( HANDLE hFile, LONG distance, LONG *highword,
                              DWORD method )
 {
     DWORD ret = INVALID_SET_FILE_POINTER;
@@ -2203,6 +2334,23 @@
     return ret;
 }
 
+DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword,
+                             DWORD method )
+{
+int i;
+	for (i=0; i<RFBuffers; i++)
+	if (hRFBufferedFile[i]==hFile)
+	{ // invalidate buffer
+	    TRACE("RF Invalidate buffer\n");
+	    if (method==FILE_CURRENT)
+	    {
+	    	distance-=RFBufEnd[i]-RFBufPtr[i];
+            }
+	    hRFBufferedFile[i]=0;
+	    break;
+	}
+	return ubSetFilePointer(hFile, distance, highword,method);
+}
 
 /***********************************************************************
  *           _llseek   (KERNEL.84)
diff -urN wine-20021031/files/smb.h wine-20021031-patched/files/smb.h
--- wine-20021031/files/smb.h	Tue Aug 27 04:13:59 2002
+++ wine-20021031-patched/files/smb.h	Thu Nov  7 01:13:54 2002
@@ -99,6 +99,8 @@
 extern HANDLE WINAPI SMB_CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing,
                               LPSECURITY_ATTRIBUTES sa, DWORD creation,
                               DWORD attributes, HANDLE template );
+extern BOOL SMB_GetSmbInfo(HANDLE hFile, USHORT *tree_id, USHORT *user_id, USHORT *dialect, USHORT *file_id, LPDWORD offset);
+extern BOOL SMB_SetOffset(HANDLE hFile, DWORD offset);
 
 typedef struct tagSMB_DIR
 {
