kernel32: Move some file name functions to kernelbase.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ccf4ca825c
commit
0b45fc4750
|
@ -418,317 +418,6 @@ UINT WINAPI SetHandleCount( UINT count )
|
|||
**************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* CreateFileW [KERNEL32.@] 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 [in] pointer to filename to be accessed
|
||||
* access [in] access mode requested
|
||||
* sharing [in] share mode
|
||||
* sa [in] pointer to security attributes
|
||||
* creation [in] how to create the file
|
||||
* attributes [in] attributes for newly created file
|
||||
* template [in] handle to file with extended attributes to copy
|
||||
*
|
||||
* RETURNS
|
||||
* Success: Open handle to specified file
|
||||
* Failure: INVALID_HANDLE_VALUE
|
||||
*/
|
||||
HANDLE WINAPI CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing,
|
||||
LPSECURITY_ATTRIBUTES sa, DWORD creation,
|
||||
DWORD attributes, HANDLE template )
|
||||
{
|
||||
NTSTATUS status;
|
||||
UINT options;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
IO_STATUS_BLOCK io;
|
||||
HANDLE ret;
|
||||
DWORD dosdev;
|
||||
const WCHAR *vxd_name = NULL;
|
||||
static const WCHAR bkslashes_with_dotW[] = {'\\','\\','.','\\',0};
|
||||
static const WCHAR coninW[] = {'C','O','N','I','N','$',0};
|
||||
static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0};
|
||||
SECURITY_QUALITY_OF_SERVICE qos;
|
||||
|
||||
static const UINT nt_disposition[5] =
|
||||
{
|
||||
FILE_CREATE, /* CREATE_NEW */
|
||||
FILE_OVERWRITE_IF, /* CREATE_ALWAYS */
|
||||
FILE_OPEN, /* OPEN_EXISTING */
|
||||
FILE_OPEN_IF, /* OPEN_ALWAYS */
|
||||
FILE_OVERWRITE /* TRUNCATE_EXISTING */
|
||||
};
|
||||
|
||||
|
||||
/* sanity checks */
|
||||
|
||||
if (!filename || !filename[0])
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
TRACE("%s %s%s%s%s%s%s%s creation %d attributes 0x%x\n", debugstr_w(filename),
|
||||
(access & GENERIC_READ)?"GENERIC_READ ":"",
|
||||
(access & GENERIC_WRITE)?"GENERIC_WRITE ":"",
|
||||
(access & GENERIC_EXECUTE)?"GENERIC_EXECUTE ":"",
|
||||
(!access)?"QUERY_ACCESS ":"",
|
||||
(sharing & FILE_SHARE_READ)?"FILE_SHARE_READ ":"",
|
||||
(sharing & FILE_SHARE_WRITE)?"FILE_SHARE_WRITE ":"",
|
||||
(sharing & FILE_SHARE_DELETE)?"FILE_SHARE_DELETE ":"",
|
||||
creation, attributes);
|
||||
|
||||
/* Open a console for CONIN$ or CONOUT$ */
|
||||
|
||||
if (!strcmpiW(filename, coninW) || !strcmpiW(filename, conoutW))
|
||||
{
|
||||
ret = OpenConsoleW(filename, access, (sa && sa->bInheritHandle),
|
||||
creation ? OPEN_EXISTING : 0);
|
||||
if (ret == INVALID_HANDLE_VALUE) SetLastError(ERROR_INVALID_PARAMETER);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strncmpW(filename, bkslashes_with_dotW, 4))
|
||||
{
|
||||
static const WCHAR pipeW[] = {'P','I','P','E','\\',0};
|
||||
static const WCHAR mailslotW[] = {'M','A','I','L','S','L','O','T','\\',0};
|
||||
|
||||
if ((isalphaW(filename[4]) && filename[5] == ':' && filename[6] == '\0') ||
|
||||
!strncmpiW( filename + 4, pipeW, 5 ) ||
|
||||
!strncmpiW( filename + 4, mailslotW, 9 ))
|
||||
{
|
||||
dosdev = 0;
|
||||
}
|
||||
else if ((dosdev = RtlIsDosDeviceName_U( filename + 4 )))
|
||||
{
|
||||
dosdev += MAKELONG( 0, 4*sizeof(WCHAR) ); /* adjust position to start of filename */
|
||||
}
|
||||
else if (GetVersion() & 0x80000000)
|
||||
{
|
||||
vxd_name = filename + 4;
|
||||
if (!creation) creation = OPEN_EXISTING;
|
||||
}
|
||||
}
|
||||
else dosdev = RtlIsDosDeviceName_U( filename );
|
||||
|
||||
if (dosdev)
|
||||
{
|
||||
static const WCHAR conW[] = {'C','O','N'};
|
||||
|
||||
if (LOWORD(dosdev) == sizeof(conW) &&
|
||||
!strncmpiW( filename + HIWORD(dosdev)/sizeof(WCHAR), conW, ARRAY_SIZE( conW )))
|
||||
{
|
||||
switch (access & (GENERIC_READ|GENERIC_WRITE))
|
||||
{
|
||||
case GENERIC_READ:
|
||||
ret = OpenConsoleW(coninW, access, (sa && sa->bInheritHandle), OPEN_EXISTING);
|
||||
goto done;
|
||||
case GENERIC_WRITE:
|
||||
ret = OpenConsoleW(conoutW, access, (sa && sa->bInheritHandle), OPEN_EXISTING);
|
||||
goto done;
|
||||
default:
|
||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (creation < CREATE_NEW || creation > TRUNCATE_EXISTING)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( filename, &nameW, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/* now call NtCreateFile */
|
||||
|
||||
options = 0;
|
||||
if (attributes & FILE_FLAG_BACKUP_SEMANTICS)
|
||||
options |= FILE_OPEN_FOR_BACKUP_INTENT;
|
||||
else
|
||||
options |= FILE_NON_DIRECTORY_FILE;
|
||||
if (attributes & FILE_FLAG_DELETE_ON_CLOSE)
|
||||
{
|
||||
options |= FILE_DELETE_ON_CLOSE;
|
||||
access |= DELETE;
|
||||
}
|
||||
if (attributes & FILE_FLAG_NO_BUFFERING)
|
||||
options |= FILE_NO_INTERMEDIATE_BUFFERING;
|
||||
if (!(attributes & FILE_FLAG_OVERLAPPED))
|
||||
options |= FILE_SYNCHRONOUS_IO_NONALERT;
|
||||
if (attributes & FILE_FLAG_RANDOM_ACCESS)
|
||||
options |= FILE_RANDOM_ACCESS;
|
||||
if (attributes & FILE_FLAG_WRITE_THROUGH)
|
||||
options |= FILE_WRITE_THROUGH;
|
||||
attributes &= FILE_ATTRIBUTE_VALID_FLAGS;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nameW;
|
||||
attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
|
||||
if (attributes & SECURITY_SQOS_PRESENT)
|
||||
{
|
||||
qos.Length = sizeof(qos);
|
||||
qos.ImpersonationLevel = (attributes >> 16) & 0x3;
|
||||
qos.ContextTrackingMode = attributes & SECURITY_CONTEXT_TRACKING ? SECURITY_DYNAMIC_TRACKING : SECURITY_STATIC_TRACKING;
|
||||
qos.EffectiveOnly = (attributes & SECURITY_EFFECTIVE_ONLY) != 0;
|
||||
attr.SecurityQualityOfService = &qos;
|
||||
}
|
||||
else
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
if (sa && sa->bInheritHandle) attr.Attributes |= OBJ_INHERIT;
|
||||
|
||||
status = NtCreateFile( &ret, access | SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attr, &io,
|
||||
NULL, attributes, sharing, nt_disposition[creation - CREATE_NEW],
|
||||
options, NULL, 0 );
|
||||
if (status)
|
||||
{
|
||||
if (vxd_name && vxd_name[0])
|
||||
{
|
||||
static HANDLE (*vxd_open)(LPCWSTR,DWORD,SECURITY_ATTRIBUTES*);
|
||||
if (!vxd_open) vxd_open = (void *)GetProcAddress( GetModuleHandleW(krnl386W),
|
||||
"__wine_vxd_open" );
|
||||
if (vxd_open && (ret = vxd_open( vxd_name, access, sa ))) goto done;
|
||||
}
|
||||
|
||||
WARN("Unable to create file %s (status %x)\n", debugstr_w(filename), status);
|
||||
ret = INVALID_HANDLE_VALUE;
|
||||
|
||||
/* In the case file creation was rejected due to CREATE_NEW flag
|
||||
* was specified and file with that name already exists, correct
|
||||
* last error is ERROR_FILE_EXISTS and not ERROR_ALREADY_EXISTS.
|
||||
* Note: RtlNtStatusToDosError is not the subject to blame here.
|
||||
*/
|
||||
if (status == STATUS_OBJECT_NAME_COLLISION)
|
||||
SetLastError( ERROR_FILE_EXISTS );
|
||||
else
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((creation == CREATE_ALWAYS && io.Information == FILE_OVERWRITTEN) ||
|
||||
(creation == OPEN_ALWAYS && io.Information == FILE_OPENED))
|
||||
SetLastError( ERROR_ALREADY_EXISTS );
|
||||
else
|
||||
SetLastError( 0 );
|
||||
}
|
||||
RtlFreeUnicodeString( &nameW );
|
||||
|
||||
done:
|
||||
if (!ret) ret = INVALID_HANDLE_VALUE;
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* CreateFileA (KERNEL32.@)
|
||||
*
|
||||
* See CreateFileW.
|
||||
*/
|
||||
HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
|
||||
LPSECURITY_ATTRIBUTES sa, DWORD creation,
|
||||
DWORD attributes, HANDLE template)
|
||||
{
|
||||
WCHAR *nameW;
|
||||
|
||||
if ((GetVersion() & 0x80000000) && IsBadStringPtrA(filename, -1)) return INVALID_HANDLE_VALUE;
|
||||
if (!(nameW = FILE_name_AtoW( filename, FALSE ))) return INVALID_HANDLE_VALUE;
|
||||
return CreateFileW( nameW, access, sharing, sa, creation, attributes, template );
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* CreateFile2 (KERNEL32.@)
|
||||
*/
|
||||
HANDLE WINAPI CreateFile2( LPCWSTR filename, DWORD access, DWORD sharing, DWORD creation,
|
||||
CREATEFILE2_EXTENDED_PARAMETERS *exparams )
|
||||
{
|
||||
LPSECURITY_ATTRIBUTES sa = exparams ? exparams->lpSecurityAttributes : NULL;
|
||||
DWORD attributes = exparams ? exparams->dwFileAttributes : 0;
|
||||
HANDLE template = exparams ? exparams->hTemplateFile : NULL;
|
||||
|
||||
FIXME("(%s %x %x %x %p), partial stub\n", debugstr_w(filename), access, sharing, creation, exparams);
|
||||
|
||||
return CreateFileW( filename, access, sharing, sa, creation, attributes, template );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DeleteFileW (KERNEL32.@)
|
||||
*
|
||||
* Delete a file.
|
||||
*
|
||||
* PARAMS
|
||||
* path [I] Path to the file to delete.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE.
|
||||
* Failure: FALSE, check GetLastError().
|
||||
*/
|
||||
BOOL WINAPI DeleteFileW( LPCWSTR path )
|
||||
{
|
||||
UNICODE_STRING nameW;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
HANDLE hFile;
|
||||
IO_STATUS_BLOCK io;
|
||||
|
||||
TRACE("%s\n", debugstr_w(path) );
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nameW;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtCreateFile(&hFile, SYNCHRONIZE | DELETE, &attr, &io, NULL, 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
FILE_OPEN, FILE_DELETE_ON_CLOSE | FILE_NON_DIRECTORY_FILE, NULL, 0);
|
||||
if (status == STATUS_SUCCESS) status = NtClose(hFile);
|
||||
|
||||
RtlFreeUnicodeString( &nameW );
|
||||
if (status)
|
||||
{
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DeleteFileA (KERNEL32.@)
|
||||
*
|
||||
* See DeleteFileW.
|
||||
*/
|
||||
BOOL WINAPI DeleteFileA( LPCSTR path )
|
||||
{
|
||||
WCHAR *pathW;
|
||||
|
||||
if (!(pathW = FILE_name_AtoW( path, FALSE ))) return FALSE;
|
||||
return DeleteFileW( pathW );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* ReplaceFileW (KERNEL32.@)
|
||||
* ReplaceFile (KERNEL32.@)
|
||||
|
@ -1386,243 +1075,6 @@ BOOL WINAPI FindNextStreamW(HANDLE handle, void *data)
|
|||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* GetFileAttributesW (KERNEL32.@)
|
||||
*/
|
||||
DWORD WINAPI GetFileAttributesW( LPCWSTR name )
|
||||
{
|
||||
FILE_BASIC_INFORMATION info;
|
||||
UNICODE_STRING nt_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE("%s\n", debugstr_w(name));
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nt_name;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtQueryAttributesFile( &attr, &info );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
|
||||
if (status == STATUS_SUCCESS) return info.FileAttributes;
|
||||
|
||||
/* NtQueryAttributesFile fails on devices, but GetFileAttributesW succeeds */
|
||||
if (RtlIsDosDeviceName_U( name )) return FILE_ATTRIBUTE_ARCHIVE;
|
||||
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* GetFileAttributesA (KERNEL32.@)
|
||||
*/
|
||||
DWORD WINAPI GetFileAttributesA( LPCSTR name )
|
||||
{
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return INVALID_FILE_ATTRIBUTES;
|
||||
return GetFileAttributesW( nameW );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* SetFileAttributesW (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI SetFileAttributesW( LPCWSTR name, DWORD attributes )
|
||||
{
|
||||
UNICODE_STRING nt_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status;
|
||||
HANDLE handle;
|
||||
|
||||
TRACE("%s %x\n", debugstr_w(name), attributes);
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nt_name;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtOpenFile( &handle, SYNCHRONIZE, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
FILE_BASIC_INFORMATION info;
|
||||
|
||||
memset( &info, 0, sizeof(info) );
|
||||
info.FileAttributes = attributes | FILE_ATTRIBUTE_NORMAL; /* make sure it's not zero */
|
||||
status = NtSetInformationFile( handle, &io, &info, sizeof(info), FileBasicInformation );
|
||||
NtClose( handle );
|
||||
}
|
||||
|
||||
if (status == STATUS_SUCCESS) return TRUE;
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* SetFileAttributesA (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI SetFileAttributesA( LPCSTR name, DWORD attributes )
|
||||
{
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return FALSE;
|
||||
return SetFileAttributesW( nameW, attributes );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* GetFileAttributesExW (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI GetFileAttributesExW( LPCWSTR name, GET_FILEEX_INFO_LEVELS level, LPVOID ptr )
|
||||
{
|
||||
FILE_NETWORK_OPEN_INFORMATION info;
|
||||
WIN32_FILE_ATTRIBUTE_DATA *data = ptr;
|
||||
UNICODE_STRING nt_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE("%s %d %p\n", debugstr_w(name), level, ptr);
|
||||
|
||||
if (level != GetFileExInfoStandard)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nt_name;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtQueryFullAttributesFile( &attr, &info );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
data->dwFileAttributes = info.FileAttributes;
|
||||
data->ftCreationTime.dwLowDateTime = info.CreationTime.u.LowPart;
|
||||
data->ftCreationTime.dwHighDateTime = info.CreationTime.u.HighPart;
|
||||
data->ftLastAccessTime.dwLowDateTime = info.LastAccessTime.u.LowPart;
|
||||
data->ftLastAccessTime.dwHighDateTime = info.LastAccessTime.u.HighPart;
|
||||
data->ftLastWriteTime.dwLowDateTime = info.LastWriteTime.u.LowPart;
|
||||
data->ftLastWriteTime.dwHighDateTime = info.LastWriteTime.u.HighPart;
|
||||
data->nFileSizeLow = info.EndOfFile.u.LowPart;
|
||||
data->nFileSizeHigh = info.EndOfFile.u.HighPart;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* GetFileAttributesExA (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI GetFileAttributesExA( LPCSTR name, GET_FILEEX_INFO_LEVELS level, LPVOID ptr )
|
||||
{
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return FALSE;
|
||||
return GetFileAttributesExW( nameW, level, ptr );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetCompressedFileSizeW (KERNEL32.@)
|
||||
*
|
||||
* Get the actual number of bytes used on disk.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: Low-order doubleword of number of bytes
|
||||
* Failure: INVALID_FILE_SIZE
|
||||
*/
|
||||
DWORD WINAPI GetCompressedFileSizeW(
|
||||
LPCWSTR name, /* [in] Pointer to name of file */
|
||||
LPDWORD size_high ) /* [out] Receives high-order doubleword of size */
|
||||
{
|
||||
UNICODE_STRING nt_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status;
|
||||
HANDLE handle;
|
||||
DWORD ret = INVALID_FILE_SIZE;
|
||||
|
||||
TRACE("%s %p\n", debugstr_w(name), size_high);
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return INVALID_FILE_SIZE;
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nt_name;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtOpenFile( &handle, SYNCHRONIZE, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
/* we don't support compressed files, simply return the file size */
|
||||
ret = GetFileSize( handle, size_high );
|
||||
NtClose( handle );
|
||||
}
|
||||
else SetLastError( RtlNtStatusToDosError(status) );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetCompressedFileSizeA (KERNEL32.@)
|
||||
*
|
||||
* See GetCompressedFileSizeW.
|
||||
*/
|
||||
DWORD WINAPI GetCompressedFileSizeA( LPCSTR name, LPDWORD size_high )
|
||||
{
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return INVALID_FILE_SIZE;
|
||||
return GetCompressedFileSizeW( nameW, size_high );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* OpenVxDHandle (KERNEL32.@)
|
||||
*
|
||||
|
@ -1818,66 +1270,6 @@ error: /* We get here if there was an error opening the file */
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* OpenFileById (KERNEL32.@)
|
||||
*/
|
||||
HANDLE WINAPI OpenFileById( HANDLE handle, LPFILE_ID_DESCRIPTOR id, DWORD access,
|
||||
DWORD share, LPSECURITY_ATTRIBUTES sec_attr, DWORD flags )
|
||||
{
|
||||
UINT options;
|
||||
HANDLE result;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
IO_STATUS_BLOCK io;
|
||||
UNICODE_STRING objectName;
|
||||
|
||||
if (!id)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
options = FILE_OPEN_BY_FILE_ID;
|
||||
if (flags & FILE_FLAG_BACKUP_SEMANTICS)
|
||||
options |= FILE_OPEN_FOR_BACKUP_INTENT;
|
||||
else
|
||||
options |= FILE_NON_DIRECTORY_FILE;
|
||||
if (flags & FILE_FLAG_NO_BUFFERING) options |= FILE_NO_INTERMEDIATE_BUFFERING;
|
||||
if (!(flags & FILE_FLAG_OVERLAPPED)) options |= FILE_SYNCHRONOUS_IO_NONALERT;
|
||||
if (flags & FILE_FLAG_RANDOM_ACCESS) options |= FILE_RANDOM_ACCESS;
|
||||
flags &= FILE_ATTRIBUTE_VALID_FLAGS;
|
||||
|
||||
objectName.Length = sizeof(ULONGLONG);
|
||||
objectName.Buffer = (WCHAR *)&id->u.FileId;
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = handle;
|
||||
attr.Attributes = 0;
|
||||
attr.ObjectName = &objectName;
|
||||
attr.SecurityDescriptor = sec_attr ? sec_attr->lpSecurityDescriptor : NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
if (sec_attr && sec_attr->bInheritHandle) attr.Attributes |= OBJ_INHERIT;
|
||||
|
||||
status = NtCreateFile( &result, access | SYNCHRONIZE, &attr, &io, NULL, flags,
|
||||
share, OPEN_EXISTING, options, NULL, 0 );
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
SetLastError( RtlNtStatusToDosError( status ) );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ReOpenFile (KERNEL32.@)
|
||||
*/
|
||||
HANDLE WINAPI ReOpenFile(HANDLE handle_original, DWORD access, DWORD sharing, DWORD flags)
|
||||
{
|
||||
FIXME("(%p, %d, %d, %d): stub\n", handle_original, access, sharing, flags);
|
||||
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* K32EnumDeviceDrivers (KERNEL32.@)
|
||||
*/
|
||||
|
|
|
@ -280,13 +280,13 @@
|
|||
@ stdcall -import CreateEventW(ptr long long wstr)
|
||||
@ stdcall -import CreateFiber(long ptr ptr)
|
||||
@ stdcall -import CreateFiberEx(long long long ptr ptr)
|
||||
@ stdcall CreateFile2(wstr long long long ptr)
|
||||
@ stdcall CreateFileA(str long long ptr long long long)
|
||||
@ stdcall -import CreateFile2(wstr long long long ptr)
|
||||
@ stdcall -import CreateFileA(str long long ptr long long long)
|
||||
@ stdcall CreateFileMappingA(long ptr long long long str)
|
||||
# @ stub CreateFileMappingNumaA
|
||||
# @ stub CreateFileMappingNumaW
|
||||
@ stdcall -import CreateFileMappingW(long ptr long long long wstr)
|
||||
@ stdcall CreateFileW(wstr long long ptr long long long)
|
||||
@ stdcall -import CreateFileW(wstr long long ptr long long long)
|
||||
@ stdcall CreateHardLinkA(str str ptr)
|
||||
@ stdcall CreateHardLinkTransactedA(str str ptr ptr)
|
||||
@ stdcall CreateHardLinkTransactedW(wstr wstr ptr ptr)
|
||||
|
@ -361,10 +361,10 @@
|
|||
# @ stub DeleteBoundaryDescriptor
|
||||
@ stdcall DeleteCriticalSection(ptr) ntdll.RtlDeleteCriticalSection
|
||||
@ stdcall -import DeleteFiber(ptr)
|
||||
@ stdcall DeleteFileA(str)
|
||||
@ stdcall -import DeleteFileA(str)
|
||||
# @ stub DeleteFileTransactedA
|
||||
# @ stub DeleteFileTransactedW
|
||||
@ stdcall DeleteFileW(wstr)
|
||||
@ stdcall -import DeleteFileW(wstr)
|
||||
@ stdcall -import DeleteProcThreadAttributeList(ptr)
|
||||
# @ stub DisableThreadProfiling
|
||||
@ stdcall DisassociateCurrentThreadFromCallback(ptr) ntdll.TpDisassociateCallback
|
||||
|
@ -570,10 +570,10 @@
|
|||
@ stdcall GetCommTimeouts(long ptr)
|
||||
@ stdcall GetCommandLineA()
|
||||
@ stdcall GetCommandLineW()
|
||||
@ stdcall GetCompressedFileSizeA(long ptr)
|
||||
@ stdcall -import GetCompressedFileSizeA(long ptr)
|
||||
# @ stub GetCompressedFileSizeTransactedA
|
||||
# @ stub GetCompressedFileSizeTransactedW
|
||||
@ stdcall GetCompressedFileSizeW(long ptr)
|
||||
@ stdcall -import GetCompressedFileSizeW(long ptr)
|
||||
@ stdcall GetComputerNameA(ptr ptr)
|
||||
@ stdcall GetComputerNameExA(long ptr ptr)
|
||||
@ stdcall GetComputerNameExW(long ptr ptr)
|
||||
|
@ -669,12 +669,12 @@
|
|||
@ stdcall -import GetExitCodeThread(long ptr)
|
||||
@ stdcall GetExpandedNameA(str ptr)
|
||||
@ stdcall GetExpandedNameW(wstr ptr)
|
||||
@ stdcall GetFileAttributesA(str)
|
||||
@ stdcall GetFileAttributesExA(str long ptr)
|
||||
@ stdcall GetFileAttributesExW(wstr long ptr)
|
||||
@ stdcall -import GetFileAttributesA(str)
|
||||
@ stdcall -import GetFileAttributesExA(str long ptr)
|
||||
@ stdcall -import GetFileAttributesExW(wstr long ptr)
|
||||
# @ stub GetFileAttributesTransactedA
|
||||
# @ stub GetFileAttributesTransactedW
|
||||
@ stdcall GetFileAttributesW(wstr)
|
||||
@ stdcall -import GetFileAttributesW(wstr)
|
||||
# @ stub GetFileBandwidthReservation
|
||||
@ stdcall -import GetFileInformationByHandle(long ptr)
|
||||
@ stdcall -import GetFileInformationByHandleEx(long long ptr long)
|
||||
|
@ -1115,7 +1115,7 @@
|
|||
@ stdcall -import OpenEventA(long long str)
|
||||
@ stdcall -import OpenEventW(long long wstr)
|
||||
@ stdcall OpenFile(str ptr long)
|
||||
@ stdcall OpenFileById(long ptr long long ptr long)
|
||||
@ stdcall -import OpenFileById(long ptr long long ptr long)
|
||||
@ stdcall OpenFileMappingA(long long str)
|
||||
@ stdcall -import OpenFileMappingW(long long wstr)
|
||||
@ stdcall OpenJobObjectA(long long str)
|
||||
|
@ -1268,7 +1268,7 @@
|
|||
# @ stub RemoveLocalAlternateComputerNameW
|
||||
@ stdcall RemoveVectoredContinueHandler(ptr) ntdll.RtlRemoveVectoredContinueHandler
|
||||
@ stdcall RemoveVectoredExceptionHandler(ptr) ntdll.RtlRemoveVectoredExceptionHandler
|
||||
@ stdcall ReOpenFile(ptr long long long) ReOpenFile
|
||||
@ stdcall -import ReOpenFile(ptr long long long) ReOpenFile
|
||||
@ stdcall ReplaceFile(wstr wstr wstr long ptr ptr) ReplaceFileW
|
||||
@ stdcall ReplaceFileA(str str str long ptr ptr)
|
||||
@ stdcall ReplaceFileW(wstr wstr wstr long ptr ptr)
|
||||
|
@ -1393,10 +1393,10 @@
|
|||
@ stdcall SetEventWhenCallbackReturns(ptr long) ntdll.TpCallbackSetEventOnCompletion
|
||||
@ stdcall -import SetFileApisToANSI()
|
||||
@ stdcall -import SetFileApisToOEM()
|
||||
@ stdcall SetFileAttributesA(str long)
|
||||
@ stdcall -import SetFileAttributesA(str long)
|
||||
# @ stub SetFileAttributesTransactedA
|
||||
# @ stub SetFileAttributesTransactedW
|
||||
@ stdcall SetFileAttributesW(wstr long)
|
||||
@ stdcall -import SetFileAttributesW(wstr long)
|
||||
# @ stub SetFileBandwidthReservation
|
||||
@ stdcall SetFileCompletionNotificationModes(long long)
|
||||
@ stdcall -import SetFileInformationByHandle(long long ptr long)
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(file);
|
||||
|
||||
static const WCHAR krnl386W[] = {'k','r','n','l','3','8','6','.','e','x','e','1','6',0};
|
||||
|
||||
static BOOL oem_file_apis;
|
||||
|
||||
|
||||
|
@ -115,6 +117,441 @@ BOOL WINAPI DECLSPEC_HOTPATCH AreFileApisANSI(void)
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* CreateFile2 (kernelbase.@)
|
||||
*/
|
||||
HANDLE WINAPI DECLSPEC_HOTPATCH CreateFile2( LPCWSTR name, DWORD access, DWORD sharing, DWORD creation,
|
||||
CREATEFILE2_EXTENDED_PARAMETERS *params )
|
||||
{
|
||||
LPSECURITY_ATTRIBUTES sa = params ? params->lpSecurityAttributes : NULL;
|
||||
DWORD attributes = params ? params->dwFileAttributes : 0;
|
||||
HANDLE template = params ? params->hTemplateFile : NULL;
|
||||
|
||||
FIXME( "(%s %x %x %x %p), partial stub\n", debugstr_w(name), access, sharing, creation, params );
|
||||
|
||||
return CreateFileW( name, access, sharing, sa, creation, attributes, template );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* CreateFileA (kernelbase.@)
|
||||
*/
|
||||
HANDLE WINAPI DECLSPEC_HOTPATCH CreateFileA( LPCSTR name, DWORD access, DWORD sharing,
|
||||
LPSECURITY_ATTRIBUTES sa, DWORD creation,
|
||||
DWORD attributes, HANDLE template)
|
||||
{
|
||||
WCHAR *nameW;
|
||||
|
||||
if ((GetVersion() & 0x80000000) && IsBadStringPtrA( name, -1 )) return INVALID_HANDLE_VALUE;
|
||||
if (!(nameW = file_name_AtoW( name, FALSE ))) return INVALID_HANDLE_VALUE;
|
||||
return CreateFileW( nameW, access, sharing, sa, creation, attributes, template );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* CreateFileW (kernelbase.@)
|
||||
*/
|
||||
HANDLE WINAPI DECLSPEC_HOTPATCH CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing,
|
||||
LPSECURITY_ATTRIBUTES sa, DWORD creation,
|
||||
DWORD attributes, HANDLE template )
|
||||
{
|
||||
NTSTATUS status;
|
||||
UINT options;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
IO_STATUS_BLOCK io;
|
||||
HANDLE ret;
|
||||
DWORD dosdev;
|
||||
const WCHAR *vxd_name = NULL;
|
||||
static const WCHAR bkslashes_with_dotW[] = {'\\','\\','.','\\',0};
|
||||
static const WCHAR coninW[] = {'C','O','N','I','N','$',0};
|
||||
static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0};
|
||||
SECURITY_QUALITY_OF_SERVICE qos;
|
||||
|
||||
static const UINT nt_disposition[5] =
|
||||
{
|
||||
FILE_CREATE, /* CREATE_NEW */
|
||||
FILE_OVERWRITE_IF, /* CREATE_ALWAYS */
|
||||
FILE_OPEN, /* OPEN_EXISTING */
|
||||
FILE_OPEN_IF, /* OPEN_ALWAYS */
|
||||
FILE_OVERWRITE /* TRUNCATE_EXISTING */
|
||||
};
|
||||
|
||||
|
||||
/* sanity checks */
|
||||
|
||||
if (!filename || !filename[0])
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
TRACE( "%s %s%s%s%s%s%s%s creation %d attributes 0x%x\n", debugstr_w(filename),
|
||||
(access & GENERIC_READ) ? "GENERIC_READ " : "",
|
||||
(access & GENERIC_WRITE) ? "GENERIC_WRITE " : "",
|
||||
(access & GENERIC_EXECUTE) ? "GENERIC_EXECUTE " : "",
|
||||
!access ? "QUERY_ACCESS " : "",
|
||||
(sharing & FILE_SHARE_READ) ? "FILE_SHARE_READ " : "",
|
||||
(sharing & FILE_SHARE_WRITE) ? "FILE_SHARE_WRITE " : "",
|
||||
(sharing & FILE_SHARE_DELETE) ? "FILE_SHARE_DELETE " : "",
|
||||
creation, attributes);
|
||||
|
||||
/* Open a console for CONIN$ or CONOUT$ */
|
||||
|
||||
if (!wcsicmp(filename, coninW) || !wcsicmp(filename, conoutW))
|
||||
{
|
||||
ret = OpenConsoleW( filename, access, sa && sa->bInheritHandle, creation ? OPEN_EXISTING : 0 );
|
||||
if (ret == INVALID_HANDLE_VALUE) SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!wcsncmp( filename, bkslashes_with_dotW, 4 ))
|
||||
{
|
||||
static const WCHAR pipeW[] = {'P','I','P','E','\\',0};
|
||||
static const WCHAR mailslotW[] = {'M','A','I','L','S','L','O','T','\\',0};
|
||||
|
||||
if ((iswalpha(filename[4]) && filename[5] == ':' && filename[6] == '\0') ||
|
||||
!wcsnicmp( filename + 4, pipeW, 5 ) ||
|
||||
!wcsnicmp( filename + 4, mailslotW, 9 ))
|
||||
{
|
||||
dosdev = 0;
|
||||
}
|
||||
else if ((dosdev = RtlIsDosDeviceName_U( filename + 4 )))
|
||||
{
|
||||
dosdev += MAKELONG( 0, 4*sizeof(WCHAR) ); /* adjust position to start of filename */
|
||||
}
|
||||
else if (GetVersion() & 0x80000000)
|
||||
{
|
||||
vxd_name = filename + 4;
|
||||
if (!creation) creation = OPEN_EXISTING;
|
||||
}
|
||||
}
|
||||
else dosdev = RtlIsDosDeviceName_U( filename );
|
||||
|
||||
if (dosdev)
|
||||
{
|
||||
static const WCHAR conW[] = {'C','O','N'};
|
||||
|
||||
if (LOWORD(dosdev) == sizeof(conW) &&
|
||||
!wcsnicmp( filename + HIWORD(dosdev)/sizeof(WCHAR), conW, ARRAY_SIZE( conW )))
|
||||
{
|
||||
switch (access & (GENERIC_READ|GENERIC_WRITE))
|
||||
{
|
||||
case GENERIC_READ:
|
||||
return OpenConsoleW( coninW, access, sa && sa->bInheritHandle, OPEN_EXISTING );
|
||||
case GENERIC_WRITE:
|
||||
return OpenConsoleW( conoutW, access, sa && sa->bInheritHandle, OPEN_EXISTING );
|
||||
default:
|
||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (creation < CREATE_NEW || creation > TRUNCATE_EXISTING)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( filename, &nameW, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/* now call NtCreateFile */
|
||||
|
||||
options = 0;
|
||||
if (attributes & FILE_FLAG_BACKUP_SEMANTICS)
|
||||
options |= FILE_OPEN_FOR_BACKUP_INTENT;
|
||||
else
|
||||
options |= FILE_NON_DIRECTORY_FILE;
|
||||
if (attributes & FILE_FLAG_DELETE_ON_CLOSE)
|
||||
{
|
||||
options |= FILE_DELETE_ON_CLOSE;
|
||||
access |= DELETE;
|
||||
}
|
||||
if (attributes & FILE_FLAG_NO_BUFFERING)
|
||||
options |= FILE_NO_INTERMEDIATE_BUFFERING;
|
||||
if (!(attributes & FILE_FLAG_OVERLAPPED))
|
||||
options |= FILE_SYNCHRONOUS_IO_NONALERT;
|
||||
if (attributes & FILE_FLAG_RANDOM_ACCESS)
|
||||
options |= FILE_RANDOM_ACCESS;
|
||||
if (attributes & FILE_FLAG_WRITE_THROUGH)
|
||||
options |= FILE_WRITE_THROUGH;
|
||||
attributes &= FILE_ATTRIBUTE_VALID_FLAGS;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nameW;
|
||||
attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
|
||||
if (attributes & SECURITY_SQOS_PRESENT)
|
||||
{
|
||||
qos.Length = sizeof(qos);
|
||||
qos.ImpersonationLevel = (attributes >> 16) & 0x3;
|
||||
qos.ContextTrackingMode = attributes & SECURITY_CONTEXT_TRACKING ? SECURITY_DYNAMIC_TRACKING : SECURITY_STATIC_TRACKING;
|
||||
qos.EffectiveOnly = (attributes & SECURITY_EFFECTIVE_ONLY) != 0;
|
||||
attr.SecurityQualityOfService = &qos;
|
||||
}
|
||||
else
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
if (sa && sa->bInheritHandle) attr.Attributes |= OBJ_INHERIT;
|
||||
|
||||
status = NtCreateFile( &ret, access | SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attr, &io,
|
||||
NULL, attributes, sharing, nt_disposition[creation - CREATE_NEW],
|
||||
options, NULL, 0 );
|
||||
if (status)
|
||||
{
|
||||
if (vxd_name && vxd_name[0])
|
||||
{
|
||||
static HANDLE (*vxd_open)(LPCWSTR,DWORD,SECURITY_ATTRIBUTES*);
|
||||
if (!vxd_open) vxd_open = (void *)GetProcAddress( GetModuleHandleW(krnl386W),
|
||||
"__wine_vxd_open" );
|
||||
if (vxd_open && (ret = vxd_open( vxd_name, access, sa ))) goto done;
|
||||
}
|
||||
|
||||
WARN("Unable to create file %s (status %x)\n", debugstr_w(filename), status);
|
||||
ret = INVALID_HANDLE_VALUE;
|
||||
|
||||
/* In the case file creation was rejected due to CREATE_NEW flag
|
||||
* was specified and file with that name already exists, correct
|
||||
* last error is ERROR_FILE_EXISTS and not ERROR_ALREADY_EXISTS.
|
||||
* Note: RtlNtStatusToDosError is not the subject to blame here.
|
||||
*/
|
||||
if (status == STATUS_OBJECT_NAME_COLLISION)
|
||||
SetLastError( ERROR_FILE_EXISTS );
|
||||
else
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((creation == CREATE_ALWAYS && io.Information == FILE_OVERWRITTEN) ||
|
||||
(creation == OPEN_ALWAYS && io.Information == FILE_OPENED))
|
||||
SetLastError( ERROR_ALREADY_EXISTS );
|
||||
else
|
||||
SetLastError( 0 );
|
||||
}
|
||||
RtlFreeUnicodeString( &nameW );
|
||||
|
||||
done:
|
||||
if (!ret) ret = INVALID_HANDLE_VALUE;
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DeleteFileA (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH DeleteFileA( LPCSTR path )
|
||||
{
|
||||
WCHAR *pathW;
|
||||
|
||||
if (!(pathW = file_name_AtoW( path, FALSE ))) return FALSE;
|
||||
return DeleteFileW( pathW );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DeleteFileW (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH DeleteFileW( LPCWSTR path )
|
||||
{
|
||||
UNICODE_STRING nameW;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
HANDLE hFile;
|
||||
IO_STATUS_BLOCK io;
|
||||
|
||||
TRACE( "%s\n", debugstr_w(path) );
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nameW;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtCreateFile(&hFile, SYNCHRONIZE | DELETE, &attr, &io, NULL, 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
FILE_OPEN, FILE_DELETE_ON_CLOSE | FILE_NON_DIRECTORY_FILE, NULL, 0);
|
||||
if (status == STATUS_SUCCESS) status = NtClose(hFile);
|
||||
|
||||
RtlFreeUnicodeString( &nameW );
|
||||
return set_ntstatus( status );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetCompressedFileSizeA (kernelbase.@)
|
||||
*/
|
||||
DWORD WINAPI DECLSPEC_HOTPATCH GetCompressedFileSizeA( LPCSTR name, LPDWORD size_high )
|
||||
{
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!(nameW = file_name_AtoW( name, FALSE ))) return INVALID_FILE_SIZE;
|
||||
return GetCompressedFileSizeW( nameW, size_high );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetCompressedFileSizeW (kernelbase.@)
|
||||
*/
|
||||
DWORD WINAPI DECLSPEC_HOTPATCH GetCompressedFileSizeW( LPCWSTR name, LPDWORD size_high )
|
||||
{
|
||||
UNICODE_STRING nt_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status;
|
||||
HANDLE handle;
|
||||
DWORD ret;
|
||||
|
||||
TRACE("%s %p\n", debugstr_w(name), size_high);
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return INVALID_FILE_SIZE;
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nt_name;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtOpenFile( &handle, SYNCHRONIZE, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
if (!set_ntstatus( status )) return INVALID_FILE_SIZE;
|
||||
|
||||
/* we don't support compressed files, simply return the file size */
|
||||
ret = GetFileSize( handle, size_high );
|
||||
NtClose( handle );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* GetFileAttributesA (kernelbase.@)
|
||||
*/
|
||||
DWORD WINAPI DECLSPEC_HOTPATCH GetFileAttributesA( LPCSTR name )
|
||||
{
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!(nameW = file_name_AtoW( name, FALSE ))) return INVALID_FILE_ATTRIBUTES;
|
||||
return GetFileAttributesW( nameW );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* GetFileAttributesW (kernelbase.@)
|
||||
*/
|
||||
DWORD WINAPI DECLSPEC_HOTPATCH GetFileAttributesW( LPCWSTR name )
|
||||
{
|
||||
FILE_BASIC_INFORMATION info;
|
||||
UNICODE_STRING nt_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE( "%s\n", debugstr_w(name) );
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nt_name;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtQueryAttributesFile( &attr, &info );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
|
||||
if (status == STATUS_SUCCESS) return info.FileAttributes;
|
||||
|
||||
/* NtQueryAttributesFile fails on devices, but GetFileAttributesW succeeds */
|
||||
if (RtlIsDosDeviceName_U( name )) return FILE_ATTRIBUTE_ARCHIVE;
|
||||
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* GetFileAttributesExA (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH GetFileAttributesExA( LPCSTR name, GET_FILEEX_INFO_LEVELS level, void *ptr )
|
||||
{
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!(nameW = file_name_AtoW( name, FALSE ))) return FALSE;
|
||||
return GetFileAttributesExW( nameW, level, ptr );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* GetFileAttributesExW (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH GetFileAttributesExW( LPCWSTR name, GET_FILEEX_INFO_LEVELS level, void *ptr )
|
||||
{
|
||||
FILE_NETWORK_OPEN_INFORMATION info;
|
||||
WIN32_FILE_ATTRIBUTE_DATA *data = ptr;
|
||||
UNICODE_STRING nt_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE("%s %d %p\n", debugstr_w(name), level, ptr);
|
||||
|
||||
if (level != GetFileExInfoStandard)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nt_name;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtQueryFullAttributesFile( &attr, &info );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
if (!set_ntstatus( status )) return FALSE;
|
||||
|
||||
data->dwFileAttributes = info.FileAttributes;
|
||||
data->ftCreationTime.dwLowDateTime = info.CreationTime.u.LowPart;
|
||||
data->ftCreationTime.dwHighDateTime = info.CreationTime.u.HighPart;
|
||||
data->ftLastAccessTime.dwLowDateTime = info.LastAccessTime.u.LowPart;
|
||||
data->ftLastAccessTime.dwHighDateTime = info.LastAccessTime.u.HighPart;
|
||||
data->ftLastWriteTime.dwLowDateTime = info.LastWriteTime.u.LowPart;
|
||||
data->ftLastWriteTime.dwHighDateTime = info.LastWriteTime.u.HighPart;
|
||||
data->nFileSizeLow = info.EndOfFile.u.LowPart;
|
||||
data->nFileSizeHigh = info.EndOfFile.u.HighPart;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* SetFileApisToANSI (kernelbase.@)
|
||||
*/
|
||||
|
@ -133,6 +570,60 @@ void WINAPI DECLSPEC_HOTPATCH SetFileApisToOEM(void)
|
|||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* SetFileAttributesA (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH SetFileAttributesA( LPCSTR name, DWORD attributes )
|
||||
{
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!(nameW = file_name_AtoW( name, FALSE ))) return FALSE;
|
||||
return SetFileAttributesW( nameW, attributes );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* SetFileAttributesW (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH SetFileAttributesW( LPCWSTR name, DWORD attributes )
|
||||
{
|
||||
UNICODE_STRING nt_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status;
|
||||
HANDLE handle;
|
||||
|
||||
TRACE( "%s %x\n", debugstr_w(name), attributes );
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||
{
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nt_name;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
status = NtOpenFile( &handle, SYNCHRONIZE, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
FILE_BASIC_INFORMATION info;
|
||||
|
||||
memset( &info, 0, sizeof(info) );
|
||||
info.FileAttributes = attributes | FILE_ATTRIBUTE_NORMAL; /* make sure it's not zero */
|
||||
status = NtSetInformationFile( handle, &io, &info, sizeof(info), FileBasicInformation );
|
||||
NtClose( handle );
|
||||
}
|
||||
return set_ntstatus( status );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Operations on file handles
|
||||
***********************************************************************/
|
||||
|
@ -460,6 +951,61 @@ BOOL WINAPI DECLSPEC_HOTPATCH LockFileEx( HANDLE file, DWORD flags, DWORD reserv
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* OpenFileById (kernelbase.@)
|
||||
*/
|
||||
HANDLE WINAPI DECLSPEC_HOTPATCH OpenFileById( HANDLE handle, LPFILE_ID_DESCRIPTOR id, DWORD access,
|
||||
DWORD share, LPSECURITY_ATTRIBUTES sec_attr, DWORD flags )
|
||||
{
|
||||
UINT options;
|
||||
HANDLE result;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
UNICODE_STRING objectName;
|
||||
|
||||
if (!id)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
options = FILE_OPEN_BY_FILE_ID;
|
||||
if (flags & FILE_FLAG_BACKUP_SEMANTICS)
|
||||
options |= FILE_OPEN_FOR_BACKUP_INTENT;
|
||||
else
|
||||
options |= FILE_NON_DIRECTORY_FILE;
|
||||
if (flags & FILE_FLAG_NO_BUFFERING) options |= FILE_NO_INTERMEDIATE_BUFFERING;
|
||||
if (!(flags & FILE_FLAG_OVERLAPPED)) options |= FILE_SYNCHRONOUS_IO_NONALERT;
|
||||
if (flags & FILE_FLAG_RANDOM_ACCESS) options |= FILE_RANDOM_ACCESS;
|
||||
flags &= FILE_ATTRIBUTE_VALID_FLAGS;
|
||||
|
||||
objectName.Length = sizeof(ULONGLONG);
|
||||
objectName.Buffer = (WCHAR *)&id->u.FileId;
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = handle;
|
||||
attr.Attributes = 0;
|
||||
attr.ObjectName = &objectName;
|
||||
attr.SecurityDescriptor = sec_attr ? sec_attr->lpSecurityDescriptor : NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
if (sec_attr && sec_attr->bInheritHandle) attr.Attributes |= OBJ_INHERIT;
|
||||
|
||||
if (!set_ntstatus( NtCreateFile( &result, access | SYNCHRONIZE, &attr, &io, NULL, flags,
|
||||
share, OPEN_EXISTING, options, NULL, 0 )))
|
||||
return INVALID_HANDLE_VALUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ReOpenFile (kernelbase.@)
|
||||
*/
|
||||
HANDLE WINAPI DECLSPEC_HOTPATCH ReOpenFile( HANDLE handle, DWORD access, DWORD sharing, DWORD flags )
|
||||
{
|
||||
FIXME( "(%p, %d, %d, %d): stub\n", handle, access, sharing, flags );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ReadFile (kernelbase.@)
|
||||
*/
|
||||
|
|
|
@ -185,12 +185,12 @@
|
|||
@ stdcall CreateEventW(ptr long long wstr)
|
||||
@ stdcall CreateFiber(long ptr ptr)
|
||||
@ stdcall CreateFiberEx(long long long ptr ptr)
|
||||
@ stdcall CreateFile2(wstr long long long ptr) kernel32.CreateFile2
|
||||
@ stdcall CreateFileA(str long long ptr long long long) kernel32.CreateFileA
|
||||
@ stdcall CreateFile2(wstr long long long ptr)
|
||||
@ stdcall CreateFileA(str long long ptr long long long)
|
||||
# @ stub CreateFileMappingFromApp
|
||||
@ stub CreateFileMappingNumaW
|
||||
@ stdcall CreateFileMappingW(long ptr long long long wstr)
|
||||
@ stdcall CreateFileW(wstr long long ptr long long long) kernel32.CreateFileW
|
||||
@ stdcall CreateFileW(wstr long long ptr long long long)
|
||||
@ stdcall CreateHardLinkA(str str ptr) kernel32.CreateHardLinkA
|
||||
@ stdcall CreateHardLinkW(wstr wstr ptr) kernel32.CreateHardLinkW
|
||||
@ stdcall CreateIoCompletionPort(long long long long)
|
||||
|
@ -250,8 +250,8 @@
|
|||
# @ stub DeleteBoundaryDescriptor
|
||||
@ stdcall DeleteCriticalSection(ptr) ntdll.RtlDeleteCriticalSection
|
||||
@ stdcall DeleteFiber(ptr)
|
||||
@ stdcall DeleteFileA(str) kernel32.DeleteFileA
|
||||
@ stdcall DeleteFileW(wstr) kernel32.DeleteFileW
|
||||
@ stdcall DeleteFileA(str)
|
||||
@ stdcall DeleteFileW(wstr)
|
||||
@ stdcall DeleteProcThreadAttributeList(ptr)
|
||||
# @ stub DeleteStateAtomValue
|
||||
# @ stub DeleteStateContainer
|
||||
|
@ -435,8 +435,8 @@
|
|||
@ stdcall GetCommTimeouts(long ptr) kernel32.GetCommTimeouts
|
||||
@ stdcall GetCommandLineA() kernel32.GetCommandLineA
|
||||
@ stdcall GetCommandLineW() kernel32.GetCommandLineW
|
||||
@ stdcall GetCompressedFileSizeA(long ptr) kernel32.GetCompressedFileSizeA
|
||||
@ stdcall GetCompressedFileSizeW(long ptr) kernel32.GetCompressedFileSizeW
|
||||
@ stdcall GetCompressedFileSizeA(long ptr)
|
||||
@ stdcall GetCompressedFileSizeW(long ptr)
|
||||
@ stdcall GetComputerNameExA(long ptr ptr) kernel32.GetComputerNameExA
|
||||
@ stdcall GetComputerNameExW(long ptr ptr) kernel32.GetComputerNameExW
|
||||
@ stdcall GetConsoleCP() kernel32.GetConsoleCP
|
||||
|
@ -502,10 +502,10 @@
|
|||
@ stdcall GetExitCodeProcess(long ptr)
|
||||
@ stdcall GetExitCodeThread(long ptr)
|
||||
@ stub GetFallbackDisplayName
|
||||
@ stdcall GetFileAttributesA(str) kernel32.GetFileAttributesA
|
||||
@ stdcall GetFileAttributesExA(str long ptr) kernel32.GetFileAttributesExA
|
||||
@ stdcall GetFileAttributesExW(wstr long ptr) kernel32.GetFileAttributesExW
|
||||
@ stdcall GetFileAttributesW(wstr) kernel32.GetFileAttributesW
|
||||
@ stdcall GetFileAttributesA(str)
|
||||
@ stdcall GetFileAttributesExA(str long ptr)
|
||||
@ stdcall GetFileAttributesExW(wstr long ptr)
|
||||
@ stdcall GetFileAttributesW(wstr)
|
||||
@ stdcall GetFileInformationByHandle(long ptr)
|
||||
@ stdcall GetFileInformationByHandleEx(long long ptr long)
|
||||
@ stdcall GetFileMUIInfo(long wstr ptr ptr) kernel32.GetFileMUIInfo
|
||||
|
@ -983,7 +983,7 @@
|
|||
# @ stub OfferVirtualMemory
|
||||
@ stdcall OpenEventA(long long str)
|
||||
@ stdcall OpenEventW(long long wstr)
|
||||
@ stdcall OpenFileById(long ptr long long ptr long) kernel32.OpenFileById
|
||||
@ stdcall OpenFileById(long ptr long long ptr long)
|
||||
# @ stub OpenFileMappingFromApp
|
||||
@ stdcall OpenFileMappingW(long long wstr)
|
||||
# @ stub OpenGlobalizationUserSettingsKey
|
||||
|
@ -1234,7 +1234,7 @@
|
|||
# @ stub QuirkIsEnabledForProcess
|
||||
@ stdcall RaiseException(long long long ptr) kernel32.RaiseException
|
||||
# @ stub RaiseFailFastException
|
||||
@ stdcall ReOpenFile(ptr long long long) kernel32.ReOpenFile
|
||||
@ stdcall ReOpenFile(ptr long long long)
|
||||
@ stdcall ReadConsoleA(long ptr long ptr ptr) kernel32.ReadConsoleA
|
||||
@ stdcall ReadConsoleInputA(long ptr long ptr) kernel32.ReadConsoleInputA
|
||||
@ stub ReadConsoleInputExA
|
||||
|
@ -1431,8 +1431,8 @@
|
|||
@ stdcall SetEventWhenCallbackReturns(ptr long) ntdll.TpCallbackSetEventOnCompletion
|
||||
@ stdcall SetFileApisToANSI()
|
||||
@ stdcall SetFileApisToOEM()
|
||||
@ stdcall SetFileAttributesA(str long) kernel32.SetFileAttributesA
|
||||
@ stdcall SetFileAttributesW(wstr long) kernel32.SetFileAttributesW
|
||||
@ stdcall SetFileAttributesA(str long)
|
||||
@ stdcall SetFileAttributesW(wstr long)
|
||||
@ stdcall SetFileInformationByHandle(long long ptr long)
|
||||
# @ stub SetFileIoOverlappedRange
|
||||
@ stdcall SetFilePointer(long long ptr long)
|
||||
|
|
Loading…
Reference in New Issue