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