def eventHandler(self, dlg, event, name): if lbc.IsCloseEvent(event) or (name==self.btn_cancel.GetName() and lbc.IsButtonEvent(event)): return globals.destroy(self, self.txt_search.GetName(), [self.txt_search.GetName()]) elif name==self.lst_searchTypes.GetName() and lbc.IsListChangeEvent(event): #show/hide category/grades depending on search type if self.lst_searchTypes.GetStringSelection() in globals.uncategorizedSearch: self.lst_categories.Hide() self.lst_grades.Hide() else: #show them in case they were hidden by passing over a search type that would hide them self.lst_categories.Show() self.lst_grades.Show() self.Layout() elif name==self.btn_search.GetName() and lbc.IsButtonEvent(event): #do the search text=self.txt_search.GetValue() grade=None category=None typeIndex=self.lst_searchTypes.GetSelection() categoryIndex=self.lst_categories.GetSelection() gradeIndex=self.lst_grades.GetSelection() if typeIndex<0: typeIndex=0 #the next 2 say >0 because selection 0 is for leaving the option unspecified if categoryIndex>0: category=globals.categories[categoryIndex] if gradeIndex>0: grade=globals.grades[gradeIndex] searchType=globals.searchTypes.keys()[typeIndex] if text=="" and searchType!=globals.search_getBooksInCategory: #only category searches can be blank, since they just list all books in that category return ErrorDialog("No Search Terms", "You did not enter anything to search for. Please enter your search terms and try again.") if searchType==globals.search_getBooksInCategory: if categoryIndex==0: return ErrorDialog("No Category Selected", "You must select a category before the books in that category can be retrieved. Please choose a category and try again.") text="all books in "+category+" category" if globals.canSpeak: globals.output("Searching, please wait.", 1) try: results=globals.searchTypes[searchType](text, category=category, grade=grade) #search for the text except pybookshare.ApiError, e: return ErrorDialog("Error!", e.message) SearchResultsDialog(searchTerms=text, searchType=globals.searchTypes.keys()[typeIndex], results=results, category=category, grade=grade) return self.Destroy()
def eventHandler(self, dlg, event, name): if self.lst_favorites.GetCount()==0: #hide the list and its "open" button self.lst_favorites.Hide() self.btn_open.Hide() self.btn_delete.Hide() self.Layout() favoriteIndex=self.lst_favorites.GetSelection() #which favorite was selected favorite=self.lst_favorites.GetStringSelection() #which favorite was selected if lbc.IsCloseEvent(event) or (name==self.btn_close.GetName() and lbc.IsButtonEvent(event)): return self.Destroy() elif name==self.btn_newSearch.GetName() and lbc.IsButtonEvent(event): #pop up new search dlg return NewSearchDialog() elif name==self.btn_open.GetName() and lbc.IsButtonEvent(event): #open selected favorite if self.lst_favorites.GetCount()==0: return ErrorDialog("No Favorites", "There are no favorites to open.") if favoriteIndex<0: favoriteIndex=0 #if none selected, select the first one return self.openFavorite(favorite) elif name==self.btn_delete.GetName() and lbc.IsButtonEvent(event): #delete selected favorite if lbc.DialogConfirm(title="Delete Favorite", message="Are you sure you want to delete this favorite?")=='Y': del globals.config['favorites'][favorite] globals.config.write() self.lst_favorites.Delete(favoriteIndex) self.lst_favorites.SetFocus() self.Layout() elif name==self.btn_mostPopular.GetName() and lbc.IsButtonEvent(event): if globals.canSpeak: globals.output("Loading most popular books, please wait.", 1) try: results=globals.bs.getPopular() #search for the text except pybookshare.ApiError, e: return ErrorDialog("Error!", e) return SearchResultsDialog(title="Most Popular Books", favoriteable=False, results=results)
def __outputRaw(self, name, bytes): if bytes == None: return output("%s: " % name) for byte in bytes: output("%2.2X " % ord(byte)) print("")
def readRecord (self): pos, header, size, bytes, roflist = self.__readRecAndContBytes() # record handler that parses the raw bytes and displays more # meaningful information. handler = None print("") headerStr = "%4.4Xh: "%header self.__printSep('=', globals.OutputWidth-len(headerStr), headerStr) if recData.has_key(header): print("%4.4Xh: %s - %s (%4.4Xh)"% (header, recData[header][0], recData[header][1], header)) if len(recData[header]) >= 3: handler = recData[header][2](header, size, bytes, self.strmData, roflist) elif self.type == DirType.RevisionLog and recDataRev.has_key(header): print("%4.4Xh: %s - %s (%4.4Xh)"% (header, recDataRev[header][0], recDataRev[header][1], header)) if len(recDataRev[header]) >= 3: handler = recDataRev[header][2](header, size, bytes, self.strmData, roflist) else: print("%4.4Xh: [unknown record name] (%4.4Xh)"%(header, header)) if self.params.showStreamPos: print("%4.4Xh: size = %d; pos = %d"%(header, size, pos)) else: print("%4.4Xh: size = %d"%(header, size)) # print the raw bytes, with 16 bytes per line. self.__printSep('-', globals.OutputWidth-len(headerStr), headerStr) lines = [] for i in xrange(0, size): if i % 16 == 0: lines.append([]) lines[-1].append(bytes[i]) for line in lines: output("%4.4Xh: "%header) n = len(line) for byte in line: output("%2.2X "%ord(byte)) for i in xrange(n, 16): output(" ") output(' ') for byte in line: output(globals.toCharOrDot(byte)) print("") if handler != None and not self.strmData.encrypted: # record handler exists. Parse the record and display more info # unless the stream is encrypted. handler.output() self.__postReadRecord(header) return header
def printRecordDump (self, bytes, recordType): size = len(bytes) self.__printSep('-', 61, "%4.4Xh: "%recordType) for i in xrange(0, size): if (i+1) % 16 == 1: output(self.prefix + "%4.4Xh: "%recordType) output("%2.2X "%ord(bytes[i])) if (i+1) % 16 == 0 and i != size-1: print("") if size > 0: print("") self.__printSep('-', 61, "%4.4Xh: "%recordType)
def openFavorite(self, fav): #uses info in config file to see which favorite is being opened, then re-searches text=globals.config['favorites'][fav][0] type=globals.config['favorites'][fav][1] category=globals.config['favorites'][fav][2] grade=globals.config['favorites'][fav][3] if type not in globals.searchTypes.keys(): return ErrorDialog("Error in Favorite", "The selected favorite cannot be opened; it seems to be corrupted somehow. Please delete it and re-save the favorite by performing the search again.") if globals.canSpeak: globals.output("Opening favorite, please wait.", 1) try: #perform the search again... results=globals.searchTypes[type](text, category=category, grade=grade) #search for the text except pybookshare.ApiError, e: return ErrorDialog("Error!", e.number+", "+e.message)
def output(self): print('') print("=" * globals.OutputWidth) print("Short Sector Allocation Table (SSAT)") print("-" * globals.OutputWidth) if self.params.debug: self.outputRawBytes() print("-" * globals.OutputWidth) for i in xrange(0, len(self.array)): item = self.array[i] output("%3d : %3d\n" % (i, item)) self.outputArrayStats()
def output(self): print("") print("=" * 68) print("Short Sector Allocation Table (SSAT)") print("-" * 68) if self.params.debug: self.outputRawBytes() print("-" * 68) for i in xrange(0, len(self.array)): item = self.array[i] output("%3d : %3d\n" % (i, item)) self.outputArrayStats()
def output (self): globals.outputln('') globals.outputln("="*globals.OutputWidth) globals.outputln("Short Sector Allocation Table (SSAT)") globals.outputln("-"*globals.OutputWidth) if self.params.debug: self.outputRawBytes() globals.outputln("-"*globals.OutputWidth) for i in xrange(0, len(self.array)): item = self.array[i] output("%3d : %3d\n"%(i, item)) self.outputArrayStats()
def readRecord (self): if self.size - self.pos < 4: raise EndOfStream pos = self.pos header = self.readRaw(2) if header == 0x0000: raise EndOfStream size = self.readRaw(2) bytes = self.readByteArray(size) # record handler that parses the raw bytes and displays more # meaningful information. handler = None print("") self.__printSep('=', 61, "%4.4Xh: "%header) if recData.has_key(header): print("%4.4Xh: %s - %s (%4.4Xh)"% (header, recData[header][0], recData[header][1], header)) if len(recData[header]) >= 3: handler = recData[header][2](header, size, bytes, self.strmData) elif self.type == DirType.RevisionLog and recDataRev.has_key(header): print("%4.4Xh: %s - %s (%4.4Xh)"% (header, recDataRev[header][0], recDataRev[header][1], header)) if len(recDataRev[header]) >= 3: handler = recDataRev[header][2](header, size, bytes, self.strmData) else: print("%4.4Xh: [unknown record name] (%4.4Xh)"%(header, header)) if self.params.showStreamPos: print("%4.4Xh: size = %d; pos = %d"%(header, size, pos)) else: print("%4.4Xh: size = %d"%(header, size)) self.__printSep('-', 61, "%4.4Xh: "%header) for i in xrange(0, size): if (i+1) % 16 == 1: output("%4.4Xh: "%header) output("%2.2X "%bytes[i]) if (i+1) % 16 == 0 and i != size-1: print("") if size > 0: print("") if handler != None: # record handler exists. Parse the record and display more info. handler.output() return header
def printRecordDump (self, bytes, recordType): if self.params.noStructOutput and self.params.dumpText: return size = len(bytes) self.__printSep('-', 61, "%4.4Xh: "%recordType, recordType = recordType) for i in xrange(0, size): if (i+1) % 16 == 1: output(self.prefix + "%4.4Xh: "%recordType, recordType = recordType) output("%2.2X "%ord(bytes[i]), recordType = recordType) if (i+1) % 16 == 0 and i != size-1: globals.outputln("", recordType = recordType) if size > 0: globals.outputln("", recordType = recordType) self.__printSep('-', 61, "%4.4Xh: "%recordType, recordType = recordType)
def __init__(self, result, handler=None, *args, **kwords): if globals.canSpeak: globals.output("Retrieving book information, please wait.", 1) self.result=globals.bs.getMetaData(result) title=self.result.title lbc.Dialog.__init__(self, title=title, *args, **kwords) self.memo_basicInfo=self.AddMemo(label="Basic Information", value=SearchResultsDialog.getInfo(self, self.result, ["shortSynopsis", "longSynopsis"])) self.AddBand() self.memo_shortSynopsis=self.AddMemo(label="Short Synopsis", value=self.result.shortSynopsis) self.AddBand() self.memo_longSynopsis=self.AddMemo(label="Long Synopsis", value=self.result.longSynopsis) self.AddBand() self.btn_download=self.AddButton(label="Download Book") self.btn_close=self.AddButton(label="Close") if handler is None: handler=self.eventHandler self.Complete(buttons=[], handler=handler)
def eventHandler(self, dlg, event, name): result=self.lst_results.GetSelection() if lbc.IsCloseEvent(event) or (name==self.btn_close.GetName() and lbc.IsButtonEvent(event)): return globals.destroy(self, self.lst_results.GetName(), [self.lst_results.GetName()]) elif name==self.lst_results.GetName() and (lbc.IsFocusEvent(event) or lbc.IsListChangeEvent(event)): #update info box with current item when user changes selection or lands on list self.memo_info.SetValue(self.getInfo(self, self.results[result], ["longSynopsis"])) elif self.favoriteable and name==self.btn_favorite.GetName() and lbc.IsButtonEvent(event): #save this search to the favorites section of config globals.config['favorites'][self.searchName]=[str(self.searchTerms), self.searchType, self.category, self.grade] try: globals.config.write() return AlertDialog("Success", "The favorite has been saved.") except: return ErrorDialog("Error", "There was an error trying to save the favorite. Please try closing the program and re-launching it, then search again.") elif name==self.btn_download.GetName() and lbc.IsButtonEvent(event): if globals.config['settings']['format']!=str(globals.prompt[1]): #download book in preferred format globals.download(self.results[result]) else: return DownloadDialog(self.results[result]) elif name==self.btn_moreInfo.GetName() and lbc.IsButtonEvent(event): #use an api call to show all info about the book return BookInfoDialog(self.results[result]) elif name==self.btn_prev.GetName() and lbc.IsButtonEvent(event): if globals.canSpeak: globals.output("Loading previous "+str(globals.limit)+" results, please wait.", 1) self.results.prevPage() self.Destroy() return SearchResultsDialog(searchTerms=self.searchTerms, searchType=self.searchType, results=self.results, category=self.category, grade=self.grade) elif name==self.btn_next.GetName() and lbc.IsButtonEvent(event): if globals.canSpeak: globals.output("Loading next "+str(globals.limit)+" results, please wait.", 1) self.results.nextPage() self.Destroy() return SearchResultsDialog(searchTerms=self.searchTerms, searchType=self.searchType, results=self.results, category=self.category, grade=self.grade) elif name==self.btn_first.GetName() and lbc.IsButtonEvent(event): if globals.canSpeak: globals.output("Loading first "+str(globals.limit)+" results, please wait.", 1) self.results.getPage(1, True) self.Destroy() return SearchResultsDialog(searchTerms=self.searchTerms, searchType=self.searchType, results=self.results, category=self.category, grade=self.grade) elif name==self.btn_last.GetName() and lbc.IsButtonEvent(event): if globals.canSpeak: globals.output("Loading final results, please wait.", 1) self.results.getPage(self.results.pages, True) self.Destroy() return SearchResultsDialog(searchTerms=self.searchTerms, searchType=self.searchType, results=self.results, category=self.category, grade=self.grade) elif name==self.btn_author.GetName() and lbc.IsButtonEvent(event): if len(self.results[result].authorList)>1: author=lbc.DialogPick(title="Choose Author", names=self.results[result].authorList, values=self.results[result].authorList) else: author=self.results[result].authorList[0] if globals.canSpeak: globals.output("Searching for all books by "+author+", please wait.", 1) try: results=globals.searchTypes[globals.search_author](author, category=self.category, grade=self.grade) #search for the text except pybookshare.ApiError, e: return ErrorDialog("Error!", e) return SearchResultsDialog(searchTerms=author, searchType=globals.searchTypes.keys()[1], results=results, category=self.category, grade=self.grade)
def readRecord(self): pos, header, size, bytes = self.__readRecordBytes() # record handler that parses the raw bytes and displays more # meaningful information. handler = None print("") headerStr = "%4.4Xh: " % header self.__printSep('=', globals.OutputWidth - len(headerStr), headerStr) if recData.has_key(header): print("%4.4Xh: %s - %s (%4.4Xh)" % (header, recData[header][0], recData[header][1], header)) if len(recData[header]) >= 3: handler = recData[header][2](header, size, bytes, self.strmData) elif self.type == DirType.RevisionLog and recDataRev.has_key(header): print( "%4.4Xh: %s - %s (%4.4Xh)" % (header, recDataRev[header][0], recDataRev[header][1], header)) if len(recDataRev[header]) >= 3: handler = recDataRev[header][2](header, size, bytes, self.strmData) else: print("%4.4Xh: [unknown record name] (%4.4Xh)" % (header, header)) if self.params.showStreamPos: print("%4.4Xh: size = %d; pos = %d" % (header, size, pos)) else: print("%4.4Xh: size = %d" % (header, size)) self.__printSep('-', globals.OutputWidth - len(headerStr), headerStr) for i in xrange(0, size): if (i + 1) % 16 == 1: output("%4.4Xh: " % header) output("%2.2X " % bytes[i]) if (i + 1) % 16 == 0 and i != size - 1: print("") if size > 0: print("") if handler != None and not self.strmData.encrypted: # record handler exists. Parse the record and display more info # unless the stream is encrypted. handler.output() self.__postReadRecord(header) return header
def readRecord (self): pos, header, size, bytes = self.__readRecordBytes() # record handler that parses the raw bytes and displays more # meaningful information. handler = None print("") headerStr = "%4.4Xh: "%header self.__printSep('=', globals.OutputWidth-len(headerStr), headerStr) if recData.has_key(header): print("%4.4Xh: %s - %s (%4.4Xh)"% (header, recData[header][0], recData[header][1], header)) if len(recData[header]) >= 3: handler = recData[header][2](header, size, bytes, self.strmData) elif self.type == DirType.RevisionLog and recDataRev.has_key(header): print("%4.4Xh: %s - %s (%4.4Xh)"% (header, recDataRev[header][0], recDataRev[header][1], header)) if len(recDataRev[header]) >= 3: handler = recDataRev[header][2](header, size, bytes, self.strmData) else: print("%4.4Xh: [unknown record name] (%4.4Xh)"%(header, header)) if self.params.showStreamPos: print("%4.4Xh: size = %d; pos = %d"%(header, size, pos)) else: print("%4.4Xh: size = %d"%(header, size)) self.__printSep('-', globals.OutputWidth-len(headerStr), headerStr) for i in xrange(0, size): if (i+1) % 16 == 1: output("%4.4Xh: "%header) output("%2.2X "%bytes[i]) if (i+1) % 16 == 0 and i != size-1: print("") if size > 0: print("") if handler != None and not self.strmData.encrypted: # record handler exists. Parse the record and display more info # unless the stream is encrypted. handler.output() self.__postReadRecord(header) return header
def eventHandler(self, dlg, event, name): username=self.txt_username.GetValue() password=self.txt_password.GetValue() if lbc.IsCloseEvent(event) or (name==self.btn_cancel.GetName() and lbc.IsButtonEvent(event)): globals.gaveUp=True return self.Destroy() elif name==self.btn_login.GetName() and lbc.IsButtonEvent(event): globals.bs.setCreds(username, password) if globals.canSpeak: globals.output("Checking username and password, please wait.", 1) try: info=globals.bs.getUserInfo() #if this throws no exception, we're good globals.loggedIn=True globals.config['settings']['username']=username globals.config['settings']['password']=password globals.config['settings']['name']=info['displayname']['value'] globals.config.write() if globals.canSpeak: globals.output(info['displayname']['value']+" ("+username+") is authenticated.", 1) return self.Destroy() except pybookshare.ApiError: globals.loggedIn=False self.txt_password.Clear() return ErrorDialog("Login Failed", "login failed with username "+username+". Please try again, or click the Cancel button to exit.")
def output(self): def printRawBytes(bytes): for b in bytes: output("%2.2X " % ord(b)) output("\n") def printSep(c, w, prefix=''): print(prefix + c * w) printSep('=', globals.OutputWidth) print("Compound Document Header") printSep('-', globals.OutputWidth) if self.params.debug: globals.dumpBytes(self.bytes[0:512]) printSep('-', globals.OutputWidth) # document ID and unique ID output("Document ID: ") printRawBytes(self.docId) output("Unique ID: ") printRawBytes(self.uId) # revision and version print("Revision: %d Version: %d" % (self.revision, self.version)) # byte order output("Byte order: ") if self.byteOrder == ByteOrder.LittleEndian: print("little endian") elif self.byteOrder == ByteOrder.BigEndian: print("big endian") else: print("unknown") # sector size (usually 512 bytes) print("Sector size: %d (%d)" % (2**self.secSize, self.secSize)) # short sector size (usually 64 bytes) print("Short sector size: %d (%d)" % (2**self.secSizeShort, self.secSizeShort)) # total number of sectors in SAT (equals the number of sector IDs # stored in the MSAT). print("Total number of sectors used in SAT: %d" % self.numSecSAT) print("Sector ID of the first sector of the directory stream: %d" % self.__secIDFirstDirStrm) print("Minimum stream size: %d" % self.minStreamSize) if self.__secIDFirstSSAT == -2: print("Sector ID of the first SSAT sector: [none]") else: print("Sector ID of the first SSAT sector: %d" % self.__secIDFirstSSAT) print("Total number of sectors used in SSAT: %d" % self.numSecSSAT) if self.__secIDFirstMSAT == -2: # There is no more sector ID stored outside the header. print("Sector ID of the first MSAT sector: [end of chain]") else: # There is more sector IDs than 109 IDs stored in the header. print("Sector ID of the first MSAT sector: %d" % (self.__secIDFirstMSAT)) print("Total number of sectors used to store additional MSAT: %d" % self.numSecMSAT)
def printRawBytes(bytes): for b in bytes: output("%2.2X " % ord(b)) output("\n")
def output(self): def printRawBytes(bytes): for b in bytes: output("%2.2X " % ord(b)) output("\n") def printSep(c="-", w=68, prefix=""): print(prefix + c * w) printSep("=", 68) print("Compound Document Header") printSep("-", 68) if self.params.debug: globals.dumpBytes(self.bytes[0:512]) printSep("-", 68) # document ID and unique ID output("Document ID: ") printRawBytes(self.docId) output("Unique ID: ") printRawBytes(self.uId) # revision and version print("Revision: %d Version: %d" % (self.revision, self.version)) # byte order output("Byte order: ") if self.byteOrder == ByteOrder.LittleEndian: print("little endian") elif self.byteOrder == ByteOrder.BigEndian: print("big endian") else: print("unknown") # sector size (usually 512 bytes) print("Sector size: %d (%d)" % (2 ** self.secSize, self.secSize)) # short sector size (usually 64 bytes) print("Short sector size: %d (%d)" % (2 ** self.secSizeShort, self.secSizeShort)) # total number of sectors in SAT (equals the number of sector IDs # stored in the MSAT). print("Total number of sectors used in SAT: %d" % self.numSecSAT) print("Sector ID of the first sector of the directory stream: %d" % self.__secIDFirstDirStrm) print("Minimum stream size: %d" % self.minStreamSize) if self.__secIDFirstSSAT == -2: print("Sector ID of the first SSAT sector: [none]") else: print("Sector ID of the first SSAT sector: %d" % self.__secIDFirstSSAT) print("Total number of sectors used in SSAT: %d" % self.numSecSSAT) if self.__secIDFirstMSAT == -2: # There is no more sector ID stored outside the header. print("Sector ID of the first MSAT sector: [end of chain]") else: # There is more sector IDs than 109 IDs stored in the header. print("Sector ID of the first MSAT sector: %d" % (self.__secIDFirstMSAT)) print("Total number of sectors used to store additional MSAT: %d" % self.numSecMSAT)
def __outputEntry(self, entry, debug): print("-" * 68) if len(entry.Name) > 0: name = entry.Name if ord(name[0]) <= 5: name = "<%2.2Xh>%s" % (ord(name[0]), name[1:]) print("name: %s (name buffer size: %d bytes)" % (name, entry.CharBufferSize)) else: print("name: [empty] (name buffer size: %d bytes)" % entry.CharBufferSize) if self.params.debug: print("-" * 68) globals.dumpBytes(entry.bytes) print("-" * 68) output("type: ") if entry.Type == Directory.Type.Empty: print("empty") elif entry.Type == Directory.Type.LockBytes: print("lock bytes") elif entry.Type == Directory.Type.Property: print("property") elif entry.Type == Directory.Type.RootStorage: print("root storage") elif entry.Type == Directory.Type.UserStorage: print("user storage") elif entry.Type == Directory.Type.UserStream: print("user stream") else: print("[unknown type]") output("node color: ") if entry.NodeColor == Directory.NodeColor.Red: print("red") elif entry.NodeColor == Directory.NodeColor.Black: print("black") elif entry.NodeColor == Directory.NodeColor.Unknown: print("[unknown color]") print( "linked dir entries: left: %d; right: %d; root: %d" % (entry.DirIDLeft, entry.DirIDRight, entry.DirIDRoot) ) self.__outputRaw("unique ID", entry.UniqueID) self.__outputRaw("user flags", entry.UserFlags) self.__outputRaw("time created", entry.TimeCreated) self.__outputRaw("time last modified", entry.TimeModified) output("stream info: ") if entry.StreamSectorID < 0: print("[empty stream]") else: strmLoc = "SAT" if entry.StreamLocation == StreamLocation.SSAT: strmLoc = "SSAT" print("(first sector ID: %d; size: %d; location: %s)" % (entry.StreamSectorID, entry.StreamSize, strmLoc)) satObj = None secSize = 0 if entry.StreamLocation == StreamLocation.SAT: satObj = self.SAT secSize = self.header.getSectorSize() elif entry.StreamLocation == StreamLocation.SSAT: satObj = self.SSAT secSize = self.header.getShortSectorSize() if satObj != None: chain = satObj.getSectorIDChain(entry.StreamSectorID) print("sector count: %d" % len(chain)) print("total sector size: %d" % (len(chain) * secSize)) if self.params.showSectorChain: self.__outputSectorChain(chain)
def __outputEntry(self, entry, debug): print("-" * globals.OutputWidth) if len(entry.Name) > 0: name = entry.Name if ord(name[0]) <= 5: name = "<%2.2Xh>%s" % (ord(name[0]), name[1:]) print("name: %s (name buffer size: %d bytes)" % (name, entry.CharBufferSize)) else: print("name: [empty] (name buffer size: %d bytes)" % entry.CharBufferSize) if self.params.debug: print("-" * globals.OutputWidth) globals.dumpBytes(entry.bytes) print("-" * globals.OutputWidth) output("type: ") if entry.Type == Directory.Type.Empty: print("empty") elif entry.Type == Directory.Type.LockBytes: print("lock bytes") elif entry.Type == Directory.Type.Property: print("property") elif entry.Type == Directory.Type.RootStorage: print("root storage") elif entry.Type == Directory.Type.UserStorage: print("user storage") elif entry.Type == Directory.Type.UserStream: print("user stream") else: print("[unknown type]") output("node color: ") if entry.NodeColor == Directory.NodeColor.Red: print("red") elif entry.NodeColor == Directory.NodeColor.Black: print("black") elif entry.NodeColor == Directory.NodeColor.Unknown: print("[unknown color]") print("linked dir entries: left: %d; right: %d; root: %d" % (entry.DirIDLeft, entry.DirIDRight, entry.DirIDRoot)) self.__outputRaw("unique ID", entry.UniqueID) self.__outputRaw("user flags", entry.UserFlags) self.__outputRaw("time created", entry.TimeCreated) self.__outputRaw("time last modified", entry.TimeModified) output("stream info: ") if entry.StreamSectorID < 0 or entry.StreamSize == 0: print("[empty stream]") else: strmLoc = "SAT" if entry.StreamLocation == StreamLocation.SSAT: strmLoc = "SSAT" print("(first sector ID: %d; size: %d; location: %s)" % (entry.StreamSectorID, entry.StreamSize, strmLoc)) satObj = None secSize = 0 if entry.StreamLocation == StreamLocation.SAT: satObj = self.SAT secSize = self.header.getSectorSize() elif entry.StreamLocation == StreamLocation.SSAT: satObj = self.SSAT secSize = self.header.getShortSectorSize() if satObj != None: chain = satObj.getSectorIDChain(entry.StreamSectorID) print("sector count: %d" % len(chain)) print("total sector size: %d" % (len(chain) * secSize)) if self.params.showSectorChain: self.__outputSectorChain(chain)