Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automate downloading, extracting and updating of cab files #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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);