Alexandre Julliard : kernel32: Reimplemented SetFilePointerEx on top of ntdll functions.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Nov 2 05:46:44 CST 2006


Module: wine
Branch: master
Commit: 2cb4361c06669803d4ec057cc96c306b254be230
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2cb4361c06669803d4ec057cc96c306b254be230

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Nov  1 16:12:57 2006 +0100

kernel32: Reimplemented SetFilePointerEx on top of ntdll functions.

---

 dlls/kernel32/file.c |   65 ++++++++++++++++++++++++++-----------------------
 1 files changed, 34 insertions(+), 31 deletions(-)

diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c
index 8f8890d..d0b28d0 100644
--- a/dlls/kernel32/file.c
+++ b/dlls/kernel32/file.c
@@ -47,7 +47,6 @@ #include "excpt.h"
 #include "wine/unicode.h"
 #include "wine/debug.h"
 #include "thread.h"
-#include "wine/server.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(file);
 
@@ -940,44 +939,48 @@ DWORD WINAPI SetFilePointer( HANDLE hFil
 BOOL WINAPI SetFilePointerEx( HANDLE hFile, LARGE_INTEGER distance,
                               LARGE_INTEGER *newpos, DWORD method )
 {
-    static const int whence[3] = { SEEK_SET, SEEK_CUR, SEEK_END };
-    BOOL ret = FALSE;
-    NTSTATUS status;
-    int fd;
-
-    TRACE("handle %p offset %s newpos %p origin %d\n",
-          hFile, wine_dbgstr_longlong(distance.QuadPart), newpos, method );
+    LONGLONG pos;
+    IO_STATUS_BLOCK io;
+    FILE_POSITION_INFORMATION info;
 
-    if (method > FILE_END)
+    switch(method)
     {
+    case FILE_BEGIN:
+        pos = distance.QuadPart;
+        break;
+    case FILE_CURRENT:
+        if (NtQueryInformationFile( hFile, &io, &info, sizeof(info), FilePositionInformation ))
+            goto error;
+        pos = info.CurrentByteOffset.QuadPart + distance.QuadPart;
+        break;
+    case FILE_END:
+        {
+            FILE_END_OF_FILE_INFORMATION eof;
+            if (NtQueryInformationFile( hFile, &io, &eof, sizeof(eof), FileEndOfFileInformation ))
+                goto error;
+            pos = eof.EndOfFile.QuadPart + distance.QuadPart;
+        }
+        break;
+    default:
         SetLastError( ERROR_INVALID_PARAMETER );
-        return ret;
+        return FALSE;
     }
 
-    if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL )))
+    if (pos < 0)
     {
-        off_t pos, res;
-
-        pos = distance.QuadPart;
-        if ((res = lseek( fd, pos, whence[method] )) == (off_t)-1)
-        {
-            /* also check EPERM due to SuSE7 2.2.16 lseek() EPERM kernel bug */
-            if (((errno == EINVAL) || (errno == EPERM)) && (method != FILE_BEGIN) && (pos < 0))
-                SetLastError( ERROR_NEGATIVE_SEEK );
-            else
-                FILE_SetDosError();
-        }
-        else
-        {
-            ret = TRUE;
-            if( newpos )
-                newpos->QuadPart = res;
-        }
-        wine_server_release_fd( hFile, fd );
+        SetLastError( ERROR_NEGATIVE_SEEK );
+        return FALSE;
     }
-    else SetLastError( RtlNtStatusToDosError(status) );
 
-    return ret;
+    info.CurrentByteOffset.QuadPart = pos;
+    if (NtSetInformationFile( hFile, &io, &info, sizeof(info), FilePositionInformation ))
+        goto error;
+    if (newpos) newpos->QuadPart = pos;
+    return TRUE;
+
+error:
+    SetLastError( RtlNtStatusToDosError(io.u.Status) );
+    return FALSE;
 }
 
 /***********************************************************************




More information about the wine-cvs mailing list