Skip to content

Instantly share code, notes, and snippets.

@tmplinshi
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmplinshi/10261365 to your computer and use it in GitHub Desktop.
Save tmplinshi/10261365 to your computer and use it in GitHub Desktop.
; Last update: 2014-4-23
IsOfficeFile(FileName, Extensions = "doc,docx,xls,xlsx,ppt,pptx") {
static doc := "57006f007200640044006f00630075006d0065006e0074" ; W.o.r.d.D.o.c.u.m.e.n.t
, docx := "00776F72642F" ; .word/
, xls := "0057006f0072006b0062006f006f006b00" ; .W.o.r.k.b.o.o.k.
, xlsx := "0000786C2F" ; ..xl/
, ppt := "0050006f0077006500720050006f0069006e007400200044006f00630075006d0065006e007400" ; .P.o.w.e.r.P.o.i.n.t. .D.o.c.u.m.e.n.t.
, pptx := "00007070742F" ; ..ppt/
; =======================================
; Check first 4 bytes
; =======================================
File := FileOpen(FileName, "r")
File.RawRead(bin, 4)
MCode_Bin2Hex(&bin, 4, hex)
; Magic Numbers (http://en.wikipedia.org/wiki/List_of_file_signatures)
; doc/xls/ppt: D0CF11E0
; zip/jar/odt/ods/odp/docx/xlsx/pptx/apk: 504B0304, 504B0506 (empty archive) or 504B0708 (spanned archive)
If hex not in D0CF11E0,504B0304,504B0506,504B0708
Return "", File.Close()
; =======================================
; docx/xlsx/pptx --> check last 1024 bytes
; =======================================
If hex in 504B0304,504B0506,504B0708
{
File.Position := File.Length - 1024
File.RawRead(bin, 1024)
File.Close()
MCode_Bin2Hex(&bin, 1024, hex)
Loop, Parse, Extensions, CSV, %A_Space%%A_Tab%
If ( InStr(hex, %A_LoopField%) )
Return A_LoopField
Return
}
; =======================================
; detect doc/xls/ppt
; Reference: Daniel Rentz. Microsoft Compound Document File Format. 2006-Dec - 21.
; =======================================
; SecID of first sector of the directory stream
File.Position := 48
File.RawRead(bin, 4)
MCode_Bin2Hex(&bin, 4, hex)
SecID1 := "0x" SubStr(hex, 7, 2) SubStr(hex, 5, 2) SubStr(hex, 3, 2) SubStr(hex, 1, 2)
SecID1 := SecID1 + 0
; Jump to this offset...
Offset := 512 * (SecID1 + 1)
Length := 5 * 128
File.Position := Offset
File.RawRead(bin, Length)
MCode_Bin2Hex(&bin, Length, hex)
File.Close()
; detecting...
Loop, Parse, Extensions, CSV, %A_Space%%A_Tab%
If ( InStr(hex, %A_LoopField%) )
Return A_LoopField
}
MCode_Bin2Hex(addr, len, ByRef hex) { ; By Lexikos, http://goo.gl/LjP9Zq
Static fun
If (fun = "") {
If Not A_IsUnicode
h =
( LTrim Join
8B54240C85D2568B7424087E3A53578B7C24148A07478AC8C0E90480F9090F97C3F6
DB80E30702D980C330240F881E463C090F97C1F6D980E10702C880C130880E464A75
CE5F5BC606005EC3
)
Else
h =
( LTrim Join
8B44240C8B4C240485C07E53568B74240C578BF88A168AC2C0E804463C090FB6C076
066683C037EB046683C03066890180E20F83C10280FA09760C0FB6D26683C2376689
11EB0A0FB6C26683C03066890183C1024F75BD33D25F6689115EC333C0668901C3
)
VarSetCapacity(fun, n := StrLen(h)//2)
Loop % n
NumPut("0x" . SubStr(h, 2 * A_Index - 1, 2), fun, A_Index - 1, "Char")
}
hex := ""
VarSetCapacity(hex, A_IsUnicode ? 4 * len + 2 : 2 * len + 1)
DllCall(&fun, "uint", &hex, "uint", addr, "uint", len, "cdecl")
VarSetCapacity(hex, -1) ;update StrLen
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment