From c4c4da4e07e6d3ce4df159553017a8e574592a8b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 3 Apr 2004 00:05:24 +0000 Subject: [PATCH] Reimplemented DeleteFile by using CreateFile with FILE_FLAG_DELETE_ON_CLOSE. Added/fixed a few tests. --- dlls/kernel/file.c | 38 ++++++++++++++++++++++ dlls/kernel/tests/file.c | 33 +++++++++++++++---- dlls/kernel/volume.c | 5 +-- files/file.c | 70 ++-------------------------------------- 4 files changed, 71 insertions(+), 75 deletions(-) diff --git a/dlls/kernel/file.c b/dlls/kernel/file.c index f136a13481b..ded6a64e0fc 100644 --- a/dlls/kernel/file.c +++ b/dlls/kernel/file.c @@ -552,6 +552,44 @@ void WINAPI DisposeLZ32Handle( HANDLE handle ) * 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.@) * ReplaceFile (KERNEL32.@) diff --git a/dlls/kernel/tests/file.c b/dlls/kernel/tests/file.c index f7341061b9a..88fc271099c 100644 --- a/dlls/kernel/tests/file.c +++ b/dlls/kernel/tests/file.c @@ -596,6 +596,7 @@ static void test_CreateFileW(void) HANDLE hFile; WCHAR temp_path[MAX_PATH]; WCHAR filename[MAX_PATH]; + WCHAR emptyW[]={'\0'}; static const WCHAR prefix[] = {'p','f','x',0}; DWORD ret; @@ -615,6 +616,16 @@ static void test_CreateFileW(void) ret = DeleteFileW(filename); 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 || GetLastError() == ERROR_BAD_PATHNAME), "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 ) @@ -701,12 +717,13 @@ static void test_MoveFileA(void) lstrcpyA(source, dest); lstrcpyA(dest, tempdir); 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); todo_wine { ok(!ret, "MoveFileA: shouldn't move to wildcard file\n"); ok(GetLastError() == ERROR_INVALID_NAME, "MoveFileA: with wildcards, unexpected error %ld\n", GetLastError()); -#if 0 if (ret || (GetLastError() != ERROR_INVALID_NAME)) { WIN32_FIND_DATAA fd; @@ -730,12 +747,12 @@ static void test_MoveFileA(void) FindClose(hFind); } } -#endif ret = DeleteFileA(source); ok(ret, "DeleteFileA: error %ld\n", GetLastError()); ret = DeleteFileA(dest); ok(!ret, "DeleteFileA: error %ld\n", GetLastError()); } +#endif ret = RemoveDirectoryA(tempdir); 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) { ok(rc, "WriteFile error %ld\n", GetLastError()); 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)), "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) { ok(rc, "ReadFile error %ld\n", GetLastError()); 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)), "expected file offset %d\n", PATTERN_OFFSET + sizeof(pattern)); 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 }; 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 (s1 = 0; s1 < 4; 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) { 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++) { 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], access_modes[a2], sharing_modes[s2] )) { diff --git a/dlls/kernel/volume.c b/dlls/kernel/volume.c index 08d6e53da98..48cc2f130ff 100644 --- a/dlls/kernel/volume.c +++ b/dlls/kernel/volume.c @@ -312,7 +312,8 @@ HANDLE VOLUME_OpenDevice( LPCWSTR name, DWORD access, DWORD sharing, { 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 (!dev) break; @@ -346,7 +347,7 @@ HANDLE VOLUME_OpenDevice( LPCWSTR name, DWORD access, DWORD sharing, 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 ); return ret; } diff --git a/files/file.c b/files/file.c index f0f670f3b56..c41bc9fd1c8 100644 --- a/files/file.c +++ b/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 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; } + 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_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.@) */