Reimplemented CreateDirectoryW and RemoveDirectoryW using ntdll
functions.
This commit is contained in:
parent
cf67839bc4
commit
ad9b799324
|
@ -1003,6 +1003,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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
15
server/fd.c
15
server/fd.c
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue