Handle the set_file_pointer request on the client side.

This commit is contained in:
Alexandre Julliard 2004-04-07 22:02:09 +00:00
parent 2d0413012f
commit db4517010b
7 changed files with 45 additions and 118 deletions

View File

@ -858,23 +858,21 @@ NTSTATUS WINAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
break; break;
case FilePositionInformation: case FilePositionInformation:
{ {
int fd;
FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)answer; 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; off_t res = lseek( fd, 0, SEEK_CUR );
req->low = 0; if (res == (off_t)-1) status = FILE_GetNtStatus();
req->high = 0; else
req->whence = SEEK_CUR;
if (!(status = wine_server_call( req )))
{ {
fpi->CurrentByteOffset.u.HighPart = reply->new_high; fpi->CurrentByteOffset.QuadPart = res;
fpi->CurrentByteOffset.u.LowPart = reply->new_low;
used = sizeof(*fpi); used = sizeof(*fpi);
} }
wine_server_release_fd( hFile, fd );
} }
SERVER_END_REQ;
} }
break; break;
default: default:
@ -920,18 +918,15 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
case FilePositionInformation: case FilePositionInformation:
if (len >= sizeof(FILE_POSITION_INFORMATION)) if (len >= sizeof(FILE_POSITION_INFORMATION))
{ {
int fd;
FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)ptr; 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; if (lseek( fd, fpi->CurrentByteOffset.QuadPart, SEEK_SET ) == (off_t)-1)
req->low = fpi->CurrentByteOffset.u.LowPart; status = FILE_GetNtStatus();
req->high = fpi->CurrentByteOffset.u.HighPart; wine_server_release_fd( hFile, fd );
req->whence = SEEK_SET;
status = wine_server_call( req );
} }
SERVER_END_REQ;
status = STATUS_SUCCESS;
} }
break; break;
default: default:

View File

@ -1145,26 +1145,44 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword, DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword,
DWORD method ) DWORD method )
{ {
static const int whence[3] = { SEEK_SET, SEEK_CUR, SEEK_END };
DWORD ret = INVALID_SET_FILE_POINTER; DWORD ret = INVALID_SET_FILE_POINTER;
NTSTATUS status;
int fd;
TRACE("handle %p offset %ld high %ld origin %ld\n", TRACE("handle %p offset %ld high %ld origin %ld\n",
hFile, distance, highword?*highword:0, method ); hFile, distance, highword?*highword:0, method );
SERVER_START_REQ( set_file_pointer ) if (method > FILE_END)
{ {
req->handle = hFile; SetLastError( ERROR_INVALID_PARAMETER );
req->low = distance; return ret;
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 ))
{
ret = reply->new_low;
if (highword) *highword = reply->new_high;
}
} }
SERVER_END_REQ;
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)
{
/* 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 );
}
wine_server_release_fd( hFile, fd );
}
else SetLastError( RtlNtStatusToDosError(status) );
return ret; return ret;
} }

View File

@ -804,22 +804,6 @@ enum fd_type
#define FD_FLAG_SEND_SHUTDOWN 0x08 #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 struct truncate_file_request
{ {
@ -3179,7 +3163,6 @@ enum request
REQ_create_file, REQ_create_file,
REQ_alloc_file_handle, REQ_alloc_file_handle,
REQ_get_handle_fd, REQ_get_handle_fd,
REQ_set_file_pointer,
REQ_truncate_file, REQ_truncate_file,
REQ_flush_file, REQ_flush_file,
REQ_get_file_info, REQ_get_file_info,
@ -3365,7 +3348,6 @@ union generic_request
struct create_file_request create_file_request; struct create_file_request create_file_request;
struct alloc_file_handle_request alloc_file_handle_request; struct alloc_file_handle_request alloc_file_handle_request;
struct get_handle_fd_request get_handle_fd_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 truncate_file_request truncate_file_request;
struct flush_file_request flush_file_request; struct flush_file_request flush_file_request;
struct get_file_info_request get_file_info_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 create_file_reply create_file_reply;
struct alloc_file_handle_reply alloc_file_handle_reply; struct alloc_file_handle_reply alloc_file_handle_reply;
struct get_handle_fd_reply get_handle_fd_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 truncate_file_reply truncate_file_reply;
struct flush_file_reply flush_file_reply; struct flush_file_reply flush_file_reply;
struct get_file_info_reply get_file_info_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; 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 */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -426,33 +426,6 @@ int get_file_unix_fd( struct file *file )
return get_unix_fd( file->fd ); 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 */ /* extend a file beyond the current end of file */
static int extend_file( struct file *file, off_t size ) 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 */ /* truncate (or extend) a file */
DECL_HANDLER(truncate_file) DECL_HANDLER(truncate_file)
{ {

View File

@ -614,17 +614,6 @@ enum fd_type
#define FD_FLAG_RECV_SHUTDOWN 0x04 #define FD_FLAG_RECV_SHUTDOWN 0x04
#define FD_FLAG_SEND_SHUTDOWN 0x08 #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 */ /* Truncate (or extend) a file */
@REQ(truncate_file) @REQ(truncate_file)

View File

@ -142,7 +142,6 @@ DECL_HANDLER(open_semaphore);
DECL_HANDLER(create_file); DECL_HANDLER(create_file);
DECL_HANDLER(alloc_file_handle); DECL_HANDLER(alloc_file_handle);
DECL_HANDLER(get_handle_fd); DECL_HANDLER(get_handle_fd);
DECL_HANDLER(set_file_pointer);
DECL_HANDLER(truncate_file); DECL_HANDLER(truncate_file);
DECL_HANDLER(flush_file); DECL_HANDLER(flush_file);
DECL_HANDLER(get_file_info); 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_create_file,
(req_handler)req_alloc_file_handle, (req_handler)req_alloc_file_handle,
(req_handler)req_get_handle_fd, (req_handler)req_get_handle_fd,
(req_handler)req_set_file_pointer,
(req_handler)req_truncate_file, (req_handler)req_truncate_file,
(req_handler)req_flush_file, (req_handler)req_flush_file,
(req_handler)req_get_file_info, (req_handler)req_get_file_info,

View File

@ -871,20 +871,6 @@ static void dump_get_handle_fd_reply( const struct get_handle_fd_reply *req )
fprintf( stderr, " flags=%d", req->flags ); 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 ) static void dump_truncate_file_request( const struct truncate_file_request *req )
{ {
fprintf( stderr, " handle=%p", req->handle ); 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_create_file_request,
(dump_func)dump_alloc_file_handle_request, (dump_func)dump_alloc_file_handle_request,
(dump_func)dump_get_handle_fd_request, (dump_func)dump_get_handle_fd_request,
(dump_func)dump_set_file_pointer_request,
(dump_func)dump_truncate_file_request, (dump_func)dump_truncate_file_request,
(dump_func)dump_flush_file_request, (dump_func)dump_flush_file_request,
(dump_func)dump_get_file_info_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_create_file_reply,
(dump_func)dump_alloc_file_handle_reply, (dump_func)dump_alloc_file_handle_reply,
(dump_func)dump_get_handle_fd_reply, (dump_func)dump_get_handle_fd_reply,
(dump_func)dump_set_file_pointer_reply,
(dump_func)0, (dump_func)0,
(dump_func)dump_flush_file_reply, (dump_func)dump_flush_file_reply,
(dump_func)dump_get_file_info_reply, (dump_func)dump_get_file_info_reply,
@ -2961,7 +2945,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_file", "create_file",
"alloc_file_handle", "alloc_file_handle",
"get_handle_fd", "get_handle_fd",
"set_file_pointer",
"truncate_file", "truncate_file",
"flush_file", "flush_file",
"get_file_info", "get_file_info",