Your IP : 216.73.216.213


Current Path : /opt/alt/python35/lib64/python3.5/site-packages/PIL/__pycache__/
Upload File :
Current File : //opt/alt/python35/lib64/python3.5/site-packages/PIL/__pycache__/OleFileIO.cpython-35.opt-1.pyc



�^N��,@sddlmZdZdZdZddlZddlZddlZddlZddl	Z
ddlZee
k	r|eZy
eZWneZYnXejd�jdkr�dZnNejd�jdkr�dZn-ejd	�jdkr�d	Zned
��yeWnek
r(eZYnXdZejddkrKd
ZndZdadd�Zdd�Zeadd�ZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5d Z6d!Z7d"Z8d#Z9d$Z:d%Z;d&Z<d'Z=d(Z>d)Z?d*Z@d+ZAd,ZBd-ZCd.ZDd/ZEd0ZFd1ZGd2ZHd3ZId4ZJd5ZKd6ZLd7ZMd8ZNd9ZOd:ZPd;ZQd<ZRd=ZSd>ZTd?ZUd@ZViZWxCeXeY�jZ��D],\Z[Z\e[dd�dAkre[eWe\<q�WdBZ]d"Z^d+Z_d5Z`dCZadDZbdEdF�Zce
ekrbdGdH�ZdndIdH�ZdddJdK�ZeddLdM�ZfdNdO�ZgdPdQ�ZhGdRdS�dSei�ZjGdTdU�dUejk�ZlGdVdW�dWei�ZmGdXdY�dYei�ZneodZkrepejq�dkrKerd[eeef�erd\�ejs�dZtx�ejqdd�D]�Zueud]kr�ed�qeeud^kr�dZtqeeneu�Zverd_d;�ereu�erd_d;�evjw�xEevjx�D]7Zyeyddd`krereyda�evjzeydbd�Z{e|e{jZ��Z{x�e{D]�\Z}Z~ee~ee
f�r{epe~�dckr{e~ddc�Z~ee~e
�rxxdddddddd#d$d&ddd'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6fD]Z�e�e�e~�krdeZ~Pq�Werdfe}e~�q8Wq�Wetr�erdg�x�evjx�D]{Zyerd_e�dhj�ey��d_didj�evj�ey�Z�e�e*kr�erdkevj�ey��evj�ey�nerdle��q:Wer�erdm�xCevj�D]8Z�e�dk	rerdne�j�e�j��e�j��f�q�Wer�evj��Z�e�j��er�evj��Z�erdoe��evj�dp�r�erdq�erdrevj�dp��erdsevj�dp��evj�dt�r�erdu�erdv�evj�r�x.evj�D]#\Z�Z�erdwe�joe�f�q�Wn
erdx�qeWdS)y�)�print_functionzPhilippe Lagadecz
2015-01-25z0.42bN�L��I�iz>Need to fix a bug with 32 bit arrays, please contact author...T�zutf-8FcCst|�dS)N)�print)�msg�r
�@/opt/alt/python35/lib64/python3.5/site-packages/PIL/OleFileIO.py�debug_printMsrcCsdS)Nr
)r	r
r
r�
debug_passQsr
cCs|a|rtantadS)zl
    Set debug mode on or off, to control display of debugging messages.
    :param mode: True or False
    N)�
DEBUG_MODEr�debugr
)Z
debug_moder
r
r�set_debug_modeXs	rs��ࡱ�l��l��l��l��l���������	�
���
������������������@�A�B�C�D�E�F�G�HiZVT_z$00020900-0000-0000-C000-000000000046�(icCs�t|d�r4|jtt��}|jd�nXt|t�rnt|�tkrn|dtt��}nt|d�jtt��}|tkr�dSdSdS)aH
    Test if a file is an OLE container (according to the magic bytes in its header).

    :param filename: string-like or file-like object, OLE file to parse

        - if filename is a string smaller than 1536 bytes, it is the path
          of the file to open. (bytes or unicode string)
        - if filename is a string longer than 1535 bytes, it is parsed
          as the content of an OLE file in memory. (bytes type only)
        - if filename is a file-like object (with read and seek methods),
          it is parsed as-is.

    :returns: True if OLE, False otherwise.
    �readrN�rbTF)	�hasattrr7�len�MAGIC�seek�
isinstance�bytes�MINIMAL_OLEFILE_SIZE�open)�filename�headerr
r
r�	isOleFile�s!rCcCs
t|�S)N)�ord)�cr
r
r�i8�srFcCs|jtkr|S|dS)Nr)�	__class__�int)rEr
r
rrF�scCs"tjd|||d��dS)z�
    Converts a 2-bytes (16 bits) string to an integer.

    c: string containing bytes to convert
    o: offset of bytes to convert in string
    z<Hrr)�struct�unpack)rE�or
r
r�i16�srLcCs"tjd|||d��dS)z�
    Converts a 4-bytes (32 bits) string to an integer.

    c: string containing bytes to convert
    o: offset of bytes to convert in string
    z<Irr)rIrJ)rErKr
r
r�i32�srMcCsd|jd�sdSdddt|d�t|d�t|d�fttt|dd	���S)
z^
    Converts a CLSID to a human-readable string.

    :param clsid: string of length 16.
    s�z%08X-%04X-%04X-%02X%02X-z%02Xrrrrr)�striprMrL�tuple�maprF)�clsidr
r
r�_clsid�s
	'rScCs6tjdddddd�}|tjd|d�S)zD
    convert FILETIME (64 bits int) to Python datetime.datetime
    iArr�microsecondsr)�datetime�	timedelta)Zfiletime�_FILETIME_null_dater
r
r�filetime2datetime�srXc@s�eZdZdZdddddddd	d
ddd
dddddddgZdddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0gZd1d2�Zd3d4�Zd5d6�Zd7S)8�OleMetadataaP
    class to parse and store metadata from standard properties of OLE files.

    Available attributes:
    codepage, title, subject, author, keywords, comments, template,
    last_saved_by, revision_number, total_edit_time, last_printed, create_time,
    last_saved_time, num_pages, num_words, num_chars, thumbnail,
    creating_application, security, codepage_doc, category, presentation_target,
    bytes, lines, paragraphs, slides, notes, hidden_slides, mm_clips,
    scale_crop, heading_pairs, titles_of_parts, manager, company, links_dirty,
    chars_with_spaces, unused, shared_doc, link_base, hlinks, hlinks_changed,
    version, dig_sig, content_type, content_status, language, doc_version

    Note: an attribute is set to None when not present in the properties of the
    OLE file.

    References for SummaryInformation stream:
    - https://msdn.microsoft.com/en-us/library/dd942545.aspx
    - https://msdn.microsoft.com/en-us/library/dd925819%28v=office.12%29.aspx
    - https://msdn.microsoft.com/en-us/library/windows/desktop/aa380376%28v=vs.85%29.aspx
    - https://msdn.microsoft.com/en-us/library/aa372045.aspx
    - http://sedna-soft.de/articles/summary-information-stream/
    - http://poi.apache.org/apidocs/org/apache/poi/hpsf/SummaryInformation.html

    References for DocumentSummaryInformation stream:
    - https://msdn.microsoft.com/en-us/library/dd945671%28v=office.12%29.aspx
    - https://msdn.microsoft.com/en-us/library/windows/desktop/aa380374%28v=vs.85%29.aspx
    - http://poi.apache.org/apidocs/org/apache/poi/hpsf/DocumentSummaryInformation.html

    new in version 0.25
    �codepage�title�subject�author�keywords�comments�template�
last_saved_by�revision_number�total_edit_time�last_printed�create_time�last_saved_time�	num_pages�	num_words�	num_chars�	thumbnail�creating_application�security�codepage_doc�category�presentation_targetr>�lines�
paragraphs�slides�notes�
hidden_slides�mm_clips�
scale_crop�
heading_pairs�titles_of_parts�manager�company�links_dirty�chars_with_spaces�unused�
shared_doc�	link_base�hlinks�hlinks_changed�version�dig_sig�content_type�content_status�language�doc_versioncCs�d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_	d|_
d|_d|_d|_
d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_ d|_!d|_"d|_#d|_$d|_%d|_&d|_'d|_(d|_)d|_*d|_+d|_,d|_-d|_.dS)z_
        Constructor for OleMetadata
        All attributes are set to None by default
        N)/rZr[r\r]r^r_r`rarbrcrdrerfrgrhrirjrkrlrmrnror>rprqrrrsrtrurvrwrxryrzr{r|r}r~rr�r�r�r�r�r�r�r�)�selfr
r
r�__init__>s^																																														zOleMetadata.__init__cCsx(|j|jD]}t||d�qW|jd�r�|jdddddg�}xJtt|j��D]3}|j|dd�}t||j||�qnW|jd�r|jddd�}xJtt|j��D]3}|j|dd�}t||j||�q�WdS)	a3
        Parse standard properties of an OLE file, from the streams
        "SummaryInformation" and "DocumentSummaryInformation",
        if present.
        Properties are converted to strings, integers or python datetime objects.
        If a property is not present, its value is set to None.
        NzSummaryInformation�convert_timeT�
no_conversionrrzDocumentSummaryInformation)�SUMMARY_ATTRIBS�DOCSUM_ATTRIBS�setattr�exists�
getproperties�ranger:�get)r��olefileZattrib�propsr�valuer
r
r�parse_propertiesus		zOleMetadata.parse_propertiescCs�td�x:|jD]/}t||�}td|t|�f�qWtd�x:|jD]/}t||�}td|t|�f�q[WdS)z<
        Dump all metadata, for debugging purposes.
        z*Properties from SummaryInformation stream:z- %s: %sz2Properties from DocumentSummaryInformation stream:N)rr��getattr�reprr�)r�Zpropr�r
r
r�dump�s

zOleMetadata.dumpN)	�__name__�
__module__�__qualname__�__doc__r�r�r�r�r�r
r
r
rrYs	7 rYc@s"eZdZdZdd�ZdS)�
_OleStreama�
    OLE2 Stream

    Returns a read-only file object which can be used to read
    the contents of a OLE stream (instance of the BytesIO class).
    To open a stream, use the openstream method in the OleFile class.

    This function can be used with either ordinary streams,
    or ministreams, depending on the offset, sectorsize, and
    fat table arguments.

    Attributes:

        - size: actual size of data stream, after it was opened.
    c
CsHtd�td|||||t|�t|�f�d}|dkrkt|�|}d}td�||d|}	td|	�|	t|�kr�td	��g}
|d
kr�|tkr�td�td��x�t|	�D]�}|tkr|rPntd
�td��|d
ks:|t|�krwtd||t|�f�td||	f�td��y|j|||�Wn3td|||||f�td��YnX|j|�}t|�|krZ|t|�dkrZtd|t|�||||t|�f�td|||t|��td��|
j|�y||d@}Wq�t	k
r�td��Yq�Xq�W|tkr�td��dj
|
�}
t|
�|kr�|
d|�}
||_n>|rt|
�|_n&tdt|
�|f�td��tj
j||
�dS)a
        Constructor for _OleStream class.

        :param fp: file object, the OLE container or the MiniFAT stream
        :param sect: sector index of first sector in the stream
        :param size: total size of the stream
        :param offset: offset in bytes for the first FAT or MiniFAT sector
        :param sectorsize: size of one sector
        :param fat: array/list of sector indexes (FAT or MiniFAT)
        :param filesize: size of OLE file (for debugging)
        :returns: a BytesIO instance containing the OLE stream
        z_OleStream.__init__:zE  sect=%d (%X), size=%d, offset=%d, sectorsize=%d, len(fat)=%d, fp=%sFi���Tz  stream with UNKNOWN SIZErznb_sectors = %dz(malformed OLE document, stream too largerz!size == 0 and sect != ENDOFCHAIN:z+incorrect OLE sector index for empty streamz$sect=ENDOFCHAIN before expected sizezincomplete OLE streamzsect=%d (%X) / len(fat)=%dzi=%d / nb_sectors=%dz,incorrect OLE FAT, sector index out of rangezsect=%d, seek=%d, filesize=%dzOLE sector index out of rangez9sect=%d / len(fat)=%d, seek=%d / filesize=%d, len read=%dzseek+len(read)=%dzincomplete OLE sectorl��z)incorrect last sector index in OLE stream�Nzlen(data)=%d, size=%dz%OLE stream size is less than declared)rr:r��IOError�
ENDOFCHAINr�r<r7�append�
IndexError�join�size�io�BytesIOr�)
r��fp�sectr��offset�
sectorsize�fat�filesizeZunknown_size�
nb_sectors�datarZsector_datar
r
rr��sl
)


(+ 

z_OleStream.__init__N)r�r�r�r�r�r
r
r
rr��sr�c@s�eZdZdZdZdZdd�Zdd�Zdd	�Zd
d�Z	dd
�Z
dd�Zdd�Zddd�Z
dd�Zdd�ZdS)�_OleDirectoryEntryz
    OLE2 Directory Entry
    z<64sHBBIII16sIQQIII�c
Cs�||_||_g|_i|_d|_tjtj|�\}}|_	|_
|_|_|_
}|_|_|_|_}}|j	ttttgkr�|jtd�|j	tkr�|dkr�|jtd�|dkr|j	tkr|jtd�|dkr*|jtd�d}|d|d	�}|j|�|_td
|jt|j�f�td|j	�td|j�td
|j|j|j
f�|jdkr|dkr|dkrtd|j|||f�|jtd�||_n|t|�d>|_td|j||f�t |�|_!|j	tkr�|jdkr�|jt"d�|j	ttfkr�|jdkr�|j|j#kr�|j	tkr�d}	nd}	|j$|j|	�dS)aJ
        Constructor for an _OleDirectoryEntry object.
        Parses a 128-bytes entry from the OLE Directory stream.

        :param entry  : string (must be 128 bytes long)
        :param sid    : index of this directory entry in the OLE file directory
        :param olefile: OleFileIO containing this directory entry
        Fzunhandled OLE storage typerzduplicate OLE root entryzincorrect OLE root entryr-zincorrect DirEntry name lengthNrzDirEntry SID=%d: %sz - type: %dz - sect: %dz% - SID left: %d, right: %d, child: %dil��z+sectorsize=%d, sizeLow=%d, sizeHigh=%d (%X)zincorrect OLE stream size� z% - size: %d (sizeLow=%d, sizeHigh=%d)zOLE storage with size>0T)%�sidr��kids�	kids_dict�usedrIrJr��STRUCT_DIRENTRY�
entry_typeZcolor�sid_left�	sid_right�	sid_childZdwUserFlags�
createTime�
modifyTime�
isectStart�
STGTY_ROOT�
STGTY_STORAGE�STGTY_STREAM�STGTY_EMPTY�raise_defect�DEFECT_INCORRECT�_decode_utf16_str�namerr�r��
DEFECT_UNSUREr��longrSrR�DEFECT_POTENTIAL�minisectorcutoff�_check_duplicate_stream)
r��entryr�r�r�Z
namelengthrRZsizeLowZsizeHigh�minifatr
r
rr�GsN						Z $	z_OleDirectoryEntry.__init__cCsVtd|jt|j�|jf�|jtkrR|j|j�|jj�dS)z�
        Read and build the red-black tree attached to this _OleDirectoryEntry
        object, if it is a storage.
        Note that this method builds a tree of all subentries, so it should
        only be called for the root object once.
        z.build_storage_tree: SID=%d - %s - sid_child=%dN)	rr�r�r�r��NOSTREAM�append_kidsr��sort)r�r
r
r�build_storage_tree�s
 	z%_OleDirectoryEntry.build_storage_treecCs,|tkrdS|dks4|t|jj�krG|jjtd�|jj|�}td|jt	|j
�|j|j|j
f�|j|j�|j
j�}||jkr�|jjtd�|jj|�||j|<|jr|jjtd�d|_|j|j�|j�dS)a*
        Walk through red-black tree of children of this directory entry to add
        all of them to the kids list. (recursive method)

        :param child_sid : index of child directory entry to use, or None when called
            first time for the root. (only used during recursion)
        NrzOLE DirEntry index out of rangezHappend_kids: child_sid=%d - %s - sid_left=%d, sid_right=%d, sid_child=%dz!Duplicate filename in OLE storagez#OLE Entry referenced more than onceT)r�r:r��
direntriesr��DEFECT_FATAL�_load_direntryrr�r�r�r�r�r�r��lowerr�r�r�r�r�r�)r�Z	child_sidZchildZ
name_lowerr
r
rr��s($,
		z_OleDirectoryEntry.append_kidscCs|j|jkS)zCompare entries by name)r�)r��otherr
r
r�__eq__�sz_OleDirectoryEntry.__eq__cCs|j|jkS)zCompare entries by name)r�)r�r�r
r
r�__lt__�sz_OleDirectoryEntry.__lt__cCs|j|�S)N)r�)r�r�r
r
r�__ne__�sz_OleDirectoryEntry.__ne__cCs|j|�p|j|�S)N)r�r�)r�r�r
r
r�__le__�sz_OleDirectoryEntry.__le__rcCs�ddddddg}td|t|j�||jdd�|jttfkrnt|jd	dd�t�|jttfkr�|jr�td|d
|j�x"|j	D]}|j
|d�q�WdS)
zADump this entry, and all its subentries (for debug purposes only)z	(invalid)z	(storage)z(stream)z(lockbytes)z
(property)z(root)� �endr>z{%s}rN)rr�r�r�r�r�r�r�rRr�r�)r��tabZTYPES�kidr
r
rr��s+z_OleDirectoryEntry.dumpcCs |jdkrdSt|j�S)z�
        Return modification time of a directory entry.

        :returns: None if modification time is null, a python datetime object
            otherwise (UTC timezone)

        new in version 0.26
        rN)r�rX)r�r
r
r�getmtime	s	z_OleDirectoryEntry.getmtimecCs |jdkrdSt|j�S)z�
        Return creation time of a directory entry.

        :returns: None if modification time is null, a python datetime object
            otherwise (UTC timezone)

        new in version 0.26
        rN)r�rX)r�r
r
r�getctimes	z_OleDirectoryEntry.getctimeN)r�r�r�r�r�Z
DIRENTRY_SIZEr�r�r�r�r�r�r�r�r�r�r
r
r
rr�)s_+
r�c@s�eZdZdZdeddedd�Zedd�Zdd	d
�Z	ddd�Z
d
d�Zddd�Zddd�Z
ddd�Zdd�Zdd�Zdd�Zdd�Zdd�Zd d!d"�Zd#d$�Zd%d&�Zd'd(�Zd)dd*d+�Zd,dd-d.�Zd,dd/d0�Zd1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!d?d@�Z"dAdB�Z#dddCdD�Z$dEdF�Z%dS)G�	OleFileIOa�
    OLE container object

    This class encapsulates the interface to an OLE 2 structured
    storage file.  Use the :py:meth:`~PIL.OleFileIO.OleFileIO.listdir` and
    :py:meth:`~PIL.OleFileIO.OleFileIO.openstream` methods to
    access the contents of this file.

    Object names are given as a list of strings, one for each subentry
    level.  The root entry should be omitted.  For example, the following
    code extracts all image streams from a Microsoft Image Composer file::

        ole = OleFileIO("fan.mic")

        for entry in ole.listdir():
            if entry[1:2] == "Image":
                fin = ole.openstream(entry)
                fout = open(entry[0:1], "wb")
                while True:
                    s = fin.read(8192)
                    if not s:
                        break
                    fout.write(s)

    You can use the viewer application provided with the Python Imaging
    Library to view the resulting files (which happens to be standard
    TIFF files).
    NFcCs]t|�||_g|_||_||_d|_d|_|rY|j|d|�dS)a�
        Constructor for the OleFileIO class.

        :param filename: file to open.

            - if filename is a string smaller than 1536 bytes, it is the path
              of the file to open. (bytes or unicode string)
            - if filename is a string longer than 1535 bytes, it is parsed
              as the content of an OLE file in memory. (bytes type only)
            - if filename is a file-like object (with read, seek and tell methods),
              it is parsed as-is.

        :param raise_defects: minimal level for defects to be raised as exceptions.
            (use DEFECT_FATAL for a typical application, DEFECT_INCORRECT for a
            security-oriented application, see source code for details)

        :param write_mode: bool, if True the file is opened in read/write mode instead
            of read-only by default.

        :param debug: bool, set debug mode

        :param path_encoding: None or str, name of the codec to use for path
            names (streams and storages), or None for Unicode.
            Unicode by default on Python 3+, UTF-8 on Python 2.x.
            (new in olefile 0.42, was hardcoded to Latin-1 until olefile v0.41)
        N�
write_mode)r�_raise_defects_level�parsing_issuesr��
path_encoding�	_filesizer�r@)r�rAZ
raise_defectsr�rr�r
r
rr�Ds
						zOleFileIO.__init__cCs8||jkr||��n|jj||f�dS)a�
        This method should be called for any defect found during file parsing.
        It may raise an IOError exception according to the minimal level chosen
        for the OleFileIO object.

        :param defect_level: defect level, possible values are:

            - DEFECT_UNSURE    : a case which looks weird, but not sure it's a defect
            - DEFECT_POTENTIAL : a potential defect
            - DEFECT_INCORRECT : an error according to specifications, but parsing can go on
            - DEFECT_FATAL     : an error which cannot be ignored, parsing is impossible

        :param message: string describing the defect, used with raised exception.
        :param exception_type: exception class to be raised, IOError by default
        N)r�r�r�)r�Zdefect_level�messageZexception_typer
r
rr�mszOleFileIO.raise_defect�replacecCs6|jd|�}|jr.|j|j|�S|SdS)a�
        Decode a string encoded in UTF-16 LE format, as found in the OLE
        directory or in property streams. Return a string encoded
        according to the path_encoding specified for the OleFileIO object.

        :param utf16_str: bytes string encoded in UTF-16 LE format
        :param errors: str, see python documentation for str.decode()
        :return: str, encoded according to path_encoding
        zUTF-16LEN)�decoder��encode)r�Z	utf16_str�errorsZunicode_strr
r
rr��s
	zOleFileIO._decode_utf16_strc	Cs�||_t|d�r$||_n`t|t�rZt|�tkrZtj|�|_n*|jrld}nd}t	||�|_d}|jj
dtj�z|jj
�}Wd|jj
d�X||_g|_g|_|jjd�}t|�dks|dd�tkr,|jtd�d	}tj|�}td
||d/f�|d|�}tj||�\|_|_|_|_|_|_|_|_ |_!|_"|_#|_$|_%|_&|_'|_(|_)|_*ttj||��|jtkr|jtd
�|jt+d�krA|jt,d�td|j�td|j�|jd0kr�|jt,d�td|j�|jdkr�|jtd�d|j|_-td|j-�|j-d1kr�|jt,d�|jdkr|j-dks.|jdkr>|j-dkr>|jt,d�d|j|_.td|j.�|j.d2kr~|jt,d�|j dks�|j!dkr�|jt,d�td |j"�|j-dkr�|j"dkr�|jt,d!�td"|j#�td#|j$�td$|j%�|j%dkr=|jt/d%�td&|j&�|j&dkrm|jt,d'�td(|j'�td)|j(�td*|j)�td+|j*�||j-d,|j-d,|_0td-|j0�t1|dd.��|_|j-|_2|j.|_3|j&|_4|j5|j$�|j(rG|j5|j'�|j*r`|j5|j)�|j6|�|j7|j$�d|_8|j'|_9dS)3a�
        Open an OLE2 file in read-only or read/write mode.
        Read and parse the header, FAT and directory.

        :param filename: string-like or file-like object, OLE file to parse

            - if filename is a string smaller than 1536 bytes, it is the path
              of the file to open. (bytes or unicode string)
            - if filename is a string longer than 1535 bytes, it is parsed
              as the content of an OLE file in memory. (bytes type only)
            - if filename is a file-like object (with read, seek and tell methods),
              it is parsed as-is.

        :param write_mode: bool, if True the file is opened in read/write mode instead
            of read-only by default. (ignored if filename is not a path)
        r7zr+br8rN�rz#not an OLE2 structured storage filez<8s16sHHHHHHLLLLLLLLLLzfmt_header size = %d, +FAT = %d�mrzincorrect OLE signaturerzincorrect CLSID in OLE headerzMinorVersion = %dzDllVersion   = %drz"incorrect DllVersion in OLE headerzByteOrder    = %Xi��z!incorrect ByteOrder in OLE headerrzSectorSize   = %d�z"incorrect SectorSize in OLE headerz2SectorSize does not match DllVersion in OLE headerzMiniSectorSize   = %dr-z&incorrect MiniSectorSize in OLE headerz.incorrect OLE header (non-null reserved bytes)zcsectDir     = %dz incorrect csectDir in OLE headerzcsectFat     = %dzsectDirStart = %Xzsignature    = %dz"incorrect OLE header (signature>0)zMiniSectorCutoff = %dz(incorrect MiniSectorCutoff in OLE headerzMiniFatStart     = %XzcsectMiniFat     = %dzsectDifStart     = %XzcsectDif         = %drz!Number of sectors in the file: %dr%i�)rr)r�r�)r-):r�r9r�r=r>r:r?r�r�r@r<�os�SEEK_END�tellr��_used_streams_fat�_used_streams_minifatr7r;r�r�rIZcalcsizerrJZSigrRZMinorVersionZ
DllVersionZ	ByteOrderZSectorShiftZMiniSectorShiftZReservedZ	Reserved1ZcsectDir�csectFatZsectDirStartZ	signatureZMiniSectorCutoffZMiniFatStart�csectMiniFat�sectDifStart�csectDif�	bytearrayr��
SectorSize�MiniSectorSizer��nb_sectrSr��minisectorsizer�r��loadfat�
loaddirectory�
ministream�minifatsect)	r�rAr��moder�rBZ
fmt_headerZheader_sizeZheader1r
r
rr@�s�	!					('~		
	zOleFileIO.opencCs|jj�dS)z@
        close the OLE file, to release the file object
        N)r��close)r�r
r
rrmszOleFileIO.closecCs�|r td|�|j}n3td|�|ttttfkrJdS|j}||krr|jtd�n
|j	|�dS)ag
        Checks if a stream has not been already referenced elsewhere.
        This method should only be called once for each known stream, and only
        if stream size is not null.

        :param first_sect: int, index of first sector of the stream in FAT
        :param minifat: bool, if True, stream is located in the MiniFAT, else in the FAT
        z+_check_duplicate_stream: sect=%d in MiniFATz'_check_duplicate_stream: sect=%d in FATNzStream referenced twice)
rr��DIFSECT�FATSECTr��FREESECTr�r�r�r�)r�Z
first_sectr�Zused_streamsr
r
rr�ss		z!OleFileIO._check_duplicate_streamrc
Cs]ts
dSd}tdtdtdtdi}t|�}||d|}tdd	d
�x(t|�D]}td|d	d
�qiWt�x�t|�D]�}||}	td||	d	d
�x�t|	|	|�D]s}||kr�P||}
|
d
@}||kr||}n#|
|dkr0d}n
d|
}t|d	d
�q�Wt�q�WdS)zCDisplays a part of FAT in human-readable form for debugging purposeNrz..free..z[ END. ]zFATSECT zDIFSECT r�indexr�r�z%8Xz%8X:l��z    --->)rrr�rrr:rr�)
r�r��
firstindex�VPLZfatnames�nbsect�nlinesr�lrr�Zauxr�r
r
r�dumpfat�s8



	
zOleFileIO.dumpfatcCs.ts
dSd}tjt|�}tjdkr;|j�t|�}||d|}tddd�x(t|�D]}td|dd�qvWt�x�t|�D]~}||}	td	||	dd�xLt|	|	|�D]7}||kr�P||}
d|
}t|dd�q�Wt�q�WdS)
zBDisplays a sector in a human-readable form, for debugging purpose.Nr�bigrrr�r�z%8Xz%8X:)	r�array�UINT32�sys�	byteorder�byteswapr:rr�)r��sectorrrr�r	r
rrrr�r�r
r
r�dumpsect�s,



zOleFileIO.dumpsectcCs/tjt|�}tjdkr+|j�|S)z�
        convert a sector to an array of 32 bits unsigned integers,
        swapping bytes on big endian CPUs such as PowerPC (old Macs)
        r
)rrrrr)r�r��ar
r
r�
sect2array�s
zOleFileIO.sect2arraycCs�t|tj�r|}n|j|�}|j|�xw|D]o}|d@}td|�|tkst|tkrtd�P|j|�}|j|�}|j||_q>W|S)z�
        Adds the indexes of the given sector to the FAT

        :param sect: string containing the first FAT sector, or array of long integers
        :returns: index of last FAT sector.
        l��z
isect = %Xzfound end of sector chain)	r=rrrrr�r�getsectr�)r�r�Zfat1Zisect�sZnextfatr
r
r�loadfat_sect�s	



zOleFileIO.loadfat_sectc	Cs|dd�}tdt|�t|�df�tjt�|_|j|�|jdkr�|jdkr�|jt	d�|j
|jkr�|jtd�td	�|j
dd
}|jd|d
|}td|�|j|krtd��|j
}x�t|�D]t}td
||f�|j|�}|j|�}|j|�|j|d|��||}td|�qW|ttgkr�td��t|j�|jkr�tdt|j�|jf�|jd|j�|_td�|j|j�dS)z%
        Load the FAT table.
        �Lizlen(sect)=%d, so %d integersrrr�z#incorrect DIFAT, not enough sectorsz)incorrect DIFAT, first index out of rangezDIFAT analysis...rz
nb_difat = %dzincorrect DIFATzDIFAT block %d, sector %XNznext DIFAT sector: %Xzincorrect end of DIFATz!len(fat)=%d, shrunk to nb_sect=%dz
FAT:)rr:rrr�rr�r�r�r�r�r�r�r�r��	iterrangerrrr�rr)	r�rBr�Znb_difat_sectorsZnb_difatZisect_difatrZsector_difatZdifatr
r
rr��s>	$

	

 
zOleFileIO.loadfatcCs|j|j}|jj|jd|j}|d}td|j|j|||f�||krw|jtd�|j	|j|dd�j
�}|j|�|_tdt
|j�|f�|jd|�|_td	t
|j��td
�|j|j�dS)z)
        Load the MiniFAT table.
        rrzaloadminifat(): minifatsect=%d, nb FAT sectors=%d, used_size=%d, stream_size=%d, nb MiniSectors=%dz%OLE MiniStream is larger than MiniFAT�	force_FATTz$MiniFAT shrunk from %d to %d sectorsNzloadminifat(): len=%dz	
MiniFAT:)r�r��rootr�r�rrr�r��_openr7rr�r:r)r�Zstream_sizeZnb_minisectorsZ	used_sizerr
r
r�loadminifat>s
!
zOleFileIO.loadminifatcCs�y|jj|j|d�Wn=td||j|d|jf�|jtd�YnX|jj|j�}t|�|jkr�td|t|�|jf�|jtd�|S)z�
        Read given sector from file on disk.

        :param sect: int, sector index
        :returns: a string containing the sector data.
        rz(getsect(): sect=%X, seek=%d, filesize=%dzOLE sector index out of rangez*getsect(): sect=%X, read=%d, sectorsize=%dzincomplete OLE sector)	r�r<r�rr�r�r�r7r:)r�r�rr
r
rr`szOleFileIO.getsectscCst|t�std��t|t�s=t|�dkrItd��y|jj|j|d�Wn=td||j|d|jf�|j	t
d�YnXt|�|jkr�|||jt|�7}n!t|�|jkr�td��|jj|�dS)z�
        Write given sector to file on disk.

        :param sect: int, sector index
        :param data: bytes, sector data
        :param padding: single byte, padding character if data < sector size
        z'write_sect: data must be a bytes stringrz4write_sect: padding must be a bytes string of 1 charz+write_sect(): sect=%X, seek=%d, filesize=%dzOLE sector index out of rangezData is larger than sector sizeN)
r=r>�	TypeErrorr:r�r<r�rr�r�r��
ValueError�write)r�r�r�Zpaddingr
r
r�
write_sects"zOleFileIO.write_sectcCs||j|�|_|jjd}td|jj|f�dg||_|jd�}|jd|_|jj�dS)z]
        Load the directory.

        :param sect: sector index of directory stream.
        r�z&loaddirectory: size=%d, max_entries=%dNr)r�directory_fpr�rr�r�rr�)r�r�Zmax_entriesZ
root_entryr
r
rr��szOleFileIO.loaddirectorycCs�|dks!|t|j�kr1|jtd�|j|dk	r_|jtd�|j|S|jj|d�|jjd�}t|||�|j|<|j|S)aZ
        Load a directory entry from the directory.
        This method should only be called once for each storage/stream when
        loading the directory.

        :param sid: index of storage/stream in the directory.
        :returns: a _OleDirectoryEntry object

        :exception IOError: if the entry has always been referenced.
        rz OLE directory index out of rangeNz'double reference for OLE stream/storager�)	r:r�r�r�r�r$r<r7r�)r�r�r�r
r
rr��s!	zOleFileIO._load_direntrycCs|jj�dS)z5
        Dump directory (for debugging only)
        N)rr�)r�r
r
r�
dumpdirectory�szOleFileIO.dumpdirectoryi���cCstd||t|�f�||jkr�|r�|js�|j�|jj}td|jj|f�|j|jj|dd�|_t	d|jd|d|dd	d
|j
d|jd|jj�St	d|jd|d|d|j
d
|j
d|jd|j�Sd
S)a|
        Open a stream, either in FAT or MiniFAT according to its size.
        (openstream helper)

        :param start: index of first sector
        :param size: size of stream (or nothing if size is unknown)
        :param force_FAT: if False (default), stream will be opened in FAT or MiniFAT
            according to size. If True, it will always be opened in FAT.
        z0OleFileIO.open(): sect=%d, size=%d, force_FAT=%sz$Opening MiniStream: sect=%d, size=%drTr�r�r�r�rr�r�r�N)r�strr�r�rrr�r�rr�r�r�r�r�r�r�)r��startr�rZsize_ministreamr
r
rr�s"
	
	zOleFileIO._openTcCs�||jg}x�|jD]�}|jtkrr|rV|j|dd�|jg�|j|||||�q|jtkr�|r�|j|dd�|jg�q|jtd�qWdS)a�
        listdir helper

        :param files: list of files to fill in
        :param prefix: current location in storage tree (list of names)
        :param node: current node (_OleDirectoryEntry object)
        :param streams: bool, include streams if True (True by default) - new in v0.26
        :param storages: bool, include storages if True (False by default) - new in v0.26
            (note: the root storage is never included)
        rNzIThe directory tree contains an entry which is not a stream nor a storage.)	r�r�r�r�r��_listr�r�r�)r��files�prefix�node�streams�storagesr�r
r
rr(�s!$zOleFileIO._listcCs&g}|j|g|j||�|S)am
        Return a list of streams and/or storages stored in this file

        :param streams: bool, include streams if True (True by default) - new in v0.26
        :param storages: bool, include storages if True (False by default) - new in v0.26
            (note: the root storage is never included)
        :returns: list of stream and/or storage paths
        )r(r)r�r,r-r)r
r
r�listdirs	zOleFileIO.listdircCs�t|t�r|jd�}|j}xP|D]H}x9|jD]"}|jj�|j�kr>Pq>Wtd��|}q.W|jS)a*
        Returns directory entry of given filename. (openstream helper)
        Note: this method is case-insensitive.

        :param filename: path of stream in storage tree (except root entry), either:

            - a string using Unix path syntax, for example:
              'storage_1/storage_1.2/stream'
            - or a list of storage filenames, path to the desired stream/storage.
              Example: ['storage_1', 'storage_1.2', 'stream']

        :returns: sid of requested filename
        :exception IOError: if file not found
        �/zfile not found)	r=�
basestring�splitrr�r�r�r�r�)r�rAr+r�r�r
r
r�_find's	

zOleFileIO._findcCsM|j|�}|j|}|jtkr7td��|j|j|j�S)a;
        Open a stream as a read-only file object (BytesIO).
        Note: filename is case-insensitive.

        :param filename: path of stream in storage tree (except root entry), either:

            - a string using Unix path syntax, for example:
              'storage_1/storage_1.2/stream'
            - or a list of storage filenames, path to the desired stream/storage.
              Example: ['storage_1', 'storage_1.2', 'stream']

        :returns: file object (read-only)
        :exception IOError: if filename not found, or if this is not a stream.
        zthis file is not a stream)r2r�r�r�r�rr�r�)r�rAr�r�r
r
r�
openstreamFs

zOleFileIO.openstreamc
Cs�t|t�std��|j|�}|j|}|jtkrRtd��|j}|t	|�kryt
d��||jkr�td��|j
}||jd|j}td|�x�t|�D]�}||dkr|||j|d|j�}	nA|||jd�}	td||jt	|	�||jf�|j||	�y|j|}Wq�tk
r�td	��Yq�Xq�W|tkr�td
��dS)aD
        Write a stream to disk. For now, it is only possible to replace an
        existing stream by data of the same size.

        :param stream_name: path of stream in storage tree (except root entry), either:

            - a string using Unix path syntax, for example:
              'storage_1/storage_1.2/stream'
            - or a list of storage filenames, path to the desired stream/storage.
              Example: ['storage_1', 'storage_1.2', 'stream']

        :param data: bytes, data to be written, must be the same size as the original
            stream.
        z)write_stream: data must be a bytes stringzthis is not a streamz?write_stream: data must be the same size as the existing streamz2Writing a stream in MiniFAT is not implemented yetrznb_sectors = %dNzFwrite_stream: size=%d sectorsize=%d data_sector=%d size%%sectorsize=%dz,incorrect OLE FAT, sector index out of rangez)incorrect last sector index in OLE stream)r=r>r r2r�r�r�r�r�r:r!r��NotImplementedErrorr�r�rr�r#r�r�r�)
r�Zstream_namer�r�r�r�r�r�rZdata_sectorr
r
r�write_stream[s8
		"$
zOleFileIO.write_streamc	Cs:y'|j|�}|j|}|jSWndSYnXdS)a�
        Test if given filename exists as a stream or a storage in the OLE
        container, and return its type.

        :param filename: path of stream in storage tree. (see openstream for syntax)
        :returns: False if object does not exist, its entry type (>0) otherwise:

            - STGTY_STREAM: a stream
            - STGTY_STORAGE: a storage
            - STGTY_ROOT: the root entry
        FN)r2r�r�)r�rAr�r�r
r
r�get_type�s
zOleFileIO.get_typecCs&|j|�}|j|}|j�S)a9
        Return modification time of a stream/storage.

        :param filename: path of stream/storage in storage tree. (see openstream for
            syntax)
        :returns: None if modification time is null, a python datetime object
            otherwise (UTC timezone)

        new in version 0.26
        )r2r�r�)r�rAr�r�r
r
rr��s
zOleFileIO.getmtimecCs&|j|�}|j|}|j�S)a1
        Return creation time of a stream/storage.

        :param filename: path of stream/storage in storage tree. (see openstream for
            syntax)
        :returns: None if creation time is null, a python datetime object
            otherwise (UTC timezone)

        new in version 0.26
        )r2r�r�)r�rAr�r�r
r
rr��s
zOleFileIO.getctimec	Cs*y|j|�}dSWndSYnXdS)a
        Test if given filename exists as a stream or a storage in the OLE
        container.
        Note: filename is case-insensitive.

        :param filename: path of stream in storage tree. (see openstream for syntax)
        :returns: True if object exist, else False.
        TFN)r2)r�rAr�r
r
rr��s
	zOleFileIO.existscCs>|j|�}|j|}|jtkr7td��|jS)a2
        Return size of a stream in the OLE container, in bytes.

        :param filename: path of stream in storage tree (see openstream for syntax)
        :returns: size in bytes (long integer)
        :exception IOError: if file not found
        :exception TypeError: if this is not a stream.
        zobject is not an OLE stream)r2r�r�r�r r�)r�rAr�r�r
r
r�get_size�s
	
zOleFileIO.get_sizecCs
|jjS)zp
        Return root entry name. Should usually be 'Root Entry' or 'R' in most
        implementations.
        )rr�)r�r
r
r�get_rootentry_name�szOleFileIO.get_rootentry_namec CsI|dkrg}|}t|t�s6dj|�}|j|�}i}y�|jd�}t|dd��}|jd�}t|dd��}	|jt|d��d|jt|jd	��d	�}t|d	�}
WnXtk
r>}z8d
t	|�|f}|j
t||
|��|SWYdd}~XnXxt|
�D]�}y�d}t|d|d�}t|d|d�}t||�}
t
d
||
|f�|
tkr�t||d	�}|dkr�|d}n�|
tkr	t||d	�}n�|
tttfkr4t||d	�}n�|
ttfkr\t||d	�}n�|
ttfkr�t||d	�}||d|d|d�}|jdd�}n&|
tkr�t||d	�}||d|d|�}n�|
tkr?t||d	�}|j||d|d|d��}n�|
tkrtt||d	��tt||d��d>}|r�||kr�t
d||t|�df�tjdddddd�}t
d|d!�|tj d|d�}q�|d}n�|
t!kr/t"||d	�}n�|
t#kr\t||d	|d��}n�|
t$kr�t||d	�}||d|d|�}nB|
t%kr�t&t||d	��}nd}t
d||
f�|||<WqLtk
r@}z7d|t	|�|f}|j
t||
|��WYdd}~XqLXqLW|S)"a�
        Return properties described in substream.

        :param filename: path of stream in storage tree (see openstream for syntax)
        :param convert_time: bool, if True timestamps will be converted to Python datetime
        :param no_conversion: None or list of int, timestamps not to be converted
                              (for example total editing time is not a real timestamp)

        :returns: a dictionary of values indexed by id (integer)
        Nr/r)rr%r!rs****rz6Error while parsing properties header in stream %s: %srrz!property id=%d: type=%d offset=%Xi�irsr�rr�z8Converting property #%d to python datetime, value=%d=%fsi���iAztimedelta days=%dri@BirTz5property id=%d: type=%d not implemented in parser yetz3Error while parsing property id %d in stream %s: %si���lh�C!l@�T$)'r=r&r�r3r7rSr<rM�
BaseExceptionr�r�r�r�r�VT_I2rL�VT_UI2�VT_I4�VT_INT�VT_ERROR�VT_UI4�VT_UINT�VT_BSTR�VT_LPSTRr��VT_BLOB�	VT_LPWSTRr��VT_FILETIMEr��floatrUrV�VT_UI1rF�VT_CLSID�VT_CF�VT_BOOL�bool)r�rAr�r�Z
streampathr�r�rrRZfmtidZ	num_props�excr	�typer�idr�r��countrWr
r
rr��s�
&
 ,4
!0zOleFileIO.getpropertiescCs#t�|_|jj|�|jS)z�
        Parse standard properties streams, return an OleMetadata object
        containing all the available metadata.
        (also stored in the metadata attribute of the OleFileIO object)

        new in version 0.25
        )rYZmetadatar�)r�r
r
r�get_metadata�szOleFileIO.get_metadata)&r�r�r�r�r��DEFAULT_PATH_ENCODINGr�r�r�r�r@rr�rrrrr�rrr#r�r�r%rr(r.r2r3r5r6r�r�r�r7r8r�rPr
r
r
rr�&sB(�%J"##
<�r��__main__zolefile version %s %s - %sa@
Launched from the command line, this script parses OLE files and prints info.

Usage: olefile.py [-d] [-c] <file> [file2 ...]

Options:
-d : debug mode (displays a lot of debug information, for developers only)
-c : check all streams (for debugging purposes)

For more information, see http://www.decalage.info/olefile
z-dz-c�-�z: propertiesr��2�z
(binary data)z   z
Checking streams...r/r�r�zsize %dzNOT a stream : type=%dz5Modification/Creation times of all directory entries:z- %s: mtime=%s ctime=%szRoot entry name: "%s"ZworddocumentzThis is a Word document.ztype of stream 'WordDocument':zsize :z
macros/vbaz%This document may contain VBA macros.z(
Non-fatal issues raised during parsing:z- %s: %s�None)�Z
__future__r�
__author__Z__date__�__version__r�rrIrZos.pathr�rUr&r>rHr�Zxrangerr��itemsizerr!r0�	NameErrorZKEEP_UNICODE_NAMES�version_inforQrrr
rrr;Z
MAXREGSECTrrr�rZ	MAXREGSIDr�r�r�r�ZSTGTY_LOCKBYTESZSTGTY_PROPERTYr�ZVT_EMPTYZVT_NULLr:r<ZVT_R4ZVT_R8ZVT_CYZVT_DATErAZVT_DISPATCHr>rJZ
VT_VARIANTZ
VT_UNKNOWNZ
VT_DECIMALZVT_I1rGr;r?ZVT_I8ZVT_UI8r=r@ZVT_VOIDZ
VT_HRESULTZVT_PTRZVT_SAFEARRAYZ	VT_CARRAYZVT_USERDEFINEDrBrDrErCZ	VT_STREAMZ
VT_STORAGEZVT_STREAMED_OBJECTZVT_STORED_OBJECTZVT_BLOB_OBJECTrIrHZ	VT_VECTORZVT�list�vars�items�keyword�varZ
WORD_CLSIDr�r�r�r�r?rCrFrLrMrSrX�objectrYr�r�r�r�r�r:�argvr�exitZ
check_streamsrAZoler%r.Z
streamnamer�r��sorted�k�vr=rEr�r�r�r6Zst_typer7r3r�r�r�r�r�rP�metar�r8rr�r��exctyper	r
r
r
r�<module>sn�	
			
		"
!


�������r




3+
%