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 *
|
||||
**************************************************************************/
|
||||
|
||||
/***********************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
|
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 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.@)
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue