§
    6³–[_› ã                   óœ  — d Z ddlmZ dZdZdZg d¢ZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZeeureZ	 eZn	#  eZY nxY w e
j
        d¦  «        j        d	k    rdZnC e
j
        d
¦  «        j        d	k    rd
Zn' e
j
        d¦  «        j        d	k    rdZn ed¦  «        ‚	 e n# e$ r eZY nw xY wdZej        d         dk     rdZndZej        dz   fd„Z ed¦  «        Z d„ Z!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,dZ-d	Z.dZ/dZ0dZ1dZ2dZ3dZ4d	Z5dZ6dZ7dZ8dZ9d Z:d!Z;d"Z<d#Z=d$Z>d%Z?d&Z@d'ZAd(ZBd)ZCd*ZDd+ZEd,ZFd-ZGd.ZHd/ZId0ZJd1ZKd2ZLd3ZMd4ZNd5ZOd6ZPd7ZQd8ZRd9ZSd:ZTd;ZUd<ZVd=ZWd>ZXd?ZYd@ZZd!Z[d*Z\d4Z]dAZ^dBZ_dC„ Z`eeu rdD„ ZandE„ ZadTdF„ZbdTdG„ZcdH„ ZddI„ Ze G dJ„ dK¦  «        Zf G dL„ dMejg        ¦  «        Zh G dN„ dO¦  «        Zi G dP„ dQ¦  «        ZjdR„ ZkeldSk    r ek¦   «          dS dS )Ua:  
olefile (formerly OleFileIO_PL)

Module to read/write Microsoft OLE2 files (also called Structured Storage or
Microsoft Compound Document File Format), such as Microsoft Office 97-2003
documents, Image Composer and FlashPix files, Outlook messages, ...
This version is compatible with Python 2.7 and 3.4+

Project website: https://www.decalage.info/olefile

olefile is copyright (c) 2005-2018 Philippe Lagadec
(https://www.decalage.info)

olefile is based on the OleFileIO module from the PIL library v1.1.7
See: http://www.pythonware.com/products/pil/index.htm
and http://svn.effbot.org/public/tags/pil-1.1.7/PIL/OleFileIO.py

The Python Imaging Library (PIL) is
Copyright (c) 1997-2009 by Secret Labs AB
Copyright (c) 1995-2009 by Fredrik Lundh

See source code and LICENSE.txt for information on usage and redistribution.
é    )Úprint_functionz
2018-09-09z0.46zPhilippe Lagadec)Ú	isOleFileÚ	OleFileIOÚOleMetadataÚenable_loggingÚMAGICÚSTGTY_EMPTYÚKEEP_UNICODE_NAMESÚSTGTY_STREAMÚSTGTY_STORAGEÚ
STGTY_ROOTÚSTGTY_PROPERTYÚSTGTY_LOCKBYTESÚMINIMAL_OLEFILE_SIZEÚDEFECT_UNSUREÚDEFECT_POTENTIALÚDEFECT_INCORRECTÚDEFECT_FATALÚDEFAULT_PATH_ENCODINGÚ
MAXREGSECTÚDIFSECTÚFATSECTÚ
ENDOFCHAINÚFREESECTÚ	MAXREGSIDÚNOSTREAMÚUNKNOWN_SIZEÚ
WORD_CLSIDNÚLé   ÚIÚiz>Need to fix a bug with 32 bit arrays, please contact author...Té   zutf-8é   c                 ó*  — | t           j        j        j        v r+t          j        | ¦  «        }|                     |¦  «         |S t          j        | ¦  «        }|                     t          j        ¦   «         ¦  «         |                     |¦  «         |S )an  
    Create a suitable logger object for this module.
    The goal is not to change settings of the root logger, to avoid getting
    other modules' logs on the screen.
    If a logger exists with same name, reuse it. (Else it would have duplicate
    handlers and messages would be doubled.)
    The level is set to CRITICAL+1 by default, to avoid any logging.
    )ÚloggingÚLoggerÚmanagerÚ
loggerDictÚ	getLoggerÚsetLevelÚ
addHandlerÚNullHandler)ÚnameÚlevelÚloggers      ú1/usr/lib/python3/dist-packages/olefile/olefile.pyÚ
get_loggerr2   ¦   s†   € ð �wŒ~Ô%Ô0Ð0Ð0õ Ô" 4Ñ(Ô(ˆà�Š˜ÑÔÐØˆåÔ˜tÑ$Ô$€Fð ×Ò•gÔ)Ñ+Ô+Ñ,Ô,Ð,Ø
‡O‚O�EÑÔÐØ€Mó    Úolefilec                  óN   — t                                t          j        ¦  «         dS )zÅ
    Enable logging for this module (disabled by default).
    This will set the module-specific logger level to NOTSET, which
    means the main application controls the actual logging level.
    N)Úlogr+   r&   ÚNOTSET© r3   r1   r   r   Å   s   € õ ‡L‚L•”Ñ Ô Ð Ð Ð r3   s   ÐÏà¡±ál   úÿ l   üÿ l   ýÿ l   þÿ ì   ÿÿ é   é   iÿÿÿé   é   é   é	   é
   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é@   éA   éB   éC   éD   éE   éF   éG   éH   é   z$00020900-0000-0000-C000-000000000046é(   i   c                 óì  — t          | d¦  «        r=|                      t          t          ¦  «        ¦  «        }|                      d¦  «         n™t          | t          ¦  «        r5t          | ¦  «        t          k    r| dt          t          ¦  «        …         }nOt          | d¦  «        5 }|                     t          t          ¦  «        ¦  «        }ddd¦  «         n# 1 swxY w Y   |t          k    rdS dS )aJ  
    Test if a file is an OLE container (according to the magic bytes in its header).

    .. note::
        This function only checks the first 8 bytes of the file, not the
        rest of the OLE structure.

    .. versionadded:: 0.16

    :param filename: filename, contents or file-like object of the OLE file (string-like or file-like object)

        - 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.

    :type filename: bytes or str or unicode or file
    :returns: True if OLE, False otherwise.
    :rtype: bool
    Úreadr   NÚrbTF)	Úhasattrra   Úlenr   ÚseekÚ
isinstanceÚbytesr   Úopen)ÚfilenameÚheaderÚfps      r1   r   r     s	  € õ0 ˆx˜Ñ Ô ð )à—’�s¥5™zœzÑ*Ô*ˆà�Š�aÑÔÐÐÝ	�H�eÑ	$Ô	$ð )­¨X©¬Õ:NÒ)NÐ)Nà˜+�3�u™:œ:˜+Ô&ˆˆõ �(˜DÑ!Ô!ð 	) RØ—W’W�S¥™ZœZÑ(Ô(ˆFð	)ð 	)ð 	)ñ 	)ô 	)ð 	)ð 	)ð 	)ð 	)ð 	)ð 	)øøøð 	)ð 	)ð 	)ð 	)à•‚€Øˆtàˆus   Â((CÃC Ã#C c                 ó    — t          | ¦  «        S ©N)Úord©Úcs    r1   Úi8rq   ?  s   € Ý�1‰vŒvˆr3   c                 ó2   — | j         t          u r| n| d         S ©Nr   )Ú	__class__Úintro   s    r1   rq   rq   C  s   € Ø”K¥3Ð&Ð&ˆqˆq¨A¨a¬DÐ0r3   c                 óN   — t          j        d| ||dz   …         ¦  «        d         S )z¡
    Converts a 2-bytes (16 bits) string to an integer.

    :param c: string containing bytes to convert
    :param o: offset of bytes to convert in string
    z<Hr:   r   ©ÚstructÚunpack©rp   Úos     r1   Úi16r|   G  ó'   € õ Œ=˜˜q  1 Q¡3 œxÑ(Ô(¨Ô+Ð+r3   c                 óN   — t          j        d| ||dz   …         ¦  «        d         S )z¡
    Converts a 4-bytes (32 bits) string to an integer.

    :param c: string containing bytes to convert
    :param o: offset of bytes to convert in string
    z<Ir    r   rw   rz   s     r1   Úi32r   Q  r}   r3   c           
      ó  — t          | ¦  «        dk    sJ ‚|                      d¦  «        sdS dt          | d¦  «        t          | d¦  «        t          | d¦  «        ft	          t          t          | dd…         ¦  «        ¦  «        z   z  S )	z^
    Converts a CLSID to a human-readable string.

    :param clsid: string of length 16.
    rE   ó    Ú z0%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02Xr   r    r<   r>   )rd   Ústripr   r|   ÚtupleÚmaprq   )Úclsids    r1   Ú_clsidr‡   [  s‡   € õ ˆu‰:Œ:˜ÒÐÐÐð �;Š;�uÑÔð ØˆrØ4Ý�%˜‰mŒm�S ¨™]œ]­C°°q©M¬MÐ:Ý•#•b˜%  " œ+Ñ&Ô&Ñ'Ô'ñ(ñ)ð *r3   c                 ój   — t          j         dddddd¦  «        }|t          j        | dz  ¬¦  «        z   S )zL
        convert FILETIME (64 bits int) to Python datetime.datetime
        éA  r$   r   r@   ©Úmicroseconds)ÚdatetimeÚ	timedelta)ÚfiletimeÚ_FILETIME_null_dates     r1   Úfiletime2datetimer�   l  s<   € õ 'Ô/°°a¸¸A¸qÀ!ÑDÔDÐà"¥XÔ%7ÀXÈrÁ\Ð%RÑ%RÔ%RÑRÐRr3   c                   ó4   — e Zd ZdZg d¢Zg d¢Zd„ Zd„ Zd„ ZdS )r   aT  
    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/
    - https://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
    - https://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_targetrg   ÚlinesÚ
paragraphsÚslidesÚnotesÚhidden_slidesÚmm_clipsÚ
scale_cropÚheading_pairsÚtitles_of_partsr(   ÚcompanyÚlinks_dirtyÚchars_with_spacesÚunusedÚ
shared_docÚ	link_baseÚhlinksÚhlinks_changedÚversionÚdig_sigÚcontent_typeÚcontent_statusÚlanguageÚdoc_versionc                 ó˜  — 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| _.        dS )z_
        Constructor for OleMetadata
        All attributes are set to None by default
        N)/r’   r“   r”   r•   r–   r—   r˜   r™   rš   r›   rœ   r�   rž   rŸ   r    r¡   r¢   r£   r¤   r¥   r¦   r§   rg   r¨   r©   rª   r«   r¬   r­   r®   r¯   r°   r(   r±   r²   r³   r´   rµ   r¶   r·   r¸   r¹   rº   r»   r¼   r½   r¾   ©Úselfs    r1   Ú__init__zOleMetadata.__init__®  se  € ð ˆŒØˆŒ
ØˆŒØˆŒØˆŒØˆŒØˆŒØ!ˆÔØ#ˆÔØ#ˆÔØ ˆÔØˆÔØ#ˆÔØˆŒØˆŒØˆŒØˆŒØ$(ˆÔ!ØˆŒà ˆÔØˆŒØ#'ˆÔ ØˆŒ
ØˆŒ
ØˆŒØˆŒØˆŒ
Ø!ˆÔØˆŒØˆŒØ!ˆÔØ#ˆÔØˆŒØˆŒØˆÔØ!%ˆÔØˆŒØˆŒØˆŒØˆŒØ"ˆÔØˆŒØˆŒØ ˆÔØ"ˆÔØˆŒØˆÔÐÐr3   c                 óh  — | j         | j        z   D ]}t          | |d¦  «         Œ|                     d¦  «        rr|                     dddg¬¦  «        }t          t          | j         ¦  «        ¦  «        D ]7}|                     |dz   d¦  «        }t          | | j         |         |¦  «         Œ8|                     d¦  «        rp|                     dd¬¦  «        }t          t          | j        ¦  «        ¦  «        D ]9}|                     |dz   d¦  «        }t          | | j        |         |¦  «         Œ8dS dS )	a=  
        Parse standard properties of an OLE file, from the streams
        ``\x05SummaryInformation`` and ``\x05DocumentSummaryInformation``,
        if present.
        Properties are converted to strings, integers or python datetime objects.
        If a property is not present, its value is set to None.
        NzSummaryInformationTr@   )Úconvert_timeÚno_conversionr$   zDocumentSummaryInformation©rÄ   )ÚSUMMARY_ATTRIBSÚDOCSUM_ATTRIBSÚsetattrÚexistsÚgetpropertiesÚrangerd   Úget)rÁ   r4   ÚattribÚpropsr"   Úvalues         r1   Úparse_propertieszOleMetadata.parse_propertiesæ  sg  € ð Ô+¨dÔ.AÑAð 	(ð 	(ˆFÝ�D˜& $Ñ'Ô'Ð'Ð'Ø�>Š>Ð2Ñ3Ô3ð 
	>ð ×)Ò)Ð*BØ!°"°ð *ñ 7ô 7ˆEõ �3˜tÔ3Ñ4Ô4Ñ5Ô5ð >ð >�àŸ	š	 ! A¡# tÑ,Ô,�Ý˜˜dÔ2°1Ô5°uÑ=Ô=Ð=Ð=Ø�>Š>Ð:Ñ;Ô;ð 	=à×)Ò)Ð*JØ!ð *ñ #ô #ˆEõ �3˜tÔ2Ñ3Ô3Ñ4Ô4ð =ð =�àŸ	š	 ! A¡# tÑ,Ô,�Ý˜˜dÔ1°!Ô4°eÑ<Ô<Ð<Ð<ð	=ð 	=ð
=ð =r3   c           	      ó2  — t          d¦  «         | j        D ]4}t          | |¦  «        }t          d|›dt          |¦  «        ›�¦  «         Œ5t          d¦  «         | j        D ]4}t          | |¦  «        }t          d|›dt          |¦  «        ›�¦  «         Œ5dS )z<
        Dump all metadata, for debugging purposes.
        z*Properties from SummaryInformation stream:ú- ú: z2Properties from DocumentSummaryInformation stream:N)ÚprintrÇ   ÚgetattrÚreprrÈ   )rÁ   ÚproprÐ   s      r1   ÚdumpzOleMetadata.dump  s¶   € õ 	Ð:Ñ;Ô;Ð;ØÔ(ð 	4ð 	4ˆDÝ˜D $Ñ'Ô'ˆEÝˆE   ¥d¨5¡k¤k kÐ2Ñ3Ô3Ð3Ð3ÝÐBÑCÔCÐCØÔ'ð 	4ð 	4ˆDÝ˜D $Ñ'Ô'ˆEÝˆE   ¥d¨5¡k¤k kÐ2Ñ3Ô3Ð3Ð3ð	4ð 	4r3   N)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__rÇ   rÈ   rÂ   rÑ   rÙ   r8   r3   r1   r   r   z  ss   € € € € € ð ð  ðHð ð €OðEð Eð E€Nð5 ð 5 ð 5 ðp=ð =ð =ð@4ð 4ð 4ð 4ð 4r3   r   c                   ó   — e Zd ZdZd„ ZdS )Ú	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	                 óx
  — t                                d¦  «         t                                d|||||t          |¦  «        t          |¦  «        fz  ¦  «         || _        | j        j        j        rt          d¦  «        ‚d}	|t          k    r.t          |¦  «        |z  }d}	t                                d¦  «         ||dz
  z   |z  }
t                                d|
z  ¦  «         |
t          |¦  «        k    r | j         	                    t          d	¦  «         g }|d
k    rE|t          k    r:t                                d¦  «         | j         	                    t          d¦  «         t          |
¦  «        D �]Ÿ}t                                d||fz  ¦  «         |t          k    rY|	rt                                d¦  «          �nUt                                d¦  «         | j         	                    t          d¦  «         |d
k     s|t          |¦  «        k    rot                                d||t          |¦  «        fz  ¦  «         t                                d||
fz  ¦  «         | j         	                    t          d¦  «          �n“	 |                     |||z  z   ¦  «         nO#  t                                d||||z  z   |fz  ¦  «         | j         	                    t          d¦  «         Y  �n*xY w|                     |¦  «        }t          |¦  «        |k    r«|t          |¦  «        dz
  k    r•t                                d|t          |¦  «        |||z  z   |t          |¦  «        fz  ¦  «         t                                d|||z  z   t          |¦  «        z   z  ¦  «         | j         	                    t          d¦  «         |                     |¦  «         	 ||         dz  }�Œp# t           $ r$ | j         	                    t          d¦  «         Y  nw xY wd                     |¦  «        }t          |¦  «        |k    r>t                                dt          |¦  «        |fz  ¦  «         |d|…         }|| _        n¡|	r?t                                dt          |¦  «        z  ¦  «         t          |¦  «        | _        n`t                                dt          |¦  «        |fz  ¦  «         t          |¦  «        | _        | j         	                    t          d¦  «         t&          j                             | |¦  «         dS ) 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)
        :param olefileio: OleFileIO object containing this stream
        :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=%sz2Attempting to open a stream from a closed OLE FileFTz  stream with UNKNOWN SIZEr$   únb_sectors = %dz(malformed OLE document, stream too larger   z!size == 0 and sect != ENDOFCHAIN:z+incorrect OLE sector index for empty streamzReading stream sector[%d] = %Xhz6Reached ENDOFCHAIN sector for stream with unknown sizez$sect=ENDOFCHAIN before expected sizezincomplete OLE streamzsect=%d (%X) / len(fat)=%dzi=%d / nb_sectors=%dú,incorrect OLE FAT, sector index out of rangezsect=%d, seek=%d, filesize=%dúOLE sector index out of rangez9sect=%d / len(fat)=%d, seek=%d / filesize=%d, len read=%dzseek+len(read)=%dúincomplete OLE sectorr9   r3   z3Read data of length %d, truncated to stream size %dNz3Read data of length %d, the stream size was unknownz9Read data of length %d, less than expected stream size %dz%OLE stream size is less than declared)r6   Údebugrd   r×   Úolerk   ÚclosedÚOSErrorr   Ú_raise_defectr   r   rÌ   re   ra   ÚappendÚ
IndexErrorÚjoinÚsizeÚioÚBytesIOrÂ   )rÁ   rk   Úsectrí   ÚoffsetÚ
sectorsizeÚfatÚfilesizeÚ	olefileioÚunknown_sizeÚ
nb_sectorsÚdatar"   Úsector_datas                 r1   rÂ   zOleStream.__init__*  s  € õ 	�	Š	Ð'Ñ(Ô(Ð(Ý�	Š	ÐYØ�4˜˜V J­s°3©x¬x½¸b¹¼ÐBñCñ 	Dô 	Dð 	DàˆŒð Œ8Œ;Ôð 	PÝÐNÑOÔOÐOð ˆØ•<ÒÐõ �s‘8”8˜JÑ&ˆDàˆLÝ�IŠIÐ2Ñ3Ô3Ð3Ø˜j¨™lÑ+°
Ñ:ˆ
Ý�	Š	Ð# jÑ0Ñ1Ô1Ð1ð �˜C™œÒ Ð ØŒH×"Ò"Õ#3Ð5_Ñ`Ô`Ð`ð ˆà�1Š9ˆ9˜¥Ò+Ð+Ý�IŠIÐ9Ñ:Ô:Ð:ØŒH×"Ò"Õ#3Ð5bÑcÔcÐcõ �zÑ"Ô"ð 3	ñ 3	ˆAÝ�IŠIÐ7¸1¸d¸)ÑCÑDÔDÐDà•zÒ!Ð!Øð VÝ—I’IÐVÑWÔWÐWØ‘Eõ —I’IÐDÑEÔEÐEØ”H×*Ò*Õ+;Ð=TÑUÔUÐUà�AŠvˆv˜�s 3™xœxš˜Ý—	’	Ð6¸$ÀÅcÈ#ÁhÄhÐ9OÑOÑPÔPÐPÝ—	’	Ð0°1°j°/ÑAÑBÔBÐBð ”×&Ò&Õ'7Ð9gÑhÔhÐhà‘ðØ—’˜ ¨dÑ!2Ñ2Ñ3Ô3Ð3Ð3øðÝ—	’	Ð9Ø˜6 *¨T¡/Ñ1°8Ð<ñ=ñ >ô >ð >à”×&Ò&Õ'7Ð9XÑYÔYÐYà�‘øøøØŸ'š' *Ñ-Ô-ˆKõ
 �;ÑÔ Ò+Ð+°µs¸3±x´xÀ±zÒ0BÐ0BÝ—	’	ÐUØ�3˜s™8œ8 V¨J°t©OÑ%;¸XÅsÈ;ÑGWÔGWÐXñYñ Zô Zð Zå—	’	Ð-°¸
À4¹Ñ1GÍÈKÑHXÔHXÑ1XÑYÑZÔZÐZØ”×&Ò&Õ'7Ð9PÑQÔQÐQØ�KŠK˜Ñ$Ô$Ð$ðØ˜4”y :Ñ-�‘øÝð ð ð à”×&Ò&Õ'7Ð9gÑhÔhÐhà��ð	øøøð �xŠx˜‰~Œ~ˆåˆt‰9Œ9˜ÒÐÝ�IŠIÐKÍsÐSWÉyÌyÐZ^ÐN_Ñ_Ñ`Ô`Ð`Ø˜˜˜”;ˆDàˆDŒIˆIØð 
	^õ �IŠIÐKÍcÐRVÉiÌiÑWÑXÔXÐXÝ˜D™	œ	ˆDŒIˆIõ �IŠIÐQÕUXÐY]ÑU^ÔU^Ð`dÐTeÑeÑfÔfÐfå˜D™	œ	ˆDŒIØŒH×"Ò"Õ#3Ð5\Ñ]Ô]Ð]å
Œ
×Ò˜D $Ñ'Ô'Ð'Ð'Ð's   ÊJÊAK)ÏO"Ï"*PÐPN)rÚ   rÛ   rÜ   rÝ   rÂ   r8   r3   r1   rß   rß     s2   € € € € € ðð ð&|(ð |(ð |(ð |(ð |(r3   rß   c                   óŠ   — e Zd ZdZdZdZ ej        e¦  «        ek    sJ ‚d„ Zd„ Z	d„ Z
d„ Zd„ Zd	„ Zd
„ Zd„ Zdd„Zd„ Zd„ ZdS )ÚOleDirectoryEntryz
    OLE2 Directory Entry
    z<64sHBBIII16sIQQIIIé€   c                 ó¸  — || _         || _        g | _        i | _        d| _        t          j        t          j        |¦  «        \  | _	        | _
        | _        | _        | _        | _        | _        }| _        | _        | _        | _        | _        | _        | j        t,          t.          t0          t2          fvr|                     t6          d¦  «         | j        t,          k    r!|dk    r|                     t6          d¦  «         |dk    r+| j        t,          k    r|                     t6          d¦  «         | j
        dk    r"|                     t6          d¦  «         d| _
        | j	        d| j
        d	z
  …         | _        |                     | j        ¦  «        | _        t>                                d
| j         tC          | j        ¦  «        fz  ¦  «         t>                                d| j        z  ¦  «         t>                                d| j        z  ¦  «         t>                                d| j        | j        | j        fz  ¦  «         |j"        dk    rs| j        dk    r[| j        dk    rPt>                                d|j"        | j        | j        | j        fz  ¦  «         |                     tF          d¦  «         | j        | _$        n$| j        tK          | j        ¦  «        dz  z   | _$        t>                                d| j$        | j        | j        fz  ¦  «         tM          |¦  «        | _'        | j        t.          k    r&| j$        dk    r|                     tP          d¦  «         d| _)        | j        t,          t0          fv rZ| j$        dk    rO| j$        |j*        k     r| j        t0          k    rd| _)        nd| _)        | +                    | j        | j)        ¦  «         d| _,        dS )aI  
        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
        Fzunhandled OLE storage typer   zduplicate OLE root entryzincorrect OLE root entryrU   z(incorrect DirEntry name length >64 bytesNr:   zDirEntry SID=%d: %sz - type: %dz - sect: %Xhz% - SID left: %d, right: %d, child: %dé   r9   z+sectorsize=%d, sizeLow=%d, sizeHigh=%d (%X)zincorrect OLE stream sizeé    z% - size: %d (sizeLow=%d, sizeHigh=%d)zOLE storage with size>0T)-Úsidr4   ÚkidsÚ	kids_dictÚusedrx   ry   rû   ÚSTRUCT_DIRENTRYÚname_rawÚ
namelengthÚ
entry_typeÚcolorÚsid_leftÚ	sid_rightÚ	sid_childÚdwUserFlagsÚ
createTimeÚ
modifyTimeÚ
isectStartÚsizeLowÚsizeHighr   r   r   r	   ré   r   Ú
name_utf16Ú_decode_utf16_strr.   r6   rå   r×   rò   r   rí   Úlongr‡   r†   r   Ú
is_minifatÚminisectorcutoffÚ_check_duplicate_streamÚ
sect_chain)rÁ   Úentryr   r4   r†   s        r1   rÂ   zOleDirectoryEntry.__init__Ë  sx  € ð ˆŒàˆŒð ˆŒ	ð ˆŒð ˆŒ	õ" ŒMÕ+Ô;¸UÑCÔCñ	
ØŒMØŒOØŒOØŒJØŒMØŒNØŒNØØÔØŒOØŒOØŒOØŒLØŒMàŒ?¥:­}½lÍKÐ"XÐXÐXØ×!Ò!Õ"2Ð4PÑQÔQÐQàŒ?�jÒ(Ð(¨S°AªX¨XØ×!Ò!Õ"2Ð4NÑOÔOÐOØ�!Š8ˆ8˜œ­:Ò5Ð5Ø×!Ò!Õ"2Ð4NÑOÔOÐOð Œ?˜2ÒÐØ×!Ò!Õ"2Ð4^Ñ_Ô_Ð_à ˆDŒOàœ-Ð(<¨$¬/¸!Ñ*;Ð(<Ô=ˆŒð
 ×-Ò-¨d¬oÑ>Ô>ˆŒ	å�	Š	Ð'¨4¬8µT¸$¼)±_´_Ð*EÑEÑFÔFÐFÝ�	Š	�- $¤/Ñ1Ñ2Ô2Ð2Ý�	Š	�. 4¤?Ñ2Ñ3Ô3Ð3Ý�	Š	Ð9¸T¼]ØŒN˜DœNð=,ñ ,ñ 	-ô 	-ð 	-ð Ô Ò$Ð$ØŒ} Ò!Ð! d¤m°zÒ&AÐ&AÝ—	’	ÐGØÔ'¨¬°t´}ÀdÄmÐTñUñ Vô Vð Và×%Ò%¥mÐ5PÑQÔQÐQØœˆDŒIˆIàœ­¨T¬]Ñ(;Ô(;¸RÑ(?Ñ@ˆDŒIÝ�	Š	Ð9¸T¼YÈÌÐVZÔVcÐ<dÑdÑeÔeÐeå˜E‘]”]ˆŒ
ð Œ?�mÒ+Ð+°´	¸Q²°Ø×!Ò!Õ"2Ð4MÑNÔNÐNàˆŒØŒ?�z­<Ð8Ð8Ð8¸T¼YÀqº[¸[ØŒy˜7Ô3Ò3Ð3Ø”¥Ò-Ð-à"&�”�à"'�”Ø×+Ò+¨D¬O¸T¼_ÑMÔMÐMØˆŒˆˆr3   c                 ó|  — | j         rd S | j        t          t          fvs| j        dk    rd S t          ¦   «         | _         | j        r|j        s|                     ¦   «          | j	        }|t          k    rI| j                              |¦  «         | j        r|j        |         }n|j        |         }|t          k    °Gd S d S rs   )r  r  r   r   rí   Úlistr  ÚminifatÚloadminifatr  r   rê   ró   )rÁ   r4   Ú	next_sects      r1   Úbuild_sect_chainz"OleDirectoryEntry.build_sect_chain-  sÇ   € ØŒ?ð 	ØˆFØŒ?¥:­|Ð"<Ð<Ð<ÀÄ	ÈQÂÀØˆFå™&œ&ˆŒàŒ?ð 	" 7¤?ð 	"Ø×ÒÑ!Ô!Ð!à”Oˆ	Ø�:Ò%Ð%ØŒO×"Ò" 9Ñ-Ô-Ð-ØŒð 3Ø#œO¨IÔ6�	�	à#œK¨	Ô2�	ð �:Ò%Ð%Ð%Ð%Ð%Ð%r3   c                 ó  — t                                d| j        t          | j        ¦  «        | j        fz  ¦  «         | j        t          k    r5|                      | j        ¦  «         | j         	                    ¦   «          dS dS )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)
r6   rå   r   r×   r.   r  r   Úappend_kidsr  ÚsortrÀ   s    r1   Úbuild_storage_treez$OleDirectoryEntry.build_storage_tree@  s   € õ 	�	Š	ÐBØŒx�˜dœi™œ¨$¬.Ð9ñ:ñ 	;ô 	;ð 	;àŒ>�XÒ%Ð%ð ×Ò˜Tœ^Ñ,Ô,Ð,ð ŒI�NŠNÑÔÐÐÐð &Ð%r3   c                 ód  — t                                d|z  ¦  «         |t          k    rdS |dk     s|t          | j        j        ¦  «        k    r"| j                             t          d¦  «         dS | j                             |¦  «        }t                                d|j	        t          |j        ¦  «        |j        |j        |j        fz  ¦  «         |j        r"| j                             t          d¦  «         dS d|_        |                      |j        ¦  «         |j                             ¦   «         }|| j        v r | j                             t          d¦  «         | j                             |¦  «         || j        |<   |                      |j        ¦  «         |                     ¦   «          dS )	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)
        zappend_kids: child_sid=%dNr   zOLE DirEntry index out of rangezHappend_kids: child_sid=%d - %s - sid_left=%d, sid_right=%d, sid_child=%dz#OLE Entry referenced more than onceTz!Duplicate filename in OLE storage)r6   rå   r   rd   r4   Ú
direntriesré   r   Ú_load_direntryr   r×   r.   r	  r
  r  r  r!  Úlowerr  r  rê   r#  )rÁ   Ú	child_sidÚchildÚ
name_lowers       r1   r!  zOleDirectoryEntry.append_kidsX  s«  € õ 	�	Š	Ð-°	Ñ9Ñ:Ô:Ð:ð �Ò Ð ØˆFà�QŠ;ˆ;˜)¥S¨¬Ô)@Ñ%AÔ%AÒAÐAØŒL×&Ò&Õ'7Ð9ZÑ[Ô[Ð[Ð[Ð[ð ”L×/Ò/°	Ñ:Ô:ˆEÝ�IŠIÐ`Ø”9�d 5¤:Ñ.Ô.°´ÀÄÐQVÔQ`Ðañbñ cô cð cð Œzð Ø”×*Ò*Õ+;Ø9ñ;ô ;ð ;à�ØˆEŒJð ×Ò˜Uœ^Ñ,Ô,Ð,àœ×)Ò)Ñ+Ô+ˆJØ˜Tœ^Ð+Ð+Ø”×*Ò*Õ+;Ø7ñ9ô 9ð 9ð ŒI×Ò˜UÑ#Ô#Ð#Ø).ˆDŒN˜:Ñ&à×Ò˜Uœ_Ñ-Ô-Ð-à×$Ò$Ñ&Ô&Ð&Ð&Ð&r3   c                 ó"   — | j         |j         k    S ©zCompare entries by name©r.   ©rÁ   Úothers     r1   Ú__eq__zOleDirectoryEntry.__eq__‡  s   € àŒy˜EœJÒ&Ð&r3   c                 ó"   — | j         |j         k     S r,  r-  r.  s     r1   Ú__lt__zOleDirectoryEntry.__lt__‹  s   € àŒy˜5œ:Ò%Ð%r3   c                 ó.   — |                       |¦  «         S rm   )r0  r.  s     r1   Ú__ne__zOleDirectoryEntry.__ne__�  s   € Ø—;’;˜uÑ%Ô%Ð%Ð%r3   c                 óV   — |                       |¦  «        p|                      |¦  «        S rm   )r0  r2  r.  s     r1   Ú__le__zOleDirectoryEntry.__le__’  s%   € Ø�{Š{˜5Ñ!Ô!Ð7 T§[¢[°Ñ%7Ô%7Ð7r3   r   c                 óÎ  — g d¢}	 || j                  }n# t          $ r d}Y nw xY wt          d|z  t          | j        ¦  «        z   |d¬¦  «         | j         t
          t          fv rt          | j        dd¬¦  «         t          ¦   «          | j         t          t          fv r$| j	        rt          d|z  d| j	        z  z   ¦  «         | j
        D ]}|                     |dz   ¦  «         ŒdS )	zADump this entry, and all its subentries (for debug purposes only))z	(invalid)z	(storage)z(stream)z(lockbytes)z
(property)z(root)z	(UNKNOWN)ú ©Úendrg   z{%s}r:   N)r  rë   rÕ   r×   r.   r   r   rí   r   r†   r  rÙ   )rÁ   ÚtabÚTYPESÚ	type_nameÚkids        r1   rÙ   zOleDirectoryEntry.dump›  s  € ð)ð )ð )ˆð	$Ø˜dœoÔ.ˆIˆIøÝð 	$ð 	$ð 	$Ø#ˆIˆIˆIð	$øøøåˆc�#‰g�˜TœY™œÑ'¨¸Ð<Ñ<Ô<Ð<ØŒ?�|­ZÐ8Ð8Ð8Ý�$”)˜W¨#Ð.Ñ.Ô.Ð.Ý‰ŒˆØŒ?�}­jÐ9Ð9Ð9¸d¼jÐ9Ý�#�c‘'˜F T¤ZÑ/Ñ/Ñ0Ô0Ð0à”9ð 	ð 	ˆCØ�HŠH�S˜1‘WÑÔÐÐð	ð 	s   † ”#¢#c                 óD   — | j         dk    rdS t          | 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
        r   N)r  r�   rÀ   s    r1   ÚgetmtimezOleDirectoryEntry.getmtime®  ó&   € ð Œ?˜aÒÐØ�4Ý  ¤Ñ1Ô1Ð1r3   c                 óD   — | j         dk    rdS t          | 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
        r   N)r  r�   rÀ   s    r1   ÚgetctimezOleDirectoryEntry.getctime¼  rA  r3   N©r   )rÚ   rÛ   rÜ   rÝ   r  ÚDIRENTRY_SIZErx   ÚcalcsizerÂ   r  r#  r!  r0  r2  r4  r6  rÙ   r@  rC  r8   r3   r1   rû   rû   ¬  sö   € € € € € ðð ð. ,€Oà€MØˆ6Œ?˜?Ñ+Ô+¨}Ò<Ð<Ð<Ð<ð_ð _ð _ðD3ð 3ð 3ð&ð ð ð0,'ð ,'ð ,'ð^'ð 'ð 'ð&ð &ð &ð&ð &ð &ð8ð 8ð 8ðð ð ð ð&2ð 2ð 2ð2ð 2ð 2ð 2ð 2r3   rû   c                   ó  — e Zd ZdZdeddefd„Zd„ Zd„ Ze	fd„Z
d,d	„Zd-d
„Zd„ Zd-d„Zd.d„Zd.d„Zd„ Zd„ Zd„ Zd„ Zd„ Zd/d„Zd/d„Zd„ Zd„ Zd„ Zedfd„Zd0d„Zd0d„Zd„ Zd „ Z d!„ Z!d"„ Z"d#„ Z#d$„ Z$d%„ Z%d&„ Z&d'„ Z'd(„ Z(d)„ Z)d1d*„Z*d+„ Z+dS )2r   aª  
    OLE container object

    This class encapsulates the interface to an OLE 2 structured
    storage file.  Use the listdir and 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).
    NFc                 ól  — || _         g | _        || _        || _        d| _        d| _        g | _        g | _        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| _&        |r|  '                    ||¬¦  «         dS dS )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 (deprecated, not used anymore)

        :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)(Ú_raise_defects_levelÚparsing_issuesrI  Úpath_encodingÚ	_filesizeÚ
ministreamÚ_used_streams_fatÚ_used_streams_minifatÚ
byte_orderÚdirectory_fpr%  Údll_versionró   Úfirst_difat_sectorÚfirst_dir_sectorÚfirst_mini_fat_sectorrk   Úheader_clsidÚheader_signatureÚmetadataÚmini_sector_shiftÚmini_sector_sizeÚmini_stream_cutoff_sizer  Úminifatsectr  ÚminisectorsizeÚminor_versionÚnb_sectÚnum_difat_sectorsÚnum_dir_sectorsÚnum_fat_sectorsÚnum_mini_fat_sectorsÚ	reserved1Ú	reserved2ÚrootÚsector_shiftÚsector_sizeÚtransaction_signature_numberrh   )rÁ   ri   Úraise_defectsrI  rå   rL  s         r1   rÂ   zOleFileIO.__init__é  sf  € ð: %2ˆÔ!ð !ˆÔØ$ˆŒØ*ˆÔàˆŒØˆŒØ!#ˆÔØ%'ˆÔ"ØˆŒØ ˆÔØˆŒØˆÔØˆŒØ"&ˆÔØ $ˆÔØ%)ˆÔ"ØˆŒØ ˆÔØ $ˆÔØˆŒØ!%ˆÔØ $ˆÔØ'+ˆÔ$ØˆŒØˆÔà $ˆÔØ"ˆÔØˆŒØ!ˆÔØˆŒØ!%ˆÔØ#ˆÔØ#ˆÔØ$(ˆÔ!ØˆŒØˆŒØˆŒ	Ø ˆÔØˆÔØ,0ˆÔ)Øð 	7Ø�IŠI�h¨:ˆIÑ6Ô6Ð6Ð6Ð6ð	7ð 	7r3   c                 ó   — | S rm   r8   rÀ   s    r1   Ú	__enter__zOleFileIO.__enter__6  s   € Øˆr3   c                 ó.   — |                       ¦   «          d S rm   )Úclose)rÁ   Úargss     r1   Ú__exit__zOleFileIO.__exit__:  s   € Ø�
Š
‰Œˆˆˆr3   c                 óÒ   — || j         k    r%t                               |¦  «          ||¦  «        ‚| j                             ||f¦  «         t                               |¦  «         dS )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)rJ  r6   ÚerrorrK  rê   Úwarning)rÁ   Údefect_levelÚmessageÚexception_types       r1   ré   zOleFileIO._raise_defect>  sj   € ð" ˜4Ô4Ò4Ð4Ý�IŠI�gÑÔÐØ �. Ñ)Ô)Ð)ð Ô×&Ò&¨¸Ð'@ÑAÔAÐAÝ�KŠK˜Ñ Ô Ð Ð Ð r3   Úreplacec                 óv   — |                      d|¦  «        }| j        r|                     | j        |¦  «        S |S )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
        zUTF-16LE)ÚdecoderL  Úencode)rÁ   Ú	utf16_strÚerrorsÚunicode_strs       r1   r  zOleFileIO._decode_utf16_strX  sE   € ð  ×&Ò& z°6Ñ:Ô:ˆØÔð 	à×%Ò% dÔ&8¸&ÑAÔAÐAð Ðr3   c                 óÂ  — || _         t          |d¦  «        r|| _        nht          |t          ¦  «        r2t          |¦  «        t          k    rt          j        |¦  «        | _        n!| j         rd}nd}t          ||¦  «        | _        d}| j         
                    dt          j        ¦  «         	 | j                             ¦   «         }| j         
                    d¦  «         n# | j         
                    d¦  «         w xY w|| _        t                               d| j        | j        fz  ¦  «         g | _        g | _        | j                             d¦  «        }t          |¦  «        dk    s|dd…         t(          k    rHt                               d	|dd…         ›d
t(          ›�¦  «         |                      t,          d¦  «         d}t/          j        |¦  «        }t                               d||dz   fz  ¦  «         |d|…         }t/          j        ||¦  «        \  | _        | _        | _        | _        | _        | _        | _         | _!        | _"        | _#        | _$        | _%        | _&        | _'        | _(        | _)        | _*        | _+        t                               t/          j        ||¦  «        ¦  «         | j        t(          k    r|                      t,          d¦  «         | j        tY          d¦  «        k    r|                      tZ          d¦  «         t                               d| j        z  ¦  «         t                               d| j        z  ¦  «         | j        dvr|                      tZ          d¦  «         t                               d| j        z  ¦  «         | j        dk    r|                      tZ          d¦  «         d| j        z  | _.        t                               d| j.        z  ¦  «         | j.        dvr|                      tZ          d¦  «         | j        dk    r| j.        dk    s| j        dk    r&| j.        dk    r|                      tZ          d ¦  «         d| j         z  | _/        t                               d!| j/        z  ¦  «         | j/        d"vr|                      tZ          d#¦  «         | j!        dk    s| j"        dk    r|                      tZ          d$¦  «         t                               d%| j#        z  ¦  «         | j.        dk    r&| j#        dk    r|                      tZ          d&¦  «         t                               d'| j$        z  ¦  «         t                               d(| j%        z  ¦  «         t                               d)| j&        z  ¦  «         | j&        dk    r|                      t`          d*¦  «         t                               d+| j'        z  ¦  «         | j'        dk    rD|                      tZ          d,¦  «         t           1                    d-| j'        z  ¦  «         d| _'        t                               d.| j(        z  ¦  «         t                               d/| j)        z  ¦  «         t                               d0| j*        z  ¦  «         t                               d1| j+        z  ¦  «         || j.        z   d2z
  | j.        z  d2z
  | _2        t                               d3| j2        | j2        fz  ¦  «         tg          |dd4…         ¦  «        | _        | j.        | _4        | j/        | _5        | j'        | _6        |  7                    | j%        ¦  «         | j)        r|  7                    | j(        ¦  «         | j+        r|  7                    | j*        ¦  «         |  8                    |¦  «         |  9                    | j%        ¦  «         | j(        | _:        dS )5aþ  
        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)
        ra   zr+brb   r   zFile size: %d bytes (%Xh)rþ   Nr>   zMagic = z instead of z#not an OLE2 structured storage filez<8s16sHHHHHHLLLLLLLLLLzfmt_header size = %d, +FAT = %di´  zincorrect OLE signaturerE   zincorrect CLSID in OLE headerzMinor Version = %dz%DLL Version   = %d (expected: 3 or 4))r#   r    z"incorrect DllVersion in OLE headerz#Byte Order    = %X (expected: FFFE)iþÿ  z!incorrect ByteOrder in OLE headerr:   z0Sector Size   = %d bytes (expected: 512 or 4096))rþ   r^   z#incorrect sector_size in OLE headerr#   r    r^   z3sector_size does not match DllVersion in OLE headerz/MiniFAT Sector Size   = %d bytes (expected: 64))rU   z(incorrect mini_sector_size in OLE headerz.incorrect OLE header (non-null reserved bytes)z Number of Directory sectors = %dz3incorrect number of directory sectors in OLE headerzNumber of FAT sectors = %dzFirst Directory sector  = %Xhz$Transaction Signature Number    = %dz5incorrect OLE header (transaction_signature_number>0)z/Mini Stream cutoff size = %Xh (expected: 1000h)z/incorrect mini_stream_cutoff_size in OLE headerzJFixing the mini_stream_cutoff_size to 4096 (mandatory value) instead of %dzFirst MiniFAT sector      = %XhzNumber of MiniFAT sectors = %dzFirst DIFAT sector        = %XhzNumber of DIFAT sectors   = %dr$   z/Maximum number of sectors in the file: %d (%Xh)rM   );rI  rc   rk   rf   rg   rd   r   rî   rï   rh   re   ÚosÚSEEK_ENDÚtellrM  r6   rå   rO  rP  ra   r   ré   r   rx   rF  ry   rX  rW  r_  rS  rQ  rh  rZ  re  rf  rb  rc  rU  rj  r\  rV  rd  rT  ra  Ú	bytearrayr   ri  r[  r   rt  r`  r‡   rò   r^  r  r  ÚloadfatÚloaddirectoryr]  )	rÁ   ri   rI  Úmoderô   rj   Ú
fmt_headerÚheader_sizeÚheader1s	            r1   rh   zOleFileIO.openk  sQ  € ð" %ˆŒõ �8˜VÑ$Ô$ð 	+ð ˆDŒGˆGÝ˜¥%Ñ(Ô(ð 	+­S°©]¬]Õ>RÒ-RÐ-Rõ ”j Ñ*Ô*ˆDŒGˆGð Œð ð ��ð �Ý˜8 TÑ*Ô*ˆDŒGð
 ˆØŒ�Š�Q�œÑ$Ô$Ð$ð	Ø”w—|’|‘~”~ˆHàŒG�LŠL˜‰OŒOˆOˆOøˆDŒG�LŠL˜‰OŒOˆOˆOøøøØ!ˆŒÝ�	Š	Ð-°´ÀÄÐ0PÑPÑQÔQÐQð "$ˆÔØ%'ˆÔ"à”—’˜cÑ"Ô"ˆåˆv‰;Œ;˜#ÒÐ ¨¨¨¤­uÒ!4Ð!4Ý�IŠIˆI°F¸2¸A¸2´J°J°JÅÀÐFÑGÔGÐGØ×Ò�|Ð-RÑSÔSÐSðN .ˆ
Ý”o jÑ1Ô1ˆÝ�	Š	Ð4¸À[ÐSXÑEXÐ7YÑYÑ[Ô[Ð[Ø˜˜+˜Ô&ˆõ( ŒM˜* gÑ.Ô.ñ'	
ØÔ!ØÔØÔØÔØŒOØÔØÔ"ØŒNØŒNØÔ ØÔ ØÔ!ØÔ-ØÔ(ØÔ&ØÔ%ØÔ#ØÔ"å�	Š	•6”= °Ñ8Ô8Ñ9Ô9Ð9àÔ ¥EÒ)Ð)à×Ò�|Ð-FÑGÔGÐGØÔ¥	¨"¡¤Ò-Ð-à×ÒÕ/Ð1PÑQÔQÐQÝ�	Š	Ð'¨$Ô*<Ñ<Ñ>Ô>Ð>å�	Š	Ð:¸TÔ=MÑMÑOÔOÐOØÔ 6Ð)Ð)ð ×ÒÕ/Ð1UÑVÔVÐVÝ�	Š	Ð8¸4¼?ÑJÑLÔLÐLØŒ?˜fÒ$Ð$à×ÒÕ/Ð1TÑUÔUÐUð ˜dÔ/Ñ/ˆÔÝ�	Š	ÐEÈÔHXÑXÑZÔZÐZØÔ ;Ð.Ð.Ø×ÒÕ/Ð1VÑWÔWÐWØÔ˜aÒÐ DÔ$4°cÒ$9Ð$9ØÔ˜aÒÐ DÔ$4°dÒ$:Ð$:Ø×ÒÕ/Ð1fÑgÔgÐgØ ! 4Ô#9Ñ 9ˆÔÝ�	Š	ÐDÀtÔG\Ñ\Ñ^Ô^Ð^ØÔ ¨Ð,Ð,Ø×ÒÕ/Ð1[Ñ\Ô\Ð\ØŒ>˜QÒÐ $¤.°AÒ"5Ð"5Ø×ÒÕ/Ð1aÑbÔbÐbÝ�	Š	Ð5¸Ô8LÑLÑNÔNÐNàÔ˜SÒ Ð  TÔ%9¸1Ò%<Ð%<Ø×ÒÕ/Ð1fÑgÔgÐgÝ�	Š	Ð/°$Ô2FÑFÑHÔHÐHå�	Š	Ð2°TÔ5JÑJÑLÔLÐLå�	Š	Ð9¸DÔ<]Ñ]Ñ_Ô_Ð_ð
 Ô,°Ò1Ð1Ø×ÒÕ/Ð1hÑiÔiÐiÝ�	Š	ÐDÀtÔGcÑcÑeÔeÐeð Ô'¨6Ò1Ð1Ø×ÒÕ/Ð1bÑcÔcÐcå�KŠKÐdØÔ4ñ5ñ 6ô 6ð 6à+1ˆDÔ(å�	Š	Ð4°tÔ7QÑQÑSÔSÐSÝ�	Š	Ð3°dÔ6OÑOÑQÔQÐQÝ�	Š	Ð4°tÔ7NÑNÑPÔPÐPÝ�	Š	Ð3°dÔ6LÑLÑNÔNÐNð # TÔ%5Ñ5°aÑ7¸DÔ<LÑLÐPQÑQˆŒÝ�	Š	ÐDÈÌÐVZÔVbÐGcÑcÑdÔdÐdõ
 # 6¨!¨B¨$¤<Ñ0Ô0ˆÔð Ô*ˆŒØ"Ô3ˆÔØ $Ô <ˆÔð 	×$Ò$ TÔ%:Ñ;Ô;Ð;àÔ$ð 	EØ×(Ò(¨Ô)CÑDÔDÐDàÔ!ð 	BØ×(Ò(¨Ô)@ÑAÔAÐAð 	�Š�VÑÔÐð 	×Ò˜4Ô0Ñ1Ô1Ð1ØÔ5ˆÔÐÐs   Â0C$ Ã$D c                 ó8   — | j                              ¦   «          dS )z@
        close the OLE file, to release the file object
        N)rk   ro  rÀ   s    r1   ro  zOleFileIO.closeK  s   € ð 	Œ�Š‰Œˆˆˆr3   c                 óD  — |r%t                                d|z  ¦  «         | j        }nBt                                d|z  ¦  «         |t          t          t
          t          fv rdS | j        }||v r|                      t          d¦  «         dS | 
                    |¦  «         dS )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=%Xh in MiniFATz(_check_duplicate_stream: sect=%Xh in FATNzStream referenced twice)r6   rå   rP  r   r   r   r   rO  ré   r   rê   )rÁ   Ú
first_sectr  Úused_streamss       r1   r  z!OleFileIO._check_duplicate_streamR  s¬   € ð ð 	2Ý�IŠIÐDÀzÑQÑRÔRÐRØÔ5ˆLˆLå�IŠIÐ@À:ÑMÑNÔNÐNà�g¥g­j½ÐBÐBÐBØ�ØÔ1ˆLð ˜Ð%Ð%Ø×ÒÕ/Ð1JÑKÔKÐKÐKÐKà×Ò 
Ñ+Ô+Ð+Ð+Ð+r3   r   c                 ó0  — d}t           dt          dt          dt          di}t	          |¦  «        }||z   dz
  |z  }t          dd¬	¦  «         t          |¦  «        D ]}t          d
|z  d¬	¦  «         Œt          ¦   «          t          |¦  «        D ]†}||z  }	t          d||	z   z  d¬	¦  «         t          |	|	|z   ¦  «        D ]F}||k    r n=||         }
|
dz  }||v r	||         }n|
|dz   k    rd}nd
|
z  }t          |d¬	¦  «         ŒGt          ¦   «          Œ‡dS )zU
        Display a part of FAT in human-readable form for debugging purposes
        r>   z..free..z[ END. ]zFATSECT zDIFSECT r$   Úindexr8  r9  ú%8Xú%6X:r9   z    --->N)r   r   r   r   rd   rÕ   rÌ   )rÁ   ró   Ú
firstindexÚVPLÚfatnamesÚnbsectÚnlinesr"   Úlr�  rð   Úauxr.   s                r1   ÚdumpfatzOleFileIO.dumpfatl  sc  € ð
 ˆå˜
Ý˜
Ý˜
Ý˜
ð	ˆõ �S‘”ˆØ˜‘*˜Q‘, Ñ$ˆÝˆg˜3ÐÑÔÐÝ�s‘”ð 	&ð 	&ˆAÝ�%˜!‘) Ð%Ñ%Ô%Ð%Ð%Ý‰ŒˆÝ�v‘”ð 	ð 	ˆAØ�c‘EˆEÝ�&˜J uÑ,Ñ-°3Ð7Ñ7Ô7Ð7Ý˜5 %¨¡)Ñ,Ô,ð %ð %�Ø�f’9�9Ø�EØ˜1”v�Ø˜ZÑ'�Ø˜(�?�?Ø# Cœ=�D�Dà˜q ™s’{�{Ø)˜˜à$ t™|˜Ý�d Ð$Ñ$Ô$Ð$Ð$Ý‰GŒGˆGˆGð!	ð 	r3   c                 ó4  — d}t          j         t          |¦  «        }t          j        dk    r|                     ¦   «          t          |¦  «        }||z   dz
  |z  }t          dd¬¦  «         t          |¦  «        D ]}t          d|z  d¬¦  «         Œt          ¦   «          t          |¦  «        D ]h}||z  }	t          d||	z   z  d¬¦  «         t          |	|	|z   ¦  «        D ](}||k    r n||         }
d|
z  }t          |d¬¦  «         Œ)t          ¦   «          Œid	S )
zS
        Display a sector in a human-readable form, for debugging purposes
        r>   Úbigr$   r�  r8  r9  r�  r‘  N)ÚarrayÚUINT32ÚsysÚ	byteorderÚbyteswaprd   rÕ   rÌ   )rÁ   Úsectorr’  r“  r;  r•  r–  r"   r—  r�  rð   r.   s               r1   ÚdumpsectzOleFileIO.dumpsect‘  s?  € ð ˆÝŒk�& &Ñ)Ô)ˆÝŒ=˜EÒ!Ð!Ø�LŠL‰NŒNˆNÝ�S‘”ˆØ˜‘*˜Q‘, Ñ$ˆÝˆg˜3ÐÑÔÐÝ�s‘”ð 	&ð 	&ˆAÝ�%˜!‘) Ð%Ñ%Ô%Ð%Ð%Ý‰ŒˆÝ�v‘”ð 		ð 		ˆAØ�c‘EˆEÝ�&˜J uÑ,Ñ-°3Ð7Ñ7Ô7Ð7Ý˜5 %¨¡)Ñ,Ô,ð %ð %�Ø�f’9�9Ø�EØ˜1”v�Ø˜t‘|�Ý�d Ð$Ñ$Ô$Ð$Ð$Ý‰GŒGˆGˆGð		ð 		r3   c                 ó‚   — t          j         t          |¦  «        }t          j        dk    r|                     ¦   «          |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›  )rœ  r�  rž  rŸ  r   )rÁ   rð   Úas      r1   Ú
sect2arrayzOleFileIO.sect2arrayª  s4   € õ
 ŒK� Ñ%Ô%ˆåŒ=˜EÒ!Ð!Ø�JŠJ‰LŒLˆLØˆr3   c                 ó  — t          |t          j        ¦  «        r|}nN|                      |¦  «        }t                               t
          j        ¦  «        r|                      |¦  «         d}|D ]�}|dz  }t                               d|z  ¦  «         |t          k    s|t          k    rt                               d¦  «          n:|                      |¦  «        }|                      |¦  «        }| j        |z   | _        Œ�|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.
        Nr9   z
isect = %Xzfound end of sector chain)rf   rœ  r¥  r6   ÚisEnabledForr&   ÚDEBUGr¢  rå   r   r   Úgetsectró   )rÁ   rð   Úfat1ÚisectÚsÚnextfats         r1   Úloadfat_sectzOleFileIO.loadfat_sect¶  sù   € õ �d�EœKÑ(Ô(ð 	$àˆDˆDð —?’? 4Ñ(Ô(ˆDå×Ò¥¤Ñ.Ô.ð $Ø—’˜dÑ#Ô#Ð#ð ˆØð 	*ð 	*ˆEØ˜JÑ&ˆEÝ�IŠI�l UÑ*Ñ+Ô+Ð+Ø�
Ò"Ð" e­xÒ&7Ð&7å—	’	Ð5Ñ6Ô6Ð6Ø�à—’˜UÑ#Ô#ˆAð —o’o aÑ(Ô(ˆGØ”x 'Ñ)ˆDŒHˆHØˆr3   c                 ó"  — t                                d¦  «         |dd…         }t                                dt          |¦  «        t          |¦  «        dz  fz  ¦  «         t          j        t          ¦  «        | _        |                      |¦  «         | j        dk    �rÙt                                d¦  «         | j        dk    r|  	                    t          d	¦  «         | j        | j        k    r|  	                    t          d
¦  «         t                                d¦  «         | j        dz  dz
  }| j        dz
  |z   dz
  |z  }t                                d|z  ¦  «         | j        |k    rt          d¦  «        ‚| j        }t!          |¦  «        D ]Æ}t                                d||fz  ¦  «         |                      |¦  «        }|                      |¦  «        }t                                t(          j        ¦  «        r|                      |¦  «         |                      |d|…         ¦  «         ||         }t                                d|z  ¦  «         ŒÇ|t.          t0          fvrt          d¦  «        ‚nt                                d¦  «         t          | j        ¦  «        | j        k    rOt                                dt          | j        ¦  «        | j        fz  ¦  «         | j        d| j        …         | _        t                                dt          | j        ¦  «        | j        fz  ¦  «         t                                t(          j        ¦  «        r6t                                d¦  «         |                      | j        ¦  «         dS dS )z%
        Load the FAT table.
        zDLoading the FAT table, starting with the 1st sector after the headeréL   rþ   zlen(sect)=%d, so %d integersr    r   z)DIFAT is used, because file size > 6.8MB.ém   z#incorrect DIFAT, not enough sectorsz)incorrect DIFAT, first index out of rangezDIFAT analysis...r$   znb_difat = %dzincorrect DIFATzDIFAT block %d, sector %XNznext DIFAT sector: %Xzincorrect end of DIFATz$No DIFAT, because file size < 6.8MB.z!len(fat)=%d, shrunk to nb_sect=%dz6FAT references %d sectors / Maximum %d sectors in filez
FAT:)r6   rå   rd   rœ  r�  ró   r®  ra  rc  ré   r   rT  r`  r   rò   ÚIOErrorÚ	iterranger©  r¥  r§  r&   r¨  r¢  r   r   r™  )	rÁ   rj   rð   Únb_difat_sectorsÚnb_difatÚisect_difatr"   Úsector_difatÚdifats	            r1   r„  zOleFileIO.loadfatÚ  s9  € õ 	�	Š	ÐXÑYÔYÐYØ�b˜�fŒ~ˆÝ�	Š	Ð1µS¸±Y´YÅÀDÁ	Ä	È1ÁÐ4MÑMÑOÔOÐOõ
 ”;�vÑ&Ô&ˆŒØ×Ò˜$ÑÔÐð Ô! QÒ&Ñ&Ý�IŠIÐAÑBÔBÐBð Ô# sÒ*Ð*ð ×"Ò"Õ#3Ð5ZÑ[Ô[Ð[ØÔ&¨$¬,Ò6Ð6à×"Ò"¥<Ð1\Ñ]Ô]Ð]Ý�IŠIÐ*Ñ,Ô,Ð,ð !%¤°Ñ 2°AÑ5ÐàÔ,¨SÑ0Ð3CÑCÀAÑEÐHXÑXˆHÝ�IŠI�¨Ñ1Ñ3Ô3Ð3ØÔ%¨Ò1Ð1ÝÐ/Ñ0Ô0Ð0ØÔ1ˆKÝ˜xÑ(Ô(ð Cð C�Ý—	’	Ð6¸!¸[Ð9IÑIÑKÔKÐKà#Ÿ|š|¨KÑ8Ô8�ØŸš¨Ñ5Ô5�å×#Ò#¥G¤MÑ2Ô2ð 0Ø—M’M ,Ñ/Ô/Ð/Ø×!Ò! %Ð(9Ð)9Ð(9Ô":Ñ;Ô;Ð;à#Ð$4Ô5�Ý—	’	Ð2°[Ñ@ÑBÔBÐBÐBà¥:­xÐ"8Ð8Ð8åÐ6Ñ7Ô7Ð7ð 9õ �IŠIÐ<Ñ=Ô=Ð=õ ˆtŒx‰=Œ=˜4œ<Ò'Ð'Ý�IŠIÐ9½SÀÄ¹]¼]ÈDÌLÐ<YÑYÑZÔZÐZØ”x  ¤ Ô.ˆDŒHÝ�	Š	ÐJÍcÐRVÔRZÉmÌmÐ]aÔ]iÐMjÑjÑkÔkÐkå×Ò�GœMÑ*Ô*ð 	#Ý�IŠI�hÑÔÐØ�LŠL˜œÑ"Ô"Ð"Ð"Ð"ð	#ð 	#r3   c                 ó4  — | j         | j        z  }| j        j        | j        z   dz
  | j        z  }|dz  }t
                               d| j        | j         |||fz  ¦  «         ||k    r|                      t          d¦  «         |  
                    | j        |d¬¦  «                             ¦   «         }|                      |¦  «        | _        t
                               dt          | j        ¦  «        |fz  ¦  «         | j        d|…         | _        t
                               d	t          | j        ¦  «        z  ¦  «         t
                               t           j        ¦  «        r6t
                               d
¦  «         |                      | j        ¦  «         dS dS )z)
        Load the MiniFAT table.
        r$   r    zaloadminifat(): minifatsect=%d, nb FAT sectors=%d, used_size=%d, stream_size=%d, nb MiniSectors=%dz%OLE MiniStream is larger than MiniFATT©Ú	force_FATz$MiniFAT shrunk from %d to %d sectorsNzloadminifat(): len=%dz	
MiniFAT:)rd  ri  rg  rí   r[  r6   rå   r]  ré   r   Ú_openra   r¥  r  rd   r§  r&   r¨  r™  )rÁ   Ústream_sizeÚnb_minisectorsÚ	used_sizer¬  s        r1   r  zOleFileIO.loadminifat.  s|  € ð Ô/°$Ô2BÑBˆð œ)œ.¨4Ô+@Ñ@ÀÑBÀtÔG\Ñ\ˆØ" QÑ&ˆ	Ý�	Š	ÐuØÔ˜tÔ8¸)À[ÐR`Ðañbñ 	cô 	cð 	cà�{Ò"Ð"à×ÒÕ/Ð1XÑYÔYÐYà�JŠJ�tÔ'¨ÀˆJÑEÔE×JÒJÑLÔLˆð —’ qÑ)Ô)ˆŒå�	Š	Ð8½CÀÄÑ<MÔ<MÈ~Ð;^Ñ^Ñ_Ô_Ð_Ø”| O ^ OÔ4ˆŒÝ�	Š	Ð)­C°´Ñ,=Ô,=Ñ=Ñ>Ô>Ð>å×Ò�GœMÑ*Ô*ð 	'Ý�IŠI�lÑ#Ô#Ð#Ø�LŠL˜œÑ&Ô&Ð&Ð&Ð&ð	'ð 	'r3   c                 ó   — 	 | j                              | j        |dz   z  ¦  «         nR#  t                               d|| j        |dz   z  | j        fz  ¦  «         |                      t          d¦  «         Y nxY w| j                              | j        ¦  «        }t          |¦  «        | j        k    rMt                               d|t          |¦  «        | j        fz  ¦  «         |                      t          d¦  «         |S )z•
        Read given sector from file on disk.

        :param sect: int, sector index
        :returns: a string containing the sector data.
        r$   z(getsect(): sect=%X, seek=%d, filesize=%drã   z*getsect(): sect=%X, read=%d, sectorsize=%drä   )
rk   re   rò   r6   rå   rM  ré   r   ra   rd   )rÁ   rð   r¡  s      r1   r©  zOleFileIO.getsectR  sþ   € ð$	NØŒG�LŠL˜œ¨D°©FÑ3Ñ4Ô4Ð4Ð4øð	NÝ�IŠIÐ@Ø�t”¨¨Q©Ñ/°´Ð@ñAñ Bô Bð Bà×Ò�|Ð-LÑMÔMÐMÐMÐMøøøØ”—’˜dœoÑ.Ô.ˆÝˆv‰;Œ;˜$œ/Ò)Ð)Ý�IŠIÐBØ•s˜6‘{”{ D¤OÐ4ñ5ñ 6ô 6ð 6à×Ò�|Ð-DÑEÔEÐEØˆs
   ‚%( ¨AA7r�   c                 óœ  — t          |t          ¦  «        st          d¦  «        ‚t          |t          ¦  «        rt          |¦  «        dk    rt          d¦  «        ‚	 | j                             | j        |dz   z  ¦  «         nR#  t                               d|| j        |dz   z  | j	        fz  ¦  «         |  
                    t          d¦  «         Y nxY wt          |¦  «        | j        k     r||| j        t          |¦  «        z
  z  z  }n't          |¦  «        | j        k     rt          d¦  «        ‚| j                             |¦  «         dS )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 stringr$   z4write_sect: padding must be a bytes string of 1 charz+write_sect(): sect=%X, seek=%d, filesize=%drã   úData is larger than sector sizeN)rf   rg   Ú	TypeErrorrd   rk   re   rò   r6   rå   rM  ré   r   Ú
ValueErrorÚwrite)rÁ   rð   rø   Úpaddings       r1   Ú
write_sectzOleFileIO.write_sectr  sK  € õ ˜$¥Ñ&Ô&ð 	GÝÐEÑFÔFÐFÝ˜'¥5Ñ)Ô)ð 	T­S°©\¬\¸1ª_¨_ÝÐRÑSÔSÐSð	NØŒG�LŠL˜œ¨D°©FÑ3Ñ4Ô4Ð4Ð4øð	NÝ�IŠIÐCØ�t”¨¨Q©Ñ/°´Ð@ñAñ Bô Bð Bà×Ò�|Ð-LÑMÔMÐMÐMÐMøøøÝˆt‰9Œ9�t”Ò&Ð&à�G˜tœµ°T±´Ñ:Ñ;Ñ;ˆDˆDÝ�‰YŒY˜œÒ(Ð(ÝÐ>Ñ?Ô?Ð?ØŒ�Š�dÑÔÐÐÐs   Á%B ÂACc                 ó<  — t          |t          ¦  «        st          d¦  «        ‚t          |t          ¦  «        rt          |¦  «        dk    rt          d¦  «        ‚	 | j                             |¦  «         nF#  t                               d|| j        fz  ¦  «         |  	                    t          d¦  «         Y nxY wt          |¦  «        }|| j        k     r||| j        |z
  z  z  }| j        |k     rt          d¦  «        ‚| j                             |¦  «         dS )zÕ
        Write given sector to file on disk.

        :param fp_pos: int, file position
        :param data: bytes, sector data
        :param padding: single byte, padding character if data < sector size
        z,write_mini_sect: data must be a bytes stringr$   z9write_mini_sect: padding must be a bytes string of 1 charz)write_mini_sect(): fp_pos=%d, filesize=%drã   rÂ  N)rf   rg   rÃ  rd   rk   re   r6   rå   rM  ré   r   r[  rÄ  rÅ  )rÁ   Úfp_posrø   rÆ  Úlen_datas        r1   Ú_write_mini_sectzOleFileIO._write_mini_sectŒ  s+  € õ ˜$¥Ñ&Ô&ð 	LÝÐJÑKÔKÐKÝ˜'¥5Ñ)Ô)ð 	Y­S°©\¬\¸QÒ->Ð->ÝÐWÑXÔXÐXð	NØŒG�LŠL˜Ñ Ô Ð Ð øð	NÝ�IŠIÐAØ˜tœ~Ð.ñ/ñ 0ô 0ð 0à×Ò�|Ð-LÑMÔMÐMÐMÐMøøøÝ�t‘9”9ˆØ�dÔ+Ò+Ð+Ø�G˜tÔ4°xÑ?Ñ@Ñ@ˆDØÔ  8Ò+Ð+ÝÐ>Ñ?Ô?Ð?ØŒ�Š�dÑÔÐÐÐs   ÁA8 Á8AB;c                 óx  — t                                d¦  «         |                      |d¬¦  «        | _        | j        j        dz  }t                                d| j        j        |fz  ¦  «         dg|z  | _        |                      d¦  «        }| j        d         | _        | j                             ¦   «          dS )z]
        Load the directory.

        :param sect: sector index of directory stream.
        zLoading the Directory:Trº  rü   z&loaddirectory: size=%d, max_entries=%dNr   )	r6   rå   r¼  rR  rí   r%  r&  rg  r#  )rÁ   rð   Úmax_entriesÚ
root_entrys       r1   r…  zOleFileIO.loaddirectory¦  s¾   € õ 	�	Š	Ð*Ñ+Ô+Ð+ð !ŸJšJ t°t˜JÑ<Ô<ˆÔð Ô'Ô,°Ñ3ˆÝ�	Š	Ð:ØÔÔ# [Ð1ñ2ñ 	3ô 	3ð 	3ð  ˜& ;Ñ.ˆŒð ×(Ò(¨Ñ+Ô+ˆ
à”O AÔ&ˆŒ	ð 	Œ	×$Ò$Ñ&Ô&Ð&Ð&Ð&r3   c                 ó˜  — |dk     s|t          | j        ¦  «        k    r|                      t          d¦  «         | j        |         �(|                      t          d¦  «         | j        |         S | j                             |dz  ¦  «         | j                             d¦  «        }t          ||| ¦  «        | j        |<   | j        |         S )aY  
        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.
        r   z OLE directory index out of rangeNz'double reference for OLE stream/storagerü   )	rd   r%  ré   r   r   rR  re   ra   rû   )rÁ   r   r  s      r1   r&  zOleFileIO._load_direntryÏ  sÈ   € ð ˆqŠ5ˆ5�C�˜Tœ_Ñ-Ô-Ò-Ð-Ø×Ò�|Ð-OÑPÔPÐPàŒ?˜3ÔÐ+Ø×ÒÕ/Ø9ñ;ô ;ð ;ð ”? 3Ô'Ð'ØÔ×Ò˜s S™yÑ)Ô)Ð)ØÔ!×&Ò& sÑ+Ô+ˆÝ0°¸¸TÑBÔBˆŒ˜ÑØŒ˜sÔ#Ð#r3   c                 ó8   — | j                              ¦   «          dS )z5
        Dump directory (for debugging only)
        N)rg  rÙ   rÀ   s    r1   ÚdumpdirectoryzOleFileIO.dumpdirectoryé  s   € ð 	Œ	�ŠÑÔÐÐÐr3   c           
      ó$  — t                                d||t          |¦  «        fz  ¦  «         || j        k     r©|s§| j        sp|                      ¦   «          | j        j        }t                                d| j        j        |fz  ¦  «         |  	                    | j        j        |d¬¦  «        | _        t          | j        ||d| j        | j        | j        j        | ¬¦  «        S t          | j        ||| j        | j        | j        | j        | ¬¦  «        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.
        z1OleFileIO.open(): sect=%Xh, size=%d, force_FAT=%sz%Opening MiniStream: sect=%Xh, size=%dTrº  r   )rk   rð   rí   rñ   rò   ró   rô   rõ   )r6   rå   Ústrr  rN  r  rg  rí   r  r¼  rß   r^  r  rk   rò   ró   rM  )rÁ   Ústartrí   r»  Úsize_ministreams        r1   r¼  zOleFileIO._openð  s,  € õ 	�	Š	ÐEØ�D�#˜i™.œ.Ð)ñ*ñ 	+ô 	+ð 	+ð �$Ô'Ò'Ð'°	Ð'à”?ð 	5à× Ò Ñ"Ô"Ð"ð #'¤)¤.�Ý—	’	ÐAØ”YÔ)¨?Ð;ñ<ñ =ô =ð =à"&§*¢*¨T¬YÔ-AØ#¨tð #-ñ #5ô #5�”å ¤°eÀ$Ø$%°$Ô2EØ!%¤¸¼Ô8LØ'+ð-ñ -ô -ð -õ  ¤¨e¸$Ø$(¤OØ(,¬¸T¼XØ&*¤nØ'+ð	-ñ -ô -ð -r3   Tc                 ó|  — ||j         gz   }|j        D ]¨}|j        t          k    rB|r&|                     |dd…         |j         gz   ¦  «         |                      |||||¦  «         ŒT|j        t          k    r)|r&|                     |dd…         |j         gz   ¦  «         Œ�|                      t          d¦  «         Œ©dS )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)
        r$   NzIThe 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  s          r1   r×  zOleFileIO._list  së   € ð ˜4œ9˜+Ñ%ˆØ”Yð 	Bð 	BˆEØÔ¥=Ò0Ð0àð <à—L’L ¨¨¨¤¨u¬z¨lÑ!:Ñ;Ô;Ð;à—
’
˜5 &¨%°¸(ÑCÔCÐCÐCØÔ!¥\Ò1Ð1àð <à—L’L ¨¨¨¤¨u¬z¨lÑ!:Ñ;Ô;Ð;øà×"Ò"Õ#3ð  6Añ  Bô  Bð  Bð  Bð	Bð 	Br3   c                 óF   — g }|                       |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×  rg  )rÁ   rÛ  rÜ  rØ  s       r1   ÚlistdirzOleFileIO.listdir3  s*   € ð ˆØ�
Š
�5˜"˜dœi¨°(Ñ;Ô;Ð;Øˆr3   c                 ó  — t          |t          ¦  «        r|                     d¦  «        }| j        }|D ]N}|j        D ]3}|j                             ¦   «         |                     ¦   «         k    r nŒ4t          d¦  «        ‚|}ŒO|j        S )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
        ú/zfile not found)	rf   Ú
basestringÚsplitrg  r  r.   r'  r²  r   )rÁ   ri   rÚ  r.   r>  s        r1   Ú_findzOleFileIO._findA  s–   € õ$ �h¥
Ñ+Ô+ð 	+Ø—~’~ cÑ*Ô*ˆHàŒyˆØð 	ð 	ˆDØ”yð 0ð 0�Ø”8—>’>Ñ#Ô# t§z¢z¡|¤|Ò3Ð3Ø�Eð 4õ Ð.Ñ/Ô/Ð/ØˆDˆDØŒxˆr3   c                 óÄ   — |                       |¦  «        }| j        |         }|j        t          k    rt	          d¦  «        ‚|                      |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.
        zthis file is not a stream)rã  r%  r  r   r²  r¼  r  rí   ©rÁ   ri   r   r  s       r1   Ú
openstreamzOleFileIO.openstreama  sW   € ð �jŠj˜Ñ"Ô"ˆØ” Ô$ˆØÔ�|Ò+Ð+ÝÐ5Ñ6Ô6Ð6Ø�zŠz˜%Ô*¨E¬JÑ7Ô7Ð7r3   c                 ó  — |j         s|                     | ¦  «         t          |j         ¦  «        }| j        j         s| j                             | ¦  «         | j        | j        z  }t          |j         ¦  «        D ]†\  }}||z  }||z  }| j        j         |         dz   | j        z  || j        z  z   }	||dz
  k     r||| j        z  |dz   | j        z  …         }
n||| j        z  d …         }
|                      |	|
¦  «         Œ‡d S )Nr$   )r  r  rd   rg  ri  r[  Ú	enumeraterË  )rÁ   r  Údata_to_writer÷   Ú
block_sizeÚidxrð   Ú	sect_baseÚsect_offsetrÉ  Údata_per_sectors              r1   Ú_write_mini_streamzOleFileIO._write_mini_streamv  s1  € ØÔð 	)Ø×"Ò" 4Ñ(Ô(Ð(Ý˜Ô)Ñ*Ô*ˆ
àŒyÔ#ð 	-ØŒI×&Ò& tÑ,Ô,Ð,ØÔ%¨Ô)>Ñ>ˆ
Ý" 5Ô#3Ñ4Ô4ð 	;ð 	;‰IˆC�Ø 
Ñ*ˆIØ Ñ+ˆKØ”iÔ*¨9Ô5¸Ñ9¸4Ô;KÑKÈkÐZ^ÔZoÑNoÑoˆFØ�j 1‘nÒ%Ð%Ø"/°°dÔ6KÑ0KÈcÐTUÉgÐY]ÔYnÑMnÐ0nÔ"o��à"/°°dÔ6KÑ0KÐ0LÐ0LÔ"M�Ø×!Ò! &¨/Ñ:Ô:Ð:Ð:ð	;ð 	;r3   c           	      ó8  — t          |t          ¦  «        st          d¦  «        ‚|                      |¦  «        }| j        |         }|j        t          k    rt          d¦  «        ‚|j        }|t          |¦  «        k    rt          d¦  «        ‚|| j        k     r'|j        t          k    r|                      ||¬¦  «        S |j        }|| j        dz
  z   | j        z  }t                                d|z  ¦  «         t%          |¦  «        D ]ö}||dz
  k     r8||| j        z  |dz   | j        z  …         }	t          |	¦  «        | j        k    sJ ‚nr||| j        z  d…         }	t                                d|| j        t          |	¦  «        || j        z  fz  ¦  «         t          |	¦  «        | j        z  || j        z  k    sJ ‚|                      ||	¦  «         	 | j        |         }ŒÚ# t*          $ r t          d	¦  «        ‚w xY w|t,          k    rt          d
¦  «        ‚dS )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 stringzthis is not a streamz?write_stream: data must be the same size as the existing stream)r  ré  r$   rá   NzGwrite_stream: size=%d sectorsize=%d data_sector=%Xh size%%sectorsize=%drâ   z)incorrect last sector index in OLE stream)rf   rg   rÃ  rã  r%  r  r   r²  rí   rd   rÄ  r  r   rï  r  rò   r6   rå   rÌ   rÇ  ró   rë   r   )
rÁ   Ústream_namerø   r   r  rí   rð   r÷   r"   Údata_sectors
             r1   Úwrite_streamzOleFileIO.write_streamˆ  sR  € õ ˜$¥Ñ&Ô&ð 	IÝÐGÑHÔHÐHØ�jŠj˜Ñ%Ô%ˆØ” Ô$ˆØÔ�|Ò+Ð+ÝÐ0Ñ1Ô1Ð1ØŒzˆØ•3�t‘9”9ÒÐÝÐ^Ñ_Ô_Ð_Ø�$Ô'Ò'Ð'¨EÔ,<Å
Ò,JÐ,JØ×*Ò*°5È$Ð*ÑOÔOÐOàÔˆà˜dœo¨aÑ/Ñ0°T´_ÑDˆ
Ý�	Š	Ð# jÑ0Ñ1Ô1Ð1Ý�zÑ"Ô"ð 	Nð 	NˆAð �*˜Q‘,ÒÐØ" A d¤oÑ$5¸¸1¹¸d¼oÑ8MÐ$MÔN�å˜;Ñ'Ô'¨¬Ò8Ð8Ð8Ð8Ð8à" A d¤oÑ$5Ð$6Ð$6Ô7�å—	’	ÐcØ˜Tœ_­c°+Ñ.>Ô.>ÀÀtÄÑ@VÐWñXñ Yô Yð Yå˜;Ñ'Ô'¨$¬/Ñ9¸4À$Ä/Ñ;QÒQÐQÐQÐQØ�OŠO˜D +Ñ.Ô.Ð.ðNØ”x ”~��øÝð Nð Nð NåÐLÑMÔMÐMðNøøøð •:ÒÐÝÐEÑFÔFÐFð Ðs   ÇG#Ç#G=c                 óf   — 	 |                       |¦  «        }| j        |         }|j        S #  Y dS xY w)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
        F)rã  r%  r  rå  s       r1   Úget_typezOleFileIO.get_typeÆ  s=   € ð	Ø—*’*˜XÑ&Ô&ˆCØ”O CÔ(ˆEØÔ#Ð#øð	Ø�5�5øøøs   ‚(+ «0c                 óT   — |                       |¦  «        }| j        |         }|j        S )a  
        Return clsid of a stream/storage.

        :param filename: path of stream/storage in storage tree. (see openstream for
            syntax)
        :returns: Empty string if clsid is null, a printable representation of the clsid otherwise

        new in version 0.44
        )rã  r%  r†   rå  s       r1   ÚgetclsidzOleFileIO.getclsidÚ  s)   € ð �jŠj˜Ñ"Ô"ˆØ” Ô$ˆØŒ{Ðr3   c                 ón   — |                       |¦  «        }| 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
        )rã  r%  r@  rå  s       r1   r@  zOleFileIO.getmtimeé  ó1   € ð �jŠj˜Ñ"Ô"ˆØ” Ô$ˆØ�~Š~ÑÔÐr3   c                 ón   — |                       |¦  «        }| 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
        )rã  r%  rC  rå  s       r1   rC  zOleFileIO.getctimeù  rù  r3   c                 óB   — 	 |                       |¦  «        }dS #  Y dS xY w)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.
        TF)rã  )rÁ   ri   r   s      r1   rÊ   zOleFileIO.exists	  s-   € ð	Ø—*’*˜XÑ&Ô&ˆCØ�4øð	Ø�5�5øøøs   ‚ ™c                 ó’   — |                       |¦  «        }| j        |         }|j        t          k    rt	          d¦  «        ‚|j        S )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.
        zobject is not an OLE stream)rã  r%  r  r   rÃ  rí   rå  s       r1   Úget_sizezOleFileIO.get_size  sF   € ð �jŠj˜Ñ"Ô"ˆØ” Ô$ˆØÔ�|Ò+Ð+åÐ9Ñ:Ô:Ð:ØŒzÐr3   c                 ó   — | j         j        S )zp
        Return root entry name. Should usually be 'Root Entry' or 'R' in most
        implementations.
        )rg  r.   rÀ   s    r1   Úget_rootentry_namezOleFileIO.get_rootentry_name*  s   € ð
 ŒyŒ~Ðr3   c           	      óø
  — |dk    rg }|}t          |t          ¦  «        sd                     |¦  «        }|                      |¦  «        }i }	 |                     d¦  «        }t          |dd…         ¦  «        }|                     d¦  «        }t          |dd…         ¦  «        }	|                     t          |d¦  «        ¦  «         d|                     t          |                     d	¦  «        ¦  «        d	z
  ¦  «        z   }t          |d	¦  «        }
nW# t          $ rJ}d
t          |¦  «        ›d|›�}|  
                    t          |t          |¦  «        ¦  «         |cY d}~S d}~ww xY wt          |
t          t          |¦  «        dz  ¦  «        ¦  «        }
t!          |
¦  «        D �]Ñ}d}	 t          |d|dz  z   ¦  «        }t          |d|dz  z   ¦  «        }t          ||¦  «        }t"                               d|||fz  ¦  «         |t&          k    r t)          ||d	z   ¦  «        }|dk    r|dz
  }�né|t*          k    rt)          ||d	z   ¦  «        }�nÉ|t,          t.          t0          fv rt          ||d	z   ¦  «        }�nž|t2          t4          fv rt          ||d	z   ¦  «        }�ny|t6          t8          fv rAt          ||d	z   ¦  «        }||dz   |dz   |z   dz
  …         }|                     dd¦  «        }�n(|t<          k    r(t          ||d	z   ¦  «        }||dz   |dz   |z   …         }�nõ|t>          k    r>t          ||d	z   ¦  «        }|                       ||dz   |dz   |dz  z   …         ¦  «        }�n¬|tB          k    rÕtE          t          ||d	z   ¦  «        ¦  «        tE          t          ||dz   ¦  «        ¦  «        dz  z   }|r‰||vr…t"                               d||tG          |¦  «        dz  fz  ¦  «         tI          j$        dddddd¦  «        }t"                               d|dz  z  ¦  «         |tI          j%        |dz  ¬¦  «        z   }nÒ|dz  }nÌ|tL          k    rtO          ||d	z            ¦  «        }n¨|tP          k    rt          ||d	z   |dz   …         ¦  «        }n|tR          k    r't          ||d	z   ¦  «        }||dz   |dz   |z   …         }nM|tT          k    r!tW          t)          ||d	z   ¦  «        ¦  «        }n!d}t"                               d||fz  ¦  «         |||<   �Œ}# t          $ rI}d|t          |¦  «        |fz  }|  
                    t          |t          |¦  «        ¦  «         Y d}~�ŒËd}~ww xY w|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à  rQ   r>   rM   rI   rE   s   ****r    z0Error while parsing properties header in stream rÔ   r   rB   z!property id=%d: type=%d offset=%Xi €  i   r$   r�   r3   r:   rÿ   z8Converting property #%d to python datetime, value=%d=%fsi€–˜ r‰   ztimedelta days=%dl    @ÓT$r@   rŠ   z5property id=%d: type=%d not implemented in parser yetz3Error while parsing property id %d in stream %s: %s),rf   rÓ  rì   ræ  ra   r‡   re   r   ÚBaseExceptionr×   ré   r   ÚtypeÚminru   rd   r³  r6   rå   ÚVT_I2r|   ÚVT_UI2ÚVT_I4ÚVT_INTÚVT_ERRORÚVT_UI4ÚVT_UINTÚVT_BSTRÚVT_LPSTRrx  ÚVT_BLOBÚ	VT_LPWSTRr  ÚVT_FILETIMEr  ÚfloatrŒ   r�   ÚVT_UI1rq   ÚVT_CLSIDÚVT_CFÚVT_BOOLÚbool)rÁ   ri   rÄ   rÅ   Ú
streampathrk   rø   r¬  r†   ÚfmtidÚ	num_propsÚexcÚmsgr"   Úproperty_idrñ   Úproperty_typerÐ   Úcountr�   s                       r1   rË   zOleFileIO.getproperties2  sæ  € ð ˜DÒ Ð ØˆMàˆ
Ý˜*¥cÑ*Ô*ð 	.ØŸš *Ñ-Ô-ˆJà�_Š_˜XÑ&Ô&ˆàˆð	à—’˜‘”ˆAÝ˜1˜Q˜r˜Tœ7‘O”OˆEð —’˜‘”ˆAÝ˜1˜S˜b˜Sœ6‘N”NˆEØ�GŠG•C˜˜2‘J”JÑÔÐð ˜"Ÿ'š'¥# b§g¢g¨a¡j¤j¡/¤/°!Ñ"3Ñ4Ô4Ñ4ˆAå˜A˜q™	œ	ˆIˆIøÝð 	ð 	ð 	ð 	õ
 �ZÑ Ô Ð Ð  # #ð'ˆCà×ÒÕ/°µd¸3±i´iÑ@Ô@Ð@ØˆKˆKˆKˆKˆKˆKøøøøð	øøøõ ˜	¥3¥s¨1¡v¤v°¡z¡?¤?Ñ3Ô3ˆ	å˜9Ñ%Ô%ð b	Eñ b	EˆAØˆKð`EÝ! ! Q q¨¡s¡U™mœm�Ý˜Q  1 Q¡3¡™œ�Ý # A v¡¤�å—	’	Ð=ÀÈmÐ]cÐ@dÑdÑeÔeÐeð
 !¥EÒ)Ð)Ý  6¨!¡8Ñ,Ô,�EØ ’~�~Ø %¨¡˜ùØ"¥fÒ,Ð,Ý  6¨!¡8Ñ,Ô,�E‘EØ"¥u­fµhÐ&?Ð?Ð?õ    6¨!¡8Ñ,Ô,�E‘EØ"¥v­wÐ&7Ð7Ð7Ý  6¨!¡8Ñ,Ô,�E‘EØ"¥wµÐ&9Ð9Ð9õ
    6¨!¡8Ñ,Ô,�EØ˜f Q™h v¨a¡x°¡~°aÑ'7Ð7Ô8�Eà!ŸMšM¨'°3Ñ7Ô7�E‘EØ"¥gÒ-Ð-õ    6¨!¡8Ñ,Ô,�EØ˜f Q™h v¨a¡x°¡~Ð5Ô6�E‘EØ"¥iÒ/Ð/õ
    6¨!¡8Ñ,Ô,�EØ ×2Ò2°1°V¸A±X¸fÀQ¹hÀuÈQÁwÑ>NÐ5NÔ3OÑPÔP�E‘EØ"¥kÒ1Ð1Ý ¥ Q¨¨q©Ñ!1Ô!1Ñ2Ô2µd½3¸qÀ&ÈÁ(Ñ;KÔ;KÑ6LÔ6LÈbÑ6PÑQ�Eð $ð 2¨¸=Ð(HÐ(HÝŸ	š	Ð"\Ø"-¨uµe¸E±l´lÀ8Ñ6KÐ!Lñ#Mñ Nô Nð Nõ /7Ô.?ÀÀaÈÈAÈqÐRSÑ.TÔ.TÐ+ÝŸ	š	Ð"5¸ÐASÑ9TÑ"UÑVÔVÐVØ 3µhÔ6HÐV[Ð]_ÑV_Ð6`Ñ6`Ô6`Ñ `˜˜ð !&¨Ñ 1˜˜Ø"¥fÒ,Ð,Ý˜q ¨¡œ{™OœO�E�EØ"¥hÒ.Ð.Ý" 1 V¨A¡X¨f°R©iÐ%7Ô#8Ñ9Ô9�E�EØ"¥eÒ+Ð+õ    6¨!¡8Ñ,Ô,�EØ˜f Q™h v¨a¡x°¡~Ð5Ô6�E�EØ"¥gÒ-Ð-õ !¥ Q¨¨q©Ñ!1Ô!1Ñ2Ô2�E�Eà �EÝ—I’IÐUÐYdÐfsÐXtÑtÑuÔuÐuð %*��[Ñ!Ñ!øÝ ð Eð Eð Eð LØ¥ jÑ!1Ô!1°3ðO8ñ 8�à×"Ò"Õ#3°S½$¸s¹)¼)ÑDÔDÐDÐDÐDÐDÐDÑDøøøøðEøøøð ˆs8   ÁCD Ä
E(Ä?E#ÅE(Å#E(Æ-M5T$Ô$
U7Ô.>U2Õ2U7c                 ój   — t          ¦   «         | _        | j                             | ¦  «         | j        S )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
        )r   rY  rÑ   rÀ   s    r1   Úget_metadatazOleFileIO.get_metadataÊ  s-   € õ $™œˆŒØŒ×&Ò& tÑ,Ô,Ð,ØŒ}Ðr3   )rx  )FrD  )r�   )TF)FN),rÚ   rÛ   rÜ   rÝ   r   r   rÂ   rm  rq  r²  ré   r  rh   ro  r  r™  r¢  r¥  r®  r„  r  r©  rÇ  rË  r…  r&  rÑ  r   r¼  r×  rÞ  rã  ræ  rï  ró  rõ  r÷  r@  rC  rÊ   rý  rÿ  rË   r  r8   r3   r1   r   r   Ì  sº  € € € € € ðð ð8 !%°LØ!¨Ð>SðJ7ð J7ð J7ð J7ðZð ð ðð ð ð CJð !ð !ð !ð !ð4ð ð ð ð&]6ð ]6ð ]6ð ]6ð@ð ð ð,ð ,ð ,ð ,ð4"ð "ð "ð "ðJð ð ð ð2	ð 	ð 	ð!ð !ð !ðHQ#ð Q#ð Q#ðh"'ð "'ð "'ðHð ð ð@ð ð ð ð4ð ð ð ð4&'ð &'ð &'ðR$ð $ð $ð4ð ð ð #/¸%ð #-ð #-ð #-ð #-ðLBð Bð Bð Bð:ð ð ð ðð ð ð@8ð 8ð 8ð*;ð ;ð ;ð$;Gð ;Gð ;Gð|ð ð ð(ð ð ð ð  ð  ð  ð  ð  ð ð ð ð ð ð ð"ð ð ðVð Vð Vð Vðp
ð 
ð 
ð 
ð 
r3   r   c                  óF  — ddl } ddl}d}t          j        t          j        t          j        t          j        t          j        dœ}d}|                     |¬¦  «        }| 	                    ddd	d
¬¦  «         | 	                    dddd¬¦  «         | 	                    dddd|d¬¦  «         | 
                    ¦   «         \  }}t          dt          ›dt          ›d�¦  «         t          |¦  «        dk    r7t          t          ¦  «         |                     ¦   «           | j        ¦   «          |j        rd|_        t          j        ||j                 d¬¦  «         t+          ¦   «          |D �]5}	 t-          |¦  «        }	t          d¦  «         t          |¦  «         t          d¦  «         |	                     ¦   «          |	                     ¦   «         D �]}
|
d         d         dk    ròt          d|
z  ¦  «         	 |	                     |
d¬ ¦  «        }t5          |                     ¦   «         ¦  «        }|D ]~\  }}t9          |t:          t<          f¦  «        rt          |¦  «        d!k    r
|dd!…         }t9          |t<          ¦  «        rd"D ]}|t?          |¦  «        v rd#} nŒt          d$||¦  «         ŒŒâ#  t@           !                    d%|
z  ¦  «         Y �ŒxY w�Œ	|j"        rÔt          d&¦  «         |	                     ¦   «         D ]¢}
t          d'tG          d( $                    |
¦  «        ¦  «        d'd¬)¦  «         |	 %                    |
¦  «        }|tL          k    r;t          d*|	 '                    |
¦  «        z  ¦  «         |	 (                    |
¦  «         Œ�t          d+|z  ¦  «         Œ£t          ¦   «          t          d,¦  «         |	j)        D ]E}|�At          d-|j*        ›d.| +                    ¦   «         ›d/| ,                    ¦   «         ›�¦  «         ŒFt          ¦   «          	 |	 -                    ¦   «         }| .                    ¦   «          n!#  t@           !                    d0¦  «         Y nxY wt          ¦   «          |	 /                    ¦   «         }t          d1|z  ¦  «         |	 0                    d2¦  «        ryt          d3¦  «         t          d4|	 %                    d2¦  «        ¦  «         t          d5|	 '                    d2¦  «        ¦  «         |	 0                    d6¦  «        rt          d7¦  «         t          d8¦  «         |	j1        r(|	j1        D ]\  }}t          d-|j2        ›d9|›�¦  «         Œ nt          d:¦  «         �Œ#  t@           !                    d;|z  ¦  «         Y �Œ4xY wdS )<z­
    Main function when olefile is runs as a script from the command line.
    This will open an OLE2 file and display its structure and properties
    :return: nothing
    r   Nrt  )rå   Úinfort  rs  Úcriticalz1usage: %prog [options] <filename> [filename2 ...])Úusagez-cÚ
store_trueÚcheck_streamsz*check all streams (for debugging purposes))ÚactionÚdestÚhelpz-dÚ
debug_modez\debug mode, shortcut for -l debug (displays a lot of debug information, for developers only)z-lz
--loglevelÚloglevelÚstorezBlogging level debug/info/warning/error/critical (default=%default))r'  r&  Údefaultr(  zolefile version r8  z( - https://www.decalage.info/en/olefile
rå   z%(levelname)-8s %(message)s)r/   ÚformatzD--------------------------------------------------------------------éÿÿÿÿúz%r: propertiesTrÆ   é2   )r$   r:   r#   r    r;   r<   r=   rA   rB   rD   é   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   z(binary data)z   z&Error while parsing property stream %rz
Checking streams...ú-rà  r9  zsize %dzNOT a stream : type=%dz5Modification/Creation times of all directory entries:rÓ   z: mtime=z ctime=zError while parsing metadatazRoot entry name: "%s"ÚworddocumentzThis is a Word document.ztype of stream 'WordDocument':zsize :z
macros/vbaz%This document may contain VBA macros.z(
Non-fatal issues raised during parsing:rÔ   ÚNonezError while parsing file %r)3rž  Úoptparser&   r¨  ÚINFOÚWARNINGÚERRORÚCRITICALÚOptionParserÚ
add_optionÚ
parse_argsrÕ   Ú__version__Ú__date__rd   rÝ   Ú
print_helpÚexitr)  r*  ÚbasicConfigr   r   rÑ  rÞ  rË   ÚsortedÚitemsrf   rá  rg   rƒ  r6   Ú	exceptionr%  r×   rì   rõ  r   rý  ræ  r%  r.   r@  rC  r  rÙ   rÿ  rÊ   rK  rÚ   )rž  r5  ÚDEFAULT_LOG_LEVELÚ
LOG_LEVELSr#  ÚparserÚoptionsrp  ri   ræ   Ú
streamnamerÏ   ÚkÚvrp   Úst_typer  Úmetarg  Úexctyper  s                        r1   ÚmainrO  Û  s  € ð ÐÐÐÐÐÐÐà!Ðå”MÝ”LÝ”OÝ”MÝÔ$ð
ð 
€Jð @€EØ×"Ò"¨Ð"Ñ/Ô/€FØ
×Ò�d <°oØ9ð ñ ;ô ;ð ;à
×Ò�d <°lØkð ñ mô mð mà
×Ò�d˜L¨zÀ'ÐSdØ!eð ñ gô gð gð ×'Ò'Ñ)Ô)�O€Wˆdå	€EÍkÈkÈkÕ[cÐ[cÐ[cÐ
dÑeÔeÐeõ ˆ4�y„y�A‚~€~Ý�g‰ŒˆØ×ÒÑÔÐØˆŒ‰
Œ
ˆ
àÔð #Ø"ˆÔõ Ô˜j¨Ô)9Ô:ÐC`ÐaÑaÔaÐaõ ÑÔÐàð RDñ RDˆðQ	DÝ˜HÑ%Ô%ˆCÝ�(‰OŒOˆOÝ�(‰OŒOˆOÝ�(‰OŒOˆOØ×ÒÑÔÐØ!Ÿkšk™mœmð ]ñ ]�
Ø˜b”> !Ô$¨Ò.Ð.ÝÐ*¨ZÑ7Ñ8Ô8Ð8ð]Ø #× 1Ò 1°*È4Ð 1Ñ PÔ P˜Ý & u§{¢{¡}¤}Ñ 5Ô 5˜Ø$)ð /ð /™D˜A˜qå)¨!­j½%Ð-@ÑAÔAð /Ý#& q¡6¤6¨B¢; ;Ø()¨#¨2¨#¬ AÝ)¨!­UÑ3Ô3ð .ð*Fð !.ð !. Aà'(­I°a©L¬LÐ'8Ð'8Ø,;¨Ø(-¨ð (9õ " %¨¨AÑ.Ô.Ð.Ð.ð/øð]ÝŸšÐ&NÐQ[Ñ&[Ñ\Ô\Ð\Ð\Ñ\øøøñ' /ð* Ô$ð åÐ-Ñ.Ô.Ð.Ø"%§+¢+¡-¤-ð 	Bð 	B�Jå˜#�t C§H¢H¨ZÑ$8Ô$8Ñ9Ô9¸#À3ÐGÑGÔGÐGØ!Ÿlšl¨:Ñ6Ô6�GØ¥,Ò.Ð.Ý˜i¨#¯,ª,°zÑ*BÔ*BÑBÑCÔCÐCàŸš zÑ2Ô2Ð2Ð2åÐ6¸Ñ@ÑAÔAÐAÐAÝ‘”�õ ÐIÑJÔJÐJØœð =ð =�ØÐ$Ý�E°u´z°z°zØŸšÑ(Ô(Ð(Ð(¨%¯.ª.Ñ*:Ô*:Ð*:ð<ñ =ô =ð =øå‰GŒGˆGð>Ø×'Ò'Ñ)Ô)�Ø—	’	‘”��øð>Ý—’Ð<Ñ=Ô=Ð=Ð=Ð=øøøÝ‰GŒGˆGà×)Ò)Ñ+Ô+ˆDÝÐ)¨DÑ0Ñ1Ô1Ð1Ø�zŠz˜.Ñ)Ô)ð CÝÐ0Ñ1Ô1Ð1ÝÐ6¸¿ºÀ^Ñ8TÔ8TÑUÔUÐUÝ�h §¢¨^Ñ <Ô <Ñ=Ô=Ð=Ø—:’:˜lÑ+Ô+ð CÝÐAÑBÔBÐBõ Ð=Ñ>Ô>Ð>ØÔ!ð Ø$'Ô$6ð @ð @‘L�G˜SÝ�E¨Ô(8Ð(8Ð(8¸#¸#Ð>Ñ?Ô?Ð?Ð?ð@õ �f‘”�ùøð	DÝ�MŠMÐ7¸(ÑBÑCÔCÐCÐCÑCøøøðeRDð RDs@   Å.BU<Ç:B9J4Ê3U<Ê4KËEU<Ð!(Q
Ñ	U<Ñ
Q(Ñ&DU<Õ<VÚ__main__rD  )mrÝ   Ú
__future__r   r>  r=  Ú
__author__Ú__all__rî   rž  rx   rœ  Úos.pathr€  rŒ   r&   rÓ  rg   ru   r  Úxranger³  rÌ   Úitemsizer�  rÄ  rá  Ú	NameErrorr
   Úversion_infor   r9  r2   r6   r   r   r   r   r   r   r   r   r   r	   r   r   r   r   r   r   ÚVT_EMPTYÚVT_NULLr  r  ÚVT_R4ÚVT_R8ÚVT_CYÚVT_DATEr  ÚVT_DISPATCHr  r  Ú
VT_VARIANTÚ
VT_UNKNOWNÚ
VT_DECIMALÚVT_I1r  r  r	  ÚVT_I8ÚVT_UI8r  r
  ÚVT_VOIDÚ
VT_HRESULTÚVT_PTRÚVT_SAFEARRAYÚ	VT_CARRAYÚVT_USERDEFINEDr  r  r  r  Ú	VT_STREAMÚ
VT_STORAGEÚVT_STREAMED_OBJECTÚVT_STORED_OBJECTÚVT_BLOB_OBJECTr  r  Ú	VT_VECTORr   r   r   r   r   r   r   rq   r|   r   r‡   r�   r   rï   rß   rû   r   rO  rÚ   r8   r3   r1   ú<module>rr     s‘  ððð ð8 &Ð %Ð %Ð %Ð %Ð %ðx €Ø€Ø €
ðð ð €ð 
€	€	€	Ø 
€
€
€
Ø 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0ð
 ˆeÐÐØ€Dðà€I€Iøðà€I€I€Iøøøð €5„;ˆsÑÔÔ Ò!Ð!à€F€FØ€U„[�ÑÔÔ !Ò#Ð#à€F€FØ€U„[�ÑÔÔ !Ò#Ð#ð €F€Fà
ˆ*ÐUÑ
VÔ
VÐVð
Ø€J€JøØð ð ð Ø€J€J€Jðøøøð
 Ð àÔ�AÔ˜ÒÐà#ÐÐð !Ðð
 #Ô+¨AÑ-ð ð ð ð ð8 €j�ÑÔ€ð!ð !ð !ð 	,€ð €
Ø€Ø€Ø€
Ø€ð €	Ø€ð €Ø€Ø€Ø€Ø€Ø€
ð €ð 
€�AˆG˜Q�u a ¨q¨¸°%À¸5Ø	€�1ˆ7 !�k¨b X¸"°'Ø€
˜"ˆz¨˜j°2¨U¸b°vØ	€�"ˆ6˜B�e r °"¨6¸b°gØ
€�rˆJ "˜6°2 lÀ°yØ€˜B�8¨" 	¸"¨kØ
€�bˆI R˜*¸BÐ);ØÐ  B�^¨b¨¸2°(Ø
€	ð 4€
ð €ØÐ ØÐ à€ð
 Ð ð
'ð 'ð 'ðT 	ˆC€<€<ðð ð ð ð1ð 1ð 1ð,ð ,ð ,ð ,ð,ð ,ð ,ð ,ð*ð *ð *ð"Sð Sð SðW4ð W4ð W4ð W4ð W4ñ W4ô W4ð W4ðxP(ð P(ð P(ð P(ð P(�”
ñ P(ô P(ð P(ðl[2ð [2ð [2ð [2ð [2ñ [2ô [2ð [2ð@	Hð Hð Hð Hð Hñ Hô Hð Hð^(Dð Dð DðD ˆzÒÐØ€D�F„F€F€F€Fð Ðs   ¶9 ¹?Â"B% Â%B/Â.B/