Commit 2cb4361c authored by Alexandre Julliard's avatar Alexandre Julliard

kernel32: Reimplemented SetFilePointerEx on top of ntdll functions.

parent 83a66a98
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "thread.h" #include "thread.h"
#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(file); WINE_DEFAULT_DEBUG_CHANNEL(file);
...@@ -940,44 +939,48 @@ DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword, DWORD ...@@ -940,44 +939,48 @@ DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword, DWORD
BOOL WINAPI SetFilePointerEx( HANDLE hFile, LARGE_INTEGER distance, BOOL WINAPI SetFilePointerEx( HANDLE hFile, LARGE_INTEGER distance,
LARGE_INTEGER *newpos, DWORD method ) LARGE_INTEGER *newpos, DWORD method )
{ {
static const int whence[3] = { SEEK_SET, SEEK_CUR, SEEK_END }; LONGLONG pos;
BOOL ret = FALSE; IO_STATUS_BLOCK io;
NTSTATUS status; FILE_POSITION_INFORMATION info;
int fd;
TRACE("handle %p offset %s newpos %p origin %d\n",
hFile, wine_dbgstr_longlong(distance.QuadPart), newpos, method );
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 ); 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; SetLastError( ERROR_NEGATIVE_SEEK );
return FALSE;
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 );
} }
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;
} }
/*********************************************************************** /***********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment