internal short GetDOPFlag(DOPHeader dopHeader, int nOffset) { short bFlags = 0; int sizeFlags = Marshal.SizeOf(bFlags); IntPtr pFlags = Marshal.AllocHGlobal(sizeFlags); try { int iOffset = dopHeader.fcDop + nOffset; Marshal.Copy(m_btContents, iOffset, pFlags, sizeFlags); bFlags = (short) Marshal.PtrToStructure(pFlags, typeof(short)); } finally { Marshal.FreeHGlobal(pFlags); } return bFlags; }
private bool InitialiserMethodForWordFileOnDisk() { StructuredStorageInterface.IStorage iStorage; IStream iStream = GetStream(out iStorage, "WordDocument"); if (null == iStream) return false; StreamWrapper stream; FIB fib; DOPHeader dopHeader; using (new ComObjectGovernor(iStream)) using (new ComObjectGovernor(iStorage)) { stream = new StreamWrapper(iStream); fib = new FIB(); dopHeader = new DOPHeader(); stream.GetDOP(ref dopHeader); object fibObject = fib as object; stream.GetHeaderStructure(ref fibObject); fib = (FIB)fibObject; } // \ / // .\-/. // /\ () () /\ // / \ /~-~\ / \ // y Y V // ,-^-./ | \,-^-. /// { | } \ // \ | / // /\ A /\ // / \/ \/ \ // / \ // // int numLols = 1 // increment every time you see this for the first time if (fib.magicNumber != 0) //THIS ZERO-CHECK IS A HACK FOR PROTECT MOBILE - IT SHOULD BE REMOVED ASAP { //THIS is the proper code to check for Word file versioning. This should stay. if (fib.magicNumber != 0xA5DC && fib.magicNumber != 0xA5EC) return false; } //we will get this far with a docx/docm if it is encrypted but the FIB is empty then so we can drop out now if (fib.bitData == 0 && fib.lid == 0 && fib.magicNumber == 0 && fib.version == 0 && fib.nProduct == 0) { return false; } m_fileData.FileType = FileType.WordDocument; if ((fib.bitData & StreamWrapper.fEncrypted) == StreamWrapper.fEncrypted) m_fileData.ReadPasswordProtected = true; if ((fib.bitData & StreamWrapper.fWriteReservation) == StreamWrapper.fWriteReservation) m_fileData.WritePasswordProtected = true; // only try to find the document protection flags within the DOP if we know that the // file is not encrypted. Otherwise the offsets are not valid. if (!m_fileData.ReadPasswordProtected && !m_fileData.WritePasswordProtected) { //DOPHeader dopHeader = new DOPHeader(); //stream.GetDOP(ref dopHeader); m_fileData.DocumentProtected = HasDocumentProtection(fib, dopHeader); } m_impl = new FileImpl(m_fileData); return true; //} }
internal void GetDOP(ref DOPHeader dopHeader) { int sizeDOPHeader = Marshal.SizeOf(dopHeader); IntPtr pDOPInfo = Marshal.AllocHGlobal(sizeDOPHeader); Marshal.Copy(m_btContents, 0x0192, pDOPInfo, sizeDOPHeader); dopHeader = (DOPHeader)Marshal.PtrToStructure(pDOPInfo, typeof(DOPHeader)); Marshal.FreeHGlobal(pDOPInfo); Logger.LogInfo("DOP offset: " + dopHeader.fcDop.ToString() + " DOP size: " + dopHeader.lcbDop.ToString()); }
private bool HasDocumentProtection(FIB fib, DOPHeader dopHeader) { StructuredStorageInterface.IStorage iStorageDOP; IStream iStreamDOP; // read the fWhichTblStm bit if ((fib.bitData & 0x0200) == 0x0200) { iStreamDOP = GetStream(out iStorageDOP, "1Table"); } else { iStreamDOP = GetStream(out iStorageDOP, "0Table"); } if (iStreamDOP != null) { using (new ComObjectGovernor(iStreamDOP)) using (new ComObjectGovernor(iStorageDOP)) { StreamWrapper streamDOP = new StreamWrapper(iStreamDOP); short bFlags = streamDOP.GetDOPFlag(dopHeader, 0x0006); bool bLockAtn = (bFlags & 0x0010) == 0x0010; // annotations locked for editing bool bProtEnabled = (bFlags & 0x0200) == 0x0200; // document protected for edit operations bool bLockRev = (bFlags & 0x4000) == 0x4000; // revision marking state locked if (bLockAtn || bLockRev || bProtEnabled) { return true; } if (fib.version >= 217) // Word 2000 or later { short bDocumentProtection = streamDOP.GetDOPFlag(dopHeader, 0x0254); bool bEnforceProtection = (bDocumentProtection & 0x0008) == 0x0008; return bEnforceProtection; } } } return false; }