- 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:
parent
6c9b097fae
commit
f6a70969e1
|
@ -28,6 +28,8 @@ C_SRCS = \
|
|||
console.c \
|
||||
debugger.c \
|
||||
editline.c \
|
||||
file.c \
|
||||
file16.c \
|
||||
format_msg.c \
|
||||
kernel_main.c \
|
||||
lcformat.c \
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 );
|
||||
}
|
|
@ -44,4 +44,9 @@ static inline HANDLE console_handle_unmap(HANDLE h)
|
|||
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
|
||||
|
|
|
@ -345,32 +345,161 @@ NTSTATUS WINAPI NtSetVolumeInformationFile(
|
|||
* NtQueryInformationFile [NTDLL.@]
|
||||
* ZwQueryInformationFile [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtQueryInformationFile(
|
||||
HANDLE FileHandle,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
PVOID FileInformation,
|
||||
ULONG Length,
|
||||
FILE_INFORMATION_CLASS FileInformationClass)
|
||||
NTSTATUS WINAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
|
||||
PVOID ptr, LONG len,
|
||||
FILE_INFORMATION_CLASS class)
|
||||
{
|
||||
FIXME("(%p,%p,%p,0x%08lx,0x%08x),stub!\n",
|
||||
FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
|
||||
return 0;
|
||||
NTSTATUS status;
|
||||
LONG used = 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.@]
|
||||
* ZwSetInformationFile [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtSetInformationFile(
|
||||
HANDLE FileHandle,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
PVOID FileInformation,
|
||||
ULONG Length,
|
||||
FILE_INFORMATION_CLASS FileInformationClass)
|
||||
NTSTATUS WINAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
|
||||
PVOID ptr, ULONG len,
|
||||
FILE_INFORMATION_CLASS class)
|
||||
{
|
||||
FIXME("(%p,%p,%p,0x%08lx,0x%08x)\n",
|
||||
FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
|
||||
return 0;
|
||||
NTSTATUS status = STATUS_INVALID_PARAMETER_3;
|
||||
|
||||
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:
|
||||
break;
|
||||
}
|
||||
IoStatusBlock->DUMMYUNIONNAME.Status = STATUS_SUCCESS;
|
||||
IoStatusBlock->u.Status = STATUS_SUCCESS;
|
||||
IoStatusBlock->Information = len;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -514,3 +643,103 @@ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@
|
|||
@ stdcall NtListenPort(ptr ptr)
|
||||
@ stub NtLoadDriver
|
||||
@ stdcall NtLoadKey(ptr ptr)
|
||||
@ stub NtLockFile
|
||||
@ stdcall NtLockFile(long long ptr ptr ptr ptr ptr ptr long long)
|
||||
@ stdcall NtLockVirtualMemory(long ptr ptr long)
|
||||
@ stub NtMakeTemporaryObject
|
||||
@ stdcall NtMapViewOfSection(long long ptr long long ptr ptr long long long)
|
||||
|
@ -245,7 +245,7 @@
|
|||
@ stub NtUnloadDriver
|
||||
@ stdcall NtUnloadKey(long)
|
||||
@ stub NtUnloadKeyEx
|
||||
@ stub NtUnlockFile
|
||||
@ stdcall NtUnlockFile(long ptr ptr ptr ptr)
|
||||
@ stdcall NtUnlockVirtualMemory(long ptr ptr long)
|
||||
@ stdcall NtUnmapViewOfSection(long ptr)
|
||||
@ stub NtVdmControl
|
||||
|
@ -655,7 +655,7 @@
|
|||
@ stdcall ZwListenPort(ptr ptr) NtListenPort
|
||||
@ stub ZwLoadDriver
|
||||
@ 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
|
||||
@ stub ZwMakeTemporaryObject
|
||||
@ stdcall ZwMapViewOfSection(long long ptr long long ptr ptr long long long) NtMapViewOfSection
|
||||
|
@ -774,7 +774,7 @@
|
|||
@ stub ZwUnloadDriver
|
||||
@ stdcall ZwUnloadKey(long) NtUnloadKey
|
||||
@ stub ZwUnloadKeyEx
|
||||
@ stub ZwUnlockFile
|
||||
@ stdcall ZwUnlockFile(long ptr ptr ptr ptr) NtUnlockFile
|
||||
@ stdcall ZwUnlockVirtualMemory(long ptr ptr long) NtUnlockVirtualMemory
|
||||
@ stdcall ZwUnmapViewOfSection(long ptr) NtUnmapViewOfSection
|
||||
@ stub ZwVdmControl
|
||||
|
|
502
files/file.c
502
files/file.c
|
@ -82,14 +82,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(file);
|
|||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
/* Size of per-process table of DOS handles */
|
||||
#define DOS_TABLE_SIZE 256
|
||||
|
||||
/* Macro to derive file offset from OVERLAPPED struct */
|
||||
#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;
|
||||
|
||||
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.
|
||||
*/
|
||||
static void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing )
|
||||
void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing )
|
||||
{
|
||||
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.@)
|
||||
*/
|
||||
|
@ -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.@)
|
||||
*/
|
||||
|
@ -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.@)
|
||||
*/
|
||||
|
@ -1133,6 +1074,7 @@ BOOL WINAPI GetFileTime( HANDLE hFile, FILETIME *lpCreationTime,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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
|
||||
*
|
||||
* Implementation of OpenFile16() and OpenFile32().
|
||||
*/
|
||||
static HFILE FILE_DoOpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode,
|
||||
BOOL win32 )
|
||||
static HFILE FILE_DoOpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode, BOOL win32 )
|
||||
{
|
||||
HFILE hFileRet;
|
||||
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.@)
|
||||
*
|
||||
|
@ -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.@)
|
||||
*/
|
||||
|
@ -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.@)
|
||||
*/
|
||||
|
@ -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.@)
|
||||
*/
|
||||
|
@ -2488,15 +2161,6 @@ BOOL WINAPI SetEndOfFile( HANDLE hFile )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DeleteFile (KERNEL.146)
|
||||
*/
|
||||
BOOL16 WINAPI DeleteFile16( LPCSTR path )
|
||||
{
|
||||
return DeleteFileA( path );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DeleteFileW (KERNEL32.@)
|
||||
*/
|
||||
|
@ -3041,6 +2705,7 @@ BOOL WINAPI CopyFileExW(LPCWSTR sourceFilename, LPCWSTR destFilename,
|
|||
return CopyFileW(sourceFilename, destFilename, (copyFlags & COPY_FILE_FAIL_IF_EXISTS) != 0);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* 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.@)
|
||||
*/
|
||||
|
@ -3289,30 +2824,3 @@ BOOL WINAPI GetFileAttributesExA(
|
|||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -892,8 +892,11 @@ struct get_file_info_reply
|
|||
int attr;
|
||||
time_t access_time;
|
||||
time_t write_time;
|
||||
time_t change_time;
|
||||
int size_high;
|
||||
int size_low;
|
||||
int alloc_high;
|
||||
int alloc_low;
|
||||
int links;
|
||||
int index_high;
|
||||
int index_low;
|
||||
|
@ -3615,6 +3618,6 @@ union generic_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 */
|
||||
|
|
|
@ -936,6 +936,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory(HANDLE,LPCVOID*,ULONG*,ULONG);
|
|||
NTSTATUS WINAPI NtFreeVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG);
|
||||
NTSTATUS WINAPI NtGetContextThread(HANDLE,CONTEXT*);
|
||||
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 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);
|
||||
|
@ -951,6 +952,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG,ULONG*);
|
|||
NTSTATUS WINAPI NtPulseEvent(HANDLE,PULONG);
|
||||
NTSTATUS WINAPI NtQueueApcThread(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PTR);
|
||||
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 NtQueryInformationThread(HANDLE,THREADINFOCLASS,PVOID,ULONG,PULONG);
|
||||
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 NtSetDefaultLocale(BOOLEAN,LCID);
|
||||
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 NtSetInformationObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG);
|
||||
NTSTATUS WINAPI NtSetSecurityObject(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
|
||||
|
@ -983,6 +986,7 @@ NTSTATUS WINAPI NtSuspendThread(HANDLE,PULONG);
|
|||
NTSTATUS WINAPI NtTerminateProcess(HANDLE,LONG);
|
||||
NTSTATUS WINAPI NtTerminateThread(HANDLE,LONG);
|
||||
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 NtUnmapViewOfSection(HANDLE,PVOID);
|
||||
NTSTATUS WINAPI NtWaitForSingleObject(HANDLE,BOOLEAN,PLARGE_INTEGER);
|
||||
|
|
|
@ -313,7 +313,7 @@ struct _w31_valent {
|
|||
};
|
||||
|
||||
/* 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};
|
||||
struct _w31_dirent *dir;
|
||||
|
@ -379,9 +379,9 @@ void _w31_dumptree(unsigned short idx,unsigned char *txt,struct _w31_tabent *tab
|
|||
/******************************************************************************
|
||||
* _w31_loadreg [Internal]
|
||||
*/
|
||||
void _w31_loadreg(void)
|
||||
static void _w31_loadreg(void)
|
||||
{
|
||||
HFILE hf;
|
||||
HANDLE hf;
|
||||
HKEY root;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
|
@ -392,56 +392,57 @@ void _w31_loadreg(void)
|
|||
OFSTRUCT ofs;
|
||||
BY_HANDLE_FILE_INFORMATION hfinfo;
|
||||
time_t lastmodified;
|
||||
DWORD r;
|
||||
|
||||
TRACE("(void)\n");
|
||||
|
||||
hf = OpenFile("reg.dat",&ofs,OF_READ);
|
||||
if (hf==HFILE_ERROR) return;
|
||||
hf = (HANDLE)OpenFile("reg.dat",&ofs,OF_READ);
|
||||
if (hf==(HANDLE)HFILE_ERROR) return;
|
||||
|
||||
/* 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");
|
||||
_lclose(hf);
|
||||
CloseHandle(hf);
|
||||
return;
|
||||
}
|
||||
if (memcmp(head.cookie, "SHCC3.10", sizeof(head.cookie))!=0) {
|
||||
ERR("reg.dat has bad signature.\n");
|
||||
_lclose(hf);
|
||||
CloseHandle(hf);
|
||||
return;
|
||||
}
|
||||
|
||||
len = head.tabcnt * sizeof(struct _w31_tabent);
|
||||
/* read and dump index table */
|
||||
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);
|
||||
free(tab);
|
||||
_lclose(hf);
|
||||
CloseHandle(hf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* read text */
|
||||
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");
|
||||
free(tab);
|
||||
free(txt);
|
||||
_lclose(hf);
|
||||
CloseHandle(hf);
|
||||
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);
|
||||
free(tab);
|
||||
free(txt);
|
||||
_lclose(hf);
|
||||
CloseHandle(hf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetFileInformationByHandle((HANDLE)hf,&hfinfo)) {
|
||||
if (!GetFileInformationByHandle(hf,&hfinfo)) {
|
||||
ERR("GetFileInformationByHandle failed?.\n");
|
||||
free(tab);
|
||||
free(txt);
|
||||
_lclose(hf);
|
||||
CloseHandle(hf);
|
||||
return;
|
||||
}
|
||||
lastmodified = DOSFS_FileTimeToUnixTime(&hfinfo.ftLastWriteTime,NULL);
|
||||
|
@ -461,7 +462,7 @@ void _w31_loadreg(void)
|
|||
}
|
||||
free(tab);
|
||||
free(txt);
|
||||
_lclose(hf);
|
||||
CloseHandle(hf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
reply->access_time = st.st_atime;
|
||||
reply->write_time = st.st_mtime;
|
||||
reply->change_time = st.st_ctime;
|
||||
if (S_ISDIR(st.st_mode))
|
||||
{
|
||||
reply->size_high = 0;
|
||||
reply->size_low = 0;
|
||||
reply->size_high = 0;
|
||||
reply->size_low = 0;
|
||||
reply->alloc_high = 0;
|
||||
reply->alloc_low = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
reply->size_high = st.st_size >> 32;
|
||||
reply->size_low = st.st_size & 0xffffffff;
|
||||
file_pos_t alloc;
|
||||
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->index_high = st.st_dev;
|
||||
|
|
|
@ -677,8 +677,11 @@ enum fd_type
|
|||
int attr; /* file attributes */
|
||||
time_t access_time; /* last access time */
|
||||
time_t write_time; /* last write time */
|
||||
time_t change_time; /* last change time */
|
||||
int size_high; /* 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 index_high; /* unique index */
|
||||
int index_low; /* unique index */
|
||||
|
|
|
@ -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, " access_time=%ld,", req->access_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_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, " index_high=%d,", req->index_high );
|
||||
fprintf( stderr, " index_low=%d,", req->index_low );
|
||||
|
|
Loading…
Reference in New Issue