Reimplemented DeleteFile by using CreateFile with
FILE_FLAG_DELETE_ON_CLOSE. Added/fixed a few tests.
This commit is contained in:
parent
b70e0c8ea6
commit
c4c4da4e07
|
@ -552,6 +552,44 @@ void WINAPI DisposeLZ32Handle( HANDLE handle )
|
||||||
* Operations on file names *
|
* Operations on file names *
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* DeleteFileW (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI DeleteFileW( LPCWSTR path )
|
||||||
|
{
|
||||||
|
HANDLE hFile;
|
||||||
|
|
||||||
|
TRACE("%s\n", debugstr_w(path) );
|
||||||
|
|
||||||
|
hFile = CreateFileW( path, GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 );
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
|
||||||
|
|
||||||
|
CloseHandle(hFile); /* last close will delete the file */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* DeleteFileA (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI DeleteFileA( LPCSTR path )
|
||||||
|
{
|
||||||
|
UNICODE_STRING pathW;
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
|
if (RtlCreateUnicodeStringFromAsciiz(&pathW, path))
|
||||||
|
{
|
||||||
|
ret = DeleteFileW(pathW.Buffer);
|
||||||
|
RtlFreeUnicodeString(&pathW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* ReplaceFileW (KERNEL32.@)
|
* ReplaceFileW (KERNEL32.@)
|
||||||
* ReplaceFile (KERNEL32.@)
|
* ReplaceFile (KERNEL32.@)
|
||||||
|
|
|
@ -596,6 +596,7 @@ static void test_CreateFileW(void)
|
||||||
HANDLE hFile;
|
HANDLE hFile;
|
||||||
WCHAR temp_path[MAX_PATH];
|
WCHAR temp_path[MAX_PATH];
|
||||||
WCHAR filename[MAX_PATH];
|
WCHAR filename[MAX_PATH];
|
||||||
|
WCHAR emptyW[]={'\0'};
|
||||||
static const WCHAR prefix[] = {'p','f','x',0};
|
static const WCHAR prefix[] = {'p','f','x',0};
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
|
|
||||||
|
@ -615,6 +616,16 @@ static void test_CreateFileW(void)
|
||||||
|
|
||||||
ret = DeleteFileW(filename);
|
ret = DeleteFileW(filename);
|
||||||
ok(ret, "DeleteFileW: error %ld\n", GetLastError());
|
ok(ret, "DeleteFileW: error %ld\n", GetLastError());
|
||||||
|
|
||||||
|
hFile = CreateFileW(NULL, GENERIC_READ, 0, NULL,
|
||||||
|
CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
|
||||||
|
ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
|
||||||
|
"CreateFileW(NULL) returned ret=%p error=%ld\n",hFile,GetLastError());
|
||||||
|
|
||||||
|
hFile = CreateFileW(emptyW, GENERIC_READ, 0, NULL,
|
||||||
|
CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
|
||||||
|
ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
|
||||||
|
"CreateFileW(\"\") returned ret=%p error=%ld\n",hFile,GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -647,6 +658,11 @@ static void test_DeleteFileA( void )
|
||||||
ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND ||
|
ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND ||
|
||||||
GetLastError() == ERROR_BAD_PATHNAME),
|
GetLastError() == ERROR_BAD_PATHNAME),
|
||||||
"DeleteFileA(\"\") returned ret=%d error=%ld\n",ret,GetLastError());
|
"DeleteFileA(\"\") returned ret=%d error=%ld\n",ret,GetLastError());
|
||||||
|
|
||||||
|
ret = DeleteFileA("nul");
|
||||||
|
ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
|
||||||
|
GetLastError() == ERROR_INVALID_PARAMETER),
|
||||||
|
"DeleteFileA(\"nul\") returned ret=%d error=%ld\n",ret,GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_DeleteFileW( void )
|
static void test_DeleteFileW( void )
|
||||||
|
@ -701,12 +717,13 @@ static void test_MoveFileA(void)
|
||||||
lstrcpyA(source, dest);
|
lstrcpyA(source, dest);
|
||||||
lstrcpyA(dest, tempdir);
|
lstrcpyA(dest, tempdir);
|
||||||
lstrcatA(dest, "\\wild?.*");
|
lstrcatA(dest, "\\wild?.*");
|
||||||
|
/* FIXME: if we create a file with wildcards we can't delete it now that DeleteFile works correctly */
|
||||||
|
#if 0
|
||||||
ret = MoveFileA(source, dest);
|
ret = MoveFileA(source, dest);
|
||||||
todo_wine {
|
todo_wine {
|
||||||
ok(!ret, "MoveFileA: shouldn't move to wildcard file\n");
|
ok(!ret, "MoveFileA: shouldn't move to wildcard file\n");
|
||||||
ok(GetLastError() == ERROR_INVALID_NAME,
|
ok(GetLastError() == ERROR_INVALID_NAME,
|
||||||
"MoveFileA: with wildcards, unexpected error %ld\n", GetLastError());
|
"MoveFileA: with wildcards, unexpected error %ld\n", GetLastError());
|
||||||
#if 0
|
|
||||||
if (ret || (GetLastError() != ERROR_INVALID_NAME))
|
if (ret || (GetLastError() != ERROR_INVALID_NAME))
|
||||||
{
|
{
|
||||||
WIN32_FIND_DATAA fd;
|
WIN32_FIND_DATAA fd;
|
||||||
|
@ -730,12 +747,12 @@ static void test_MoveFileA(void)
|
||||||
FindClose(hFind);
|
FindClose(hFind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
ret = DeleteFileA(source);
|
ret = DeleteFileA(source);
|
||||||
ok(ret, "DeleteFileA: error %ld\n", GetLastError());
|
ok(ret, "DeleteFileA: error %ld\n", GetLastError());
|
||||||
ret = DeleteFileA(dest);
|
ret = DeleteFileA(dest);
|
||||||
ok(!ret, "DeleteFileA: error %ld\n", GetLastError());
|
ok(!ret, "DeleteFileA: error %ld\n", GetLastError());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = RemoveDirectoryA(tempdir);
|
ret = RemoveDirectoryA(tempdir);
|
||||||
ok(ret, "DeleteDirectoryA: error %ld\n", GetLastError());
|
ok(ret, "DeleteDirectoryA: error %ld\n", GetLastError());
|
||||||
|
@ -802,7 +819,7 @@ static void test_offset_in_overlapped_structure(void)
|
||||||
if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
|
if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
|
||||||
ok(rc, "WriteFile error %ld\n", GetLastError());
|
ok(rc, "WriteFile error %ld\n", GetLastError());
|
||||||
ok(done == sizeof(pattern), "expected number of bytes written %lu\n", done);
|
ok(done == sizeof(pattern), "expected number of bytes written %lu\n", done);
|
||||||
trace("Current offset = %04lx\n", SetFilePointer(hFile, 0, NULL, FILE_CURRENT));
|
/*trace("Current offset = %04lx\n", SetFilePointer(hFile, 0, NULL, FILE_CURRENT));*/
|
||||||
ok(SetFilePointer(hFile, 0, NULL, FILE_CURRENT) == (PATTERN_OFFSET + sizeof(pattern)),
|
ok(SetFilePointer(hFile, 0, NULL, FILE_CURRENT) == (PATTERN_OFFSET + sizeof(pattern)),
|
||||||
"expected file offset %d\n", PATTERN_OFFSET + sizeof(pattern));
|
"expected file offset %d\n", PATTERN_OFFSET + sizeof(pattern));
|
||||||
|
|
||||||
|
@ -831,7 +848,7 @@ static void test_offset_in_overlapped_structure(void)
|
||||||
if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
|
if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
|
||||||
ok(rc, "ReadFile error %ld\n", GetLastError());
|
ok(rc, "ReadFile error %ld\n", GetLastError());
|
||||||
ok(done == sizeof(pattern), "expected number of bytes read %lu\n", done);
|
ok(done == sizeof(pattern), "expected number of bytes read %lu\n", done);
|
||||||
trace("Current offset = %04lx\n", SetFilePointer(hFile, 0, NULL, FILE_CURRENT));
|
/*trace("Current offset = %04lx\n", SetFilePointer(hFile, 0, NULL, FILE_CURRENT));*/
|
||||||
ok(SetFilePointer(hFile, 0, NULL, FILE_CURRENT) == (PATTERN_OFFSET + sizeof(pattern)),
|
ok(SetFilePointer(hFile, 0, NULL, FILE_CURRENT) == (PATTERN_OFFSET + sizeof(pattern)),
|
||||||
"expected file offset %d\n", PATTERN_OFFSET + sizeof(pattern));
|
"expected file offset %d\n", PATTERN_OFFSET + sizeof(pattern));
|
||||||
ok(!memcmp(buf, pattern, sizeof(pattern)), "pattern match failed\n");
|
ok(!memcmp(buf, pattern, sizeof(pattern)), "pattern match failed\n");
|
||||||
|
@ -930,12 +947,16 @@ static void test_file_sharing(void)
|
||||||
static const DWORD sharing_modes[4] = { 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE };
|
static const DWORD sharing_modes[4] = { 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE };
|
||||||
int a1, s1, a2, s2;
|
int a1, s1, a2, s2;
|
||||||
|
|
||||||
|
/* make sure the file exists */
|
||||||
|
HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||||
|
CloseHandle( h );
|
||||||
|
|
||||||
for (a1 = 0; a1 < 4; a1++)
|
for (a1 = 0; a1 < 4; a1++)
|
||||||
{
|
{
|
||||||
for (s1 = 0; s1 < 4; s1++)
|
for (s1 = 0; s1 < 4; s1++)
|
||||||
{
|
{
|
||||||
HANDLE h = CreateFileA( filename, access_modes[a1], sharing_modes[s1],
|
HANDLE h = CreateFileA( filename, access_modes[a1], sharing_modes[s1],
|
||||||
NULL, CREATE_ALWAYS, 0, 0 );
|
NULL, OPEN_EXISTING, 0, 0 );
|
||||||
if (h == INVALID_HANDLE_VALUE)
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
|
ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
|
||||||
|
@ -946,7 +967,7 @@ static void test_file_sharing(void)
|
||||||
for (s2 = 0; s2 < 4; s2++)
|
for (s2 = 0; s2 < 4; s2++)
|
||||||
{
|
{
|
||||||
HANDLE h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
|
HANDLE h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
|
||||||
NULL, CREATE_ALWAYS, 0, 0 );
|
NULL, OPEN_EXISTING, 0, 0 );
|
||||||
if (is_sharing_compatible( access_modes[a1], sharing_modes[s1],
|
if (is_sharing_compatible( access_modes[a1], sharing_modes[s1],
|
||||||
access_modes[a2], sharing_modes[s2] ))
|
access_modes[a2], sharing_modes[s2] ))
|
||||||
{
|
{
|
||||||
|
|
|
@ -312,7 +312,8 @@ HANDLE VOLUME_OpenDevice( LPCWSTR name, DWORD access, DWORD sharing,
|
||||||
{
|
{
|
||||||
TRACE("trying %s\n", buffer );
|
TRACE("trying %s\n", buffer );
|
||||||
|
|
||||||
ret = FILE_CreateFile( buffer, access, sharing, sa, OPEN_EXISTING, 0, 0, DRIVE_FIXED );
|
ret = FILE_CreateFile( buffer, access, sharing, sa, OPEN_EXISTING,
|
||||||
|
attributes, 0, DRIVE_FIXED );
|
||||||
if (ret || GetLastError() != ERROR_FILE_NOT_FOUND) break;
|
if (ret || GetLastError() != ERROR_FILE_NOT_FOUND) break;
|
||||||
if (!dev) break;
|
if (!dev) break;
|
||||||
|
|
||||||
|
@ -346,7 +347,7 @@ HANDLE VOLUME_OpenDevice( LPCWSTR name, DWORD access, DWORD sharing,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret) ERR( "could not open device %s err %ld\n", debugstr_w(name), GetLastError() );
|
if (!ret) WARN( "could not open device %s err %ld\n", debugstr_w(name), GetLastError() );
|
||||||
HeapFree( GetProcessHeap(), 0, buffer );
|
HeapFree( GetProcessHeap(), 0, buffer );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
70
files/file.c
70
files/file.c
|
@ -311,11 +311,12 @@ HANDLE WINAPI CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing,
|
||||||
static const WCHAR coninW[] = {'C','O','N','I','N','$',0};
|
static const WCHAR coninW[] = {'C','O','N','I','N','$',0};
|
||||||
static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0};
|
static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0};
|
||||||
|
|
||||||
if (!filename)
|
if (!filename || !filename[0])
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_INVALID_PARAMETER );
|
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("%s %s%s%s%s%s%s%s attributes 0x%lx\n", debugstr_w(filename),
|
TRACE("%s %s%s%s%s%s%s%s attributes 0x%lx\n", debugstr_w(filename),
|
||||||
((access & GENERIC_READ)==GENERIC_READ)?"GENERIC_READ ":"",
|
((access & GENERIC_READ)==GENERIC_READ)?"GENERIC_READ ":"",
|
||||||
((access & GENERIC_WRITE)==GENERIC_WRITE)?"GENERIC_WRITE ":"",
|
((access & GENERIC_WRITE)==GENERIC_WRITE)?"GENERIC_WRITE ":"",
|
||||||
|
@ -1195,71 +1196,6 @@ BOOL WINAPI SetEndOfFile( HANDLE hFile )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* DeleteFileW (KERNEL32.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI DeleteFileW( LPCWSTR path )
|
|
||||||
{
|
|
||||||
DOS_FULL_NAME full_name;
|
|
||||||
HANDLE hFile;
|
|
||||||
|
|
||||||
TRACE("%s\n", debugstr_w(path) );
|
|
||||||
if (!path || !*path)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_PATH_NOT_FOUND);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (RtlIsDosDeviceName_U( path ))
|
|
||||||
{
|
|
||||||
WARN("cannot remove DOS device %s!\n", debugstr_w(path));
|
|
||||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DOSFS_GetFullName( path, TRUE, &full_name )) return FALSE;
|
|
||||||
|
|
||||||
/* check if we are allowed to delete the source */
|
|
||||||
hFile = FILE_CreateFile( full_name.long_name, GENERIC_READ|GENERIC_WRITE, 0,
|
|
||||||
NULL, OPEN_EXISTING, 0, 0,
|
|
||||||
GetDriveTypeW( full_name.short_name ) );
|
|
||||||
if (!hFile) return FALSE;
|
|
||||||
|
|
||||||
if (unlink( full_name.long_name ) == -1)
|
|
||||||
{
|
|
||||||
FILE_SetDosError();
|
|
||||||
CloseHandle(hFile);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
CloseHandle(hFile);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* DeleteFileA (KERNEL32.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI DeleteFileA( LPCSTR path )
|
|
||||||
{
|
|
||||||
UNICODE_STRING pathW;
|
|
||||||
BOOL ret = FALSE;
|
|
||||||
|
|
||||||
if (!path)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RtlCreateUnicodeStringFromAsciiz(&pathW, path))
|
|
||||||
{
|
|
||||||
ret = DeleteFileW(pathW.Buffer);
|
|
||||||
RtlFreeUnicodeString(&pathW);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GetFileType (KERNEL32.@)
|
* GetFileType (KERNEL32.@)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue