kernel32: Fixed behavior of FindFirstFile for DOS devices.
This commit is contained in:
parent
d65e80c85e
commit
98a3912e9f
|
@ -1553,6 +1553,7 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR filename, FINDEX_INFO_LEVELS level,
|
|||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status;
|
||||
DWORD device = 0;
|
||||
|
||||
TRACE("%s %d %p %d %p %x\n", debugstr_w(filename), level, data, search_op, filter, flags);
|
||||
|
||||
|
@ -1574,27 +1575,56 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR filename, FINDEX_INFO_LEVELS level,
|
|||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (!mask || !*mask)
|
||||
{
|
||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info))))
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!RtlCreateUnicodeString( &info->mask, mask ))
|
||||
if (!mask && (device = RtlIsDosDeviceName_U( filename )))
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
WCHAR *dir = NULL;
|
||||
|
||||
/* we still need to check that the directory can be opened */
|
||||
|
||||
if (HIWORD(device))
|
||||
{
|
||||
if (!(dir = HeapAlloc( GetProcessHeap(), 0, HIWORD(device) + sizeof(WCHAR) )))
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
goto error;
|
||||
}
|
||||
memcpy( dir, filename, HIWORD(device) );
|
||||
dir[HIWORD(device)/sizeof(WCHAR)] = 0;
|
||||
}
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
if (!RtlDosPathNameToNtPathName_U( dir ? dir : dotW, &nt_name, &mask, NULL ))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, dir );
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
goto error;
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, dir );
|
||||
RtlInitUnicodeString( &info->mask, NULL );
|
||||
}
|
||||
else if (!mask || !*mask)
|
||||
{
|
||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!RtlCreateUnicodeString( &info->mask, mask ))
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* truncate dir name before mask */
|
||||
*mask = 0;
|
||||
nt_name.Length = (mask - nt_name.Buffer) * sizeof(WCHAR);
|
||||
/* truncate dir name before mask */
|
||||
*mask = 0;
|
||||
nt_name.Length = (mask - nt_name.Buffer) * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/* check if path is the root of the drive */
|
||||
info->is_root = FALSE;
|
||||
|
@ -1620,7 +1650,10 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR filename, FINDEX_INFO_LEVELS level,
|
|||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
RtlFreeUnicodeString( &info->mask );
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||
else
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -1631,14 +1664,24 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR filename, FINDEX_INFO_LEVELS level,
|
|||
info->data_len = 0;
|
||||
info->search_op = search_op;
|
||||
|
||||
if (!FindNextFileW( (HANDLE)info, data ))
|
||||
if (device)
|
||||
{
|
||||
WIN32_FIND_DATAW *wfd = data;
|
||||
|
||||
memset( wfd, 0, sizeof(*wfd) );
|
||||
memcpy( wfd->cFileName, filename + HIWORD(device)/sizeof(WCHAR), LOWORD(device) );
|
||||
wfd->dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
|
||||
CloseHandle( info->handle );
|
||||
info->handle = 0;
|
||||
}
|
||||
else if (!FindNextFileW( (HANDLE)info, data ))
|
||||
{
|
||||
TRACE( "%s not found\n", debugstr_w(filename) );
|
||||
FindClose( (HANDLE)info );
|
||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (!strpbrkW( info->mask.Buffer, wildcardsW ))
|
||||
else if (!strpbrkW( info->mask.Buffer, wildcardsW ))
|
||||
{
|
||||
/* we can't find two files with the same name */
|
||||
CloseHandle( info->handle );
|
||||
|
|
|
@ -1186,7 +1186,7 @@ static char get_windows_drive(void)
|
|||
static void test_FindFirstFileA(void)
|
||||
{
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAA search_results;
|
||||
WIN32_FIND_DATAA data;
|
||||
int err;
|
||||
char buffer[5] = "C:\\";
|
||||
char buffer2[100];
|
||||
|
@ -1195,7 +1195,7 @@ static void test_FindFirstFileA(void)
|
|||
buffer[0] = get_windows_drive();
|
||||
|
||||
SetLastError( 0xdeadbeaf );
|
||||
handle = FindFirstFileA(buffer, &search_results);
|
||||
handle = FindFirstFileA(buffer, &data);
|
||||
err = GetLastError();
|
||||
ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on root directory should fail\n" );
|
||||
ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
|
@ -1203,7 +1203,7 @@ static void test_FindFirstFileA(void)
|
|||
/* try FindFirstFileA on "C:\*" */
|
||||
strcpy(buffer2, buffer);
|
||||
strcat(buffer2, "*");
|
||||
handle = FindFirstFileA(buffer2, &search_results);
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
|
||||
ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
|
||||
|
||||
|
@ -1211,7 +1211,7 @@ static void test_FindFirstFileA(void)
|
|||
SetLastError( 0xdeadbeaf );
|
||||
strcpy(buffer2, buffer);
|
||||
strcat(buffer2, "foo\\");
|
||||
handle = FindFirstFileA(buffer2, &search_results);
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
err = GetLastError();
|
||||
ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
|
||||
todo_wine {
|
||||
|
@ -1222,33 +1222,94 @@ static void test_FindFirstFileA(void)
|
|||
SetLastError( 0xdeadbeaf );
|
||||
strcpy(buffer2, buffer);
|
||||
strcat(buffer2, "foo\\bar.txt");
|
||||
handle = FindFirstFileA(buffer2, &search_results);
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
err = GetLastError();
|
||||
ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
|
||||
todo_wine {
|
||||
ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
}
|
||||
ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
|
||||
/* try FindFirstFileA on "C:\foo\*.*" */
|
||||
SetLastError( 0xdeadbeaf );
|
||||
strcpy(buffer2, buffer);
|
||||
strcat(buffer2, "foo\\*.*");
|
||||
handle = FindFirstFileA(buffer2, &search_results);
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
err = GetLastError();
|
||||
ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
|
||||
todo_wine {
|
||||
ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
}
|
||||
ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
|
||||
/* try FindFirstFileA on "foo\bar.txt" */
|
||||
SetLastError( 0xdeadbeaf );
|
||||
strcpy(buffer2, "foo\\bar.txt");
|
||||
handle = FindFirstFileA(buffer2, &search_results);
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
err = GetLastError();
|
||||
ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
|
||||
todo_wine {
|
||||
ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
}
|
||||
ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
|
||||
/* try FindFirstFileA on "c:\nul" */
|
||||
SetLastError( 0xdeadbeaf );
|
||||
strcpy(buffer2, buffer);
|
||||
strcat(buffer2, "nul");
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
err = GetLastError();
|
||||
ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed\n", buffer2 );
|
||||
ok( 0 == lstrcmpiA(data.cFileName, "nul"), "wrong name %s\n", data.cFileName );
|
||||
ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
|
||||
ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
|
||||
ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes, "wrong attributes %x\n", data.dwFileAttributes );
|
||||
SetLastError( 0xdeadbeaf );
|
||||
ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
|
||||
ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
|
||||
ok( FindClose( handle ), "failed to close handle\n" );
|
||||
|
||||
/* try FindFirstFileA on "lpt1" */
|
||||
SetLastError( 0xdeadbeaf );
|
||||
strcpy(buffer2, "lpt1");
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
err = GetLastError();
|
||||
ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed\n", buffer2 );
|
||||
ok( 0 == lstrcmpiA(data.cFileName, "lpt1"), "wrong name %s\n", data.cFileName );
|
||||
ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
|
||||
ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
|
||||
ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes, "wrong attributes %x\n", data.dwFileAttributes );
|
||||
SetLastError( 0xdeadbeaf );
|
||||
ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
|
||||
ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
|
||||
ok( FindClose( handle ), "failed to close handle\n" );
|
||||
|
||||
/* try FindFirstFileA on "c:\nul\*" */
|
||||
SetLastError( 0xdeadbeaf );
|
||||
strcpy(buffer2, buffer);
|
||||
strcat(buffer2, "nul\\*");
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
err = GetLastError();
|
||||
ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
|
||||
ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
|
||||
/* try FindFirstFileA on "c:\nul*" */
|
||||
SetLastError( 0xdeadbeaf );
|
||||
strcpy(buffer2, buffer);
|
||||
strcat(buffer2, "nul*");
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
err = GetLastError();
|
||||
ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
|
||||
ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
|
||||
/* try FindFirstFileA on "c:\foo\bar\nul" */
|
||||
SetLastError( 0xdeadbeaf );
|
||||
strcpy(buffer2, buffer);
|
||||
strcat(buffer2, "foo\\bar\\nul");
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
err = GetLastError();
|
||||
ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
|
||||
ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
|
||||
/* try FindFirstFileA on "c:\foo\nul\bar" */
|
||||
SetLastError( 0xdeadbeaf );
|
||||
strcpy(buffer2, buffer);
|
||||
strcat(buffer2, "foo\\nul\\bar");
|
||||
handle = FindFirstFileA(buffer2, &data);
|
||||
err = GetLastError();
|
||||
ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
|
||||
ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
|
||||
}
|
||||
|
||||
static void test_FindNextFileA(void)
|
||||
|
|
Loading…
Reference in New Issue