Commit c4c4da4e authored by Alexandre Julliard's avatar Alexandre Julliard

Reimplemented DeleteFile by using CreateFile with

FILE_FLAG_DELETE_ON_CLOSE. Added/fixed a few tests.
parent b70e0c8e
......@@ -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.@)
......
......@@ -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] ))
{
......
......@@ -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;
}
......
......@@ -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 ":"",
......@@ -1196,71 +1197,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.@)
*/
DWORD WINAPI GetFileType( HANDLE hFile )
......
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