title: How can I get the summary information from MS Word (.DOC) file?
body: <p>I only need the <strong>page count</strong> property in PHP without using only thi built-in functions (not  framework and COM). The input is an "old" doc file.</p>
  
  <p>Here is what I know, and I found about this topic, I hope it will help you to solve the problem:</p>
  
  <p>SummarayInformation looks like this and it is in encrypted into the file code:
  <img src="https://i.stack.imgur.com/LFUPa.jpg" alt="enter image description here">:</p>
  
  <p>I found some C files where the method of extracting that data can be found, but it is too difficult for me to understand that.</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  
  #include "wv_Base.h"
  #include "wv_Common.h"
  #include "wv.h"
  
  #include "glib.h"
  #include "ms-ole.h"
  #include "ms-ole-summary.h"
  
  
  /*
   * This is a simple example that take an ole file and prints some
   * information from the summaryinformation stream
   */
  
  
  int main(int argc, char *argv[])
      {
      char *str = NULL;
      int ret = 0;
      short s = 0;
      long l = 0;
  
      MsOle *ole = NULL;
      MsOleSummary *summary = NULL;
  
      if (argc &lt; 2)
          {
          fprintf(stderr, "Usage: wvSummary oledocument\n");
          return(1);
          }
  
      ms_ole_open(&amp;ole, argv[1]);
      if (!ole)
          {
          fprintf(stderr,"sorry problem with getting ole streams from %s\n",argv[1]);
          return 1;
          }
  
      summary = ms_ole_summary_open(ole);
      if (!summary)
          {
          fprintf(stderr, "Could not open summary stream\n");
          return 1;
          }
  
      ms_ole_summary_get_string(summary, , &amp;ret);
  
      if (ret)
        printf("PageCount is %d\n", l);
      else
        printf("no pagecount\n");
  
  
      ms_ole_summary_close(summary);
      ms_ole_destroy(&amp;ole);
  
      return 0;
      }
  </code></pre>
  
  <p>about MS_OLE_SUMMARY_TITLE:</p>
  
  <pre><code>/**
   * ms-ole-summary.h: MS Office OLE support
   *
   * Author:
   *    Michael Meeks (michael@imaginator.com)
   * From work by:
   *    Caolan McNamara (Caolan.McNamara@ul.ie)
   * Built on work by:
   *    Somar Software's CPPSUM (http://www.somar.com)
   *
   * Copyright 1998-2000 Helix Code, Inc., Frank Chiulli, and others.
   **/
  
  #ifndef MS_OLE_SUMMARY_H
  #define MS_OLE_SUMMARY_H
  
  #include &lt;time.h&gt;
  #include &lt;libole2/ms-ole.h&gt;
  
  /*
   * MS Ole Property Set IDs
   * The SummaryInformation stream contains the SummaryInformation property set.
   * The DocumentSummaryInformation stream contains both the
   * DocumentSummaryInformation and the UserDefined property sets as sections.
   */
  typedef enum {
      MS_OLE_PS_SUMMARY_INFO,
      MS_OLE_PS_DOCUMENT_SUMMARY_INFO,
      MS_OLE_PS_USER_DEFINED_SUMMARY_INFO
  } MsOlePropertySetID;
  
  typedef struct {
      guint8          class_id[16];
      GArray *        sections;
      GArray *        items;
      GList *         write_items;
      gboolean        read_mode;
      MsOleStream *       s;
      MsOlePropertySetID  ps_id;
  } MsOleSummary;
  
  /* Could store the FID, but why bother ? */
  typedef struct {
      guint32         offset;
      guint32         props;
      guint32         bytes;
      MsOlePropertySetID  ps_id;
  } MsOleSummarySection;
  
  MsOleSummary *ms_ole_summary_open       (MsOle *f);
  MsOleSummary *ms_ole_docsummary_open        (MsOle *f);
  MsOleSummary *ms_ole_summary_open_stream    (MsOleStream *stream,
                           const MsOlePropertySetID psid);
  MsOleSummary *ms_ole_summary_create     (MsOle *f);
  MsOleSummary *ms_ole_docsummary_create      (MsOle *f);
  MsOleSummary *ms_ole_summary_create_stream  (MsOleStream *s,
                           const MsOlePropertySetID psid);
  GArray       *ms_ole_summary_get_properties (MsOleSummary *si);
  void          ms_ole_summary_close      (MsOleSummary *si);
  
  
  /*
   * Can be used to interrogate a summary item as to its type
   */
  typedef enum {
      MS_OLE_SUMMARY_TYPE_STRING  = 0x10,
      MS_OLE_SUMMARY_TYPE_TIME    = 0x20,
      MS_OLE_SUMMARY_TYPE_LONG    = 0x30,
      MS_OLE_SUMMARY_TYPE_SHORT   = 0x40,
      MS_OLE_SUMMARY_TYPE_BOOLEAN = 0x50,
      MS_OLE_SUMMARY_TYPE_OTHER   = 0x60
  } MsOleSummaryType;
  
  #define MS_OLE_SUMMARY_TYPE(x) ((MsOleSummaryType)((x)&gt;&gt;8))
  
  /* FIXME MS_OLE_SUMMARY_THUMBNAIL is Preview, no Security, isn't it? */
  /*
   *  The MS byte specifies the type, the LS byte is the
   * 'standard' MS PID.
   */
  typedef enum {
  /* SummaryInformation Stream Properties */
  /* String properties */
      MS_OLE_SUMMARY_TITLE          = 0x1002,
      MS_OLE_SUMMARY_SUBJECT        = 0x1003,
      MS_OLE_SUMMARY_AUTHOR         = 0x1004,
      MS_OLE_SUMMARY_KEYWORDS       = 0x1005,
      MS_OLE_SUMMARY_COMMENTS       = 0x1006,
      MS_OLE_SUMMARY_TEMPLATE       = 0x1007,
      MS_OLE_SUMMARY_LASTAUTHOR     = 0x1008,
      MS_OLE_SUMMARY_REVNUMBER      = 0x1009,
      MS_OLE_SUMMARY_APPNAME        = 0x1012,
  
  /* Time properties */
      MS_OLE_SUMMARY_TOTAL_EDITTIME = 0x200A,
      MS_OLE_SUMMARY_LASTPRINTED    = 0x200B,
      MS_OLE_SUMMARY_CREATED        = 0x200C,
      MS_OLE_SUMMARY_LASTSAVED      = 0x200D,
  
  /* Long integer properties */
      MS_OLE_SUMMARY_PAGECOUNT      = 0x300E,
      MS_OLE_SUMMARY_WORDCOUNT      = 0x300F,
      MS_OLE_SUMMARY_CHARCOUNT      = 0x3010,
      MS_OLE_SUMMARY_SECURITY       = 0x3013,
  
  /* Short integer properties */
      MS_OLE_SUMMARY_CODEPAGE       = 0x4001,
  
  /* Security */  
      MS_OLE_SUMMARY_THUMBNAIL      = 0x6011,
  
  
  /* DocumentSummaryInformation Properties */
  /* String properties */
      MS_OLE_SUMMARY_CATEGORY       = 0x1002,
      MS_OLE_SUMMARY_PRESFORMAT     = 0x1003,
      MS_OLE_SUMMARY_MANAGER        = 0x100E,
      MS_OLE_SUMMARY_COMPANY        = 0x100F,
  
  /* Long integer properties */
      MS_OLE_SUMMARY_BYTECOUNT      = 0x3004,
      MS_OLE_SUMMARY_LINECOUNT      = 0x3005,
      MS_OLE_SUMMARY_PARCOUNT       = 0x3006,
      MS_OLE_SUMMARY_SLIDECOUNT     = 0x3007,
      MS_OLE_SUMMARY_NOTECOUNT      = 0x3008,
      MS_OLE_SUMMARY_HIDDENCOUNT    = 0x3009,
      MS_OLE_SUMMARY_MMCLIPCOUNT    = 0X300A,
  
  /* Boolean properties */
      MS_OLE_SUMMARY_SCALE          = 0x500B,
      MS_OLE_SUMMARY_LINKSDIRTY     = 0x5010
  } MsOleSummaryPID;
  
  
  /* bit masks for security long integer */
  #define MsOleSummaryAllSecurityFlagsEqNone        0x00
  #define MsOleSummarySecurityPassworded            0x01
  #define MsOleSummarySecurityRORecommended         0x02
  #define MsOleSummarySecurityRO                    0x04
  #define MsOleSummarySecurityLockedForAnnotations  0x08
  
  typedef struct {
      GTimeVal time;
      GDate    date;
  } MsOleSummaryTime;
  
  typedef struct {
      guint32 len;
      guint8 *data;
  } MsOleSummaryPreview;
  
  gchar *         ms_ole_summary_get_string   (MsOleSummary *si,
                               MsOleSummaryPID id,
                               gboolean *available);
  gboolean        ms_ole_summary_get_boolean  (MsOleSummary *si,
                               MsOleSummaryPID id,
                               gboolean *available);
  guint16         ms_ole_summary_get_short    (MsOleSummary *si,
                               MsOleSummaryPID id,
                               gboolean *available);
  guint32         ms_ole_summary_get_long     (MsOleSummary *si,
                               MsOleSummaryPID id,
                               gboolean *available);
  GTimeVal        ms_ole_summary_get_time     (MsOleSummary *si,
                               MsOleSummaryPID id,
                               gboolean *available);
  MsOleSummaryPreview ms_ole_summary_get_preview  (MsOleSummary *si,
                               MsOleSummaryPID id,
                               gboolean *available);
  void            ms_ole_summary_preview_destroy  (MsOleSummaryPreview d);
  
  /* FIXME The next comment isn't true, is it?
     Return TRUE if write is successful */
  void            ms_ole_summary_set_string   (MsOleSummary *si,
                               MsOleSummaryPID id,
                               const gchar *str);
  void            ms_ole_summary_set_boolean  (MsOleSummary *si,
                               MsOleSummaryPID id,
                               gboolean value);
  void            ms_ole_summary_set_short    (MsOleSummary *si,
                               MsOleSummaryPID id,
                               guint16 i);
  void            ms_ole_summary_set_long     (MsOleSummary *si,
                               MsOleSummaryPID id,
                               guint32 i);
  void            ms_ole_summary_set_time     (MsOleSummary *si,
                               MsOleSummaryPID id,
                               GTimeVal time);
  void            ms_ole_summary_set_preview  (MsOleSummary *si,
                               MsOleSummaryPID id,
                               const
                               MsOleSummaryPreview *
                               preview);
  
  #endif  /* MS_OLE_SUMMARY_H */
  </code></pre>
  
  <p>msOle structure:</p>
  
  <pre><code>/**
   * Structure describing an OLE file
   **/
  struct _MsOle {
      int               ref_count;
      gboolean          ole_mmap;
      guint8           *mem;
      guint32           length;
      MsOleSysWrappers *syswrap;
  
      char              mode;
      int               file_des;
      int               dirty;
      GArray           *bb;      /* Big  blocks status  */
      GArray           *sb;      /* Small block status  */
      GArray           *sbf;     /* The small block file */
      guint32           num_pps; /* Count of number of property sets */
      GList            *pps;     /* Property Storage -&gt; struct _PPS, always 1 valid entry or NULL */
  /* if memory mapped */
      GPtrArray        *bbattr;  /* Pointers to block structures */
  /* end if memory mapped */
  };
  </code></pre>
  
  <p>other resources:</p>
  
  <p><a href="http://slackware.mirrors.pair.com/slackware-8.1/source/gnome/libole2/libole2-0.2.4.tar.bz2" rel="nofollow noreferrer">http://slackware.mirrors.pair.com/slackware-8.1/source/gnome/libole2/libole2-0.2.4.tar.bz2</a>
  <a href="ftp://ftp.ca.com/caproducts/Opal/jasmine064/framework/include/" rel="nofollow noreferrer">ftp://ftp.ca.com/caproducts/Opal/jasmine064/framework/include/</a></p>
  
  <p>reference:
  <a href="http://wvware.sourceforge.net/libole2/libole2.html" rel="nofollow noreferrer">http://wvware.sourceforge.net/libole2/libole2.html</a></p>
  
  <p>I have tired it this way - but I did not found the pagecount:</p>
  
  <pre><code>echo("&lt;pre&gt;");
  $file = "files/doctest.doc";
  if(!is_file($file))die("File not found.");
  
  //bind file to a stream.
  $handle = fopen($file, "rb");
  
  //read file content
  $content = fread($handle, filesize($file));
  
  $binaryfile = "";
  for ($i = 0; $i &lt; strlen($content); $i++) {
      //get ascii char
      $char = $content[$i];
  
      //get the acsii value 0-255 (2^8)
      $decimal = ord($char);
  
      //decimal number in base 200
      $binary =  base_convert($decimal, 10, 2);
  
      echo($char);
  
      echo sprintf(" %3d %08b",$decimal,$decimal);
      if($i % 4==0)echo("*");
  
      $bit32 = b($content[$i]).b($content[$i+1]).b($content[$i+2]).b($content[$i+3]);
      echo sprintf("&lt;br&gt;&lt;b&gt;%d&lt;/b&gt;",base_convert($bit32,2,10)); //32bit int
  
  
      echo("&lt;br&gt;");
  }
  fclose($handle);
  </code></pre>
  
  <p>thanks for any help!</p>