diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..096dd73
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+*.fods eol=lf
+
diff --git a/Documents/ClassOffset.fods b/Documents/ClassOffset.fods
new file mode 100644
index 0000000..ebbb7f4
--- /dev/null
+++ b/Documents/ClassOffset.fods
@@ -0,0 +1,1321 @@
+
+
+
+ Tad William2015-06-05T18:17:202023-02-04T22:19:06.714000000PT45SLibreOffice/7.3.7.2$Windows_X86_64 LibreOffice_project/e114eadc50a9ff8d8c8a0567d6da8f454beeb84f116.0300
+
+
+ 0
+ 0
+ 13026
+ 2434
+
+
+ view1
+
+
+ 4
+ 15
+ 2
+ 0
+ 0
+ 0
+ 0
+ 0
+ 100
+ 60
+ true
+ false
+
+
+ 2
+ 13
+ 2
+ 0
+ 0
+ 0
+ 0
+ 0
+ 100
+ 60
+ true
+ false
+
+
+ 2
+ 19
+ 2
+ 0
+ 0
+ 0
+ 0
+ 0
+ 100
+ 60
+ true
+ false
+
+
+ CKBufferParser
+ 1855
+ 0
+ 100
+ 60
+ false
+ true
+ true
+ true
+ 12632256
+ true
+ true
+ true
+ true
+ false
+ false
+ false
+ 1000
+ 1000
+ 1
+ 1
+ true
+ false
+
+
+
+
+ true
+ true
+ true
+ 0
+ true
+ true
+ false
+ true
+ false
+ 12632256
+ true
+ true
+ false
+ false
+ true
+ true
+ false
+ 3
+ false
+ Microsoft XPS Document Writer
+ false
+ YQX+/01pY3Jvc29mdCBYUFMgRG9jdW1lbnQgV3JpdGVyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATWljcm9zb2Z0IFhQUyBEb2N1bWVudCBXcml0ZXIgdgAWAAEAfgQAAAAAAAAEAAhSAAAEdAAAM1ROVwAAAAAKAE0AaQBjAHIAbwBzAG8AZgB0ACAAWABQAFMAIABEAG8AYwB1AG0AZQBuAHQAIABXAHIAaQB0AGUAcgAAAAAAAAABBAMG3ACYAwOvAAABAAkAmgs0CGQAAQAPAFgCAgABAFgCAwAAAEEANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAIAAAABAAAA/////0dJUzQAAAAAAAAAAAAAAABESU5VIgAgAXwDHADK0vZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAEAAFNNVEoAAAAAEAAQAXsAMABGADQAMQAzADAARABEAC0AMQA5AEMANwAtADcAYQBiADYALQA5ADkAQQAxAC0AOQA4ADAARgAwADMAQgAyAEUARQA0AEUAfQAAAElucHV0QmluAEZPUk1TT1VSQ0UAUkVTRExMAFVuaXJlc0RMTABJbnRlcmxlYXZpbmcAT0ZGAEltYWdlVHlwZQBKUEVHTWVkAE9yaWVudGF0aW9uAFBPUlRSQUlUAENvbGxhdGUAT0ZGAFJlc29sdXRpb24AT3B0aW9uMQBQYXBlclNpemUATEVUVEVSAENvbG9yTW9kZQAyNGJwcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAFY0RE0BAAAAAAAAAAAAAAAAAAAAAAAAABIAQ09NUEFUX0RVUExFWF9NT0RFEwBEdXBsZXhNb2RlOjpVbmtub3du
+ false
+ 1000
+ 1000
+ 1
+ 1
+ true
+ false
+ true
+ true
+ true
+ true
+ 2
+ true
+
+
+ 工作表1
+
+
+ CKBufferParser
+
+
+ CKStateChunk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ¥
+
+
+
+ ¥-
+
+
+
+
+ ¥
+
+
+
+
+ ¥-
+
+
+
+
+ ¥
+
+
+
+ ¥-
+
+
+
+
+ ¥
+
+
+
+
+ ¥-
+
+
+
+
+
+ -
+
+ -
+
+
+
+
+ -
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ :
+
+
+
+
+
+
+ :
+
+ :
+
+
+
+
+
+
+ :
+
+
+
+
+ :
+
+ :
+
+
+
+
+ -
+
+ -
+
+
+
+ :
+
+
+
+ $
+
+
+
+
+ ($
+
+ )
+
+
+
+ $
+
+
+
+
+
+ ($
+
+ )
+
+
+
+ $
+
+
+
+
+ ($
+
+ )
+
+
+
+ $
+
+
+
+
+
+ ($
+
+ )
+
+
+
+
+ -
+
+ -
+
+
+
+
+ 时
+
+ 分
+
+
+
+ 时
+
+ 分
+
+ 秒
+
+
+
+
+ 时
+
+ 分
+
+
+
+
+ 时
+
+ 分
+
+ 秒
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+ ¥
+
+
+
+
+
+ ¥
+
+ -
+
+
+
+
+ ¥
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+ ¥
+
+
+
+
+
+ ¥
+
+ -
+
+
+
+
+ ¥
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+ :
+
+
+
+
+ :
+
+ :
+
+
+
+
+ :
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ offset
+
+
+ type
+
+
+ meaning
+
+
+
+
+
+ 16
+
+
+ field
+
+
+ header zero
+
+
+
+
+
+ 17
+
+
+ field
+
+
+ header version
+
+
+
+
+
+ 18
+
+
+ field
+
+
+ header flags
+
+
+
+
+
+ 19
+
+
+ field
+
+
+ header plugin1
+
+
+
+
+
+ 20
+
+
+ field
+
+
+ header date
+
+
+
+
+
+ 21
+
+
+ field
+
+
+ opened compressed file buffer size
+
+
+
+
+
+ 22
+
+
+ field
+
+
+ header components count
+
+
+
+
+
+ 23
+
+
+ field
+
+
+ header addpath
+
+
+
+
+
+ 24
+
+
+ field
+
+
+ header objects count
+
+
+
+
+
+ 25
+
+
+ field
+
+
+ header crc
+
+
+
+
+
+ 26
+
+
+ field
+
+
+ header components compressed size
+
+
+
+
+
+ 27
+
+
+ field
+
+
+ header components decompressed size
+
+
+
+
+
+ 28
+
+
+ field
+
+
+ header objects compressed size
+
+
+
+
+
+ 29
+
+
+ field
+
+
+ header objects decompressed size
+
+
+
+
+
+ 33
+
+
+ field
+
+
+ load flag CK_LOAD_FLAGS
+
+
+
+
+
+ 34
+
+
+ field
+
+
+ opened virtools file name
+
+
+
+
+
+ 36
+
+
+ field
+
+
+ opened compressed file buffer
+
+
+
+
+
+ 0
+
+
+ field
+
+
+ objects count
+
+
+
+
+
+ 1
+
+
+ field
+
+
+ components list header(unit 44)
+
+
+
+
+
+ 2
+
+
+ field
+
+
+ components list tail
+
+
+
+
+
+ 7
+
+
+ field
+
+
+ components extra list header(unit 24, internal cell 8)
+
+
+
+
+
+ 8
+
+
+ field
+
+
+ components extra list tail
+
+
+
+
+
+ 4
+
+
+ field
+
+
+ components addpath list header(unit 12)
+
+
+
+
+
+ 5
+
+
+ field
+
+
+ components addpath list tail
+
+
+
+
+
+ 37
+
+
+ field
+
+
+ vt file (memeory mapped file)
+
+
+
+
+
+ 35
+
+
+ field
+
+
+ ckcontext
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ offset
+
+
+ type
+
+
+ meaning
+
+
+
+
+
+ 0
+
+
+ char*
+
+
+ reader ptr
+
+
+
+
+
+ 1
+
+
+ DWORD
+
+
+ read counter
+
+
+
+
+
+ 2
+
+
+ DWORD
+
+
+ need_free_manuall
+
+
+
+
+
+ 3
+
+
+ DWORD
+
+
+ buffer size
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ offset
+
+
+ type
+
+
+ meaning
+
+
+
+
+
+ 0
+
+
+ CK_CLASSID
+
+
+ the class identifier
+
+
+
+
+
+ 1
+
+
+ int
+
+
+ data size in DWORD (*4 for byte)
+
+
+
+
+
+ 2
+
+
+ DWORD**
+
+
+ pointer to pointer of data
+
+
+
+
+
+ 3.0
+
+
+ WORD
+
+
+ data version, LowWord
+
+
+
+
+
+ 3.1
+
+
+ WORD
+
+
+ chunk bersion, HighWord
+
+
+
+
+
+ 4
+
+
+ DWORD*
+
+
+ pointer to current pos(in DWROD) may have complex struct (0xCh)
+
+
+
+
+
+ 5
+
+
+ XArray* like
+
+
+
+
+
+
+ 6
+
+
+ XArray* like
+
+
+
+
+
+
+ 7
+
+
+ XArray* like
+
+
+
+
+
+
+ 8
+
+
+ CKFile*
+
+
+ related ck file
+
+
+
+
+
+ 9
+
+
+
+
+
+
+
+
+
+ some unknow struct
+
+
+
+
+
+
+ offset
+
+
+ type
+
+
+ meaning
+
+
+
+
+
+ 0
+
+
+ CK_CLASSID
+
+
+ the class identifier
+
+
+
+
+
+
+
+
+ 4
+
+
+ int
+
+
+ max size
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Documents/Recorder.txt b/Documents/Recorder.txt
new file mode 100644
index 0000000..840d787
--- /dev/null
+++ b/Documents/Recorder.txt
@@ -0,0 +1,166 @@
+CKFile in VT21: 0xC8, 200, count50; in VT25: 0xE0, 224, count 56
+lost 24 byte, 6 fields or 2 lists
+
+m_FileName
+in VT21 +34, 136
+in VT25 +31, 124
+
+m_MappedFile
+in VT21 +37, 148
+in VT25 +34, 136
+
+m_Context
+in VT21 +35, 140
+in VT25 +32, 128
+
+VxMemoryMappedFile and CKFileInfo seems no change
+CKFileObject still no change
+CKFilePluginDependencies still no change
+
+CKStateChunk is 0x28u black box
+CKBufferParser also is 0x10u black box
+
+struct CKGUID {
+DWORD d1,d2;
+};
+
+struct XBaseString {
+ // the string
+ char* m_Buffer;
+ // the length of the string
+ WORD m_Length;
+ // the allocated size
+ WORD m_Allocated;
+};
+
+struct XArray {
+ // elements start {secret}
+ DWORD* m_Begin;
+ // elements end {secret}
+ DWORD* m_End;
+ // reserved end {secret}
+ DWORD* m_AllocatedEnd;
+}
+struct XClassArray {
+ DWORD* m_Begin;
+ DWORD* m_End;
+ DWORD* m_AllocatedEnd;
+}
+struct XSArray {
+ DWORD* m_Begin;
+ DWORD* m_End;
+};
+struct XBitArray {
+ DWORD m_Data_Flags;
+ DWORD m_Size;
+};
+
+struct CKFileInfo
+{
+ DWORD ProductVersion; // Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION)
+ DWORD ProductBuild; // Virtools Build Number.
+ DWORD FileWriteMode; // Options used to save this file. (CK_FILE_WRITEMODE)
+ DWORD FileVersion; // Version of file format when file was saved.
+ DWORD CKVersion; // Version of CK when file was saved.
+ DWORD FileSize; // Size of file in bytes.
+ DWORD ObjectCount; // Number of objects stored in the file.
+ DWORD ManagerCount; // Number of managers which saved data in the file.
+ DWORD MaxIDSaved; // Maximum Object identifier saved
+ DWORD Crc; // Crc of data
+ DWORD Hdr1PackSize; // Reserved
+ DWORD Hdr1UnPackSize; // Reserved
+ DWORD DataPackSize; // Reserved
+ DWORD DataUnPackSize; // Reserved
+};
+
+struct CKFileObject {
+ CK_ID Object; // ID of the object being load/saved (as it will be/was saved in the file)
+ CK_ID CreatedObject; // ID of the object being created
+ CK_CLASSID ObjectCid; // Class Identifier of the object
+ CKObject* ObjPtr; // A pointer to the object itself (as CreatedObject when loading)
+ CKSTRING Name; // Name of the Object
+ CKStateChunk* Data; // A CKStateChunk that contains object information
+ int PostPackSize; // When compressed chunk by chunk : size of Data after compression
+ int PrePackSize; // When compressed chunk by chunk : size of Data before compression
+ CK_FO_OPTIONS Options; // When loading an object it may be renamed , use to replace another object
+ int FileIndex; // Position of the object data inside uncompressed file buffer
+ CKDWORD SaveFlags; // Flags used when this object was saved.
+};
+
+struct CKFilePluginDependencies{
+ int m_PluginCategory;
+ XArray/**/ m_Guids;
+ XBitArray ValidGuids;
+};
+
+struct VxMemoryMappedFile {
+ void* m_hFile;
+ void* m_hFileMapping; // Handle of memory mapped file
+ void* m_pMemoryMappedFileBase;
+ DWORD m_cbFile;
+ DWORD m_errCode;
+};
+
+struct CKBufferParser {
+ char* m_ReaderBegin;
+ DWORD m_ReaderPos;
+ CKBOOL m_NeedManualFree;
+ DWORD m_ReaderSize;
+};
+
+struct CKFile {
+// 0
+ int m_SaveIDMax; // Maximum CK_ID found when saving or loading objects {secret}
+ XArray/**/ m_FileObjects; // List of objects being saved / loaded {secret}
+ XArray/**/ m_ManagersData; // Manager Data loaded {secret}
+ XClassArray/**/ m_PluginsDep; // Plugins dependencies for this file {secret}
+ XClassArray/**/ m_IndexByClassId; // List of index in the m_FileObjects table sorted by ClassID {secret}
+ XClassArray/**/ m_IncludedFiles; // List of files that should be inserted in the CMO file. {secret}
+// 16
+ CKFileInfo m_FileInfo; // Headers summary {secret}
+// 16 + 14 = 30
+ // guess
+ DWORD unknow_fields;
+ XBitArray m_AlreadySavedMask; // BitArray of IDs already saved {secret}
+// 30 + 3 = 33
+ CKDWORD m_Flags; // Flags used to save file {secret}
+ CKSTRING m_FileName; // Current file name {secret}
+ CKContext* m_Context; // CKContext on which file is loaded/Saved {secret}
+ CKBufferParser* m_Parser;
+ VxMemoryMappedFile* m_MappedFile;
+// 33 + 5 = 38
+ // guess
+ float m_Chrono[5];
+// 38 + 5 = 43
+ //[guess]
+ CKBOOL m_SceneSaved;
+ CKBOOL m_ReadFileDataDone;
+// 43 + 2 = 45
+ XBitArray m_AlreadyReferencedMask; // BitArray of IDs already referenced {secret}
+ XObjectPointerArray m_ReferencedObjects;
+// 45 + 2 + 3 = 50
+};
+
+ VxTimeProfiler m_Chrono;
+
+ XFileObjectsTable m_ObjectsHashTable;
+//#ifdef USECHUNKTABLE
+ XClassArray/**/ m_FileChunks; // Instead of allocating chunk per chunk a whole memory buffer is allocated to store all chunks and their readers
+ CKFileChunk* m_ObjectChunks;
+ CKFileChunk* m_ManagersChunks;
+ VxMemoryPool m_ChunkBuffers; // Store all decompressed file buffer in memory so that all chunks directly points to it...
+ // can only work for recent files ( > 2.0)
+ BYTE* m_CurrentChunkBufferPtr;
+//#endif
+
+ CKBOOL m_ReadFileDataDone;
+ CKBOOL m_SceneSaved;
+//-----------
+ XIntArray m_DuplicateNameFounds; // A List of file object index for which a existing object with the same name has been
+ // found, this list is build if the load option contains CK_LOAD_AUTOMATICMODE or CK_LOAD_DODIALOG
+
+//-----
+ XBitArray m_AlreadySavedMask; // BitArray of IDs already saved {secret}
+ XBitArray m_AlreadyReferencedMask; // BitArray of IDs already referenced {secret}
+ XObjectPointerArray m_ReferencedObjects;
+};
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..9c348bf
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-2023 BearKidsTeam
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/PyCmo/VTConstants.py b/PyCmo/VTConstants.py
index 9b63ce2..4090da1 100644
--- a/PyCmo/VTConstants.py
+++ b/PyCmo/VTConstants.py
@@ -25,7 +25,7 @@ class CKEnum(object):
if i.value == self.m_Value:
return '<' + i.name + '>'
- return "<[None] {:d}>".format(self.m_Value)
+ return "<[None]: {:d}>".format(self.m_Value)
def __str__(self):
return self.__repr__()
@@ -48,14 +48,14 @@ class CKFlagEnum(CKEnum):
for i in self:
# if it have exactly same entry, return directly
if i.value == self.m_Value:
- return i.name
+ return '<' + i.name + '>'
# check exist
if bool(self.m_Value & i.value):
pending.append(i.name)
result = ', '.join(pending)
- return ('<' + result + '>') if len(result) != 9 else "<[None] {:d}>".format(self.m_Value)
+ return ('<' + result + '>') if len(result) != 0 else "<[None]: {:d}>".format(self.m_Value)
class CK_FILE_WRITEMODE(CKFlagEnum):
CKFILE_UNCOMPRESSED =0 # Save data uncompressed
diff --git a/PyCmo/VTStruct.py b/PyCmo/VTStruct.py
index 1dd740d..b9d45c0 100644
--- a/PyCmo/VTStruct.py
+++ b/PyCmo/VTStruct.py
@@ -19,7 +19,7 @@ class CKFileInfo:
self.ProductVersion: int = 0
self.ProductBuild: int = 0
- self.FileWriteMode: VTConstants.CK_FILE_WRITEMODE = VTConstants.CK_FILE_WRITEMODE(0)
+ self.FileWriteMode: VTConstants.CK_FILE_WRITEMODE = VTConstants.CK_FILE_WRITEMODE(VTConstants.CK_FILE_WRITEMODE.CKFILE_WHOLECOMPRESSED)
self.FileVersion: int = 0
self.CKVersion: int = 0