Commit db451701 authored by Alexandre Julliard's avatar Alexandre Julliard

Handle the set_file_pointer request on the client side.

parent 2d041301
......@@ -858,23 +858,21 @@ NTSTATUS WINAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
break;
case FilePositionInformation:
{
int fd;
FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)answer;
if (sizeof(answer) < sizeof(*fpi)) goto too_small;
SERVER_START_REQ( set_file_pointer )
if (sizeof(answer) < sizeof(*fpi)) goto too_small;
if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
{
req->handle = hFile;
req->low = 0;
req->high = 0;
req->whence = SEEK_CUR;
if (!(status = wine_server_call( req )))
off_t res = lseek( fd, 0, SEEK_CUR );
if (res == (off_t)-1) status = FILE_GetNtStatus();
else
{
fpi->CurrentByteOffset.u.HighPart = reply->new_high;
fpi->CurrentByteOffset.u.LowPart = reply->new_low;
fpi->CurrentByteOffset.QuadPart = res;
used = sizeof(*fpi);
}
wine_server_release_fd( hFile, fd );
}
SERVER_END_REQ;
}
break;
default:
......@@ -920,18 +918,15 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
case FilePositionInformation:
if (len >= sizeof(FILE_POSITION_INFORMATION))
{
int fd;
FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)ptr;
SERVER_START_REQ( set_file_pointer )
if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
{
req->handle = hFile;
req->low = fpi->CurrentByteOffset.u.LowPart;
req->high = fpi->CurrentByteOffset.u.HighPart;
req->whence = SEEK_SET;
status = wine_server_call( req );
if (lseek( fd, fpi->CurrentByteOffset.QuadPart, SEEK_SET ) == (off_t)-1)
status = FILE_GetNtStatus();
wine_server_release_fd( hFile, fd );
}
SERVER_END_REQ;
status = STATUS_SUCCESS;
}
break;
default:
......
......@@ -1145,26 +1145,44 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword,
DWORD method )
{
static const int whence[3] = { SEEK_SET, SEEK_CUR, SEEK_END };
DWORD ret = INVALID_SET_FILE_POINTER;
NTSTATUS status;
int fd;
TRACE("handle %p offset %ld high %ld origin %ld\n",
hFile, distance, highword?*highword:0, method );
SERVER_START_REQ( set_file_pointer )
if (method > FILE_END)
{
req->handle = hFile;
req->low = distance;
req->high = highword ? *highword : (distance >= 0) ? 0 : -1;
/* FIXME: assumes 1:1 mapping between Windows and Unix seek constants */
req->whence = method;
SetLastError( 0 );
if (!wine_server_call_err( req ))
SetLastError( ERROR_INVALID_PARAMETER );
return ret;
}
if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
{
off_t pos, res;
if (highword) pos = ((off_t)*highword << 32) | (ULONG)distance;
else pos = (off_t)distance;
if ((res = lseek( fd, pos, whence[method] )) == (off_t)-1)
{
ret = reply->new_low;
if (highword) *highword = reply->new_high;
/* 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 = (DWORD)res;
if (highword) *highword = (res >> 32);
if (ret == INVALID_SET_FILE_POINTER) SetLastError( 0 );
}
SERVER_END_REQ;
wine_server_release_fd( hFile, fd );
}
else SetLastError( RtlNtStatusToDosError(status) );
return ret;
}
......
......@@ -804,22 +804,6 @@ enum fd_type
#define FD_FLAG_SEND_SHUTDOWN 0x08
struct set_file_pointer_request
{
struct request_header __header;
obj_handle_t handle;
int low;
int high;
int whence;
};
struct set_file_pointer_reply
{
struct reply_header __header;
int new_low;
int new_high;
};
struct truncate_file_request
{
......@@ -3179,7 +3163,6 @@ enum request
REQ_create_file,
REQ_alloc_file_handle,
REQ_get_handle_fd,
REQ_set_file_pointer,
REQ_truncate_file,
REQ_flush_file,
REQ_get_file_info,
......@@ -3365,7 +3348,6 @@ union generic_request
struct create_file_request create_file_request;
struct alloc_file_handle_request alloc_file_handle_request;
struct get_handle_fd_request get_handle_fd_request;
struct set_file_pointer_request set_file_pointer_request;
struct truncate_file_request truncate_file_request;
struct flush_file_request flush_file_request;
struct get_file_info_request get_file_info_request;
......@@ -3549,7 +3531,6 @@ union generic_reply
struct create_file_reply create_file_reply;
struct alloc_file_handle_reply alloc_file_handle_reply;
struct get_handle_fd_reply get_handle_fd_reply;
struct set_file_pointer_reply set_file_pointer_reply;
struct truncate_file_reply truncate_file_reply;
struct flush_file_reply flush_file_reply;
struct get_file_info_reply get_file_info_reply;
......@@ -3691,6 +3672,6 @@ union generic_reply
struct set_global_windows_reply set_global_windows_reply;
};
#define SERVER_PROTOCOL_VERSION 137
#define SERVER_PROTOCOL_VERSION 138
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -426,33 +426,6 @@ int get_file_unix_fd( struct file *file )
return get_unix_fd( file->fd );
}
static int set_file_pointer( obj_handle_t handle, unsigned int *low, int *high, int whence )
{
struct file *file;
off_t result,xto;
xto = *low+((off_t)*high<<32);
if (!(file = get_file_obj( current->process, handle, 0 )))
return 0;
if ((result = lseek( get_file_unix_fd(file), xto, whence))==-1)
{
/* Check for seek before start of file */
/* also check EPERM due to SuSE7 2.2.16 lseek() EPERM kernel bug */
if (((errno == EINVAL) || (errno == EPERM))
&& (whence != SEEK_SET) && (*high < 0))
set_win32_error( ERROR_NEGATIVE_SEEK );
else
file_set_error();
release_object( file );
return 0;
}
*low = result & 0xffffffff;
*high = result >> 32;
release_object( file );
return 1;
}
/* extend a file beyond the current end of file */
static int extend_file( struct file *file, off_t size )
{
......@@ -542,16 +515,6 @@ DECL_HANDLER(alloc_file_handle)
}
}
/* set a file current position */
DECL_HANDLER(set_file_pointer)
{
int high = req->high;
int low = req->low;
set_file_pointer( req->handle, &low, &high, req->whence );
reply->new_low = low;
reply->new_high = high;
}
/* truncate (or extend) a file */
DECL_HANDLER(truncate_file)
{
......
......@@ -614,17 +614,6 @@ enum fd_type
#define FD_FLAG_RECV_SHUTDOWN 0x04
#define FD_FLAG_SEND_SHUTDOWN 0x08
/* Set a file current position */
@REQ(set_file_pointer)
obj_handle_t handle; /* handle to the file */
int low; /* position low word */
int high; /* position high word */
int whence; /* whence to seek */
@REPLY
int new_low; /* new position low word */
int new_high; /* new position high word */
@END
/* Truncate (or extend) a file */
@REQ(truncate_file)
......
......@@ -142,7 +142,6 @@ DECL_HANDLER(open_semaphore);
DECL_HANDLER(create_file);
DECL_HANDLER(alloc_file_handle);
DECL_HANDLER(get_handle_fd);
DECL_HANDLER(set_file_pointer);
DECL_HANDLER(truncate_file);
DECL_HANDLER(flush_file);
DECL_HANDLER(get_file_info);
......@@ -327,7 +326,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_create_file,
(req_handler)req_alloc_file_handle,
(req_handler)req_get_handle_fd,
(req_handler)req_set_file_pointer,
(req_handler)req_truncate_file,
(req_handler)req_flush_file,
(req_handler)req_get_file_info,
......
......@@ -871,20 +871,6 @@ static void dump_get_handle_fd_reply( const struct get_handle_fd_reply *req )
fprintf( stderr, " flags=%d", req->flags );
}
static void dump_set_file_pointer_request( const struct set_file_pointer_request *req )
{
fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " low=%d,", req->low );
fprintf( stderr, " high=%d,", req->high );
fprintf( stderr, " whence=%d", req->whence );
}
static void dump_set_file_pointer_reply( const struct set_file_pointer_reply *req )
{
fprintf( stderr, " new_low=%d,", req->new_low );
fprintf( stderr, " new_high=%d", req->new_high );
}
static void dump_truncate_file_request( const struct truncate_file_request *req )
{
fprintf( stderr, " handle=%p", req->handle );
......@@ -2597,7 +2583,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_file_request,
(dump_func)dump_alloc_file_handle_request,
(dump_func)dump_get_handle_fd_request,
(dump_func)dump_set_file_pointer_request,
(dump_func)dump_truncate_file_request,
(dump_func)dump_flush_file_request,
(dump_func)dump_get_file_info_request,
......@@ -2779,7 +2764,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_file_reply,
(dump_func)dump_alloc_file_handle_reply,
(dump_func)dump_get_handle_fd_reply,
(dump_func)dump_set_file_pointer_reply,
(dump_func)0,
(dump_func)dump_flush_file_reply,
(dump_func)dump_get_file_info_reply,
......@@ -2961,7 +2945,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_file",
"alloc_file_handle",
"get_handle_fd",
"set_file_pointer",
"truncate_file",
"flush_file",
"get_file_info",
......
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