title: Extracting structure information from pdbs of unloaded modules
body: <p>I'm trying to write a WinDbg debugger extension that works on both live remote targets and crash dumps. This extension analyzes an opaque block of memory by walking down it via structure offsets and casting different regions of it to known objects.</p>
  
  <p>The structures change fields/field ordering between versions, so I can't hard code it (or include the headers) in my debugger extension itself. Instead I'd like to extract the structure information from the pdbs for which I have private symbols. </p>
  
  <p>When using this on a live target where the pdb/image is in the loaded module list, this works great, and I can use functions like <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff546758(v=vs.85).aspx" rel="nofollow">GetFieldOffset</a> to get a field in a structure in a class.</p>
  
  <pre><code>GetFieldOffset("MyClass!MyNestedClass", "m_Struct", &amp;offsetInClass);
  
  GetFieldData(offsetInClass + classAddr, "MyClass!_MY_STRUCT", "FieldInStruct",
               sizeof(ULONG), &amp;myFieldValue);
  </code></pre>
  
  <p><strong>My problem:</strong> When I don't have the module in the loaded module list (either in the wrong context, or analyzing a crash dump), I can't use the above functions.</p>
  
  <p>At the beginning of the memory region I'm analyzing, I've stored the pdb GUID and age. Using that I can find the path to my pdb in my symbol path/symbol cache using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680726(v=vs.85).aspx" rel="nofollow">SymFindFileInPath</a>.</p>
  
  <pre><code>char symbolPath[MAX_SYMBOL_PATH] = "";
  PSTR pdbPath = NULL;
  
  hr = ExtSymbols-&gt;lpVtbl-&gt;GetSymbolPath(ExtSymbols,
                                         symbolPath,
                                         sizeof(symbolPath),
                                         NULL);
  
  SymSetOptions(SYMOPT_IGNORE_CVREC | SYMOPT_FAIL_CRITICAL_ERRORS | 
                SYMOPT_CASE_INSENSITIVE);
  
  result = SymFindFileInPath(hSymbols,
                             symbolPath,
                             Name,
                             &amp;GUID,
                             Age,
                             0,
                             SSRVOPT_GUIDPTR,
                             pdbPath,
                             NULL,
                             NULL);
  </code></pre>
  
  <p>So I have the path to my specific pdb instance, but I'm not sure where to go from here. Looking through the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680726(v=vs.85).aspx" rel="nofollow">Sym* functions</a> exposed by DbgHelp.dll, I don't see any obvious way to use this pdb file to get type information. Functions such as <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms681349(v=vs.85).aspx" rel="nofollow">SymGetTypeInfo</a> require a module base, and my module is not and cannot be loaded. All I need is the byte offset of fields within a structure. Any ideas?</p>
  
  <p>Thanks!</p>