diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp
index ec7969c..0e7123b 100644
--- a/UEFIExtract/uefiextract_main.cpp
+++ b/UEFIExtract/uefiextract_main.cpp
@@ -1,6 +1,6 @@
 /* uefiextract_main.cpp
 
-Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
+Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -52,7 +52,7 @@ int main(int argc, char *argv[])
     
   }
   else {
-    std::cout << "UEFIExtract 0.4.1" << std::endl << std::endl <<
+    std::cout << "UEFIExtract 0.4.2" << std::endl << std::endl <<
     "Usage: uefiextract imagefile [FileGUID_1 FileGUID_2 ... FileGUID_31]" << std::endl <<
     "Returned value is a bit mask where 0 on position N meant File with GUID_N was found and unpacked, 1 otherwise" << std::endl;
     return 1;
diff --git a/UEFIFind/uefifind.cpp b/UEFIFind/uefifind.cpp
index 2a5d71b..2adfafb 100644
--- a/UEFIFind/uefifind.cpp
+++ b/UEFIFind/uefifind.cpp
@@ -53,10 +53,28 @@ UINT8 UEFIFind::init(const QString & path)
     return ERR_SUCCESS;
 }
 
+QString UEFIFind::guidToQString(const UINT8* guid)
+{
+    const UINT32 u32 = *(const UINT32*)guid;
+    const UINT16 u16_1 = *(const UINT16*)(guid + 4);
+    const UINT16 u16_2 = *(const UINT16*)(guid + 6);
+    const UINT8  u8_1 = *(const UINT8*)(guid + 8);
+    const UINT8  u8_2 = *(const UINT8*)(guid + 9);
+    const UINT8  u8_3 = *(const UINT8*)(guid + 10);
+    const UINT8  u8_4 = *(const UINT8*)(guid + 11);
+    const UINT8  u8_5 = *(const UINT8*)(guid + 12);
+    const UINT8  u8_6 = *(const UINT8*)(guid + 13);
+    const UINT8  u8_7 = *(const UINT8*)(guid + 14);
+    const UINT8  u8_8 = *(const UINT8*)(guid + 15);
+
+    return QString("%1-%2-%3-%4%5-%6%7%8%9%10%11").hexarg2(u32, 8).hexarg2(u16_1, 4).hexarg2(u16_2, 4).hexarg2(u8_1, 2).hexarg2(u8_2, 2)
+        .hexarg2(u8_3, 2).hexarg2(u8_4, 2).hexarg2(u8_5, 2).hexarg2(u8_6, 2).hexarg2(u8_7, 2).hexarg2(u8_8, 2);
+}
+
 UINT8 UEFIFind::find(const UINT8 mode, const bool count, const QString & hexPattern, QString & result)
 {
     QModelIndex root = model->index(0, 0);
-    QSet<QModelIndex> files;
+    QSet<QPair<QModelIndex, QModelIndex> > files;
 
     result.clear();
 
@@ -70,31 +88,24 @@ UINT8 UEFIFind::find(const UINT8 mode, const bool count, const QString & hexPatt
         return ERR_SUCCESS;
     }
 
-    QModelIndex index;
-    Q_FOREACH(index, files) {
-        QByteArray data = model->header(index).left(16);
+    QPair<QModelIndex, QModelIndex> indexes;
+    Q_FOREACH(indexes, files) {
+        QByteArray data = model->header(indexes.first).left(16);
+        result.append(guidToQString((const UINT8*)data.constData()));
 
-        UINT32 u32   = *(UINT32*)data.constData();
-        UINT16 u16_1 = *(UINT16*)(data.constData() + 4);
-        UINT16 u16_2 = *(UINT16*)(data.constData() + 6);
-        UINT8  u8_1  = *(UINT8*)(data.constData()  + 8);
-        UINT8  u8_2  = *(UINT8*)(data.constData()  + 9);
-        UINT8  u8_3  = *(UINT8*)(data.constData()  + 10);
-        UINT8  u8_4  = *(UINT8*)(data.constData()  + 11);
-        UINT8  u8_5  = *(UINT8*)(data.constData()  + 12);
-        UINT8  u8_6  = *(UINT8*)(data.constData()  + 13);
-        UINT8  u8_7  = *(UINT8*)(data.constData()  + 14);
-        UINT8  u8_8  = *(UINT8*)(data.constData()  + 15);
+        // Special case of freeform subtype GUID files
+        if (indexes.second.isValid() && model->subtype(indexes.second) == EFI_SECTION_FREEFORM_SUBTYPE_GUID) {
+            data = model->header(indexes.second).left(sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION));
+            result.append(" ").append(guidToQString((const UINT8*)data.constData() + sizeof(EFI_COMMON_SECTION_HEADER)));
+        }
+        
+        result.append("\n");
 
-        QString guid = QString("%1-%2-%3-%4%5-%6%7%8%9%10%11\n").hexarg2(u32, 8).hexarg2(u16_1, 4).hexarg2(u16_2, 4).hexarg2(u8_1, 2).hexarg2(u8_2, 2)
-            .hexarg2(u8_3, 2).hexarg2(u8_4, 2).hexarg2(u8_5, 2).hexarg2(u8_6, 2).hexarg2(u8_7, 2).hexarg2(u8_8, 2);
-
-        result.append(guid);
     }
     return ERR_SUCCESS;
 }
 
-UINT8 UEFIFind::findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, QSet<QModelIndex> & files)
+UINT8 UEFIFind::findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, QSet<QPair<QModelIndex, QModelIndex> > & files)
 {
     if (!index.isValid())
         return ERR_SUCCESS;
@@ -132,10 +143,13 @@ UINT8 UEFIFind::findFileRecursive(const QModelIndex index, const QString & hexPa
         if (offset % 2 == 0) {
             if (model->type(index) != Types::File) {
                 QModelIndex ffs = model->findParentOfType(index, Types::File);
-                files.insert(ffs);
+                if (model->type(index) == Types::Section && model->subtype(index) == EFI_SECTION_FREEFORM_SUBTYPE_GUID)
+                    files.insert(QPair<QModelIndex, QModelIndex>(ffs, index));
+                else
+                    files.insert(QPair<QModelIndex, QModelIndex>(ffs, QModelIndex()));
             }
             else
-                files.insert(index);
+                files.insert(QPair<QModelIndex, QModelIndex>(index, QModelIndex()));
 
             break;
         }
diff --git a/UEFIFind/uefifind.h b/UEFIFind/uefifind.h
index 374b56d..4137f9b 100644
--- a/UEFIFind/uefifind.h
+++ b/UEFIFind/uefifind.h
@@ -19,12 +19,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <QString>
 #include <QDir>
 #include <QFileInfo>
+#include <QPair>
 #include <QSet>
 #include <QString>
 #include <QUuid>
 
 #include "../basetypes.h"
 #include "../ffsengine.h"
+#include "../ffs.h"
 
 class UEFIFind : public QObject
 {
@@ -38,7 +40,8 @@ public:
     UINT8 find(const UINT8 mode, const bool count, const QString & hexPattern, QString & result);
 
 private:
-    UINT8 findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, QSet<QModelIndex> & files);
+    UINT8 findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, QSet<QPair<QModelIndex, QModelIndex> > & files);
+    QString UEFIFind::guidToQString(const UINT8* guid);
 
     FfsEngine* ffsEngine;
     TreeModel* model;
diff --git a/UEFIFind/uefifind_main.cpp b/UEFIFind/uefifind_main.cpp
index 01b2fa6..bcd5c2e 100644
--- a/UEFIFind/uefifind_main.cpp
+++ b/UEFIFind/uefifind_main.cpp
@@ -1,6 +1,6 @@
 /* uefifind_main.cpp
 
-Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
+Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -64,7 +64,7 @@ int main(int argc, char *argv[])
         return ERR_SUCCESS;
     }
     else {
-        std::cout << "UEFIFind 0.2.0" << std::endl << std::endl <<
+        std::cout << "UEFIFind 0.3.0" << std::endl << std::endl <<
             "Usage: uefifind {header | body | all} {list | count} pattern imagefile\n";
         return ERR_INVALID_PARAMETER;
     }
diff --git a/UEFIPatch/uefipatch_main.cpp b/UEFIPatch/uefipatch_main.cpp
index 74ad273..8d6e44b 100644
--- a/UEFIPatch/uefipatch_main.cpp
+++ b/UEFIPatch/uefipatch_main.cpp
@@ -1,6 +1,6 @@
 /* uefipatch_main.cpp
 
-Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
+Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -31,7 +31,7 @@ int main(int argc, char *argv[])
         result = w.patchFromFile(a.arguments().at(1));
     }
     else {
-        std::cout << "UEFIPatch 0.3.1 - UEFI image file patching utility" << std::endl << std::endl <<
+        std::cout << "UEFIPatch 0.3.2 - UEFI image file patching utility" << std::endl << std::endl <<
             "Usage: UEFIPatch image_file" << std::endl << std::endl <<
             "Patches will be read from patches.txt file\n";
         return ERR_SUCCESS;
diff --git a/ffs.cpp b/ffs.cpp
index 9b50ea1..fcdf03f 100644
--- a/ffs.cpp
+++ b/ffs.cpp
@@ -23,6 +23,10 @@ const QVector<QByteArray> FFSv2Volumes =
     << EFI_INTEL_FILE_SYSTEM2_GUID
     << EFI_SONY_FILE_SYSTEM_GUID;
 
+const QVector<QByteArray> FFSv3Volumes =
+    QVector<QByteArray>()
+    << EFI_FIRMWARE_FILE_SYSTEM3_GUID;
+
 const UINT8 ffsAlignmentTable[] =
 { 0, 4, 7, 9, 10, 12, 15, 16 };
 
@@ -140,7 +144,7 @@ QString sectionTypeToQString(const UINT8 type)
     case EFI_SECTION_RAW:                       return QObject::tr("Raw");
     case EFI_SECTION_PEI_DEPEX:                 return QObject::tr("PEI dependency");
     case EFI_SECTION_SMM_DEPEX:                 return QObject::tr("SMM dependency");
-    case HP_SECTION_POSTCODE:                   return QObject::tr("HP postcode");
+    case INSYDE_SECTION_POSTCODE:               return QObject::tr("Insyde postcode");
     case SCT_SECTION_POSTCODE:                  return QObject::tr("SCT postcode");
     default:                                    return QObject::tr("Unknown");
     }
@@ -151,27 +155,47 @@ UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header)
     if (!header)
         return 0;
 
+    bool extended = false;
+    /*if (uint24ToUint32(header->Size) == EFI_SECTION2_IS_USED) {
+        extended = true;
+    }*/
+
     switch (header->Type)
     {
     case EFI_SECTION_GUID_DEFINED: {
-        const EFI_GUID_DEFINED_SECTION* gdsHeader = (const EFI_GUID_DEFINED_SECTION*)header;
-        return gdsHeader->DataOffset; }
-    case EFI_SECTION_COMPRESSION:           return sizeof(EFI_COMPRESSION_SECTION);
-    case EFI_SECTION_DISPOSABLE:            return sizeof(EFI_DISPOSABLE_SECTION);
-    case EFI_SECTION_PE32:                  return sizeof(EFI_PE32_SECTION);
-    case EFI_SECTION_PIC:                   return sizeof(EFI_PIC_SECTION);
-    case EFI_SECTION_TE:                    return sizeof(EFI_TE_SECTION);
-    case EFI_SECTION_DXE_DEPEX:             return sizeof(EFI_DXE_DEPEX_SECTION);
-    case EFI_SECTION_VERSION:               return sizeof(EFI_VERSION_SECTION);
-    case EFI_SECTION_USER_INTERFACE:        return sizeof(EFI_USER_INTERFACE_SECTION);
-    case EFI_SECTION_COMPATIBILITY16:       return sizeof(EFI_COMPATIBILITY16_SECTION);
-    case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION);
-    case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
-    case EFI_SECTION_RAW:                   return sizeof(EFI_RAW_SECTION);
-    case EFI_SECTION_PEI_DEPEX:             return sizeof(EFI_PEI_DEPEX_SECTION);
-    case EFI_SECTION_SMM_DEPEX:             return sizeof(EFI_SMM_DEPEX_SECTION);
-    case HP_SECTION_POSTCODE:               return sizeof(POSTCODE_SECTION);
-    case SCT_SECTION_POSTCODE:              return sizeof(POSTCODE_SECTION);
-    default:                                return sizeof(EFI_COMMON_SECTION_HEADER);
+        if (!extended) {
+            const EFI_GUID_DEFINED_SECTION* gdsHeader = (const EFI_GUID_DEFINED_SECTION*)header;
+            if (QByteArray((const char*)&gdsHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
+                const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)(gdsHeader + 1);
+                return gdsHeader->DataOffset + certificateHeader->Length;
+            }
+            return gdsHeader->DataOffset;
+        }
+        else {
+            const EFI_GUID_DEFINED_SECTION2* gdsHeader = (const EFI_GUID_DEFINED_SECTION2*)header;
+            if (QByteArray((const char*)&gdsHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
+                const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)(gdsHeader + 1);
+                return gdsHeader->DataOffset + certificateHeader->Length;
+            }
+            return gdsHeader->DataOffset;
+        }
+    }
+    case EFI_SECTION_COMPRESSION:           return extended ? sizeof(EFI_COMPRESSION_SECTION2) : sizeof(EFI_COMPRESSION_SECTION);
+    case EFI_SECTION_DISPOSABLE:            return extended ? sizeof(EFI_DISPOSABLE_SECTION2) : sizeof(EFI_DISPOSABLE_SECTION);
+    case EFI_SECTION_PE32:                  return extended ? sizeof(EFI_PE32_SECTION2) : sizeof(EFI_PE32_SECTION);
+    case EFI_SECTION_PIC:                   return extended ? sizeof(EFI_PIC_SECTION2) : sizeof(EFI_PIC_SECTION);
+    case EFI_SECTION_TE:                    return extended ? sizeof(EFI_TE_SECTION2) : sizeof(EFI_TE_SECTION);
+    case EFI_SECTION_DXE_DEPEX:             return extended ? sizeof(EFI_DXE_DEPEX_SECTION2) : sizeof(EFI_DXE_DEPEX_SECTION);
+    case EFI_SECTION_VERSION:               return extended ? sizeof(EFI_VERSION_SECTION2) : sizeof(EFI_VERSION_SECTION);
+    case EFI_SECTION_USER_INTERFACE:        return extended ? sizeof(EFI_USER_INTERFACE_SECTION2) : sizeof(EFI_USER_INTERFACE_SECTION);
+    case EFI_SECTION_COMPATIBILITY16:       return extended ? sizeof(EFI_COMPATIBILITY16_SECTION2) : sizeof(EFI_COMPATIBILITY16_SECTION);
+    case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return extended ? sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION2) : sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION);
+    case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return extended ? sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION2) : sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
+    case EFI_SECTION_RAW:                   return extended ? sizeof(EFI_RAW_SECTION2) : sizeof(EFI_RAW_SECTION);
+    case EFI_SECTION_PEI_DEPEX:             return extended ? sizeof(EFI_PEI_DEPEX_SECTION2) : sizeof(EFI_PEI_DEPEX_SECTION);
+    case EFI_SECTION_SMM_DEPEX:             return extended ? sizeof(EFI_SMM_DEPEX_SECTION2) : sizeof(EFI_SMM_DEPEX_SECTION);
+    case INSYDE_SECTION_POSTCODE:           return extended ? sizeof(POSTCODE_SECTION2) : sizeof(POSTCODE_SECTION);
+    case SCT_SECTION_POSTCODE:              return extended ? sizeof(POSTCODE_SECTION2) : sizeof(POSTCODE_SECTION);
+    default:                                return extended ? sizeof(EFI_COMMON_SECTION_HEADER2) : sizeof(EFI_COMMON_SECTION_HEADER);
     }
 }
diff --git a/ffs.h b/ffs.h
index 8287e3d..8b7da95 100644
--- a/ffs.h
+++ b/ffs.h
@@ -108,18 +108,23 @@ const QByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID
 ("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16);
 const QByteArray EFI_INTEL_FILE_SYSTEM_GUID
 ("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16);
-//AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 //Intel 1
+// AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 // Intel 1
 const QByteArray EFI_INTEL_FILE_SYSTEM2_GUID
 ("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16);
-//D6A1CD70-4B33-4994-A6EA-375F2CCC5437 //Intel 2
+// D6A1CD70-4B33-4994-A6EA-375F2CCC5437 // Intel 2
 const QByteArray EFI_SONY_FILE_SYSTEM_GUID
 ("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16);
-//4F494156-AED6-4D64-A537-B8A5557BCEEC //Sony 1
+// 4F494156-AED6-4D64-A537-B8A5557BCEEC // Sony 1
 
-
-//Vector of volume GUIDs with FFSv2-compatible files
+// Vector of volume GUIDs with FFSv2-compatible files
 extern const QVector<QByteArray> FFSv2Volumes;
 
+const QByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID // 5473C07A-3DCB-4dca-BD6F-1E9689E7349A
+("\x7A\xC0\x73\x54\xCB\x3D\xCA\x4D\xBD\x6F\x1E\x96\x89\xE7\x34\x9A", 16);
+
+// Vector of volume GUIDs with FFSv3-compatible files
+extern const QVector<QByteArray> FFSv3Volumes;
+
 // Firmware volume signature
 const QByteArray EFI_FV_SIGNATURE("_FVH", 4);
 #define EFI_FV_SIGNATURE_OFFSET 0x28
@@ -214,21 +219,21 @@ typedef struct _EFI_FIRMWARE_VOLUME_EXT_HEADER {
 // Extended header entry
 // The extended header entries follow each other and are
 // terminated by ExtHeaderType EFI_FV_EXT_TYPE_END
-#define EFI_FV_EXT_TYPE_END        0x00
+#define EFI_FV_EXT_TYPE_END        0x0000
 typedef struct _EFI_FIRMWARE_VOLUME_EXT_ENTRY {
     UINT16  ExtEntrySize;
     UINT16  ExtEntryType;
 } EFI_FIRMWARE_VOLUME_EXT_ENTRY;
 
 // GUID that maps OEM file types to GUIDs
-#define EFI_FV_EXT_TYPE_OEM_TYPE   0x01
+#define EFI_FV_EXT_TYPE_OEM_TYPE   0x0001
 typedef struct _EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE {
     EFI_FIRMWARE_VOLUME_EXT_ENTRY    Header;
     UINT32                           TypeMask;
     //EFI_GUID                         Types[1];
 } EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE;
 
-#define EFI_FV_EXT_TYPE_GUID_TYPE  0x02
+#define EFI_FV_EXT_TYPE_GUID_TYPE  0x0002
 typedef struct _EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE {
     EFI_FIRMWARE_VOLUME_EXT_ENTRY Header;
     EFI_GUID FormatType;
@@ -269,7 +274,7 @@ EFI_GUID                Name;
 EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
 UINT8                   Type;
 UINT8                   Attributes;
-UINT8                   Size[3];
+UINT8                   Size[3]; // Set to 0xFFFFFF
 UINT8                   State;
 UINT32                  ExtendedSize;
 } EFI_FFS_FILE_HEADER2;
@@ -302,8 +307,9 @@ UINT32                  ExtendedSize;
 #define EFI_FV_FILETYPE_FFS_MAX                 0xFF
 
 // File attributes
-#define FFS_ATTRIB_TAIL_PRESENT       0x01
-#define FFS_ATTRIB_RECOVERY           0x02
+#define FFS_ATTRIB_TAIL_PRESENT       0x01 // Valid only for revision 1 volumes
+#define FFS_ATTRIB_RECOVERY           0x02 // Valid only for revision 1 volumes
+#define FFS_ATTRIB_LARGE_FILE         0x01 // Valid only for FFSv3 volumes
 #define FFS_ATTRIB_FIXED              0x04
 #define FFS_ATTRIB_DATA_ALIGNMENT     0x38
 #define FFS_ATTRIB_CHECKSUM           0x40
@@ -357,6 +363,9 @@ typedef struct _EFI_COMMON_SECTION_HEADER2 {
     UINT32   ExtendedSize;
 } EFI_COMMON_SECTION_HEADER2;
 
+// Section2 usage indicator
+#define EFI_SECTION2_IS_USED 0xFFFFFF
+
 // File section types
 #define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS
 
@@ -379,7 +388,7 @@ typedef struct _EFI_COMMON_SECTION_HEADER2 {
 #define EFI_SECTION_PEI_DEPEX               0x1B
 #define EFI_SECTION_SMM_DEPEX               0x1C
 #define SCT_SECTION_POSTCODE                0xF0 // Specific to Phoenix SCT images
-#define HP_SECTION_POSTCODE                 0x20 // Specific to HP images
+#define INSYDE_SECTION_POSTCODE             0x20 // Specific to Insyde images
 
 // Compression section
 typedef struct _EFI_COMPRESSION_SECTION {
@@ -389,6 +398,14 @@ typedef struct _EFI_COMPRESSION_SECTION {
     UINT8    CompressionType;
 } EFI_COMPRESSION_SECTION;
 
+typedef struct _EFI_COMPRESSION_SECTION2 {
+    UINT8    Size[3];
+    UINT8    Type;
+    UINT32   ExtendedSize;
+    UINT32   UncompressedLength;
+    UINT8    CompressionType;
+} EFI_COMPRESSION_SECTION2;
+
 // Compression types
 #define EFI_NOT_COMPRESSED          0x00
 #define EFI_STANDARD_COMPRESSION    0x01
@@ -403,6 +420,15 @@ typedef struct _EFI_GUID_DEFINED_SECTION {
     UINT16   Attributes;
 } EFI_GUID_DEFINED_SECTION;
 
+typedef struct _EFI_GUID_DEFINED_SECTION2 {
+    UINT8    Size[3];
+    UINT8    Type;
+    UINT32   ExtendedSize;
+    EFI_GUID SectionDefinitionGuid;
+    UINT16   DataOffset;
+    UINT16   Attributes;
+} EFI_GUID_DEFINED_SECTION2;
+
 // Attributes for GUID defined section
 #define EFI_GUIDED_SECTION_PROCESSING_REQUIRED  0x01
 #define EFI_GUIDED_SECTION_AUTH_STATUS_VALID    0x02
@@ -417,7 +443,7 @@ const QByteArray EFI_GUIDED_SECTION_TIANO // A31280AD-481E-41B6-95E8-127F4C98477
 const QByteArray EFI_GUIDED_SECTION_LZMA // EE4E5898-3914-4259-9D6E-DC7BD79403CF
 ("\x98\x58\x4E\xEE\x14\x39\x59\x42\x9D\x6E\xDC\x7B\xD7\x94\x03\xCF", 16);
 
-const QByteArray EFI_GUIDED_SECTION_INTEL_SIGNED //0F9D89E8-9259-4F76-A5AF-0C89E34023DF
+const QByteArray EFI_FIRMWARE_CONTENTS_SIGNED_GUID //0F9D89E8-9259-4F76-A5AF-0C89E34023DF
 ("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16);
 
 // Version section
@@ -427,6 +453,13 @@ typedef struct _EFI_VERSION_SECTION {
     UINT16   BuildNumber;
 } EFI_VERSION_SECTION;
 
+typedef struct _EFI_VERSION_SECTION2 {
+    UINT8    Size[3];
+    UINT8    Type;
+    UINT32   ExtendedSize;
+    UINT16   BuildNumber;
+} EFI_VERSION_SECTION2;
+
 // Freeform subtype GUID section
 typedef struct _EFI_FREEFORM_SUBTYPE_GUID_SECTION {
     UINT8    Size[3];
@@ -434,6 +467,13 @@ typedef struct _EFI_FREEFORM_SUBTYPE_GUID_SECTION {
     EFI_GUID SubTypeGuid;
 } EFI_FREEFORM_SUBTYPE_GUID_SECTION;
 
+typedef struct _EFI_FREEFORM_SUBTYPE_GUID_SECTION2 {
+    UINT8    Size[3];
+    UINT8    Type;
+    UINT32   ExtendedSize;
+    EFI_GUID SubTypeGuid;
+} EFI_FREEFORM_SUBTYPE_GUID_SECTION2;
+
 // Phoenix SCT and HP postcode section
 typedef struct _POSTCODE_SECTION {
     UINT8    Size[3];
@@ -441,18 +481,36 @@ typedef struct _POSTCODE_SECTION {
     UINT32   Postcode;
 } POSTCODE_SECTION;
 
+typedef struct _POSTCODE_SECTION2 {
+    UINT8    Size[3];
+    UINT8    Type;
+    UINT32   ExtendedSize;
+    UINT32   Postcode;
+} POSTCODE_SECTION2;
+
 // Other sections
-typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION;
-typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION;
-typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION;
-typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION;
-typedef EFI_COMMON_SECTION_HEADER EFI_SMM_DEPEX_SECTION;
-typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION;
-typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION;
-typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION;
-typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION;
-typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
-typedef EFI_COMMON_SECTION_HEADER EFI_USER_INTERFACE_SECTION;
+typedef EFI_COMMON_SECTION_HEADER  EFI_DISPOSABLE_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_DISPOSABLE_SECTION2;
+typedef EFI_COMMON_SECTION_HEADER  EFI_RAW_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2;
+typedef EFI_COMMON_SECTION_HEADER  EFI_DXE_DEPEX_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2;
+typedef EFI_COMMON_SECTION_HEADER  EFI_PEI_DEPEX_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2;
+typedef EFI_COMMON_SECTION_HEADER  EFI_SMM_DEPEX_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_SMM_DEPEX_SECTION2;
+typedef EFI_COMMON_SECTION_HEADER  EFI_PE32_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2;
+typedef EFI_COMMON_SECTION_HEADER  EFI_PIC_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2;
+typedef EFI_COMMON_SECTION_HEADER  EFI_TE_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2;
+typedef EFI_COMMON_SECTION_HEADER  EFI_COMPATIBILITY16_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2;
+typedef EFI_COMMON_SECTION_HEADER  EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2;
+typedef EFI_COMMON_SECTION_HEADER  EFI_USER_INTERFACE_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_USER_INTERFACE_SECTION2;
 
 //Section routines
 extern UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header);
@@ -490,6 +548,39 @@ extern UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header);
 ///
 #define EFI_DEP_SOR           0x09
 
+//*****************************************************************************
+// UEFI Crypto-signed Stuff
+//*****************************************************************************
+
+#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
+#define WIN_CERT_TYPE_EFI_GUID         0x0EF1
+
+typedef struct _WIN_CERTIFICATE {
+    UINT32  Length;
+    UINT16  Revision;
+    UINT16  CertificateType;
+    //UINT8 CertData[];
+} WIN_CERTIFICATE;
+
+typedef struct _WIN_CERTIFICATE_UEFI_GUID {
+    WIN_CERTIFICATE   Header;     // Standard WIN_CERTIFICATE
+    EFI_GUID          CertType;   // Determines format of CertData
+    // UINT8          CertData[]; // Certificate data follows
+} WIN_CERTIFICATE_UEFI_GUID;
+
+// WIN_CERTIFICATE_UEFI_GUID.CertType
+const QByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID
+("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF");
+const QByteArray EFI_CERT_TYPE_PKCS7_GUID
+("\x9D\xD2\xAF\x4A\xDF\x68\xEE\x49\x8A\xA9\x34\x7D\x37\x56\x65\xA7");
+
+// WIN_CERTIFICATE_UEFI_GUID.CertData
+typedef struct _EFI_CERT_BLOCK_RSA_2048_SHA256 {
+    UINT32  HashType;
+    UINT8   PublicKey[256];
+    UINT8   Signature[256];
+} EFI_CERT_BLOCK_RSA_2048_SHA256;
+
 // Restore previous packing rules
 #pragma pack(pop)
 
diff --git a/ffsengine.cpp b/ffsengine.cpp
index a2c075b..9eb883c 100644
--- a/ffsengine.cpp
+++ b/ffsengine.cpp
@@ -784,8 +784,12 @@ UINT8  FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co
         volumeFfsVersion = 2;
     }
 
-    //!TODO:Check for FFS v3 volume
-    
+    // Check for FFS v3 volume
+    /*if (FFSv3Volumes.contains(QByteArray::fromRawData((const char*)volumeHeader->FileSystemGuid.Data, sizeof(EFI_GUID)))) {
+        volumeIsUnknown = false;
+        volumeFfsVersion = 3;
+    }*/
+
     // Check attributes
     // Determine value of empty byte
     char empty = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00';
@@ -896,7 +900,7 @@ UINT8  FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co
             // Check free space to be actually free
             QByteArray freeSpace = volume.mid(fileOffset);
             if (freeSpace.count(empty) != freeSpace.count()) {
-                msg(tr("parseVolume: non-standard data found in volume's free space"), index);
+                msg(tr("parseVolume: non-UEFI data found in volume's free space"), index);
 
                 // Search for the first non-empty byte
                 UINT32 i;
@@ -1085,7 +1089,6 @@ UINT8 FfsEngine::parseFile(const QByteArray & file, QModelIndex & index, const U
     // Check for non-empty pad file
     else if (fileHeader->Type == EFI_FV_FILETYPE_PAD) {
         parseAsNonEmptyPadFile = true;
-        msg(tr("parseFile: non-empty pad-file contents will be destroyed after volume modifications"), index);
     }
 
     // Get info
@@ -1139,7 +1142,11 @@ UINT8 FfsEngine::parseFile(const QByteArray & file, QModelIndex & index, const U
         }
         // ... and all bytes after as a padding
         QByteArray padding = body.mid(i);
-        model->addItem(Types::Padding, Subtypes::DataPadding, COMPRESSION_ALGORITHM_NONE, tr("Non-UEFI data"), "", tr("Full size: %1h (%2)").hexarg(padding.size()).arg(padding.size()), QByteArray(), padding, QByteArray(), index, mode);
+        QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, COMPRESSION_ALGORITHM_NONE, tr("Non-UEFI data"), "", tr("Full size: %1h (%2)").hexarg(padding.size()).arg(padding.size()), QByteArray(), padding, QByteArray(), index, mode);
+        
+        // Show message
+        msg(tr("parseFile: non-empty pad-file contents will be destroyed after volume modifications"), dataIndex);
+        
         return ERR_SUCCESS;
     }
 
@@ -1360,6 +1367,9 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
         bool msgUnknownGuid = false;
         bool msgInvalidCrc = false;
         bool msgUnknownAuth = false;
+        bool msgSigned = false;
+        bool msgUnknownSignature = false;
+        bool msgUnknownUefiGuidSignature = false;
 
         const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader;
         header = section.left(sizeof(EFI_GUID_DEFINED_SECTION));
@@ -1368,7 +1378,6 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
         guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)(header.constData());
         body = section.mid(guidDefinedSectionHeader->DataOffset, sectionSize - guidDefinedSectionHeader->DataOffset);
         QByteArray processed = body;
-        QByteArray signature;
 
         // Get info
         name = guidToQString(guidDefinedSectionHeader->SectionDefinitionGuid);
@@ -1418,11 +1427,39 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
                 else
                     info += tr("\nCompression type: unknown");
             }
-            // Intel signed section
-            else if (QByteArray((const char*)&guidDefinedSectionHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_GUIDED_SECTION_INTEL_SIGNED) {
-                UINT32 signatureSize = *(const UINT32*)body.constData();
-                signature = body.left(signatureSize);
-                processed = body.mid(signatureSize);
+            // Signed section
+            else if (QByteArray((const char*)&guidDefinedSectionHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
+                msgSigned = true;
+                const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)body.constData();
+                if (certificateHeader->CertificateType == WIN_CERT_TYPE_EFI_GUID) {
+                    info += tr("\nSignature type: UEFI");
+                    const WIN_CERTIFICATE_UEFI_GUID* guidCertificateHeader = (const WIN_CERTIFICATE_UEFI_GUID*)certificateHeader;
+                    if (QByteArray((const char*)&guidCertificateHeader->CertType, sizeof(EFI_GUID)) == EFI_CERT_TYPE_RSA2048_SHA256_GUID) {
+                        info += tr("\nSignature subtype: RSA2048/SHA256");
+                        // TODO: show signature info in Information panel
+                    }
+                    else if (QByteArray((const char*)&guidCertificateHeader->CertType, sizeof(EFI_GUID)) == EFI_CERT_TYPE_PKCS7_GUID) {
+                        info += tr("\nSignature subtype: PCKS7");
+                        // TODO: show signature info in Information panel
+                    }
+                    else {
+                        info += tr("\nSignature subtype: unknown");
+                        msgUnknownUefiGuidSignature = true;
+                    }
+                }
+                else if (certificateHeader->CertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
+                    info += tr("\nSignature type: PCKS7");
+                    // TODO: show signature info in Information panel
+                }
+                else {
+                    info += tr("\nSignature type: unknown");
+                    msgUnknownSignature = true;
+                }
+
+                // Add additional to the header
+                header.append(body.left(certificateHeader->Length));
+                // Get new body
+                processed = body = body.mid(certificateHeader->Length);
             }
             // Unknown GUIDed section
             else {
@@ -1461,18 +1498,17 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
             msg(tr("parseSection: GUID defined section with unknown authentication method"), index);
         if (msgInvalidCrc)
             msg(tr("parseSection: GUID defined section with invalid CRC32"), index);
+        if (msgSigned)
+            msg(tr("parseSection: signature may become invalid after any modification"), index);
+        if (msgUnknownUefiGuidSignature)
+            msg(tr("parseSection: GUID defined section with unknown signature subtype"), index);
+        if (msgUnknownSignature)
+            msg(tr("parseSection: GUID defined section with unknown signature type"), index);
 
         if (!parseCurrentSection) {
             msg(tr("parseSection: GUID defined section can not be processed"), index);
         }
         else { // Parse processed data
-            if (!signature.isEmpty()) {
-                // Add Intel signature padding to the tree
-                QModelIndex signatureIndex = model->addItem(Types::Padding, Subtypes::DataPadding, COMPRESSION_ALGORITHM_NONE, tr("Intel signature"), "", tr("Full size: %1h (%2)").hexarg(signature.size()).arg(signature.size()), QByteArray(), signature, QByteArray(), index, mode);
-                // Show message
-                msg(tr("parseSection: Intel signature may become invalid after any modification of the following sections"), signatureIndex);
-            }
-            
             result = parseSections(processed, index);
             if (result)
                 return result;
@@ -1824,7 +1860,7 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
     } break;
 
     case SCT_SECTION_POSTCODE:
-    case HP_SECTION_POSTCODE: {
+    case INSYDE_SECTION_POSTCODE: {
         header = section.left(sizeof(POSTCODE_SECTION));
         body = section.mid(sizeof(POSTCODE_SECTION), sectionSize - sizeof(POSTCODE_SECTION));
 
@@ -3358,7 +3394,7 @@ UINT8 FfsEngine::reconstructSection(const QModelIndex& index, const UINT32 base,
                 }
                 // Check for Intel signed section
                 if (guidDefinedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED
-                    && QByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_GUIDED_SECTION_INTEL_SIGNED) {
+                    && QByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
                     msg(tr("reconstructSection: GUID defined section signature can become invalid")
                         .arg(guidToQString(guidDefinedHeader->SectionDefinitionGuid)), index);
                 }
diff --git a/uefitool.cpp b/uefitool.cpp
index bc885c9..67436c9 100644
--- a/uefitool.cpp
+++ b/uefitool.cpp
@@ -17,7 +17,7 @@
 UEFITool::UEFITool(QWidget *parent) :
 QMainWindow(parent),
 ui(new Ui::UEFITool), 
-version(tr("0.20.1"))
+version(tr("0.20.2"))
 {
     clipboard = QApplication::clipboard();
 
@@ -349,7 +349,7 @@ void UEFITool::replace(const UINT8 mode)
     }
     else if (model->type(index) == Types::Section) {
         if (mode == REPLACE_MODE_AS_IS) {
-            path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected object"), currentDir, "Section files (*.sec *.bin);;All files (*)");
+            path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected object"), currentDir, "Section files (*.sct *.bin);;All files (*)");
         }
         else if (mode == REPLACE_MODE_BODY) {
             if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE)