Commit ad9b7993 authored by Alexandre Julliard's avatar Alexandre Julliard

Reimplemented CreateDirectoryW and RemoveDirectoryW using ntdll

functions.
parent cf67839b
......@@ -1004,6 +1004,195 @@ BOOL WINAPI MoveFileA( LPCSTR source, LPCSTR dest )
/***********************************************************************
* CreateDirectoryW (KERNEL32.@)
* RETURNS:
* TRUE : success
* FALSE : failure
* ERROR_DISK_FULL: on full disk
* ERROR_ALREADY_EXISTS: if directory name exists (even as file)
* ERROR_ACCESS_DENIED: on permission problems
* ERROR_FILENAME_EXCED_RANGE: too long filename(s)
*/
BOOL WINAPI CreateDirectoryW( LPCWSTR path, LPSECURITY_ATTRIBUTES sa )
{
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nt_name;
IO_STATUS_BLOCK io;
NTSTATUS status;
HANDLE handle;
BOOL ret = FALSE;
TRACE( "%s\n", debugstr_w(path) );
if (!RtlDosPathNameToNtPathName_U( path, &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 = sa ? sa->lpSecurityDescriptor : NULL;
attr.SecurityQualityOfService = NULL;
status = NtCreateFile( &handle, GENERIC_READ, &attr, &io, NULL,
FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_CREATE,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 );
if (status == STATUS_SUCCESS)
{
NtClose( handle );
ret = TRUE;
}
else SetLastError( RtlNtStatusToDosError(status) );
RtlFreeUnicodeString( &nt_name );
return ret;
}
/***********************************************************************
* CreateDirectoryA (KERNEL32.@)
*/
BOOL WINAPI CreateDirectoryA( LPCSTR path, LPSECURITY_ATTRIBUTES sa )
{
UNICODE_STRING pathW;
BOOL ret;
if (path)
{
if (!RtlCreateUnicodeStringFromAsciiz(&pathW, path))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
}
else pathW.Buffer = NULL;
ret = CreateDirectoryW( pathW.Buffer, sa );
RtlFreeUnicodeString( &pathW );
return ret;
}
/***********************************************************************
* CreateDirectoryExA (KERNEL32.@)
*/
BOOL WINAPI CreateDirectoryExA( LPCSTR template, LPCSTR path, LPSECURITY_ATTRIBUTES sa )
{
UNICODE_STRING pathW, templateW;
BOOL ret;
if (path)
{
if (!RtlCreateUnicodeStringFromAsciiz( &pathW, path ))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
}
else pathW.Buffer = NULL;
if (template)
{
if (!RtlCreateUnicodeStringFromAsciiz( &templateW, template ))
{
RtlFreeUnicodeString( &pathW );
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
}
else templateW.Buffer = NULL;
ret = CreateDirectoryExW( templateW.Buffer, pathW.Buffer, sa );
RtlFreeUnicodeString( &pathW );
RtlFreeUnicodeString( &templateW );
return ret;
}
/***********************************************************************
* CreateDirectoryExW (KERNEL32.@)
*/
BOOL WINAPI CreateDirectoryExW( LPCWSTR template, LPCWSTR path, LPSECURITY_ATTRIBUTES sa )
{
return CreateDirectoryW( path, sa );
}
/***********************************************************************
* RemoveDirectoryW (KERNEL32.@)
*/
BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
{
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nt_name;
ANSI_STRING unix_name;
IO_STATUS_BLOCK io;
NTSTATUS status;
HANDLE handle;
BOOL ret = FALSE;
TRACE( "%s\n", debugstr_w(path) );
if (!RtlDosPathNameToNtPathName_U( path, &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, GENERIC_READ, &attr, &io,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT );
if (status == STATUS_SUCCESS)
status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN, FALSE );
RtlFreeUnicodeString( &nt_name );
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
if (!(ret = (rmdir( unix_name.Buffer ) != -1))) FILE_SetDosError();
RtlFreeAnsiString( &unix_name );
NtClose( handle );
return ret;
}
/***********************************************************************
* RemoveDirectoryA (KERNEL32.@)
*/
BOOL WINAPI RemoveDirectoryA( LPCSTR path )
{
UNICODE_STRING pathW;
BOOL ret = FALSE;
if (!path)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&pathW, path))
{
ret = RemoveDirectoryW(pathW.Buffer);
RtlFreeUnicodeString(&pathW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
}
/***********************************************************************
* wine_get_unix_file_name (KERNEL32.@) Not a Windows API
*
* Return the full Unix file name for a given path.
......
......@@ -329,157 +329,3 @@ UINT WINAPI GetSystemDirectoryA( LPSTR path, UINT count )
}
return len;
}
/***********************************************************************
* CreateDirectoryW (KERNEL32.@)
* RETURNS:
* TRUE : success
* FALSE : failure
* ERROR_DISK_FULL: on full disk
* ERROR_ALREADY_EXISTS: if directory name exists (even as file)
* ERROR_ACCESS_DENIED: on permission problems
* ERROR_FILENAME_EXCED_RANGE: too long filename(s)
*/
BOOL WINAPI CreateDirectoryW( LPCWSTR path,
LPSECURITY_ATTRIBUTES lpsecattribs )
{
DOS_FULL_NAME full_name;
if (!path || !*path)
{
SetLastError(ERROR_PATH_NOT_FOUND);
return FALSE;
}
TRACE_(file)("(%s,%p)\n", debugstr_w(path), lpsecattribs );
if (RtlIsDosDeviceName_U( path ))
{
TRACE_(file)("cannot use device %s!\n", debugstr_w(path));
SetLastError( ERROR_ACCESS_DENIED );
return FALSE;
}
if (!DOSFS_GetFullName( path, FALSE, &full_name )) return 0;
if (mkdir( full_name.long_name, 0777 ) == -1) {
WARN_(file)("Error '%s' trying to create directory '%s'\n", strerror(errno), full_name.long_name);
/* the FILE_SetDosError() generated error codes don't match the
* CreateDirectory ones for some errnos */
switch (errno) {
case EEXIST:
{
if (!strcmp(DRIVE_GetRoot(full_name.drive), full_name.long_name))
SetLastError(ERROR_ACCESS_DENIED);
else
SetLastError(ERROR_ALREADY_EXISTS);
break;
}
case ENOSPC: SetLastError(ERROR_DISK_FULL); break;
default: FILE_SetDosError();break;
}
return FALSE;
}
return TRUE;
}
/***********************************************************************
* CreateDirectoryA (KERNEL32.@)
*/
BOOL WINAPI CreateDirectoryA( LPCSTR path,
LPSECURITY_ATTRIBUTES lpsecattribs )
{
UNICODE_STRING pathW;
BOOL ret = FALSE;
if (!path || !*path)
{
SetLastError(ERROR_PATH_NOT_FOUND);
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&pathW, path))
{
ret = CreateDirectoryW(pathW.Buffer, lpsecattribs);
RtlFreeUnicodeString(&pathW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
}
/***********************************************************************
* CreateDirectoryExA (KERNEL32.@)
*/
BOOL WINAPI CreateDirectoryExA( LPCSTR template, LPCSTR path,
LPSECURITY_ATTRIBUTES lpsecattribs)
{
return CreateDirectoryA(path,lpsecattribs);
}
/***********************************************************************
* CreateDirectoryExW (KERNEL32.@)
*/
BOOL WINAPI CreateDirectoryExW( LPCWSTR template, LPCWSTR path,
LPSECURITY_ATTRIBUTES lpsecattribs)
{
return CreateDirectoryW(path,lpsecattribs);
}
/***********************************************************************
* RemoveDirectoryW (KERNEL32.@)
*/
BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
{
DOS_FULL_NAME full_name;
if (!path)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
TRACE_(file)("%s\n", debugstr_w(path));
if (RtlIsDosDeviceName_U( path ))
{
TRACE_(file)("cannot remove device %s!\n", debugstr_w(path));
SetLastError( ERROR_FILE_NOT_FOUND );
return FALSE;
}
if (!DOSFS_GetFullName( path, TRUE, &full_name )) return FALSE;
if (rmdir( full_name.long_name ) == -1)
{
FILE_SetDosError();
return FALSE;
}
return TRUE;
}
/***********************************************************************
* RemoveDirectoryA (KERNEL32.@)
*/
BOOL WINAPI RemoveDirectoryA( LPCSTR path )
{
UNICODE_STRING pathW;
BOOL ret = FALSE;
if (!path)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&pathW, path))
{
ret = RemoveDirectoryW(pathW.Buffer);
RtlFreeUnicodeString(&pathW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
}
......@@ -929,6 +929,21 @@ struct fd *open_fd( struct fd *fd, const char *name, int flags, mode_t *mode,
release_object( fd );
return NULL;
}
/* create the directory if needed */
if ((options & FILE_DIRECTORY_FILE) && (flags & O_CREAT))
{
if (mkdir( name, 0777 ) == -1)
{
if (errno != EEXIST || (flags & O_EXCL))
{
file_set_error();
release_object( fd );
free( closed_fd );
return NULL;
}
}
flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
}
if ((fd->unix_fd = open( name, flags, *mode )) == -1)
{
file_set_error();
......
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