From 490ee4e5d8f568b3eb84858b22912b07617fc6ee Mon Sep 17 00:00:00 2001 From: Apprentice Alf Date: Mon, 4 Feb 2013 14:25:25 +0000 Subject: [PATCH] tools v5.6.1 --- Calibre_Plugins/K4MobiDeDRM_ReadMe.txt | 4 +- .../K4MobiDeDRM_plugin/__init__.py | 3 +- .../K4MobiDeDRM_plugin/alfcrypto.py | 8 ++- .../K4MobiDeDRM_plugin/k4mobidedrm.py | 1 + .../K4MobiDeDRM_plugin/kindlepid.py | 16 ++--- Calibre_Plugins/k4mobidedrm_plugin.zip | Bin 230414 -> 230152 bytes .../k4mobidedrm_plugin/k4pcutils.py | 20 +++--- .../k4mobidedrm_plugin/mobidedrm.py | 25 ++++---- DeDRM_Macintosh_Application/DeDRM ReadMe.rtf | 2 +- .../DeDRM.app/Contents/Info.plist | 6 +- .../Contents/Resources/Scripts/main.scpt | Bin 269068 -> 273522 bytes .../DeDRM.app/Contents/Resources/k4pcutils.py | 20 +++--- .../DeDRM.app/Contents/Resources/kindlepid.py | 16 ++--- .../DeDRM.app/Contents/Resources/mobidedrm.py | 25 ++++---- .../DeDRM_App/DeDRM_Drop_Target.bat | 4 +- .../DeDRM_App/DeDRM_lib/DeDRM_app.pyw | 59 +++++++++--------- .../DeDRM_App/DeDRM_lib/lib/k4pcutils.py | 20 +++--- .../DeDRM_App/DeDRM_lib/lib/kindlepid.py | 16 ++--- .../DeDRM_App/DeDRM_lib/lib/mobidedrm.py | 25 ++++---- 19 files changed, 141 insertions(+), 129 deletions(-) diff --git a/Calibre_Plugins/K4MobiDeDRM_ReadMe.txt b/Calibre_Plugins/K4MobiDeDRM_ReadMe.txt index bacc9b5..66cce14 100644 --- a/Calibre_Plugins/K4MobiDeDRM_ReadMe.txt +++ b/Calibre_Plugins/K4MobiDeDRM_ReadMe.txt @@ -1,4 +1,4 @@ -Kindle and Mobipocket Plugin - K4MobiDeDRM_v04.18_plugin.zip +Kindle and Mobipocket Plugin - K4MobiDeDRM_v04.19_plugin.zip ============================================================ Credit given to The Dark Reverser for the original standalone script. Credit also to the many people who have updated and expanded that script since then. @@ -13,7 +13,7 @@ This plugin is meant to remove the DRM from .prc, .mobi, .azw, .azw1, .azw3, .az Installation ------------ -Do **NOT** select "Get plugins to enhance calibre" as this is reserved for "official" calibre plugins, instead select "Change calibre behavior" to go to Calibre's Preferences page. Under "Advanced" click on the Plugins button. Use the "Load plugin from file" button to select the plugin's zip file (K4MobiDeDRM_v04.18_plugin.zip) and click the 'Add' button. Click 'Yes' in the the "Are you sure?" dialog. Click OK in the "Success" dialog. +Do **NOT** select "Get plugins to enhance calibre" as this is reserved for "official" calibre plugins, instead select "Change calibre behavior" to go to Calibre's Preferences page. Under "Advanced" click on the Plugins button. Use the "Load plugin from file" button to select the plugin's zip file (K4MobiDeDRM_v04.19_plugin.zip) and click the 'Add' button. Click 'Yes' in the the "Are you sure?" dialog. Click OK in the "Success" dialog. Make sure that you delete any old versions of the plugin. They might interfere with the operation of the new one. diff --git a/Calibre_Plugins/K4MobiDeDRM_plugin/__init__.py b/Calibre_Plugins/K4MobiDeDRM_plugin/__init__.py index 6b3fe2f..c1dfa1b 100644 --- a/Calibre_Plugins/K4MobiDeDRM_plugin/__init__.py +++ b/Calibre_Plugins/K4MobiDeDRM_plugin/__init__.py @@ -27,13 +27,14 @@ __docformat__ = 'restructuredtext en' # 0.4.16 - Yet another Topaz fix # 0.4.17 - Manage to include the actual fix. # 0.4.18 - More Topaz fixes +# 0.4.19 - MobiDeDRM PalmDoc fix """ Decrypt Amazon Kindle and Mobipocket encrypted ebooks. """ PLUGIN_NAME = u"Kindle and Mobipocket DeDRM" -PLUGIN_VERSION_TUPLE = (0, 4, 18) +PLUGIN_VERSION_TUPLE = (0, 4, 19) PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE]) import sys, os, re diff --git a/Calibre_Plugins/K4MobiDeDRM_plugin/alfcrypto.py b/Calibre_Plugins/K4MobiDeDRM_plugin/alfcrypto.py index b1b0606..036ba10 100644 --- a/Calibre_Plugins/K4MobiDeDRM_plugin/alfcrypto.py +++ b/Calibre_Plugins/K4MobiDeDRM_plugin/alfcrypto.py @@ -34,10 +34,14 @@ def _load_libalfcrypto(): else: name_of_lib = 'libalfcrypto64.so' + # hard code to local location for libalfcrypto libalfcrypto = os.path.join(sys.path[0],name_of_lib) - if not os.path.isfile(libalfcrypto): - raise Exception('libalfcrypto not found') + libalfcrypto = os.path.join(sys.path[0], 'lib', name_of_lib) + if not os.path.isfile(libalfcrypto): + libalfcrypto = os.path.join('.',name_of_lib) + if not os.path.isfile(libalfcrypto): + raise Exception('libalfcrypto not found at %s' % libalfcrypto) libalfcrypto = CDLL(libalfcrypto) diff --git a/Calibre_Plugins/K4MobiDeDRM_plugin/k4mobidedrm.py b/Calibre_Plugins/K4MobiDeDRM_plugin/k4mobidedrm.py index ca8fdcc..70ed898 100644 --- a/Calibre_Plugins/K4MobiDeDRM_plugin/k4mobidedrm.py +++ b/Calibre_Plugins/K4MobiDeDRM_plugin/k4mobidedrm.py @@ -248,6 +248,7 @@ def decryptBook(infile, outdir, kInfoFiles, serials, pids): # remove internal temporary directory of Topaz pieces book.cleanup() + return 0 def usage(progname): diff --git a/Calibre_Plugins/K4MobiDeDRM_plugin/kindlepid.py b/Calibre_Plugins/K4MobiDeDRM_plugin/kindlepid.py index 38c5e4e..d16c017 100644 --- a/Calibre_Plugins/K4MobiDeDRM_plugin/kindlepid.py +++ b/Calibre_Plugins/K4MobiDeDRM_plugin/kindlepid.py @@ -8,6 +8,7 @@ # 0.2 Added support for generating PID for iPhone (thanks to mbp) # 0.3 changed to autoflush stdout, fixed return code usage # 0.3 updated for unicode +# 0.4 Added support for serial numbers starting with '9', fixed unicode bugs. import sys import binascii @@ -63,7 +64,7 @@ def unicode_argv(): xrange(start, argc.value)] # if we don't have any arguments at all, just pass back script name # this should never happen - return [u"mobidedrm.py"] + return [u"kindlepid.py"] else: argvencoding = sys.stdin.encoding if argvencoding == None: @@ -92,7 +93,6 @@ def checksumPid(s): return res - def pidFromSerial(s, l): crc = crc32(s) @@ -113,27 +113,27 @@ def pidFromSerial(s, l): def cli_main(argv=unicode_argv()): print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky" - if len(sys.argv)==2: - serial = sys.argv[1] + if len(argv)==2: + serial = argv[1] else: print u"Usage: kindlepid.py /" return 1 if len(serial)==16: - if serial.startswith("B"): + if serial.startswith("B") or serial.startswith("9"): print u"Kindle serial number detected" else: print u"Warning: unrecognized serial number. Please recheck input." return 1 pid = pidFromSerial(serial.encode("utf-8"),7)+'*' - print u"Mobipocket PID for Kindle serial#{0} is {1} ".format(serial,checksumPid(pid)) + print u"Mobipocket PID for Kindle serial#{0} is {1}".format(serial,checksumPid(pid)) return 0 elif len(serial)==40: print u"iPhone serial number (UDID) detected" pid = pidFromSerial(serial.encode("utf-8"),8) - print u"Mobipocket PID for iPhone serial#{0} is {1} ".format(serial,checksumPid(pid)) + print u"Mobipocket PID for iPhone serial#{0} is {1}".format(serial,checksumPid(pid)) return 0 print u"Warning: unrecognized serial number. Please recheck input." - return 1 + return 1 if __name__ == "__main__": diff --git a/Calibre_Plugins/k4mobidedrm_plugin.zip b/Calibre_Plugins/k4mobidedrm_plugin.zip index 702253e5371ef08076319367590eadc561f8b716..87e4a40e1767ab6dfe9684ec54d9dbc1e4b5838f 100644 GIT binary patch delta 24910 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 I0QTws0J+sa>i_@% delta 26207 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 us3h!+oK`3~Pp4sL<@9!gx`F{3YP7kIuf#r&POH', self.sect[0x8:0x8+2]) self.compression, = struct.unpack('>H', self.sect[0x0:0x0+2]) + # det default values before PalmDoc test + self.print_replica = False + self.extra_data_flags = 0 + self.meta_array = {} + self.mobi_length = 0 + self.mobi_codepage = 1252 + self.mobi_version = -1 + if self.magic == 'TEXtREAd': print u"PalmDoc format book detected." - self.extra_data_flags = 0 - self.mobi_length = 0 - self.mobi_codepage = 1252 - self.mobi_version = -1 - self.meta_array = {} return + self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18]) self.mobi_codepage, = struct.unpack('>L',self.sect[0x1c:0x20]) self.mobi_version, = struct.unpack('>L',self.sect[0x68:0x6C]) print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length) - self.extra_data_flags = 0 if (self.mobi_length >= 0xE4) and (self.mobi_version >= 5): self.extra_data_flags, = struct.unpack('>H', self.sect[0xF2:0xF4]) print u"Extra Data Flags: {0:d}".format(self.extra_data_flags) @@ -290,7 +294,6 @@ class MobiBook: self.extra_data_flags &= 0xFFFE # if exth region exists parse it for metadata array - self.meta_array = {} try: exth_flag, = struct.unpack('>L', self.sect[0x80:0x84]) exth = '' @@ -313,9 +316,7 @@ class MobiBook: # print type, size, content, content.encode('hex') pos += size except: - self.meta_array = {} pass - self.print_replica = False def getBookTitle(self): codec_map = { @@ -406,7 +407,9 @@ class MobiBook: return u"Print Replica" if self.mobi_version >= 8: return u"Kindle Format 8" - return u"Mobipocket" + if self.mobi_version >= 0: + return u"Mobipocket {0:d}".format(self.mobi_version) + return u"PalmDoc" def getBookExtension(self): if self.print_replica: diff --git a/DeDRM_Macintosh_Application/DeDRM ReadMe.rtf b/DeDRM_Macintosh_Application/DeDRM ReadMe.rtf index b6f5244..99c6d57 100644 --- a/DeDRM_Macintosh_Application/DeDRM ReadMe.rtf +++ b/DeDRM_Macintosh_Application/DeDRM ReadMe.rtf @@ -41,7 +41,7 @@ Mac OS X 10.5 and above: You do \i not \i0 need to install Python.\ \ -Drag the DeDRM application from from tools_v5.6\\DeDRM_Applications\\Macintosh (the location of this ReadMe) to your Applications folder, or anywhere else you find convenient.\ +Drag the DeDRM application from from tools_v5.6.1\\DeDRM_Applications\\Macintosh (the location of this ReadMe) to your Applications folder, or anywhere else you find convenient.\ \ \ diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist index eee088f..2c12ee2 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist @@ -24,17 +24,17 @@ CFBundleExecutable droplet CFBundleGetInfoString - DeDRM 5.6. AppleScript written 2010–2013 by Apprentice Alf and others. + DeDRM 5.6.1. AppleScript written 2010–2013 by Apprentice Alf and others. CFBundleIconFile DeDRM CFBundleInfoDictionaryVersion 6.0 CFBundleName - DeDRM 5.6 + DeDRM 5.6.1 CFBundlePackageType APPL CFBundleShortVersionString - 5.6 + 5.6.1 CFBundleSignature dplt LSRequiresCarbon diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt index 2108e076d5a207a67e0a765de334f705e3e4d44b..a0000f4a703729ead340d367470fe9bff9a5f4d8 100644 GIT binary patch delta 8370 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 delta 5208 zcmd5=i+dDBwy)~bPG-`fO^5IbkfcfoVjv_CAQ4u>Ls)@mcm#RK#w0vK1fmc`K5!FO z+!c+0vU&i$8bl!wSU?TUE6PjdVL%WO5EXE-XF44u>Oug;dn$VGW$(9tK)(KZrt3U@ z=U3-cSDl$3PDPe&jVxWr7i#Z8_2{VBlGta&pX&zJ4XEp1*RL)^l-Nf{LzEFH1@9mW zH$^GBxsZ^!K>Wq~(C`j0Gns|YnK`w1QgP9=qA84--p5SSz5U{8@b)uqil?zp9>nnl zI6e=0@W0qg@}MJ!h2j~s^C8~9ka2I5;cZ%0AKd~XNqRLOF2G;K-|*~25d5!rb0Wm@ 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/" return 1 if len(serial)==16: - if serial.startswith("B"): + if serial.startswith("B") or serial.startswith("9"): print u"Kindle serial number detected" else: print u"Warning: unrecognized serial number. Please recheck input." return 1 pid = pidFromSerial(serial.encode("utf-8"),7)+'*' - print u"Mobipocket PID for Kindle serial#{0} is {1} ".format(serial,checksumPid(pid)) + print u"Mobipocket PID for Kindle serial#{0} is {1}".format(serial,checksumPid(pid)) return 0 elif len(serial)==40: print u"iPhone serial number (UDID) detected" pid = pidFromSerial(serial.encode("utf-8"),8) - print u"Mobipocket PID for iPhone serial#{0} is {1} ".format(serial,checksumPid(pid)) + print u"Mobipocket PID for iPhone serial#{0} is {1}".format(serial,checksumPid(pid)) return 0 print u"Warning: unrecognized serial number. Please recheck input." - return 1 + return 1 if __name__ == "__main__": diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py index 113f57a..264c175 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py @@ -66,9 +66,10 @@ # 0.36 - fixed problem with TEXtREAd and getBookTitle interface # 0.37 - Fixed double announcement for stand-alone operation # 0.38 - Unicode used wherever possible, cope with absent alfcrypto +# 0.39 - Fixed problem with TEXtREAd and getBookType interface -__version__ = u"0.38" +__version__ = u"0.39" import sys import os @@ -268,19 +269,22 @@ class MobiBook: self.records, = struct.unpack('>H', self.sect[0x8:0x8+2]) self.compression, = struct.unpack('>H', self.sect[0x0:0x0+2]) + # det default values before PalmDoc test + self.print_replica = False + self.extra_data_flags = 0 + self.meta_array = {} + self.mobi_length = 0 + self.mobi_codepage = 1252 + self.mobi_version = -1 + if self.magic == 'TEXtREAd': print u"PalmDoc format book detected." - self.extra_data_flags = 0 - self.mobi_length = 0 - self.mobi_codepage = 1252 - self.mobi_version = -1 - self.meta_array = {} return + self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18]) self.mobi_codepage, = struct.unpack('>L',self.sect[0x1c:0x20]) self.mobi_version, = struct.unpack('>L',self.sect[0x68:0x6C]) print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length) - self.extra_data_flags = 0 if (self.mobi_length >= 0xE4) and (self.mobi_version >= 5): self.extra_data_flags, = struct.unpack('>H', self.sect[0xF2:0xF4]) print u"Extra Data Flags: {0:d}".format(self.extra_data_flags) @@ -290,7 +294,6 @@ class MobiBook: self.extra_data_flags &= 0xFFFE # if exth region exists parse it for metadata array - self.meta_array = {} try: exth_flag, = struct.unpack('>L', self.sect[0x80:0x84]) exth = '' @@ -313,9 +316,7 @@ class MobiBook: # print type, size, content, content.encode('hex') pos += size except: - self.meta_array = {} pass - self.print_replica = False def getBookTitle(self): codec_map = { @@ -406,7 +407,9 @@ class MobiBook: return u"Print Replica" if self.mobi_version >= 8: return u"Kindle Format 8" - return u"Mobipocket" + if self.mobi_version >= 0: + return u"Mobipocket {0:d}".format(self.mobi_version) + return u"PalmDoc" def getBookExtension(self): if self.print_replica: diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_Drop_Target.bat b/DeDRM_Windows_Application/DeDRM_App/DeDRM_Drop_Target.bat index 9e33348..fa1cb9b 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_Drop_Target.bat +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_Drop_Target.bat @@ -1,4 +1,4 @@ echo off set PWD=%~dp0 -cd /d %PWD%\DeDRM_lib && start /min python DeDRM_app.pyw %* -exit +cd /d %PWD%DeDRM_lib && start /min python DeDRM_app.pyw %* +exit \ No newline at end of file diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_app.pyw b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_app.pyw index 8e9290e..03268c8 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_app.pyw +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_app.pyw @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# DeDRM.pyw, version 5.6 +# DeDRM.pyw, version 5.6.1 # By some_updates and Apprentice Alf import sys @@ -34,23 +34,19 @@ from scriptinterface import decryptepub, decryptpdb, decryptpdf, decryptk4mobi # Wrap a stream so that output gets flushed immediately # and appended to shared queue -class QueuedStream: +class QueuedUTF8Stream: def __init__(self, stream, q): self.stream = stream - self.encoding = stream.encoding + self.encoding = 'utf-8' self.q = q - if self.encoding == None: - self.encoding = "utf-8" def write(self, data): if isinstance(data,unicode): - data = data.encode(self.encoding,"replace") + data = data.encode('utf-8',"replace") self.q.put(data) - # self.stream.write(data) - # self.stream.flush() def __getattr__(self, attr): return getattr(self.stream, attr) -__version__ = '5.6' +__version__ = '5.6.1' class DrmException(Exception): pass @@ -280,7 +276,7 @@ class PrefsDialog(Toplevel): def get_altinfopath(self): cpath = self.altinfopath.get() altinfopath = tkFileDialog.askopenfilename(parent=None, title='Select Alternative kindle.info or .kinf File', - defaultextension='.info', filetypes=[('Kindle Info', '.info'),('Kindle KInf','.kinf')('All Files', '.*')], + defaultextension='.info', filetypes=[('Kindle Info', '.info'),('Kindle KInf','.kinf'),('All Files', '.*')], initialdir=cpath) if altinfopath: altinfopath = os.path.normpath(altinfopath) @@ -291,17 +287,17 @@ class PrefsDialog(Toplevel): def get_bookpath(self): cpath = self.bookpath.get() bookpath = tkFileDialog.askopenfilename(parent=None, title='Select eBook for DRM Removal', - filetypes=[('ePub Files','.epub'), - ('Kindle','.azw'), - ('Kindle','.azw1'), - ('Kindle','.azw3'), - ('Kindle','.azw4'), - ('Kindle','.tpz'), - ('Kindle','.mobi'), - ('Kindle','.prc'), - ('eReader','.pdb'), - ('PDF','.pdf'), - ('All Files', '.*')], + filetypes=[('All Files', '.*'), + ('ePub Files','.epub'), + ('Kindle','.azw'), + ('Kindle','.azw1'), + ('Kindle','.azw3'), + ('Kindle','.azw4'), + ('Kindle','.tpz'), + ('Kindle','.mobi'), + ('Kindle','.prc'), + ('eReader','.pdb'), + ('PDF','.pdf')], initialdir=cpath) if bookpath: bookpath = os.path.normpath(bookpath) @@ -412,8 +408,9 @@ class ConvDialog(Toplevel): self.showCmdOutput(msg) if self.numbad == 0: self.after(2000,self.conversion_done()) - logfile = os.path.join(rscpath,'dedrm.log') - file(logfile,'wb').write(self.log) + logfile = os.path.join(os.path.expanduser('~'),'DeDRM.log') + file(logfile,'w').write(self.log) + self.log='' return infile = filename bname = os.path.basename(infile) @@ -537,8 +534,8 @@ class ConvDialog(Toplevel): def processK4MOBI(q, infile, outdir, rscpath): add_cp65001_codec() set_utf8_default_encoding() - sys.stdout = QueuedStream(sys.stdout, q) - sys.stderr = QueuedStream(sys.stderr, q) + sys.stdout = QueuedUTF8Stream(sys.stdout, q) + sys.stderr = QueuedUTF8Stream(sys.stderr, q) rv = decryptk4mobi(infile, outdir, rscpath) sys.exit(rv) @@ -546,8 +543,8 @@ def processK4MOBI(q, infile, outdir, rscpath): def processPDF(q, infile, outdir, rscpath): add_cp65001_codec() set_utf8_default_encoding() - sys.stdout = QueuedStream(sys.stdout, q) - sys.stderr = QueuedStream(sys.stderr, q) + sys.stdout = QueuedUTF8Stream(sys.stdout, q) + sys.stderr = QueuedUTF8Stream(sys.stderr, q) rv = decryptpdf(infile, outdir, rscpath) sys.exit(rv) @@ -555,8 +552,8 @@ def processPDF(q, infile, outdir, rscpath): def processEPUB(q, infile, outdir, rscpath): add_cp65001_codec() set_utf8_default_encoding() - sys.stdout = QueuedStream(sys.stdout, q) - sys.stderr = QueuedStream(sys.stderr, q) + sys.stdout = QueuedUTF8Stream(sys.stdout, q) + sys.stderr = QueuedUTF8Stream(sys.stderr, q) rv = decryptepub(infile, outdir, rscpath) sys.exit(rv) @@ -564,8 +561,8 @@ def processEPUB(q, infile, outdir, rscpath): def processPDB(q, infile, outdir, rscpath): add_cp65001_codec() set_utf8_default_encoding() - sys.stdout = QueuedStream(sys.stdout, q) - sys.stderr = QueuedStream(sys.stderr, q) + sys.stdout = QueuedUTF8Stream(sys.stdout, q) + sys.stderr = QueuedUTF8Stream(sys.stderr, q) rv = decryptpdb(infile, outdir, rscpath) sys.exit(rv) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4pcutils.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4pcutils.py index 476844c..bb9289e 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4pcutils.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4pcutils.py @@ -208,7 +208,7 @@ CryptUnprotectData = CryptUnprotectData() def getKindleInfoFiles(): kInfoFiles = [] # some 64 bit machines do not have the proper registry key for some reason - # or the pythonn interface to the 32 vs 64 bit registry is broken + # or the python interface to the 32 vs 64 bit registry is broken path = "" if 'LOCALAPPDATA' in os.environ.keys(): path = os.environ['LOCALAPPDATA'] @@ -217,17 +217,17 @@ def getKindleInfoFiles(): try: regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\") path = winreg.QueryValueEx(regkey, 'Local AppData')[0] + except WindowsError: + pass + if not os.path.isdir(path): + path = "" + try: + regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\") + path = winreg.QueryValueEx(regkey, 'Local AppData')[0] + except WindowsError: + pass if not os.path.isdir(path): path = "" - try: - regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\") - path = winreg.QueryValueEx(regkey, 'Local AppData')[0] - if not os.path.isdir(path): - path = "" - except RegError: - pass - except RegError: - pass found = False if path == "": diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlepid.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlepid.py index 38c5e4e..d16c017 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlepid.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlepid.py @@ -8,6 +8,7 @@ # 0.2 Added support for generating PID for iPhone (thanks to mbp) # 0.3 changed to autoflush stdout, fixed return code usage # 0.3 updated for unicode +# 0.4 Added support for serial numbers starting with '9', fixed unicode bugs. import sys import binascii @@ -63,7 +64,7 @@ def unicode_argv(): xrange(start, argc.value)] # if we don't have any arguments at all, just pass back script name # this should never happen - return [u"mobidedrm.py"] + return [u"kindlepid.py"] else: argvencoding = sys.stdin.encoding if argvencoding == None: @@ -92,7 +93,6 @@ def checksumPid(s): return res - def pidFromSerial(s, l): crc = crc32(s) @@ -113,27 +113,27 @@ def pidFromSerial(s, l): def cli_main(argv=unicode_argv()): print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky" - if len(sys.argv)==2: - serial = sys.argv[1] + if len(argv)==2: + serial = argv[1] else: print u"Usage: kindlepid.py /" return 1 if len(serial)==16: - if serial.startswith("B"): + if serial.startswith("B") or serial.startswith("9"): print u"Kindle serial number detected" else: print u"Warning: unrecognized serial number. Please recheck input." return 1 pid = pidFromSerial(serial.encode("utf-8"),7)+'*' - print u"Mobipocket PID for Kindle serial#{0} is {1} ".format(serial,checksumPid(pid)) + print u"Mobipocket PID for Kindle serial#{0} is {1}".format(serial,checksumPid(pid)) return 0 elif len(serial)==40: print u"iPhone serial number (UDID) detected" pid = pidFromSerial(serial.encode("utf-8"),8) - print u"Mobipocket PID for iPhone serial#{0} is {1} ".format(serial,checksumPid(pid)) + print u"Mobipocket PID for iPhone serial#{0} is {1}".format(serial,checksumPid(pid)) return 0 print u"Warning: unrecognized serial number. Please recheck input." - return 1 + return 1 if __name__ == "__main__": diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py index 113f57a..264c175 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py @@ -66,9 +66,10 @@ # 0.36 - fixed problem with TEXtREAd and getBookTitle interface # 0.37 - Fixed double announcement for stand-alone operation # 0.38 - Unicode used wherever possible, cope with absent alfcrypto +# 0.39 - Fixed problem with TEXtREAd and getBookType interface -__version__ = u"0.38" +__version__ = u"0.39" import sys import os @@ -268,19 +269,22 @@ class MobiBook: self.records, = struct.unpack('>H', self.sect[0x8:0x8+2]) self.compression, = struct.unpack('>H', self.sect[0x0:0x0+2]) + # det default values before PalmDoc test + self.print_replica = False + self.extra_data_flags = 0 + self.meta_array = {} + self.mobi_length = 0 + self.mobi_codepage = 1252 + self.mobi_version = -1 + if self.magic == 'TEXtREAd': print u"PalmDoc format book detected." - self.extra_data_flags = 0 - self.mobi_length = 0 - self.mobi_codepage = 1252 - self.mobi_version = -1 - self.meta_array = {} return + self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18]) self.mobi_codepage, = struct.unpack('>L',self.sect[0x1c:0x20]) self.mobi_version, = struct.unpack('>L',self.sect[0x68:0x6C]) print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length) - self.extra_data_flags = 0 if (self.mobi_length >= 0xE4) and (self.mobi_version >= 5): self.extra_data_flags, = struct.unpack('>H', self.sect[0xF2:0xF4]) print u"Extra Data Flags: {0:d}".format(self.extra_data_flags) @@ -290,7 +294,6 @@ class MobiBook: self.extra_data_flags &= 0xFFFE # if exth region exists parse it for metadata array - self.meta_array = {} try: exth_flag, = struct.unpack('>L', self.sect[0x80:0x84]) exth = '' @@ -313,9 +316,7 @@ class MobiBook: # print type, size, content, content.encode('hex') pos += size except: - self.meta_array = {} pass - self.print_replica = False def getBookTitle(self): codec_map = { @@ -406,7 +407,9 @@ class MobiBook: return u"Print Replica" if self.mobi_version >= 8: return u"Kindle Format 8" - return u"Mobipocket" + if self.mobi_version >= 0: + return u"Mobipocket {0:d}".format(self.mobi_version) + return u"PalmDoc" def getBookExtension(self): if self.print_replica: