[PATCH 15/26] [DbgHelp]: implemented SymFindFileInPathW

Eric Pouech eric.pouech at wanadoo.fr
Wed Feb 21 14:55:46 CST 2007




A+
---

 dlls/dbghelp/dbghelp.spec |    2 -
 dlls/dbghelp/msc.c        |    2 -
 dlls/dbghelp/path.c       |  153 ++++++++++++++++++++++-----------------------
 include/dbghelp.h         |    5 +
 4 files changed, 80 insertions(+), 82 deletions(-)

diff --git a/dlls/dbghelp/dbghelp.spec b/dlls/dbghelp/dbghelp.spec
index 7c0433b..ffb51bb 100644
--- a/dlls/dbghelp/dbghelp.spec
+++ b/dlls/dbghelp/dbghelp.spec
@@ -54,7 +54,7 @@
 @ stub SymFindDebugInfoFile
 @ stub SymFindDebugInfoFileW
 @ stdcall SymFindFileInPath(long str str ptr long long long ptr ptr ptr)
-@ stub SymFindFileInPathW
+@ stdcall SymFindFileInPathW(long wstr wstr ptr long long long ptr ptr ptr)
 @ stdcall SymFromAddr(ptr double ptr ptr)
 @ stdcall SymFromAddrW(ptr double ptr ptr)
 @ stub SymFromIndex
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 5b54561..87c57b6 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -1856,7 +1856,7 @@ static void pdb_convert_symbol_file(cons
     }
 }
 
-static BOOL CALLBACK pdb_match(char* file, void* user)
+static BOOL CALLBACK pdb_match(const char* file, void* user)
 {
     /* accept first file that exists */
     HANDLE h = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
diff --git a/dlls/dbghelp/path.c b/dlls/dbghelp/path.c
index 5fccc7b..d051feb 100644
--- a/dlls/dbghelp/path.c
+++ b/dlls/dbghelp/path.c
@@ -42,6 +42,14 @@ static inline const char* file_name(cons
     return p + 1;
 }
 
+static inline const WCHAR* file_nameW(const WCHAR* str)
+{
+    const WCHAR*      p;
+
+    for (p = str + strlenW(str) - 1; p >= str && !is_sepW(*p); p--);
+    return p + 1;
+}
+
 /******************************************************************
  *		FindDebugInfoFile (DBGHELP.@)
  *
@@ -238,40 +246,6 @@ static BOOL do_searchW(const WCHAR* file
     return found;
 }
 
-static BOOL do_search(const char* file, char* buffer, BOOL recurse,
-                      PENUMDIRTREE_CALLBACK cb, void* user)
-{
-    HANDLE              h;
-    WIN32_FIND_DATAA    fd;
-    unsigned            pos;
-    BOOL                found = FALSE;
-
-    pos = strlen(buffer);
-    if (buffer[pos - 1] != '\\') buffer[pos++] = '\\';
-    strcpy(buffer + pos, "*.*");
-    if ((h = FindFirstFileA(buffer, &fd)) == INVALID_HANDLE_VALUE)
-        return FALSE;
-    /* doc doesn't specify how the tree is enumerated... 
-     * doing a depth first based on, but may be wrong
-     */
-    do
-    {
-        if (!strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, "..")) continue;
-
-        strcpy(buffer + pos, fd.cFileName);
-        if (recurse && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
-            found = do_search(file, buffer, TRUE, cb, user);
-        else if (SymMatchFileName(buffer, (char*)file, NULL, NULL))
-        {
-            if (!cb || cb(buffer, user)) found = TRUE;
-        }
-    } while (!found && FindNextFileA(h, &fd));
-    if (!found) buffer[--pos] = '\0';
-    FindClose(h);
-
-    return found;
-}
-
 /***********************************************************************
  *           SearchTreeForFileW (DBGHELP.@)
  */
@@ -368,7 +342,7 @@ struct sffip
     DWORD                       two;
     DWORD                       three;
     DWORD                       flags;
-    PFINDFILEINPATHCALLBACK     cb;
+    PFINDFILEINPATHCALLBACKW    cb;
     void*                       user;
 };
 
@@ -377,7 +351,7 @@ struct sffip
  * returns TRUE when file is found, FALSE to continue searching
  * (NB this is the opposite conventions as for SymFindFileInPathProc)
  */
-static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
+static BOOL CALLBACK sffip_cb(LPCWSTR buffer, void* user)
 {
     struct sffip*       s = (struct sffip*)user;
     DWORD               size, checksum;
@@ -395,10 +369,10 @@ static BOOL CALLBACK sffip_cb(LPCSTR buf
 
             timestamp = ~(DWORD_PTR)s->id;
             size = ~s->two;
-            hFile = CreateFileA(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, 
+            hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, 
                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
             if (hFile == INVALID_HANDLE_VALUE) return FALSE;
-            if ((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
+            if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
             {
                 if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
                 {
@@ -412,7 +386,7 @@ static BOOL CALLBACK sffip_cb(LPCSTR buf
             CloseHandle(hFile);
             if (timestamp != (DWORD_PTR)s->id || size != s->two)
             {
-                WARN("Found %s, but wrong size or timestamp\n", buffer);
+                WARN("Found %s, but wrong size or timestamp\n", debugstr_w(buffer));
                 return FALSE;
             }
         }
@@ -423,21 +397,23 @@ static BOOL CALLBACK sffip_cb(LPCSTR buf
             if (checksum != (DWORD_PTR)s->id)
             {
                 WARN("Found %s, but wrong checksums: %08x %08lx\n",
-                      buffer, checksum, (DWORD_PTR)s->id);
+                     debugstr_w(buffer), checksum, (DWORD_PTR)s->id);
                 return FALSE;
             }
         }
         else
         {
-            WARN("Couldn't read %s\n", buffer);
+            WARN("Couldn't read %s\n", debugstr_w(buffer));
             return FALSE;
         }
         break;
     case DMT_PDB:
         {
             struct pdb_lookup   pdb_lookup;
+            char                fn[MAX_PATH];
 
-            pdb_lookup.filename = buffer;
+            WideCharToMultiByte(CP_ACP, 0, buffer, -1, fn, MAX_PATH, NULL, NULL);
+            pdb_lookup.filename = fn;
 
             if (!pdb_fetch_file_info(&pdb_lookup)) return FALSE;
             switch (pdb_lookup.kind)
@@ -445,26 +421,26 @@ static BOOL CALLBACK sffip_cb(LPCSTR buf
             case PDB_JG:
                 if (s->flags & SSRVOPT_GUIDPTR)
                 {
-                    WARN("Found %s, but wrong PDB version\n", buffer);
+                    WARN("Found %s, but wrong PDB version\n", debugstr_w(buffer));
                     return FALSE;
                 }
                 if (pdb_lookup.u.jg.timestamp != (DWORD_PTR)s->id)
                 {
                     WARN("Found %s, but wrong signature: %08x %08lx\n",
-                         buffer, pdb_lookup.u.jg.timestamp, (DWORD_PTR)s->id);
+                         debugstr_w(buffer), pdb_lookup.u.jg.timestamp, (DWORD_PTR)s->id);
                     return FALSE;
                 }
                 break;
             case PDB_DS:
                 if (!(s->flags & SSRVOPT_GUIDPTR))
                 {
-                    WARN("Found %s, but wrong PDB version\n", buffer);
+                    WARN("Found %s, but wrong PDB version\n", debugstr_w(buffer));
                     return FALSE;
                 }
                 if (memcmp(&pdb_lookup.u.ds.guid, (GUID*)s->id, sizeof(GUID)))
                 {
                     WARN("Found %s, but wrong GUID: %s %s\n",
-                         buffer, debugstr_guid(&pdb_lookup.u.ds.guid),
+                         debugstr_w(buffer), debugstr_guid(&pdb_lookup.u.ds.guid),
                          debugstr_guid((GUID*)s->id));
                     return FALSE;
                 }
@@ -473,7 +449,7 @@ static BOOL CALLBACK sffip_cb(LPCSTR buf
             if (pdb_lookup.age != s->two)
             {
                 WARN("Found %s, but wrong age: %08x %08x\n",
-                     buffer, pdb_lookup.age, s->two);
+                     debugstr_w(buffer), pdb_lookup.age, s->two);
                 return FALSE;
             }
         }
@@ -485,39 +461,30 @@ static BOOL CALLBACK sffip_cb(LPCSTR buf
     /* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
      * convention to stop/continue enumeration. sigh.
      */
-    return !(s->cb)((char*)buffer, s->user);
+    return !(s->cb)((WCHAR*)buffer, s->user);
 }
 
 /******************************************************************
- *		SymFindFileInPath (DBGHELP.@)
+ *		SymFindFileInPathW (DBGHELP.@)
  *
  */
-BOOL WINAPI SymFindFileInPath(HANDLE hProcess, PCSTR inSearchPath, PCSTR full_path,
-                              PVOID id, DWORD two, DWORD three, DWORD flags,
-                              LPSTR buffer, PFINDFILEINPATHCALLBACK cb,
-                              PVOID user)
+BOOL WINAPI SymFindFileInPathW(HANDLE hProcess, PCWSTR searchPath, PCWSTR full_path,
+                               PVOID id, DWORD two, DWORD three, DWORD flags,
+                               LPWSTR buffer, PFINDFILEINPATHCALLBACKW cb,
+                               PVOID user)
 {
     struct sffip        s;
     struct process*     pcs = process_find_by_handle(hProcess);
-    char                tmp[MAX_PATH];
-    char*               ptr;
-    char*               buf = NULL;
-    const char*         filename;
-    const char*         searchPath = inSearchPath;
+    WCHAR               tmp[MAX_PATH];
+    WCHAR*              ptr;
+    const WCHAR*        filename;
 
     TRACE("(%p %s %s %p %08x %08x %08x %p %p %p)\n",
-          hProcess, searchPath, full_path, id, two, three, flags,
-          buffer, cb, user);
+          hProcess, debugstr_w(searchPath), debugstr_w(full_path),
+          id, two, three, flags, buffer, cb, user);
 
     if (!pcs) return FALSE;
-    if (!searchPath)
-    {
-        unsigned len = WideCharToMultiByte(CP_ACP, 0, pcs->search_path, -1, NULL, 0, NULL, NULL);
-
-        searchPath = buf = HeapAlloc(GetProcessHeap(), 0, len);
-        if (!searchPath) return FALSE;
-        WideCharToMultiByte(CP_ACP, 0, pcs->search_path, -1, buf, len, NULL, NULL);
-    }
+    if (!searchPath) searchPath = pcs->search_path;
 
     s.id = id;
     s.two = two;
@@ -526,38 +493,66 @@ BOOL WINAPI SymFindFileInPath(HANDLE hPr
     s.cb = cb;
     s.user = user;
 
-    filename = file_name(full_path);
-    s.kind = module_get_type_by_nameA(filename);
+    filename = file_nameW(full_path);
+    s.kind = module_get_type_by_name(filename);
 
     /* first check full path to file */
     if (sffip_cb(full_path, &s))
     {
-        strcpy(buffer, full_path);
-        HeapFree(GetProcessHeap(), 0, buf);
+        strcpyW(buffer, full_path);
         return TRUE;
     }
 
     while (searchPath)
     {
-        ptr = strchr(searchPath, ';');
+        ptr = strchrW(searchPath, ';');
         if (ptr)
         {
-            memcpy(tmp, searchPath, ptr - searchPath);
+            memcpy(tmp, searchPath, (ptr - searchPath) * sizeof(WCHAR));
             tmp[ptr - searchPath] = 0;
             searchPath = ptr + 1;
         }
         else
         {
-            strcpy(tmp, searchPath);
+            strcpyW(tmp, searchPath);
             searchPath = NULL;
         }
-        if (do_search(filename, tmp, FALSE, sffip_cb, &s))
+        if (do_searchW(filename, tmp, FALSE, sffip_cb, &s))
         {
-            strcpy(buffer, tmp);
-            HeapFree(GetProcessHeap(), 0, buf);
+            strcpyW(buffer, tmp);
             return TRUE;
         }
     }
-    HeapFree(GetProcessHeap(), 0, buf);
     return FALSE;
 }
+
+/******************************************************************
+ *		SymFindFileInPath (DBGHELP.@)
+ *
+ */
+BOOL WINAPI SymFindFileInPath(HANDLE hProcess, PCSTR searchPath, PCSTR full_path,
+                              PVOID id, DWORD two, DWORD three, DWORD flags,
+                              LPSTR buffer, PFINDFILEINPATHCALLBACK cb,
+                              PVOID user)
+{
+    WCHAR                       searchPathW[MAX_PATH];
+    WCHAR                       full_pathW[MAX_PATH];
+    WCHAR                       bufferW[MAX_PATH];
+    struct enum_dir_treeWA      edt;
+    BOOL                        ret;
+
+    /* a PFINDFILEINPATHCALLBACK and a PENUMDIRTREE_CALLBACK have actually the
+     * same signature & semantics, hence we can reuse the EnumDirTree W->A
+     * conversion helper
+     */
+    edt.cb = cb;
+    edt.user = user;
+    if (searchPath)
+        MultiByteToWideChar(CP_ACP, 0, searchPath, -1, searchPathW, MAX_PATH);
+    MultiByteToWideChar(CP_ACP, 0, full_path, -1, full_pathW, MAX_PATH);
+    if ((ret =  SymFindFileInPathW(hProcess, searchPath ? searchPathW : NULL, full_pathW,
+                                   id, two, three, flags,
+                                   bufferW, enum_dir_treeWA, &edt)))
+        WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
+    return ret;
+}
diff --git a/include/dbghelp.h b/include/dbghelp.h
index 2752f47..b777224 100644
--- a/include/dbghelp.h
+++ b/include/dbghelp.h
@@ -999,9 +999,12 @@ BOOL WINAPI SymCleanup(HANDLE);
 HANDLE WINAPI FindDebugInfoFile(PCSTR, PCSTR, PSTR);
 typedef BOOL (CALLBACK *PFIND_DEBUG_FILE_CALLBACK)(HANDLE, PSTR, PVOID);
 HANDLE WINAPI FindDebugInfoFileEx(PCSTR, PCSTR, PSTR, PFIND_DEBUG_FILE_CALLBACK, PVOID);
-typedef BOOL (CALLBACK *PFINDFILEINPATHCALLBACK)(PSTR, PVOID);
+typedef BOOL (CALLBACK *PFINDFILEINPATHCALLBACK)(PCSTR, PVOID);
 BOOL WINAPI SymFindFileInPath(HANDLE, PCSTR, PCSTR, PVOID, DWORD, DWORD, DWORD,
                               PSTR, PFINDFILEINPATHCALLBACK, PVOID);
+typedef BOOL (CALLBACK *PFINDFILEINPATHCALLBACKW)(PCWSTR, PVOID);
+BOOL WINAPI SymFindFileInPathW(HANDLE, PCWSTR, PCWSTR, PVOID, DWORD, DWORD, DWORD,
+                              PWSTR, PFINDFILEINPATHCALLBACKW, PVOID);
 HANDLE WINAPI FindExecutableImage(PCSTR, PCSTR, PSTR);
 typedef BOOL (CALLBACK *PFIND_EXE_FILE_CALLBACK)(HANDLE, PSTR, PVOID);
 HANDLE WINAPI FindExecutableImageEx(PCSTR, PCSTR, PSTR, PFIND_EXE_FILE_CALLBACK, PVOID);



More information about the wine-patches mailing list