Implemented FindFirstFileEx, cleaned old implementation up.
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 3d45991..5570241 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -1434,94 +1434,154 @@
return count;
}
-
-
/*************************************************************************
- * FindFirstFile16 (KERNEL.413)
+ * FindFirstFileExA (KERNEL32)
*/
-HANDLE16 WINAPI FindFirstFile16( LPCSTR path, WIN32_FIND_DATAA *data )
+HANDLE WINAPI FindFirstFileExA(
+ LPCSTR lpFileName,
+ FINDEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFindFileData,
+ FINDEX_SEARCH_OPS fSearchOp,
+ LPVOID lpSearchFilter,
+ DWORD dwAdditionalFlags)
{
DOS_FULL_NAME full_name;
- HGLOBAL16 handle;
+ HGLOBAL handle;
FIND_FIRST_INFO *info;
-
- data->dwReserved0 = data->dwReserved1 = 0x0;
- if (!path) return 0;
- if (!DOSFS_GetFullName( path, FALSE, &full_name ))
- return INVALID_HANDLE_VALUE16;
- if (!(handle = GlobalAlloc16( GMEM_MOVEABLE, sizeof(FIND_FIRST_INFO) )))
- return INVALID_HANDLE_VALUE16;
- info = (FIND_FIRST_INFO *)GlobalLock16( handle );
- info->path = HEAP_strdupA( GetProcessHeap(), 0, full_name.long_name );
- info->long_mask = strrchr( info->path, '/' );
- *(info->long_mask++) = '\0';
- info->short_mask = NULL;
- info->attr = 0xff;
- if (path[0] && (path[1] == ':')) info->drive = toupper(*path) - 'A';
- else info->drive = DRIVE_GetCurrentDrive();
- info->cur_pos = 0;
-
- info->dir = DOSFS_OpenDir( info->path );
-
- GlobalUnlock16( handle );
- if (!FindNextFile16( handle, data ))
+
+ if ((fSearchOp != FindExSearchNameMatch) || (dwAdditionalFlags != 0))
{
- FindClose16( handle );
- SetLastError( ERROR_NO_MORE_FILES );
- return INVALID_HANDLE_VALUE16;
+ FIXME("options not implemented 0x%08x 0x%08lx\n", fSearchOp, dwAdditionalFlags );
+ return INVALID_HANDLE_VALUE;
}
- return handle;
-}
+ switch(fInfoLevelId)
+ {
+ case FindExInfoStandard:
+ {
+ WIN32_FIND_DATAA * data = (WIN32_FIND_DATAA *) lpFindFileData;
+ data->dwReserved0 = data->dwReserved1 = 0x0;
+ if (!lpFileName) return 0;
+ if (!DOSFS_GetFullName( lpFileName, FALSE, &full_name )) break;
+ if (!(handle = GlobalAlloc(GMEM_MOVEABLE, sizeof(FIND_FIRST_INFO)))) break;
+ info = (FIND_FIRST_INFO *)GlobalLock( handle );
+ info->path = HEAP_strdupA( GetProcessHeap(), 0, full_name.long_name );
+ info->long_mask = strrchr( info->path, '/' );
+ *(info->long_mask++) = '\0';
+ info->short_mask = NULL;
+ info->attr = 0xff;
+ if (lpFileName[0] && (lpFileName[1] == ':'))
+ info->drive = toupper(*lpFileName) - 'A';
+ else info->drive = DRIVE_GetCurrentDrive();
+ info->cur_pos = 0;
+
+ info->dir = DOSFS_OpenDir( info->path );
+
+ GlobalUnlock( handle );
+ if (!FindNextFileA( handle, data ))
+ {
+ FindClose( handle );
+ SetLastError( ERROR_NO_MORE_FILES );
+ break;
+ }
+ return handle;
+ }
+ break;
+ default:
+ FIXME("fInfoLevelId 0x%08x not implemented\n", fInfoLevelId );
+ }
+ return INVALID_HANDLE_VALUE;
+}
/*************************************************************************
* FindFirstFileA (KERNEL32.123)
*/
-HANDLE WINAPI FindFirstFileA( LPCSTR path, WIN32_FIND_DATAA *data )
+HANDLE WINAPI FindFirstFileA(
+ LPCSTR lpFileName,
+ WIN32_FIND_DATAA *lpFindData )
{
- HANDLE handle = FindFirstFile16( path, data );
- if (handle == INVALID_HANDLE_VALUE16) return INVALID_HANDLE_VALUE;
- return handle;
+ return FindFirstFileExA(lpFileName, FindExInfoStandard, lpFindData,
+ FindExSearchNameMatch, NULL, 0);
}
+/*************************************************************************
+ * FindFirstFileExW (KERNEL32)
+ */
+HANDLE WINAPI FindFirstFileExW(
+ LPCWSTR lpFileName,
+ FINDEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFindFileData,
+ FINDEX_SEARCH_OPS fSearchOp,
+ LPVOID lpSearchFilter,
+ DWORD dwAdditionalFlags)
+{
+ HANDLE handle;
+ WIN32_FIND_DATAA dataA;
+ LPVOID _lpFindFileData;
+ LPSTR pathA;
+
+ switch(fInfoLevelId)
+ {
+ case FindExInfoStandard:
+ {
+ _lpFindFileData = &dataA;
+ }
+ break;
+ default:
+ FIXME("fInfoLevelId 0x%08x not implemented\n", fInfoLevelId );
+ return INVALID_HANDLE_VALUE;
+ }
+
+ pathA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName );
+ handle = FindFirstFileExA(pathA, fInfoLevelId, _lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags);
+ HeapFree( GetProcessHeap(), 0, pathA );
+ if (handle == INVALID_HANDLE_VALUE) return handle;
+
+ switch(fInfoLevelId)
+ {
+ case FindExInfoStandard:
+ {
+ WIN32_FIND_DATAW *dataW = (WIN32_FIND_DATAW*) lpFindFileData;
+ dataW->dwFileAttributes = dataA.dwFileAttributes;
+ dataW->ftCreationTime = dataA.ftCreationTime;
+ dataW->ftLastAccessTime = dataA.ftLastAccessTime;
+ dataW->ftLastWriteTime = dataA.ftLastWriteTime;
+ dataW->nFileSizeHigh = dataA.nFileSizeHigh;
+ dataW->nFileSizeLow = dataA.nFileSizeLow;
+ lstrcpyAtoW( dataW->cFileName, dataA.cFileName );
+ lstrcpyAtoW( dataW->cAlternateFileName, dataA.cAlternateFileName );
+ }
+ break;
+ default:
+ FIXME("fInfoLevelId 0x%08x not implemented\n", fInfoLevelId );
+ return INVALID_HANDLE_VALUE;
+ }
+ return handle;
+}
/*************************************************************************
* FindFirstFileW (KERNEL32.124)
*/
-HANDLE WINAPI FindFirstFileW( LPCWSTR path, WIN32_FIND_DATAW *data )
+HANDLE WINAPI FindFirstFileW( LPCWSTR lpFileName, WIN32_FIND_DATAW *lpFindData )
{
- WIN32_FIND_DATAA dataA;
- LPSTR pathA = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
- HANDLE handle = FindFirstFileA( pathA, &dataA );
- HeapFree( GetProcessHeap(), 0, pathA );
- if (handle != INVALID_HANDLE_VALUE)
- {
- data->dwFileAttributes = dataA.dwFileAttributes;
- data->ftCreationTime = dataA.ftCreationTime;
- data->ftLastAccessTime = dataA.ftLastAccessTime;
- data->ftLastWriteTime = dataA.ftLastWriteTime;
- data->nFileSizeHigh = dataA.nFileSizeHigh;
- data->nFileSizeLow = dataA.nFileSizeLow;
- lstrcpyAtoW( data->cFileName, dataA.cFileName );
- lstrcpyAtoW( data->cAlternateFileName, dataA.cAlternateFileName );
- }
- return handle;
+ return FindFirstFileExW(lpFileName, FindExInfoStandard, lpFindData,
+ FindExSearchNameMatch, NULL, 0);
}
-
/*************************************************************************
- * FindNextFile16 (KERNEL.414)
+ * FindNextFileA (KERNEL32.126)
*/
-BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATAA *data )
+BOOL WINAPI FindNextFileA( HANDLE handle, WIN32_FIND_DATAA *data )
{
FIND_FIRST_INFO *info;
- if (!(info = (FIND_FIRST_INFO *)GlobalLock16( handle )))
+ if ((handle == INVALID_HANDLE_VALUE) ||
+ !(info = (FIND_FIRST_INFO *)GlobalLock( handle )))
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
- GlobalUnlock16( handle );
+ GlobalUnlock( handle );
if (!info->path || !info->dir)
{
SetLastError( ERROR_NO_MORE_FILES );
@@ -1540,15 +1600,6 @@
/*************************************************************************
- * FindNextFileA (KERNEL32.126)
- */
-BOOL WINAPI FindNextFileA( HANDLE handle, WIN32_FIND_DATAA *data )
-{
- return FindNextFile16( handle, data );
-}
-
-
-/*************************************************************************
* FindNextFileW (KERNEL32.127)
*/
BOOL WINAPI FindNextFileW( HANDLE handle, WIN32_FIND_DATAW *data )
@@ -1566,37 +1617,26 @@
return TRUE;
}
-
/*************************************************************************
- * FindClose16 (KERNEL.415)
+ * FindClose (KERNEL32.119)
*/
-BOOL16 WINAPI FindClose16( HANDLE16 handle )
+BOOL WINAPI FindClose( HANDLE handle )
{
FIND_FIRST_INFO *info;
- if ((handle == INVALID_HANDLE_VALUE16) ||
- !(info = (FIND_FIRST_INFO *)GlobalLock16( handle )))
+ if ((handle == INVALID_HANDLE_VALUE) ||
+ !(info = (FIND_FIRST_INFO *)GlobalLock( handle )))
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
if (info->dir) DOSFS_CloseDir( info->dir );
if (info->path) HeapFree( GetProcessHeap(), 0, info->path );
- GlobalUnlock16( handle );
- GlobalFree16( handle );
+ GlobalUnlock( handle );
+ GlobalFree( handle );
return TRUE;
}
-
-/*************************************************************************
- * FindClose (KERNEL32.119)
- */
-BOOL WINAPI FindClose( HANDLE handle )
-{
- return FindClose16( (HANDLE16)handle );
-}
-
-
/***********************************************************************
* DOSFS_UnixTimeToFileTime
*
@@ -2008,3 +2048,96 @@
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
+
+/*
+ --- 16 bit functions ---
+*/
+
+/*************************************************************************
+ * FindFirstFile16 (KERNEL.413)
+ */
+HANDLE16 WINAPI FindFirstFile16( LPCSTR path, WIN32_FIND_DATAA *data )
+{
+ DOS_FULL_NAME full_name;
+ HGLOBAL16 handle;
+ FIND_FIRST_INFO *info;
+
+ data->dwReserved0 = data->dwReserved1 = 0x0;
+ if (!path) return 0;
+ if (!DOSFS_GetFullName( path, FALSE, &full_name ))
+ return INVALID_HANDLE_VALUE16;
+ if (!(handle = GlobalAlloc16( GMEM_MOVEABLE, sizeof(FIND_FIRST_INFO) )))
+ return INVALID_HANDLE_VALUE16;
+ info = (FIND_FIRST_INFO *)GlobalLock16( handle );
+ info->path = HEAP_strdupA( SystemHeap, 0, full_name.long_name );
+ info->long_mask = strrchr( info->path, '/' );
+ if (info->long_mask )
+ *(info->long_mask++) = '\0';
+ info->short_mask = NULL;
+ info->attr = 0xff;
+ if (path[0] && (path[1] == ':')) info->drive = toupper(*path) - 'A';
+ else info->drive = DRIVE_GetCurrentDrive();
+ info->cur_pos = 0;
+
+ info->dir = DOSFS_OpenDir( info->path );
+
+ GlobalUnlock16( handle );
+ if (!FindNextFile16( handle, data ))
+ {
+ FindClose16( handle );
+ SetLastError( ERROR_NO_MORE_FILES );
+ return INVALID_HANDLE_VALUE16;
+ }
+ return handle;
+}
+
+/*************************************************************************
+ * FindNextFile16 (KERNEL.414)
+ */
+BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATAA *data )
+{
+ FIND_FIRST_INFO *info;
+
+ if ((handle == INVALID_HANDLE_VALUE16) ||
+ !(info = (FIND_FIRST_INFO *)GlobalLock16( handle )))
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ return FALSE;
+ }
+ GlobalUnlock16( handle );
+ if (!info->path || !info->dir)
+ {
+ SetLastError( ERROR_NO_MORE_FILES );
+ return FALSE;
+ }
+ if (!DOSFS_FindNextEx( info, data ))
+ {
+ DOSFS_CloseDir( info->dir ); info->dir = NULL;
+ HeapFree( SystemHeap, 0, info->path );
+ info->path = info->long_mask = NULL;
+ SetLastError( ERROR_NO_MORE_FILES );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*************************************************************************
+ * FindClose16 (KERNEL.415)
+ */
+BOOL16 WINAPI FindClose16( HANDLE16 handle )
+{
+ FIND_FIRST_INFO *info;
+
+ if ((handle == INVALID_HANDLE_VALUE16) ||
+ !(info = (FIND_FIRST_INFO *)GlobalLock16( handle )))
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ return FALSE;
+ }
+ if (info->dir) DOSFS_CloseDir( info->dir );
+ if (info->path) HeapFree( SystemHeap, 0, info->path );
+ GlobalUnlock16( handle );
+ GlobalFree16( handle );
+ return TRUE;
+}
+
diff --git a/include/winbase.h b/include/winbase.h
index b61749d..9f8f21a 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -201,6 +201,20 @@
DECL_WINELIB_TYPE_AW(WIN32_FIND_DATA)
DECL_WINELIB_TYPE_AW(LPWIN32_FIND_DATA)
+typedef enum _FINDEX_INFO_LEVELS
+{
+ FindExInfoStandard,
+ FindExInfoMaxInfoLevel
+} FINDEX_INFO_LEVELS;
+
+typedef enum _FINDEX_SEARCH_OPS
+{
+ FindExSearchNameMatch,
+ FindExSearchLimitToDirectories,
+ FindExSearchLimitToDevices,
+ FindExSearchMaxSearchOp
+} FINDEX_SEARCH_OPS;
+
typedef struct
{
LPVOID lpData;
@@ -1492,6 +1506,9 @@
HANDLE WINAPI FindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA);
HANDLE WINAPI FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW);
#define FindFirstFile WINELIB_NAME_AW(FindFirstFile)
+HANDLE WINAPI FindFirstFileExA(LPCSTR,FINDEX_INFO_LEVELS,LPVOID,FINDEX_SEARCH_OPS,LPVOID,DWORD);
+HANDLE WINAPI FindFirstFileExW(LPCWSTR,FINDEX_INFO_LEVELS,LPVOID,FINDEX_SEARCH_OPS,LPVOID,DWORD);
+#define FindFirstFileEx WINELIB_NAME_AW(FindFirstFileEx)
BOOL16 WINAPI FindNextFile16(HANDLE16,LPWIN32_FIND_DATAA);
BOOL WINAPI FindNextFileA(HANDLE,LPWIN32_FIND_DATAA);
BOOL WINAPI FindNextFileW(HANDLE,LPWIN32_FIND_DATAW);
diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec
index 58599cf..44bbfb0 100644
--- a/relay32/kernel32.spec
+++ b/relay32/kernel32.spec
@@ -881,8 +881,8 @@
862 stdcall CreateWaitableTimerW(ptr long wstr) CreateWaitableTimerW
863 stub DeleteFiber
864 stub DuplicateConsoleHandle
-865 stub FindFirstFileExA
-866 stub FindFirstFileExW
+865 stdcall FindFirstFileExA(str long ptr long ptr long)FindFirstFileExA
+866 stdcall FindFirstFileExW(wstr long ptr long ptr long)FindFirstFileExW
867 stub GetConsoleInputExeNameA
868 stub GetConsoleInputExeNameW
869 stub GetConsoleKeyboardLayoutNameA
@@ -927,4 +927,3 @@
#1599 wrong ordinal (249 in Win32s's W32SCOMB.DLL) !
1599 stdcall Get16DLLAddress(long str) Get16DLLAddress
-