Eric Pouech a écrit :
minidumps now contain more accurate information about modules, especially information that will allow when reloading a minidump in a debugger to check whether we're using the right modules (ELF & PE)
implemented also check for this information in SymFindFileInPath
A+
Please use this version instead (the previous had an un-wanted statement)
A+

--
Eric Pouech
Name:          dbghelp18
ChangeLog:     
	- various improvements for minidump module information
	  . added timestamp & checksum in PE module
	  . added size & checksum in ELF module
	  . wine loader now appears with its pathname
	- Implemented PE & ELF timestamp & checksum validation in SymFindFileInPath

License:       X11
GenDate:       2005/03/28 16:36:41 UTC
ModifiedFiles: dlls/dbghelp/dbghelp_private.h dlls/dbghelp/elf_module.c dlls/dbghelp/minidump.c dlls/dbghelp/module.c
dlls/dbghelp/path.c dlls/dbghelp/pe_module.c include/dbghelp.h
AddedFiles:    
RemovedFiles:  
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/dbghelp/dbghelp_private.h,v
retrieving revision 1.14
diff -u -u -r1.14 dbghelp_private.h
--- dlls/dbghelp/dbghelp_private.h	1 Mar 2005 10:39:49 -0000	1.14
+++ dlls/dbghelp/dbghelp_private.h	28 Mar 2005 11:28:25 -0000
@@ -249,6 +249,7 @@
     DMT_UNKNOWN,        /* for lookup, not actually used for a module */
     DMT_ELF,            /* a real ELF shared module */
     DMT_PE,             /* a native or builtin PE module */
+    DMT_PDB,            /* PDB file */
 };
 
 struct module
@@ -295,6 +296,7 @@
 /* elf_module.c */
 typedef BOOL (*elf_enum_modules_cb)(const char*, unsigned long addr, void* user);
 extern BOOL         elf_enum_modules(HANDLE hProc, elf_enum_modules_cb, void*);
+extern BOOL         elf_fetch_file_info(const char* name, DWORD* base, DWORD* size, DWORD* checksum);
 struct elf_file_map;
 extern BOOL         elf_load_debug_info(struct module* module, struct elf_file_map* fmap);
 extern struct module*
@@ -324,6 +326,8 @@
 extern struct module*
                     module_get_containee(const struct process* pcs,
                                          const struct module* inner);
+extern enum module_type
+                    module_get_type_by_name(const char* name);
 extern void         module_reset_debug_info(struct module* module);
 extern BOOL         module_remove(struct process* pcs, 
                                   struct module* module);
@@ -334,6 +338,7 @@
                                             const IMAGE_SECTION_HEADER* sectp, DWORD nsect,
                                             const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg);
 /* pe_module.c */
+extern BOOL         pe_load_nt_header(HANDLE hProc, DWORD base, IMAGE_NT_HEADERS* nth);
 extern struct module*
                     pe_load_module(struct process* pcs, char* name,
                                    HANDLE hFile, DWORD base, DWORD size);
Index: dlls/dbghelp/elf_module.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/dbghelp/elf_module.c,v
retrieving revision 1.17
diff -u -u -r1.17 elf_module.c
--- dlls/dbghelp/elf_module.c	23 Mar 2005 13:15:20 -0000	1.17
+++ dlls/dbghelp/elf_module.c	28 Mar 2005 12:00:09 -0000
@@ -81,12 +81,14 @@
 
 #define ELF_INFO_DEBUG_HEADER   0x0001
 #define ELF_INFO_MODULE         0x0002
+#define ELF_INFO_NAME           0x0004
 
 struct elf_info
 {
     unsigned                    flags;          /* IN  one (or several) of the ELF_INFO constants */
     unsigned long               dbg_hdr_addr;   /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
     struct module*              module;         /* OUT loaded module (if ELF_INFO_MODULE is set) */
+    const char*                 module_name;    /* OUT found module name (if ELF_INFO_NAME is set) */
 };
 
 #define NO_MAP                  ((const void*)0xffffffff)
@@ -139,7 +141,8 @@
         return NO_MAP;
     /* align required information on page size (we assume pagesize is a power of 2) */
     ofst = fmap->sect[sidx].shdr.sh_offset & ~(pgsz - 1);
-    size = (fmap->sect[sidx].shdr.sh_offset + fmap->sect[sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1);
+    size = (fmap->sect[sidx].shdr.sh_offset + 
+            fmap->sect[sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1);
     fmap->sect[sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fmap->fd, ofst);
     if (fmap->sect[sidx].mapped == NO_MAP) return NO_MAP;
     return fmap->sect[sidx].mapped + (fmap->sect[sidx].shdr.sh_offset & (pgsz - 1));
@@ -188,7 +191,8 @@
     if (memcmp(fmap->elfhdr.e_ident, 
                elf_signature, sizeof(elf_signature))) return FALSE;
 
-    fmap->sect = HeapAlloc(GetProcessHeap(), 0, fmap->elfhdr.e_shnum * sizeof(fmap->sect[0]));
+    fmap->sect = HeapAlloc(GetProcessHeap(), 0,
+                           fmap->elfhdr.e_shnum * sizeof(fmap->sect[0]));
     if (!fmap->sect) return FALSE;
 
     lseek(fmap->fd, fmap->elfhdr.e_shoff, SEEK_SET);
@@ -800,7 +804,8 @@
     shstrtab = elf_map_section(fmap, fmap->elfhdr.e_shstrndx);
     if (shstrtab == NO_MAP) return FALSE;
 
-    symtab_sect = dynsym_sect = stab_sect = stabstr_sect = debug_sect = debuglink_sect = -1;
+    symtab_sect = dynsym_sect = stab_sect = stabstr_sect =
+        debug_sect = debuglink_sect = -1;
 
     for (i = 0; i < fmap->elfhdr.e_shnum; i++)
     {
@@ -867,7 +872,8 @@
         else if (debug_sect != -1)
         {
             /* Dwarf 2 debug information */
-            FIXME("Unsupported Dwarf2 information for %s\n", module->module.ModuleName);
+            FIXME("Unsupported Dwarf2 information for %s\n",
+                  module->module.ModuleName);
         }
         else if (debuglink_sect != -1)
         {
@@ -876,7 +882,8 @@
 
             dbg_link = elf_map_section(fmap, debuglink_sect);
             /* The content of a debug link section is:
-             * 1/ a NULL terminated string, containing the file name for the debug info
+             * 1/ a NULL terminated string, containing the file name for the
+             *    debug info
              * 2/ padding on 4 byte boundary
              * 3/ CRC of the linked ELF file
              */
@@ -884,11 +891,14 @@
             {
                 fmap_link.crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
                 fmap_link.with_crc = 1;
-                ret = elf_load_debug_info_from_map(module, &fmap_link, pool, ht_symtab);
+                ret = elf_load_debug_info_from_map(module, &fmap_link, pool,
+                                                   ht_symtab);
                 if (!ret)
                     WARN("Couldn't load debug information from %s\n", dbg_link);
             }
-            else WARN("Couldn't load linked debug file for %s\n", module->module.ModuleName);
+            else
+                WARN("Couldn't load linked debug file for %s\n",
+                     module->module.ModuleName);
             elf_unmap_file(&fmap_link);
         }
     }
@@ -940,6 +950,22 @@
     return ret;
 }
 
+/******************************************************************
+ *		elf_fetch_file_info
+ *
+ * Gathers some more information for an ELF module from a given file
+ */
+BOOL elf_fetch_file_info(const char* name, DWORD* base,
+                         DWORD* size, DWORD* checksum)
+{
+    struct elf_file_map fmap;
+    if (!elf_map_file(name, &fmap)) return FALSE;
+    if (base) *base = fmap.elf_start;
+    *size = fmap.elf_size;
+    *checksum = calc_crc32(&fmap);
+    elf_unmap_file(&fmap);
+    return TRUE;
+}
 
 /******************************************************************
  *		is_dt_flag_valid
@@ -1033,7 +1059,7 @@
         if (!elf_module_info) goto leave;
         elf_info->module = module_new(pcs, filename, DMT_ELF, 
                                       (load_offset) ? load_offset : fmap.elf_start, 
-                                      fmap.elf_size, 0, 0);
+                                      fmap.elf_size, 0, calc_crc32(&fmap));
         if (!elf_info->module)
         {
             HeapFree(GetProcessHeap(), 0, elf_module_info);
@@ -1053,6 +1079,11 @@
         elf_info->module->elf_info->elf_loader = 0;
     } else ret = TRUE;
 
+    if (elf_info->flags & ELF_INFO_NAME)
+    {
+        elf_info->module_name = strcpy(HeapAlloc(GetProcessHeap(), 0,
+                                                 strlen(filename) + 1), filename);
+    }
 leave:
     elf_unmap_file(&fmap);
 
@@ -1137,6 +1168,7 @@
  * Enumerate ELF modules from a running process
  */
 static BOOL elf_enum_modules_internal(const struct process* pcs,
+                                      const char* main_name,
                                       elf_enum_modules_cb cb, void* user)
 {
     struct r_debug      dbg_hdr;
@@ -1164,7 +1196,8 @@
 	    ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL)) 
         {
 	    bufstr[sizeof(bufstr) - 1] = '\0';
-            if (!cb(bufstr, lm.l_addr, user)) break;
+            if (main_name && !bufstr[0]) strcpy(bufstr, main_name);
+            if (!cb(bufstr, (unsigned long)lm.l_addr, user)) break;
 	}
     }
     return TRUE;
@@ -1204,7 +1237,7 @@
 
     es.pcs = pcs;
     es.elf_info.flags = ELF_INFO_MODULE;
-    if (!elf_enum_modules_internal(pcs, elf_enum_sync_cb, &es))
+    if (!elf_enum_modules_internal(pcs, NULL, elf_enum_sync_cb, &es))
         return FALSE;
 
     module = pcs->lmodules;
@@ -1277,13 +1310,16 @@
 {
     struct process      pcs;
     struct elf_info     elf_info;
+    BOOL                ret;
 
     memset(&pcs, 0, sizeof(pcs));
     pcs.handle = hProc;
-    elf_info.flags = ELF_INFO_DEBUG_HEADER;
+    elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_NAME;
     if (!elf_search_loader(&pcs, &elf_info)) return FALSE;
     pcs.dbg_hdr_addr = elf_info.dbg_hdr_addr;
-    return elf_enum_modules_internal(&pcs, cb, user);
+    ret = elf_enum_modules_internal(&pcs, elf_info.module_name, cb, user);
+    HeapFree(GetProcessHeap(), 0, (char*)elf_info.module_name);
+    return ret;
 }
 
 struct elf_load
@@ -1329,7 +1365,7 @@
 {
     struct elf_load     el;
 
-    TRACE("(%p %s)\n", pcs, name);
+    TRACE("(%p %s %08lx)\n", pcs, name, addr);
 
     el.elf_info.flags = ELF_INFO_MODULE;
     el.ret = FALSE;
@@ -1337,14 +1373,14 @@
     if (pcs->dbg_hdr_addr) /* we're debugging a life target */
     {
         el.pcs = pcs;
-        /* do only the lookup from the filename, not the path (as we lookup module name
-         * in the process' loaded module list)
+        /* do only the lookup from the filename, not the path (as we lookup module
+         * name in the process' loaded module list)
          */
         el.name = strrchr(name, '/');
         if (!el.name++) el.name = name;
         el.ret = FALSE;
 
-        if (!elf_enum_modules_internal(pcs, elf_load_cb, &el))
+        if (!elf_enum_modules_internal(pcs, NULL, elf_load_cb, &el))
             return NULL;
     }
     else if (addr)
Index: dlls/dbghelp/minidump.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/dbghelp/minidump.c,v
retrieving revision 1.3
diff -u -u -r1.3 minidump.c
--- dlls/dbghelp/minidump.c	23 Mar 2005 13:15:20 -0000	1.3
+++ dlls/dbghelp/minidump.c	28 Mar 2005 16:35:49 -0000
@@ -1,7 +1,7 @@
 /*
  * File minidump.c - management of dumps (read & write)
  *
- * Copyright (C) 2004, Eric Pouech
+ * Copyright (C) 2004-2005, Eric Pouech
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -45,6 +45,8 @@
     unsigned                            is_elf;
     ULONG                               base;
     ULONG                               size;
+    DWORD                               timestamp;
+    DWORD                               checksum;
     char                                name[MAX_PATH];
 };
 
@@ -182,12 +184,15 @@
  * Add a module to a dump context
  */
 static BOOL add_module(struct dump_context* dc, const char* name,
-                       DWORD base, DWORD size, BOOL is_elf)
+                       DWORD base, DWORD size, DWORD timestamp, DWORD checksum,
+                       BOOL is_elf)
 {
     if (!dc->module)
-        dc->module = HeapAlloc(GetProcessHeap(), 0, ++dc->num_module * sizeof(*dc->module));
+        dc->module = HeapAlloc(GetProcessHeap(), 0,
+                               ++dc->num_module * sizeof(*dc->module));
     else
-        dc->module = HeapReAlloc(GetProcessHeap(), 0, dc->module, ++dc->num_module * sizeof(*dc->module));
+        dc->module = HeapReAlloc(GetProcessHeap(), 0, dc->module,
+                                 ++dc->num_module * sizeof(*dc->module));
     if (!dc->module) return FALSE;
     if (is_elf ||
         !GetModuleFileNameExA(dc->hProcess, (HMODULE)base, 
@@ -197,6 +202,8 @@
                   sizeof(dc->module[dc->num_module - 1].name));
     dc->module[dc->num_module - 1].base = base;
     dc->module[dc->num_module - 1].size = size;
+    dc->module[dc->num_module - 1].timestamp = timestamp;
+    dc->module[dc->num_module - 1].checksum = checksum;
     dc->module[dc->num_module - 1].is_elf = is_elf;
 
     return TRUE;
@@ -210,7 +217,14 @@
 static BOOL WINAPI fetch_pe_module_info_cb(char* name, DWORD base, DWORD size,
                                            void* user)
 {
-    return add_module((struct dump_context*)user, name, base, size, FALSE);
+    struct dump_context*        dc = (struct dump_context*)user;
+    IMAGE_NT_HEADERS            nth;
+
+    if (pe_load_nt_header(dc->hProcess, base, &nth))
+        add_module((struct dump_context*)user, name, base, size, 
+                   nth.FileHeader.TimeDateStamp, nth.OptionalHeader.CheckSum,
+                   FALSE);
+    return TRUE;
 }
 
 /******************************************************************
@@ -221,13 +235,22 @@
 static BOOL fetch_elf_module_info_cb(const char* name, unsigned long base, 
                                      void* user)
 {
-    return add_module((struct dump_context*)user, name, 
-                      base, 0 /* FIXME */, TRUE);
+    struct dump_context*        dc = (struct dump_context*)user;
+    DWORD size, checksum;
+
+    /* FIXME: there's no relevant timestamp on ELF modules */
+    /* NB: if we have a non-null base from the live-target use it (whenever
+     * the ELF module is relocatable or not). If we have a null base (ELF
+     * module isn't relocatable) then grab its base address from ELF file
+     */
+    if (!elf_fetch_file_info(name, base ? NULL : &base, &size, &checksum))
+        size = checksum = 0;
+    add_module(dc, name, base, size, 0 /* FIXME */, checksum, TRUE);
+    return TRUE;
 }
 
 static void fetch_module_info(struct dump_context* dc)
 {
-    WINE_FIXME("--> %p\n", dc->hProcess);
     EnumerateLoadedModules(dc->hProcess, fetch_pe_module_info_cb, dc);
     /* Since we include ELF modules in a separate stream from the regular PE ones,
      * we can always include those ELF modules (they don't eat lots of space)
@@ -352,7 +375,8 @@
 
     for (i = nmod = 0; i < dc->num_module; i++)
     {
-        if ((dc->module[i].is_elf && dump_elf) || (!dc->module[i].is_elf && !dump_elf))
+        if ((dc->module[i].is_elf && dump_elf) ||
+            (!dc->module[i].is_elf && !dump_elf))
             nmod++;
     }
 
@@ -366,7 +390,8 @@
     dc->rva += sizeof(mdModuleList.NumberOfModules) + sizeof(mdModule) * nmod;
     for (i = 0; i < dc->num_module; i++)
     {
-        if ((dc->module[i].is_elf && !dump_elf) || (!dc->module[i].is_elf && dump_elf))
+        if ((dc->module[i].is_elf && !dump_elf) ||
+            (!dc->module[i].is_elf && dump_elf))
             continue;
 
         flags_out = ModuleWriteModule | ModuleWriteMiscRecord | ModuleWriteCvRecord;
@@ -396,8 +421,8 @@
             cbin.u.Module.FullPath = ms->Buffer;
             cbin.u.Module.BaseOfImage = dc->module[i].base;
             cbin.u.Module.SizeOfImage = dc->module[i].size;
-            cbin.u.Module.CheckSum = 0; /* FIXME */
-            cbin.u.Module.TimeDateStamp = 0; /* FIXME */
+            cbin.u.Module.CheckSum = dc->module[i].checksum;
+            cbin.u.Module.TimeDateStamp = dc->module[i].timestamp;
             memset(&cbin.u.Module.VersionInfo, 0, sizeof(cbin.u.Module.VersionInfo));
             cbin.u.Module.CvRecord = NULL;
             cbin.u.Module.SizeOfCvRecord = 0;
@@ -413,8 +438,8 @@
         {
             mdModule.BaseOfImage = dc->module[i].base;
             mdModule.SizeOfImage = dc->module[i].size;
-            mdModule.CheckSum = 0; /* FIXME */
-            mdModule.TimeDateStamp = 0; /* FIXME */
+            mdModule.CheckSum = dc->module[i].checksum;
+            mdModule.TimeDateStamp = dc->module[i].timestamp;
             mdModule.ModuleNameRva = dc->rva;
             ms->Length -= sizeof(WCHAR);
             append(dc, ms, sizeof(ULONG) + ms->Length);
@@ -619,7 +644,6 @@
 /******************************************************************
  *		MiniDumpWriteDump (DEBUGHLP.@)
  *
- *
  */
 BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile,
                               MINIDUMP_TYPE DumpType,
Index: dlls/dbghelp/module.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/dbghelp/module.c,v
retrieving revision 1.10
diff -u -u -r1.10 module.c
--- dlls/dbghelp/module.c	28 Mar 2005 14:17:52 -0000	1.10
+++ dlls/dbghelp/module.c	28 Mar 2005 14:36:40 -0000
@@ -76,6 +76,7 @@
 {
     struct module*      module;
 
+    assert(type == DMT_ELF || type == DMT_PE);
     if (!(module = HeapAlloc(GetProcessHeap(), 0, sizeof(*module))))
 	return NULL;
 
@@ -93,7 +94,8 @@
     module->module.SizeOfStruct = sizeof(module->module);
     module->module.BaseOfImage = mod_addr;
     module->module.ImageSize = size;
-    module_fill_module(name, module->module.ModuleName, sizeof(module->module.ModuleName));
+    module_fill_module(name, module->module.ModuleName,
+                       sizeof(module->module.ModuleName));
     module->module.ImageName[0] = '\0';
     lstrcpynA(module->module.LoadedImageName, name, sizeof(module->module.LoadedImageName));
     module->module.SymType = SymNone;
@@ -139,13 +141,15 @@
 
         for (module = pcs->lmodules; module; module = module->next)
         {
-            if (type == module->type && !strcasecmp(name, module->module.LoadedImageName)) 
+            if (type == module->type &&
+                !strcasecmp(name, module->module.LoadedImageName)) 
                 return module;
         }
         module_fill_module(name, modname, sizeof(modname));
         for (module = pcs->lmodules; module; module = module->next)
         {
-            if (type == module->type && !strcasecmp(modname, module->module.ModuleName)) 
+            if (type == module->type &&
+                !strcasecmp(modname, module->module.ModuleName)) 
                 return module;
         }
     }
@@ -258,7 +262,7 @@
     return module;
 }
 
-static BOOL module_is_elf_container_loaded(struct process* pcs, const char* ImageName, 
+static BOOL module_is_elf_container_loaded(struct process* pcs, const char* ImageName,
                                            const char* ModuleName)
 {
     char                buffer[MAX_PATH];
@@ -281,31 +285,34 @@
     return FALSE;
 }
 
-static BOOL elf_is_shared_by_name(const char* name)
+/******************************************************************
+ *		module_get_type_by_name
+ *
+ * Guesses a filename type from its extension
+ */
+enum module_type module_get_type_by_name(const char* name)
 {
     const char* ptr;
     int         len = strlen(name);
 
-    /* check for terminating .so or .so.[digit]+ */
-    while (len)
-    {
-        for (ptr = name + len - 1; ptr >= name; ptr--) if (*ptr == '.') break;
-        if (ptr < name) break;
-        if (ptr == name + len - 2 && isdigit(ptr[1]))
-        {
-            len -= 2;
-            continue;
-        }
-        if (ptr == name + len - 3 && ptr[1] == 's' && ptr[2] == 'o')
-            return TRUE;
-        break;
+    /* check for terminating .so or .so.[digit] */
+    ptr = strrchr(name, '.');
+    if (ptr)
+    {
+        if (!strcmp(ptr, ".so") ||
+            (isdigit(ptr[1]) && !ptr[2] && ptr >= name + 3 && !memcmp(ptr - 3, ".so", 3)))
+            return DMT_ELF;
+        else if (!strcasecmp(ptr, ".pdb"))
+            return DMT_PDB;
     }
-    /* wine-[kp]thread is valid too */
-    if (((len > 12 && name[len - 13] == '/') || len == 12) && 
+    /* wine-[kp]thread is also an ELF module */
+    else if (((len > 12 && name[len - 13] == '/') || len == 12) && 
              (!strcasecmp(name + len - 12, "wine-pthread") || 
               !strcasecmp(name + len - 12, "wine-kthread")))
-        return TRUE;
-    return FALSE;
+    {
+        return DMT_ELF;
+    }
+    return DMT_PE;
 }
 
 /***********************************************************************
@@ -333,7 +340,8 @@
     if (module_is_elf_container_loaded(pcs, ImageName, ModuleName))
     {
         /* force the loading of DLL as builtin */
-        if ((module = pe_load_module_from_pcs(pcs, ImageName, ModuleName, BaseOfDll, SizeOfDll)))
+        if ((module = pe_load_module_from_pcs(pcs, ImageName, ModuleName,
+                                              BaseOfDll, SizeOfDll)))
             goto done;
         WARN("Couldn't locate %s\n", ImageName);
         return 0;
@@ -341,12 +349,13 @@
     TRACE("Assuming %s as native DLL\n", ImageName);
     if (!(module = pe_load_module(pcs, ImageName, hFile, BaseOfDll, SizeOfDll)))
     {
-        if (elf_is_shared_by_name(ImageName) &&
+        if (module_get_type_by_name(ImageName) == DMT_ELF &&
             (module = elf_load_module(pcs, ImageName, BaseOfDll)))
             goto done;
         FIXME("Should have successfully loaded debug information for image %s\n",
               ImageName);
-        if ((module = pe_load_module_from_pcs(pcs, ImageName, ModuleName, BaseOfDll, SizeOfDll)))
+        if ((module = pe_load_module_from_pcs(pcs, ImageName, ModuleName,
+                                              BaseOfDll, SizeOfDll)))
             goto done;
         WARN("Couldn't locate %s\n", ImageName);
         return 0;
@@ -461,7 +470,6 @@
             !GetModuleBaseNameA(hProcess, hMods[i], base, sizeof(base)))
             continue;
         module_fill_module(base, mod, sizeof(mod));
-
         EnumLoadedModulesCallback(mod, (DWORD)mi.lpBaseOfDll, mi.SizeOfImage, 
                                   UserContext);
     }
Index: dlls/dbghelp/path.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/dbghelp/path.c,v
retrieving revision 1.4
diff -u -u -r1.4 path.c
--- dlls/dbghelp/path.c	21 Oct 2004 19:57:56 -0000	1.4
+++ dlls/dbghelp/path.c	28 Mar 2005 16:21:25 -0000
@@ -24,6 +24,10 @@
 #include <string.h>
 
 #include "dbghelp_private.h"
+#include "ntstatus.h"
+#include "winnls.h"
+#include "winreg.h"
+#include "winternl.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
@@ -140,7 +144,7 @@
     return mptr == match - 1;
 }
 
-static BOOL do_search(const char* file, char* buffer,
+static BOOL do_search(const char* file, char* buffer, BOOL recurse,
                       PENUMDIRTREE_CALLBACK cb, void* user)
 {
     HANDLE              h;
@@ -161,8 +165,8 @@
         if (!strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, "..")) continue;
 
         strcpy(buffer + pos, fd.cFileName);
-        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-            found = do_search(file, buffer, cb, user);
+        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;
@@ -182,7 +186,7 @@
     TRACE("(%s, %s, %p)\n", 
           debugstr_a(root), debugstr_a(file), buffer);
     strcpy(buffer, root);
-    return do_search(file, buffer, NULL, NULL);
+    return do_search(file, buffer, TRUE, NULL, NULL);
 }
 
 /******************************************************************
@@ -196,11 +200,19 @@
     TRACE("(%p %s %s %p %p %p)\n", hProcess, root, file, buffer, cb, user);
 
     strcpy(buffer, root);
-    return do_search(file, buffer, cb, user);
+    return do_search(file, buffer, TRUE, cb, user);
 }
 
 struct sffip
 {
+    enum module_type            kind;
+    /* pe:  id  -> DWORD:timestamp
+     *      two -> size of image (from PE header)
+     * pdb: id  -> PDB signature
+     *            I think either DWORD:timestamp or GUID:guid depending on PDB version
+     *      two -> PDB age ???
+     * elf: id  -> DWORD:CRC 32 of ELF image (Wine only)
+     */
     PVOID                       id;
     DWORD                       two;
     DWORD                       three;
@@ -212,11 +224,66 @@
 static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
 {
     struct sffip*       s = (struct sffip*)user;
-
+    DWORD               size, checksum;
+    DWORD_PTR           timestamp;
     /* FIXME: should check that id/two/three match the file pointed
      * by buffer
      */
-    /* yes, EnumDirTree and SymFindFileInPath callbacks use the opposite
+    switch (s->kind)
+    {
+    case DMT_PE:
+        {
+            HANDLE  hFile, hMap;
+            void*   mapping;
+
+            timestamp = ~(DWORD_PTR)s->id;
+            size = ~s->two;
+            hFile = CreateFileA(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, 
+                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+            if (hFile == INVALID_HANDLE_VALUE) return TRUE;
+            if ((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
+            {
+                if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
+                {
+                    IMAGE_NT_HEADERS*   nth = RtlImageNtHeader(mapping);
+                    timestamp = nth->FileHeader.TimeDateStamp;
+                    size = nth->OptionalHeader.SizeOfImage;
+                    UnmapViewOfFile(mapping);
+                }
+                CloseHandle(hMap);
+            }
+            CloseHandle(hFile);
+            if (timestamp != (DWORD_PTR)s->id || size != s->two)
+            {
+                WARN("Found %s, but wrong size or timestamp\n", buffer);
+                return TRUE;
+            }
+        }
+        break;
+    case DMT_ELF:
+        if (elf_fetch_file_info(buffer, 0, &size, &checksum))
+        {
+            if (checksum != (DWORD_PTR)s->id)
+            {
+                WARN("Found %s, but wrong checksums: %08lx %08lx\n",
+                      buffer, checksum, (DWORD_PTR)s->id);
+                return TRUE;
+            }
+        }
+        else
+        {
+            WARN("Couldn't read %s\n", buffer);
+            return TRUE;
+        }
+        break;
+    case DMT_PDB:
+        FIXME("NIY on '%s'\n", buffer);
+        break;
+    default:
+        FIXME("What the heck??\n");
+        return TRUE;
+    }
+    /* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
      * convention to stop/continue enumeration. sigh.
      */
     return !(s->cb)((char*)buffer, s->user);
@@ -226,7 +293,7 @@
  *		SymFindFileInPath (DBGHELP.@)
  *
  */
-BOOL WINAPI SymFindFileInPath(HANDLE hProcess, LPSTR searchPath, LPSTR file,
+BOOL WINAPI SymFindFileInPath(HANDLE hProcess, LPSTR searchPath, LPSTR full_path,
                               PVOID id, DWORD two, DWORD three, DWORD flags,
                               LPSTR buffer, PFINDFILEINPATHCALLBACK cb,
                               PVOID user)
@@ -235,9 +302,10 @@
     struct process*     pcs = process_find_by_handle(hProcess);
     char                tmp[MAX_PATH];
     char*               ptr;
+    char*               filename;
 
     TRACE("(%p %s %s %p %08lx %08lx %08lx %p %p %p)\n",
-          hProcess, searchPath, file, id, two, three, flags, 
+          hProcess, searchPath, full_path, id, two, three, flags, 
           buffer, cb, user);
 
     if (!pcs) return FALSE;
@@ -250,7 +318,15 @@
     s.cb = cb;
     s.user = user;
 
-    file = file_name(file);
+    filename = file_name(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);
+        return TRUE;
+    }
 
     while (searchPath)
     {
@@ -266,7 +342,8 @@
             strcpy(tmp, searchPath);
             searchPath = NULL;
         }
-        if (EnumDirTree(hProcess, tmp, file, buffer, sffip_cb, &s)) return TRUE;
+        if (do_search(filename, tmp, FALSE, sffip_cb, &s)) return TRUE;
     }
     return FALSE;
 }
+
Index: dlls/dbghelp/pe_module.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/dbghelp/pe_module.c,v
retrieving revision 1.10
diff -u -u -r1.10 pe_module.c
--- dlls/dbghelp/pe_module.c	1 Mar 2005 10:39:49 -0000	1.10
+++ dlls/dbghelp/pe_module.c	28 Mar 2005 08:39:50 -0000
@@ -341,7 +341,7 @@
             /* FIXME SetLastError */
             return NULL;
         }
-        if ((hFile = FindExecutableImage(name, NULL, loaded_name)) == NULL)
+        if ((hFile = FindExecutableImage(name, pcs->search_path, loaded_name)) == NULL)
             return NULL;
         opened = TRUE;
     }
@@ -381,6 +381,21 @@
 }
 
 /******************************************************************
+ *		pe_load_nt_header
+ *
+ */
+BOOL pe_load_nt_header(HANDLE hProc, DWORD base, IMAGE_NT_HEADERS* nth)
+{
+    IMAGE_DOS_HEADER    dos;
+
+    return ReadProcessMemory(hProc, (char*)base, &dos, sizeof(dos), NULL) &&
+        dos.e_magic == IMAGE_DOS_SIGNATURE &&
+        ReadProcessMemory(hProc, (char*)(base + dos.e_lfanew), 
+                          nth, sizeof(*nth), NULL) &&
+        nth->Signature == IMAGE_NT_SIGNATURE;
+}
+
+/******************************************************************
  *		pe_load_module_from_pcs
  *
  */
@@ -408,14 +423,9 @@
     {
         if (pcs->dbg_hdr_addr)
         {
-            IMAGE_DOS_HEADER    dos;
             IMAGE_NT_HEADERS    nth;
 
-            if (ReadProcessMemory(pcs->handle, (char*)base, &dos, sizeof(dos), NULL) &&
-                dos.e_magic == IMAGE_DOS_SIGNATURE &&
-                ReadProcessMemory(pcs->handle, (char*)(base + dos.e_lfanew), 
-                                  &nth, sizeof(nth), NULL) &&
-                nth.Signature == IMAGE_NT_SIGNATURE)
+            if (pe_load_nt_header(pcs->handle, base, &nth))
             {
                 if (!size) size = nth.OptionalHeader.SizeOfImage;
                 module = module_new(pcs, name, DMT_PE, base, size,
Index: include/dbghelp.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/include/dbghelp.h,v
retrieving revision 1.10
diff -u -u -r1.10 dbghelp.h
--- include/dbghelp.h	7 Mar 2005 11:03:21 -0000	1.10
+++ include/dbghelp.h	28 Mar 2005 08:11:08 -0000
@@ -887,6 +887,35 @@
 DWORD   WINAPI  SymGetOptions(void);
 DWORD   WINAPI  SymSetOptions(DWORD);
 
+/* Symbol server bits */
+typedef BOOL     (WINAPI* PSYMBOLSERVERPROC)(LPCSTR, LPCSTR, PVOID, DWORD, DWORD, LPSTR);
+typedef BOOL     (WINAPI* PSYMBOLSERVEROPENPROC)(void);
+typedef BOOL     (WINAPI* PSYMBOLSERVERCLOSEPROC)(void);
+typedef BOOL     (WINAPI* PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR, ULONG64);
+typedef BOOL     (CALLBACK* PSYMBOLSERVERCALLBACKPROC)(UINT_PTR, ULONG64, ULONG64);
+typedef UINT_PTR (WINAPI* PSYMBOLSERVERGETOPTIONSPROC)();
+typedef BOOL     (WINAPI* PSYMBOLSERVERPINGPROC)(LPCSTR);
+
+#define SSRVOPT_CALLBACK            0x0001
+#define SSRVOPT_DWORD               0x0002
+#define SSRVOPT_DWORDPTR            0x0004
+#define SSRVOPT_GUIDPTR             0x0008
+#define SSRVOPT_OLDGUIDPTR          0x0010
+#define SSRVOPT_UNATTENDED          0x0020
+#define SSRVOPT_NOCOPY              0x0040
+#define SSRVOPT_PARENTWIN           0x0080
+#define SSRVOPT_PARAMTYPE           0x0100
+#define SSRVOPT_SECURE              0x0200
+#define SSRVOPT_TRACE               0x0400
+#define SSRVOPT_SETCONTEXT          0x0800
+#define SSRVOPT_PROXY               0x1000
+#define SSRVOPT_DOWNSTREAM_STORE    0x2000
+#define SSRVOPT_RESET               ((ULONG_PTR)-1)
+
+#define SSRVACTION_TRACE        1
+#define SSRVACTION_QUERYCANCEL  2
+#define SSRVACTION_EVENT        3
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* defined(__cplusplus) */

Reply via email to