server: Fail if non-empty directory marked for deletion.
Signed-off-by: Daniel Lehman <dlehman25@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
306c40e673
commit
a302ab44ac
|
@ -3185,17 +3185,14 @@ todo_wine
|
|||
CloseHandle( handle2 );
|
||||
fdi.DoDeleteFile = TRUE;
|
||||
res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
|
||||
todo_wine
|
||||
ok( res == STATUS_DIRECTORY_NOT_EMPTY, "unexpected FileDispositionInformation result (expected STATUS_DIRECTORY_NOT_EMPTY, got %x)\n", res );
|
||||
fileDeleted = DeleteFileA( buffer );
|
||||
ok( fileDeleted, "File should have been deleted\n" );
|
||||
buffer[dirpos] = '\0';
|
||||
CloseHandle( handle );
|
||||
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
todo_wine
|
||||
ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
|
||||
fileDeleted = RemoveDirectoryA( buffer );
|
||||
todo_wine
|
||||
ok( fileDeleted, "Directory should have been deleted\n" );
|
||||
}
|
||||
|
||||
|
|
74
server/fd.c
74
server/fd.c
|
@ -23,6 +23,7 @@
|
|||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
@ -2364,6 +2365,31 @@ static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handl
|
|||
return fd;
|
||||
}
|
||||
|
||||
static int is_dir_empty( int fd )
|
||||
{
|
||||
DIR *dir;
|
||||
int empty;
|
||||
struct dirent *de;
|
||||
|
||||
if ((fd = dup( fd )) == -1)
|
||||
return -1;
|
||||
|
||||
if (!(dir = fdopendir( fd )))
|
||||
{
|
||||
close( fd );
|
||||
return -1;
|
||||
}
|
||||
|
||||
empty = 1;
|
||||
while (empty && (de = readdir( dir )))
|
||||
{
|
||||
if (!strcmp( de->d_name, "." ) || !strcmp( de->d_name, ".." )) continue;
|
||||
empty = 0;
|
||||
}
|
||||
closedir( dir );
|
||||
return empty;
|
||||
}
|
||||
|
||||
/* set disposition for the fd */
|
||||
static void set_fd_disposition( struct fd *fd, int unlink )
|
||||
{
|
||||
|
@ -2381,24 +2407,38 @@ static void set_fd_disposition( struct fd *fd, int unlink )
|
|||
return;
|
||||
}
|
||||
|
||||
if (fstat( fd->unix_fd, &st ) == -1)
|
||||
if (unlink)
|
||||
{
|
||||
file_set_error();
|
||||
return;
|
||||
}
|
||||
|
||||
/* can't unlink special files */
|
||||
if (unlink && !S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
/* can't unlink files we don't have permission to write */
|
||||
if (unlink && !(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) && !S_ISDIR(st.st_mode))
|
||||
{
|
||||
set_error( STATUS_CANNOT_DELETE );
|
||||
return;
|
||||
if (fstat( fd->unix_fd, &st ) == -1)
|
||||
{
|
||||
file_set_error();
|
||||
return;
|
||||
}
|
||||
if (S_ISREG( st.st_mode )) /* can't unlink files we don't have permission to write */
|
||||
{
|
||||
if (!(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
|
||||
{
|
||||
set_error( STATUS_CANNOT_DELETE );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (S_ISDIR( st.st_mode )) /* can't remove non-empty directories */
|
||||
{
|
||||
switch (is_dir_empty( fd->unix_fd ))
|
||||
{
|
||||
case -1:
|
||||
file_set_error();
|
||||
return;
|
||||
case 0:
|
||||
set_error( STATUS_DIRECTORY_NOT_EMPTY );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else /* can't unlink special files */
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fd->closed->unlink = unlink ? 1 : 0;
|
||||
|
|
Loading…
Reference in New Issue