Commit ccf4ca82 authored by Alexandre Julliard's avatar Alexandre Julliard

kernel32: Move file handle functions to kernelbase.

parent cbd038f7
...@@ -71,8 +71,6 @@ typedef struct ...@@ -71,8 +71,6 @@ typedef struct
static const UINT max_entry_size = offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[256] ); static const UINT max_entry_size = offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[256] );
static BOOL oem_file_apis;
static const WCHAR wildcardsW[] = { '*','?',0 }; static const WCHAR wildcardsW[] = { '*','?',0 };
static const WCHAR krnl386W[] = {'k','r','n','l','3','8','6','.','e','x','e','1','6',0}; static const WCHAR krnl386W[] = {'k','r','n','l','3','8','6','.','e','x','e','1','6',0};
...@@ -251,7 +249,7 @@ WCHAR *FILE_name_AtoW( LPCSTR name, BOOL alloc ) ...@@ -251,7 +249,7 @@ WCHAR *FILE_name_AtoW( LPCSTR name, BOOL alloc )
RtlInitAnsiString( &str, name ); RtlInitAnsiString( &str, name );
pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString; pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString;
if (oem_file_apis) if (!AreFileApisANSI())
status = RtlOemStringToUnicodeString( pstrW, &str, alloc ); status = RtlOemStringToUnicodeString( pstrW, &str, alloc );
else else
status = RtlAnsiStringToUnicodeString( pstrW, &str, alloc ); status = RtlAnsiStringToUnicodeString( pstrW, &str, alloc );
...@@ -275,7 +273,7 @@ DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen ) ...@@ -275,7 +273,7 @@ DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen )
DWORD ret; DWORD ret;
if (srclen < 0) srclen = strlenW( src ) + 1; if (srclen < 0) srclen = strlenW( src ) + 1;
if (oem_file_apis) if (!AreFileApisANSI())
RtlUnicodeToOemN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) ); RtlUnicodeToOemN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) );
else else
RtlUnicodeToMultiByteN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) ); RtlUnicodeToMultiByteN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) );
...@@ -283,430 +281,6 @@ DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen ) ...@@ -283,430 +281,6 @@ DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen )
} }
/**************************************************************************
* SetFileApisToOEM (KERNEL32.@)
*/
VOID WINAPI SetFileApisToOEM(void)
{
oem_file_apis = TRUE;
}
/**************************************************************************
* SetFileApisToANSI (KERNEL32.@)
*/
VOID WINAPI SetFileApisToANSI(void)
{
oem_file_apis = FALSE;
}
/******************************************************************************
* AreFileApisANSI (KERNEL32.@)
*
* Determines if file functions are using ANSI
*
* RETURNS
* TRUE: Set of file functions is using ANSI code page
* FALSE: Set of file functions is using OEM code page
*/
BOOL WINAPI AreFileApisANSI(void)
{
return !oem_file_apis;
}
/**************************************************************************
* Operations on file handles *
**************************************************************************/
/******************************************************************
* FILE_ReadWriteApc (internal)
*/
static void WINAPI FILE_ReadWriteApc(void* apc_user, PIO_STATUS_BLOCK io_status, ULONG reserved)
{
LPOVERLAPPED_COMPLETION_ROUTINE cr = apc_user;
cr(RtlNtStatusToDosError(io_status->u.Status), io_status->Information, (LPOVERLAPPED)io_status);
}
/***********************************************************************
* ReadFileEx (KERNEL32.@)
*/
BOOL WINAPI ReadFileEx(HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
LPOVERLAPPED overlapped,
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
LARGE_INTEGER offset;
NTSTATUS status;
PIO_STATUS_BLOCK io_status;
TRACE("(hFile=%p, buffer=%p, bytes=%u, ovl=%p, ovl_fn=%p)\n", hFile, buffer, bytesToRead, overlapped, lpCompletionRoutine);
if (!overlapped)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
io_status = (PIO_STATUS_BLOCK)overlapped;
io_status->u.Status = STATUS_PENDING;
io_status->Information = 0;
status = NtReadFile(hFile, NULL, FILE_ReadWriteApc, lpCompletionRoutine,
io_status, buffer, bytesToRead, &offset, NULL);
if (status && status != STATUS_PENDING)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* ReadFileScatter (KERNEL32.@)
*/
BOOL WINAPI ReadFileScatter( HANDLE file, FILE_SEGMENT_ELEMENT *segments, DWORD count,
LPDWORD reserved, LPOVERLAPPED overlapped )
{
PIO_STATUS_BLOCK io_status;
LARGE_INTEGER offset;
void *cvalue = NULL;
NTSTATUS status;
TRACE( "(%p %p %u %p)\n", file, segments, count, overlapped );
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
if (!((ULONG_PTR)overlapped->hEvent & 1)) cvalue = overlapped;
io_status = (PIO_STATUS_BLOCK)overlapped;
io_status->u.Status = STATUS_PENDING;
io_status->Information = 0;
status = NtReadFileScatter( file, overlapped->hEvent, NULL, cvalue, io_status,
segments, count, &offset, NULL );
if (status) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/***********************************************************************
* ReadFile (KERNEL32.@)
*/
BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
LPDWORD bytesRead, LPOVERLAPPED overlapped )
{
LARGE_INTEGER offset;
PLARGE_INTEGER poffset = NULL;
IO_STATUS_BLOCK iosb;
PIO_STATUS_BLOCK io_status = &iosb;
HANDLE hEvent = 0;
NTSTATUS status;
LPVOID cvalue = NULL;
TRACE("%p %p %d %p %p\n", hFile, buffer, bytesToRead,
bytesRead, overlapped );
if (bytesRead) *bytesRead = 0; /* Do this before anything else */
if (is_console_handle(hFile))
{
DWORD conread, mode;
if (!ReadConsoleA(hFile, buffer, bytesToRead, &conread, NULL) ||
!GetConsoleMode(hFile, &mode))
return FALSE;
/* ctrl-Z (26) means end of file on window (if at beginning of buffer)
* but Unix uses ctrl-D (4), and ctrl-Z is a bad idea on Unix :-/
* So map both ctrl-D ctrl-Z to EOF.
*/
if ((mode & ENABLE_PROCESSED_INPUT) && conread > 0 &&
(((char*)buffer)[0] == 26 || ((char*)buffer)[0] == 4))
{
conread = 0;
}
if (bytesRead) *bytesRead = conread;
return TRUE;
}
if (overlapped != NULL)
{
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
poffset = &offset;
hEvent = overlapped->hEvent;
io_status = (PIO_STATUS_BLOCK)overlapped;
if (((ULONG_PTR)hEvent & 1) == 0) cvalue = overlapped;
}
else io_status->Information = 0;
io_status->u.Status = STATUS_PENDING;
status = NtReadFile(hFile, hEvent, NULL, cvalue, io_status, buffer, bytesToRead, poffset, NULL);
if (status == STATUS_PENDING && !overlapped)
{
WaitForSingleObject( hFile, INFINITE );
status = io_status->u.Status;
}
if (bytesRead)
*bytesRead = overlapped && status ? 0 : io_status->Information;
if (status == STATUS_END_OF_FILE)
{
if (overlapped != NULL)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
}
else if (status && status != STATUS_TIMEOUT)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* WriteFileEx (KERNEL32.@)
*/
BOOL WINAPI WriteFileEx(HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
LPOVERLAPPED overlapped,
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
LARGE_INTEGER offset;
NTSTATUS status;
PIO_STATUS_BLOCK io_status;
TRACE("%p %p %d %p %p\n", hFile, buffer, bytesToWrite, overlapped, lpCompletionRoutine);
if (overlapped == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
io_status = (PIO_STATUS_BLOCK)overlapped;
io_status->u.Status = STATUS_PENDING;
io_status->Information = 0;
status = NtWriteFile(hFile, NULL, FILE_ReadWriteApc, lpCompletionRoutine,
io_status, buffer, bytesToWrite, &offset, NULL);
if (status && status != STATUS_PENDING)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* WriteFileGather (KERNEL32.@)
*/
BOOL WINAPI WriteFileGather( HANDLE file, FILE_SEGMENT_ELEMENT *segments, DWORD count,
LPDWORD reserved, LPOVERLAPPED overlapped )
{
PIO_STATUS_BLOCK io_status;
LARGE_INTEGER offset;
void *cvalue = NULL;
NTSTATUS status;
TRACE( "%p %p %u %p\n", file, segments, count, overlapped );
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
if (!((ULONG_PTR)overlapped->hEvent & 1)) cvalue = overlapped;
io_status = (PIO_STATUS_BLOCK)overlapped;
io_status->u.Status = STATUS_PENDING;
io_status->Information = 0;
status = NtWriteFileGather( file, overlapped->hEvent, NULL, cvalue, io_status,
segments, count, &offset, NULL );
if (status) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/***********************************************************************
* WriteFile (KERNEL32.@)
*/
BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
LPDWORD bytesWritten, LPOVERLAPPED overlapped )
{
HANDLE hEvent = NULL;
LARGE_INTEGER offset;
PLARGE_INTEGER poffset = NULL;
NTSTATUS status;
IO_STATUS_BLOCK iosb;
PIO_STATUS_BLOCK piosb = &iosb;
LPVOID cvalue = NULL;
TRACE("%p %p %d %p %p\n", hFile, buffer, bytesToWrite, bytesWritten, overlapped );
if (is_console_handle(hFile))
return WriteConsoleA(hFile, buffer, bytesToWrite, bytesWritten, NULL);
if (overlapped)
{
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
poffset = &offset;
hEvent = overlapped->hEvent;
piosb = (PIO_STATUS_BLOCK)overlapped;
if (((ULONG_PTR)hEvent & 1) == 0) cvalue = overlapped;
}
else piosb->Information = 0;
piosb->u.Status = STATUS_PENDING;
status = NtWriteFile(hFile, hEvent, NULL, cvalue, piosb,
buffer, bytesToWrite, poffset, NULL);
if (status == STATUS_PENDING && !overlapped)
{
WaitForSingleObject( hFile, INFINITE );
status = piosb->u.Status;
}
if (bytesWritten)
*bytesWritten = overlapped && status ? 0 : piosb->Information;
if (status && status != STATUS_TIMEOUT)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* GetOverlappedResult (KERNEL32.@)
*
* Check the result of an Asynchronous data transfer from a file.
*
* Parameters
* HANDLE hFile [in] handle of file to check on
* LPOVERLAPPED lpOverlapped [in/out] pointer to overlapped
* LPDWORD lpTransferred [in/out] number of bytes transferred
* BOOL bWait [in] wait for the transfer to complete ?
*
* RETURNS
* TRUE on success
* FALSE on failure
*
* If successful (and relevant) lpTransferred will hold the number of
* bytes transferred during the async operation.
*/
BOOL WINAPI GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped,
LPDWORD lpTransferred, BOOL bWait)
{
NTSTATUS status;
TRACE( "(%p %p %p %x)\n", hFile, lpOverlapped, lpTransferred, bWait );
status = lpOverlapped->Internal;
if (status == STATUS_PENDING)
{
if (!bWait)
{
SetLastError( ERROR_IO_INCOMPLETE );
return FALSE;
}
if (WaitForSingleObject( lpOverlapped->hEvent ? lpOverlapped->hEvent : hFile,
INFINITE ) == WAIT_FAILED)
return FALSE;
status = lpOverlapped->Internal;
if (status == STATUS_PENDING) status = STATUS_SUCCESS;
}
*lpTransferred = lpOverlapped->InternalHigh;
if (status) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/***********************************************************************
* CancelIoEx (KERNEL32.@)
*
* Cancels pending I/O operations on a file given the overlapped used.
*
* PARAMS
* handle [I] File handle.
* lpOverlapped [I,OPT] pointer to overlapped (if null, cancel all)
*
* RETURNS
* Success: TRUE.
* Failure: FALSE, check GetLastError().
*/
BOOL WINAPI CancelIoEx(HANDLE handle, LPOVERLAPPED lpOverlapped)
{
IO_STATUS_BLOCK io_status;
NtCancelIoFileEx(handle, (PIO_STATUS_BLOCK) lpOverlapped, &io_status);
if (io_status.u.Status)
{
SetLastError( RtlNtStatusToDosError( io_status.u.Status ) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* CancelIo (KERNEL32.@)
*
* Cancels pending I/O operations initiated by the current thread on a file.
*
* PARAMS
* handle [I] File handle.
*
* RETURNS
* Success: TRUE.
* Failure: FALSE, check GetLastError().
*/
BOOL WINAPI CancelIo(HANDLE handle)
{
IO_STATUS_BLOCK io_status;
NtCancelIoFile(handle, &io_status);
if (io_status.u.Status)
{
SetLastError( RtlNtStatusToDosError( io_status.u.Status ) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* CancelSynchronousIo (KERNEL32.@)
*
* Marks pending synchronous I/O operations issued by the specified thread as cancelled
*
* PARAMS
* handle [I] handle to the thread whose I/O operations should be cancelled
*
* RETURNS
* Success: TRUE.
* Failure: FALSE, check GetLastError().
*/
BOOL WINAPI CancelSynchronousIo(HANDLE thread)
{
FIXME("(%p): stub\n", thread);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*********************************************************************** /***********************************************************************
* _hread (KERNEL32.@) * _hread (KERNEL32.@)
*/ */
...@@ -813,265 +387,12 @@ UINT WINAPI _lwrite( HFILE hFile, LPCSTR buffer, UINT count ) ...@@ -813,265 +387,12 @@ UINT WINAPI _lwrite( HFILE hFile, LPCSTR buffer, UINT count )
} }
/*********************************************************************** /**************************************************************************
* FlushFileBuffers (KERNEL32.@) * SetFileCompletionNotificationModes (KERNEL32.@)
*/
BOOL WINAPI FlushFileBuffers( HANDLE hFile )
{
NTSTATUS nts;
IO_STATUS_BLOCK ioblk;
if (is_console_handle( hFile ))
{
/* this will fail (as expected) for an output handle */
return FlushConsoleInputBuffer( hFile );
}
nts = NtFlushBuffersFile( hFile, &ioblk );
if (nts != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError( nts ) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* GetFileType (KERNEL32.@)
*/ */
DWORD WINAPI GetFileType( HANDLE hFile ) BOOL WINAPI SetFileCompletionNotificationModes( HANDLE file, UCHAR flags )
{ {
FILE_FS_DEVICE_INFORMATION info; FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info;
IO_STATUS_BLOCK io;
NTSTATUS status;
if (hFile == (HANDLE)STD_INPUT_HANDLE || hFile == (HANDLE)STD_OUTPUT_HANDLE
|| hFile == (HANDLE)STD_ERROR_HANDLE)
hFile = GetStdHandle((DWORD_PTR)hFile);
if (is_console_handle( hFile )) return FILE_TYPE_CHAR;
status = NtQueryVolumeInformationFile( hFile, &io, &info, sizeof(info), FileFsDeviceInformation );
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError(status) );
return FILE_TYPE_UNKNOWN;
}
switch(info.DeviceType)
{
case FILE_DEVICE_NULL:
case FILE_DEVICE_SERIAL_PORT:
case FILE_DEVICE_PARALLEL_PORT:
case FILE_DEVICE_TAPE:
case FILE_DEVICE_UNKNOWN:
return FILE_TYPE_CHAR;
case FILE_DEVICE_NAMED_PIPE:
return FILE_TYPE_PIPE;
default:
return FILE_TYPE_DISK;
}
}
/***********************************************************************
* GetFileInformationByHandle (KERNEL32.@)
*/
BOOL WINAPI GetFileInformationByHandle( HANDLE hFile, BY_HANDLE_FILE_INFORMATION *info )
{
FILE_ALL_INFORMATION all_info;
IO_STATUS_BLOCK io;
NTSTATUS status;
status = NtQueryInformationFile( hFile, &io, &all_info, sizeof(all_info), FileAllInformation );
if (status == STATUS_BUFFER_OVERFLOW) status = STATUS_SUCCESS;
if (status == STATUS_SUCCESS)
{
info->dwFileAttributes = all_info.BasicInformation.FileAttributes;
info->ftCreationTime.dwHighDateTime = all_info.BasicInformation.CreationTime.u.HighPart;
info->ftCreationTime.dwLowDateTime = all_info.BasicInformation.CreationTime.u.LowPart;
info->ftLastAccessTime.dwHighDateTime = all_info.BasicInformation.LastAccessTime.u.HighPart;
info->ftLastAccessTime.dwLowDateTime = all_info.BasicInformation.LastAccessTime.u.LowPart;
info->ftLastWriteTime.dwHighDateTime = all_info.BasicInformation.LastWriteTime.u.HighPart;
info->ftLastWriteTime.dwLowDateTime = all_info.BasicInformation.LastWriteTime.u.LowPart;
info->dwVolumeSerialNumber = 0; /* FIXME */
info->nFileSizeHigh = all_info.StandardInformation.EndOfFile.u.HighPart;
info->nFileSizeLow = all_info.StandardInformation.EndOfFile.u.LowPart;
info->nNumberOfLinks = all_info.StandardInformation.NumberOfLinks;
info->nFileIndexHigh = all_info.InternalInformation.IndexNumber.u.HighPart;
info->nFileIndexLow = all_info.InternalInformation.IndexNumber.u.LowPart;
return TRUE;
}
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
/***********************************************************************
* GetFileInformationByHandleEx (KERNEL32.@)
*/
BOOL WINAPI GetFileInformationByHandleEx( HANDLE handle, FILE_INFO_BY_HANDLE_CLASS class,
LPVOID info, DWORD size )
{
NTSTATUS status;
IO_STATUS_BLOCK io;
switch (class)
{
case FileStreamInfo:
case FileCompressionInfo:
case FileAttributeTagInfo:
case FileRemoteProtocolInfo:
case FileFullDirectoryInfo:
case FileFullDirectoryRestartInfo:
case FileStorageInfo:
case FileAlignmentInfo:
case FileIdExtdDirectoryInfo:
case FileIdExtdDirectoryRestartInfo:
FIXME( "%p, %u, %p, %u\n", handle, class, info, size );
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
case FileBasicInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileBasicInformation );
break;
case FileStandardInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileStandardInformation );
break;
case FileNameInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileNameInformation );
break;
case FileIdInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileIdInformation );
break;
case FileIdBothDirectoryRestartInfo:
case FileIdBothDirectoryInfo:
status = NtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, info, size,
FileIdBothDirectoryInformation, FALSE, NULL,
(class == FileIdBothDirectoryRestartInfo) );
break;
case FileRenameInfo:
case FileDispositionInfo:
case FileAllocationInfo:
case FileIoPriorityHintInfo:
case FileEndOfFileInfo:
default:
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError( status ) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* GetFileSize (KERNEL32.@)
*
* Retrieve the size of a file.
*
* PARAMS
* hFile [I] File to retrieve size of.
* filesizehigh [O] On return, the high bits of the file size.
*
* RETURNS
* Success: The low bits of the file size.
* Failure: INVALID_FILE_SIZE. As this is could also be a success value,
* check GetLastError() for values other than ERROR_SUCCESS.
*/
DWORD WINAPI GetFileSize( HANDLE hFile, LPDWORD filesizehigh )
{
LARGE_INTEGER size;
if (!GetFileSizeEx( hFile, &size )) return INVALID_FILE_SIZE;
if (filesizehigh) *filesizehigh = size.u.HighPart;
if (size.u.LowPart == INVALID_FILE_SIZE) SetLastError(0);
return size.u.LowPart;
}
/***********************************************************************
* GetFileSizeEx (KERNEL32.@)
*
* Retrieve the size of a file.
*
* PARAMS
* hFile [I] File to retrieve size of.
* lpFileSIze [O] On return, the size of the file.
*
* RETURNS
* Success: TRUE.
* Failure: FALSE, check GetLastError().
*/
BOOL WINAPI GetFileSizeEx( HANDLE hFile, PLARGE_INTEGER lpFileSize )
{
FILE_STANDARD_INFORMATION info;
IO_STATUS_BLOCK io;
NTSTATUS status;
if (is_console_handle( hFile ))
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
status = NtQueryInformationFile( hFile, &io, &info, sizeof(info), FileStandardInformation );
if (status == STATUS_SUCCESS)
{
*lpFileSize = info.EndOfFile;
return TRUE;
}
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
/**************************************************************************
* SetEndOfFile (KERNEL32.@)
*
* Sets the current position as the end of the file.
*
* PARAMS
* hFile [I] File handle.
*
* RETURNS
* Success: TRUE.
* Failure: FALSE, check GetLastError().
*/
BOOL WINAPI SetEndOfFile( HANDLE hFile )
{
FILE_POSITION_INFORMATION pos;
FILE_END_OF_FILE_INFORMATION eof;
IO_STATUS_BLOCK io;
NTSTATUS status;
status = NtQueryInformationFile( hFile, &io, &pos, sizeof(pos), FilePositionInformation );
if (status == STATUS_SUCCESS)
{
eof.EndOfFile = pos.CurrentByteOffset;
status = NtSetInformationFile( hFile, &io, &eof, sizeof(eof), FileEndOfFileInformation );
}
if (status == STATUS_SUCCESS) return TRUE;
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
/**************************************************************************
* SetFileCompletionNotificationModes (KERNEL32.@)
*/
BOOL WINAPI SetFileCompletionNotificationModes( HANDLE file, UCHAR flags )
{
FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info;
IO_STATUS_BLOCK io; IO_STATUS_BLOCK io;
NTSTATUS status; NTSTATUS status;
...@@ -1083,329 +404,6 @@ BOOL WINAPI SetFileCompletionNotificationModes( HANDLE file, UCHAR flags ) ...@@ -1083,329 +404,6 @@ BOOL WINAPI SetFileCompletionNotificationModes( HANDLE file, UCHAR flags )
} }
/***********************************************************************
* SetFileInformationByHandle (KERNEL32.@)
*/
BOOL WINAPI SetFileInformationByHandle( HANDLE file, FILE_INFO_BY_HANDLE_CLASS class, VOID *info, DWORD size )
{
NTSTATUS status;
IO_STATUS_BLOCK io;
TRACE( "%p %u %p %u\n", file, class, info, size );
switch (class)
{
case FileNameInfo:
case FileRenameInfo:
case FileAllocationInfo:
case FileEndOfFileInfo:
case FileStreamInfo:
case FileIdBothDirectoryInfo:
case FileIdBothDirectoryRestartInfo:
case FileFullDirectoryInfo:
case FileFullDirectoryRestartInfo:
case FileStorageInfo:
case FileAlignmentInfo:
case FileIdInfo:
case FileIdExtdDirectoryInfo:
case FileIdExtdDirectoryRestartInfo:
FIXME( "%p, %u, %p, %u\n", file, class, info, size );
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
case FileBasicInfo:
status = NtSetInformationFile( file, &io, info, size, FileBasicInformation );
break;
case FileDispositionInfo:
status = NtSetInformationFile( file, &io, info, size, FileDispositionInformation );
break;
case FileIoPriorityHintInfo:
status = NtSetInformationFile( file, &io, info, size, FileIoPriorityHintInformation );
break;
case FileStandardInfo:
case FileCompressionInfo:
case FileAttributeTagInfo:
case FileRemoteProtocolInfo:
default:
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError( status ) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* SetFilePointer (KERNEL32.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH SetFilePointer( HANDLE hFile, LONG distance, LONG *highword, DWORD method )
{
LARGE_INTEGER dist, newpos;
if (highword)
{
dist.u.LowPart = distance;
dist.u.HighPart = *highword;
}
else dist.QuadPart = distance;
if (!SetFilePointerEx( hFile, dist, &newpos, method )) return INVALID_SET_FILE_POINTER;
if (highword) *highword = newpos.u.HighPart;
if (newpos.u.LowPart == INVALID_SET_FILE_POINTER) SetLastError( 0 );
return newpos.u.LowPart;
}
/***********************************************************************
* SetFilePointerEx (KERNEL32.@)
*/
BOOL WINAPI SetFilePointerEx( HANDLE hFile, LARGE_INTEGER distance,
LARGE_INTEGER *newpos, DWORD method )
{
LONGLONG pos;
IO_STATUS_BLOCK io;
FILE_POSITION_INFORMATION info;
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 FALSE;
}
if (pos < 0)
{
SetLastError( ERROR_NEGATIVE_SEEK );
return FALSE;
}
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;
}
/***********************************************************************
* SetFileValidData (KERNEL32.@)
*/
BOOL WINAPI SetFileValidData( HANDLE hFile, LONGLONG ValidDataLength )
{
FILE_VALID_DATA_LENGTH_INFORMATION info;
IO_STATUS_BLOCK io;
NTSTATUS status;
info.ValidDataLength.QuadPart = ValidDataLength;
status = NtSetInformationFile( hFile, &io, &info, sizeof(info), FileValidDataLengthInformation );
if (status == STATUS_SUCCESS) return TRUE;
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
/***********************************************************************
* GetFileTime (KERNEL32.@)
*/
BOOL WINAPI GetFileTime( HANDLE hFile, FILETIME *lpCreationTime,
FILETIME *lpLastAccessTime, FILETIME *lpLastWriteTime )
{
FILE_BASIC_INFORMATION info;
IO_STATUS_BLOCK io;
NTSTATUS status;
status = NtQueryInformationFile( hFile, &io, &info, sizeof(info), FileBasicInformation );
if (status == STATUS_SUCCESS)
{
if (lpCreationTime)
{
lpCreationTime->dwHighDateTime = info.CreationTime.u.HighPart;
lpCreationTime->dwLowDateTime = info.CreationTime.u.LowPart;
}
if (lpLastAccessTime)
{
lpLastAccessTime->dwHighDateTime = info.LastAccessTime.u.HighPart;
lpLastAccessTime->dwLowDateTime = info.LastAccessTime.u.LowPart;
}
if (lpLastWriteTime)
{
lpLastWriteTime->dwHighDateTime = info.LastWriteTime.u.HighPart;
lpLastWriteTime->dwLowDateTime = info.LastWriteTime.u.LowPart;
}
return TRUE;
}
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
/***********************************************************************
* SetFileTime (KERNEL32.@)
*/
BOOL WINAPI SetFileTime( HANDLE hFile, const FILETIME *ctime,
const FILETIME *atime, const FILETIME *mtime )
{
FILE_BASIC_INFORMATION info;
IO_STATUS_BLOCK io;
NTSTATUS status;
memset( &info, 0, sizeof(info) );
if (ctime)
{
info.CreationTime.u.HighPart = ctime->dwHighDateTime;
info.CreationTime.u.LowPart = ctime->dwLowDateTime;
}
if (atime)
{
info.LastAccessTime.u.HighPart = atime->dwHighDateTime;
info.LastAccessTime.u.LowPart = atime->dwLowDateTime;
}
if (mtime)
{
info.LastWriteTime.u.HighPart = mtime->dwHighDateTime;
info.LastWriteTime.u.LowPart = mtime->dwLowDateTime;
}
status = NtSetInformationFile( hFile, &io, &info, sizeof(info), FileBasicInformation );
if (status == STATUS_SUCCESS) return TRUE;
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
/**************************************************************************
* LockFile (KERNEL32.@)
*/
BOOL WINAPI LockFile( HANDLE hFile, DWORD offset_low, DWORD offset_high,
DWORD count_low, DWORD count_high )
{
NTSTATUS status;
LARGE_INTEGER count, offset;
TRACE( "%p %x%08x %x%08x\n",
hFile, offset_high, offset_low, count_high, count_low );
count.u.LowPart = count_low;
count.u.HighPart = count_high;
offset.u.LowPart = offset_low;
offset.u.HighPart = offset_high;
status = NtLockFile( hFile, 0, NULL, NULL,
NULL, &offset, &count, NULL, TRUE, TRUE );
if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/**************************************************************************
* LockFileEx [KERNEL32.@]
*
* Locks a byte range within an open file for shared or exclusive access.
*
* RETURNS
* success: TRUE
* failure: FALSE
*
* NOTES
* Per Microsoft docs, the third parameter (reserved) must be set to 0.
*/
BOOL WINAPI LockFileEx( HANDLE hFile, DWORD flags, DWORD reserved,
DWORD count_low, DWORD count_high, LPOVERLAPPED overlapped )
{
NTSTATUS status;
LARGE_INTEGER count, offset;
LPVOID cvalue = NULL;
if (reserved)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
TRACE( "%p %x%08x %x%08x flags %x\n",
hFile, overlapped->u.s.OffsetHigh, overlapped->u.s.Offset,
count_high, count_low, flags );
count.u.LowPart = count_low;
count.u.HighPart = count_high;
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
if (((ULONG_PTR)overlapped->hEvent & 1) == 0) cvalue = overlapped;
status = NtLockFile( hFile, overlapped->hEvent, NULL, cvalue,
NULL, &offset, &count, NULL,
flags & LOCKFILE_FAIL_IMMEDIATELY,
flags & LOCKFILE_EXCLUSIVE_LOCK );
if (status) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/**************************************************************************
* UnlockFile (KERNEL32.@)
*/
BOOL WINAPI UnlockFile( HANDLE hFile, DWORD offset_low, DWORD offset_high,
DWORD count_low, DWORD count_high )
{
NTSTATUS status;
LARGE_INTEGER count, offset;
count.u.LowPart = count_low;
count.u.HighPart = count_high;
offset.u.LowPart = offset_low;
offset.u.HighPart = offset_high;
status = NtUnlockFile( hFile, NULL, &offset, &count, NULL);
if (status) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/**************************************************************************
* UnlockFileEx (KERNEL32.@)
*/
BOOL WINAPI UnlockFileEx( HANDLE hFile, DWORD reserved, DWORD count_low, DWORD count_high,
LPOVERLAPPED overlapped )
{
if (reserved)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (overlapped->hEvent) FIXME("Unimplemented overlapped operation\n");
return UnlockFile( hFile, overlapped->u.s.Offset, overlapped->u.s.OffsetHigh, count_low, count_high );
}
/************************************************************************* /*************************************************************************
* SetHandleCount (KERNEL32.@) * SetHandleCount (KERNEL32.@)
*/ */
...@@ -3127,7 +2125,7 @@ DWORD WINAPI GetFinalPathNameByHandleA(HANDLE file, LPSTR path, DWORD charcount, ...@@ -3127,7 +2125,7 @@ DWORD WINAPI GetFinalPathNameByHandleA(HANDLE file, LPSTR path, DWORD charcount,
return 0; return 0;
} }
cp = oem_file_apis ? CP_OEMCP : CP_ACP; cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
len = WideCharToMultiByte(cp, 0, str, -1, NULL, 0, NULL, NULL); len = WideCharToMultiByte(cp, 0, str, -1, NULL, 0, NULL, NULL);
if (!len) if (!len)
......
...@@ -157,7 +157,7 @@ ...@@ -157,7 +157,7 @@
@ stdcall AllocateUserPhysicalPages(long ptr ptr) @ stdcall AllocateUserPhysicalPages(long ptr ptr)
@ stdcall ApplicationRecoveryFinished(long) @ stdcall ApplicationRecoveryFinished(long)
@ stdcall ApplicationRecoveryInProgress(ptr) @ stdcall ApplicationRecoveryInProgress(ptr)
@ stdcall AreFileApisANSI() @ stdcall -import AreFileApisANSI()
@ stdcall AssignProcessToJobObject(ptr ptr) @ stdcall AssignProcessToJobObject(ptr ptr)
@ stdcall AttachConsole(long) @ stdcall AttachConsole(long)
@ stdcall BackupRead(ptr ptr long ptr long long ptr) @ stdcall BackupRead(ptr ptr long ptr long long ptr)
...@@ -207,9 +207,9 @@ ...@@ -207,9 +207,9 @@
@ stdcall CallNamedPipeA(str ptr long ptr long ptr long) @ stdcall CallNamedPipeA(str ptr long ptr long ptr long)
@ stdcall -import CallNamedPipeW(wstr ptr long ptr long ptr long) @ stdcall -import CallNamedPipeW(wstr ptr long ptr long ptr long)
@ stub CancelDeviceWakeupRequest @ stub CancelDeviceWakeupRequest
@ stdcall CancelIo(long) @ stdcall -import CancelIo(long)
@ stdcall CancelIoEx(long ptr) @ stdcall -import CancelIoEx(long ptr)
@ stdcall CancelSynchronousIo(long) @ stdcall -import CancelSynchronousIo(long)
# @ stub CancelThreadpoolIo # @ stub CancelThreadpoolIo
@ stdcall CancelTimerQueueTimer(ptr ptr) @ stdcall CancelTimerQueueTimer(ptr ptr)
@ stdcall -import CancelWaitableTimer(long) @ stdcall -import CancelWaitableTimer(long)
...@@ -516,7 +516,7 @@ ...@@ -516,7 +516,7 @@
@ stdcall -import FlsGetValue(long) @ stdcall -import FlsGetValue(long)
@ stdcall -import FlsSetValue(long ptr) @ stdcall -import FlsSetValue(long ptr)
@ stdcall FlushConsoleInputBuffer(long) @ stdcall FlushConsoleInputBuffer(long)
@ stdcall FlushFileBuffers(long) @ stdcall -import FlushFileBuffers(long)
@ stdcall -import FlushInstructionCache(long long long) @ stdcall -import FlushInstructionCache(long long long)
@ stdcall FlushProcessWriteBuffers() @ stdcall FlushProcessWriteBuffers()
@ stdcall FlushViewOfFile(ptr long) @ stdcall FlushViewOfFile(ptr long)
...@@ -676,14 +676,14 @@ ...@@ -676,14 +676,14 @@
# @ stub GetFileAttributesTransactedW # @ stub GetFileAttributesTransactedW
@ stdcall GetFileAttributesW(wstr) @ stdcall GetFileAttributesW(wstr)
# @ stub GetFileBandwidthReservation # @ stub GetFileBandwidthReservation
@ stdcall GetFileInformationByHandle(long ptr) @ stdcall -import GetFileInformationByHandle(long ptr)
@ stdcall GetFileInformationByHandleEx(long long ptr long) @ stdcall -import GetFileInformationByHandleEx(long long ptr long)
@ stdcall GetFileMUIInfo(long wstr ptr ptr) @ stdcall GetFileMUIInfo(long wstr ptr ptr)
@ stdcall GetFileMUIPath(long wstr wstr ptr ptr ptr ptr) @ stdcall GetFileMUIPath(long wstr wstr ptr ptr ptr ptr)
@ stdcall GetFileSize(long ptr) @ stdcall -import GetFileSize(long ptr)
@ stdcall GetFileSizeEx(long ptr) @ stdcall -import GetFileSizeEx(long ptr)
@ stdcall GetFileTime(long ptr ptr ptr) @ stdcall -import GetFileTime(long ptr ptr ptr)
@ stdcall GetFileType(long) @ stdcall -import GetFileType(long)
@ stdcall GetFinalPathNameByHandleA(long ptr long long) @ stdcall GetFinalPathNameByHandleA(long ptr long long)
@ stdcall GetFinalPathNameByHandleW(long ptr long long) @ stdcall GetFinalPathNameByHandleW(long ptr long long)
@ stdcall GetFirmwareEnvironmentVariableA(str str ptr long) @ stdcall GetFirmwareEnvironmentVariableA(str str ptr long)
...@@ -759,7 +759,7 @@ ...@@ -759,7 +759,7 @@
@ stdcall GetNumberOfConsoleInputEvents(long ptr) @ stdcall GetNumberOfConsoleInputEvents(long ptr)
@ stdcall GetNumberOfConsoleMouseButtons(ptr) @ stdcall GetNumberOfConsoleMouseButtons(ptr)
@ stdcall GetOEMCP() @ stdcall GetOEMCP()
@ stdcall GetOverlappedResult(long ptr ptr long) @ stdcall -import GetOverlappedResult(long ptr ptr long)
@ stdcall GetUserPreferredUILanguages(long ptr ptr ptr) @ stdcall GetUserPreferredUILanguages(long ptr ptr ptr)
@ stdcall GetPackageFullName(long ptr ptr) @ stdcall GetPackageFullName(long ptr ptr)
@ stdcall GetPhysicallyInstalledSystemMemory(ptr) @ stdcall GetPhysicallyInstalledSystemMemory(ptr)
...@@ -1063,8 +1063,8 @@ ...@@ -1063,8 +1063,8 @@
@ stdcall LocalUnlock(long) @ stdcall LocalUnlock(long)
@ stdcall LocaleNameToLCID(wstr long) @ stdcall LocaleNameToLCID(wstr long)
# @ stub LocateXStateFeature # @ stub LocateXStateFeature
@ stdcall LockFile(long long long long long) @ stdcall -import LockFile(long long long long long)
@ stdcall LockFileEx(long long long long long ptr) @ stdcall -import LockFileEx(long long long long long ptr)
@ stdcall -import LockResource(long) @ stdcall -import LockResource(long)
@ stdcall MakeCriticalSectionGlobal(ptr) @ stdcall MakeCriticalSectionGlobal(ptr)
@ stdcall -i386 -private -norelay MapHInstLS() krnl386.exe16.MapHInstLS @ stdcall -i386 -private -norelay MapHInstLS() krnl386.exe16.MapHInstLS
...@@ -1195,9 +1195,9 @@ ...@@ -1195,9 +1195,9 @@
@ stdcall ReadConsoleOutputW(long ptr long long ptr) @ stdcall ReadConsoleOutputW(long ptr long long ptr)
@ stdcall ReadConsoleW(long ptr long ptr ptr) @ stdcall ReadConsoleW(long ptr long ptr ptr)
@ stdcall ReadDirectoryChangesW(long ptr long long long ptr ptr ptr) @ stdcall ReadDirectoryChangesW(long ptr long long long ptr ptr ptr)
@ stdcall ReadFile(long ptr long ptr ptr) @ stdcall -import ReadFile(long ptr long ptr ptr)
@ stdcall ReadFileEx(long ptr long ptr ptr) @ stdcall -import ReadFileEx(long ptr long ptr ptr)
@ stdcall ReadFileScatter(long ptr long ptr ptr) @ stdcall -import ReadFileScatter(long ptr long ptr ptr)
@ stdcall ReadProcessMemory(long ptr ptr long ptr) @ stdcall ReadProcessMemory(long ptr ptr long ptr)
# @ stub ReadThreadProfilingData # @ stub ReadThreadProfilingData
@ stdcall -private RegCloseKey(long) advapi32.RegCloseKey @ stdcall -private RegCloseKey(long) advapi32.RegCloseKey
...@@ -1383,7 +1383,7 @@ ...@@ -1383,7 +1383,7 @@
@ stdcall SetDllDirectoryA(str) @ stdcall SetDllDirectoryA(str)
@ stdcall SetDllDirectoryW(wstr) @ stdcall SetDllDirectoryW(wstr)
# @ stub SetDynamicTimeZoneInformation # @ stub SetDynamicTimeZoneInformation
@ stdcall SetEndOfFile(long) @ stdcall -import SetEndOfFile(long)
# @ stub SetEnvironmentStringsA # @ stub SetEnvironmentStringsA
# @ stub SetEnvironmentStringsW # @ stub SetEnvironmentStringsW
@ stdcall SetEnvironmentVariableA(str str) @ stdcall SetEnvironmentVariableA(str str)
...@@ -1391,22 +1391,22 @@ ...@@ -1391,22 +1391,22 @@
@ stdcall -import SetErrorMode(long) @ stdcall -import SetErrorMode(long)
@ stdcall -import SetEvent(long) @ stdcall -import SetEvent(long)
@ stdcall SetEventWhenCallbackReturns(ptr long) ntdll.TpCallbackSetEventOnCompletion @ stdcall SetEventWhenCallbackReturns(ptr long) ntdll.TpCallbackSetEventOnCompletion
@ stdcall SetFileApisToANSI() @ stdcall -import SetFileApisToANSI()
@ stdcall SetFileApisToOEM() @ stdcall -import SetFileApisToOEM()
@ stdcall SetFileAttributesA(str long) @ stdcall SetFileAttributesA(str long)
# @ stub SetFileAttributesTransactedA # @ stub SetFileAttributesTransactedA
# @ stub SetFileAttributesTransactedW # @ stub SetFileAttributesTransactedW
@ stdcall SetFileAttributesW(wstr long) @ stdcall SetFileAttributesW(wstr long)
# @ stub SetFileBandwidthReservation # @ stub SetFileBandwidthReservation
@ stdcall SetFileCompletionNotificationModes(long long) @ stdcall SetFileCompletionNotificationModes(long long)
@ stdcall SetFileInformationByHandle(long long ptr long) @ stdcall -import SetFileInformationByHandle(long long ptr long)
# @ stub SetFileIoOverlappedRange # @ stub SetFileIoOverlappedRange
@ stdcall SetFilePointer(long long ptr long) @ stdcall -import SetFilePointer(long long ptr long)
@ stdcall SetFilePointerEx(long int64 ptr long) @ stdcall -import SetFilePointerEx(long int64 ptr long)
# @ stub SetFileShortNameA # @ stub SetFileShortNameA
# @ stub SetFileShortNameW # @ stub SetFileShortNameW
@ stdcall SetFileTime(long ptr ptr ptr) @ stdcall -import SetFileTime(long ptr ptr ptr)
@ stdcall SetFileValidData(ptr int64) @ stdcall -import SetFileValidData(ptr int64)
# @ stub SetFirmwareEnvironmentVariableA # @ stub SetFirmwareEnvironmentVariableA
# @ stub SetFirmwareEnvironmentVariableW # @ stub SetFirmwareEnvironmentVariableW
@ stdcall SetHandleContext(long long) @ stdcall SetHandleContext(long long)
...@@ -1534,8 +1534,8 @@ ...@@ -1534,8 +1534,8 @@
@ stdcall -i386 -private -norelay UnMapSLFixArray(long long) krnl386.exe16.UnMapSLFixArray @ stdcall -i386 -private -norelay UnMapSLFixArray(long long) krnl386.exe16.UnMapSLFixArray
@ stdcall UnhandledExceptionFilter(ptr) @ stdcall UnhandledExceptionFilter(ptr)
@ stdcall UninitializeCriticalSection(ptr) @ stdcall UninitializeCriticalSection(ptr)
@ stdcall UnlockFile(long long long long long) @ stdcall -import UnlockFile(long long long long long)
@ stdcall UnlockFileEx(long long long long ptr) @ stdcall -import UnlockFileEx(long long long long ptr)
@ stdcall UnmapViewOfFile(ptr) @ stdcall UnmapViewOfFile(ptr)
# @ stub UnregisterApplicationRecoveryCallback # @ stub UnregisterApplicationRecoveryCallback
@ stdcall UnregisterApplicationRestart() @ stdcall UnregisterApplicationRestart()
...@@ -1618,9 +1618,9 @@ ...@@ -1618,9 +1618,9 @@
@ stdcall WriteConsoleOutputCharacterW(long ptr long long ptr) @ stdcall WriteConsoleOutputCharacterW(long ptr long long ptr)
@ stdcall WriteConsoleOutputW(long ptr long long ptr) @ stdcall WriteConsoleOutputW(long ptr long long ptr)
@ stdcall WriteConsoleW(long ptr long ptr ptr) @ stdcall WriteConsoleW(long ptr long ptr ptr)
@ stdcall WriteFile(long ptr long ptr ptr) @ stdcall -import WriteFile(long ptr long ptr ptr)
@ stdcall WriteFileEx(long ptr long ptr ptr) @ stdcall -import WriteFileEx(long ptr long ptr ptr)
@ stdcall WriteFileGather(long ptr long ptr ptr) @ stdcall -import WriteFileGather(long ptr long ptr ptr)
@ stdcall WritePrivateProfileSectionA(str str str) @ stdcall WritePrivateProfileSectionA(str str str)
@ stdcall WritePrivateProfileSectionW(wstr wstr wstr) @ stdcall WritePrivateProfileSectionW(wstr wstr wstr)
@ stdcall WritePrivateProfileStringA(str str str str) @ stdcall WritePrivateProfileStringA(str str str str)
......
...@@ -4,6 +4,7 @@ IMPORTS = uuid ntdll winecrt0 kernel32 ...@@ -4,6 +4,7 @@ IMPORTS = uuid ntdll winecrt0 kernel32
EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -mno-cygwin EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -mno-cygwin
C_SRCS = \ C_SRCS = \
file.c \
loader.c \ loader.c \
main.c \ main.c \
path.c \ path.c \
......
/*
* File handling functions
*
* Copyright 1993 John Burton
* Copyright 1996, 2004 Alexandre Julliard
* Copyright 2008 Jeff Zaroyko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "winerror.h"
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "winioctl.h"
#include "wincon.h"
#include "fileapi.h"
#include "ddk/ntddk.h"
#include "kernelbase.h"
#include "wine/exception.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(file);
static BOOL oem_file_apis;
static void WINAPI read_write_apc( void *apc_user, PIO_STATUS_BLOCK io, ULONG reserved )
{
LPOVERLAPPED_COMPLETION_ROUTINE func = apc_user;
func( RtlNtStatusToDosError( io->u.Status ), io->Information, (LPOVERLAPPED)io );
}
/***********************************************************************
* Operations on file names
***********************************************************************/
/***********************************************************************
* file_name_AtoW
*
* Convert a file name to Unicode, taking into account the OEM/Ansi API mode.
*
* If alloc is FALSE uses the TEB static buffer, so it can only be used when
* there is no possibility for the function to do that twice, taking into
* account any called function.
*/
WCHAR *file_name_AtoW( LPCSTR name, BOOL alloc )
{
ANSI_STRING str;
UNICODE_STRING strW, *pstrW;
NTSTATUS status;
RtlInitAnsiString( &str, name );
pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString;
if (oem_file_apis)
status = RtlOemStringToUnicodeString( pstrW, &str, alloc );
else
status = RtlAnsiStringToUnicodeString( pstrW, &str, alloc );
if (status == STATUS_SUCCESS) return pstrW->Buffer;
if (status == STATUS_BUFFER_OVERFLOW)
SetLastError( ERROR_FILENAME_EXCED_RANGE );
else
SetLastError( RtlNtStatusToDosError(status) );
return NULL;
}
/***********************************************************************
* file_name_WtoA
*
* Convert a file name back to OEM/Ansi. Returns number of bytes copied.
*/
DWORD file_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen )
{
DWORD ret;
if (srclen < 0) srclen = lstrlenW( src ) + 1;
if (oem_file_apis)
RtlUnicodeToOemN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) );
else
RtlUnicodeToMultiByteN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) );
return ret;
}
/******************************************************************************
* AreFileApisANSI (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH AreFileApisANSI(void)
{
return !oem_file_apis;
}
/**************************************************************************
* SetFileApisToANSI (kernelbase.@)
*/
void WINAPI DECLSPEC_HOTPATCH SetFileApisToANSI(void)
{
oem_file_apis = FALSE;
}
/**************************************************************************
* SetFileApisToOEM (kernelbase.@)
*/
void WINAPI DECLSPEC_HOTPATCH SetFileApisToOEM(void)
{
oem_file_apis = TRUE;
}
/***********************************************************************
* Operations on file handles
***********************************************************************/
/***********************************************************************
* CancelIo (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH CancelIo( HANDLE handle )
{
IO_STATUS_BLOCK io;
NtCancelIoFile( handle, &io );
return set_ntstatus( io.u.Status );
}
/***********************************************************************
* CancelIoEx (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH CancelIoEx( HANDLE handle, LPOVERLAPPED overlapped )
{
IO_STATUS_BLOCK io;
NtCancelIoFileEx( handle, (PIO_STATUS_BLOCK)overlapped, &io );
return set_ntstatus( io.u.Status );
}
/***********************************************************************
* CancelSynchronousIo (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH CancelSynchronousIo( HANDLE thread )
{
FIXME( "(%p): stub\n", thread );
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
}
/***********************************************************************
* FlushFileBuffers (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH FlushFileBuffers( HANDLE file )
{
IO_STATUS_BLOCK iosb;
/* this will fail (as expected) for an output handle */
if (is_console_handle( file )) return FlushConsoleInputBuffer( file );
return set_ntstatus( NtFlushBuffersFile( file, &iosb ));
}
/***********************************************************************
* GetFileInformationByHandle (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetFileInformationByHandle( HANDLE file, BY_HANDLE_FILE_INFORMATION *info )
{
FILE_ALL_INFORMATION all_info;
IO_STATUS_BLOCK io;
NTSTATUS status;
status = NtQueryInformationFile( file, &io, &all_info, sizeof(all_info), FileAllInformation );
if (status == STATUS_BUFFER_OVERFLOW) status = STATUS_SUCCESS;
if (!set_ntstatus( status )) return FALSE;
info->dwFileAttributes = all_info.BasicInformation.FileAttributes;
info->ftCreationTime.dwHighDateTime = all_info.BasicInformation.CreationTime.u.HighPart;
info->ftCreationTime.dwLowDateTime = all_info.BasicInformation.CreationTime.u.LowPart;
info->ftLastAccessTime.dwHighDateTime = all_info.BasicInformation.LastAccessTime.u.HighPart;
info->ftLastAccessTime.dwLowDateTime = all_info.BasicInformation.LastAccessTime.u.LowPart;
info->ftLastWriteTime.dwHighDateTime = all_info.BasicInformation.LastWriteTime.u.HighPart;
info->ftLastWriteTime.dwLowDateTime = all_info.BasicInformation.LastWriteTime.u.LowPart;
info->dwVolumeSerialNumber = 0; /* FIXME */
info->nFileSizeHigh = all_info.StandardInformation.EndOfFile.u.HighPart;
info->nFileSizeLow = all_info.StandardInformation.EndOfFile.u.LowPart;
info->nNumberOfLinks = all_info.StandardInformation.NumberOfLinks;
info->nFileIndexHigh = all_info.InternalInformation.IndexNumber.u.HighPart;
info->nFileIndexLow = all_info.InternalInformation.IndexNumber.u.LowPart;
return TRUE;
}
/***********************************************************************
* GetFileInformationByHandleEx (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetFileInformationByHandleEx( HANDLE handle, FILE_INFO_BY_HANDLE_CLASS class,
LPVOID info, DWORD size )
{
NTSTATUS status;
IO_STATUS_BLOCK io;
switch (class)
{
case FileStreamInfo:
case FileCompressionInfo:
case FileAttributeTagInfo:
case FileRemoteProtocolInfo:
case FileFullDirectoryInfo:
case FileFullDirectoryRestartInfo:
case FileStorageInfo:
case FileAlignmentInfo:
case FileIdExtdDirectoryInfo:
case FileIdExtdDirectoryRestartInfo:
FIXME( "%p, %u, %p, %u\n", handle, class, info, size );
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
case FileBasicInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileBasicInformation );
break;
case FileStandardInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileStandardInformation );
break;
case FileNameInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileNameInformation );
break;
case FileIdInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileIdInformation );
break;
case FileIdBothDirectoryRestartInfo:
case FileIdBothDirectoryInfo:
status = NtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, info, size,
FileIdBothDirectoryInformation, FALSE, NULL,
(class == FileIdBothDirectoryRestartInfo) );
break;
case FileRenameInfo:
case FileDispositionInfo:
case FileAllocationInfo:
case FileIoPriorityHintInfo:
case FileEndOfFileInfo:
default:
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
return set_ntstatus( status );
}
/***********************************************************************
* GetFileSize (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetFileSize( HANDLE file, LPDWORD size_high )
{
LARGE_INTEGER size;
if (!GetFileSizeEx( file, &size )) return INVALID_FILE_SIZE;
if (size_high) *size_high = size.u.HighPart;
if (size.u.LowPart == INVALID_FILE_SIZE) SetLastError( 0 );
return size.u.LowPart;
}
/***********************************************************************
* GetFileSizeEx (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetFileSizeEx( HANDLE file, PLARGE_INTEGER size )
{
FILE_STANDARD_INFORMATION info;
IO_STATUS_BLOCK io;
if (is_console_handle( file ))
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
if (!set_ntstatus( NtQueryInformationFile( file, &io, &info, sizeof(info), FileStandardInformation )))
return FALSE;
*size = info.EndOfFile;
return TRUE;
}
/***********************************************************************
* GetFileTime (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetFileTime( HANDLE file, FILETIME *creation,
FILETIME *access, FILETIME *write )
{
FILE_BASIC_INFORMATION info;
IO_STATUS_BLOCK io;
if (!set_ntstatus( NtQueryInformationFile( file, &io, &info, sizeof(info), FileBasicInformation )))
return FALSE;
if (creation)
{
creation->dwHighDateTime = info.CreationTime.u.HighPart;
creation->dwLowDateTime = info.CreationTime.u.LowPart;
}
if (access)
{
access->dwHighDateTime = info.LastAccessTime.u.HighPart;
access->dwLowDateTime = info.LastAccessTime.u.LowPart;
}
if (write)
{
write->dwHighDateTime = info.LastWriteTime.u.HighPart;
write->dwLowDateTime = info.LastWriteTime.u.LowPart;
}
return TRUE;
}
/***********************************************************************
* GetFileType (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetFileType( HANDLE file )
{
FILE_FS_DEVICE_INFORMATION info;
IO_STATUS_BLOCK io;
if (file == (HANDLE)STD_INPUT_HANDLE ||
file == (HANDLE)STD_OUTPUT_HANDLE ||
file == (HANDLE)STD_ERROR_HANDLE)
file = GetStdHandle( (DWORD_PTR)file );
if (is_console_handle( file )) return FILE_TYPE_CHAR;
if (!set_ntstatus( NtQueryVolumeInformationFile( file, &io, &info, sizeof(info),
FileFsDeviceInformation )))
return FILE_TYPE_UNKNOWN;
switch (info.DeviceType)
{
case FILE_DEVICE_NULL:
case FILE_DEVICE_SERIAL_PORT:
case FILE_DEVICE_PARALLEL_PORT:
case FILE_DEVICE_TAPE:
case FILE_DEVICE_UNKNOWN:
return FILE_TYPE_CHAR;
case FILE_DEVICE_NAMED_PIPE:
return FILE_TYPE_PIPE;
default:
return FILE_TYPE_DISK;
}
}
/***********************************************************************
* GetOverlappedResult (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH GetOverlappedResult( HANDLE file, LPOVERLAPPED overlapped,
LPDWORD result, BOOL wait )
{
NTSTATUS status;
TRACE( "(%p %p %p %x)\n", file, overlapped, result, wait );
status = overlapped->Internal;
if (status == STATUS_PENDING)
{
if (!wait)
{
SetLastError( ERROR_IO_INCOMPLETE );
return FALSE;
}
if (WaitForSingleObject( overlapped->hEvent ? overlapped->hEvent : file, INFINITE ) == WAIT_FAILED)
return FALSE;
status = overlapped->Internal;
if (status == STATUS_PENDING) status = STATUS_SUCCESS;
}
*result = overlapped->InternalHigh;
return set_ntstatus( status );
}
/**************************************************************************
* LockFile (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH LockFile( HANDLE file, DWORD offset_low, DWORD offset_high,
DWORD count_low, DWORD count_high )
{
LARGE_INTEGER count, offset;
TRACE( "%p %x%08x %x%08x\n", file, offset_high, offset_low, count_high, count_low );
count.u.LowPart = count_low;
count.u.HighPart = count_high;
offset.u.LowPart = offset_low;
offset.u.HighPart = offset_high;
return set_ntstatus( NtLockFile( file, 0, NULL, NULL, NULL, &offset, &count, NULL, TRUE, TRUE ));
}
/**************************************************************************
* LockFileEx (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH LockFileEx( HANDLE file, DWORD flags, DWORD reserved,
DWORD count_low, DWORD count_high, LPOVERLAPPED overlapped )
{
LARGE_INTEGER count, offset;
LPVOID cvalue = NULL;
if (reserved)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
TRACE( "%p %x%08x %x%08x flags %x\n",
file, overlapped->u.s.OffsetHigh, overlapped->u.s.Offset, count_high, count_low, flags );
count.u.LowPart = count_low;
count.u.HighPart = count_high;
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
if (((ULONG_PTR)overlapped->hEvent & 1) == 0) cvalue = overlapped;
return set_ntstatus( NtLockFile( file, overlapped->hEvent, NULL, cvalue,
NULL, &offset, &count, NULL,
flags & LOCKFILE_FAIL_IMMEDIATELY,
flags & LOCKFILE_EXCLUSIVE_LOCK ));
}
/***********************************************************************
* ReadFile (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH ReadFile( HANDLE file, LPVOID buffer, DWORD count,
LPDWORD result, LPOVERLAPPED overlapped )
{
LARGE_INTEGER offset;
PLARGE_INTEGER poffset = NULL;
IO_STATUS_BLOCK iosb;
PIO_STATUS_BLOCK io_status = &iosb;
HANDLE event = 0;
NTSTATUS status;
LPVOID cvalue = NULL;
TRACE( "%p %p %d %p %p\n", file, buffer, count, result, overlapped );
if (result) *result = 0;
if (is_console_handle( file ))
{
DWORD conread, mode;
if (!ReadConsoleA( file, buffer, count, &conread, NULL) || !GetConsoleMode( file, &mode ))
return FALSE;
/* ctrl-Z (26) means end of file on window (if at beginning of buffer)
* but Unix uses ctrl-D (4), and ctrl-Z is a bad idea on Unix :-/
* So map both ctrl-D ctrl-Z to EOF.
*/
if ((mode & ENABLE_PROCESSED_INPUT) && conread > 0 &&
(((char *)buffer)[0] == 26 || ((char *)buffer)[0] == 4))
{
conread = 0;
}
if (result) *result = conread;
return TRUE;
}
if (overlapped)
{
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
poffset = &offset;
event = overlapped->hEvent;
io_status = (PIO_STATUS_BLOCK)overlapped;
if (((ULONG_PTR)event & 1) == 0) cvalue = overlapped;
}
else io_status->Information = 0;
io_status->u.Status = STATUS_PENDING;
status = NtReadFile( file, event, NULL, cvalue, io_status, buffer, count, poffset, NULL);
if (status == STATUS_PENDING && !overlapped)
{
WaitForSingleObject( file, INFINITE );
status = io_status->u.Status;
}
if (result) *result = overlapped && status ? 0 : io_status->Information;
if (status == STATUS_END_OF_FILE)
{
if (overlapped != NULL)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
}
else if (status && status != STATUS_TIMEOUT)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* ReadFileEx (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH ReadFileEx( HANDLE file, LPVOID buffer, DWORD count, LPOVERLAPPED overlapped,
LPOVERLAPPED_COMPLETION_ROUTINE completion )
{
PIO_STATUS_BLOCK io;
LARGE_INTEGER offset;
NTSTATUS status;
TRACE( "(file=%p, buffer=%p, bytes=%u, ovl=%p, ovl_fn=%p)\n",
file, buffer, count, overlapped, completion );
if (!overlapped)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
io = (PIO_STATUS_BLOCK)overlapped;
io->u.Status = STATUS_PENDING;
io->Information = 0;
status = NtReadFile( file, NULL, read_write_apc, completion, io, buffer, count, &offset, NULL);
if (status == STATUS_PENDING) return TRUE;
return set_ntstatus( status );
}
/***********************************************************************
* ReadFileScatter (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH ReadFileScatter( HANDLE file, FILE_SEGMENT_ELEMENT *segments, DWORD count,
LPDWORD reserved, LPOVERLAPPED overlapped )
{
PIO_STATUS_BLOCK io;
LARGE_INTEGER offset;
void *cvalue = NULL;
TRACE( "(%p %p %u %p)\n", file, segments, count, overlapped );
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
if (!((ULONG_PTR)overlapped->hEvent & 1)) cvalue = overlapped;
io = (PIO_STATUS_BLOCK)overlapped;
io->u.Status = STATUS_PENDING;
io->Information = 0;
return set_ntstatus( NtReadFileScatter( file, overlapped->hEvent, NULL, cvalue, io,
segments, count, &offset, NULL ));
}
/**************************************************************************
* SetEndOfFile (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetEndOfFile( HANDLE file )
{
FILE_POSITION_INFORMATION pos;
FILE_END_OF_FILE_INFORMATION eof;
IO_STATUS_BLOCK io;
NTSTATUS status;
if (!(status = NtQueryInformationFile( file, &io, &pos, sizeof(pos), FilePositionInformation )))
{
eof.EndOfFile = pos.CurrentByteOffset;
status = NtSetInformationFile( file, &io, &eof, sizeof(eof), FileEndOfFileInformation );
}
return set_ntstatus( status );
}
/***********************************************************************
* SetFileInformationByHandle (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetFileInformationByHandle( HANDLE file, FILE_INFO_BY_HANDLE_CLASS class,
void *info, DWORD size )
{
NTSTATUS status;
IO_STATUS_BLOCK io;
TRACE( "%p %u %p %u\n", file, class, info, size );
switch (class)
{
case FileNameInfo:
case FileRenameInfo:
case FileAllocationInfo:
case FileEndOfFileInfo:
case FileStreamInfo:
case FileIdBothDirectoryInfo:
case FileIdBothDirectoryRestartInfo:
case FileFullDirectoryInfo:
case FileFullDirectoryRestartInfo:
case FileStorageInfo:
case FileAlignmentInfo:
case FileIdInfo:
case FileIdExtdDirectoryInfo:
case FileIdExtdDirectoryRestartInfo:
FIXME( "%p, %u, %p, %u\n", file, class, info, size );
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
case FileBasicInfo:
status = NtSetInformationFile( file, &io, info, size, FileBasicInformation );
break;
case FileDispositionInfo:
status = NtSetInformationFile( file, &io, info, size, FileDispositionInformation );
break;
case FileIoPriorityHintInfo:
status = NtSetInformationFile( file, &io, info, size, FileIoPriorityHintInformation );
break;
case FileStandardInfo:
case FileCompressionInfo:
case FileAttributeTagInfo:
case FileRemoteProtocolInfo:
default:
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
return set_ntstatus( status );
}
/***********************************************************************
* SetFilePointer (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH SetFilePointer( HANDLE file, LONG distance, LONG *highword, DWORD method )
{
LARGE_INTEGER dist, newpos;
if (highword)
{
dist.u.LowPart = distance;
dist.u.HighPart = *highword;
}
else dist.QuadPart = distance;
if (!SetFilePointerEx( file, dist, &newpos, method )) return INVALID_SET_FILE_POINTER;
if (highword) *highword = newpos.u.HighPart;
if (newpos.u.LowPart == INVALID_SET_FILE_POINTER) SetLastError( 0 );
return newpos.u.LowPart;
}
/***********************************************************************
* SetFilePointerEx (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetFilePointerEx( HANDLE file, LARGE_INTEGER distance,
LARGE_INTEGER *newpos, DWORD method )
{
LONGLONG pos;
IO_STATUS_BLOCK io;
FILE_POSITION_INFORMATION info;
FILE_END_OF_FILE_INFORMATION eof;
switch(method)
{
case FILE_BEGIN:
pos = distance.QuadPart;
break;
case FILE_CURRENT:
if (NtQueryInformationFile( file, &io, &info, sizeof(info), FilePositionInformation ))
goto error;
pos = info.CurrentByteOffset.QuadPart + distance.QuadPart;
break;
case FILE_END:
if (NtQueryInformationFile( file, &io, &eof, sizeof(eof), FileEndOfFileInformation ))
goto error;
pos = eof.EndOfFile.QuadPart + distance.QuadPart;
break;
default:
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (pos < 0)
{
SetLastError( ERROR_NEGATIVE_SEEK );
return FALSE;
}
info.CurrentByteOffset.QuadPart = pos;
if (!NtSetInformationFile( file, &io, &info, sizeof(info), FilePositionInformation ))
{
if (newpos) newpos->QuadPart = pos;
return TRUE;
}
error:
return set_ntstatus( io.u.Status );
}
/***********************************************************************
* SetFileTime (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetFileTime( HANDLE file, const FILETIME *ctime,
const FILETIME *atime, const FILETIME *mtime )
{
FILE_BASIC_INFORMATION info;
IO_STATUS_BLOCK io;
memset( &info, 0, sizeof(info) );
if (ctime)
{
info.CreationTime.u.HighPart = ctime->dwHighDateTime;
info.CreationTime.u.LowPart = ctime->dwLowDateTime;
}
if (atime)
{
info.LastAccessTime.u.HighPart = atime->dwHighDateTime;
info.LastAccessTime.u.LowPart = atime->dwLowDateTime;
}
if (mtime)
{
info.LastWriteTime.u.HighPart = mtime->dwHighDateTime;
info.LastWriteTime.u.LowPart = mtime->dwLowDateTime;
}
return set_ntstatus( NtSetInformationFile( file, &io, &info, sizeof(info), FileBasicInformation ));
}
/***********************************************************************
* SetFileValidData (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetFileValidData( HANDLE file, LONGLONG length )
{
FILE_VALID_DATA_LENGTH_INFORMATION info;
IO_STATUS_BLOCK io;
info.ValidDataLength.QuadPart = length;
return set_ntstatus( NtSetInformationFile( file, &io, &info, sizeof(info),
FileValidDataLengthInformation ));
}
/**************************************************************************
* UnlockFile (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH UnlockFile( HANDLE file, DWORD offset_low, DWORD offset_high,
DWORD count_low, DWORD count_high )
{
LARGE_INTEGER count, offset;
count.u.LowPart = count_low;
count.u.HighPart = count_high;
offset.u.LowPart = offset_low;
offset.u.HighPart = offset_high;
return set_ntstatus( NtUnlockFile( file, NULL, &offset, &count, NULL ));
}
/**************************************************************************
* UnlockFileEx (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH UnlockFileEx( HANDLE file, DWORD reserved,
DWORD count_low, DWORD count_high, LPOVERLAPPED overlapped )
{
if (reserved)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (overlapped->hEvent) FIXME("Unimplemented overlapped operation\n");
return UnlockFile( file, overlapped->u.s.Offset, overlapped->u.s.OffsetHigh, count_low, count_high );
}
/***********************************************************************
* WriteFile (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH WriteFile( HANDLE file, LPCVOID buffer, DWORD count,
LPDWORD result, LPOVERLAPPED overlapped )
{
HANDLE event = NULL;
LARGE_INTEGER offset;
PLARGE_INTEGER poffset = NULL;
NTSTATUS status;
IO_STATUS_BLOCK iosb;
PIO_STATUS_BLOCK piosb = &iosb;
LPVOID cvalue = NULL;
TRACE( "%p %p %d %p %p\n", file, buffer, count, result, overlapped );
if (is_console_handle( file )) return WriteConsoleA( file, buffer, count, result, NULL);
if (overlapped)
{
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
poffset = &offset;
event = overlapped->hEvent;
piosb = (PIO_STATUS_BLOCK)overlapped;
if (((ULONG_PTR)event & 1) == 0) cvalue = overlapped;
}
else piosb->Information = 0;
piosb->u.Status = STATUS_PENDING;
status = NtWriteFile( file, event, NULL, cvalue, piosb, buffer, count, poffset, NULL );
if (status == STATUS_PENDING && !overlapped)
{
WaitForSingleObject( file, INFINITE );
status = piosb->u.Status;
}
if (result) *result = overlapped && status ? 0 : piosb->Information;
if (status && status != STATUS_TIMEOUT)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* WriteFileEx (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH WriteFileEx( HANDLE file, LPCVOID buffer,
DWORD count, LPOVERLAPPED overlapped,
LPOVERLAPPED_COMPLETION_ROUTINE completion )
{
LARGE_INTEGER offset;
NTSTATUS status;
PIO_STATUS_BLOCK io;
TRACE( "%p %p %d %p %p\n", file, buffer, count, overlapped, completion );
if (!overlapped)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
io = (PIO_STATUS_BLOCK)overlapped;
io->u.Status = STATUS_PENDING;
io->Information = 0;
status = NtWriteFile( file, NULL, read_write_apc, completion, io, buffer, count, &offset, NULL );
if (status == STATUS_PENDING) return TRUE;
return set_ntstatus( status );
}
/***********************************************************************
* WriteFileGather (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH WriteFileGather( HANDLE file, FILE_SEGMENT_ELEMENT *segments, DWORD count,
LPDWORD reserved, LPOVERLAPPED overlapped )
{
PIO_STATUS_BLOCK io;
LARGE_INTEGER offset;
void *cvalue = NULL;
TRACE( "%p %p %u %p\n", file, segments, count, overlapped );
offset.u.LowPart = overlapped->u.s.Offset;
offset.u.HighPart = overlapped->u.s.OffsetHigh;
if (!((ULONG_PTR)overlapped->hEvent & 1)) cvalue = overlapped;
io = (PIO_STATUS_BLOCK)overlapped;
io->u.Status = STATUS_PENDING;
io->Information = 0;
return set_ntstatus( NtWriteFileGather( file, overlapped->hEvent, NULL, cvalue,
io, segments, count, &offset, NULL ));
}
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
extern WCHAR *file_name_AtoW( LPCSTR name, BOOL alloc ) DECLSPEC_HIDDEN;
extern DWORD file_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen ) DECLSPEC_HIDDEN;
static inline BOOL is_console_handle(HANDLE h) static inline BOOL is_console_handle(HANDLE h)
{ {
return h != INVALID_HANDLE_VALUE && ((UINT_PTR)h & 3) == 3; return h != INVALID_HANDLE_VALUE && ((UINT_PTR)h & 3) == 3;
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
# @ stub ApplicationUserModelIdFromProductId # @ stub ApplicationUserModelIdFromProductId
@ stdcall AreAllAccessesGranted(long long) @ stdcall AreAllAccessesGranted(long long)
@ stdcall AreAnyAccessesGranted(long long) @ stdcall AreAnyAccessesGranted(long long)
@ stdcall AreFileApisANSI() kernel32.AreFileApisANSI @ stdcall AreFileApisANSI()
# @ stub AreThereVisibleLogoffScriptsInternal # @ stub AreThereVisibleLogoffScriptsInternal
# @ stub AreThereVisibleShutdownScriptsInternal # @ stub AreThereVisibleShutdownScriptsInternal
@ stdcall AttachConsole(long) kernel32.AttachConsole @ stdcall AttachConsole(long) kernel32.AttachConsole
...@@ -102,9 +102,9 @@ ...@@ -102,9 +102,9 @@
# @ stub CLOSE_LOCAL_HANDLE_INTERNAL # @ stub CLOSE_LOCAL_HANDLE_INTERNAL
@ stdcall CallNamedPipeW(wstr ptr long ptr long ptr long) @ stdcall CallNamedPipeW(wstr ptr long ptr long ptr long)
@ stdcall CallbackMayRunLong(ptr) @ stdcall CallbackMayRunLong(ptr)
@ stdcall CancelIo(long) kernel32.CancelIo @ stdcall CancelIo(long)
@ stdcall CancelIoEx(long ptr) kernel32.CancelIoEx @ stdcall CancelIoEx(long ptr)
@ stdcall CancelSynchronousIo(long) kernel32.CancelSynchronousIo @ stdcall CancelSynchronousIo(long)
@ stub CancelThreadpoolIo @ stub CancelThreadpoolIo
@ stdcall CancelWaitableTimer(long) @ stdcall CancelWaitableTimer(long)
# @ stub CeipIsOptedIn # @ stub CeipIsOptedIn
...@@ -380,7 +380,7 @@ ...@@ -380,7 +380,7 @@
@ stdcall FlsGetValue(long) @ stdcall FlsGetValue(long)
@ stdcall FlsSetValue(long ptr) @ stdcall FlsSetValue(long ptr)
@ stdcall FlushConsoleInputBuffer(long) kernel32.FlushConsoleInputBuffer @ stdcall FlushConsoleInputBuffer(long) kernel32.FlushConsoleInputBuffer
@ stdcall FlushFileBuffers(long) kernel32.FlushFileBuffers @ stdcall FlushFileBuffers(long)
@ stdcall FlushInstructionCache(long long long) @ stdcall FlushInstructionCache(long long long)
@ stdcall FlushProcessWriteBuffers() kernel32.FlushProcessWriteBuffers @ stdcall FlushProcessWriteBuffers() kernel32.FlushProcessWriteBuffers
@ stdcall FlushViewOfFile(ptr long) kernel32.FlushViewOfFile @ stdcall FlushViewOfFile(ptr long) kernel32.FlushViewOfFile
...@@ -506,15 +506,15 @@ ...@@ -506,15 +506,15 @@
@ stdcall GetFileAttributesExA(str long ptr) kernel32.GetFileAttributesExA @ stdcall GetFileAttributesExA(str long ptr) kernel32.GetFileAttributesExA
@ stdcall GetFileAttributesExW(wstr long ptr) kernel32.GetFileAttributesExW @ stdcall GetFileAttributesExW(wstr long ptr) kernel32.GetFileAttributesExW
@ stdcall GetFileAttributesW(wstr) kernel32.GetFileAttributesW @ stdcall GetFileAttributesW(wstr) kernel32.GetFileAttributesW
@ stdcall GetFileInformationByHandle(long ptr) kernel32.GetFileInformationByHandle @ stdcall GetFileInformationByHandle(long ptr)
@ stdcall GetFileInformationByHandleEx(long long ptr long) kernel32.GetFileInformationByHandleEx @ stdcall GetFileInformationByHandleEx(long long ptr long)
@ stdcall GetFileMUIInfo(long wstr ptr ptr) kernel32.GetFileMUIInfo @ stdcall GetFileMUIInfo(long wstr ptr ptr) kernel32.GetFileMUIInfo
@ stdcall GetFileMUIPath(long wstr wstr ptr ptr ptr ptr) kernel32.GetFileMUIPath @ stdcall GetFileMUIPath(long wstr wstr ptr ptr ptr ptr) kernel32.GetFileMUIPath
@ stdcall GetFileSecurityW(wstr long ptr long ptr) @ stdcall GetFileSecurityW(wstr long ptr long ptr)
@ stdcall GetFileSize(long ptr) kernel32.GetFileSize @ stdcall GetFileSize(long ptr)
@ stdcall GetFileSizeEx(long ptr) kernel32.GetFileSizeEx @ stdcall GetFileSizeEx(long ptr)
@ stdcall GetFileTime(long ptr ptr ptr) kernel32.GetFileTime @ stdcall GetFileTime(long ptr ptr ptr)
@ stdcall GetFileType(long) kernel32.GetFileType @ stdcall GetFileType(long)
@ stdcall GetFileVersionInfoA(str long long ptr) @ stdcall GetFileVersionInfoA(str long long ptr)
# @ stub GetFileVersionInfoByHandle # @ stub GetFileVersionInfoByHandle
@ stdcall GetFileVersionInfoExA(long str long long ptr) @ stdcall GetFileVersionInfoExA(long str long long ptr)
...@@ -584,7 +584,7 @@ ...@@ -584,7 +584,7 @@
@ stdcall GetOEMCP() kernel32.GetOEMCP @ stdcall GetOEMCP() kernel32.GetOEMCP
# @ stub GetOsManufacturingMode # @ stub GetOsManufacturingMode
# @ stub GetOsSafeBootMode # @ stub GetOsSafeBootMode
@ stdcall GetOverlappedResult(long ptr ptr long) kernel32.GetOverlappedResult @ stdcall GetOverlappedResult(long ptr ptr long)
# @ stub GetOverlappedResultEx # @ stub GetOverlappedResultEx
# @ stub GetPackageApplicationContext # @ stub GetPackageApplicationContext
# @ stub GetPackageApplicationIds # @ stub GetPackageApplicationIds
...@@ -941,8 +941,8 @@ ...@@ -941,8 +941,8 @@
@ stdcall LocalUnlock(long) kernel32.LocalUnlock @ stdcall LocalUnlock(long) kernel32.LocalUnlock
@ stdcall LocaleNameToLCID(wstr long) kernel32.LocaleNameToLCID @ stdcall LocaleNameToLCID(wstr long) kernel32.LocaleNameToLCID
# @ stub LocateXStateFeature # @ stub LocateXStateFeature
@ stdcall LockFile(long long long long long) kernel32.LockFile @ stdcall LockFile(long long long long long)
@ stdcall LockFileEx(long long long long long ptr) kernel32.LockFileEx @ stdcall LockFileEx(long long long long long ptr)
@ stdcall LockResource(long) @ stdcall LockResource(long)
@ stdcall MakeAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall MakeAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr)
@ stub MakeAbsoluteSD2 @ stub MakeAbsoluteSD2
...@@ -1247,9 +1247,9 @@ ...@@ -1247,9 +1247,9 @@
@ stdcall ReadConsoleOutputW(long ptr long long ptr) kernel32.ReadConsoleOutputW @ stdcall ReadConsoleOutputW(long ptr long long ptr) kernel32.ReadConsoleOutputW
@ stdcall ReadConsoleW(long ptr long ptr ptr) kernel32.ReadConsoleW @ stdcall ReadConsoleW(long ptr long ptr ptr) kernel32.ReadConsoleW
@ stdcall ReadDirectoryChangesW(long ptr long long long ptr ptr ptr) kernel32.ReadDirectoryChangesW @ stdcall ReadDirectoryChangesW(long ptr long long long ptr ptr ptr) kernel32.ReadDirectoryChangesW
@ stdcall ReadFile(long ptr long ptr ptr) kernel32.ReadFile @ stdcall ReadFile(long ptr long ptr ptr)
@ stdcall ReadFileEx(long ptr long ptr ptr) kernel32.ReadFileEx @ stdcall ReadFileEx(long ptr long ptr ptr)
@ stdcall ReadFileScatter(long ptr long ptr ptr) kernel32.ReadFileScatter @ stdcall ReadFileScatter(long ptr long ptr ptr)
@ stdcall ReadProcessMemory(long ptr ptr long ptr) kernel32.ReadProcessMemory @ stdcall ReadProcessMemory(long ptr ptr long ptr) kernel32.ReadProcessMemory
# @ stub ReadStateAtomValue # @ stub ReadStateAtomValue
# @ stub ReadStateContainerValue # @ stub ReadStateContainerValue
...@@ -1422,24 +1422,24 @@ ...@@ -1422,24 +1422,24 @@
@ stdcall SetCurrentDirectoryW(wstr) kernel32.SetCurrentDirectoryW @ stdcall SetCurrentDirectoryW(wstr) kernel32.SetCurrentDirectoryW
@ stdcall SetDefaultDllDirectories(long) kernel32.SetDefaultDllDirectories @ stdcall SetDefaultDllDirectories(long) kernel32.SetDefaultDllDirectories
# @ stub SetDynamicTimeZoneInformation # @ stub SetDynamicTimeZoneInformation
@ stdcall SetEndOfFile(long) kernel32.SetEndOfFile @ stdcall SetEndOfFile(long)
@ stub SetEnvironmentStringsW @ stub SetEnvironmentStringsW
@ stdcall SetEnvironmentVariableA(str str) kernel32.SetEnvironmentVariableA @ stdcall SetEnvironmentVariableA(str str) kernel32.SetEnvironmentVariableA
@ stdcall SetEnvironmentVariableW(wstr wstr) kernel32.SetEnvironmentVariableW @ stdcall SetEnvironmentVariableW(wstr wstr) kernel32.SetEnvironmentVariableW
@ stdcall SetErrorMode(long) @ stdcall SetErrorMode(long)
@ stdcall SetEvent(long) @ stdcall SetEvent(long)
@ stdcall SetEventWhenCallbackReturns(ptr long) ntdll.TpCallbackSetEventOnCompletion @ stdcall SetEventWhenCallbackReturns(ptr long) ntdll.TpCallbackSetEventOnCompletion
@ stdcall SetFileApisToANSI() kernel32.SetFileApisToANSI @ stdcall SetFileApisToANSI()
@ stdcall SetFileApisToOEM() kernel32.SetFileApisToOEM @ stdcall SetFileApisToOEM()
@ stdcall SetFileAttributesA(str long) kernel32.SetFileAttributesA @ stdcall SetFileAttributesA(str long) kernel32.SetFileAttributesA
@ stdcall SetFileAttributesW(wstr long) kernel32.SetFileAttributesW @ stdcall SetFileAttributesW(wstr long) kernel32.SetFileAttributesW
@ stdcall SetFileInformationByHandle(long long ptr long) kernel32.SetFileInformationByHandle @ stdcall SetFileInformationByHandle(long long ptr long)
# @ stub SetFileIoOverlappedRange # @ stub SetFileIoOverlappedRange
@ stdcall SetFilePointer(long long ptr long) kernel32.SetFilePointer @ stdcall SetFilePointer(long long ptr long)
@ stdcall SetFilePointerEx(long int64 ptr long) kernel32.SetFilePointerEx @ stdcall SetFilePointerEx(long int64 ptr long)
@ stdcall SetFileSecurityW(wstr long ptr) @ stdcall SetFileSecurityW(wstr long ptr)
@ stdcall SetFileTime(long ptr ptr ptr) kernel32.SetFileTime @ stdcall SetFileTime(long ptr ptr ptr)
@ stdcall SetFileValidData(ptr int64) kernel32.SetFileValidData @ stdcall SetFileValidData(ptr int64)
@ stdcall SetHandleCount(long) kernel32.SetHandleCount @ stdcall SetHandleCount(long) kernel32.SetHandleCount
@ stdcall SetHandleInformation(long long long) kernel32.SetHandleInformation @ stdcall SetHandleInformation(long long long) kernel32.SetHandleInformation
# @ stub SetIsDeveloperModeEnabled # @ stub SetIsDeveloperModeEnabled
...@@ -1613,8 +1613,8 @@ ...@@ -1613,8 +1613,8 @@
@ stdcall TzSpecificLocalTimeToSystemTime(ptr ptr ptr) kernel32.TzSpecificLocalTimeToSystemTime @ stdcall TzSpecificLocalTimeToSystemTime(ptr ptr ptr) kernel32.TzSpecificLocalTimeToSystemTime
@ stub TzSpecificLocalTimeToSystemTimeEx @ stub TzSpecificLocalTimeToSystemTimeEx
@ stdcall UnhandledExceptionFilter(ptr) kernel32.UnhandledExceptionFilter @ stdcall UnhandledExceptionFilter(ptr) kernel32.UnhandledExceptionFilter
@ stdcall UnlockFile(long long long long long) kernel32.UnlockFile @ stdcall UnlockFile(long long long long long)
@ stdcall UnlockFileEx(long long long long ptr) kernel32.UnlockFileEx @ stdcall UnlockFileEx(long long long long ptr)
@ stdcall UnmapViewOfFile(ptr) kernel32.UnmapViewOfFile @ stdcall UnmapViewOfFile(ptr) kernel32.UnmapViewOfFile
# @ stub UnmapViewOfFileEx # @ stub UnmapViewOfFileEx
# @ stub UnregisterBadMemoryNotification # @ stub UnregisterBadMemoryNotification
...@@ -1726,9 +1726,9 @@ ...@@ -1726,9 +1726,9 @@
@ stdcall WriteConsoleOutputCharacterW(long ptr long long ptr) kernel32.WriteConsoleOutputCharacterW @ stdcall WriteConsoleOutputCharacterW(long ptr long long ptr) kernel32.WriteConsoleOutputCharacterW
@ stdcall WriteConsoleOutputW(long ptr long long ptr) kernel32.WriteConsoleOutputW @ stdcall WriteConsoleOutputW(long ptr long long ptr) kernel32.WriteConsoleOutputW
@ stdcall WriteConsoleW(long ptr long ptr ptr) kernel32.WriteConsoleW @ stdcall WriteConsoleW(long ptr long ptr ptr) kernel32.WriteConsoleW
@ stdcall WriteFile(long ptr long ptr ptr) kernel32.WriteFile @ stdcall WriteFile(long ptr long ptr ptr)
@ stdcall WriteFileEx(long ptr long ptr ptr) kernel32.WriteFileEx @ stdcall WriteFileEx(long ptr long ptr ptr)
@ stdcall WriteFileGather(long ptr long ptr ptr) kernel32.WriteFileGather @ stdcall WriteFileGather(long ptr long ptr ptr)
@ stdcall WriteProcessMemory(long ptr ptr long ptr) kernel32.WriteProcessMemory @ stdcall WriteProcessMemory(long ptr ptr long ptr) kernel32.WriteProcessMemory
# @ stub WriteStateAtomValue # @ stub WriteStateAtomValue
# @ stub WriteStateContainerValue # @ stub WriteStateContainerValue
......
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