
C#[c           @  s   d  Z  d d l m Z d Z d Z d Z 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  g 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 k	 r e Z n  y
 e Z Wn e Z n Xe
 j
 d"  j d# k r#d" Z nN e
 j
 d$  j d# k rDd$ Z n- e
 j
 d%  j d# k red% Z n e d&   y e Wn e k
 re Z n Xe Z e j d' d( k  rd) Z n e Z e j  d* d+  Z! e! d,  Z" d-   Z# d. Z$ d/ Z% d0 Z& d1 Z' d2 Z( d3 Z) d/ Z* d3 Z+ d' Z, d* Z- d4 Z. d( Z/ d# Z0 d5 Z1 d6 Z2 d' Z3 d* Z4 d4 Z5 d( Z6 d# Z7 d5 Z8 d7 Z9 d8 Z: d9 Z; d: Z< d; Z= d< Z> d= Z? d> Z@ d? ZA d@ ZB dA ZC dB ZD dC ZE dD ZF dE ZG dF ZH dG ZI dH ZJ dI ZK dJ ZL dK ZM dL ZN dM ZO dN ZP dO ZQ dP ZR dQ ZS dR ZT dS ZU dT ZV dU ZW dV ZX dW ZY dX ZZ dY Z[ dZ Z\ d; Z] dD Z^ dN Z_ d[ Z` d\ Za d]   Zb e e k rxd^   Zc n	 d_   Zc d' d`  Zd d' da  Ze db   Zf dc   Zg d f  dd     YZh de e ji f df     YZj dg f  dh     YZk d f  di     YZl dj   Zm en dk k rem   n  d! S(l   s:  
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.
i(   t   print_functions
   2018-09-09s   0.46s   Philippe Lagadect	   isOleFilet	   OleFileIOt   OleMetadatat   enable_loggingt   MAGICt   STGTY_EMPTYt   KEEP_UNICODE_NAMESt   STGTY_STREAMt   STGTY_STORAGEt
   STGTY_ROOTt   STGTY_PROPERTYt   STGTY_LOCKBYTESt   MINIMAL_OLEFILE_SIZEt   DEFECT_UNSUREt   DEFECT_POTENTIALt   DEFECT_INCORRECTt   DEFECT_FATALt   DEFAULT_PATH_ENCODINGt
   MAXREGSECTt   DIFSECTt   FATSECTt
   ENDOFCHAINt   FREESECTt	   MAXREGSIDt   NOSTREAMt   UNKNOWN_SIZEt
   WORD_CLSIDNt   Li   t   It   is>   Need to fix a bug with 32 bit arrays, please contact author...i    i   s   utf-8i   c         C  sh   |  t  j j j k r5 t  j |   } | j |  | St  j |   } | j t  j    | j |  | S(   sn  
    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.
    (   t   loggingt   Loggert   managert
   loggerDictt	   getLoggert   setLevelt
   addHandlert   NullHandler(   t   namet   levelt   logger(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt
   get_logger   s    t   olefilec           C  s   t  j t j  d S(   s   
    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(   t   logR$   R   t   NOTSET(    (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR      s    s   ࡱI    I    I    I    I    i   i   ii   i   i   i	   i
   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i@   iA   iB   iC   iD   iE   iF   iG   iH   i   s$   00020900-0000-0000-C000-000000000046i(   i   c         C  s   t  |  d  r4 |  j t t   } |  j d  na t |  t  rh t |   t k rh |  t t   } n- t |  d   } | j t t   } Wd QX| t k r t	 St
 Sd S(   sJ  
    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
    t   readi    t   rbN(   t   hasattrR.   t   lenR   t   seekt
   isinstancet   bytesR   t   opent   Truet   False(   t   filenamet   headert   fp(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR     s    !c         C  s
   t  |   S(   N(   t   ord(   t   c(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   i8?  s    c         C  s   |  j  t k r |  S|  d S(   Ni    (   t	   __class__t   int(   R<   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR=   C  s    c         C  s   t  j d |  | | d ! d S(   s   
    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
    s   <Hi   i    (   t   structt   unpack(   R<   t   o(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   i16G  s    c         C  s   t  j d |  | | d ! d S(   s   
    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
    s   <Ii   i    (   R@   RA   (   R<   RB   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   i32Q  s    c         C  sy   t  |   d k s t  |  j d  s+ d Sd d d t |  d  t |  d  t |  d  f t t t |  d	 d !  S(
   s^   
    Converts a CLSID to a human-readable string.

    :param clsid: string of length 16.
    i   s    t    s   %08X-%04X-%04X-%02X%02X-s   %02Xi   i    i   i   (   R1   t   AssertionErrort   stripRD   RC   t   tuplet   mapR=   (   t   clsid(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   _clsid[  s    'c         C  s6   t  j  d d d d d d  } | t  j d |  d  S(   sL   
        convert FILETIME (64 bits int) to Python datetime.datetime
        iA  i   i    t   microsecondsi
   (   t   datetimet	   timedelta(   t   filetimet   _FILETIME_null_date(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   filetime2datetimel  s    c           B  s   e  Z d  Z d d d d d d d d d	 d
 d d d d d d d d d g Z 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/ g Z d0   Z d1   Z d2   Z RS(3   sT  
    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
    t   codepaget   titlet   subjectt   authort   keywordst   commentst   templatet   last_saved_byt   revision_numbert   total_edit_timet   last_printedt   create_timet   last_saved_timet	   num_pagest	   num_wordst	   num_charst	   thumbnailt   creating_applicationt   securityt   codepage_doct   categoryt   presentation_targetR4   t   linest
   paragraphst   slidest   notest   hidden_slidest   mm_clipst
   scale_cropt   heading_pairst   titles_of_partsR!   t   companyt   links_dirtyt   chars_with_spacest   unusedt
   shared_doct	   link_baset   hlinkst   hlinks_changedt   versiont   dig_sigt   content_typet   content_statust   languaget   doc_versionc         C  s  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(   s_   
        Constructor for OleMetadata
        All attributes are set to None by default
        N(0   t   NoneRR   RS   RT   RU   RV   RW   RX   RY   RZ   R[   R\   R]   R^   R_   R`   Ra   Rb   Rc   Rd   Re   Rf   Rg   R4   Rh   Ri   Rj   Rk   Rl   Rm   Rn   Ro   Rp   R!   Rq   Rr   Rs   Rt   Ru   Rv   Rw   Rx   Ry   Rz   R{   R|   R}   R~   (   t   self(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   __init__  s^    																																														c         C  s   x( |  j  |  j D] } t |  | d  q W| j d  r | j d d t d d g } xM t t |  j    D]3 } | j	 | d d  } t |  |  j  | |  qn Wn  | j d  r| j d d t } xM t t |  j   D]3 } | j	 | d d  } t |  |  j | |  q Wn  d S(   s=  
        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.
        s   SummaryInformationt   convert_timet   no_conversioni
   i   s   DocumentSummaryInformationN(
   t   SUMMARY_ATTRIBSt   DOCSUM_ATTRIBSt   setattrR   t   existst   getpropertiesR6   t   rangeR1   t   get(   R   R+   t   attribt   propsR   t   value(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   parse_properties  s    		c         C  s   t  d  x: |  j D]/ } t |  |  } t  d | t |  f  q Wt  d  x: |  j D]/ } t |  |  } t  d | t |  f  q[ Wd S(   s<   
        Dump all metadata, for debugging purposes.
        s*   Properties from SummaryInformation stream:s   - %s: %ss2   Properties from DocumentSummaryInformation stream:N(   t   printR   t   getattrt   reprR   (   R   t   propR   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   dump  s    

(   t   __name__t
   __module__t   __doc__R   R   R   R   R   (    (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR   z  s   !		8	 t	   OleStreamc           B  s   e  Z d  Z d   Z RS(   s  
    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	      
   C  s'  t  j d  t  j d | | | | | t |  t |  f  | |  _ |  j j j rf t d   n  t }	 | t	 k r t |  | } t
 }	 t  j d  n  | | d | }
 t  j d |
  |
 t |  k r |  j j t d  n  g  } | d k r*| t k r*t  j d	  |  j j t d
  n  x!t |
  D]} t  j d | | f  | t k r|	 rwt  j d  Pqt  j d  |  j j t d  n  | d k  s| t |  k rt  j d | | t |  f  t  j d | |
 f  |  j j t d  Pn  y | j | | |  Wn= t  j d | | | | | f  |  j j t d  Pn X| j |  } t |  | k r| t |  d k rt  j d | t |  | | | | t |  f  t  j d | | | t |   |  j j t d  n  | j |  y | | d @} Wq7t k
 rI|  j j t d  Pq7Xq7Wd j |  } t |  | k rt  j d t |  | f  | |  } | |  _ nn |	 rt  j d t |   t |  |  _ n? t  j d t |  | f  t |  |  _ |  j j t d  t j j |  |  d S(   s_  
        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
        s   OleStream.__init__:sE     sect=%d (%X), size=%d, offset=%d, sectorsize=%d, len(fat)=%d, fp=%ss2   Attempting to open a stream from a closed OLE Files     stream with UNKNOWN SIZEi   s   nb_sectors = %ds(   malformed OLE document, stream too largei    s!   size == 0 and sect != ENDOFCHAIN:s+   incorrect OLE sector index for empty streams   Reading stream sector[%d] = %Xhs6   Reached ENDOFCHAIN sector for stream with unknown sizes$   sect=ENDOFCHAIN before expected sizes   incomplete OLE streams   sect=%d (%X) / len(fat)=%ds   i=%d / nb_sectors=%ds,   incorrect OLE FAT, sector index out of ranges   sect=%d, seek=%d, filesize=%ds   OLE sector index out of ranges9   sect=%d / len(fat)=%d, seek=%d / filesize=%d, len read=%ds   seek+len(read)=%ds   incomplete OLE sectorI    RE   s3   Read data of length %d, truncated to stream size %ds3   Read data of length %d, the stream size was unknowns9   Read data of length %d, less than expected stream size %ds%   OLE stream size is less than declaredN(   R,   t   debugR1   R   t   oleR:   t   closedt   OSErrorR7   R   R6   t   _raise_defectR   R   R   R2   R.   t   appendt
   IndexErrort   joint   sizet   iot   BytesIOR   (   R   R:   t   sectR   t   offsett
   sectorsizet   fatt   filesizet	   olefileiot   unknown_sizet
   nb_sectorst   dataR   t   sector_data(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR   *  s~    	)	 	(	+#	
(   R   R   R   R   (    (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR     s   t   OleDirectoryEntryc           B  s   e  Z d  Z d Z d Z e j e  e k s3 t  d   Z d   Z	 d   Z
 d   Z d   Z d   Z d	   Z d
   Z d d  Z d   Z d   Z RS(   s   
    OLE2 Directory Entry
    s   <64sHBBIII16sIQQIIIi   c         C  sc  | |  _  | |  _ g  |  _ i  |  _ t |  _ t j t j	 |  \ |  _
 |  _ |  _ |  _ |  _ |  _ |  _ } |  _ |  _ |  _ |  _ |  _ |  _ |  j t t t t g k r | j t d  n  |  j t k r | d k r | j t d  n  | d k r|  j t k r| j t d  n  |  j d k rH| j t d  d |  _ n  |  j
 |  j d  |  _ | j |  j  |  _ t  j! d |  j  t" |  j  f  t  j! d	 |  j  t  j! d
 |  j  t  j! d |  j |  j |  j f  | j# d k rZ|  j d k rK|  j d k rKt  j! d | j# |  j |  j |  j f  | j t$ d  n  |  j |  _% n |  j t& |  j  d >|  _% t  j! d |  j% |  j |  j f  t' |  |  _( |  j t k r|  j% d k r| j t) d  n  t |  _* |  j t t f k rV|  j% d k rV|  j% | j+ k  r4|  j t k r4t, |  _* n	 t |  _* | j- |  j |  j*  n  d |  _/ d S(   sI  
        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
        s   unhandled OLE storage typei    s   duplicate OLE root entrys   incorrect OLE root entryi@   s(   incorrect DirEntry name length >64 bytesi   s   DirEntry SID=%d: %ss    - type: %ds    - sect: %Xhs%    - SID left: %d, right: %d, child: %di   I    s+   sectorsize=%d, sizeLow=%d, sizeHigh=%d (%X)s   incorrect OLE stream sizei    s%    - size: %d (sizeLow=%d, sizeHigh=%d)s   OLE storage with size>0N(0   t   sidR+   t   kidst	   kids_dictR7   t   usedR@   RA   R   t   STRUCT_DIRENTRYt   name_rawt
   namelengtht
   entry_typet   colort   sid_leftt	   sid_rightt	   sid_childt   dwUserFlagst
   createTimet
   modifyTimet
   isectStartt   sizeLowt   sizeHighR
   R	   R   R   R   R   t
   name_utf16t   _decode_utf16_strR'   R,   R   R   R   R   R   t   longRK   RJ   R   t
   is_minifatt   minisectorcutoffR6   t   _check_duplicate_streamR   t
   sect_chain(   R   t   entryR   R+   RJ   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR     sR    						f#	 #	$	c         C  s   |  j  r d  S|  j t t f k s1 |  j d k r5 d  St   |  _  |  j ra | j ra | j   n  |  j	 } xF | t
 k r |  j  j |  |  j r | j | } qm | j | } qm Wd  S(   Ni    (   R   R   R
   R   R   t   listR   t   minifatt   loadminifatR   R   R   R   (   R   R+   t	   next_sect(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   build_sect_chain-  s    	$		c         C  s\   t  j d |  j t |  j  |  j f  |  j t k rX |  j |  j  |  j j	   n  d S(   s   
        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.
        s.   build_storage_tree: SID=%d - %s - sid_child=%dN(
   R,   R   R   R   R'   R   R   t   append_kidsR   t   sort(   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   build_storage_tree@  s
    	 	c         C  sJ  t  j d |  | t k r! d S| d k  sE | t |  j j  k r[ |  j j t d  n |  j j |  } t  j d | j	 t
 | j  | j | j | j f  | j r |  j j t d  d St | _ |  j | j  | j j   } | |  j k r|  j j t d  n  |  j j |  | |  j | <|  j | j  | j   d S(   s)  
        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)
        s   append_kids: child_sid=%dNi    s   OLE DirEntry index out of rangesH   append_kids: child_sid=%d - %s - sid_left=%d, sid_right=%d, sid_child=%ds#   OLE Entry referenced more than onces!   Duplicate filename in OLE storage(   R,   R   R   R1   R+   t
   direntriesR   R   t   _load_direntryR   R   R'   R   R   R   R   R6   R   t   lowerR   R   R   R   (   R   t	   child_sidt   childt
   name_lower(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR   X  s,    $	,		
c         C  s   |  j  | j  k S(   s   Compare entries by name(   R'   (   R   t   other(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   __eq__  s    c         C  s   |  j  | j  k  S(   s   Compare entries by name(   R'   (   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   __lt__  s    c         C  s   |  j  |  S(   N(   R   (   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   __ne__  s    c         C  s   |  j  |  p |  j |  S(   N(   R   R   (   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   __le__  s    i    c         C  s   d d d d d d g } y | |  j  } Wn t k
 rB d } n Xt d | t |  j  | d	 d |  j  t t f k r t |  j d
 d	 d n  t   |  j  t t f k r |  j	 r t d | d |  j	  n  x" |  j
 D] } | j | d  q Wd S(   sA   Dump this entry, and all its subentries (for debug purposes only)s	   (invalid)s	   (storage)s   (stream)s   (lockbytes)s
   (property)s   (root)s	   (UNKNOWN)t    t   endR4   s   {%s}i   N(   R   R   R   R   R'   R   R
   R   R	   RJ   R   R   (   R   t   tabt   TYPESt	   type_namet   kid(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR     s    
$c         C  s    |  j  d k r d St |  j   S(   s   
        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
        i    N(   R   R   RQ   (   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   getmtime  s    	c         C  s    |  j  d k r d St |  j   S(   s   
        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
        i    N(   R   R   RQ   (   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   getctime  s    	(   R   R   R   R   t   DIRENTRY_SIZER@   t   calcsizeRF   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR     s   	b			/						c           B  s  e  Z d  Z d( e e e e d  Z d   Z d   Z	 e
 d  Z d d  Z e d  Z d   Z e 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 e d  Z e e d  Z e 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+ e d( d&  Z, d'   Z- RS()   s  
    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).
    c         C  s  | |  _  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|  j( | d | n  d S(   s  
        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)
        t
   write_modeN()   t   _raise_defects_levelt   parsing_issuesR   t   path_encodingR   t	   _filesizet
   ministreamt   _used_streams_fatt   _used_streams_minifatt
   byte_ordert   directory_fpR   t   dll_versionR   t   first_difat_sectort   first_dir_sectort   first_mini_fat_sectorR:   t   header_clsidt   header_signaturet   metadatat   mini_sector_shiftt   mini_sector_sizet   mini_stream_cutoff_sizeR   t   minifatsectR   t   minisectorsizet   minor_versiont   nb_sectt   num_difat_sectorst   num_dir_sectorst   num_fat_sectorst   num_mini_fat_sectorst	   reserved1t	   reserved2t   roott   sector_shiftt   sector_sizet   transaction_signature_numberR5   (   R   R8   t   raise_defectsR   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR     sT    																																								c         C  s   |  S(   N(    (   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt	   __enter__6  s    c         G  s   |  j    d  S(   N(   t   close(   R   t   args(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   __exit__:  s    c         C  sR   | |  j  k r+ t j |  | |   n# |  j j | | f  t j |  d S(   s  
        This method should be called for any defect found during file parsing.
        It may raise an IOError exception according to the minimal level chosen
        for the OleFileIO object.

        :param defect_level: defect level, possible values are:

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

        :param message: string describing the defect, used with raised exception.
        :param exception_type: exception class to be raised, IOError by default
        N(   R   R,   t   errorR   R   t   warning(   R   t   defect_levelt   messaget   exception_type(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR   >  s
    t   replacec         C  s6   | j  d |  } |  j r. | j |  j |  S| Sd S(   s  
        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
        s   UTF-16LEN(   t   decodeR   t   encode(   R   t	   utf16_strt   errorst   unicode_str(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR   X  s    
	c   	      C  s9  | |  _  t | d  r$ | |  _ n` t | t  rZ t |  t k rZ t j |  |  _ n* |  j  rl d } n d } t	 | |  |  _ d } |  j j
 d t j  z |  j j   } Wd |  j j
 d  X| |  _ t j d |  j |  j f  g  |  _ g  |  _ |  j j d  } t |  d k s3| d  t k rat j d	 | d  t f  |  j t d
  n  d } t j |  } t j d | | d2 f  | |  } t j | |  \ |  _ |  _ |  _ |  _ |  _ |  _ |  _  |  _! |  _" |  _# |  _$ |  _% |  _& |  _' |  _( |  _) |  _* |  _+ t j t j | |   |  j t k rT|  j t d  n  |  j t, d  k r||  j t- d  n  t j d |  j  t j d |  j  |  j d3 k r|  j t- d  n  t j d |  j  |  j d k r|  j t- d  n  d |  j |  _. t j d |  j.  |  j. d4 k rB|  j t- d  n  |  j d k r`|  j. d k s~|  j d k r|  j. d k r|  j t- d  n  d |  j  |  _/ t j d |  j/  |  j/ d5 k r|  j t- d   n  |  j! d k s|  j" d k r|  j t- d!  n  t j d" |  j#  |  j. d k rM|  j# d k rM|  j t- d#  n  t j d$ |  j$  t j d% |  j%  t j d& |  j&  |  j& d k r|  j t0 d'  n  t j d( |  j'  |  j' d k r|  j t- d)  t j1 d* |  j'  d |  _' n  t j d+ |  j(  t j d, |  j)  t j d- |  j*  t j d. |  j+  | |  j. d/ |  j. d/ |  _2 t j d0 |  j2 |  j2 f  t3 | d d1 ! |  _ |  j. |  _4 |  j/ |  _5 |  j' |  _6 |  j7 |  j%  |  j) r|  j7 |  j(  n  |  j+ r|  j7 |  j*  n  |  j8 |  |  j9 |  j%  |  j( |  _: d S(6   s  
        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)
        R.   s   r+bR/   i    Ns   File size: %d bytes (%Xh)i   i   s   Magic = %r instead of %rs#   not an OLE2 structured storage files   <8s16sHHHHHHLLLLLLLLLLs   fmt_header size = %d, +FAT = %dim   i   s   incorrect OLE signaturei   s   incorrect CLSID in OLE headers   Minor Version = %ds%   DLL Version   = %d (expected: 3 or 4)i   s"   incorrect DllVersion in OLE headers#   Byte Order    = %X (expected: FFFE)i  s!   incorrect ByteOrder in OLE headeri   s0   Sector Size   = %d bytes (expected: 512 or 4096)i   s#   incorrect sector_size in OLE headers3   sector_size does not match DllVersion in OLE headers/   MiniFAT Sector Size   = %d bytes (expected: 64)i@   s(   incorrect mini_sector_size in OLE headers.   incorrect OLE header (non-null reserved bytes)s    Number of Directory sectors = %ds3   incorrect number of directory sectors in OLE headers   Number of FAT sectors = %ds   First Directory sector  = %Xhs$   Transaction Signature Number    = %ds5   incorrect OLE header (transaction_signature_number>0)s/   Mini Stream cutoff size = %Xh (expected: 1000h)s/   incorrect mini_stream_cutoff_size in OLE headersJ   Fixing the mini_stream_cutoff_size to 4096 (mandatory value) instead of %ds   First MiniFAT sector      = %Xhs   Number of MiniFAT sectors = %ds   First DIFAT sector        = %Xhs   Number of DIFAT sectors   = %di   s/   Maximum number of sectors in the file: %d (%Xh)i   i  (   i   i   (   i   i   (   i@   (;   R   R0   R:   R3   R4   R1   R   R   R   R5   R2   t   ost   SEEK_ENDt   tellR   R,   R   R   R   R.   R   R   R   R@   R   RA   R   R   R   R   R   R  R   R  R  R   R   R   R  R   R   R   R   R   t	   bytearrayR   R  R   R   R  R   RK   R   R   R   R   t   loadfatt   loaddirectoryR   (	   R   R8   R   t   modeR   R9   t
   fmt_headert   header_sizet   header1(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR5   k  s    	!					"'
~			c         C  s   |  j  j   d S(   s@   
        close the OLE file, to release the file object
        N(   R:   R	  (   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR	  K  s    c         C  s   | r# t  j d |  |  j } n6 t  j d |  | t t t t f k rP d S|  j } | | k rx |  j t	 d  n | j
 |  d S(   sg  
        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
        s,   _check_duplicate_stream: sect=%Xh in MiniFATs(   _check_duplicate_stream: sect=%Xh in FATNs   Stream referenced twice(   R,   R   R   R   R   R   R   R   R   R   R   (   R   t
   first_sectR   t   used_streams(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR   R  s    		i    c         C  sZ  d } i d t  6d t 6d t 6d t 6} t |  } | | d | } t d d d	 x( t |  D] } t d
 | d d	 qc Wt   x t |  D] } | | }	 t d | |	 d d	 x t |	 |	 |  D]v } | | k r Pn  | | }
 |
 d @} | | k r| | } n# |
 | d k r-d } n
 d
 |
 } t | d d	 q Wt   q Wd S(   sU   
        Display a part of FAT in human-readable form for debugging purposes
        i   s   ..free..s   [ END. ]s   FATSECT s   DIFSECT i   t   indexR   R   s   %8Xs   %6X:I    s       --->N(   R   R   R   R   R1   R   R   (   R   R   t
   firstindext   VPLt   fatnamest   nbsectt   nlinesR   t   lR#  R   t   auxR'   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   dumpfatl  s6    



	
c         C  s*  d } t  j  t |  } t j d k r4 | j   n  t |  } | | d | } t d d d x( t |  D] } t d | d d qo Wt   x t |  D] } | | }	 t d | |	 d d xO t |	 |	 |  D]: } | | k r Pn  | | }
 d |
 } t | d d q Wt   q Wd	 S(
   sS   
        Display a sector in a human-readable form, for debugging purposes
        i   t   bigi   R#  R   R   s   %8Xs   %6X:N(   t   arrayt   UINT32t   syst	   byteordert   byteswapR1   R   R   (   R   t   sectorR$  R%  R   R'  R(  R   R)  R#  R   R'   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   dumpsect  s(    


c         C  s2   t  j  t |  } t j d k r. | j   n  | S(   s   
        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/  R0  R1  (   R   R   t   a(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt
   sect2array  s    c         C  s   t  | t j  r | } n1 |  j |  } t j t j  rL |  j |  n  d } x | D]x } | d @} t j	 d |  | t
 k s | t k r t j	 d  Pn  |  j |  } |  j |  } |  j | |  _ qY W| S(   s   
        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.
        I    s
   isect = %Xs   found end of sector chainN(   R3   R-  R5  R,   t   isEnabledForR   t   DEBUGR3  R   R   R   R   t   getsectR   (   R   R   t   fat1t   isectt   st   nextfat(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   loadfat_sect  s     	
c   	      C  s  t  j d  | d d !} t  j d t |  t |  d f  t j t  |  _ |  j |  |  j d k rt  j d  |  j d k r |  j	 t
 d	  n  |  j |  j k r |  j	 t d
  n  t  j d  |  j d d } |  j d | d | } t  j d |  |  j | k r)t d   n  |  j } x t |  D] } t  j d | | f  |  j |  } |  j |  } t  j t j  r|  j |  n  |  j | |   | | } t  j d |  q?W| t t g k rt d   qn t  j d  t |  j  |  j k rNt  j d t |  j  |  j f  |  j |  j  |  _ n  t  j d t |  j  |  j f  t  j t j  rt  j d  |  j |  j  n  d S(   s%   
        Load the FAT table.
        sD   Loading the FAT table, starting with the 1st sector after the headeriL   i   s   len(sect)=%d, so %d integersi   i    s)   DIFAT is used, because file size > 6.8MB.im   s#   incorrect DIFAT, not enough sectorss)   incorrect DIFAT, first index out of ranges   DIFAT analysis...i   s   nb_difat = %ds   incorrect DIFATs   DIFAT block %d, sector %Xs   next DIFAT sector: %Xs   incorrect end of DIFATs$   No DIFAT, because file size < 6.8MB.s!   len(fat)=%d, shrunk to nb_sect=%ds6   FAT references %d sectors / Maximum %d sectors in files   
FAT:N(   R,   R   R1   R-  R.  R   R=  R   R   R   R   R   R   R   R   t   IOErrort	   iterrangeR8  R5  R6  R   R7  R3  R   R   R+  (	   R   R9   R   t   nb_difat_sectorst   nb_difatt   isect_difatR   t   sector_difatt   difat(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR    sJ    	'
	
##c         C  s0  |  j  |  j } |  j j |  j d |  j } | d } t j d |  j |  j  | | | f  | | k r} |  j t	 d  n  |  j
 |  j | d t j   } |  j |  |  _ t j d t |  j  | f  |  j |  |  _ t j d t |  j   t j t j  r,t j d  |  j |  j  n  d	 S(
   s)   
        Load the MiniFAT table.
        i   i   sa   loadminifat(): minifatsect=%d, nb FAT sectors=%d, used_size=%d, stream_size=%d, nb MiniSectors=%ds%   OLE MiniStream is larger than MiniFATt	   force_FATs$   MiniFAT shrunk from %d to %d sectorss   loadminifat(): len=%ds	   
MiniFAT:N(   R   R  R  R   R   R,   R   R   R   R   t   _openR6   R.   R5  R   R1   R6  R   R7  R+  (   R   t   stream_sizet   nb_minisectorst	   used_sizeR;  (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR   .  s    
	! c         C  s   y |  j  j |  j | d  Wn? t j d | |  j | d |  j f  |  j t d  n X|  j  j |  j  } t	 |  |  j k r t j d | t	 |  |  j f  |  j t d  n  | S(   s   
        Read given sector from file on disk.

        :param sect: int, sector index
        :returns: a string containing the sector data.
        i   s(   getsect(): sect=%X, seek=%d, filesize=%ds   OLE sector index out of ranges*   getsect(): sect=%X, read=%d, sectorsize=%ds   incomplete OLE sector(
   R:   R2   R   R,   R   R   R   R   R.   R1   (   R   R   R2  (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR8  R  s    		s    c         C  s  t  | t  s t d   n  t  | t  s@ t |  d k rO t d   n  y |  j j |  j | d  Wn? t j d | |  j | d |  j	 f  |  j
 t d  n Xt |  |  j k  r | | |  j t |  7} n$ t |  |  j k  rt d   n  |  j j |  d S(   s   
        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
        s'   write_sect: data must be a bytes stringi   s4   write_sect: padding must be a bytes string of 1 chars+   write_sect(): sect=%X, seek=%d, filesize=%ds   OLE sector index out of ranges   Data is larger than sector sizeN(   R3   R4   t	   TypeErrorR1   R:   R2   R   R,   R   R   R   R   t
   ValueErrort   write(   R   R   R   t   padding(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt
   write_sectr  s    "	c         C  s   t  | t  s t d   n  t  | t  s@ t |  d k rO t d   n  y |  j j |  Wn1 t j d | |  j f  |  j	 t
 d  n Xt |  } | |  j k  r | | |  j | 7} n  |  j | k  r t d   n  |  j j |  d S(   s   
        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
        s,   write_mini_sect: data must be a bytes stringi   s9   write_mini_sect: padding must be a bytes string of 1 chars)   write_mini_sect(): fp_pos=%d, filesize=%ds   OLE sector index out of ranges   Data is larger than sector sizeN(   R3   R4   RJ  R1   R:   R2   R,   R   R   R   R   R   RK  RL  (   R   t   fp_posR   RM  t   len_data(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   _write_mini_sect  s     "	c         C  s   t  j d  |  j | d t |  _ |  j j d } t  j d |  j j | f  d g | |  _ |  j d  } |  j d |  _	 |  j	 j
   d S(   s]   
        Load the directory.

        :param sect: sector index of directory stream.
        s   Loading the Directory:RE  i   s&   loaddirectory: size=%d, max_entries=%di    N(   R,   R   RF  R6   R   R   R   R   R   R  R   (   R   R   t   max_entriest
   root_entry(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR    s    	c         C  s   | d k  s! | t  |  j  k r4 |  j t d  n  |  j | d k	 rb |  j t d  |  j | S|  j j | d  |  j j d  } t	 | | |   |  j | <|  j | S(   sY  
        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.
        i    s    OLE directory index out of ranges'   double reference for OLE stream/storagei   N(
   R1   R   R   R   R   R   R   R2   R.   R   (   R   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR     s    !	c         C  s   |  j  j   d S(   s5   
        Dump directory (for debugging only)
        N(   R  R   (   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   dumpdirectory  s    c         C  s&  t  j d | | t |  f  | |  j k  r | r |  j s |  j   |  j j } t  j d |  j j | f  |  j	 |  j j | d t
 |  _ n  t d |  j d | d | d d d	 |  j d
 |  j d |  j j d |   St d |  j d | d | d |  j d	 |  j d
 |  j d |  j d |   Sd S(   s|  
        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.
        s1   OleFileIO.open(): sect=%Xh, size=%d, force_FAT=%ss%   Opening MiniStream: sect=%Xh, size=%dRE  R:   R   R   R   i    R   R   R   R   N(   R,   R   t   strR   R   R   R  R   R   RF  R6   R   R   R   R:   R   R   R   (   R   t   startR   RE  t   size_ministream(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyRF    s&    
		
			c         C  s   | | j  g } x | j D] } | j t k ro | rS | j | d | j  g  n  |  j | | | | |  q | j t k r | r | j | d | j  g  q q |  j t d  q Wd S(   s  
        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)
        i   sI   The directory tree contains an entry which is not a stream nor a storage.N(	   R'   R   R   R	   R   t   _listR   R   R   (   R   t   filest   prefixt   nodet   streamst   storagesR   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyRX    s    !c         C  s&   g  } |  j  | g  |  j | |  | S(   sm  
        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
        (   RX  R  (   R   R\  R]  RY  (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   listdir3  s    	c         C  s   t  | t  r! | j d  } n  |  j } xS | D]K } x< | j D]% } | j j   | j   k rA PqA qA Wt d   | } q1 W| j S(   s*  
        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
        t   /s   file not found(	   R3   t
   basestringt   splitR  R   R'   R   R>  R   (   R   R8   R[  R'   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   _findA  s    	
c         C  sP   |  j  |  } |  j | } | j t k r: t d   n  |  j | j | j  S(   s;  
        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.
        s   this file is not a stream(   Rb  R   R   R   R>  RF  R   R   (   R   R8   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt
   openstreama  s
    c         C  s  | j  s | j |   n  t | j   } |  j j  sG |  j j |   n  |  j |  j } x t | j   D] \ } } | | } | | } |  j j  | d |  j | |  j }	 | | d k  r | | |  j | d |  j !}
 n | | |  j }
 |  j |	 |
  qg Wd  S(   Ni   (   R   R   R1   R  R  R   t	   enumerateRQ  (   R   R   t   data_to_writeR   t
   block_sizet   idxR   t	   sect_baset   sect_offsetRO  t   data_per_sector(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   _write_mini_streamv  s    	

&"c   
      C  s  t  | t  s t d   n  |  j |  } |  j | } | j t k rX t d   n  | j } | t	 |  k r t
 d   n  | |  j k  r | j t k r |  j d | d |  S| j } | |  j d |  j } t j d |  xt |  D] } | | d k  rH| | |  j | d |  j !}	 t	 |	  |  j k st  nd | | |  j }	 t j d | |  j t	 |	  | |  j f  t	 |	  |  j | |  j k st  |  j | |	  y |  j | } Wq t k
 rt d	   q Xq W| t k rt d
   n  d S(   sD  
        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.
        s)   write_stream: data must be a bytes strings   this is not a streams?   write_stream: data must be the same size as the existing streamR   Re  i   s   nb_sectors = %dsG   write_stream: size=%d sectorsize=%d data_sector=%Xh size%%sectorsize=%ds,   incorrect OLE FAT, sector index out of ranges)   incorrect last sector index in OLE streamN(   R3   R4   RJ  Rb  R   R   R   R>  R   R1   RK  R   R
   Rk  R   R   R,   R   R   RF   RN  R   R   R   (
   R   t   stream_nameR   R   R   R   R   R   R   t   data_sector(    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   write_stream  s:    			$&c         C  s6   y' |  j  |  } |  j | } | j SWn t SXd S(   s  
        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
        N(   Rb  R   R   R7   (   R   R8   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   get_type  s    c         C  s#   |  j  |  } |  j | } | j S(   s  
        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
        (   Rb  R   RJ   (   R   R8   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   getclsid  s    
c         C  s&   |  j  |  } |  j | } | j   S(   s9  
        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
        (   Rb  R   R   (   R   R8   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR     s    c         C  s&   |  j  |  } |  j | } | j   S(   s1  
        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
        (   Rb  R   R   (   R   R8   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR     s    c         C  s&   y |  j  |  } t SWn t SXd S(   s  
        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.
        N(   Rb  R6   R7   (   R   R8   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR   	  s
    	c         C  sA   |  j  |  } |  j | } | j t k r: t d   n  | j S(   s2  
        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.
        s   object is not an OLE stream(   Rb  R   R   R   RJ  R   (   R   R8   R   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   get_size  s
    	c         C  s
   |  j  j S(   sp   
        Return root entry name. Should usually be 'Root Entry' or 'R' in most
        implementations.
        (   R  R'   (   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   get_rootentry_name*  s    c         C  s>  | d k r g  } n  | } t | t  s< d j |  } n  |  j |  } i  } y | j d  } t | d d ! } | j d  } t | d   }	 | j t | d   d | j t | j d   d  } t | d  }
 WnC t	 k
 r&} d	 t
 |  | f } |  j t | t |   | SXt |
 t t |  d   }
 xt |
  D]} d
 } yt | d | d  } t | d | d  } t | |  } t j d | | | f  | t k rt | | d  } | d k r| d } qn| t k rt | | d  } n| t t t f k rAt | | d  } n| t t f k rit | | d  } nz| t t f k rt | | d  } | | d | d | d !} | j d d  } n#| t k rt | | d  } | | d | d | !} n| t  k rCt | | d  } |  j! | | d | d | d ! } n| t" k rt# t | | d   t# t | | d   d >} | r	| | k r	t j d | | t$ |  d f  t% j% d d d d
 d
 d
  } t j d | d!  | t% j& d | d  } q| d } n | t' k r9t( | | d  } n | t) k rct | | d | d ! } n | t* k rt | | d  } | | d | d | !} nE | t+ k rt, t | | d   } n d } t j d | | f  | | | <WqSt	 k
 r5} d | t
 |  | f } |  j t | t |   qSXqSW| S("   s  
        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)
        R_  i   i   i   i   i   s   ****i   s6   Error while parsing properties header in stream %s: %si    i   s!   property id=%d: type=%d offset=%Xi   i   i   s    RE   i   i    s8   Converting property #%d to python datetime, value=%d=%fsi iA  s   timedelta days=%di
   i@B i  RL   s5   property id=%d: type=%d not implemented in parser yets3   Error while parsing property id %d in stream %s: %sNi I ha   I i*   (-   R   R3   RU  R   Rc  R.   RK   R2   RD   t   BaseExceptionR   R   R   t   typet   minR?   R1   R?  R,   R   t   VT_I2RC   t   VT_UI2t   VT_I4t   VT_INTt   VT_ERRORt   VT_UI4t   VT_UINTt   VT_BSTRt   VT_LPSTRR  t   VT_BLOBt	   VT_LPWSTRR   t   VT_FILETIMER   t   floatRM   RN   t   VT_UI1R=   t   VT_CLSIDt   VT_CFt   VT_BOOLt   bool(   R   R8   R   R   t
   streampathR:   R   R;  RJ   t   fmtidt	   num_propst   exct   msgR   t   property_idR   t   property_typeR   t   countRP   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR   2  s    	&)4	!c         C  s#   t    |  _ |  j j |   |  j S(   s   
        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   R   R   (   R   (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   get_metadata  s    N(.   R   R   R   R   R   R7   R   R   R  R  R>  R   R   R5   R	  R   R+  R3  R5  R=  R  R   R8  RN  RQ  R  R   RT  R   RF  R6   RX  R^  Rb  Rc  Rk  Rn  Ro  Rp  R   R   R   Rq  Rr  R   R  (    (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyR     sL   L			%		$	T	$	 	)		&	 			>							c          C  s  d d l  }  d d l } d } i t j d 6t j d 6t j d 6t j d 6t j d 6} d } | j d	 |  } | j	 d
 d d d d d d | j	 d d d d d d d | j	 d d d d d d d | d d | j
   \ } } t d t t f  t |  d k r-t t  | j   |  j   n  | j rBd | _ n  t j d | | j d d  t   x| D]} yit |  }	 t d d   t |  t d d   |	 j   x|	 j   D]}
 |
 d d d! k rt d" |
  y |	 j |
 d# t } t | j    } x | D] \ } } t | t t f  r[t |  d$ k r[| d$  } q[n  t | t  rx- dW D]" } | t  |  k rqd@ } PqqqqWn  t dA | |  qWWqt! j" dB |
  qXqqW| j# rzt dC  x |	 j   D]{ }
 t d t$ dD j% |
   d dE dF |	 j& |
  } | t' k r^t dG |	 j( |
   |	 j) |
  qt dH |  qWt   n  t dI  xF |	 j* D]; } | d k	 rt dJ | j, | j-   | j.   f  qqWt   y |	 j/   } | j0   Wn t! j" dK  n Xt   |	 j1   } t dL |  |	 j2 dM  rt dN  t dO |	 j& dM   t dP |	 j( dM   |	 j2 dQ  rt dR  qn  t dS  |	 j3 rx; |	 j3 D]# \ } } t dT | j4 | f  qWn
 t dU  Wqmt! j" dV |  qmXqmWd S(X   s   
    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
    iNR  R   t   infoR  t   criticals1   usage: %prog [options] <filename> [filename2 ...]t   usages   -ct   actiont
   store_truet   destt   check_streamst   helps*   check all streams (for debugging purposes)s   -dt
   debug_modes\   debug mode, shortcut for -l debug (displays a lot of debug information, for developers only)s   -ls
   --loglevelt   loglevelt   storet   defaultsB   logging level debug/info/warning/error/critical (default=%default)s=   olefile version %s %s - https://www.decalage.info/en/olefile
i    R(   t   formats   %(levelname)-8s %(message)st   -iD   s   s   %r: propertiesR   i2   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   s   (binary data)s      s&   Error while parsing property stream %rs   
Checking streams...R_  R   R   s   size %ds   NOT a stream : type=%ds5   Modification/Creation times of all directory entries:s   - %s: mtime=%s ctime=%ss   Error while parsing metadatas   Root entry name: "%s"t   worddocuments   This is a Word document.s   type of stream 'WordDocument':s   size :s
   macros/vbas%   This document may contain VBA macros.s(   
Non-fatal issues raised during parsing:s   - %s: %sR   s   Error while parsing file %r(   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   i   (5   R/  t   optparseR   R7  t   INFOt   WARNINGt   ERRORt   CRITICALt   OptionParsert
   add_optiont
   parse_argsR   t   __version__t   __date__R1   R   t
   print_helpt   exitR  R  t   basicConfigR   R   RT  R^  R   R6   t   sortedt   itemsR3   R`  R4   R  R,   t	   exceptionR  R   R   Ro  R   Rq  Rc  R   R   R'   R   R   R  R   Rr  R   R   R   (   R/  R  t   DEFAULT_LOG_LEVELt
   LOG_LEVELSR  t   parsert   optionsR
  R8   R   t
   streamnameR   t   kt   vR<   t   st_typeR   t   metaR  t   exctypeR  (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   main  s    



!

	


	
%

!

	t   __main__(o   R   t
   __future__R    R  R  t
   __author__t   __all__R   R/  R@   R-  t   os.pathR  RM   R   RU  R4   R?   R   t   xrangeR?  R   t   itemsizeR.  RK  R`  t	   NameErrorR6   R   t   version_infoR   R   R  R*   R,   R   R   R   R   R   R   R   R   R   R   R	   R   R   R   R
   R   t   VT_EMPTYt   VT_NULLRv  Rx  t   VT_R4t   VT_R8t   VT_CYt   VT_DATER}  t   VT_DISPATCHRz  R  t
   VT_VARIANTt
   VT_UNKNOWNt
   VT_DECIMALt   VT_I1R  Rw  R{  t   VT_I8t   VT_UI8Ry  R|  t   VT_VOIDt
   VT_HRESULTt   VT_PTRt   VT_SAFEARRAYt	   VT_CARRAYt   VT_USERDEFINEDR~  R  R  R  t	   VT_STREAMt
   VT_STORAGEt   VT_STREAMED_OBJECTt   VT_STORED_OBJECTt   VT_BLOB_OBJECTR  R  t	   VT_VECTORR   R   R   R   R   R   R   R=   RC   RD   RK   RQ   R   R   R   R   R   R  R   (    (    (    s.   lib/python2.7/site-packages/olefile/olefile.pyt   <module>   s   <		<	

			
		                                	*	

		 !     	