gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r2466 - in Extractor: . src/include src/main src/plugins/wo


From: grothoff
Subject: [GNUnet-SVN] r2466 - in Extractor: . src/include src/main src/plugins/wordleaker
Date: Wed, 8 Mar 2006 05:52:22 -0800 (PST)

Author: grothoff
Date: 2006-03-08 05:52:16 -0800 (Wed, 08 Mar 2006)
New Revision: 2466

Added:
   Extractor/src/plugins/wordleaker/Makefile.am
   Extractor/src/plugins/wordleaker/SYMBOLS
   Extractor/src/plugins/wordleaker/wordextractor.cc
   Extractor/src/plugins/wordleaker/wordleaker.cpp
   Extractor/src/plugins/wordleaker/wordleaker.h
Removed:
   Extractor/src/plugins/wordleaker/WordLeaker.cpp
   Extractor/src/plugins/wordleaker/WordLeaker.h
Modified:
   Extractor/configure.ac
   Extractor/src/include/extractor.h
   Extractor/src/main/extractor.c
Log:
wordleaker integration -- draft

Modified: Extractor/configure.ac
===================================================================
--- Extractor/configure.ac      2006-02-22 18:21:26 UTC (rev 2465)
+++ Extractor/configure.ac      2006-03-08 13:52:16 UTC (rev 2466)
@@ -298,6 +298,7 @@
 src/plugins/hash/Makefile
 src/plugins/thumbnail/Makefile
 src/plugins/exiv2/Makefile
+src/plugins/wordleaker/Makefile
 src/test/Makefile
 ])
 

Modified: Extractor/src/include/extractor.h
===================================================================
--- Extractor/src/include/extractor.h   2006-02-22 18:21:26 UTC (rev 2465)
+++ Extractor/src/include/extractor.h   2006-03-08 13:52:16 UTC (rev 2466)
@@ -140,6 +140,8 @@
   EXTRACTOR_ORIENTATION = 87,
   EXTRACTOR_TEMPLATE = 88,
   EXTRACTOR_SPLIT = 89,
+
+  EXTRACTOR_PRODUCTVERSION = 90,
 } EXTRACTOR_KeywordType;
 
 /**

Modified: Extractor/src/main/extractor.c
===================================================================
--- Extractor/src/main/extractor.c      2006-02-22 18:21:26 UTC (rev 2465)
+++ Extractor/src/main/extractor.c      2006-03-08 13:52:16 UTC (rev 2466)
@@ -131,11 +131,12 @@
   gettext_noop("orientation"),
   gettext_noop("template"),
   gettext_noop("split"),
+  gettext_noop("product version"),
   NULL,
 };
 
 /* the number of keyword types (for bounds-checking) */
-#define HIGHEST_TYPE_NUMBER 90
+#define HIGHEST_TYPE_NUMBER 91
 
 #ifdef HAVE_LIBOGG
 #if HAVE_VORBIS

Added: Extractor/src/plugins/wordleaker/Makefile.am
===================================================================
--- Extractor/src/plugins/wordleaker/Makefile.am        2006-02-22 18:21:26 UTC 
(rev 2465)
+++ Extractor/src/plugins/wordleaker/Makefile.am        2006-03-08 13:52:16 UTC 
(rev 2466)
@@ -0,0 +1,25 @@
+include ../Makefile-plugins.am
+
+plugin_LTLIBRARIES = \
+ libextractor_word.la
+
+libextractor_word_la_LINK = \
+  /bin/sh ../../../libtool --mode=link $(CXXLD) -o libextractor_word.la
+libextractor_word_la_LDFLAGS = \
+  $(PLUGINFLAGS)  $(retaincommand) \
+  $(XTRA_CPPLIBS)
+libextractor_word_la_LIBADD = \
+  $(top_builddir)/src/main/libextractor.la \
+  $(top_builddir)/src/plugins/libconvert.la \
+  -lm 
+
+libextractor_word_la_SOURCES = \
+ pole.h pole.cpp \
+ wordleaker.h \
+ wordextractor.cc 
+
+# gcc 3.3 produces BROKEN code for -O1 and -O2 (PDF extraction
+# would fail silently) hence we MUST override the user flag here
+# which may contain -O1 or -O2!
+# CXXFLAGS = -O0
+

Added: Extractor/src/plugins/wordleaker/SYMBOLS
===================================================================
--- Extractor/src/plugins/wordleaker/SYMBOLS    2006-02-22 18:21:26 UTC (rev 
2465)
+++ Extractor/src/plugins/wordleaker/SYMBOLS    2006-03-08 13:52:16 UTC (rev 
2466)
@@ -0,0 +1 @@
+libextractor_word_extract

Deleted: Extractor/src/plugins/wordleaker/WordLeaker.cpp
===================================================================
--- Extractor/src/plugins/wordleaker/WordLeaker.cpp     2006-02-22 18:21:26 UTC 
(rev 2465)
+++ Extractor/src/plugins/wordleaker/WordLeaker.cpp     2006-03-08 13:52:16 UTC 
(rev 2466)
@@ -1,310 +0,0 @@
-/* 
-   WordLeaker - Shows information about Word DOC files
-   Copyright (C) 2005 Sacha Fuentes <address@hidden>
-
-   Based on poledump.c
-   Original idea from WordDumper (http://www.computerbytesman.com)
-   Info on Word format: http://www.aozw65.dsl.pipex.com/generator_wword8.htm
-   Info on Word format: http://jakarta.apache.org/poi/hpsf/internals.html
-   
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public
-   License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this library; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, US
-*/
-
-// TAKE CARE: there's not a single check for validity of data,
-// so any malformed or malicious Word file will break it
-
-#include <iostream>
-#include <fstream>
-#include <stdlib.h>
-#include <list>
-#include <ctime>
-
-#include "pole.h"
-#include "WordLeaker.h"
-
-unsigned long fcSttbSavedBy;
-unsigned long lcbSttbSavedBy;
-  
-// read the type of the property and displays its value
-void showProperty( POLE::Stream* stream ) {
-  unsigned long read, type;
-  unsigned char buffer[256];
-  unsigned char c;
-  unsigned long i;
-  unsigned long t, t1, t2;
-  char *s;
-    
-  read = stream->read(buffer, 4);
-  type = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24);
-    
-  switch (type) {
-      case 2: // VT_I2
-        read = stream->read(buffer, 2);
-        i = buffer[0] + (buffer[1] << 8);
-        cout << i << endl;
-        break;
-      case 3: // VT_I4
-        read = stream->read(buffer, 4);
-        i = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 
24);
-        cout << i << endl;
-        break;
-      case 11: // VT_BOOL
-        read = stream->read(buffer, 1);
-        if ((char) buffer[0] == -1)
-            cout << "true" << endl;
-        else        
-            cout << "false" << endl;
-        break;
-      case 30: // VT_LPSTR
-        read = stream->read(buffer, 4);
-        i = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 
24);
-        while ((c = stream->getch()) != 0)
-            cout << c;
-        cout << endl;
-        break;
-      case 64: // VT_FILETIME
-        read = stream->read(buffer, 8);
-        t1 = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 
24);
-        t2 = buffer[4]  + (buffer[5] << 8) + (buffer[6] << 16) + (buffer[7] << 
24);
-        t = filetime_to_unixtime(t1, t2);
-        s = ctime((time_t *) &t);
-        cout << s;
-        break;
-      default:
-          cout << "Unknown format " << type << endl;
-  }
-}
-
-// show the revision data (users and files)
-void dumpRevision( POLE::Storage* storage ) {
-  unsigned int nRev;
-  unsigned int where = 0;
-  POLE::Stream* stream;
-    
-  cout << "Revision:" << endl;
-  cout << "---------" << endl << endl;
-
-  // FIXME: should look if using 0Table or 1Table
-  stream = storage->stream( "1Table" );
-  if( !stream ) {
-      cout << "There's no revision information" << endl;
-      return;
-  }
-  
-  unsigned char * buffer = new unsigned char[lcbSttbSavedBy];
-  unsigned char buffer2[1024];
-  unsigned int length;
-  
-  // goto offset of revision
-  stream->seek(fcSttbSavedBy);
-  // read all the revision history
-  stream->read(buffer, lcbSttbSavedBy);
-
-  // there are n strings, so n/2 revisions (author & file)
-  nRev = (buffer[2] + (buffer[3] << 8)) / 2;
-  where = 6;
-  
-  for (unsigned int i=0; i < nRev; i++) {
-    cout << "Rev #" << i << ": Author \"";
-    length = buffer[where++];
-    // it's unicode, for now we only get the low byte
-    for (unsigned int j=0; j < length; j++) {
-        where++;
-        cout << buffer[where];
-        where++;
-    }
-    where++;
-    cout << "\" worked on file \"";
-    length = buffer[where++];
-    // it's unicode, for now we only get the low byte
-    for (unsigned int j=0; j < length; j++) {
-        where++;
-        cout << buffer[where];
-        where++;
-    }
-    where++;
-    cout << "\"" << endl;    
-  }
-  
-  cout << endl;      
-  delete buffer;
-  
-}
-
-// show data from DocumentSummary stream
-void dumpDocumentSummary( POLE::Storage* storage ) {
-  POLE::Stream* stream;
-  unsigned long read, nproperties, propertyID, offsetProp, offsetCur;
-  unsigned long begin;
-    
-  cout << "Document Summary:" << endl;
-  cout << "-----------------" << endl << endl;
-
-  stream = storage->stream( "DocumentSummaryInformation" );
-  if( !stream ) {
-      cout << "There's no document summary information" << endl;
-      return;
-  }
-  
-  unsigned char buffer[256];
-
-  // ClassID & Offset
-  stream->seek(28);
-  stream->read(buffer, 20);
-  // beginning of section
-  begin = stream->tell();
-  // length of section
-  read = stream->read(buffer, 4);
-  // number of properties
-  read = stream->read(buffer, 4);
-  nproperties = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] 
<< 24);
-  // properties
-
-  for (unsigned long i = 0; i < nproperties; i++) {
-    read = stream->read(buffer, 8);
-    propertyID = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] 
<< 24);
-    offsetProp = buffer[4] + (buffer[5] << 8) + (buffer[6] << 16) + (buffer[7] 
<< 24);
-      if (propertyID > 1 && propertyID < 16) {
-        cout << DocumentSummaryProperties[propertyID] << ": ";
-        offsetCur = stream->tell();
-        stream->seek(offsetProp + begin);
-        // read and show the property
-        showProperty(stream);  
-        stream->seek(offsetCur);
-    }
-  }
-
-  cout << endl;      
-}
-
-// show data from Summary stream
-void dumpSummary( POLE::Storage* storage ) {
-  POLE::Stream* stream;
-  unsigned long read, nproperties, propertyID, offsetProp, offsetCur;
-  unsigned long begin;
-    
-  cout << "Summary:" << endl;
-  cout << "--------" << endl << endl;
-
-  stream = storage->stream( "SummaryInformation" );
-  if( !stream ) {
-      cout << "There's no summary information" << endl;
-      return;
-  }
-  
-  unsigned char buffer[256];
-
-  // ClassID & Offset
-  stream->seek(28);
-  stream->read(buffer, 20);
-  // beginning of section
-  begin = stream->tell();
-  // length of section
-  read = stream->read(buffer, 4);
-  // number of properties
-  read = stream->read(buffer, 4);
-  nproperties = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] 
<< 24);
-  // properties
-  for (unsigned long i = 0; i < nproperties; i++) {
-    read = stream->read(buffer, 8);
-    propertyID = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] 
<< 24);
-    offsetProp = buffer[4] + (buffer[5] << 8) + (buffer[6] << 16) + (buffer[7] 
<< 24);
-    if (propertyID > 1 && propertyID < 20) {
-        cout << SummaryProperties[propertyID] << ": ";
-        offsetCur = stream->tell();
-        stream->seek(offsetProp + begin);
-        // read and show the property
-        showProperty(stream);  
-        stream->seek(offsetCur);
-    }
-  }
-
-  cout << endl;      
-}
-
-// reads the header of the file
-bool readFIB( char* filename ) {
-  fstream file;
-    
-   file.open( filename, std::ios::binary | std::ios::in );
-  if( !file.good() ) {
-    cout << "Can't find the file" << endl;
-    return false;
-  }
-  
-  unsigned char * buffer = new unsigned char[898];
-  file.seekg( 512 ); 
-  file.read( (char*)buffer, 898 );
-  file.close();
-  
-  unsigned int wIdent = buffer[0] + (buffer[1] << 8);
-  unsigned int nProduct = buffer[4] + (buffer[5] << 8);
-  unsigned int lid = buffer[6] + (buffer[7] << 8);
-  unsigned int envr = buffer[18];
-  unsigned int wMagicCreated = buffer[34] + (buffer[35] << 8);
-  unsigned int wMagicRevised = buffer[36] + (buffer[37] << 8);
-  unsigned long lProductCreated = buffer[68] + (buffer[69] << 8) + (buffer[70] 
<< 16) + (buffer[71] << 24);
-  unsigned long lProductRevised = buffer[72] + (buffer[73] << 8) + (buffer[74] 
<< 16) + (buffer[75] << 24);
-  fcSttbSavedBy = buffer[722] + (buffer[723] << 8) + (buffer[724] << 16) + 
(buffer[725] << 24);
-  lcbSttbSavedBy = buffer[726] + (buffer[727] << 8) + (buffer[728] << 16) + 
(buffer[729] << 24);
-  delete[] buffer; 
-  
-  cout << "File: " << filename << endl;
-  cout << "Product version: " << nProduct << endl;  
-  cout << "Language: " << lidToLanguage(lid) << endl;
-  cout << "Created by: " << idToProduct(wMagicCreated) << " (Build " << 
dateToString(lProductCreated) << ")" << endl;
-  cout << "Revised by: " << idToProduct(wMagicRevised) << " (Build " << 
dateToString(lProductRevised) << ")" << endl;
-  cout << endl;
-  
-  return true; 
-    
-}
-
-int main(int argc, char *argv[]) {
-  cout << endl << "WordLeaker v.0.1" << endl;
-  cout << " by Madelman (http://elligre.tk/madelman/)" << endl << endl;
-  
-    
-  if( argc < 2 ) {
-    cout << "  You must supply a filename" << endl << endl;
-    return 0;
-  }
-  
-  char* filename = argv[1];
-
-  if ( !readFIB(filename) )
-      return 1;
-  
-  POLE::Storage* storage = new POLE::Storage( filename );
-  storage->open();
-  if( storage->result() != POLE::Storage::Ok ) {
-    cout << "The file " << filename << " is not a Word document" << endl;
-    return 1;
-  }
-  
-  dumpSummary( storage );
-  // FIXME: doesn't always work
-  // but there's nothing really interesting in here
-  //dumpDocumentSummary( storage );
-  dumpRevision( storage );
-  // TODO: we don't show the GUID
-  // TODO: we don't show the macros
-  
-  delete storage;
-  
-  return 0;
-}
-

Deleted: Extractor/src/plugins/wordleaker/WordLeaker.h
===================================================================
--- Extractor/src/plugins/wordleaker/WordLeaker.h       2006-02-22 18:21:26 UTC 
(rev 2465)
+++ Extractor/src/plugins/wordleaker/WordLeaker.h       2006-03-08 13:52:16 UTC 
(rev 2466)
@@ -1,287 +0,0 @@
-/* 
-   WordLeaker - Shows information about Word DOC files
-   Copyright (C) 2005 Sacha Fuentes <address@hidden>
-
-   Based on poledump.c
-   Original idea from WordDumper (http://www.computerbytesman.com)
-   Info on Word format: http://www.aozw65.dsl.pipex.com/generator_wword8.htm
-   Info on Word format: http://jakarta.apache.org/poi/hpsf/internals.html
-   
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public
-   License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this library; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, US
-*/
-
-#include <string>
-
-using namespace std;
-
-static char* SummaryProperties[] = {
-"Unknown", 
-"Unknown",
-"Title",
-"Subject",
-"Author",
-"Keywords",
-"Comments",
-"Template",
-"Last Saved By",
-"Revision Number",
-"Total Editing Time",
-"Last Printed",
-"Create Time/Date",
-"Last Saved Time/Date",
-"Number of Pages",
-"Number of Words",
-"Number of Characters",
-"Thumbnails",
-"Creating Application",
-"Security"
-};
-
-static char* DocumentSummaryProperties[] = {
-"Dictionary",
-"Code page",
-"Category",
-"PresentationTarget",
-"Bytes",
-"Lines",
-"Paragraphs",
-"Slides",
-"Notes",
-"HiddenSlides",
-"MMClips",
-"ScaleCrop",
-"HeadingPairs",
-"TitlesofParts",
-"Manager",
-"Company",
-"LinksUpTo"
-};
-
-string dateToString( unsigned long date ) {
-  char f[9];
-  sprintf(f, "%d/%d/%d", (date / 10000 % 100), (date / 100 % 100), (date % 
100));
-  return f;
-}
-
-string idToProduct( unsigned int id ) {
-  // TODO: find the rest of ids
-  switch ( id ) {
-    case  0x6A62:
-        return "Word 97";
-    case 0x626A:
-        return "Word 98 (Mac)";
-    default:
-        return "Unknown";
-  }      
-}
-
-string lidToLanguage( unsigned int lid ) {
-  switch ( lid ) {
-    case 0x0400: 
-        return "No Proofing";
-    case 0x0401: 
-        return "Arabic";
-    case 0x0402:
-        return "Bulgarian";
-    case 0x0403:
-        return "Catalan";
-    case 0x0404:
-        return "Traditional Chinese";
-    case 0x0804:
-        return "Simplified Chinese";
-    case 0x0405:
-        return "Czech";
-    case 0x0406:
-        return "Danish";
-    case 0x0407:
-        return "German";
-    case 0x0807:
-        return "Swiss German";
-    case 0x0408:
-        return "Greek";
-    case 0x0409:
-        return "U.S. English";
-    case 0x0809:
-        return "U.K. English";
-    case 0x0c09:
-        return "Australian English";
-    case 0x040a:
-        return "Castilian Spanish";
-    case 0x080a:
-        return "Mexican Spanish";
-    case 0x040b:
-        return "Finnish";
-    case 0x040c:
-        return "French";
-    case 0x080c:
-        return "Belgian French";
-    case 0x0c0c:
-        return "Canadian French";
-    case 0x100c:
-        return "Swiss French";
-    case 0x040d:
-        return "Hebrew";
-    case 0x040e:
-        return "Hungarian";
-    case 0x040f:
-        return "Icelandic";
-    case 0x0410:
-        return "Italian";
-    case 0x0810:
-        return "Swiss Italian";
-    case 0x0411:
-        return "Japanese";
-    case 0x0412:
-        return "Korean";
-    case 0x0413:
-        return "Dutch";
-    case 0x0813:
-        return "Belgian Dutch";
-    case 0x0414:
-        return "Norwegian - Bokmal";
-    case 0x0814:
-        return "Norwegian - Nynorsk";
-    case 0x0415:
-        return "Polish";
-    case 0x0416:
-        return "Brazilian Portuguese";
-    case 0x0816:
-        return "Portuguese";
-    case 0x0417:
-        return "Rhaeto-Romanic";
-    case 0x0418:
-        return "Romanian";
-    case 0x0419:
-        return "Russian";
-    case 0x041a:
-        return "Croato-Serbian (Latin)";
-    case 0x081a:
-        return "Serbo-Croatian (Cyrillic)";
-    case 0x041b:
-        return "Slovak";
-    case 0x041c:
-        return "Albanian";
-    case 0x041d:
-        return "Swedish";
-    case 0x041e:
-        return "Thai";
-    case 0x041f:
-        return "Turkish";
-    case 0x0420:
-        return "Urdu";
-    case 0x0421:
-        return "Bahasa"; 
-    case 0x0422:
-        return "Ukrainian";
-    case 0x0423:
-        return "Byelorussian";
-    case 0x0424:
-        return "Slovenian";
-    case 0x0425:
-        return "Estonian";
-    case 0x0426:
-        return "Latvian";
-    case 0x0427:
-        return "Lithuanian";
-    case 0x0429:
-        return "Farsi";
-    case 0x042D:
-        return "Basque";
-    case 0x042F:
-        return "Macedonian";
-    case 0x0436:
-        return "Afrikaans";
-    case 0x043E:
-        return "Malaysian";  
-    default:
-        return "Unknown";
-  }
-}
-
-/*
- *  filetime_to_unixtime
- *
- *  Adapted from work in 'wv' by:
- *    Caolan McNamara (address@hidden)
- */
-#define HIGH32_DELTA 27111902
-#define MID16_DELTA  54590
-#define LOW16_DELTA  32768
-
-unsigned long filetime_to_unixtime (unsigned long low_time, unsigned long 
high_time) {
-  unsigned long low16;/* 16 bit, low    bits */
-  unsigned long mid16;/* 16 bit, medium bits */
-  unsigned long hi32;/* 32 bit, high   bits */
-  unsigned int carry;/* carry bit for subtraction */
-  int negative;/* whether a represents a negative value */
-
-/* Copy the time values to hi32/mid16/low16 */
-hi32  =  high_time;
-mid16 = low_time >> 16;
-low16 = low_time &  0xffff;
-
-/* Subtract the time difference */
-if (low16 >= LOW16_DELTA           )
-low16 -=             LOW16_DELTA        , carry = 0;
-else
-low16 += (1 << 16) - LOW16_DELTA        , carry = 1;
-
-if (mid16 >= MID16_DELTA    + carry)
-mid16 -=             MID16_DELTA + carry, carry = 0;
-else
-mid16 += (1 << 16) - MID16_DELTA - carry, carry = 1;
-
-hi32 -= HIGH32_DELTA + carry;
-
-/* If a is negative, replace a by (-1-a) */
-negative = (hi32 >= ((unsigned long)1) << 31);
-if (negative) {
-/* Set a to -a - 1 (a is hi32/mid16/low16) */
-low16 = 0xffff - low16;
-mid16 = 0xffff - mid16;
-hi32 = ~hi32;
-}
-
-/*
- *  Divide a by 10000000 (a = hi32/mid16/low16), put the rest into r.
-         * Split the divisor into 10000 * 1000 which are both less than 0xffff.
- */
-mid16 += (hi32 % 10000) << 16;
-hi32  /=       10000;
-low16 += (mid16 % 10000) << 16;
-mid16 /=       10000;
-low16 /=       10000;
-
-mid16 += (hi32 % 1000) << 16;
-hi32  /=       1000;
-low16 += (mid16 % 1000) << 16;
-mid16 /=       1000;
-low16 /=       1000;
-
-/* If a was negative, replace a by (-1-a) and r by (9999999 - r) */
-if (negative) {
-/* Set a to -a - 1 (a is hi32/mid16/low16) */
-low16 = 0xffff - low16;
-mid16 = 0xffff - mid16;
-hi32 = ~hi32;
-}
-
-/*  Do not replace this by << 32, it gives a compiler warning and
- *  it does not work
- */
-return ((((unsigned long)hi32) << 16) << 16) + (mid16 << 16) + low16;
-
-}

Added: Extractor/src/plugins/wordleaker/wordextractor.cc
===================================================================
--- Extractor/src/plugins/wordleaker/wordextractor.cc   2006-02-22 18:21:26 UTC 
(rev 2465)
+++ Extractor/src/plugins/wordleaker/wordextractor.cc   2006-03-08 13:52:16 UTC 
(rev 2466)
@@ -0,0 +1,221 @@
+/*
+     This file is part of libextractor.
+     (C) 2006 Vidyut Samanta and Christian Grothoff
+
+     libextractor is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libextractor is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libextractor; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+
+     This code depends heavily on the wordleaker code and
+     a lot of code was borrowed from wordleaker.cpp. See also
+     the README file in this directory.
+ */
+
+#include "platform.h"
+#include "extractor.h"
+#include "../convert.h"
+#include <math.h>
+
+#include "wordleaker.h"
+#include "pole.h"
+
+extern "C" {
+
+  static struct EXTRACTOR_Keywords * addKeyword(EXTRACTOR_KeywordType type,
+                                               const char * keyword,
+                                               struct EXTRACTOR_Keywords * 
next) {
+    EXTRACTOR_KeywordList * result;
+
+    if (keyword == NULL)
+      return next;
+    result = (EXTRACTOR_KeywordList*) malloc(sizeof(EXTRACTOR_KeywordList));
+    result->next = next;
+    result->keyword = strdup(keyword);
+    result->keywordType = type;
+    return result;
+  }
+
+ 
+  // read the type of the property and displays its value
+  char * getProperty( POLE::Stream* stream ) {
+    unsigned long read, type;
+    unsigned char buffer[256];
+    unsigned char c;
+    unsigned long i;
+    unsigned int j;
+    unsigned long t, t1, t2;
+    char *s;
+    
+    read = stream->read(buffer, 4);
+    type = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 
24);
+    
+    switch (type) {
+    case 2: // VT_I2
+      read = stream->read(buffer, 2);
+      i = buffer[0] + (buffer[1] << 8);
+      s = (char*) malloc(16);
+      snprintf(s, 16, "%u", i);
+      return s;
+    case 3: // VT_I4
+      read = stream->read(buffer, 4);
+      i = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24);
+      s = (char*) malloc(16);
+      snprintf(s, 16, "%u", i);
+      return s;
+    case 11: // VT_BOOL
+      read = stream->read(buffer, 1);
+      if ((char) buffer[0] == -1)
+       return strdup("true");
+      return strdup("false");
+    case 30: // VT_LPSTR
+      read = stream->read(buffer, 4);
+      i = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24);
+      if ( (i < 0) || (i > 16*1024*1024))
+       return NULL;
+      s = (char*) malloc(i+1);
+      s[i] = '\0';
+      j = 0;
+      while ( ((c = stream->getch()) != 0) && (i > j) )
+       s[j++] = c;
+      if (j != i) {
+       free(s);
+       return NULL;
+      }
+      return s;
+    case 64: // VT_FILETIME
+      read = stream->read(buffer, 8);
+      t1 = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 
24);
+      t2 = buffer[4]  + (buffer[5] << 8) + (buffer[6] << 16) + (buffer[7] << 
24);
+      t = filetime_to_unixtime(t1, t2);
+      return ctime_r((time_t *) &t, (char*)malloc(32));
+    }
+    return NULL;
+  }
+
+
+  struct EXTRACTOR_Keywords * libextractor_word_extract(const char * filename,
+                                                       const char * data,
+                                                       size_t size,
+                                                       struct 
EXTRACTOR_Keywords * prev) {
+    char ver[16];
+    if (size < 512 + 898)
+      return prev;
+    const unsigned char * buffer = (const unsigned char*) &data[512];
+    unsigned int wIdent = buffer[0] + (buffer[1] << 8);
+    unsigned int nProduct = buffer[4] + (buffer[5] << 8);
+    unsigned int lid = buffer[6] + (buffer[7] << 8);
+    unsigned int envr = buffer[18];
+    unsigned int wMagicCreated = buffer[34] + (buffer[35] << 8);
+    unsigned int wMagicRevised = buffer[36] + (buffer[37] << 8);
+    unsigned long lProductCreated = buffer[68] + (buffer[69] << 8) + 
(buffer[70] << 16) + (buffer[71] << 24);
+    unsigned long lProductRevised = buffer[72] + (buffer[73] << 8) + 
(buffer[74] << 16) + (buffer[75] << 24);
+    unsigned long fcSttbSavedBy = buffer[722] + (buffer[723] << 8) + 
(buffer[724] << 16) + (buffer[725] << 24);
+    unsigned long lcbSttbSavedBy = buffer[726] + (buffer[727] << 8) + 
(buffer[728] << 16) + (buffer[729] << 24);
+    
+    snprintf(ver, 16, "%u", nProduct);
+    prev = addKeyword(EXTRACTOR_PRODUCTVERSION,
+                     ver,
+                     prev);
+    prev = addKeyword(EXTRACTOR_LANGUAGE,
+                     lidToLanguage(lid),
+                     prev);
+    
+    // cout << "Created by: " << idToProduct(wMagicCreated) << " (Build " << 
dateToString(lProductCreated) << ")" << endl;
+    // cout << "Revised by: " << idToProduct(wMagicRevised) << " (Build " << 
dateToString(lProductRevised) << ")" << endl;
+    
+    POLE::Storage* storage = new POLE::Storage( filename );
+    storage->open();
+    if( storage->result() != POLE::Storage::Ok )
+      return prev;
+    
+    POLE::Stream * stream = storage->stream( "SummaryInformation" );
+    if (stream) {
+      unsigned char buffer[256];
+      
+      // ClassID & Offset
+      stream->seek(28);
+      stream->read(buffer, 20);
+      // beginning of section
+      unsigned long begin = stream->tell();
+      // length of section
+      unsigned long read = stream->read(buffer, 4);
+      // number of properties
+      read = stream->read(buffer, 4);
+      unsigned int nproperties = buffer[0] + (buffer[1] << 8) + (buffer[2] << 
16) + (buffer[3] << 24);
+      // properties
+      for (unsigned int i = 0; i < nproperties; i++) {
+       read = stream->read(buffer, 8);
+       unsigned int propertyID = buffer[0] + (buffer[1] << 8) + (buffer[2] << 
16) + (buffer[3] << 24);
+       unsigned int offsetProp = buffer[4] + (buffer[5] << 8) + (buffer[6] << 
16) + (buffer[7] << 24);
+       if (propertyID > 1 && propertyID < 20) {
+         // cout << SummaryProperties[propertyID] << ": ";
+         unsigned long offsetCur = stream->tell();
+         stream->seek(offsetProp + begin);
+         // read and show the property
+         char * prop = getProperty(stream);  
+         free(prop);
+         stream->seek(offsetCur);
+       }
+      }
+    }
+    
+    unsigned int where = 0;
+    
+    // FIXME: should look if using 0Table or 1Table
+    stream = storage->stream( "1Table" );
+    if (stream) {
+      unsigned char * buffer = new unsigned char[lcbSttbSavedBy];
+      unsigned char buffer2[1024];
+      
+      // goto offset of revision
+      stream->seek(fcSttbSavedBy);
+      // read all the revision history
+      stream->read(buffer, lcbSttbSavedBy);
+      
+      // there are n strings, so n/2 revisions (author & file)
+      unsigned int nRev = (buffer[2] + (buffer[3] << 8)) / 2;
+      where = 6;
+      
+      for (unsigned int i=0; i < nRev; i++) {
+       // cout << "Rev #" << i << ": Author \"";
+       unsigned int length = buffer[where++];
+       // it's unicode, for now we only get the low byte
+       for (unsigned int j=0; j < length; j++) {
+         where++;
+         // cout << buffer[where];
+         where++;
+       }
+       where++;
+       // cout << "\" worked on file \"";
+       length = buffer[where++];
+       // it's unicode, for now we only get the low byte
+       for (unsigned int j=0; j < length; j++) {
+         where++;
+         // cout << buffer[where];
+         where++;
+       }
+       where++;
+       // cout << "\"" << endl;    
+      }
+      
+      delete buffer;
+    
+    }
+    delete storage;
+    
+    return prev;
+  }
+
+}
+

Copied: Extractor/src/plugins/wordleaker/wordleaker.cpp (from rev 2465, 
Extractor/src/plugins/wordleaker/WordLeaker.cpp)
===================================================================
--- Extractor/src/plugins/wordleaker/WordLeaker.cpp     2006-02-22 18:21:26 UTC 
(rev 2465)
+++ Extractor/src/plugins/wordleaker/wordleaker.cpp     2006-03-08 13:52:16 UTC 
(rev 2466)
@@ -0,0 +1,311 @@
+/* 
+   WordLeaker - Shows information about Word DOC files
+   Copyright (C) 2005 Sacha Fuentes <address@hidden>
+
+   Based on poledump.c
+   Original idea from WordDumper (http://www.computerbytesman.com)
+   Info on Word format: http://www.aozw65.dsl.pipex.com/generator_wword8.htm
+   Info on Word format: http://jakarta.apache.org/poi/hpsf/internals.html
+   
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, US
+*/
+
+// TAKE CARE: there's not a single check for validity of data,
+// so any malformed or malicious Word file will break it
+
+#include <iostream>
+#include <fstream>
+#include <stdlib.h>
+#include <list>
+#include <ctime>
+
+#include "pole.h"
+#include "WordLeaker.h"
+
+unsigned long fcSttbSavedBy;
+unsigned long lcbSttbSavedBy;
+  
+// read the type of the property and displays its value
+void showProperty( POLE::Stream* stream ) {
+  unsigned long read, type;
+  unsigned char buffer[256];
+  unsigned char c;
+  unsigned long i;
+  unsigned long t, t1, t2;
+  char *s;
+    
+  read = stream->read(buffer, 4);
+  type = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24);
+    
+  switch (type) {
+      case 2: // VT_I2
+        read = stream->read(buffer, 2);
+        i = buffer[0] + (buffer[1] << 8);
+        cout << i << endl;
+        break;
+      case 3: // VT_I4
+        read = stream->read(buffer, 4);
+        i = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 
24);
+        cout << i << endl;
+        break;
+      case 11: // VT_BOOL
+        read = stream->read(buffer, 1);
+        if ((char) buffer[0] == -1)
+            cout << "true" << endl;
+        else        
+            cout << "false" << endl;
+        break;
+      case 30: // VT_LPSTR
+        read = stream->read(buffer, 4);
+        i = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 
24);
+        while ((c = stream->getch()) != 0)
+            cout << c;
+        cout << endl;
+        break;
+      case 64: // VT_FILETIME
+        read = stream->read(buffer, 8);
+        t1 = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 
24);
+        t2 = buffer[4]  + (buffer[5] << 8) + (buffer[6] << 16) + (buffer[7] << 
24);
+        t = filetime_to_unixtime(t1, t2);
+        s = ctime((time_t *) &t);
+        cout << s;
+        break;
+      default:
+          cout << "Unknown format " << type << endl;
+  }
+}
+
+// show the revision data (users and files)
+void dumpRevision( POLE::Storage* storage ) {
+  unsigned int nRev;
+  unsigned int where = 0;
+  POLE::Stream* stream;
+    
+  cout << "Revision:" << endl;
+  cout << "---------" << endl << endl;
+
+  // FIXME: should look if using 0Table or 1Table
+  stream = storage->stream( "1Table" );
+  if( !stream ) {
+      cout << "There's no revision information" << endl;
+      return;
+  }
+  
+  unsigned char * buffer = new unsigned char[lcbSttbSavedBy];
+  unsigned char buffer2[1024];
+  unsigned int length;
+  
+  // goto offset of revision
+  stream->seek(fcSttbSavedBy);
+  // read all the revision history
+  stream->read(buffer, lcbSttbSavedBy);
+
+  // there are n strings, so n/2 revisions (author & file)
+  nRev = (buffer[2] + (buffer[3] << 8)) / 2;
+  where = 6;
+  
+  for (unsigned int i=0; i < nRev; i++) {
+    cout << "Rev #" << i << ": Author \"";
+    length = buffer[where++];
+    // it's unicode, for now we only get the low byte
+    for (unsigned int j=0; j < length; j++) {
+        where++;
+        cout << buffer[where];
+        where++;
+    }
+    where++;
+    cout << "\" worked on file \"";
+    length = buffer[where++];
+    // it's unicode, for now we only get the low byte
+    for (unsigned int j=0; j < length; j++) {
+        where++;
+        cout << buffer[where];
+        where++;
+    }
+    where++;
+    cout << "\"" << endl;    
+  }
+  
+  cout << endl;      
+  delete buffer;
+  
+}
+
+// show data from DocumentSummary stream
+void dumpDocumentSummary( POLE::Storage* storage ) {
+  POLE::Stream* stream;
+  unsigned long read, nproperties, propertyID, offsetProp, offsetCur;
+  unsigned long begin;
+    
+  cout << "Document Summary:" << endl;
+  cout << "-----------------" << endl << endl;
+
+  stream = storage->stream( "DocumentSummaryInformation" );
+  if( !stream ) {
+      cout << "There's no document summary information" << endl;
+      return;
+  }
+  
+  unsigned char buffer[256];
+
+  // ClassID & Offset
+  stream->seek(28);
+  stream->read(buffer, 20);
+  // beginning of section
+  begin = stream->tell();
+  // length of section
+  read = stream->read(buffer, 4);
+  // number of properties
+  read = stream->read(buffer, 4);
+  nproperties = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] 
<< 24);
+  // properties
+
+  for (unsigned long i = 0; i < nproperties; i++) {
+    read = stream->read(buffer, 8);
+    propertyID = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] 
<< 24);
+    offsetProp = buffer[4] + (buffer[5] << 8) + (buffer[6] << 16) + (buffer[7] 
<< 24);
+      if (propertyID > 1 && propertyID < 16) {
+        cout << DocumentSummaryProperties[propertyID] << ": ";
+        offsetCur = stream->tell();
+        stream->seek(offsetProp + begin);
+        // read and show the property
+        showProperty(stream);  
+        stream->seek(offsetCur);
+    }
+  }
+
+  cout << endl;      
+}
+
+// show data from Summary stream
+void dumpSummary( POLE::Storage* storage ) {
+  POLE::Stream* stream;
+  unsigned long read, nproperties, propertyID, offsetProp, offsetCur;
+  unsigned long begin;
+    
+  cout << "Summary:" << endl;
+  cout << "--------" << endl << endl;
+
+  stream = storage->stream( "SummaryInformation" );
+  if( !stream ) {
+      cout << "There's no summary information" << endl;
+      return;
+  }
+  
+  unsigned char buffer[256];
+
+  // ClassID & Offset
+  stream->seek(28);
+  stream->read(buffer, 20);
+  // beginning of section
+  begin = stream->tell();
+  // length of section
+  read = stream->read(buffer, 4);
+  // number of properties
+  read = stream->read(buffer, 4);
+  nproperties = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] 
<< 24);
+  // properties
+  for (unsigned long i = 0; i < nproperties; i++) {
+    read = stream->read(buffer, 8);
+    propertyID = buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] 
<< 24);
+    offsetProp = buffer[4] + (buffer[5] << 8) + (buffer[6] << 16) + (buffer[7] 
<< 24);
+    if (propertyID > 1 && propertyID < 20) {
+        cout << SummaryProperties[propertyID] << ": ";
+        offsetCur = stream->tell();
+        stream->seek(offsetProp + begin);
+        // read and show the property
+        showProperty(stream);  
+        stream->seek(offsetCur);
+    }
+  }
+
+  cout << endl;      
+}
+
+// reads the header of the file
+bool readFIB( char* filename ) {
+  fstream file;
+    
+   file.open( filename, std::ios::binary | std::ios::in );
+  if( !file.good() ) {
+    cout << "Can't find the file" << endl;
+    return false;
+  }
+  
+  unsigned char * buffer = new unsigned char[898];
+  file.seekg( 512 ); 
+  file.read( (char*)buffer, 898 );
+  file.close();
+  
+  unsigned int wIdent = buffer[0] + (buffer[1] << 8);
+  unsigned int nProduct = buffer[4] + (buffer[5] << 8);
+  unsigned int lid = buffer[6] + (buffer[7] << 8);
+  unsigned int envr = buffer[18];
+  unsigned int wMagicCreated = buffer[34] + (buffer[35] << 8);
+  unsigned int wMagicRevised = buffer[36] + (buffer[37] << 8);
+  unsigned long lProductCreated = buffer[68] + (buffer[69] << 8) + (buffer[70] 
<< 16) + (buffer[71] << 24);
+  unsigned long lProductRevised = buffer[72] + (buffer[73] << 8) + (buffer[74] 
<< 16) + (buffer[75] << 24);
+  fcSttbSavedBy = buffer[722] + (buffer[723] << 8) + (buffer[724] << 16) + 
(buffer[725] << 24);
+  lcbSttbSavedBy = buffer[726] + (buffer[727] << 8) + (buffer[728] << 16) + 
(buffer[729] << 24);
+  delete[] buffer; 
+  
+  cout << "File: " << filename << endl;
+  cout << "Product version: " << nProduct << endl;  
+  cout << "Language: " << lidToLanguage(lid) << endl;
+  cout << "Created by: " << idToProduct(wMagicCreated) << " (Build " << 
dateToString(lProductCreated) << ")" << endl;
+  cout << "Revised by: " << idToProduct(wMagicRevised) << " (Build " << 
dateToString(lProductRevised) << ")" << endl;
+  cout << endl;
+  
+  return true; 
+    
+}
+
+#if HAVE_MAIN
+int main(int argc, char *argv[]) {
+  cout << endl << "WordLeaker v.0.1" << endl;
+  cout << " by Madelman (http://elligre.tk/madelman/)" << endl << endl;
+  
+    
+  if( argc < 2 ) {
+    cout << "  You must supply a filename" << endl << endl;
+    return 0;
+  }
+  
+  char* filename = argv[1];
+
+  if ( !readFIB(filename) )
+      return 1;
+  
+  POLE::Storage* storage = new POLE::Storage( filename );
+  storage->open();
+  if( storage->result() != POLE::Storage::Ok ) {
+    cout << "The file " << filename << " is not a Word document" << endl;
+    return 1;
+  }
+  
+  dumpSummary( storage );
+  // FIXME: doesn't always work
+  // but there's nothing really interesting in here
+  //dumpDocumentSummary( storage );
+  dumpRevision( storage );
+  // TODO: we don't show the GUID
+  // TODO: we don't show the macros
+  
+  delete storage;
+  
+  return 0;
+}
+#endif

Copied: Extractor/src/plugins/wordleaker/wordleaker.h (from rev 2465, 
Extractor/src/plugins/wordleaker/WordLeaker.h)
===================================================================
--- Extractor/src/plugins/wordleaker/WordLeaker.h       2006-02-22 18:21:26 UTC 
(rev 2465)
+++ Extractor/src/plugins/wordleaker/wordleaker.h       2006-03-08 13:52:16 UTC 
(rev 2466)
@@ -0,0 +1,287 @@
+/* 
+   WordLeaker - Shows information about Word DOC files
+   Copyright (C) 2005 Sacha Fuentes <address@hidden>
+
+   Based on poledump.c
+   Original idea from WordDumper (http://www.computerbytesman.com)
+   Info on Word format: http://www.aozw65.dsl.pipex.com/generator_wword8.htm
+   Info on Word format: http://jakarta.apache.org/poi/hpsf/internals.html
+   
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, US
+*/
+
+#include <string>
+
+using namespace std;
+
+static char* SummaryProperties[] = {
+"Unknown", 
+"Unknown",
+"Title",
+"Subject",
+"Author",
+"Keywords",
+"Comments",
+"Template",
+"Last Saved By",
+"Revision Number",
+"Total Editing Time",
+"Last Printed",
+"Create Time/Date",
+"Last Saved Time/Date",
+"Number of Pages",
+"Number of Words",
+"Number of Characters",
+"Thumbnails",
+"Creating Application",
+"Security"
+};
+
+static char* DocumentSummaryProperties[] = {
+"Dictionary",
+"Code page",
+"Category",
+"PresentationTarget",
+"Bytes",
+"Lines",
+"Paragraphs",
+"Slides",
+"Notes",
+"HiddenSlides",
+"MMClips",
+"ScaleCrop",
+"HeadingPairs",
+"TitlesofParts",
+"Manager",
+"Company",
+"LinksUpTo"
+};
+
+string dateToString( unsigned long date ) {
+  char f[9];
+  sprintf(f, "%d/%d/%d", (date / 10000 % 100), (date / 100 % 100), (date % 
100));
+  return f;
+}
+
+string idToProduct( unsigned int id ) {
+  // TODO: find the rest of ids
+  switch ( id ) {
+    case  0x6A62:
+        return "Word 97";
+    case 0x626A:
+        return "Word 98 (Mac)";
+    default:
+        return "Unknown";
+  }      
+}
+
+const char * lidToLanguage( unsigned int lid ) {
+  switch ( lid ) {
+    case 0x0400: 
+        return "No Proofing";
+    case 0x0401: 
+        return "Arabic";
+    case 0x0402:
+        return "Bulgarian";
+    case 0x0403:
+        return "Catalan";
+    case 0x0404:
+        return "Traditional Chinese";
+    case 0x0804:
+        return "Simplified Chinese";
+    case 0x0405:
+        return "Czech";
+    case 0x0406:
+        return "Danish";
+    case 0x0407:
+        return "German";
+    case 0x0807:
+        return "Swiss German";
+    case 0x0408:
+        return "Greek";
+    case 0x0409:
+        return "U.S. English";
+    case 0x0809:
+        return "U.K. English";
+    case 0x0c09:
+        return "Australian English";
+    case 0x040a:
+        return "Castilian Spanish";
+    case 0x080a:
+        return "Mexican Spanish";
+    case 0x040b:
+        return "Finnish";
+    case 0x040c:
+        return "French";
+    case 0x080c:
+        return "Belgian French";
+    case 0x0c0c:
+        return "Canadian French";
+    case 0x100c:
+        return "Swiss French";
+    case 0x040d:
+        return "Hebrew";
+    case 0x040e:
+        return "Hungarian";
+    case 0x040f:
+        return "Icelandic";
+    case 0x0410:
+        return "Italian";
+    case 0x0810:
+        return "Swiss Italian";
+    case 0x0411:
+        return "Japanese";
+    case 0x0412:
+        return "Korean";
+    case 0x0413:
+        return "Dutch";
+    case 0x0813:
+        return "Belgian Dutch";
+    case 0x0414:
+        return "Norwegian - Bokmal";
+    case 0x0814:
+        return "Norwegian - Nynorsk";
+    case 0x0415:
+        return "Polish";
+    case 0x0416:
+        return "Brazilian Portuguese";
+    case 0x0816:
+        return "Portuguese";
+    case 0x0417:
+        return "Rhaeto-Romanic";
+    case 0x0418:
+        return "Romanian";
+    case 0x0419:
+        return "Russian";
+    case 0x041a:
+        return "Croato-Serbian (Latin)";
+    case 0x081a:
+        return "Serbo-Croatian (Cyrillic)";
+    case 0x041b:
+        return "Slovak";
+    case 0x041c:
+        return "Albanian";
+    case 0x041d:
+        return "Swedish";
+    case 0x041e:
+        return "Thai";
+    case 0x041f:
+        return "Turkish";
+    case 0x0420:
+        return "Urdu";
+    case 0x0421:
+        return "Bahasa"; 
+    case 0x0422:
+        return "Ukrainian";
+    case 0x0423:
+        return "Byelorussian";
+    case 0x0424:
+        return "Slovenian";
+    case 0x0425:
+        return "Estonian";
+    case 0x0426:
+        return "Latvian";
+    case 0x0427:
+        return "Lithuanian";
+    case 0x0429:
+        return "Farsi";
+    case 0x042D:
+        return "Basque";
+    case 0x042F:
+        return "Macedonian";
+    case 0x0436:
+        return "Afrikaans";
+    case 0x043E:
+        return "Malaysian";  
+    default:
+        return "Unknown";
+  }
+}
+
+/*
+ *  filetime_to_unixtime
+ *
+ *  Adapted from work in 'wv' by:
+ *    Caolan McNamara (address@hidden)
+ */
+#define HIGH32_DELTA 27111902
+#define MID16_DELTA  54590
+#define LOW16_DELTA  32768
+
+unsigned long filetime_to_unixtime (unsigned long low_time, unsigned long 
high_time) {
+  unsigned long low16;/* 16 bit, low    bits */
+  unsigned long mid16;/* 16 bit, medium bits */
+  unsigned long hi32;/* 32 bit, high   bits */
+  unsigned int carry;/* carry bit for subtraction */
+  int negative;/* whether a represents a negative value */
+
+/* Copy the time values to hi32/mid16/low16 */
+hi32  =  high_time;
+mid16 = low_time >> 16;
+low16 = low_time &  0xffff;
+
+/* Subtract the time difference */
+if (low16 >= LOW16_DELTA           )
+low16 -=             LOW16_DELTA        , carry = 0;
+else
+low16 += (1 << 16) - LOW16_DELTA        , carry = 1;
+
+if (mid16 >= MID16_DELTA    + carry)
+mid16 -=             MID16_DELTA + carry, carry = 0;
+else
+mid16 += (1 << 16) - MID16_DELTA - carry, carry = 1;
+
+hi32 -= HIGH32_DELTA + carry;
+
+/* If a is negative, replace a by (-1-a) */
+negative = (hi32 >= ((unsigned long)1) << 31);
+if (negative) {
+/* Set a to -a - 1 (a is hi32/mid16/low16) */
+low16 = 0xffff - low16;
+mid16 = 0xffff - mid16;
+hi32 = ~hi32;
+}
+
+/*
+ *  Divide a by 10000000 (a = hi32/mid16/low16), put the rest into r.
+         * Split the divisor into 10000 * 1000 which are both less than 0xffff.
+ */
+mid16 += (hi32 % 10000) << 16;
+hi32  /=       10000;
+low16 += (mid16 % 10000) << 16;
+mid16 /=       10000;
+low16 /=       10000;
+
+mid16 += (hi32 % 1000) << 16;
+hi32  /=       1000;
+low16 += (mid16 % 1000) << 16;
+mid16 /=       1000;
+low16 /=       1000;
+
+/* If a was negative, replace a by (-1-a) and r by (9999999 - r) */
+if (negative) {
+/* Set a to -a - 1 (a is hi32/mid16/low16) */
+low16 = 0xffff - low16;
+mid16 = 0xffff - mid16;
+hi32 = ~hi32;
+}
+
+/*  Do not replace this by << 32, it gives a compiler warning and
+ *  it does not work
+ */
+return ((((unsigned long)hi32) << 16) << 16) + (mid16 << 16) + low16;
+
+}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]