diff --git a/files/dos_fs.c b/files/dos_fs.c index 3d45991aec9..5570241fd79 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -1434,94 +1434,154 @@ int DOSFS_FindNext( const char *path, const char *short_mask, 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 ); @@ -1539,15 +1599,6 @@ BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATAA *data ) } -/************************************************************************* - * FindNextFileA (KERNEL32.126) - */ -BOOL WINAPI FindNextFileA( HANDLE handle, WIN32_FIND_DATAA *data ) -{ - return FindNextFile16( handle, data ); -} - - /************************************************************************* * FindNextFileW (KERNEL32.127) */ @@ -1566,37 +1617,26 @@ BOOL WINAPI FindNextFileW( HANDLE handle, WIN32_FIND_DATAW *data ) 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 @@ BOOL WINAPI DefineDosDeviceA(DWORD flags,LPCSTR devname,LPCSTR targetpath) { 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 b61749dadd1..9f8f21ad50e 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -201,6 +201,20 @@ typedef struct 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 @@ HANDLE16 WINAPI FindFirstFile16(LPCSTR,LPWIN32_FIND_DATAA); 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 58599cf7877..44bbfb0a670 100644 --- a/relay32/kernel32.spec +++ b/relay32/kernel32.spec @@ -881,8 +881,8 @@ import ntdll.dll 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 @@ import ntdll.dll #1599 wrong ordinal (249 in Win32s's W32SCOMB.DLL) ! 1599 stdcall Get16DLLAddress(long str) Get16DLLAddress -