374 lines
10 KiB
C
374 lines
10 KiB
C
/*
|
|
* Win32 kernel functions
|
|
*
|
|
* Copyright 1995 Martin von Loewis, Sven Verdoolaege, and Cameron Heide
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <sys/errno.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/mman.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include "windows.h"
|
|
#include "winbase.h"
|
|
#include "winerror.h"
|
|
#include "file.h"
|
|
#include "device.h"
|
|
#include "process.h"
|
|
#include "heap.h"
|
|
#include "debug.h"
|
|
|
|
DWORD ErrnoToLastError(int errno_num);
|
|
|
|
static int TranslateCreationFlags(DWORD create_flags);
|
|
static int TranslateAccessFlags(DWORD access_flags);
|
|
static int TranslateShareFlags(DWORD share_flags);
|
|
|
|
/***********************************************************************
|
|
* WriteFile (KERNEL32.578)
|
|
*/
|
|
BOOL32 WINAPI WriteFile(HANDLE32 hFile, LPCVOID lpBuffer,
|
|
DWORD numberOfBytesToWrite,
|
|
LPDWORD numberOfBytesWritten, LPOVERLAPPED lpOverlapped)
|
|
{
|
|
K32OBJ *ioptr;
|
|
BOOL32 status = FALSE;
|
|
|
|
TRACE(file, "%d %p %ld\n", hFile, lpBuffer,
|
|
numberOfBytesToWrite);
|
|
|
|
if (!(ioptr = HANDLE_GetObjPtr( PROCESS_Current(), hFile,
|
|
K32OBJ_UNKNOWN, 0, NULL )))
|
|
return HFILE_ERROR32;
|
|
if (K32OBJ_OPS(ioptr)->write)
|
|
status = K32OBJ_OPS(ioptr)->write(ioptr, lpBuffer, numberOfBytesToWrite,
|
|
numberOfBytesWritten, lpOverlapped);
|
|
K32OBJ_DecCount( ioptr );
|
|
return status;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* ReadFile (KERNEL32.428)
|
|
*/
|
|
BOOL32 WINAPI ReadFile(HANDLE32 hFile, LPVOID lpBuffer, DWORD numberOfBytesToRead,
|
|
LPDWORD numberOfBytesRead, LPOVERLAPPED lpOverlapped)
|
|
{
|
|
K32OBJ *ioptr;
|
|
BOOL32 status = FALSE;
|
|
|
|
TRACE(file, "%d %p %ld\n", hFile, lpBuffer,
|
|
numberOfBytesToRead);
|
|
|
|
if (!(ioptr = HANDLE_GetObjPtr( PROCESS_Current(), hFile,
|
|
K32OBJ_UNKNOWN, 0, NULL )))
|
|
return HFILE_ERROR32;
|
|
if (K32OBJ_OPS(ioptr)->read)
|
|
status = K32OBJ_OPS(ioptr)->read(ioptr, lpBuffer, numberOfBytesToRead,
|
|
numberOfBytesRead, lpOverlapped);
|
|
K32OBJ_DecCount( ioptr );
|
|
return status;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* ReadFileEx (KERNEL32.)
|
|
*/
|
|
typedef
|
|
VOID
|
|
(CALLBACK *LPOVERLAPPED_COMPLETION_ROUTINE)(
|
|
DWORD dwErrorCode,
|
|
DWORD dwNumberOfBytesTransfered,
|
|
LPOVERLAPPED lpOverlapped
|
|
);
|
|
|
|
BOOL32 WINAPI ReadFileEx(HFILE32 hFile, LPVOID lpBuffer, DWORD numtoread,
|
|
LPOVERLAPPED lpOverlapped,
|
|
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
|
{
|
|
|
|
FIXME(file, "file %d to buf %p num %ld %p func %p stub\n",
|
|
hFile, lpBuffer, numtoread, lpOverlapped, lpCompletionRoutine);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
* CreateFile32A [KERNEL32.45] Creates or opens a file or other object
|
|
*
|
|
* Creates or opens an object, and returns a handle that can be used to
|
|
* access that object.
|
|
*
|
|
* PARAMS
|
|
*
|
|
* filename [I] pointer to filename to be accessed
|
|
* access [I] access mode requested
|
|
* sharing [I] share mode
|
|
* security [I] pointer to security attributes
|
|
* creation [I] ?
|
|
* attributes [I] ?
|
|
* template [I] handle to file with attributes to copy
|
|
*
|
|
* RETURNS
|
|
* Success: Open handle to specified file
|
|
* Failure: INVALID_HANDLE_VALUE
|
|
*
|
|
* NOTES
|
|
* Should call SetLastError() on failure.
|
|
*
|
|
* BUGS
|
|
*
|
|
* Doesn't support character devices, pipes, template files, or a
|
|
* lot of the 'attributes' flags yet.
|
|
*/
|
|
HFILE32 WINAPI CreateFile32A(LPCSTR filename, DWORD access, DWORD sharing,
|
|
LPSECURITY_ATTRIBUTES security, DWORD creation,
|
|
DWORD attributes, HANDLE32 template)
|
|
{
|
|
int access_flags, create_flags, share_flags;
|
|
HFILE32 to_dup = HFILE_ERROR32; /* handle to dup */
|
|
|
|
/* Translate the various flags to Unix-style.
|
|
*/
|
|
access_flags = TranslateAccessFlags(access);
|
|
create_flags = TranslateCreationFlags(creation);
|
|
share_flags = TranslateShareFlags(sharing);
|
|
|
|
if(template)
|
|
FIXME(file, "template handles not supported.\n");
|
|
|
|
if(!filename)
|
|
return HFILE_ERROR32;
|
|
/* If the name starts with '\\?\' or '\\.\', ignore the first 4 chars.
|
|
*/
|
|
if(!strncmp(filename, "\\\\?\\", 4) || !strncmp(filename, "\\\\.\\", 4))
|
|
{
|
|
if (filename[2] == '.')
|
|
return DEVICE_Open( filename+4, access_flags | create_flags );
|
|
|
|
filename += 4;
|
|
if (!strncmp(filename, "UNC", 3))
|
|
{
|
|
FIXME(file, "UNC name (%s) not supported.\n",filename);
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return HFILE_ERROR32;
|
|
}
|
|
}
|
|
|
|
/* If the name still starts with '\\', it's a UNC name.
|
|
*/
|
|
if(!strncmp(filename, "\\\\", 2))
|
|
{
|
|
FIXME(file, "UNC names not supported.\n");
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
return HFILE_ERROR32;
|
|
}
|
|
|
|
/* If the name is either CONIN$ or CONOUT$, give them duplicated stdin
|
|
* or stdout, respectively. The lower case version is also allowed. Most likely
|
|
* this should be a case ignore string compare.
|
|
*/
|
|
if(!strcasecmp(filename, "CONIN$"))
|
|
to_dup = GetStdHandle( STD_INPUT_HANDLE );
|
|
else if(!strcasecmp(filename, "CONOUT$"))
|
|
to_dup = GetStdHandle( STD_OUTPUT_HANDLE );
|
|
|
|
if(to_dup != HFILE_ERROR32)
|
|
{
|
|
HFILE32 handle;
|
|
if (!DuplicateHandle( GetCurrentProcess(), to_dup, GetCurrentProcess(),
|
|
&handle, access, FALSE, 0 ))
|
|
handle = HFILE_ERROR32;
|
|
return handle;
|
|
}
|
|
return FILE_Open( filename, access_flags | create_flags,share_flags );
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
* CreateFile32W (KERNEL32.48)
|
|
*/
|
|
HFILE32 WINAPI CreateFile32W(LPCWSTR filename, DWORD access, DWORD sharing,
|
|
LPSECURITY_ATTRIBUTES security, DWORD creation,
|
|
DWORD attributes, HANDLE32 template)
|
|
{
|
|
LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
|
|
HFILE32 res = CreateFile32A( afn, access, sharing, security, creation,
|
|
attributes, template );
|
|
HeapFree( GetProcessHeap(), 0, afn );
|
|
return res;
|
|
}
|
|
|
|
static int TranslateAccessFlags(DWORD access_flags)
|
|
{
|
|
int rc = 0;
|
|
|
|
switch(access_flags)
|
|
{
|
|
case GENERIC_READ:
|
|
rc = O_RDONLY;
|
|
break;
|
|
|
|
case GENERIC_WRITE:
|
|
rc = O_WRONLY;
|
|
break;
|
|
|
|
case (GENERIC_READ | GENERIC_WRITE):
|
|
rc = O_RDWR;
|
|
break;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static int TranslateCreationFlags(DWORD create_flags)
|
|
{
|
|
int rc = 0;
|
|
|
|
switch(create_flags)
|
|
{
|
|
case CREATE_NEW:
|
|
rc = O_CREAT | O_EXCL;
|
|
break;
|
|
|
|
case CREATE_ALWAYS:
|
|
rc = O_CREAT | O_TRUNC;
|
|
break;
|
|
|
|
case OPEN_EXISTING:
|
|
rc = 0;
|
|
break;
|
|
|
|
case OPEN_ALWAYS:
|
|
rc = O_CREAT;
|
|
break;
|
|
|
|
case TRUNCATE_EXISTING:
|
|
rc = O_TRUNC;
|
|
break;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
static int TranslateShareFlags(DWORD share_flags)
|
|
/*
|
|
OPEN_SHARE_DENYNONE FILE_SHARE_READ | FILE_SHARE_WRITE
|
|
OPEN_SHARE_DENYREAD FILE_SHARE_WRITE
|
|
OPEN_SHARE_DENYREADWRITE 0
|
|
OPEN_SHARE_DENYWRITE FILE_SHARE_READ
|
|
*/
|
|
{
|
|
switch(share_flags)
|
|
{
|
|
case FILE_SHARE_READ | FILE_SHARE_WRITE:
|
|
return OF_SHARE_DENY_NONE;
|
|
case FILE_SHARE_WRITE:
|
|
return OF_SHARE_DENY_READ;
|
|
case FILE_SHARE_READ:
|
|
return OF_SHARE_DENY_WRITE;
|
|
case 0:
|
|
return OF_SHARE_EXCLUSIVE;
|
|
default:
|
|
}
|
|
FIXME(file,"unknown sharing flags 0x%04lx\n",share_flags);
|
|
return OF_SHARE_EXCLUSIVE;
|
|
}
|
|
/**************************************************************************
|
|
* SetFileAttributes16 (KERNEL.421)
|
|
*/
|
|
BOOL16 WINAPI SetFileAttributes16( LPCSTR lpFileName, DWORD attributes )
|
|
{
|
|
return SetFileAttributes32A( lpFileName, attributes );
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* SetFileAttributes32A (KERNEL32.490)
|
|
*/
|
|
BOOL32 WINAPI SetFileAttributes32A(LPCSTR lpFileName, DWORD attributes)
|
|
{
|
|
struct stat buf;
|
|
DOS_FULL_NAME full_name;
|
|
|
|
if (!DOSFS_GetFullName( lpFileName, TRUE, &full_name ))
|
|
return FALSE;
|
|
|
|
TRACE(file,"(%s,%lx)\n",lpFileName,attributes);
|
|
if (attributes & FILE_ATTRIBUTE_NORMAL) {
|
|
attributes &= ~FILE_ATTRIBUTE_NORMAL;
|
|
if (attributes)
|
|
FIXME(file,"(%s):%lx illegal combination with FILE_ATTRIBUTE_NORMAL.\n",
|
|
lpFileName,attributes);
|
|
}
|
|
if(stat(full_name.long_name,&buf)==-1)
|
|
{
|
|
SetLastError(ErrnoToLastError(errno));
|
|
return FALSE;
|
|
}
|
|
if (attributes & FILE_ATTRIBUTE_READONLY)
|
|
{
|
|
buf.st_mode &= ~0222; /* octal!, clear write permission bits */
|
|
attributes &= ~FILE_ATTRIBUTE_READONLY;
|
|
}
|
|
attributes &= ~(FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
|
|
if (attributes)
|
|
FIXME(file,"(%s):%lx attribute(s) not implemented.\n",
|
|
lpFileName,attributes);
|
|
if (-1==chmod(full_name.long_name,buf.st_mode))
|
|
{
|
|
SetLastError(ErrnoToLastError(errno));
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* SetFileAttributes32W (KERNEL32.491)
|
|
*/
|
|
BOOL32 WINAPI SetFileAttributes32W(LPCWSTR lpFileName, DWORD attributes)
|
|
{
|
|
LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName );
|
|
BOOL32 res = SetFileAttributes32A( afn, attributes );
|
|
HeapFree( GetProcessHeap(), 0, afn );
|
|
return res;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* SetFileApisToOEM (KERNEL32.645)
|
|
*/
|
|
VOID WINAPI SetFileApisToOEM(void)
|
|
{
|
|
/*FIXME(file,"(): stub!\n");*/
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* SetFileApisToANSI (KERNEL32.644)
|
|
*/
|
|
VOID WINAPI SetFileApisToANSI(void)
|
|
{
|
|
/*FIXME(file,"(): stub\n");*/
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* AreFileApisANSI [KERNEL32.105] Determines if file functions are using ANSI
|
|
*
|
|
* RETURNS
|
|
* TRUE: Set of file functions is using ANSI code page
|
|
* FALSE: Set of file functions is using OEM code page
|
|
*/
|
|
BOOL32 WINAPI AreFileApisANSI(void)
|
|
{
|
|
FIXME(file,"(void): stub\n");
|
|
return TRUE;
|
|
}
|
|
|