Commit f6a70969 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- 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
parent 6c9b097f
......@@ -28,6 +28,8 @@ C_SRCS = \
console.c \
debugger.c \
editline.c \
file.c \
file16.c \
format_msg.c \
kernel_main.c \
lcformat.c \
......
/*
* 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
......@@ -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
......
......@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment