ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

path.c
Go to the documentation of this file.
00001 /*
00002  * File path.c - managing path in debugging environments
00003  *
00004  * Copyright (C) 2004,2008, Eric Pouech
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "config.h"
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 
00026 #include "dbghelp_private.h"
00027 #include "winnls.h"
00028 #include "winternl.h"
00029 #include "wine/debug.h"
00030 
00031 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
00032 
00033 static inline BOOL is_sep(char ch) {return ch == '/' || ch == '\\';}
00034 static inline BOOL is_sepW(WCHAR ch) {return ch == '/' || ch == '\\';}
00035 
00036 static inline const char* file_name(const char* str)
00037 {
00038     const char*       p;
00039 
00040     for (p = str + strlen(str) - 1; p >= str && !is_sep(*p); p--);
00041     return p + 1;
00042 }
00043 
00044 static inline const WCHAR* file_nameW(const WCHAR* str)
00045 {
00046     const WCHAR*      p;
00047 
00048     for (p = str + strlenW(str) - 1; p >= str && !is_sepW(*p); p--);
00049     return p + 1;
00050 }
00051 
00052 /******************************************************************
00053  *      FindDebugInfoFile (DBGHELP.@)
00054  *
00055  */
00056 HANDLE WINAPI FindDebugInfoFile(PCSTR FileName, PCSTR SymbolPath, PSTR DebugFilePath)
00057 {
00058     HANDLE      h;
00059 
00060     h = CreateFileA(FileName, GENERIC_READ, FILE_SHARE_READ, NULL,
00061                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00062     if (h == INVALID_HANDLE_VALUE)
00063     {
00064         if (!SearchPathA(SymbolPath, file_name(FileName), NULL, MAX_PATH, DebugFilePath, NULL))
00065             return NULL;
00066         h = CreateFileA(DebugFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
00067                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00068     }
00069     return (h == INVALID_HANDLE_VALUE) ? NULL : h;
00070 }
00071  
00072 /******************************************************************
00073  *      FindDebugInfoFileEx (DBGHELP.@)
00074  *
00075  */
00076 HANDLE WINAPI FindDebugInfoFileEx(PCSTR FileName, PCSTR SymbolPath,
00077                                   PSTR DebugFilePath, 
00078                                   PFIND_DEBUG_FILE_CALLBACK Callback,
00079                                   PVOID CallerData)
00080 {
00081     FIXME("(%s %s %p %p %p): stub\n", 
00082           debugstr_a(FileName), debugstr_a(SymbolPath), debugstr_a(DebugFilePath), Callback, CallerData);
00083     return NULL;
00084 }
00085 
00086 /******************************************************************
00087  *      FindExecutableImageExW (DBGHELP.@)
00088  *
00089  */
00090 HANDLE WINAPI FindExecutableImageExW(PCWSTR FileName, PCWSTR SymbolPath, PWSTR ImageFilePath,
00091                                      PFIND_EXE_FILE_CALLBACKW Callback, PVOID user)
00092 {
00093     HANDLE h;
00094 
00095     if (Callback) FIXME("Unsupported callback yet\n");
00096     if (!SearchPathW(SymbolPath, FileName, NULL, MAX_PATH, ImageFilePath, NULL))
00097         return NULL;
00098     h = CreateFileW(ImageFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
00099                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00100     return (h == INVALID_HANDLE_VALUE) ? NULL : h;
00101 }
00102 
00103 /******************************************************************
00104  *      FindExecutableImageEx (DBGHELP.@)
00105  *
00106  */
00107 HANDLE WINAPI FindExecutableImageEx(PCSTR FileName, PCSTR SymbolPath, PSTR ImageFilePath,
00108                                     PFIND_EXE_FILE_CALLBACK Callback, PVOID user)
00109 {
00110     HANDLE h;
00111 
00112     if (Callback) FIXME("Unsupported callback yet\n");
00113     if (!SearchPathA(SymbolPath, FileName, NULL, MAX_PATH, ImageFilePath, NULL))
00114         return NULL;
00115     h = CreateFileA(ImageFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
00116                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00117     return (h == INVALID_HANDLE_VALUE) ? NULL : h;
00118 }
00119 
00120 /******************************************************************
00121  *      FindExecutableImage (DBGHELP.@)
00122  *
00123  */
00124 HANDLE WINAPI FindExecutableImage(PCSTR FileName, PCSTR SymbolPath, PSTR ImageFilePath)
00125 {
00126     return FindExecutableImageEx(FileName, SymbolPath, ImageFilePath, NULL, NULL);
00127 }
00128 
00129 /***********************************************************************
00130  *           MakeSureDirectoryPathExists (DBGHELP.@)
00131  */
00132 BOOL WINAPI MakeSureDirectoryPathExists(PCSTR DirPath)
00133 {
00134     char path[MAX_PATH];
00135     const char *p = DirPath;
00136     int  n;
00137 
00138     if (p[0] && p[1] == ':') p += 2;
00139     while (*p == '\\') p++; /* skip drive root */
00140     while ((p = strchr(p, '\\')) != NULL)
00141     {
00142        n = p - DirPath + 1;
00143        memcpy(path, DirPath, n);
00144        path[n] = '\0';
00145        if( !CreateDirectoryA(path, NULL)            &&
00146            (GetLastError() != ERROR_ALREADY_EXISTS))
00147            return FALSE;
00148        p++;
00149     }
00150     if (GetLastError() == ERROR_ALREADY_EXISTS)
00151        SetLastError(ERROR_SUCCESS);
00152 
00153     return TRUE;
00154 }
00155 
00156 /******************************************************************
00157  *      SymMatchFileNameW (DBGHELP.@)
00158  *
00159  */
00160 BOOL WINAPI SymMatchFileNameW(PCWSTR file, PCWSTR match,
00161                               PWSTR* filestop, PWSTR* matchstop)
00162 {
00163     PCWSTR fptr;
00164     PCWSTR mptr;
00165 
00166     TRACE("(%s %s %p %p)\n",
00167           debugstr_w(file), debugstr_w(match), filestop, matchstop);
00168 
00169     fptr = file + strlenW(file) - 1;
00170     mptr = match + strlenW(match) - 1;
00171 
00172     while (fptr >= file && mptr >= match)
00173     {
00174         if (toupperW(*fptr) != toupperW(*mptr) && !(is_sepW(*fptr) && is_sepW(*mptr)))
00175             break;
00176         fptr--; mptr--;
00177     }
00178     if (filestop) *filestop = (PWSTR)fptr;
00179     if (matchstop) *matchstop = (PWSTR)mptr;
00180 
00181     return mptr == match - 1;
00182 }
00183 
00184 /******************************************************************
00185  *      SymMatchFileName (DBGHELP.@)
00186  *
00187  */
00188 BOOL WINAPI SymMatchFileName(PCSTR file, PCSTR match,
00189                              PSTR* filestop, PSTR* matchstop)
00190 {
00191     PCSTR fptr;
00192     PCSTR mptr;
00193 
00194     TRACE("(%s %s %p %p)\n", debugstr_a(file), debugstr_a(match), filestop, matchstop);
00195 
00196     fptr = file + strlen(file) - 1;
00197     mptr = match + strlen(match) - 1;
00198 
00199     while (fptr >= file && mptr >= match)
00200     {
00201         if (toupper(*fptr) != toupper(*mptr) && !(is_sep(*fptr) && is_sep(*mptr)))
00202             break;
00203         fptr--; mptr--;
00204     }
00205     if (filestop) *filestop = (PSTR)fptr;
00206     if (matchstop) *matchstop = (PSTR)mptr;
00207 
00208     return mptr == match - 1;
00209 }
00210 
00211 static BOOL do_searchW(PCWSTR file, PWSTR buffer, BOOL recurse,
00212                        PENUMDIRTREE_CALLBACKW cb, PVOID user)
00213 {
00214     HANDLE              h;
00215     WIN32_FIND_DATAW    fd;
00216     unsigned            pos;
00217     BOOL                found = FALSE;
00218     static const WCHAR  S_AllW[] = {'*','.','*','\0'};
00219     static const WCHAR  S_DotW[] = {'.','\0'};
00220     static const WCHAR  S_DotDotW[] = {'.','.','\0'};
00221 
00222     pos = strlenW(buffer);
00223     if (buffer[pos - 1] != '\\') buffer[pos++] = '\\';
00224     strcpyW(buffer + pos, S_AllW);
00225     if ((h = FindFirstFileW(buffer, &fd)) == INVALID_HANDLE_VALUE)
00226         return FALSE;
00227     /* doc doesn't specify how the tree is enumerated...
00228      * doing a depth first based on, but may be wrong
00229      */
00230     do
00231     {
00232         if (!strcmpW(fd.cFileName, S_DotW) || !strcmpW(fd.cFileName, S_DotDotW)) continue;
00233 
00234         strcpyW(buffer + pos, fd.cFileName);
00235         if (recurse && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
00236             found = do_searchW(file, buffer, TRUE, cb, user);
00237         else if (SymMatchFileNameW(buffer, file, NULL, NULL))
00238         {
00239             if (!cb || cb(buffer, user)) found = TRUE;
00240         }
00241     } while (!found && FindNextFileW(h, &fd));
00242     if (!found) buffer[--pos] = '\0';
00243     FindClose(h);
00244 
00245     return found;
00246 }
00247 
00248 /***********************************************************************
00249  *           SearchTreeForFileW (DBGHELP.@)
00250  */
00251 BOOL WINAPI SearchTreeForFileW(PCWSTR root, PCWSTR file, PWSTR buffer)
00252 {
00253     TRACE("(%s, %s, %p)\n",
00254           debugstr_w(root), debugstr_w(file), buffer);
00255     strcpyW(buffer, root);
00256     return do_searchW(file, buffer, TRUE, NULL, NULL);
00257 }
00258 
00259 /***********************************************************************
00260  *           SearchTreeForFile (DBGHELP.@)
00261  */
00262 BOOL WINAPI SearchTreeForFile(PCSTR root, PCSTR file, PSTR buffer)
00263 {
00264     WCHAR       rootW[MAX_PATH];
00265     WCHAR       fileW[MAX_PATH];
00266     WCHAR       bufferW[MAX_PATH];
00267     BOOL        ret;
00268 
00269     MultiByteToWideChar(CP_ACP, 0, root, -1, rootW, MAX_PATH);
00270     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
00271     ret = SearchTreeForFileW(rootW, fileW, bufferW);
00272     if (ret)
00273         WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
00274     return ret;
00275 }
00276 
00277 /******************************************************************
00278  *      EnumDirTreeW (DBGHELP.@)
00279  *
00280  *
00281  */
00282 BOOL WINAPI EnumDirTreeW(HANDLE hProcess, PCWSTR root, PCWSTR file,
00283                         PWSTR buffer, PENUMDIRTREE_CALLBACKW cb, PVOID user)
00284 {
00285     TRACE("(%p %s %s %p %p %p)\n",
00286           hProcess, debugstr_w(root), debugstr_w(file), buffer, cb, user);
00287 
00288     strcpyW(buffer, root);
00289     return do_searchW(file, buffer, TRUE, cb, user);
00290 }
00291 
00292 /******************************************************************
00293  *      EnumDirTree (DBGHELP.@)
00294  *
00295  *
00296  */
00297 struct enum_dir_treeWA
00298 {
00299     PENUMDIRTREE_CALLBACK       cb;
00300     void*                       user;
00301     char                        name[MAX_PATH];
00302 };
00303 
00304 static BOOL CALLBACK enum_dir_treeWA(PCWSTR name, PVOID user)
00305 {
00306     struct enum_dir_treeWA*     edt = user;
00307 
00308     WideCharToMultiByte(CP_ACP, 0, name, -1, edt->name, MAX_PATH, NULL, NULL);
00309     return edt->cb(edt->name, edt->user);
00310 }
00311 
00312 BOOL WINAPI EnumDirTree(HANDLE hProcess, PCSTR root, PCSTR file,
00313                         PSTR buffer, PENUMDIRTREE_CALLBACK cb, PVOID user)
00314 {
00315     WCHAR                       rootW[MAX_PATH];
00316     WCHAR                       fileW[MAX_PATH];
00317     WCHAR                       bufferW[MAX_PATH];
00318     struct enum_dir_treeWA      edt;
00319     BOOL                        ret;
00320 
00321     edt.cb = cb;
00322     edt.user = user;
00323     MultiByteToWideChar(CP_ACP, 0, root, -1, rootW, MAX_PATH);
00324     MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
00325     if ((ret = EnumDirTreeW(hProcess, rootW, fileW, bufferW, enum_dir_treeWA, &edt)))
00326         WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
00327     return ret;
00328 }
00329 
00330 struct sffip
00331 {
00332     PFINDFILEINPATHCALLBACKW    cb;
00333     void*                       user;
00334 };
00335 
00336 /* checks that buffer (as found by matching the name) matches the info
00337  * (information is based on file type)
00338  * returns TRUE when file is found, FALSE to continue searching
00339  * (NB this is the opposite convention of SymFindFileInPathProc)
00340  */
00341 static BOOL CALLBACK sffip_cb(PCWSTR buffer, PVOID user)
00342 {
00343     struct sffip*       s = user;
00344 
00345     if (!s->cb) return TRUE;
00346     /* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
00347      * convention to stop/continue enumeration. sigh.
00348      */
00349     return !(s->cb)(buffer, s->user);
00350 }
00351 
00352 /******************************************************************
00353  *      SymFindFileInPathW (DBGHELP.@)
00354  *
00355  */
00356 BOOL WINAPI SymFindFileInPathW(HANDLE hProcess, PCWSTR searchPath, PCWSTR full_path,
00357                                PVOID id, DWORD two, DWORD three, DWORD flags,
00358                                PWSTR buffer, PFINDFILEINPATHCALLBACKW cb,
00359                                PVOID user)
00360 {
00361     struct sffip        s;
00362     struct process*     pcs = process_find_by_handle(hProcess);
00363     WCHAR               tmp[MAX_PATH];
00364     WCHAR*              ptr;
00365     const WCHAR*        filename;
00366 
00367     TRACE("(hProcess = %p, searchPath = %s, full_path = %s, id = %p, two = 0x%08x, three = 0x%08x, flags = 0x%08x, buffer = %p, cb = %p, user = %p)\n",
00368           hProcess, debugstr_w(searchPath), debugstr_w(full_path),
00369           id, two, three, flags, buffer, cb, user);
00370 
00371     if (!pcs) return FALSE;
00372     if (!searchPath) searchPath = pcs->search_path;
00373 
00374     s.cb = cb;
00375     s.user = user;
00376 
00377     filename = file_nameW(full_path);
00378 
00379     /* first check full path to file */
00380     if (sffip_cb(full_path, &s))
00381     {
00382         strcpyW(buffer, full_path);
00383         return TRUE;
00384     }
00385 
00386     while (searchPath)
00387     {
00388         ptr = strchrW(searchPath, ';');
00389         if (ptr)
00390         {
00391             memcpy(tmp, searchPath, (ptr - searchPath) * sizeof(WCHAR));
00392             tmp[ptr - searchPath] = 0;
00393             searchPath = ptr + 1;
00394         }
00395         else
00396         {
00397             strcpyW(tmp, searchPath);
00398             searchPath = NULL;
00399         }
00400         if (do_searchW(filename, tmp, FALSE, sffip_cb, &s))
00401         {
00402             strcpyW(buffer, tmp);
00403             return TRUE;
00404         }
00405     }
00406     return FALSE;
00407 }
00408 
00409 /******************************************************************
00410  *      SymFindFileInPath (DBGHELP.@)
00411  *
00412  */
00413 BOOL WINAPI SymFindFileInPath(HANDLE hProcess, PCSTR searchPath, PCSTR full_path,
00414                               PVOID id, DWORD two, DWORD three, DWORD flags,
00415                               PSTR buffer, PFINDFILEINPATHCALLBACK cb,
00416                               PVOID user)
00417 {
00418     WCHAR                       searchPathW[MAX_PATH];
00419     WCHAR                       full_pathW[MAX_PATH];
00420     WCHAR                       bufferW[MAX_PATH];
00421     struct enum_dir_treeWA      edt;
00422     BOOL                        ret;
00423 
00424     /* a PFINDFILEINPATHCALLBACK and a PENUMDIRTREE_CALLBACK have actually the
00425      * same signature & semantics, hence we can reuse the EnumDirTree W->A
00426      * conversion helper
00427      */
00428     edt.cb = cb;
00429     edt.user = user;
00430     if (searchPath)
00431         MultiByteToWideChar(CP_ACP, 0, searchPath, -1, searchPathW, MAX_PATH);
00432     MultiByteToWideChar(CP_ACP, 0, full_path, -1, full_pathW, MAX_PATH);
00433     if ((ret =  SymFindFileInPathW(hProcess, searchPath ? searchPathW : NULL, full_pathW,
00434                                    id, two, three, flags,
00435                                    bufferW, enum_dir_treeWA, &edt)))
00436         WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
00437     return ret;
00438 }
00439 
00440 struct module_find
00441 {
00442     enum module_type            kind;
00443     /* pe:  dw1         DWORD:timestamp
00444      *      dw2         size of image (from PE header)
00445      * pdb: guid        PDB guid (if DS PDB file)
00446      *      or dw1      PDB timestamp (if JG PDB file)
00447      *      dw2         PDB age
00448      * elf: dw1         DWORD:CRC 32 of ELF image (Wine only)
00449      */
00450     const GUID*                 guid;
00451     DWORD                       dw1;
00452     DWORD                       dw2;
00453     WCHAR                       filename[MAX_PATH];
00454     unsigned                    matched;
00455 };
00456 
00457 /* checks that buffer (as found by matching the name) matches the info
00458  * (information is based on file type)
00459  * returns TRUE when file is found, FALSE to continue searching
00460  * (NB this is the opposite convention of SymFindFileInPathProc)
00461  */
00462 static BOOL CALLBACK module_find_cb(PCWSTR buffer, PVOID user)
00463 {
00464     struct module_find* mf = user;
00465     DWORD               size, checksum, timestamp;
00466     unsigned            matched = 0;
00467 
00468     /* the matching weights:
00469      * +1 if a file with same name is found and is a decent file of expected type
00470      * +1 if first parameter and second parameter match
00471      */
00472 
00473     /* FIXME: should check that id/two match the file pointed
00474      * by buffer
00475      */
00476     switch (mf->kind)
00477     {
00478     case DMT_PE:
00479         {
00480             HANDLE  hFile, hMap;
00481             void*   mapping;
00482             DWORD   timestamp;
00483 
00484             timestamp = ~mf->dw1;
00485             size = ~mf->dw2;
00486             hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL,
00487                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00488             if (hFile == INVALID_HANDLE_VALUE) return FALSE;
00489             if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
00490             {
00491                 if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
00492                 {
00493                     IMAGE_NT_HEADERS*   nth = RtlImageNtHeader(mapping);
00494 
00495                     matched++;
00496                     timestamp = nth->FileHeader.TimeDateStamp;
00497                     size = nth->OptionalHeader.SizeOfImage;
00498                     UnmapViewOfFile(mapping);
00499                 }
00500                 CloseHandle(hMap);
00501             }
00502             CloseHandle(hFile);
00503             if (timestamp != mf->dw1)
00504                 WARN("Found %s, but wrong timestamp\n", debugstr_w(buffer));
00505             if (size != mf->dw2)
00506                 WARN("Found %s, but wrong size\n", debugstr_w(buffer));
00507             if (timestamp == mf->dw1 && size == mf->dw2) matched++;
00508         }
00509         break;
00510     case DMT_ELF:
00511         if (elf_fetch_file_info(buffer, 0, &size, &checksum))
00512         {
00513             matched++;
00514             if (checksum == mf->dw1) matched++;
00515             else
00516                 WARN("Found %s, but wrong checksums: %08x %08x\n",
00517                      debugstr_w(buffer), checksum, mf->dw1);
00518         }
00519         else
00520         {
00521             WARN("Couldn't read %s\n", debugstr_w(buffer));
00522             return FALSE;
00523         }
00524         break;
00525     case DMT_MACHO:
00526         if (macho_fetch_file_info(buffer, 0, &size, &checksum))
00527         {
00528             matched++;
00529             if (checksum == mf->dw1) matched++;
00530             else
00531                 WARN("Found %s, but wrong checksums: %08x %08x\n",
00532                      debugstr_w(buffer), checksum, mf->dw1);
00533         }
00534         else
00535         {
00536             WARN("Couldn't read %s\n", debugstr_w(buffer));
00537             return FALSE;
00538         }
00539         break;
00540     case DMT_PDB:
00541         {
00542             struct pdb_lookup           pdb_lookup;
00543             char                        fn[MAX_PATH];
00544 
00545             WideCharToMultiByte(CP_ACP, 0, buffer, -1, fn, MAX_PATH, NULL, NULL);
00546             pdb_lookup.filename = fn;
00547 
00548             if (mf->guid)
00549             {
00550                 pdb_lookup.kind = PDB_DS;
00551                 pdb_lookup.timestamp = 0;
00552                 pdb_lookup.guid = *mf->guid;
00553             }
00554             else
00555             {
00556                 pdb_lookup.kind = PDB_JG;
00557                 pdb_lookup.timestamp = mf->dw1;
00558                 /* pdb_loopkup.guid = */
00559             }
00560             pdb_lookup.age = mf->dw2;
00561 
00562             if (!pdb_fetch_file_info(&pdb_lookup, &matched)) return FALSE;
00563         }
00564         break;
00565     case DMT_DBG:
00566         {
00567             HANDLE  hFile, hMap;
00568             void*   mapping;
00569 
00570             timestamp = ~mf->dw1;
00571             hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL,
00572                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00573             if (hFile == INVALID_HANDLE_VALUE) return FALSE;
00574             if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
00575             {
00576                 if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
00577                 {
00578                     const IMAGE_SEPARATE_DEBUG_HEADER*  hdr;
00579                     hdr = mapping;
00580 
00581                     if (hdr->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE)
00582                     {
00583                         matched++;
00584                         timestamp = hdr->TimeDateStamp;
00585                     }
00586                     UnmapViewOfFile(mapping);
00587                 }
00588                 CloseHandle(hMap);
00589             }
00590             CloseHandle(hFile);
00591             if (timestamp == mf->dw1) matched++;
00592             else WARN("Found %s, but wrong timestamp\n", debugstr_w(buffer));
00593         }
00594         break;
00595     default:
00596         FIXME("What the heck??\n");
00597         return FALSE;
00598     }
00599     if (matched > mf->matched)
00600     {
00601         strcpyW(mf->filename, buffer);
00602         mf->matched = matched;
00603     }
00604     /* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
00605      * convention to stop/continue enumeration. sigh.
00606      */
00607     return mf->matched == 2;
00608 }
00609 
00610 BOOL path_find_symbol_file(const struct process* pcs, PCSTR full_path,
00611                            const GUID* guid, DWORD dw1, DWORD dw2, PSTR buffer,
00612                            BOOL* is_unmatched)
00613 {
00614     struct module_find  mf;
00615     WCHAR               full_pathW[MAX_PATH];
00616     WCHAR               tmp[MAX_PATH];
00617     WCHAR*              ptr;
00618     const WCHAR*        filename;
00619     WCHAR*              searchPath = pcs->search_path;
00620 
00621     TRACE("(pcs = %p, full_path = %s, guid = %s, dw1 = 0x%08x, dw2 = 0x%08x, buffer = %p)\n",
00622           pcs, debugstr_a(full_path), debugstr_guid(guid), dw1, dw2, buffer);
00623 
00624     mf.guid = guid;
00625     mf.dw1 = dw1;
00626     mf.dw2 = dw2;
00627     mf.matched = 0;
00628 
00629     MultiByteToWideChar(CP_ACP, 0, full_path, -1, full_pathW, MAX_PATH);
00630     filename = file_nameW(full_pathW);
00631     mf.kind = module_get_type_by_name(filename);
00632     *is_unmatched = FALSE;
00633 
00634     /* first check full path to file */
00635     if (module_find_cb(full_pathW, &mf))
00636     {
00637         WideCharToMultiByte(CP_ACP, 0, full_pathW, -1, buffer, MAX_PATH, NULL, NULL);
00638         return TRUE;
00639     }
00640 
00641     while (searchPath)
00642     {
00643         ptr = strchrW(searchPath, ';');
00644         if (ptr)
00645         {
00646             memcpy(tmp, searchPath, (ptr - searchPath) * sizeof(WCHAR));
00647             tmp[ptr - searchPath] = '\0';
00648             searchPath = ptr + 1;
00649         }
00650         else
00651         {
00652             strcpyW(tmp, searchPath);
00653             searchPath = NULL;
00654         }
00655         if (do_searchW(filename, tmp, FALSE, module_find_cb, &mf))
00656         {
00657             /* return first fully matched file */
00658             WideCharToMultiByte(CP_ACP, 0, tmp, -1, buffer, MAX_PATH, NULL, NULL);
00659             return TRUE;
00660         }
00661     }
00662     /* if no fully matching file is found, return the best matching file if any */
00663     if ((dbghelp_options & SYMOPT_LOAD_ANYTHING) && mf.matched)
00664     {
00665         WideCharToMultiByte(CP_ACP, 0, mf.filename, -1, buffer, MAX_PATH, NULL, NULL);
00666         *is_unmatched = TRUE;
00667         return TRUE;
00668     }
00669     return FALSE;
00670 }

Generated on Fri May 25 2012 04:16:31 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.