summaryrefslogtreecommitdiff
path: root/src/md/inc/mdfileformat.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/md/inc/mdfileformat.h')
-rw-r--r--src/md/inc/mdfileformat.h269
1 files changed, 269 insertions, 0 deletions
diff --git a/src/md/inc/mdfileformat.h b/src/md/inc/mdfileformat.h
new file mode 100644
index 0000000000..a86549323e
--- /dev/null
+++ b/src/md/inc/mdfileformat.h
@@ -0,0 +1,269 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//*****************************************************************************
+// MDFileFormat.h
+//
+
+//
+// This file contains a set of helpers to verify and read the file format.
+// This code does not handle the paging of the data, or different types of
+// I/O. See the StgTiggerStorage and StgIO code for this level of support.
+//
+//*****************************************************************************
+#ifndef __MDFileFormat_h__
+#define __MDFileFormat_h__
+
+//*****************************************************************************
+// The signature ULONG is the first 4 bytes of the file format. The second
+// signature string starts the header containing the stream list. It is used
+// for an integrity check when reading the header in lieu of a more complicated
+// system.
+//*****************************************************************************
+#define STORAGE_MAGIC_SIG 0x424A5342 // BSJB
+
+
+
+//*****************************************************************************
+// These values get written to the signature at the front of the file. Changing
+// these values should not be done lightly because all old files will no longer
+// be supported. In a future revision if a format change is required, a
+// backwards compatible migration path must be provided.
+//*****************************************************************************
+
+#define FILE_VER_MAJOR 1
+#define FILE_VER_MINOR 1
+
+// These are the last legitimate 0.x version macros. The file format has
+// sinced move up to 1.x (see macros above). After COM+ 1.0/NT 5 RTM's, these
+// macros should no longer be required or ever seen.
+#define FILE_VER_MAJOR_v0 0
+
+#define FILE_VER_MINOR_v0 19
+
+
+#define MAXSTREAMNAME 32
+
+enum
+{
+ STGHDR_NORMAL = 0x00, // Normal default flags.
+ STGHDR_EXTRADATA = 0x01, // Additional data exists after header.
+};
+
+
+//*****************************************************************************
+// This is the formal signature area at the front of the file. This structure
+// is not allowed to change, the shim depends on it staying the same size.
+// Use the reserved pointer if it must extended.
+//*****************************************************************************
+struct STORAGESIGNATURE;
+typedef STORAGESIGNATURE UNALIGNED * PSTORAGESIGNATURE;
+
+#include "pshpack1.h"
+struct STORAGESIGNATURE
+{
+METADATA_FIELDS_PROTECTION:
+ ULONG lSignature; // "Magic" signature.
+ USHORT iMajorVer; // Major file version.
+ USHORT iMinorVer; // Minor file version.
+ ULONG iExtraData; // Offset to next structure of information
+ ULONG iVersionString; // Length of version string
+public:
+ BYTE pVersion[0]; // Version string
+ ULONG GetSignature()
+ {
+ return VAL32(lSignature);
+ }
+ void SetSignature(ULONG Signature)
+ {
+ lSignature = VAL32(Signature);
+ }
+
+ USHORT GetMajorVer()
+ {
+ return VAL16(iMajorVer);
+ }
+ void SetMajorVer(USHORT MajorVer)
+ {
+ iMajorVer = VAL16(MajorVer);
+ }
+
+ USHORT GetMinorVer()
+ {
+ return VAL16(iMinorVer);
+ }
+ void SetMinorVer(USHORT MinorVer)
+ {
+ iMinorVer = VAL16(MinorVer);
+ }
+
+ ULONG GetExtraDataOffset()
+ {
+ return VAL32(iExtraData);
+ }
+ void SetExtraDataOffset(ULONG ExtraDataOffset)
+ {
+ iExtraData = VAL32(ExtraDataOffset);
+ }
+
+ ULONG GetVersionStringLength()
+ {
+ return VAL32(iVersionString);
+ }
+ void SetVersionStringLength(ULONG VersionStringLength)
+ {
+ iVersionString = VAL32(VersionStringLength);
+ }
+};
+#include "poppack.h"
+
+
+//*****************************************************************************
+// The header of the storage format.
+//*****************************************************************************
+struct STORAGEHEADER;
+typedef STORAGEHEADER UNALIGNED * PSTORAGEHEADER;
+
+#include "pshpack1.h"
+struct STORAGEHEADER
+{
+METADATA_FIELDS_PROTECTION:
+ BYTE fFlags; // STGHDR_xxx flags.
+ BYTE pad;
+ USHORT iStreams; // How many streams are there.
+public:
+ BYTE GetFlags()
+ {
+ return fFlags;
+ }
+ void SetFlags(BYTE flags)
+ {
+ fFlags = flags;
+ }
+ void AddFlags(BYTE flags)
+ {
+ fFlags |= flags;
+ }
+
+
+ USHORT GetiStreams()
+ {
+ return VAL16(iStreams);
+ }
+ void SetiStreams(USHORT iStreamsCount)
+ {
+ iStreams = VAL16(iStreamsCount);
+ }
+};
+#include "poppack.h"
+
+
+//*****************************************************************************
+// Each stream is described by this struct, which includes the offset and size
+// of the data. The name is stored in ANSI null terminated.
+//*****************************************************************************
+struct STORAGESTREAM;
+typedef STORAGESTREAM UNALIGNED * PSTORAGESTREAM;
+
+#include "pshpack1.h"
+struct STORAGESTREAM
+{
+METADATA_FIELDS_PROTECTION:
+ ULONG iOffset; // Offset in file for this stream.
+ ULONG iSize; // Size of the file.
+ char rcName[MAXSTREAMNAME]; // Start of name, null terminated.
+public:
+ // Returns pointer to the next stream. Doesn't validate the structure.
+ inline PSTORAGESTREAM NextStream()
+ {
+ int iLen = (int)(strlen(rcName) + 1);
+ iLen = ALIGN4BYTE(iLen);
+ return ((PSTORAGESTREAM) (((BYTE*)this) + (sizeof(ULONG) * 2) + iLen));
+ }
+ // Returns pointer to the next stream.
+ // Returns NULL if the structure has invalid format.
+ inline PSTORAGESTREAM NextStream_Verify()
+ {
+ // Check existence of null-terminator in the name
+ if (memchr(rcName, 0, MAXSTREAMNAME) == NULL)
+ {
+ return NULL;
+ }
+ return NextStream();
+ }
+
+ inline ULONG GetStreamSize()
+ {
+ return (ULONG)(strlen(rcName) + 1 + (sizeof(STORAGESTREAM) - sizeof(rcName)));
+ }
+
+ inline char* GetName()
+ {
+ return rcName;
+ }
+ inline LPCWSTR GetName(__inout_ecount (iMaxSize) LPWSTR szName, int iMaxSize)
+ {
+ VERIFY(::WszMultiByteToWideChar(CP_ACP, 0, rcName, -1, szName, iMaxSize));
+ return (szName);
+ }
+ inline void SetName(LPCWSTR szName)
+ {
+ int size;
+ size = WszWideCharToMultiByte(CP_ACP, 0, szName, -1, rcName, MAXSTREAMNAME, 0, 0);
+ _ASSERTE(size > 0);
+ }
+
+ ULONG GetSize()
+ {
+ return VAL32(iSize);
+ }
+ void SetSize(ULONG Size)
+ {
+ iSize = VAL32(Size);
+ }
+
+ ULONG GetOffset()
+ {
+ return VAL32(iOffset);
+ }
+ void SetOffset(ULONG Offset)
+ {
+ iOffset = VAL32(Offset);
+ }
+};
+#include "poppack.h"
+
+
+class MDFormat
+{
+public:
+//*****************************************************************************
+// Verify the signature at the front of the file to see what type it is.
+//*****************************************************************************
+ static HRESULT VerifySignature(
+ PSTORAGESIGNATURE pSig, // The signature to check.
+ ULONG cbData); // Size of metadata.
+
+//*****************************************************************************
+// Skip over the header and find the actual stream data.
+// It doesn't perform any checks for buffer overflow - use GetFirstStream_Verify
+// instead.
+//*****************************************************************************
+ static PSTORAGESTREAM GetFirstStream(// Return pointer to the first stream.
+ PSTORAGEHEADER pHeader, // Return copy of header struct.
+ const void *pvMd); // Pointer to the full file.
+//*****************************************************************************
+// Skip over the header and find the actual stream data. Secure version of
+// GetFirstStream method.
+// The header is supposed to be verified by VerifySignature.
+//
+// Caller has to check available buffer size before using the first stream.
+//*****************************************************************************
+ static PSTORAGESTREAM GetFirstStream_Verify(// Return pointer to the first stream.
+ PSTORAGEHEADER pHeader, // Return copy of header struct.
+ const void *pvMd, // Pointer to the full file.
+ ULONG *pcbMd); // [in, out] Size of pvMd buffer (we don't want to read behind it)
+
+};
+
+#endif // __MDFileFormat_h__