- start moving a few file related functions from files/file.c to

dlls/kernel subdir (also splitting 16bit APIs in a separate file)
- implemented ntdll.Nt{Lock|Unlock}File, and made use of those for the
  kernel32 equivalent
- implemented a few information classes in NtQueryInformationFile and
  NtSetInformationFile (still lots of missing classes)
- enhanced the get_file_info server request in order to implement
  correctly NtQueryInformationFile (change time & file alloc size)
- rewrote registry loading to comply with latest changes
This commit is contained in:
Eric Pouech 2003-06-24 02:32:01 +00:00 committed by Alexandre Julliard
parent 6c9b097fae
commit f6a70969e1
13 changed files with 874 additions and 542 deletions

View File

@ -28,6 +28,8 @@ C_SRCS = \
console.c \ console.c \
debugger.c \ debugger.c \
editline.c \ editline.c \
file.c \
file16.c \
format_msg.c \ format_msg.c \
kernel_main.c \ kernel_main.c \
lcformat.c \ lcformat.c \

347
dlls/kernel/file.c Normal file
View File

@ -0,0 +1,347 @@
/*
* File handling functions
*
* Copyright 1993 John Burton
* Copyright 1996 Alexandre Julliard
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* TODO:
* Fix the CopyFileEx methods to implement the "extended" functionality.
* Right now, they simply call the CopyFile method.
*/
#include "config.h"
#include "wine/port.h"
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "kernel_private.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(file);
/**************************************************************************
* Operations on file handles *
**************************************************************************/
/***********************************************************************
* _hread (KERNEL32.@)
*/
LONG WINAPI _hread( HFILE hFile, LPVOID buffer, LONG count)
{
return _lread( hFile, buffer, count );
}
/***********************************************************************
* _hwrite (KERNEL32.@)
*
* experimentation yields that _lwrite:
* o truncates the file at the current position with
* a 0 len write
* o returns 0 on a 0 length write
* o works with console handles
*
*/
LONG WINAPI _hwrite( HFILE handle, LPCSTR buffer, LONG count )
{
DWORD result;
TRACE("%d %p %ld\n", handle, buffer, count );
if (!count)
{
/* Expand or truncate at current position */
if (!SetEndOfFile( (HANDLE)handle )) return HFILE_ERROR;
return 0;
}
if (!WriteFile( (HANDLE)handle, buffer, count, &result, NULL ))
return HFILE_ERROR;
return result;
}
/***********************************************************************
* _lclose (KERNEL32.@)
*/
HFILE WINAPI _lclose( HFILE hFile )
{
TRACE("handle %d\n", hFile );
return CloseHandle( (HANDLE)hFile ) ? 0 : HFILE_ERROR;
}
/***********************************************************************
* _lcreat (KERNEL32.@)
*/
HFILE WINAPI _lcreat( LPCSTR path, INT attr )
{
/* Mask off all flags not explicitly allowed by the doc */
attr &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
TRACE("%s %02x\n", path, attr );
return (HFILE)CreateFileA( path, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, attr, 0 );
}
/***********************************************************************
* _lopen (KERNEL32.@)
*/
HFILE WINAPI _lopen( LPCSTR path, INT mode )
{
DWORD access, sharing;
TRACE("('%s',%04x)\n", path, mode );
FILE_ConvertOFMode( mode, &access, &sharing );
return (HFILE)CreateFileA( path, access, sharing, NULL, OPEN_EXISTING, 0, 0 );
}
/***********************************************************************
* _lread (KERNEL32.@)
*/
UINT WINAPI _lread( HFILE handle, LPVOID buffer, UINT count )
{
DWORD result;
if (!ReadFile( (HANDLE)handle, buffer, count, &result, NULL )) return -1;
return result;
}
/***********************************************************************
* _llseek (KERNEL32.@)
*/
LONG WINAPI _llseek( HFILE hFile, LONG lOffset, INT nOrigin )
{
return SetFilePointer( (HANDLE)hFile, lOffset, NULL, nOrigin );
}
/***********************************************************************
* _lwrite (KERNEL32.@)
*/
UINT WINAPI _lwrite( HFILE hFile, LPCSTR buffer, UINT count )
{
return (UINT)_hwrite( hFile, buffer, (LONG)count );
}
/***********************************************************************
* FlushFileBuffers (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 */
/* FIXME: wait until FlushFileBuffers is moved to dll/kernel */
/* return FlushConsoleInputBuffer( hFile ); */
return TRUE;
}
nts = NtFlushBuffersFile( hFile, &ioblk );
if (nts != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError( nts ) );
return FALSE;
}
return TRUE;
}
/***********************************************************************
* GetFileSize (KERNEL32.@)
*/
DWORD WINAPI GetFileSize( HANDLE hFile, LPDWORD filesizehigh )
{
BY_HANDLE_FILE_INFORMATION info;
if (!GetFileInformationByHandle( hFile, &info )) return -1;
if (filesizehigh) *filesizehigh = info.nFileSizeHigh;
return info.nFileSizeLow;
}
/***********************************************************************
* GetFileSizeEx (KERNEL32.@)
*/
BOOL WINAPI GetFileSizeEx( HANDLE hFile, PLARGE_INTEGER lpFileSize )
{
BY_HANDLE_FILE_INFORMATION info;
if (!lpFileSize)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (!GetFileInformationByHandle( hFile, &info ))
{
return FALSE;
}
lpFileSize->s.LowPart = info.nFileSizeLow;
lpFileSize->s.HighPart = info.nFileSizeHigh;
return TRUE;
}
/**************************************************************************
* 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 %lx%08lx %lx%08lx\n",
hFile, offset_high, offset_low, count_high, count_low );
count.s.LowPart = count_low;
count.s.HighPart = count_high;
offset.s.LowPart = offset_low;
offset.s.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;
if (reserved)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
TRACE( "%p %lx%08lx %lx%08lx flags %lx\n",
hFile, overlapped->OffsetHigh, overlapped->Offset,
count_high, count_low, flags );
count.s.LowPart = count_low;
count.s.HighPart = count_high;
offset.s.LowPart = overlapped->Offset;
offset.s.HighPart = overlapped->OffsetHigh;
status = NtLockFile( hFile, overlapped->hEvent, NULL, NULL,
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.s.LowPart = count_low;
count.s.HighPart = count_high;
offset.s.LowPart = offset_low;
offset.s.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->Offset, overlapped->OffsetHigh, count_low, count_high );
}
/**************************************************************************
* Operations on file names *
**************************************************************************/
/**************************************************************************
* ReplaceFileW (KERNEL32.@)
* ReplaceFile (KERNEL32.@)
*/
BOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName,LPCWSTR lpReplacementFileName,
LPCWSTR lpBackupFileName, DWORD dwReplaceFlags,
LPVOID lpExclude, LPVOID lpReserved)
{
FIXME("(%s,%s,%s,%08lx,%p,%p) stub\n",debugstr_w(lpReplacedFileName),debugstr_w(lpReplacementFileName),
debugstr_w(lpBackupFileName),dwReplaceFlags,lpExclude,lpReserved);
SetLastError(ERROR_UNABLE_TO_MOVE_REPLACEMENT);
return FALSE;
}
/**************************************************************************
* ReplaceFileA (KERNEL32.@)
*/
BOOL WINAPI ReplaceFileA(LPCSTR lpReplacedFileName,LPCSTR lpReplacementFileName,
LPCSTR lpBackupFileName, DWORD dwReplaceFlags,
LPVOID lpExclude, LPVOID lpReserved)
{
FIXME("(%s,%s,%s,%08lx,%p,%p) stub\n",lpReplacedFileName,lpReplacementFileName,
lpBackupFileName,dwReplaceFlags,lpExclude,lpReserved);
SetLastError(ERROR_UNABLE_TO_MOVE_REPLACEMENT);
return FALSE;
}

220
dlls/kernel/file16.c Normal file
View File

@ -0,0 +1,220 @@
/*
* File handling functions
*
* Copyright 1993 John Burton
* Copyright 1996 Alexandre Julliard
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* TODO:
* Fix the CopyFileEx methods to implement the "extended" functionality.
* Right now, they simply call the CopyFile method.
*/
#include "config.h"
#include "wine/port.h"
#include <stdio.h>
#include <assert.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wine/winbase16.h"
#include "wine/server.h"
#include "msdos.h"
#include "kernel_private.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(file);
/***********************************************************************
* _hread16 (KERNEL.349)
*/
LONG WINAPI _hread16( HFILE16 hFile, LPVOID buffer, LONG count)
{
return _lread( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, count );
}
/***********************************************************************
* _hwrite (KERNEL.350)
*/
LONG WINAPI _hwrite16( HFILE16 hFile, LPCSTR buffer, LONG count )
{
return _hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, count );
}
/***********************************************************************
* _lcreat (KERNEL.83)
*/
HFILE16 WINAPI _lcreat16( LPCSTR path, INT16 attr )
{
return Win32HandleToDosFileHandle( (HANDLE)_lcreat( path, attr ) );
}
/***********************************************************************
* _llseek (KERNEL.84)
*
* FIXME:
* Seeking before the start of the file should be allowed for _llseek16,
* but cause subsequent I/O operations to fail (cf. interrupt list)
*
*/
LONG WINAPI _llseek16( HFILE16 hFile, LONG lOffset, INT16 nOrigin )
{
return SetFilePointer( DosFileHandleToWin32Handle(hFile), lOffset, NULL, nOrigin );
}
/***********************************************************************
* _lopen (KERNEL.85)
*/
HFILE16 WINAPI _lopen16( LPCSTR path, INT16 mode )
{
return Win32HandleToDosFileHandle( (HANDLE)_lopen( path, mode ) );
}
/***********************************************************************
* _lread16 (KERNEL.82)
*/
UINT16 WINAPI _lread16( HFILE16 hFile, LPVOID buffer, UINT16 count )
{
return (UINT16)_lread((HFILE)DosFileHandleToWin32Handle(hFile), buffer, (LONG)count );
}
/***********************************************************************
* _lwrite (KERNEL.86)
*/
UINT16 WINAPI _lwrite16( HFILE16 hFile, LPCSTR buffer, UINT16 count )
{
return (UINT16)_hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, (LONG)count );
}
/***********************************************************************
* _hread (KERNEL.349)
*/
LONG WINAPI WIN16_hread( HFILE16 hFile, SEGPTR buffer, LONG count )
{
LONG maxlen;
TRACE("%d %08lx %ld\n", hFile, (DWORD)buffer, count );
/* Some programs pass a count larger than the allocated buffer */
maxlen = GetSelectorLimit16( SELECTOROF(buffer) ) - OFFSETOF(buffer) + 1;
if (count > maxlen) count = maxlen;
return _lread((HFILE)DosFileHandleToWin32Handle(hFile), MapSL(buffer), count );
}
/***********************************************************************
* _lread (KERNEL.82)
*/
UINT16 WINAPI WIN16_lread( HFILE16 hFile, SEGPTR buffer, UINT16 count )
{
return (UINT16)WIN16_hread( hFile, buffer, (LONG)count );
}
/***********************************************************************
* DeleteFile (KERNEL.146)
*/
BOOL16 WINAPI DeleteFile16( LPCSTR path )
{
return DeleteFileA( path );
}
/**************************************************************************
* GetFileAttributes (KERNEL.420)
*/
DWORD WINAPI GetFileAttributes16( LPCSTR name )
{
return GetFileAttributesA( name );
}
/***********************************************************************
* GetTempFileName (KERNEL.97)
*/
UINT16 WINAPI GetTempFileName16( BYTE drive, LPCSTR prefix, UINT16 unique,
LPSTR buffer )
{
char temppath[MAX_PATH];
char *prefix16 = NULL;
UINT16 ret;
if (!(drive & ~TF_FORCEDRIVE)) /* drive 0 means current default drive */
{
GetCurrentDirectoryA(sizeof(temppath), temppath);
drive |= temppath[0];
}
if (drive & TF_FORCEDRIVE)
{
char d[3];
d[0] = drive & ~TF_FORCEDRIVE;
d[1] = ':';
d[2] = '\0';
if (GetDriveTypeA(d) == DRIVE_NO_ROOT_DIR)
{
drive &= ~TF_FORCEDRIVE;
WARN("invalid drive %d specified\n", drive );
}
}
if (drive & TF_FORCEDRIVE)
sprintf(temppath,"%c:", drive & ~TF_FORCEDRIVE );
else
GetTempPathA( MAX_PATH, temppath );
if (prefix)
{
prefix16 = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + 2);
*prefix16 = '~';
strcpy(prefix16 + 1, prefix);
}
ret = GetTempFileNameA( temppath, prefix16, unique, buffer );
if (prefix16) HeapFree(GetProcessHeap(), 0, prefix16);
return ret;
}
/**************************************************************************
* SetFileAttributes (KERNEL.421)
*/
BOOL16 WINAPI SetFileAttributes16( LPCSTR lpFileName, DWORD attributes )
{
return SetFileAttributesA( lpFileName, attributes );
}
/***********************************************************************
* SetHandleCount (KERNEL.199)
*/
UINT16 WINAPI SetHandleCount16( UINT16 count )
{
return SetHandleCount( count );
}

View File

@ -44,4 +44,9 @@ static inline HANDLE console_handle_unmap(HANDLE h)
return h != INVALID_HANDLE_VALUE ? (HANDLE)((DWORD)h ^ 3) : INVALID_HANDLE_VALUE; return h != INVALID_HANDLE_VALUE ? (HANDLE)((DWORD)h ^ 3) : INVALID_HANDLE_VALUE;
} }
/* Size of per-process table of DOS handles */
#define DOS_TABLE_SIZE 256
extern HANDLE dos_handles[DOS_TABLE_SIZE];
void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing );
#endif #endif

View File

@ -345,32 +345,161 @@ NTSTATUS WINAPI NtSetVolumeInformationFile(
* NtQueryInformationFile [NTDLL.@] * NtQueryInformationFile [NTDLL.@]
* ZwQueryInformationFile [NTDLL.@] * ZwQueryInformationFile [NTDLL.@]
*/ */
NTSTATUS WINAPI NtQueryInformationFile( NTSTATUS WINAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
HANDLE FileHandle, PVOID ptr, LONG len,
PIO_STATUS_BLOCK IoStatusBlock, FILE_INFORMATION_CLASS class)
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass)
{ {
FIXME("(%p,%p,%p,0x%08lx,0x%08x),stub!\n", NTSTATUS status;
FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass); LONG used = 0;
return 0; BYTE answer[256];
time_t ct = 0, wt = 0, at = 0;
TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", hFile, io_status, ptr, len, class);
switch (class)
{
case FileBasicInformation:
{
FILE_BASIC_INFORMATION* fbi = (FILE_BASIC_INFORMATION*)answer;
if (sizeof(answer) < sizeof(*fbi)) goto too_small;
SERVER_START_REQ( get_file_info )
{
req->handle = hFile;
if (!(status = wine_server_call( req )))
{
/* FIXME: which file types are supported ?
* Serial ports (FILE_TYPE_CHAR) are not,
* and MSDN also says that pipes are not supported.
* FILE_TYPE_REMOTE seems to be supported according to
* MSDN q234741.txt */
if ((reply->type == FILE_TYPE_DISK) ||
(reply->type == FILE_TYPE_REMOTE))
{
at = reply->access_time;
wt = reply->write_time;
ct = reply->change_time;
fbi->FileAttributes = reply->attr;
used = sizeof(*fbi);
}
else status = STATUS_INVALID_HANDLE; /* FIXME ??? */
}
}
SERVER_END_REQ;
if (used)
{
RtlSecondsSince1970ToTime(wt, &fbi->CreationTime);
RtlSecondsSince1970ToTime(wt, &fbi->LastWriteTime);
RtlSecondsSince1970ToTime(ct, &fbi->ChangeTime);
RtlSecondsSince1970ToTime(at, &fbi->LastAccessTime);
}
}
break;
case FileStandardInformation:
{
FILE_STANDARD_INFORMATION* fsi = (FILE_STANDARD_INFORMATION*)answer;
if (sizeof(answer) < sizeof(*fsi)) goto too_small;
SERVER_START_REQ( get_file_info )
{
req->handle = hFile;
if (!(status = wine_server_call( req )))
{
/* FIXME: which file types are supported ?
* Serial ports (FILE_TYPE_CHAR) are not,
* and MSDN also says that pipes are not supported.
* FILE_TYPE_REMOTE seems to be supported according to
* MSDN q234741.txt */
if ((reply->type == FILE_TYPE_DISK) ||
(reply->type == FILE_TYPE_REMOTE))
{
fsi->AllocationSize.s.HighPart = reply->alloc_high;
fsi->AllocationSize.s.LowPart = reply->alloc_low;
fsi->EndOfFile.s.HighPart = reply->size_high;
fsi->EndOfFile.s.LowPart = reply->size_low;
fsi->NumberOfLinks = reply->links;
fsi->DeletePending = FALSE; /* FIXME */
fsi->Directory = (reply->attr & FILE_ATTRIBUTE_DIRECTORY);
used = sizeof(*fsi);
}
else status = STATUS_INVALID_HANDLE; /* FIXME ??? */
}
}
SERVER_END_REQ;
}
break;
case FilePositionInformation:
{
FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)answer;
if (sizeof(answer) < sizeof(*fpi)) goto too_small;
SERVER_START_REQ( set_file_pointer )
{
req->handle = hFile;
req->low = 0;
req->high = 0;
req->whence = SEEK_CUR;
if (!(status = wine_server_call( req )))
{
fpi->CurrentByteOffset.s.HighPart = reply->new_high;
fpi->CurrentByteOffset.s.LowPart = reply->new_low;
used = sizeof(*fpi);
}
}
SERVER_END_REQ;
}
break;
default:
FIXME("Unsupported class (%d)\n", class);
return io_status->u.Status = STATUS_NOT_IMPLEMENTED;
}
if (used) memcpy(ptr, answer, min(used, len));
io_status->u.Status = status;
io_status->Information = len;
return status;
too_small:
io_status->Information = 0;
return io_status->u.Status = STATUS_BUFFER_TOO_SMALL;
} }
/****************************************************************************** /******************************************************************************
* NtSetInformationFile [NTDLL.@] * NtSetInformationFile [NTDLL.@]
* ZwSetInformationFile [NTDLL.@] * ZwSetInformationFile [NTDLL.@]
*/ */
NTSTATUS WINAPI NtSetInformationFile( NTSTATUS WINAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
HANDLE FileHandle, PVOID ptr, ULONG len,
PIO_STATUS_BLOCK IoStatusBlock, FILE_INFORMATION_CLASS class)
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass)
{ {
FIXME("(%p,%p,%p,0x%08lx,0x%08x)\n", NTSTATUS status = STATUS_INVALID_PARAMETER_3;
FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
return 0; TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", hFile, io_status, ptr, len, class);
switch (class)
{
case FilePositionInformation:
if (len >= sizeof(FILE_POSITION_INFORMATION))
{
FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)ptr;
SERVER_START_REQ( set_file_pointer )
{
req->handle = hFile;
req->low = fpi->CurrentByteOffset.s.LowPart;
req->high = fpi->CurrentByteOffset.s.HighPart;
req->whence = SEEK_SET;
status = wine_server_call( req );
}
SERVER_END_REQ;
status = STATUS_SUCCESS;
}
break;
default:
FIXME("Unsupported class (%d)\n", class);
return STATUS_NOT_IMPLEMENTED;
}
io_status->u.Status = status;
io_status->Information = 0;
return status;
} }
/****************************************************************************** /******************************************************************************
@ -487,7 +616,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile (
case FileFsMaximumInformation: case FileFsMaximumInformation:
break; break;
} }
IoStatusBlock->DUMMYUNIONNAME.Status = STATUS_SUCCESS; IoStatusBlock->u.Status = STATUS_SUCCESS;
IoStatusBlock->Information = len; IoStatusBlock->Information = len;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -514,3 +643,103 @@ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock
} }
return ret; return ret;
} }
/******************************************************************
* NtLockFile (NTDLL.@)
*
*
*/
NTSTATUS WINAPI NtLockFile( HANDLE hFile, HANDLE lock_granted_event,
PIO_APC_ROUTINE apc, void* apc_user,
PIO_STATUS_BLOCK io_status, PLARGE_INTEGER offset,
PLARGE_INTEGER count, ULONG* key, BOOLEAN dont_wait,
BOOLEAN exclusive )
{
NTSTATUS ret;
HANDLE handle;
BOOLEAN async;
if (apc || io_status || key)
{
FIXME("Unimplemented yet parameter\n");
return STATUS_NOT_IMPLEMENTED;
}
for (;;)
{
SERVER_START_REQ( lock_file )
{
req->handle = hFile;
req->offset_low = offset->s.LowPart;
req->offset_high = offset->s.HighPart;
req->count_low = count->s.LowPart;
req->count_high = count->s.HighPart;
req->shared = !exclusive;
req->wait = !dont_wait;
ret = wine_server_call( req );
handle = reply->handle;
async = reply->overlapped;
}
SERVER_END_REQ;
if (ret != STATUS_PENDING)
{
if (!ret && lock_granted_event) NtSetEvent(lock_granted_event, NULL);
return ret;
}
if (async)
{
FIXME( "Async I/O lock wait not implemented, might deadlock\n" );
if (handle) NtClose( handle );
return STATUS_PENDING;
}
if (handle)
{
NtWaitForSingleObject( handle, FALSE, NULL );
NtClose( handle );
}
else
{
LARGE_INTEGER time;
/* Unix lock conflict, sleep a bit and retry */
time.QuadPart = 100 * (ULONGLONG)10000;
time.QuadPart = -time.QuadPart;
NtWaitForMultipleObjects( 0, NULL, FALSE, FALSE, &time );
}
}
}
/******************************************************************
* NtUnlockFile (NTDLL.@)
*
*
*/
NTSTATUS WINAPI NtUnlockFile( HANDLE hFile, PIO_STATUS_BLOCK io_status,
PLARGE_INTEGER offset, PLARGE_INTEGER count,
PULONG key )
{
NTSTATUS status;
TRACE( "%p %lx%08lx %lx%08lx\n",
hFile, offset->s.HighPart, offset->s.LowPart, count->s.HighPart, count->s.LowPart );
if (io_status || key)
{
FIXME("Unimplemented yet parameter\n");
return STATUS_NOT_IMPLEMENTED;
}
SERVER_START_REQ( unlock_file )
{
req->handle = hFile;
req->offset_low = offset->s.LowPart;
req->offset_high = offset->s.HighPart;
req->count_low = count->s.LowPart;
req->count_high = count->s.HighPart;
status = wine_server_call( req );
}
SERVER_END_REQ;
return status;
}

View File

@ -123,7 +123,7 @@
@ stdcall NtListenPort(ptr ptr) @ stdcall NtListenPort(ptr ptr)
@ stub NtLoadDriver @ stub NtLoadDriver
@ stdcall NtLoadKey(ptr ptr) @ stdcall NtLoadKey(ptr ptr)
@ stub NtLockFile @ stdcall NtLockFile(long long ptr ptr ptr ptr ptr ptr long long)
@ stdcall NtLockVirtualMemory(long ptr ptr long) @ stdcall NtLockVirtualMemory(long ptr ptr long)
@ stub NtMakeTemporaryObject @ stub NtMakeTemporaryObject
@ stdcall NtMapViewOfSection(long long ptr long long ptr ptr long long long) @ stdcall NtMapViewOfSection(long long ptr long long ptr ptr long long long)
@ -245,7 +245,7 @@
@ stub NtUnloadDriver @ stub NtUnloadDriver
@ stdcall NtUnloadKey(long) @ stdcall NtUnloadKey(long)
@ stub NtUnloadKeyEx @ stub NtUnloadKeyEx
@ stub NtUnlockFile @ stdcall NtUnlockFile(long ptr ptr ptr ptr)
@ stdcall NtUnlockVirtualMemory(long ptr ptr long) @ stdcall NtUnlockVirtualMemory(long ptr ptr long)
@ stdcall NtUnmapViewOfSection(long ptr) @ stdcall NtUnmapViewOfSection(long ptr)
@ stub NtVdmControl @ stub NtVdmControl
@ -655,7 +655,7 @@
@ stdcall ZwListenPort(ptr ptr) NtListenPort @ stdcall ZwListenPort(ptr ptr) NtListenPort
@ stub ZwLoadDriver @ stub ZwLoadDriver
@ stdcall ZwLoadKey(ptr ptr) NtLoadKey @ stdcall ZwLoadKey(ptr ptr) NtLoadKey
@ stub ZwLockFile @ stdcall ZwLockFile(long long ptr ptr ptr ptr ptr ptr long long) NtLockFile
@ stdcall ZwLockVirtualMemory(long ptr ptr long) NtLockVirtualMemory @ stdcall ZwLockVirtualMemory(long ptr ptr long) NtLockVirtualMemory
@ stub ZwMakeTemporaryObject @ stub ZwMakeTemporaryObject
@ stdcall ZwMapViewOfSection(long long ptr long long ptr ptr long long long) NtMapViewOfSection @ stdcall ZwMapViewOfSection(long long ptr long long ptr ptr long long long) NtMapViewOfSection
@ -774,7 +774,7 @@
@ stub ZwUnloadDriver @ stub ZwUnloadDriver
@ stdcall ZwUnloadKey(long) NtUnloadKey @ stdcall ZwUnloadKey(long) NtUnloadKey
@ stub ZwUnloadKeyEx @ stub ZwUnloadKeyEx
@ stub ZwUnlockFile @ stdcall ZwUnlockFile(long ptr ptr ptr ptr) NtUnlockFile
@ stdcall ZwUnlockVirtualMemory(long ptr ptr long) NtUnlockVirtualMemory @ stdcall ZwUnlockVirtualMemory(long ptr ptr long) NtUnlockVirtualMemory
@ stdcall ZwUnmapViewOfSection(long ptr) NtUnmapViewOfSection @ stdcall ZwUnmapViewOfSection(long ptr) NtUnmapViewOfSection
@ stub ZwVdmControl @ stub ZwVdmControl

View File

@ -82,14 +82,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(file);
#define MAP_ANON MAP_ANONYMOUS #define MAP_ANON MAP_ANONYMOUS
#endif #endif
/* Size of per-process table of DOS handles */
#define DOS_TABLE_SIZE 256
/* Macro to derive file offset from OVERLAPPED struct */ /* Macro to derive file offset from OVERLAPPED struct */
#define OVERLAPPED_OFFSET(overlapped) ((off_t) (overlapped)->Offset + ((off_t) (overlapped)->OffsetHigh << 32)) #define OVERLAPPED_OFFSET(overlapped) ((off_t) (overlapped)->Offset + ((off_t) (overlapped)->OffsetHigh << 32))
static HANDLE dos_handles[DOS_TABLE_SIZE]; HANDLE dos_handles[DOS_TABLE_SIZE];
mode_t FILE_umask; mode_t FILE_umask;
extern HANDLE WINAPI FILE_SmbOpen(LPCSTR name); extern HANDLE WINAPI FILE_SmbOpen(LPCSTR name);
@ -172,7 +168,7 @@ static void fileio_async_cleanup ( struct async_private *ovp )
* *
* Convert OF_* mode into flags for CreateFile. * Convert OF_* mode into flags for CreateFile.
*/ */
static void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing ) void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing )
{ {
switch(mode & 0x03) switch(mode & 0x03)
{ {
@ -920,15 +916,6 @@ DWORD WINAPI GetFileInformationByHandle( HANDLE hFile,
} }
/**************************************************************************
* GetFileAttributes (KERNEL.420)
*/
DWORD WINAPI GetFileAttributes16( LPCSTR name )
{
return GetFileAttributesA( name );
}
/************************************************************************** /**************************************************************************
* GetFileAttributesW (KERNEL32.@) * GetFileAttributesW (KERNEL32.@)
*/ */
@ -974,15 +961,6 @@ DWORD WINAPI GetFileAttributesA( LPCSTR name )
} }
/**************************************************************************
* SetFileAttributes (KERNEL.421)
*/
BOOL16 WINAPI SetFileAttributes16( LPCSTR lpFileName, DWORD attributes )
{
return SetFileAttributesA( lpFileName, attributes );
}
/************************************************************************** /**************************************************************************
* SetFileAttributesW (KERNEL32.@) * SetFileAttributesW (KERNEL32.@)
*/ */
@ -1081,43 +1059,6 @@ BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD attributes)
} }
/***********************************************************************
* GetFileSize (KERNEL32.@)
*/
DWORD WINAPI GetFileSize( HANDLE hFile, LPDWORD filesizehigh )
{
BY_HANDLE_FILE_INFORMATION info;
if (!GetFileInformationByHandle( hFile, &info )) return -1;
if (filesizehigh) *filesizehigh = info.nFileSizeHigh;
return info.nFileSizeLow;
}
/***********************************************************************
* GetFileSizeEx (KERNEL32.@)
*/
BOOL WINAPI GetFileSizeEx( HANDLE hFile, PLARGE_INTEGER lpFileSize )
{
BY_HANDLE_FILE_INFORMATION info;
if (!lpFileSize)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (!GetFileInformationByHandle( hFile, &info ))
{
return FALSE;
}
lpFileSize->s.LowPart = info.nFileSizeLow;
lpFileSize->s.HighPart = info.nFileSizeHigh;
return TRUE;
}
/*********************************************************************** /***********************************************************************
* GetFileTime (KERNEL32.@) * GetFileTime (KERNEL32.@)
*/ */
@ -1133,6 +1074,7 @@ BOOL WINAPI GetFileTime( HANDLE hFile, FILETIME *lpCreationTime,
return TRUE; return TRUE;
} }
/*********************************************************************** /***********************************************************************
* FILE_GetTempFileName : utility for GetTempFileName * FILE_GetTempFileName : utility for GetTempFileName
*/ */
@ -1244,51 +1186,12 @@ UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique,
} }
/***********************************************************************
* GetTempFileName (KERNEL.97)
*/
UINT16 WINAPI GetTempFileName16( BYTE drive, LPCSTR prefix, UINT16 unique,
LPSTR buffer )
{
char temppath[MAX_PATH];
char *prefix16 = NULL;
UINT16 ret;
if (!(drive & ~TF_FORCEDRIVE)) /* drive 0 means current default drive */
drive |= DRIVE_GetCurrentDrive() + 'A';
if ((drive & TF_FORCEDRIVE) &&
!DRIVE_IsValid( toupper(drive & ~TF_FORCEDRIVE) - 'A' ))
{
drive &= ~TF_FORCEDRIVE;
WARN("invalid drive %d specified\n", drive );
}
if (drive & TF_FORCEDRIVE)
sprintf(temppath,"%c:", drive & ~TF_FORCEDRIVE );
else
GetTempPathA( MAX_PATH, temppath );
if (prefix)
{
prefix16 = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + 2);
*prefix16 = '~';
strcpy(prefix16 + 1, prefix);
}
ret = GetTempFileNameA( temppath, prefix16, unique, buffer );
if (prefix16) HeapFree(GetProcessHeap(), 0, prefix16);
return ret;
}
/*********************************************************************** /***********************************************************************
* FILE_DoOpenFile * FILE_DoOpenFile
* *
* Implementation of OpenFile16() and OpenFile32(). * Implementation of OpenFile16() and OpenFile32().
*/ */
static HFILE FILE_DoOpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode, static HFILE FILE_DoOpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode, BOOL win32 )
BOOL win32 )
{ {
HFILE hFileRet; HFILE hFileRet;
HANDLE handle; HANDLE handle;
@ -1630,15 +1533,6 @@ HFILE16 WINAPI _lclose16( HFILE16 hFile )
} }
/***********************************************************************
* _lclose (KERNEL32.@)
*/
HFILE WINAPI _lclose( HFILE hFile )
{
TRACE("handle %d\n", hFile );
return CloseHandle( (HANDLE)hFile ) ? 0 : HFILE_ERROR;
}
/*********************************************************************** /***********************************************************************
* GetOverlappedResult (KERNEL32.@) * GetOverlappedResult (KERNEL32.@)
* *
@ -2212,75 +2106,6 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
} }
/***********************************************************************
* _hread (KERNEL.349)
*/
LONG WINAPI WIN16_hread( HFILE16 hFile, SEGPTR buffer, LONG count )
{
LONG maxlen;
TRACE("%d %08lx %ld\n",
hFile, (DWORD)buffer, count );
/* Some programs pass a count larger than the allocated buffer */
maxlen = GetSelectorLimit16( SELECTOROF(buffer) ) - OFFSETOF(buffer) + 1;
if (count > maxlen) count = maxlen;
return _lread((HFILE)DosFileHandleToWin32Handle(hFile), MapSL(buffer), count );
}
/***********************************************************************
* _lread (KERNEL.82)
*/
UINT16 WINAPI WIN16_lread( HFILE16 hFile, SEGPTR buffer, UINT16 count )
{
return (UINT16)WIN16_hread( hFile, buffer, (LONG)count );
}
/***********************************************************************
* _lread (KERNEL32.@)
*/
UINT WINAPI _lread( HFILE handle, LPVOID buffer, UINT count )
{
DWORD result;
if (!ReadFile( (HANDLE)handle, buffer, count, &result, NULL )) return -1;
return result;
}
/***********************************************************************
* _lread16 (KERNEL.82)
*/
UINT16 WINAPI _lread16( HFILE16 hFile, LPVOID buffer, UINT16 count )
{
return (UINT16)_lread((HFILE)DosFileHandleToWin32Handle(hFile), buffer, (LONG)count );
}
/***********************************************************************
* _lcreat (KERNEL.83)
*/
HFILE16 WINAPI _lcreat16( LPCSTR path, INT16 attr )
{
return Win32HandleToDosFileHandle( (HANDLE)_lcreat( path, attr ) );
}
/***********************************************************************
* _lcreat (KERNEL32.@)
*/
HFILE WINAPI _lcreat( LPCSTR path, INT attr )
{
/* Mask off all flags not explicitly allowed by the doc */
attr &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
TRACE("%s %02x\n", path, attr );
return (HFILE)CreateFileA( path, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, attr, 0 );
}
/*********************************************************************** /***********************************************************************
* SetFilePointer (KERNEL32.@) * SetFilePointer (KERNEL32.@)
*/ */
@ -2311,132 +2136,6 @@ DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword,
} }
/***********************************************************************
* _llseek (KERNEL.84)
*
* FIXME:
* Seeking before the start of the file should be allowed for _llseek16,
* but cause subsequent I/O operations to fail (cf. interrupt list)
*
*/
LONG WINAPI _llseek16( HFILE16 hFile, LONG lOffset, INT16 nOrigin )
{
return SetFilePointer( DosFileHandleToWin32Handle(hFile), lOffset, NULL, nOrigin );
}
/***********************************************************************
* _llseek (KERNEL32.@)
*/
LONG WINAPI _llseek( HFILE hFile, LONG lOffset, INT nOrigin )
{
return SetFilePointer( (HANDLE)hFile, lOffset, NULL, nOrigin );
}
/***********************************************************************
* _lopen (KERNEL.85)
*/
HFILE16 WINAPI _lopen16( LPCSTR path, INT16 mode )
{
return Win32HandleToDosFileHandle( (HANDLE)_lopen( path, mode ) );
}
/***********************************************************************
* _lopen (KERNEL32.@)
*/
HFILE WINAPI _lopen( LPCSTR path, INT mode )
{
DWORD access, sharing;
TRACE("('%s',%04x)\n", path, mode );
FILE_ConvertOFMode( mode, &access, &sharing );
return (HFILE)CreateFileA( path, access, sharing, NULL, OPEN_EXISTING, 0, 0 );
}
/***********************************************************************
* _lwrite (KERNEL.86)
*/
UINT16 WINAPI _lwrite16( HFILE16 hFile, LPCSTR buffer, UINT16 count )
{
return (UINT16)_hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, (LONG)count );
}
/***********************************************************************
* _lwrite (KERNEL32.@)
*/
UINT WINAPI _lwrite( HFILE hFile, LPCSTR buffer, UINT count )
{
return (UINT)_hwrite( hFile, buffer, (LONG)count );
}
/***********************************************************************
* _hread16 (KERNEL.349)
*/
LONG WINAPI _hread16( HFILE16 hFile, LPVOID buffer, LONG count)
{
return _lread( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, count );
}
/***********************************************************************
* _hread (KERNEL32.@)
*/
LONG WINAPI _hread( HFILE hFile, LPVOID buffer, LONG count)
{
return _lread( hFile, buffer, count );
}
/***********************************************************************
* _hwrite (KERNEL.350)
*/
LONG WINAPI _hwrite16( HFILE16 hFile, LPCSTR buffer, LONG count )
{
return _hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, count );
}
/***********************************************************************
* _hwrite (KERNEL32.@)
*
* experimentation yields that _lwrite:
* o truncates the file at the current position with
* a 0 len write
* o returns 0 on a 0 length write
* o works with console handles
*
*/
LONG WINAPI _hwrite( HFILE handle, LPCSTR buffer, LONG count )
{
DWORD result;
TRACE("%d %p %ld\n", handle, buffer, count );
if (!count)
{
/* Expand or truncate at current position */
if (!SetEndOfFile( (HANDLE)handle )) return HFILE_ERROR;
return 0;
}
if (!WriteFile( (HANDLE)handle, buffer, count, &result, NULL ))
return HFILE_ERROR;
return result;
}
/***********************************************************************
* SetHandleCount (KERNEL.199)
*/
UINT16 WINAPI SetHandleCount16( UINT16 count )
{
return SetHandleCount( count );
}
/************************************************************************* /*************************************************************************
* SetHandleCount (KERNEL32.@) * SetHandleCount (KERNEL32.@)
*/ */
@ -2446,32 +2145,6 @@ UINT WINAPI SetHandleCount( UINT count )
} }
/***********************************************************************
* FlushFileBuffers (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 */
/* FIXME: wait until FlushFileBuffers is moved to dll/kernel */
/* return FlushConsoleInputBuffer( hFile ); */
return TRUE;
}
nts = NtFlushBuffersFile( hFile, &ioblk );
if (nts != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError( nts ) );
return FALSE;
}
return TRUE;
}
/************************************************************************** /**************************************************************************
* SetEndOfFile (KERNEL32.@) * SetEndOfFile (KERNEL32.@)
*/ */
@ -2488,15 +2161,6 @@ BOOL WINAPI SetEndOfFile( HANDLE hFile )
} }
/***********************************************************************
* DeleteFile (KERNEL.146)
*/
BOOL16 WINAPI DeleteFile16( LPCSTR path )
{
return DeleteFileA( path );
}
/*********************************************************************** /***********************************************************************
* DeleteFileW (KERNEL32.@) * DeleteFileW (KERNEL32.@)
*/ */
@ -3041,6 +2705,7 @@ BOOL WINAPI CopyFileExW(LPCWSTR sourceFilename, LPCWSTR destFilename,
return CopyFileW(sourceFilename, destFilename, (copyFlags & COPY_FILE_FAIL_IF_EXISTS) != 0); return CopyFileW(sourceFilename, destFilename, (copyFlags & COPY_FILE_FAIL_IF_EXISTS) != 0);
} }
/************************************************************************** /**************************************************************************
* CopyFileExA (KERNEL32.@) * CopyFileExA (KERNEL32.@)
*/ */
@ -3096,136 +2761,6 @@ BOOL WINAPI SetFileTime( HANDLE hFile,
} }
/**************************************************************************
* LockFile (KERNEL32.@)
*/
BOOL WINAPI LockFile( HANDLE hFile, DWORD offset_low, DWORD offset_high,
DWORD count_low, DWORD count_high )
{
BOOL ret;
TRACE( "%p %lx%08lx %lx%08lx\n", hFile, offset_high, offset_low, count_high, count_low );
SERVER_START_REQ( lock_file )
{
req->handle = hFile;
req->offset_low = offset_low;
req->offset_high = offset_high;
req->count_low = count_low;
req->count_high = count_high;
req->shared = FALSE;
req->wait = FALSE;
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
}
/**************************************************************************
* 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 err;
BOOL async;
HANDLE handle;
if (reserved)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
TRACE( "%p %lx%08lx %lx%08lx flags %lx\n",
hFile, overlapped->OffsetHigh, overlapped->Offset, count_high, count_low, flags );
for (;;)
{
SERVER_START_REQ( lock_file )
{
req->handle = hFile;
req->offset_low = overlapped->Offset;
req->offset_high = overlapped->OffsetHigh;
req->count_low = count_low;
req->count_high = count_high;
req->shared = !(flags & LOCKFILE_EXCLUSIVE_LOCK);
req->wait = !(flags & LOCKFILE_FAIL_IMMEDIATELY);
err = wine_server_call( req );
handle = reply->handle;
async = reply->overlapped;
}
SERVER_END_REQ;
if (err != STATUS_PENDING)
{
if (err) SetLastError( RtlNtStatusToDosError(err) );
return !err;
}
if (async)
{
FIXME( "Async I/O lock wait not implemented, might deadlock\n" );
if (handle) CloseHandle( handle );
SetLastError( ERROR_IO_PENDING );
return FALSE;
}
if (handle)
{
WaitForSingleObject( handle, INFINITE );
CloseHandle( handle );
}
else Sleep(100); /* Unix lock conflict, sleep a bit and retry */
}
}
/**************************************************************************
* UnlockFile (KERNEL32.@)
*/
BOOL WINAPI UnlockFile( HANDLE hFile, DWORD offset_low, DWORD offset_high,
DWORD count_low, DWORD count_high )
{
BOOL ret;
TRACE( "%p %lx%08lx %lx%08lx\n", hFile, offset_high, offset_low, count_high, count_low );
SERVER_START_REQ( unlock_file )
{
req->handle = hFile;
req->offset_low = offset_low;
req->offset_high = offset_high;
req->count_low = count_low;
req->count_high = count_high;
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
}
/**************************************************************************
* 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;
}
return UnlockFile( hFile, overlapped->Offset, overlapped->OffsetHigh, count_low, count_high );
}
/************************************************************************** /**************************************************************************
* GetFileAttributesExW (KERNEL32.@) * GetFileAttributesExW (KERNEL32.@)
*/ */
@ -3289,30 +2824,3 @@ BOOL WINAPI GetFileAttributesExA(
SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret; return ret;
} }
/**************************************************************************
* ReplaceFileW (KERNEL32.@)
* ReplaceFile (KERNEL32.@)
*/
BOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName,LPCWSTR lpReplacementFileName,
LPCWSTR lpBackupFileName, DWORD dwReplaceFlags,
LPVOID lpExclude, LPVOID lpReserved)
{
FIXME("(%s,%s,%s,%08lx,%p,%p) stub\n",debugstr_w(lpReplacedFileName),debugstr_w(lpReplacementFileName),
debugstr_w(lpBackupFileName),dwReplaceFlags,lpExclude,lpReserved);
SetLastError(ERROR_UNABLE_TO_MOVE_REPLACEMENT);
return FALSE;
}
/**************************************************************************
* ReplaceFileA (KERNEL32.@)
*/
BOOL WINAPI ReplaceFileA(LPCSTR lpReplacedFileName,LPCSTR lpReplacementFileName,
LPCSTR lpBackupFileName, DWORD dwReplaceFlags,
LPVOID lpExclude, LPVOID lpReserved)
{
FIXME("(%s,%s,%s,%08lx,%p,%p) stub\n",lpReplacedFileName,lpReplacementFileName,
lpBackupFileName,dwReplaceFlags,lpExclude,lpReserved);
SetLastError(ERROR_UNABLE_TO_MOVE_REPLACEMENT);
return FALSE;
}

View File

@ -892,8 +892,11 @@ struct get_file_info_reply
int attr; int attr;
time_t access_time; time_t access_time;
time_t write_time; time_t write_time;
time_t change_time;
int size_high; int size_high;
int size_low; int size_low;
int alloc_high;
int alloc_low;
int links; int links;
int index_high; int index_high;
int index_low; int index_low;
@ -3615,6 +3618,6 @@ union generic_reply
struct set_clipboard_info_reply set_clipboard_info_reply; struct set_clipboard_info_reply set_clipboard_info_reply;
}; };
#define SERVER_PROTOCOL_VERSION 112 #define SERVER_PROTOCOL_VERSION 113
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -936,6 +936,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory(HANDLE,LPCVOID*,ULONG*,ULONG);
NTSTATUS WINAPI NtFreeVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG); NTSTATUS WINAPI NtFreeVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG);
NTSTATUS WINAPI NtGetContextThread(HANDLE,CONTEXT*); NTSTATUS WINAPI NtGetContextThread(HANDLE,CONTEXT*);
NTSTATUS WINAPI NtLoadKey(const OBJECT_ATTRIBUTES *,const OBJECT_ATTRIBUTES *); NTSTATUS WINAPI NtLoadKey(const OBJECT_ATTRIBUTES *,const OBJECT_ATTRIBUTES *);
NTSTATUS WINAPI NtLockFile(HANDLE,HANDLE,PIO_APC_ROUTINE,void*,PIO_STATUS_BLOCK,PLARGE_INTEGER,PLARGE_INTEGER,ULONG*,BOOLEAN,BOOLEAN);
NTSTATUS WINAPI NtLockVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG); NTSTATUS WINAPI NtLockVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG);
NTSTATUS WINAPI NtMapViewOfSection(HANDLE,HANDLE,PVOID*,ULONG,ULONG,const LARGE_INTEGER*,ULONG*,SECTION_INHERIT,ULONG,ULONG); NTSTATUS WINAPI NtMapViewOfSection(HANDLE,HANDLE,PVOID*,ULONG,ULONG,const LARGE_INTEGER*,ULONG*,SECTION_INHERIT,ULONG,ULONG);
NTSTATUS WINAPI NtNotifyChangeKey(HKEY,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN); NTSTATUS WINAPI NtNotifyChangeKey(HKEY,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN);
@ -951,6 +952,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG,ULONG*);
NTSTATUS WINAPI NtPulseEvent(HANDLE,PULONG); NTSTATUS WINAPI NtPulseEvent(HANDLE,PULONG);
NTSTATUS WINAPI NtQueueApcThread(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PTR); NTSTATUS WINAPI NtQueueApcThread(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PTR);
NTSTATUS WINAPI NtQueryDefaultLocale(BOOLEAN,LCID*); NTSTATUS WINAPI NtQueryDefaultLocale(BOOLEAN,LCID*);
NTSTATUS WINAPI NtQueryInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,LONG,FILE_INFORMATION_CLASS);
NTSTATUS WINAPI NtQueryInformationProcess(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG); NTSTATUS WINAPI NtQueryInformationProcess(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG);
NTSTATUS WINAPI NtQueryInformationThread(HANDLE,THREADINFOCLASS,PVOID,ULONG,PULONG); NTSTATUS WINAPI NtQueryInformationThread(HANDLE,THREADINFOCLASS,PVOID,ULONG,PULONG);
NTSTATUS WINAPI NtQueryInformationToken(HANDLE,DWORD,LPVOID,DWORD,LPDWORD); NTSTATUS WINAPI NtQueryInformationToken(HANDLE,DWORD,LPVOID,DWORD,LPDWORD);
@ -973,6 +975,7 @@ NTSTATUS WINAPI NtSaveKey(HKEY,HANDLE);
NTSTATUS WINAPI NtSetContextThread(HANDLE,const CONTEXT*); NTSTATUS WINAPI NtSetContextThread(HANDLE,const CONTEXT*);
NTSTATUS WINAPI NtSetDefaultLocale(BOOLEAN,LCID); NTSTATUS WINAPI NtSetDefaultLocale(BOOLEAN,LCID);
NTSTATUS WINAPI NtSetEvent(HANDLE,PULONG); NTSTATUS WINAPI NtSetEvent(HANDLE,PULONG);
NTSTATUS WINAPI NtSetInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FILE_INFORMATION_CLASS);
NTSTATUS WINAPI NtSetInformationKey(HKEY,const int,PVOID,ULONG); NTSTATUS WINAPI NtSetInformationKey(HKEY,const int,PVOID,ULONG);
NTSTATUS WINAPI NtSetInformationObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG); NTSTATUS WINAPI NtSetInformationObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG);
NTSTATUS WINAPI NtSetSecurityObject(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); NTSTATUS WINAPI NtSetSecurityObject(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
@ -983,6 +986,7 @@ NTSTATUS WINAPI NtSuspendThread(HANDLE,PULONG);
NTSTATUS WINAPI NtTerminateProcess(HANDLE,LONG); NTSTATUS WINAPI NtTerminateProcess(HANDLE,LONG);
NTSTATUS WINAPI NtTerminateThread(HANDLE,LONG); NTSTATUS WINAPI NtTerminateThread(HANDLE,LONG);
NTSTATUS WINAPI NtUnloadKey(HKEY); NTSTATUS WINAPI NtUnloadKey(HKEY);
NTSTATUS WINAPI NtUnlockFile(HANDLE,PIO_STATUS_BLOCK,PLARGE_INTEGER,PLARGE_INTEGER,PULONG);
NTSTATUS WINAPI NtUnlockVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG); NTSTATUS WINAPI NtUnlockVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG);
NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID); NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID);
NTSTATUS WINAPI NtWaitForSingleObject(HANDLE,BOOLEAN,PLARGE_INTEGER); NTSTATUS WINAPI NtWaitForSingleObject(HANDLE,BOOLEAN,PLARGE_INTEGER);

View File

@ -313,7 +313,7 @@ struct _w31_valent {
}; };
/* recursive helper function to display a directory tree [Internal] */ /* recursive helper function to display a directory tree [Internal] */
void _w31_dumptree(unsigned short idx,unsigned char *txt,struct _w31_tabent *tab,struct _w31_header *head,HKEY hkey,time_t lastmodified, int level) static void _w31_dumptree(unsigned short idx,unsigned char *txt,struct _w31_tabent *tab,struct _w31_header *head,HKEY hkey,time_t lastmodified, int level)
{ {
static const WCHAR classesW[] = {'.','c','l','a','s','s','e','s',0}; static const WCHAR classesW[] = {'.','c','l','a','s','s','e','s',0};
struct _w31_dirent *dir; struct _w31_dirent *dir;
@ -379,9 +379,9 @@ void _w31_dumptree(unsigned short idx,unsigned char *txt,struct _w31_tabent *tab
/****************************************************************************** /******************************************************************************
* _w31_loadreg [Internal] * _w31_loadreg [Internal]
*/ */
void _w31_loadreg(void) static void _w31_loadreg(void)
{ {
HFILE hf; HANDLE hf;
HKEY root; HKEY root;
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW; UNICODE_STRING nameW;
@ -392,56 +392,57 @@ void _w31_loadreg(void)
OFSTRUCT ofs; OFSTRUCT ofs;
BY_HANDLE_FILE_INFORMATION hfinfo; BY_HANDLE_FILE_INFORMATION hfinfo;
time_t lastmodified; time_t lastmodified;
DWORD r;
TRACE("(void)\n"); TRACE("(void)\n");
hf = OpenFile("reg.dat",&ofs,OF_READ); hf = (HANDLE)OpenFile("reg.dat",&ofs,OF_READ);
if (hf==HFILE_ERROR) return; if (hf==(HANDLE)HFILE_ERROR) return;
/* read & dump header */ /* read & dump header */
if (sizeof(head)!=_lread(hf,&head,sizeof(head))) { if (!ReadFile(hf,&head,sizeof(head),&r,NULL) || r!=sizeof(head)) {
ERR("reg.dat is too short.\n"); ERR("reg.dat is too short.\n");
_lclose(hf); CloseHandle(hf);
return; return;
} }
if (memcmp(head.cookie, "SHCC3.10", sizeof(head.cookie))!=0) { if (memcmp(head.cookie, "SHCC3.10", sizeof(head.cookie))!=0) {
ERR("reg.dat has bad signature.\n"); ERR("reg.dat has bad signature.\n");
_lclose(hf); CloseHandle(hf);
return; return;
} }
len = head.tabcnt * sizeof(struct _w31_tabent); len = head.tabcnt * sizeof(struct _w31_tabent);
/* read and dump index table */ /* read and dump index table */
tab = _xmalloc(len); tab = _xmalloc(len);
if (len!=_lread(hf,tab,len)) { if (!ReadFile(hf,tab,len,&r,NULL) || r!=len) {
ERR("couldn't read %d bytes.\n",len); ERR("couldn't read %d bytes.\n",len);
free(tab); free(tab);
_lclose(hf); CloseHandle(hf);
return; return;
} }
/* read text */ /* read text */
txt = _xmalloc(head.textsize); txt = _xmalloc(head.textsize);
if (-1==_llseek(hf,head.textoff,SEEK_SET)) { if (-1==SetFilePointer(hf,head.textoff,NULL,SEEK_SET)) {
ERR("couldn't seek to textblock.\n"); ERR("couldn't seek to textblock.\n");
free(tab); free(tab);
free(txt); free(txt);
_lclose(hf); CloseHandle(hf);
return; return;
} }
if (head.textsize!=_lread(hf,txt,head.textsize)) { if (!ReadFile(hf,txt,head.textsize,&r,NULL) || r!=head.textsize) {
ERR("textblock too short (%d instead of %ld).\n",len,head.textsize); ERR("textblock too short (%d instead of %ld).\n",len,head.textsize);
free(tab); free(tab);
free(txt); free(txt);
_lclose(hf); CloseHandle(hf);
return; return;
} }
if (!GetFileInformationByHandle((HANDLE)hf,&hfinfo)) { if (!GetFileInformationByHandle(hf,&hfinfo)) {
ERR("GetFileInformationByHandle failed?.\n"); ERR("GetFileInformationByHandle failed?.\n");
free(tab); free(tab);
free(txt); free(txt);
_lclose(hf); CloseHandle(hf);
return; return;
} }
lastmodified = DOSFS_FileTimeToUnixTime(&hfinfo.ftLastWriteTime,NULL); lastmodified = DOSFS_FileTimeToUnixTime(&hfinfo.ftLastWriteTime,NULL);
@ -461,7 +462,7 @@ void _w31_loadreg(void)
} }
free(tab); free(tab);
free(txt); free(txt);
_lclose(hf); CloseHandle(hf);
return; return;
} }

View File

@ -329,15 +329,22 @@ static int file_get_info( struct fd *fd, struct get_file_info_reply *reply, int
if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY; if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY;
reply->access_time = st.st_atime; reply->access_time = st.st_atime;
reply->write_time = st.st_mtime; reply->write_time = st.st_mtime;
reply->change_time = st.st_ctime;
if (S_ISDIR(st.st_mode)) if (S_ISDIR(st.st_mode))
{ {
reply->size_high = 0; reply->size_high = 0;
reply->size_low = 0; reply->size_low = 0;
reply->alloc_high = 0;
reply->alloc_low = 0;
} }
else else
{ {
reply->size_high = st.st_size >> 32; file_pos_t alloc;
reply->size_low = st.st_size & 0xffffffff; reply->size_high = st.st_size >> 32;
reply->size_low = st.st_size & 0xffffffff;
alloc = (file_pos_t)st.st_blksize * st.st_blocks;
reply->alloc_high = alloc >> 32;
reply->alloc_low = alloc & 0xffffffff;
} }
reply->links = st.st_nlink; reply->links = st.st_nlink;
reply->index_high = st.st_dev; reply->index_high = st.st_dev;

View File

@ -677,8 +677,11 @@ enum fd_type
int attr; /* file attributes */ int attr; /* file attributes */
time_t access_time; /* last access time */ time_t access_time; /* last access time */
time_t write_time; /* last write time */ time_t write_time; /* last write time */
time_t change_time; /* last change time */
int size_high; /* file size */ int size_high; /* file size */
int size_low; /* file size */ int size_low; /* file size */
int alloc_high; /* size used on disk */
int alloc_low; /* size used on disk */
int links; /* number of links */ int links; /* number of links */
int index_high; /* unique index */ int index_high; /* unique index */
int index_low; /* unique index */ int index_low; /* unique index */

View File

@ -893,8 +893,11 @@ static void dump_get_file_info_reply( const struct get_file_info_reply *req )
fprintf( stderr, " attr=%d,", req->attr ); fprintf( stderr, " attr=%d,", req->attr );
fprintf( stderr, " access_time=%ld,", req->access_time ); fprintf( stderr, " access_time=%ld,", req->access_time );
fprintf( stderr, " write_time=%ld,", req->write_time ); fprintf( stderr, " write_time=%ld,", req->write_time );
fprintf( stderr, " change_time=%ld,", req->change_time );
fprintf( stderr, " size_high=%d,", req->size_high ); fprintf( stderr, " size_high=%d,", req->size_high );
fprintf( stderr, " size_low=%d,", req->size_low ); fprintf( stderr, " size_low=%d,", req->size_low );
fprintf( stderr, " alloc_high=%d,", req->alloc_high );
fprintf( stderr, " alloc_low=%d,", req->alloc_low );
fprintf( stderr, " links=%d,", req->links ); fprintf( stderr, " links=%d,", req->links );
fprintf( stderr, " index_high=%d,", req->index_high ); fprintf( stderr, " index_high=%d,", req->index_high );
fprintf( stderr, " index_low=%d,", req->index_low ); fprintf( stderr, " index_low=%d,", req->index_low );