Files
reactos/reactos/lib/kernel32/file/create.c
T
Casper Hornstrup 5a7413d3b7 2003-07-10 Casper S. Hornstrup <[email protected]>
* lib/kernel32/debug/break.c: Add @implemented and @unimplemented
	to APIs.
	* lib/kernel32/debug/debugger.c: Ditto.
	* lib/kernel32/debug/output.c: Ditto.
	* lib/kernel32/except/except.c: Ditto.
	* lib/kernel32/file/backup.c: Ditto.
	* lib/kernel32/file/cnotify.c: Ditto.
	* lib/kernel32/file/copy.c: Ditto.
	* lib/kernel32/file/create.c: Ditto.
	* lib/kernel32/file/curdir.c: Ditto.
	* lib/kernel32/file/delete.c: Ditto.
	* lib/kernel32/file/deviceio.c: Ditto.
	* lib/kernel32/file/dir.c: Ditto.
	* lib/kernel32/file/dosdev.c: Ditto.
	* lib/kernel32/file/file.c: Ditto.
	* lib/kernel32/file/find.c: Ditto.
	* lib/kernel32/file/iocompl.c: Ditto.
	* lib/kernel32/file/lfile.c: Ditto.
	* lib/kernel32/file/lock.c: Ditto.
	* lib/kernel32/file/mailslot.c: Ditto.
	* lib/kernel32/file/move.c: Ditto.
	* lib/kernel32/file/npipe.c: Ditto.
	* lib/kernel32/file/pipe.c: Ditto.
	* lib/kernel32/file/rw.c: Ditto.
	* lib/kernel32/file/tape.c: Ditto.
	* lib/kernel32/file/volume.c: Ditto.
	* lib/kernel32/mem/global.c: Ditto.
	* lib/kernel32/mem/heap.c: Ditto.
	* lib/kernel32/mem/isbad.c: Ditto.
	* lib/kernel32/mem/local.c: Ditto.
	* lib/kernel32/mem/procmem.c: Ditto.
	* lib/kernel32/mem/section.c: Ditto.
	* lib/kernel32/mem/virtual.c: Ditto.
	* lib/kernel32/misc/atom.c: Ditto.
	* lib/kernel32/misc/comm.c: Ditto.
	* lib/kernel32/misc/computername.c: Ditto.
	* lib/kernel32/misc/console.c: Ditto.
	* lib/kernel32/misc/env.c: Ditto.
	* lib/kernel32/misc/error.c: Ditto.
	* lib/kernel32/misc/errormsg.c: Ditto.
	* lib/kernel32/misc/handle.c: Ditto.
	* lib/kernel32/misc/ldr.c: Ditto.
	* lib/kernel32/misc/mbchars.c: Ditto.
	* lib/kernel32/misc/muldiv.c: Ditto.
	* lib/kernel32/misc/perfcnt.c: Ditto.
	* lib/kernel32/misc/profile.c: Ditto.
	* lib/kernel32/misc/res.c: Ditto.
	* lib/kernel32/misc/stubs.c: Ditto.
	* lib/kernel32/misc/sysinfo.c: Ditto.
	* lib/kernel32/misc/time.c: Ditto.
	* lib/kernel32/misc/toolhelp.c: Ditto.
	* lib/kernel32/process/cmdline.c: Ditto.
	* lib/kernel32/process/create.c: Ditto.
	* lib/kernel32/process/proc.c: Ditto.
	* lib/kernel32/process/session.c: Ditto.
	* lib/kernel32/string/lstring.c: Ditto.
	* lib/kernel32/synch/critical.c: Ditto.
	* lib/kernel32/synch/event.c: Ditto.
	* lib/kernel32/synch/intrlck.c: Ditto.
	* lib/kernel32/synch/mutex.c: Ditto.
	* lib/kernel32/synch/sem.c: Ditto.
	* lib/kernel32/synch/timer.c: Ditto.
	* lib/kernel32/synch/wait.c: Ditto.
	* lib/kernel32/thread/fiber.c: Ditto.
	* lib/kernel32/thread/fls.c: Ditto.
	* lib/kernel32/thread/thread.c: Ditto.
	* lib/kernel32/thread/tls.c: Ditto.

svn path=/trunk/; revision=5045
2003-07-10 18:50:51 +00:00

308 lines
7.6 KiB
C

/* $Id: create.c,v 1.33 2003/07/10 18:50:51 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/file/create.c
* PURPOSE: Directory functions
* PROGRAMMER: Ariadne ( [email protected])
* GetTempFileName is modified from WINE [ Alexandre Juiliard ]
* UPDATE HISTORY:
* Created 01/11/98
* Removed use of SearchPath (not used by Windows)
* 18/08/2002: CreateFileW mess cleaned up (KJK::Hyperion)
* 24/08/2002: removed superfluous DPRINTs (KJK::Hyperion)
*/
/* INCLUDES *****************************************************************/
#include <k32.h>
#define NDEBUG
#include <kernel32/kernel32.h>
/* FUNCTIONS ****************************************************************/
/*
* @implemented
*/
HANDLE STDCALL CreateFileA (LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile)
{
UNICODE_STRING FileNameU;
ANSI_STRING FileName;
HANDLE FileHandle;
DPRINT("CreateFileA(lpFileName %s)\n",lpFileName);
RtlInitAnsiString (&FileName,
(LPSTR)lpFileName);
/* convert ansi (or oem) string to unicode */
if (bIsFileApiAnsi)
RtlAnsiStringToUnicodeString (&FileNameU,
&FileName,
TRUE);
else
RtlOemStringToUnicodeString (&FileNameU,
&FileName,
TRUE);
FileHandle = CreateFileW (FileNameU.Buffer,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
RtlFreeHeap (RtlGetProcessHeap (),
0,
FileNameU.Buffer);
return FileHandle;
}
/*
* @implemented
*/
HANDLE STDCALL CreateFileW (LPCWSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING NtPathU;
HANDLE FileHandle;
NTSTATUS Status;
ULONG Flags = 0;
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
DPRINT("CreateFileW(lpFileName %S)\n",lpFileName);
if(hTemplateFile != NULL)
{
/* FIXME */
DPRINT("Template file feature not supported yet\n");
SetLastError(ERROR_NOT_SUPPORTED);
return INVALID_HANDLE_VALUE;
}
/* validate & translate the creation disposition */
switch (dwCreationDisposition)
{
case CREATE_NEW:
dwCreationDisposition = FILE_CREATE;
break;
case CREATE_ALWAYS:
dwCreationDisposition = FILE_OVERWRITE_IF;
break;
case OPEN_EXISTING:
dwCreationDisposition = FILE_OPEN;
break;
case OPEN_ALWAYS:
dwCreationDisposition = FILE_OPEN_IF;
break;
case TRUNCATE_EXISTING:
dwCreationDisposition = FILE_OVERWRITE;
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return (INVALID_HANDLE_VALUE);
}
/* validate & translate the flags */
if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)
{
DPRINT("Overlapped I/O not supported\n");
SetLastError(ERROR_NOT_SUPPORTED);
return INVALID_HANDLE_VALUE;
}
else
Flags |= FILE_SYNCHRONOUS_IO_ALERT;
/* validate & translate the filename */
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
&NtPathU,
NULL,
NULL))
{
DPRINT("Invalid path\n");
SetLastError(ERROR_BAD_PATHNAME);
return INVALID_HANDLE_VALUE;
}
DPRINT("NtPathU \'%S\'\n", NtPathU.Buffer);
/* translate the flags that need no validation */
if(dwFlagsAndAttributes & FILE_FLAG_WRITE_THROUGH)
Flags |= FILE_WRITE_THROUGH;
if(dwFlagsAndAttributes & FILE_FLAG_NO_BUFFERING)
Flags |= FILE_NO_INTERMEDIATE_BUFFERING;
if(dwFlagsAndAttributes & FILE_FLAG_RANDOM_ACCESS)
Flags |= FILE_RANDOM_ACCESS;
if(dwFlagsAndAttributes & FILE_FLAG_SEQUENTIAL_SCAN)
Flags |= FILE_SEQUENTIAL_ONLY;
if(dwFlagsAndAttributes & FILE_FLAG_DELETE_ON_CLOSE)
Flags |= FILE_DELETE_ON_CLOSE;
if(dwFlagsAndAttributes & FILE_FLAG_BACKUP_SEMANTICS)
{
if(dwDesiredAccess & GENERIC_ALL)
Flags |= FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_FOR_RECOVERY;
else
{
if(dwDesiredAccess & GENERIC_READ)
Flags |= FILE_OPEN_FOR_BACKUP_INTENT;
if(dwDesiredAccess & GENERIC_WRITE)
Flags |= FILE_OPEN_FOR_RECOVERY;
}
}
else
Flags |= FILE_NON_DIRECTORY_FILE;
/* FILE_FLAG_POSIX_SEMANTICS is handled later */
#if 0
/* FIXME: Win32 constants to be defined */
if(dwFlagsAndAttributes & FILE_FLAG_OPEN_REPARSE_POINT)
Flags |= FILE_OPEN_REPARSE_POINT;
if(dwFlagsAndAttributes & FILE_FLAG_OPEN_NO_RECALL)
Flags |= FILE_OPEN_NO_RECALL;
#endif
/* translate the desired access */
if (dwDesiredAccess & GENERIC_ALL)
dwDesiredAccess |= FILE_ALL_ACCESS;
else
{
if (dwDesiredAccess & GENERIC_READ)
dwDesiredAccess |= FILE_GENERIC_READ;
if (dwDesiredAccess & GENERIC_WRITE)
dwDesiredAccess |= FILE_GENERIC_WRITE;
if (dwDesiredAccess & GENERIC_EXECUTE)
dwDesiredAccess |= FILE_GENERIC_EXECUTE;
}
/* check for console output */
if (0 == _wcsicmp(L"CONOUT$", lpFileName))
{
/* FIXME: Send required access rights to Csrss */
Request.Type = CSRSS_GET_OUTPUT_HANDLE;
Status = CsrClientCallServer(&Request,
&Reply,
sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
SetLastErrorByStatus(Status);
return INVALID_HANDLE_VALUE;
}
else
{
return Reply.Data.GetOutputHandleReply.OutputHandle;
}
}
/* check for console input */
if (0 == _wcsicmp(L"CONIN$", lpFileName))
{
/* FIXME: Send required access rights to Csrss */
Request.Type = CSRSS_GET_INPUT_HANDLE;
Status = CsrClientCallServer(&Request,
&Reply,
sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
SetLastErrorByStatus(Status);
return INVALID_HANDLE_VALUE;
}
else
{
return Reply.Data.GetInputHandleReply.InputHandle;
}
}
/* build the object attributes */
InitializeObjectAttributes(
&ObjectAttributes,
&NtPathU,
0,
NULL,
NULL
);
if (lpSecurityAttributes)
{
if(lpSecurityAttributes->bInheritHandle)
ObjectAttributes.Attributes |= OBJ_INHERIT;
ObjectAttributes.SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
}
if(!(dwFlagsAndAttributes & FILE_FLAG_POSIX_SEMANTICS))
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
/* perform the call */
Status = NtCreateFile (&FileHandle,
dwDesiredAccess,
&ObjectAttributes,
&IoStatusBlock,
NULL,
dwFlagsAndAttributes,
dwShareMode,
dwCreationDisposition,
Flags,
NULL,
0);
RtlFreeUnicodeString(&NtPathU);
/* error */
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus (Status);
return INVALID_HANDLE_VALUE;
}
switch(IoStatusBlock.Information)
{
case FILE_OPENED:
case FILE_CREATED:
SetLastError(ERROR_ALREADY_EXISTS);
break;
default:
break;
}
return FileHandle;
}
/* EOF */