Handle the set_file_pointer request on the client side.
This commit is contained in:
parent
2d0413012f
commit
db4517010b
|
@ -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:
|
||||||
|
|
44
files/file.c
44
files/file.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue