PATCH: FindNextFile error code
Alex Pasadyn
ajp at mail.utexas.edu
Thu Sep 11 20:41:15 CDT 2003
Greetings all,
As discussed on wine-devel a couple weeks ago, this is a patch that
changes FindNextFile and friends to use HeapAlloc and a critical section
instead of GlobalAlloc. The reason is that GlobalUnlock was setting the
last error to 0, and that was breaking some programs.
I also merged the test program I used into the existing file tests.
Alex
ChangeLog:
- Use HeapAlloc instead of GlobalAlloc in FindNextFile
- Add test for FindNextFile that checks last error value
-------------- next part --------------
Index: files/dos_fs.c
===================================================================
RCS file: /home/wine/wine/files/dos_fs.c,v
retrieving revision 1.136
diff -u -r1.136 dos_fs.c
--- files/dos_fs.c 5 Sep 2003 23:15:45 -0000 1.136
+++ files/dos_fs.c 12 Sep 2003 01:13:57 -0000
@@ -147,6 +147,7 @@
BYTE attr;
int drive;
int cur_pos;
+ CRITICAL_SECTION cs;
union
{
DOS_DIR *dos_dir;
@@ -1995,7 +1996,6 @@
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags)
{
- HGLOBAL handle;
FIND_FIRST_INFO *info;
if (!lpFileName)
@@ -2023,20 +2023,22 @@
if (lpFileName[0] == '\\' && lpFileName[1] == '\\')
{
ERR("UNC path name\n");
- if (!(handle = GlobalAlloc(GMEM_MOVEABLE, sizeof(FIND_FIRST_INFO)))) break;
+ if (!(info = HeapAlloc( GetProcessHeap(), 0, sizeof(FIND_FIRST_INFO)))) break;
- info = (FIND_FIRST_INFO *)GlobalLock( handle );
+ RtlInitializeCriticalSection( &info->cs );
+ RtlEnterCriticalSection( &info->cs );
info->u.smb_dir = SMB_FindFirst(lpFileName);
if(!info->u.smb_dir)
{
- GlobalUnlock( handle );
- GlobalFree(handle);
+ RtlLeaveCriticalSection( &info->cs );
+ RtlDeleteCriticalSection( &info->cs );
+ HeapFree(GetProcessHeap(), 0, info);
break;
}
info->drive = -1;
- GlobalUnlock( handle );
+ RtlLeaveCriticalSection( &info->cs );
}
else
{
@@ -2053,8 +2055,9 @@
}
}
if (!DOSFS_GetFullName( lpFileName, FALSE, &full_name )) break;
- if (!(handle = GlobalAlloc(GMEM_MOVEABLE, sizeof(FIND_FIRST_INFO)))) break;
- info = (FIND_FIRST_INFO *)GlobalLock( handle );
+ if (!(info = HeapAlloc( GetProcessHeap(), 0, sizeof(FIND_FIRST_INFO)))) break;
+ RtlInitializeCriticalSection( &info->cs );
+ RtlEnterCriticalSection( &info->cs );
info->path = HeapAlloc( GetProcessHeap(), 0, strlen(full_name.long_name)+1 );
strcpy( info->path, full_name.long_name );
@@ -2071,15 +2074,15 @@
info->cur_pos = 0;
info->u.dos_dir = DOSFS_OpenDir( codepage, info->path );
- GlobalUnlock( handle );
+ RtlLeaveCriticalSection( &info->cs );
}
- if (!FindNextFileW( handle, data ))
+ if (!FindNextFileW( (HANDLE) info, data ))
{
- FindClose( handle );
+ FindClose( (HANDLE) info );
SetLastError( ERROR_FILE_NOT_FOUND );
break;
}
- return handle;
+ return (HANDLE) info;
}
break;
default:
@@ -2163,12 +2166,13 @@
BOOL ret = FALSE;
DWORD gle = ERROR_NO_MORE_FILES;
- if ((handle == INVALID_HANDLE_VALUE) ||
- !(info = (FIND_FIRST_INFO *)GlobalLock( handle )))
+ if (handle == INVALID_HANDLE_VALUE)
{
SetLastError( ERROR_INVALID_HANDLE );
return ret;
}
+ info = (FIND_FIRST_INFO*) handle;
+ RtlEnterCriticalSection( &info->cs );
if (info->drive == -1)
{
ret = SMB_FindNext( info->u.smb_dir, data );
@@ -2194,7 +2198,7 @@
}
ret = TRUE;
done:
- GlobalUnlock( handle );
+ RtlLeaveCriticalSection( &info->cs );
if( !ret ) SetLastError( gle );
return ret;
}
@@ -2226,13 +2230,14 @@
*/
BOOL WINAPI FindClose( HANDLE handle )
{
- FIND_FIRST_INFO *info;
+ FIND_FIRST_INFO *info = (FIND_FIRST_INFO*) handle;
if (handle == INVALID_HANDLE_VALUE) goto error;
__TRY
{
- if ((info = (FIND_FIRST_INFO *)GlobalLock( handle )))
+ RtlEnterCriticalSection( &info->cs );
+ if (info)
{
if (info->u.dos_dir) DOSFS_CloseDir( info->u.dos_dir );
if (info->path) HeapFree( GetProcessHeap(), 0, info->path );
@@ -2247,8 +2252,9 @@
}
__ENDTRY
if (!info) goto error;
- GlobalUnlock( handle );
- GlobalFree( handle );
+ RtlLeaveCriticalSection( &info->cs );
+ RtlDeleteCriticalSection( &info->cs );
+ HeapFree(GetProcessHeap(), 0, info);
return TRUE;
error:
-------------- next part --------------
Index: dlls/kernel/tests/file.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/tests/file.c,v
retrieving revision 1.19
diff -u -r1.19 file.c
--- dlls/kernel/tests/file.c 5 Sep 2003 23:08:36 -0000 1.19
+++ dlls/kernel/tests/file.c 12 Sep 2003 01:12:30 -0000
@@ -813,6 +813,23 @@
ok ( FindClose(handle) == TRUE, "Failed to close handle");
}
+void test_FindNextFileA()
+{
+ HANDLE handle;
+ WIN32_FIND_DATAA search_results;
+ int err;
+
+ handle = FindFirstFileA("C:\\*",&search_results);
+ ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed" );
+ while (FindNextFile(handle, &search_results))
+ {
+ /* get to the end of the files */
+ }
+ ok ( FindClose(handle) == TRUE, "Failed to close handle");
+ err = GetLastError();
+ ok ( err == ERROR_NO_MORE_FILES, "GetLastError should return ERROR_NO_MORE_FILES");
+}
+
START_TEST(file)
{
test__hread( );
@@ -830,6 +847,7 @@
test_DeleteFileA();
test_DeleteFileW();
test_FindFirstFileA();
+ test_FindNextFileA();
test_LockFile();
test_offset_in_overlapped_structure();
}
More information about the wine-patches
mailing list