Alexandre Julliard : shell32:
Grow the file list dynamically in SHFileOperation.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Mar 6 12:54:55 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 1110d62752947c82723d1eb252be8e49cac3dfb0
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=1110d62752947c82723d1eb252be8e49cac3dfb0
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Mar 6 17:47:57 2006 +0100
shell32: Grow the file list dynamically in SHFileOperation.
This avoids searching the same directories twice, once to count the
files and then once for real.
---
dlls/shell32/shlfileop.c | 73 +++++++++++-----------------------------------
1 files changed, 18 insertions(+), 55 deletions(-)
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c
index 19cf225..4f2a799 100644
--- a/dlls/shell32/shlfileop.c
+++ b/dlls/shell32/shlfileop.c
@@ -760,53 +760,20 @@ typedef struct
typedef struct
{
FILE_ENTRY *feFiles;
+ DWORD num_alloc;
DWORD dwNumFiles;
BOOL bAnyFromWildcard;
BOOL bAnyDirectories;
BOOL bAnyDontExist;
} FILE_LIST;
-/* count the number of expanded files from a given wildcard */
-static DWORD count_wildcard_files(LPCWSTR szWildFile)
-{
- WIN32_FIND_DATAW wfd;
- HANDLE hFile = FindFirstFileW(szWildFile, &wfd);
- BOOL res = TRUE;
- DWORD dwCount = 0;
-
- if (hFile == INVALID_HANDLE_VALUE)
- return 0;
-
- while (res)
- {
- if (!IsDotDir(wfd.cFileName)) dwCount++;
- res = FindNextFileW(hFile, &wfd);
- }
- FindClose(hFile);
- return dwCount;
-}
-
-/* counts the number of files in a file list including expanded wildcard files */
-static DWORD count_files(LPCWSTR szFileList)
+static inline void grow_list(FILE_LIST *list)
{
- DWORD dwCount = 0;
- LPCWSTR str = szFileList;
-
- /* test empty list */
- if (!szFileList[0]) return -1;
-
- while (*str)
- {
- if (StrPBrkW(str, wWildcardChars))
- dwCount += count_wildcard_files(str);
- else
- dwCount++;
-
- str += lstrlenW(str) + 1;
- }
-
- return dwCount;
+ FILE_ENTRY *new = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, list->feFiles,
+ list->num_alloc * 2 * sizeof(*new) );
+ list->feFiles = new;
+ list->num_alloc *= 2;
}
/* adds a file to the FILE_ENTRY struct
@@ -861,6 +828,7 @@ static void parse_wildcard_files(FILE_LI
for (res = TRUE; res; res = FindNextFileW(hFile, &wfd))
{
if (IsDotDir(wfd.cFileName)) continue;
+ if (*pdwListIndex >= flList->num_alloc) grow_list( flList );
szFullPath = wildcard_to_file(szFile, wfd.cFileName);
file = &flList->feFiles[(*pdwListIndex)++];
add_file_to_entry(file, szFullPath);
@@ -878,7 +846,7 @@ static HRESULT parse_file_list(FILE_LIST
{
LPCWSTR ptr = szFiles;
WCHAR szCurFile[MAX_PATH];
- DWORD i, dwDirLen;
+ DWORD i = 0, dwDirLen;
if (!szFiles)
return ERROR_INVALID_PARAMETER;
@@ -886,19 +854,19 @@ static HRESULT parse_file_list(FILE_LIST
flList->bAnyFromWildcard = FALSE;
flList->bAnyDirectories = FALSE;
flList->bAnyDontExist = FALSE;
- flList->dwNumFiles = count_files(szFiles);
+ flList->num_alloc = 32;
+ flList->dwNumFiles = 0;
/* empty list */
- if (flList->dwNumFiles == -1)
+ if (!szFiles[0])
return ERROR_ACCESS_DENIED;
flList->feFiles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- flList->dwNumFiles * sizeof(FILE_ENTRY));
+ flList->num_alloc * sizeof(FILE_ENTRY));
- for (i = 0; i < flList->dwNumFiles; i++)
+ while (*ptr)
{
- if (!*ptr)
- return ERROR_ACCESS_DENIED;
+ if (i >= flList->num_alloc) grow_list( flList );
/* change relative to absolute path */
if (PathIsRelativeW(ptr))
@@ -925,21 +893,16 @@ static HRESULT parse_file_list(FILE_LIST
FILE_ENTRY *file = &flList->feFiles[i];
add_file_to_entry(file, szCurFile);
file->attributes = GetFileAttributesW( file->szFullPath );
+ file->bExists = (file->attributes != INVALID_FILE_ATTRIBUTES);
+ if (!file->bExists) flList->bAnyDontExist = TRUE;
if (IsAttribDir(file->attributes)) flList->bAnyDirectories = TRUE;
}
- /* record whether the file exists */
- if (!PathFileExistsW(flList->feFiles[i].szFullPath))
- {
- flList->feFiles[i].bExists = FALSE;
- flList->bAnyDontExist = TRUE;
- }
- else
- flList->feFiles[i].bExists = TRUE;
-
/* advance to the next string */
ptr += strlenW(ptr) + 1;
+ i++;
}
+ flList->dwNumFiles = i;
return S_OK;
}
More information about the wine-cvs
mailing list