Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions ExpandCab.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Param([string]$sSourcePath, [string]$sDestinationPath)

$oShell = New-Object -Comobject "Shell.Application"
if (!$?) {
$(Throw "unable to create Shell.Application object")
}
$oCab = $oShell.Namespace($sSourcePath).items()
$oDestinationFolder = $oShell.Namespace($sDestinationPath)
$oDestinationFolder.CopyHere($oCab)
22 changes: 22 additions & 0 deletions PDBTypeCopy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os, sys;
from fbDownloadPDB import fbDownloadPDB;
from fbCopyPDBTypeData import fbCopyPDBTypeData;

if __name__ == "__main__":
if (len(sys.argv) != 5):
print "Usage: %s [file] [from hash] [to hash] [symbols folder path]"
sys.exit(1);

sFileName, sFromHash, sToHash, sSymbolCacheFolderPath = sys.argv[1:];
if (not fbDownloadPDB(sFileName, sFromHash, sSymbolCacheFolderPath)):
sys.exit(1);
if (not fbDownloadPDB(sFileName, sToHash, sSymbolCacheFolderPath)):
sys.exit(1);

sPDBFromFilePath = os.path.join(sSymbolCacheFolderPath, sFileName, sFromHash, sFileName);
sPDBToFilePath = os.path.join(sSymbolCacheFolderPath, sFileName, sToHash, sFileName);
if (not fbCopyPDBTypeData(sPDBFromFilePath, sPDBToFilePath)):
sys.exit(1);

print "+ PDB types copied successfully.";

22 changes: 22 additions & 0 deletions fbCopyPDBTypeData.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os;
from pdb_type_theft import PDB7, TPI_STREAM;

def fbCopyPDBTypeData(sPDBFromFilePath, sPDBToFilePath):
print "* Copying PDB type data...";
with open(sPDBFromFilePath, 'rb') as hPdbFromFile:
oFromPDB = PDB7(hPdbFromFile);

with open(sPDBToFilePath, 'rb') as hPDBToFile:
oToPDB = PDB7(hPDBToFile);
uFromTPIHashStream = oFromPDB.streams[TPI_STREAM].stream;
uToTPIHashStream = oToPDB.streams[TPI_STREAM].stream;

oToPDB.streams[TPI_STREAM] = oFromPDB.streams[TPI_STREAM];
oToPDB.streams[TPI_STREAM].stream = uToTPIHashStream;
oToPDB.streams[TPI_STREAM]._update_data();
oToPDB.streams[uToTPIHashStream] = oFromPDB.streams[uFromTPIHashStream];

print "* Saving updated PDB file...";
with open(sPDBToFilePath, 'wb') as hPDBToFile:
oToPDB.dump(hPDBToFile)
print " * PDB file size: %d bytes." % (os.path.getsize(sPDBToFilePath));
64 changes: 64 additions & 0 deletions fbDownloadPDB.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import os, re, subprocess, sys, urllib, urllib2;

sPowershellEXEPath = os.path.join(os.getenv("SystemRoot"), "System32", "Windowspowershell", "v1.0", "powershell.exe");
sExpendsCabPS1Path = os.path.abspath(os.path.join(os.path.dirname("__file__"), "ExpandCab.ps1"));

def fbDownloadPDB(sFileName, sHash, sSymbolCacheFolderPath):
sPDBFolderPath = os.path.join(sSymbolCacheFolderPath, sFileName, sHash);
sPDBFilePath = os.path.join(sPDBFolderPath, sFileName);
# if (os.path.isfile(sPDBFilePath)):
# print "* File already exists in local cache";
# return True;

print "* Downloading PDB Cab file for %s @ %s..." % (sFileName, sHash);
sCabFileURL = "http://msdl.microsoft.com/download/symbols/%s/%s/%s" % (sFileName, sHash, sFileName[:-1] + "_");
oCabFileRequest = urllib2.Request(sCabFileURL, headers = {"User-Agent": "Microsoft-Symbol-Server/6.6.0007.5"});
sTempCabFile = urllib2.urlopen(oCabFileRequest).read();
print " * Cab file size: %d bytes." % (len(sTempCabFile));
sTempCabFilePath = os.path.join(os.environ["TEMP"], "%s@%s.cab" % (sFileName, sHash));
open(sTempCabFilePath, "wb").write(sTempCabFile);

if (not os.path.isdir(sPDBFolderPath)):
os.makedirs(sPDBFolderPath);

sPDBBackupFilePath = None;
# Back up current file if any
if (os.path.isfile(sPDBFilePath)):
sPDBBackupFilePath = os.path.join(sPDBFolderPath, "#old#%s" % sFileName);
# Delete existing back up if any
if (os.path.isfile(sPDBBackupFilePath)):
os.remove(sPDBBackupFilePath);
# Back up current file
os.rename(sPDBFilePath, sPDBBackupFilePath);
print "* Extracting PDB Cab file to %s..." % sPDBFolderPath;
if (subprocess.call([sPowershellEXEPath, sExpendsCabPS1Path, sTempCabFilePath, sPDBFolderPath])):
print "- Extraction failed.";
# Delete failed PDB file if any
if (os.path.isfile(sPDBFilePath)):
os.remove(sPDBFilePath);
# Restore back up if any
if (sPDBBackupFilePath and os.path.isfile(sPDBBackupFilePath)):
os.rename(sPDBBackupFilePath, sPDBFilePath);
return False;

if (not os.path.isfile(sPDBFilePath)):
print "- Extraction did not reveal a %s file as expected." % sFileName;
# Restore back up if any
if (sPDBBackupFilePath and os.path.isfile(sPDBBackupFilePath)):
os.rename(sPDBBackupFilePath, sPDBFilePath);
return False;

# Remove back up if any
if (sPDBBackupFilePath and os.path.isfile(sPDBBackupFilePath)):
os.remove(sPDBBackupFilePath);

print " * PDB file size: %d bytes." % (os.path.getsize(sPDBFilePath));
return True;

if __name__ == "__main__":
if (len(sys.argv) != 4):
print "Usage: %s [file] [hash] [symbols folder path]"
sys.exit(1);
sFileName, sHash, sSymbolCacheFolderPath = sys.argv[1:];
if (not fbDownloadPDB(sFileName, sHash, sSymbolCacheFolderPath)):
sys.exit(1);