Index: trunk/include/iprt/formats/efi-varstore.h
===================================================================
--- trunk/include/iprt/formats/efi-varstore.h	(revision 90113)
+++ trunk/include/iprt/formats/efi-varstore.h	(revision 90114)
@@ -115,18 +115,36 @@
 
 /** Value in EFI_AUTH_VAR_HEADER::u16StartId for a valid variable header. */
-#define EFI_AUTH_VAR_HEADER_START                       0x55aa
+#define EFI_AUTH_VAR_HEADER_START                               0x55aa
 /** @name Possible variable states.
  * @{ */
 /** Variable is in the process of being deleted. */
-#define EFI_AUTH_VAR_HEADER_STATE_IN_DELETED_TRANSITION 0xfe
+#define EFI_AUTH_VAR_HEADER_STATE_IN_DELETED_TRANSITION         0xfe
 /** Variable was deleted. */
-#define EFI_AUTH_VAR_HEADER_STATE_DELETED               0xfd
+#define EFI_AUTH_VAR_HEADER_STATE_DELETED                       0xfd
 /** Variable has only a valid header right now. */
-#define EFI_AUTH_VAR_HEADER_STATE_HDR_VALID_ONLY        0x7f
+#define EFI_AUTH_VAR_HEADER_STATE_HDR_VALID_ONLY                0x7f
 /** Variable header, name and data are all valid. */
-#define EFI_AUTH_VAR_HEADER_STATE_ADDED                 0x3f
+#define EFI_AUTH_VAR_HEADER_STATE_ADDED                         0x3f
 /** @} */
 
 
+/** @name Possible variable attributes.
+ * @{ */
+/** The variable is stored in non volatile memory. */
+#define EFI_VAR_HEADER_ATTR_NON_VOLATILE                        RT_BIT_32(0)
+/** The variable is accessible by the EFI bootservice stage. */
+#define EFI_VAR_HEADER_ATTR_BOOTSERVICE_ACCESS                  RT_BIT_32(1)
+/** The variable is accessible during runtime. */
+#define EFI_VAR_HEADER_ATTR_RUNTIME_ACCESS                      RT_BIT_32(2)
+/** The variable contains an hardware error record. */
+#define EFI_VAR_HEADER_ATTR_HW_ERROR_RECORD                     RT_BIT_32(3)
+/** The variable can be modified only by an authenticated source. */
+#define EFI_AUTH_VAR_HEADER_ATTR_AUTH_WRITE_ACCESS              RT_BIT_32(4)
+/** The variable was written with a time based authentication. */
+#define EFI_AUTH_VAR_HEADER_ATTR_TIME_BASED_AUTH_WRITE_ACCESS   RT_BIT_32(5)
+/** The variable can be appended. */
+#define EFI_AUTH_VAR_HEADER_ATTR_APPEND_WRITE                   RT_BIT_32(6)
+/** @} */
+
 #endif /* !IPRT_INCLUDED_formats_efi_varstore_h */
 
Index: trunk/src/VBox/Runtime/common/efi/efitime.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/efi/efitime.cpp	(revision 90113)
+++ trunk/src/VBox/Runtime/common/efi/efitime.cpp	(revision 90114)
@@ -54,5 +54,5 @@
     RTTIME Time; RT_ZERO(Time);
 
-    Time.i32Year       = pEfiTime->u16Year + 1900;
+    Time.i32Year       = pEfiTime->u16Year;
     Time.u8Month       = pEfiTime->u8Month;
     Time.u8MonthDay    = pEfiTime->u8Day;
@@ -90,7 +90,7 @@
 
     RT_ZERO(*pEfiTime);
-    pEfiTime->u16Year       =   Time.i32Year < 1900
+    pEfiTime->u16Year       =   Time.i32Year < 0
                               ? 0
-                              : Time.i32Year - 1900;
+                              : (uint16_t)Time.i32Year;
     pEfiTime->u8Month       = Time.u8Month;
     pEfiTime->u8Day         = Time.u8MonthDay;
Index: trunk/src/VBox/Runtime/common/efi/efivarstorevfs.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/efi/efivarstorevfs.cpp	(revision 90113)
+++ trunk/src/VBox/Runtime/common/efi/efivarstorevfs.cpp	(revision 90114)
@@ -66,13 +66,21 @@
     /** Pointer to the owning variable store. */
     PRTEFIVARSTORE      pVarStore;
-    /** Offset of the variable header located in the backing image. */
+    /** Offset of the variable header located in the backing image - 0 if not written yet. */
     uint64_t            offVarHdr;
-    /** Offset of the variable data located in the backing image. */
+    /** Offset of the variable data located in the backing image - 0 if not written yet. */
     uint64_t            offVarData;
-    /** The validated variable header. */
-    EFI_AUTH_VAR_HEADER VarHdr;
+    /** Monotonic counter value. */
+    uint64_t            cMonotonic;
+    /** Size of the variable data in bytes. */
+    uint32_t            cbData;
+    /** Index of the assoicated public key. */
+    uint32_t            idPubKey;
+    /** Attributes for the variable. */
+    uint32_t            fAttr;
     /** Name of the variable. */
     char                *pszName;
-    /** The time creation/update time. */
+    /** The raw EFI timestamp as read from the header. */
+    EFI_TIME            EfiTimestamp;
+    /** The creation/update time. */
     RTTIMESPEC          Time;
     /** The vendor UUID of the variable. */
@@ -88,5 +96,5 @@
 typedef struct RTEFIGUID
 {
-    /** The UUID rpresentation of the GUID. */
+    /** The UUID representation of the GUID. */
     RTUUID              Uuid;
     /** Pointer to the array of indices into RTEFIVARSTORE::paVars. */
@@ -119,5 +127,5 @@
 
     /** Size of the variable store (minus the header). */
-    size_t              cbVarStore;
+    uint64_t            cbVarStore;
     /** Start offset into the backing image where the variable data starts. */
     uint64_t            offStoreData;
@@ -155,8 +163,12 @@
     /** 'by-name' directory. */
     RTEFIVARSTOREDIRTYPE_BY_NAME,
-    /** 'by-guid' directory. */
+    /** 'by-uuid' directory. */
     RTEFIVARSTOREDIRTYPE_BY_GUID,
+    /** 'raw' directory. */
+    RTEFIVARSTOREDIRTYPE_RAW,
     /** Specific 'by-uuid/{...}' directory. */
     RTEFIVARSTOREDIRTYPE_GUID,
+    /** Specific 'raw/{...}' directory. */
+    RTEFIVARSTOREDIRTYPE_RAW_ENTRY,
     /** 32bit blowup hack. */
     RTEFIVARSTOREDIRTYPE_32BIT_HACK = 0x7fffffff
@@ -177,8 +189,10 @@
     /** The variable store associated with this directory. */
     PRTEFIVARSTORE          pVarStore;
+    /** Time when the directory was created. */
+    RTTIMESPEC              Time;
     /** Pointer to the GUID entry, only valid for RTEFIVARSTOREDIRTYPE_GUID. */
     PRTEFIGUID              pGuid;
-    /** Time when the directory was created. */
-    RTTIMESPEC              Time;
+    /** The variable ID, only valid for RTEFIVARSTOREDIRTYPE_RAW_ENTRY. */
+    uint32_t                idVar;
 } RTEFIVARSTOREDIR;
 /** Pointer to an Variable store directory. */
@@ -187,14 +201,60 @@
 
 /**
+ * File type.
+ */
+typedef enum RTEFIVARSTOREFILETYPE
+{
+    /** Invalid type, do not use. */
+    RTEFIVARSTOREFILETYPE_INVALID = 0,
+    /** File accesses the data portion of the variable. */
+    RTEFIVARSTOREFILETYPE_DATA,
+    /** File accesses the attributes of the variable. */
+    RTEFIVARSTOREFILETYPE_ATTR,
+    /** File accesses the UUID of the variable. */
+    RTEFIVARSTOREFILETYPE_UUID,
+    /** File accesses the public key index of the variable. */
+    RTEFIVARSTOREFILETYPE_PUBKEY,
+    /** File accesses the raw EFI Time of the variable. */
+    RTEFIVARSTOREFILETYPE_TIME,
+    /** The monotonic counter (deprecated). */
+    RTEFIVARSTOREFILETYPE_MONOTONIC,
+    /** 32bit hack. */
+    RTEFIVARSTOREFILETYPE_32BIT_HACK = 0x7fffffff,
+} RTEFIVARSTOREFILETYPE;
+
+
+/**
+ * Raw file type entry.
+ */
+typedef struct RTEFIVARSTOREFILERAWENTRY
+{
+    /** Name of the entry. */
+    const char              *pszName;
+    /** The associated file type. */
+    RTEFIVARSTOREFILETYPE   enmType;
+    /** File size of the object, 0 if dynamic. */
+    size_t                  cbObject;
+    /** Offset of the item in the variable header. */
+    uint32_t                offObject;
+} RTEFIVARSTOREFILERAWENTRY;
+/** Pointer to a raw file type entry. */
+typedef RTEFIVARSTOREFILERAWENTRY *PRTEFIVARSTOREFILERAWENTRY;
+/** Pointer to a const file type entry. */
+typedef const RTEFIVARSTOREFILERAWENTRY *PCRTEFIVARSTOREFILERAWENTRY;
+
+
+/**
  * Open file instance.
  */
 typedef struct RTEFIVARFILE
 {
+    /** The file type. */
+    PCRTEFIVARSTOREFILERAWENTRY pEntry;
     /** Variable store this file belongs to. */
-    PRTEFIVARSTORE      pVarStore;
+    PRTEFIVARSTORE              pVarStore;
     /** The underlying variable structure. */
-    PRTEFIVAR           pVar;
+    PRTEFIVAR                   pVar;
     /** Current offset into the file for I/O. */
-    RTFOFF              offFile;
+    RTFOFF                      offFile;
 } RTEFIVARFILE;
 /** Pointer to an open file instance. */
@@ -202,8 +262,25 @@
 
 
+/**
+ * Raw files for accessing specific items in the variable header.
+ */
+static const RTEFIVARSTOREFILERAWENTRY g_aRawFiles[] =
+{
+    { "attr",      RTEFIVARSTOREFILETYPE_ATTR,      sizeof(uint32_t), RT_UOFFSETOF(RTEFIVAR, fAttr)        },
+    { "data",      RTEFIVARSTOREFILETYPE_DATA,                     0,                                    0 },
+    { "uuid",      RTEFIVARSTOREFILETYPE_UUID,      sizeof(RTUUID),   RT_UOFFSETOF(RTEFIVAR, Uuid)         },
+    { "pubkey",    RTEFIVARSTOREFILETYPE_PUBKEY,    sizeof(uint32_t), RT_UOFFSETOF(RTEFIVAR, idPubKey)     },
+    { "time",      RTEFIVARSTOREFILETYPE_TIME,      sizeof(EFI_TIME), RT_UOFFSETOF(RTEFIVAR, EfiTimestamp) },
+    { "monotonic", RTEFIVARSTOREFILETYPE_MONOTONIC, sizeof(uint64_t), RT_UOFFSETOF(RTEFIVAR, cMonotonic)   }
+};
+
+#define RTEFIVARSTORE_FILE_ENTRY_DATA 1
+
+
 /*********************************************************************************************************************************
 *   Internal Functions                                                                                                           *
 *********************************************************************************************************************************/
-static int rtEfiVarStore_NewDirByType(PRTEFIVARSTORE pThis, RTEFIVARSTOREDIRTYPE enmDirType, PRTEFIGUID pGuid, PRTVFSOBJ phVfsObj);
+static int rtEfiVarStore_NewDirByType(PRTEFIVARSTORE pThis, RTEFIVARSTOREDIRTYPE enmDirType,
+                                      PRTEFIGUID pGuid, uint32_t idVar, PRTVFSOBJ phVfsObj);
 
 
@@ -428,55 +505,75 @@
 
 
-/*
- *
- * File operations.
- * File operations.
- * File operations.
- *
- */
-
-/**
- * @interface_method_impl{RTVFSOBJOPS,pfnClose}
- */
-static DECLCALLBACK(int) rtEfiVarStoreFile_Close(void *pvThis)
-{
-    PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis;
-    LogFlow(("rtEfiVarStoreFile_Close(%p/%p)\n", pThis, pThis->pVar));
-    RT_NOREF(pThis);
-    return VINF_SUCCESS;
-}
-
-
-/**
- * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
- */
-static DECLCALLBACK(int) rtEfiVarStoreFile_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
-{
-    PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis;
-    return rtEfiVarStore_QueryInfo(RT_LE2H_U32(pThis->pVar->VarHdr.cbData), false /*fIsDir*/,
-                                   &pThis->pVar->Time, pObjInfo, enmAddAttr);
-}
-
-
-/**
- * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
- */
-static DECLCALLBACK(int) rtEfiVarStoreFile_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
-{
-    PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis;
+/**
+ * Reads variable data from the given memory area.
+ *
+ * @returns IPRT status code.
+ * @param   pThis               The EFI variable file instance.
+ * @param   pvData              Pointer to the start of the data.
+ * @param   cbData              Size of the variable data in bytes.
+ * @param   off                 Where to start reading relative from the data start offset.
+ * @param   pSgBuf              Where to store the read data.
+ * @param   pcbRead             Where to return the number of bytes read, optional.
+ */
+static int rtEfiVarStoreFile_ReadMem(PRTEFIVARFILE pThis, const void *pvData, size_t cbData,
+                                     RTFOFF off, PCRTSGBUF pSgBuf, size_t *pcbRead)
+{
+    int rc = VINF_SUCCESS;
+    size_t cbRead = pSgBuf->paSegs[0].cbSeg;
+    size_t cbThisRead = RT_MIN(cbData - off, cbRead);
+    const uint8_t *pbData = (const uint8_t *)pvData;
+    if (!pcbRead)
+    {
+        if (cbThisRead == cbRead)
+            memcpy(pSgBuf->paSegs[0].pvSeg, &pbData[off], cbThisRead);
+        else
+            rc = VERR_EOF;
+
+        if (RT_SUCCESS(rc))
+            pThis->offFile = off + cbThisRead;
+        Log6(("rtFsEfiVarStore_Read: off=%#RX64 cbSeg=%#x -> %Rrc\n", off, pSgBuf->paSegs[0].cbSeg, rc));
+    }
+    else
+    {
+        if ((uint64_t)off >= cbData)
+        {
+            *pcbRead = 0;
+            rc = VINF_EOF;
+        }
+        else
+        {
+            memcpy(pSgBuf->paSegs[0].pvSeg, &pbData[off], cbThisRead);
+            /* Return VINF_EOF if beyond end-of-file. */
+            if (cbThisRead < cbRead)
+                rc = VINF_EOF;
+            pThis->offFile = off + cbThisRead;
+            *pcbRead = cbThisRead;
+        }
+        Log6(("rtEfiVarStoreFile_ReadMem: off=%#RX64 cbSeg=%#x -> %Rrc *pcbRead=%#x\n", off, pSgBuf->paSegs[0].cbSeg, rc, *pcbRead));
+    }
+
+    return rc;
+}
+
+
+/**
+ * Reads variable data from the given range.
+ *
+ * @returns IPRT status code.
+ * @param   pThis               The EFI variable file instance.
+ * @param   offData             Where the data starts in the backing storage.
+ * @param   cbData              Size of the variable data in bytes.
+ * @param   off                 Where to start reading relative from the data start offset.
+ * @param   pSgBuf              Where to store the read data.
+ * @param   pcbRead             Where to return the number of bytes read, optional.
+ */
+static int rtEfiVarStoreFile_ReadFile(PRTEFIVARFILE pThis, uint64_t offData, size_t cbData,
+                                      RTFOFF off, PCRTSGBUF pSgBuf, size_t *pcbRead)
+{
+    int rc;
     PRTEFIVARSTORE pVarStore = pThis->pVarStore;
-    AssertReturn(pSgBuf->cSegs == 1, VERR_INTERNAL_ERROR_3);
-    RT_NOREF(fBlocking);
-
-    if (off == -1)
-        off = pThis->offFile;
-    else
-        AssertReturn(off >= 0, VERR_INTERNAL_ERROR_3);
-
-    int rc;
     size_t cbRead = pSgBuf->paSegs[0].cbSeg;
-    size_t cbData = RT_LE2H_U32(pThis->pVar->VarHdr.cbData);
     size_t cbThisRead = RT_MIN(cbData - off, cbRead);
-    uint64_t offStart = pThis->pVar->offVarData + off;
+    uint64_t offStart = offData + off;
     if (!pcbRead)
     {
@@ -519,4 +616,176 @@
 
 /**
+ * Flush the variable store to the backing storage. This will remove any
+ * deleted variables in the backing storage.
+ *
+ * @returns IPRT status code.
+ * @param   pThis               The EFI variable store instance.
+ */
+static int rtEfiVarStore_Flush(PRTEFIVARSTORE pThis)
+{
+    int rc = VINF_SUCCESS;
+    uint64_t offCur = pThis->offStoreData;
+    void *pvData = NULL;
+    size_t cbData = 0;
+    size_t cbDataMax = 0;
+
+    for (uint32_t i = 0; i < pThis->cVars && RT_SUCCESS(rc); i++)
+    {
+        PRTUTF16 pwszName = NULL;
+        size_t cwcLen = 0;
+        PRTEFIVAR pVar = &pThis->paVars[i];
+
+        rc = RTStrToUtf16Ex(pVar->pszName, RTSTR_MAX, &pwszName, 0, &cwcLen);
+        if (RT_SUCCESS(rc))
+        {
+            cwcLen++; /* Include the terminator. */
+
+            /* Read in the data of the variable if it exists. */
+            if (pVar->offVarData)
+            {
+                if (cbDataMax < pVar->cbData)
+                {
+                    size_t cbDataMaxNew = pVar->cbData;
+                    void *pvDataNew = RTMemRealloc(pvData, cbDataMaxNew);
+                    if (pvDataNew)
+                    {
+                        pvData = pvDataNew;
+                        cbDataMax = cbDataMaxNew;
+                    }
+                    else
+                        rc = VERR_NO_MEMORY;
+                }
+
+                cbData = pVar->cbData;
+
+                if (RT_SUCCESS(rc))
+                    rc = RTVfsFileReadAt(pThis->hVfsBacking, pVar->offVarData, pvData, cbData, NULL);
+            }
+
+            /* Write out the variable. */
+            if (RT_SUCCESS(rc))
+            {
+                EFI_AUTH_VAR_HEADER VarHdr;
+                size_t cbName = cwcLen * sizeof(RTUTF16);
+
+                VarHdr.u16StartId = RT_H2LE_U16(EFI_AUTH_VAR_HEADER_START);
+                VarHdr.bState     = EFI_AUTH_VAR_HEADER_STATE_ADDED;
+                VarHdr.bRsvd      = 0;
+                VarHdr.fAttr      = RT_H2LE_U32(pVar->fAttr);
+                VarHdr.cMonotonic = RT_H2LE_U64(pVar->cMonotonic);
+                VarHdr.idPubKey   = RT_H2LE_U32(pVar->idPubKey);
+                VarHdr.cbName     = RT_H2LE_U32(cbName);
+                VarHdr.cbData     = RT_H2LE_U32(pVar->cbData);
+                RTEfiGuidFromUuid(&VarHdr.GuidVendor, &pVar->Uuid);
+                memcpy(&VarHdr.Timestamp, &pVar->EfiTimestamp, sizeof(pVar->EfiTimestamp));
+
+                rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur, &VarHdr, sizeof(VarHdr), NULL);
+                if (RT_SUCCESS(rc))
+                    rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr), pwszName, cbName, NULL);
+                if (RT_SUCCESS(rc))
+                    rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur + sizeof(VarHdr) + cbName, pvData, cbData, NULL);
+                if (RT_SUCCESS(rc))
+                {
+                    offCur += sizeof(VarHdr) + cbName + cbData;
+                    uint64_t offCurAligned = RT_ALIGN_64(offCur, sizeof(uint16_t));
+                    if (offCurAligned > offCur)
+                    {
+                        /* Should be at most 1 byte to align the next variable to a 16bit boundary. */
+                        Assert(offCurAligned - offCur == 1);
+                        uint8_t bFill = 0xff;
+                        rc = RTVfsFileWriteAt(pThis->hVfsBacking, offCur, &bFill, sizeof(bFill), NULL);
+                    }
+
+                    offCur = offCurAligned;
+                }
+            }
+
+            RTUtf16Free(pwszName);
+        }
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        /* Fill the remainder with 0xff as it would be the case for a real NAND flash device. */
+        uint8_t abFF[512];
+        memset(&abFF[0], 0xff, sizeof(abFF));
+
+        uint64_t offStart = offCur;
+        uint64_t offEnd   = pThis->offStoreData + pThis->cbVarStore;
+        while (   offStart < offEnd
+               && RT_SUCCESS(rc))
+        {
+            size_t cbThisWrite = RT_MIN(sizeof(abFF), offEnd - offStart);
+            rc = RTVfsFileWriteAt(pThis->hVfsBacking, offStart, &abFF[0], cbThisWrite, NULL);
+            offStart += cbThisWrite;
+        }
+    }
+
+    if (pvData)
+        RTMemFree(pvData);
+
+    return rc;
+}
+
+
+/*
+ *
+ * File operations.
+ * File operations.
+ * File operations.
+ *
+ */
+
+/**
+ * @interface_method_impl{RTVFSOBJOPS,pfnClose}
+ */
+static DECLCALLBACK(int) rtEfiVarStoreFile_Close(void *pvThis)
+{
+    PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis;
+    LogFlow(("rtEfiVarStoreFile_Close(%p/%p)\n", pThis, pThis->pVar));
+    RT_NOREF(pThis);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
+ */
+static DECLCALLBACK(int) rtEfiVarStoreFile_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
+{
+    PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis;
+    uint64_t cbObject =   pThis->pEntry->cbObject > 0
+                        ? pThis->pEntry->cbObject
+                        : pThis->pVar->cbData;
+    return rtEfiVarStore_QueryInfo(cbObject, false /*fIsDir*/, &pThis->pVar->Time, pObjInfo, enmAddAttr);
+}
+
+
+/**
+ * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
+ */
+static DECLCALLBACK(int) rtEfiVarStoreFile_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
+{
+    PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis;
+    PRTEFIVAR pVar = pThis->pVar;
+    AssertReturn(pSgBuf->cSegs == 1, VERR_INTERNAL_ERROR_3);
+    RT_NOREF(fBlocking);
+
+    if (off == -1)
+        off = pThis->offFile;
+    else
+        AssertReturn(off >= 0, VERR_INTERNAL_ERROR_3);
+
+    int rc;
+    if (pThis->pEntry->cbObject)
+        rc = rtEfiVarStoreFile_ReadMem(pThis, (const uint8_t *)pVar + pThis->pEntry->offObject, pThis->pEntry->cbObject, off, pSgBuf, pcbRead);
+    else
+        rc = rtEfiVarStoreFile_ReadFile(pThis, pVar->offVarData, pVar->cbData, off, pSgBuf, pcbRead);
+
+    return rc;
+}
+
+
+/**
  * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
  */
@@ -593,5 +862,5 @@
             break;
         case RTFILE_SEEK_END:
-            offNew = RT_LE2H_U32(pThis->pVar->VarHdr.cbData) + offSeek;
+            offNew = pThis->pVar->cbData + offSeek;
             break;
         case RTFILE_SEEK_CURRENT:
@@ -617,5 +886,8 @@
 {
     PRTEFIVARFILE pThis = (PRTEFIVARFILE)pvThis;
-    *pcbFile = (uint64_t)RT_LE2H_U32(pThis->pVar->VarHdr.cbData);
+    if (pThis->pEntry->cbObject)
+        *pcbFile = pThis->pEntry->cbObject;
+    else
+        *pcbFile = (uint64_t)pThis->pVar->cbData;
     return VINF_SUCCESS;
 }
@@ -692,10 +964,11 @@
  * @param   pThis               The ext volume instance.
  * @param   fOpen               Open flags passed.
- * @param   iInode              The inode for the file.
+ * @param   pVar                The variable this file accesses.
+ * @param   pEntry              File type entry.
  * @param   phVfsFile           Where to store the VFS file handle on success.
  * @param   pErrInfo            Where to record additional error information on error, optional.
  */
 static int rtEfiVarStore_NewFile(PRTEFIVARSTORE pThis, uint64_t fOpen, PRTEFIVAR pVar,
-                                 PRTVFSOBJ phVfsObj)
+                                 PCRTEFIVARSTOREFILERAWENTRY pEntry, PRTVFSOBJ phVfsObj)
 {
     RTVFSFILE hVfsFile;
@@ -705,4 +978,5 @@
     if (RT_SUCCESS(rc))
     {
+        pNewFile->pEntry    = pEntry;
         pNewFile->pVarStore = pThis;
         pNewFile->pVar      = pVar;
@@ -807,8 +1081,11 @@
             if (   pThis->enmType == RTEFIVARSTOREDIRTYPE_BY_NAME
                 || pThis->enmType == RTEFIVARSTOREDIRTYPE_BY_GUID
+                || pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW
                 || pThis->enmType == RTEFIVARSTOREDIRTYPE_ROOT)
                 enmDirTypeNew = RTEFIVARSTOREDIRTYPE_ROOT;
             else if (pThis->enmType == RTEFIVARSTOREDIRTYPE_GUID)
                 enmDirTypeNew = RTEFIVARSTOREDIRTYPE_BY_GUID;
+            else if (pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW_ENTRY)
+                enmDirTypeNew = RTEFIVARSTOREDIRTYPE_RAW;
             else
                 AssertMsgFailedReturn(("Invalid directory type %d\n", pThis->enmType), VERR_ACCESS_DENIED);
@@ -821,5 +1098,5 @@
                 if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
                     || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE)
-                    rc = rtEfiVarStore_NewDirByType(pVarStore, enmDirTypeNew, NULL /*pGuid*/, phVfsObj);
+                    rc = rtEfiVarStore_NewDirByType(pVarStore, enmDirTypeNew, NULL /*pGuid*/, 0 /*idVar*/, phVfsObj);
                 else
                     rc = VERR_ACCESS_DENIED;
@@ -845,7 +1122,12 @@
         {
             if (!strcmp(pszEntry, "by-name"))
-                return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_BY_NAME, NULL /*pGuid*/, phVfsObj);
+                return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_BY_NAME,
+                                                  NULL /*pGuid*/, 0 /*idVar*/, phVfsObj);
             else if (!strcmp(pszEntry, "by-uuid"))
-                return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_BY_GUID, NULL /*pGuid*/, phVfsObj);
+                return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_BY_GUID,
+                                                  NULL /*pGuid*/, 0 /*idVar*/, phVfsObj);
+            else if (!strcmp(pszEntry, "raw"))
+                return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_RAW,
+                                                  NULL /*pGuid*/, 0 /*idVar*/, phVfsObj);
             else
                 rc = VERR_FILE_NOT_FOUND;
@@ -854,9 +1136,17 @@
         case RTEFIVARSTOREDIRTYPE_GUID: /** @todo This looks through all variables, not only the ones with the GUID. */
         case RTEFIVARSTOREDIRTYPE_BY_NAME:
+        case RTEFIVARSTOREDIRTYPE_RAW:
         {
             /* Look for the name. */
             for (uint32_t i = 0; i < pVarStore->cVars; i++)
                 if (!strcmp(pszEntry, pVarStore->paVars[i].pszName))
-                    return rtEfiVarStore_NewFile(pVarStore, fOpen, &pVarStore->paVars[i], phVfsObj);
+                {
+                    if (pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW)
+                        return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_RAW_ENTRY,
+                                                          NULL /*pGuid*/, i /*idVar*/, phVfsObj);
+                    else
+                        return rtEfiVarStore_NewFile(pVarStore, fOpen, &pVarStore->paVars[i],
+                                                     &g_aRawFiles[RTEFIVARSTORE_FILE_ENTRY_DATA], phVfsObj);
+                }
 
             rc = VERR_FILE_NOT_FOUND;
@@ -874,6 +1164,18 @@
 
                 if (!strcmp(pszEntry, szUuid))
-                    return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_GUID, pGuid, phVfsObj);
+                    return rtEfiVarStore_NewDirByType(pVarStore, RTEFIVARSTOREDIRTYPE_GUID,
+                                                      pGuid, 0 /*idVar*/, phVfsObj);
             }
+
+            rc = VERR_FILE_NOT_FOUND;
+            break;
+        }
+        case RTEFIVARSTOREDIRTYPE_RAW_ENTRY:
+        {
+            /* Look for the name. */
+            for (uint32_t i = 0; i < RT_ELEMENTS(g_aRawFiles); i++)
+                if (!strcmp(pszEntry, g_aRawFiles[i].pszName))
+                    return rtEfiVarStore_NewFile(pVarStore, fOpen, &pVarStore->paVars[pThis->idVar],
+                                                 &g_aRawFiles[i], phVfsObj);
 
             rc = VERR_FILE_NOT_FOUND;
@@ -895,7 +1197,31 @@
 static DECLCALLBACK(int) rtEfiVarStoreDir_CreateDir(void *pvThis, const char *pszSubDir, RTFMODE fMode, PRTVFSDIR phVfsDir)
 {
-    RT_NOREF(pvThis, pszSubDir, fMode, phVfsDir);
+    PRTEFIVARSTOREDIR pThis     = (PRTEFIVARSTOREDIR)pvThis;
+    PRTEFIVARSTORE    pVarStore = pThis->pVarStore;
     LogFlowFunc(("\n"));
-    return VERR_WRITE_PROTECT;
+
+    RT_NOREF(pszSubDir, fMode, phVfsDir);
+
+    if (pVarStore->fMntFlags & RTVFSMNT_F_READ_ONLY)
+        return VERR_WRITE_PROTECT;
+
+    /* We support creating directories only for GUIDs. */
+    if (pThis->enmType != RTEFIVARSTOREDIRTYPE_BY_GUID)
+        return VERR_NOT_SUPPORTED;
+
+    RTUUID Uuid;
+    int rc = RTUuidFromStr(&Uuid, pszSubDir);
+    if (RT_FAILURE(rc))
+        return VERR_NOT_SUPPORTED;
+
+    PRTEFIGUID pGuid = rtEfiVarStore_GetGuid(pVarStore, &Uuid);
+    if (pGuid)
+        return VERR_ALREADY_EXISTS;
+
+    pGuid = rtEfiVarStore_AddGuid(pVarStore, &Uuid);
+    if (!pGuid)
+        return VERR_NO_MEMORY;
+
+    return VINF_SUCCESS;
 }
 
@@ -1000,4 +1326,11 @@
                 cbObject = 1;
                 fIsDir   = true;
+            }
+            else if (pThis->idxNext == 2)
+            {
+                pszName  = "raw";
+                cbName   = sizeof("raw");
+                cbObject = 1;
+                fIsDir   = true;
                 fNoMoreFiles = true;
             }
@@ -1005,4 +1338,5 @@
         }
         case RTEFIVARSTOREDIRTYPE_BY_NAME:
+        case RTEFIVARSTOREDIRTYPE_RAW:
         {
             PRTEFIVAR pVar = &pVarStore->paVars[pThis->idxNext];
@@ -1011,6 +1345,8 @@
             pszName  = pVar->pszName;
             cbName   = strlen(pszName) + 1;
-            cbObject = RT_LE2H_U32(pVar->VarHdr.cbData);
+            cbObject = pVar->cbData;
             pTimeSpec = &pVar->Time;
+            if (pThis->enmType == RTEFIVARSTOREDIRTYPE_RAW)
+                fIsDir = true;
             break;
         }
@@ -1036,5 +1372,20 @@
             pszName  = pVar->pszName;
             cbName   = strlen(pszName) + 1;
-            cbObject = RT_LE2H_U32(pVar->VarHdr.cbData);
+            cbObject = pVar->cbData;
+            pTimeSpec = &pVar->Time;
+            break;
+        }
+        case RTEFIVARSTOREDIRTYPE_RAW_ENTRY:
+        {
+            PCRTEFIVARSTOREFILERAWENTRY pEntry = &g_aRawFiles[pThis->idxNext];
+            PRTEFIVAR                   pVar   = &pVarStore->paVars[pThis->idVar];
+
+            if (pThis->idxNext + 1 == RT_ELEMENTS(g_aRawFiles))
+                fNoMoreFiles = true;
+            pszName  = pEntry->pszName;
+            cbName   = strlen(pszName) + 1;
+            cbObject = pEntry->cbObject;
+            if (!cbObject)
+                cbObject = pVar->cbData;
             pTimeSpec = &pVar->Time;
             break;
@@ -1111,5 +1462,6 @@
 
 
-static int rtEfiVarStore_NewDirByType(PRTEFIVARSTORE pThis, RTEFIVARSTOREDIRTYPE enmDirType, PRTEFIGUID pGuid, PRTVFSOBJ phVfsObj)
+static int rtEfiVarStore_NewDirByType(PRTEFIVARSTORE pThis, RTEFIVARSTOREDIRTYPE enmDirType,
+                                      PRTEFIGUID pGuid, uint32_t idVar, PRTVFSOBJ phVfsObj)
 {
     RTVFSDIR hVfsDir;
@@ -1123,4 +1475,5 @@
         pDir->pVarStore = pThis;
         pDir->pGuid     = pGuid;
+        pDir->idVar     = idVar;
         RTTimeNow(&pDir->Time);
 
@@ -1148,4 +1501,12 @@
 {
     PRTEFIVARSTORE pThis = (PRTEFIVARSTORE)pvThis;
+
+    /* Write the variable store if in read/write mode. */
+    if (!(pThis->fMntFlags & RTVFSMNT_F_READ_ONLY))
+    {
+        int rc = rtEfiVarStore_Flush(pThis);
+        if (RT_FAILURE(rc))
+            return rc;
+    }
 
     /*
@@ -1429,5 +1790,10 @@
     pVar->offVarHdr  = offVar;
     pVar->offVarData = offVar + sizeof(VarHdr) + RT_LE2H_U32(VarHdr.cbName);
-    memcpy(&pVar->VarHdr, &VarHdr, sizeof(VarHdr));
+    pVar->fAttr      = RT_LE2H_U32(VarHdr.fAttr);
+    pVar->cMonotonic = RT_LE2H_U64(VarHdr.cMonotonic);
+    pVar->idPubKey   = RT_LE2H_U32(VarHdr.idPubKey);
+    pVar->cbData     = RT_LE2H_U32(VarHdr.cbData);
+    memcpy(&pVar->EfiTimestamp, &VarHdr.Timestamp, sizeof(VarHdr.Timestamp));
+
     if (VarHdr.Timestamp.u8Month)
         RTEfiTimeToTimeSpec(&pVar->Time, &VarHdr.Timestamp);
@@ -1666,4 +2032,5 @@
             size_t cbThisWrite = RT_MIN(sizeof(abFF), offEnd - offStart);
             rc = RTVfsFileWriteAt(hVfsFile, offStart, &abFF[0], cbThisWrite, NULL);
+            offStart += cbThisWrite;
         }
     }
