Example #1
0
        /// This method is used to deserialize the Root File Node List from the specified byte array and start index.
        /// </summary>
        /// <param name="byteArray">Specify the byte array.</param>
        /// <param name="reference">Specify the reference of Root File Node List.</param>
        public void DoDeserializeFromByteArray(byte[] byteArray, FileNodeChunkReference reference)
        {
            FileNodeListFragment fragment = new FileNodeListFragment(reference.CbValue);

            fragment.DoDeserializeFromByteArray(byteArray, (int)reference.StpValue);
            this.FileNodeListFragments.Add(fragment);
            this.FileNodeSequence.AddRange(fragment.rgFileNodes.Where(f => f.FileNodeID != FileNodeIDValues.ChunkTerminatorFND).ToArray());
            FileChunkReference64x32 nextFragmentRef = fragment.nextFragment;

            while (nextFragmentRef.IsfcrNil() == false && nextFragmentRef.IsfcrZero() == false)
            {
                FileNodeListFragment nextFragment = new FileNodeListFragment(nextFragmentRef.Cb);
                nextFragment.DoDeserializeFromByteArray(byteArray, (int)nextFragmentRef.Stp);
                nextFragmentRef = nextFragment.nextFragment;
                this.FileNodeListFragments.Add(nextFragment);
                this.FileNodeSequence.AddRange(nextFragment.rgFileNodes.Where(f => f.FileNodeID != FileNodeIDValues.ChunkTerminatorFND).ToArray());
            }

            FileNode[] objectSpaceManifestListStartArray = this.FileNodeSequence.Where(obj => obj.FileNodeID == FileNodeIDValues.ObjectSpaceManifestListStartFND).ToArray();
            if (objectSpaceManifestListStartArray.Length == 1)
            {
                this.ObjectSpaceManifestListStart = objectSpaceManifestListStartArray[0];
            }
            FileNode[] revisionManifestListRefArray = this.FileNodeSequence.Where(obj => obj.FileNodeID == FileNodeIDValues.RevisionManifestListReferenceFND).ToArray();
            foreach (FileNode revisionManifestListNode in revisionManifestListRefArray)
            {
                RevisionManifestListReferenceFND revisionManifestListReferenceFND = revisionManifestListNode.fnd as RevisionManifestListReferenceFND;
                RevisionManifestList             revisionManifestList             = new MS_ONESTORE.RevisionManifestList();
                revisionManifestList.DoDeserializeFromByteArray(byteArray, revisionManifestListReferenceFND.refField);
                this.RevisionManifestList.Add(revisionManifestList);
            }
        }
Example #2
0
        /// <summary>
        /// This method is used to deserialize the Root File Node List from the specified byte array and start index.
        /// </summary>
        /// <param name="byteArray">Specify the byte array.</param>
        /// <param name="reference">Specify the reference of Root File Node List.</param>
        public void DoDeserializeFromByteArray(byte[] byteArray, FileChunkReference64x32 reference)
        {
            FileNodeListFragment fragment = new FileNodeListFragment(reference.Cb);

            fragment.DoDeserializeFromByteArray(byteArray, (int)reference.Stp);
            this.FileNodeListFragments.Add(fragment);
            this.FileNodeSequence.AddRange(fragment.rgFileNodes.Where(f => f.FileNodeID != FileNodeIDValues.ChunkTerminatorFND).ToArray());
            FileChunkReference64x32 nextFragmentRef = fragment.nextFragment;

            while (nextFragmentRef.IsfcrNil() == false && nextFragmentRef.IsfcrZero() == false)
            {
                FileNodeListFragment nextFragment = new FileNodeListFragment(nextFragmentRef.Cb);
                nextFragment.DoDeserializeFromByteArray(byteArray, (int)nextFragmentRef.Stp);
                nextFragmentRef = nextFragment.nextFragment;
                this.FileNodeListFragments.Add(nextFragment);
                this.FileNodeSequence.AddRange(nextFragment.rgFileNodes.Where(f => f.FileNodeID != FileNodeIDValues.ChunkTerminatorFND).ToArray());
            }

            FileNode[] objectSpaceManifestListReferences = this.FileNodeSequence.Where(obj => obj.FileNodeID == FileNodeIDValues.ObjectSpaceManifestListReferenceFND).ToArray();
            foreach (FileNode node in objectSpaceManifestListReferences)
            {
                ObjectSpaceManifestListReferenceFND objectSpaceManifestListReference = node.fnd as ObjectSpaceManifestListReferenceFND;
                ObjectSpaceManifestList             objectSpaceManifestList          = new MS_ONESTORE.ObjectSpaceManifestList();
                objectSpaceManifestList.DoDeserializeFromByteArray(byteArray, objectSpaceManifestListReference.refField);
                this.ObjectSpaceManifestList.Add(objectSpaceManifestList);
            }

            this.FileDataStoreListReference.AddRange(this.FileNodeSequence.Where(obj => obj.FileNodeID == FileNodeIDValues.FileDataStoreListReferenceFND).ToArray());
            FileNode[] objectSpaceManifestRootArray = this.FileNodeSequence.Where(obj => obj.FileNodeID == FileNodeIDValues.ObjectSpaceManifestRootFND).ToArray();
            if (objectSpaceManifestRootArray.Length == 1)
            {
                this.ObjectSpaceManifestRoot = objectSpaceManifestRootArray[0];
            }
        }
        /// This method is used to deserialize the Object Group from the specified byte array and start index.
        /// </summary>
        /// <param name="byteArray">Specify the byte array.</param>
        /// <param name="reference">Specify the reference of Object Group.</param>
        public void DoDeserializeFromByteArray(byte[] byteArray, FileNodeChunkReference reference)
        {
            FileNodeListFragment fragment = new FileNodeListFragment(reference.CbValue);

            fragment.DoDeserializeFromByteArray(byteArray, (int)reference.StpValue);
            this.FileNodeListFragments.Add(fragment);
            this.FileNodeSequence.AddRange(fragment.rgFileNodes.Where(f => f.FileNodeID != FileNodeIDValues.ChunkTerminatorFND).ToArray());
            FileChunkReference64x32 nextFragmentRef = fragment.nextFragment;

            while (nextFragmentRef.IsfcrNil() == false && nextFragmentRef.IsfcrZero() == false)
            {
                FileNodeListFragment nextFragment = new FileNodeListFragment(nextFragmentRef.Cb);
                nextFragment.DoDeserializeFromByteArray(byteArray, (int)nextFragmentRef.Stp);
                nextFragmentRef = nextFragment.nextFragment;
                this.FileNodeListFragments.Add(nextFragment);
                this.FileNodeSequence.AddRange(nextFragment.rgFileNodes.Where(f => f.FileNodeID != FileNodeIDValues.ChunkTerminatorFND).ToArray());
            }
        }
        public void MSONESTORE_S02_TC01_LoadOneNoteFileWithFileData()
        {
            string fileName = Common.GetConfigurationPropertyValue("OneFileWithFileData", Site);

            OneNoteRevisionStoreFile file = this.Adapter.LoadOneNoteFile(fileName);

            for (int i = 0; i <= file.RootFileNodeList.FileNodeListFragments.Count - 1; i++)
            {
                bool isDifferent = file.RootFileNodeList.FileNodeListFragments[i].Header.FileNodeListID != file.RootFileNodeList.FileNodeListFragments[i].Header.nFragmentSequence;

                // Verify MS-ONESTORE requirement: MS-ONESTORE_R3911
                Site.CaptureRequirementIfIsTrue(
                    isDifferent,
                    3911,
                    @"[In FileNodeListHeader] The pair of FileNodeListID and nFragmentSequence field in FileNodeListFragment structures in the file, is different.");
            }

            List <RevisionManifest> revisManifestList = new List <RevisionManifest>();

            foreach (ObjectSpaceManifestList objSpaceManifestList in file.RootFileNodeList.ObjectSpaceManifestList)
            {
                foreach (RevisionManifestList revManifestList in objSpaceManifestList.RevisionManifestList)
                {
                    revisManifestList.AddRange(revManifestList.RevisionManifests);
                }
            }

            List <ExtendedGUID> ridRevisionManifestStart6FND          = new List <ExtendedGUID>();
            List <ExtendedGUID> ridDependentRevisionManifestStart6FND = new List <ExtendedGUID>();
            List <ExtendedGUID> ridRevisionManifestStart7FND          = new List <ExtendedGUID>();
            List <ExtendedGUID> ridDependentRevisionManifestStart7FND = new List <ExtendedGUID>();
            List <uint>         odcsDefault = new List <uint>();

            for (int i = 0; i < revisManifestList.Count; i++)
            {
                for (int j = 0; j < revisManifestList[i].FileNodeSequence.Count; j++)
                {
                    FileNode revision = revisManifestList[i].FileNodeSequence[j];

                    if (revision.FileNodeID == FileNodeIDValues.RevisionManifestStart6FND)
                    {
                        RevisionManifestStart6FND fnd = revision.fnd as RevisionManifestStart6FND;
                        ridRevisionManifestStart6FND.Add(((RevisionManifestStart6FND)revision.fnd).rid);
                        ridDependentRevisionManifestStart6FND.Add(((RevisionManifestStart6FND)revision.fnd).ridDependent);
                        odcsDefault.Add(((RevisionManifestStart6FND)revision.fnd).odcsDefault);
                    }

                    if (revision.FileNodeID == FileNodeIDValues.RevisionManifestStart7FND)
                    {
                        RevisionManifestStart7FND fnd = revision.fnd as RevisionManifestStart7FND;
                        ridRevisionManifestStart7FND.Add(((RevisionManifestStart7FND)revision.fnd).Base.rid);
                        ridDependentRevisionManifestStart7FND.Add(((RevisionManifestStart7FND)revision.fnd).Base.ridDependent);
                    }
                }
            }

            for (int i = 0; i < odcsDefault.Count - 1; i++)
            {
                // Verify MS-ONESTORE requirement: MS-ONESTORE_R535
                Site.CaptureRequirementIfAreEqual <uint>(
                    odcsDefault[i],
                    odcsDefault[i + 1],
                    535,
                    @"[In RevisionManifestStart6FND] [odcsDefault] MUST specify the same type of data encoding as used in the dependency revision (section 2.1.8), if one was specified in the ridDependent field.");
            }

            ExtendedGUID zeroExtendGuid = new ExtendedGUID();

            zeroExtendGuid.Guid = Guid.Empty;
            zeroExtendGuid.N    = 0;

            for (int i = 0; i < ridRevisionManifestStart6FND.Count - 1; i++)
            {
                for (int j = i + 1; j < ridRevisionManifestStart6FND.Count; j++)
                {
                    // Verify MS-ONESTORE requirement: MS-ONESTORE_R52501
                    Site.CaptureRequirementIfAreNotEqual <ExtendedGUID>(
                        ridRevisionManifestStart6FND[i],
                        ridRevisionManifestStart6FND[j],
                        52501,
                        @"[In RevisionManifestStart6FND] The rid of two RevisionManifestStart6FND in revision manifest list is different.");
                }

                if (ridDependentRevisionManifestStart6FND[i].Equals(zeroExtendGuid))
                {
                    // Verify MS-ONESTORE requirement: MS-ONESTORE_R527
                    Site.CaptureRequirementIfAreNotEqual <ExtendedGUID>(
                        zeroExtendGuid,
                        ridRevisionManifestStart6FND[i],
                        527,
                        @"[In RevisionManifestStart6FND] [ridDependent] If the value is ""{ { 00000000 - 0000 - 0000 - 0000 - 000000000000}, 0}
                "", then this revision manifest has no dependency revision. ");
                }
                else
                {
                    if (!ridDependentRevisionManifestStart6FND[i + 1].Equals(zeroExtendGuid))
                    {
                        // Verify MS-ONESTORE requirement: MS-ONESTORE_R528
                        Site.CaptureRequirementIfAreEqual <ExtendedGUID>(
                            ridRevisionManifestStart6FND[i],
                            ridDependentRevisionManifestStart6FND[i + 1],
                            528,
                            @"[In RevisionManifestStart6FND] [ridDependent] Otherwise[If the value is not ""{ { 00000000 - 0000 - 0000 - 0000 - 000000000000}, 0}
                    ""], this value MUST be equal to the RevisionManifestStart6FND.rid field [or the RevisionManifestStart7FND.base.rid field] of a previous revision manifest within this revision manifest list.");
                    }
                }
            }

            for (int i = 0; i < ridRevisionManifestStart7FND.Count - 1; i++)
            {
                for (int j = i + 1; j < ridRevisionManifestStart7FND.Count; j++)
                {
                    // Verify MS-ONESTORE requirement: MS-ONESTORE_R52502
                    Site.CaptureRequirementIfAreNotEqual <ExtendedGUID>(
                        ridRevisionManifestStart7FND[i],
                        ridRevisionManifestStart7FND[i + 1],
                        52502,
                        @"[In RevisionManifestStart6FND] The rid of two RevisionManifestStart7FND in revision manifest list is different.");
                }

                if (!ridDependentRevisionManifestStart7FND[i].Equals(zeroExtendGuid) && !ridDependentRevisionManifestStart7FND[i + 1].Equals(zeroExtendGuid))
                {
                    // Verify MS-ONESTORE requirement: MS-ONESTORE_R52801
                    Site.CaptureRequirementIfAreEqual <ExtendedGUID>(
                        ridRevisionManifestStart7FND[i],
                        ridDependentRevisionManifestStart7FND[i + 1],
                        52801,
                        @"[In RevisionManifestStart6FND] [ridDependent] Otherwise[If the value is not ""{ { 00000000 - 0000 - 0000 - 0000 - 000000000000}, 0}
                    ""], this value MUST be equal to [the RevisionManifestStart6FND.rid field or] the RevisionManifestStart7FND.base.rid field of a previous revision manifest within this revision manifest list.");
                }
            }
            foreach (ObjectSpaceManifestList objectSpaceManifestList in file.RootFileNodeList.ObjectSpaceManifestList)
            {
                foreach (RevisionManifestList revisionManifestList in objectSpaceManifestList.RevisionManifestList)
                {
                    if (revisionManifestList.FileNodeListFragments.Count > 1)
                    {
                        for (int i = 0; i < revisionManifestList.FileNodeListFragments.Count - 1; i++)
                        {
                            for (int j = i + 1; j < revisionManifestList.FileNodeListFragments.Count; j++)
                            {
                                // Verify MS-ONESTORE requirement: MS-ONESTORE_R366
                                Site.CaptureRequirementIfAreEqual <uint>(
                                    revisionManifestList.FileNodeListFragments[i].Header.FileNodeListID,
                                    revisionManifestList.FileNodeListFragments[j].Header.FileNodeListID,
                                    366,
                                    @"[In FileNodeListFragment] All fragments in the same file node list MUST have the same FileNodeListFragment.header.FileNodeListID field.");
                            }
                        }
                    }

                    foreach (FileNodeListFragment fileNodeListFragment in revisionManifestList.FileNodeListFragments)
                    {
                        FileChunkReference64x32 nextFragment = fileNodeListFragment.nextFragment;
                        if ((uint)fileNodeListFragment.rgFileNodes[fileNodeListFragment.rgFileNodes.Count - 1].FileNodeID == 0xFF)
                        {
                            // Verify MS-ONESTORE requirement: MS-ONESTORE_R373
                            Site.CaptureRequirementIfIsInstanceOfType(
                                nextFragment,
                                typeof(FileChunkReference64x32),
                                373,
                                @"[In FileNodeListFragment] [rgFileNodes If a ChunkTerminatorFND structure is present, the value of the nextFragment field MUST be a valid FileChunkReference64x32 structure (section 2.2.4.4) to the next FileNodeListFragment structure.");
                        }

                        if (nextFragment == revisionManifestList.FileNodeListFragments[revisionManifestList.FileNodeListFragments.Count - 1].nextFragment)
                        {
                            // Verify MS-ONESTORE requirement: MS-ONESTORE_R379
                            Site.CaptureRequirementIfIsTrue(
                                nextFragment.IsfcrNil(),
                                379,
                                @"[In FileNodeListFragment] If this is the last fragment, the value of the nextFragment field MUST be ""fcrNil"" (see section 2.2.4). ");
                        }
                        else
                        {
                            // Verify MS-ONESTORE requirement: MS-ONESTORE_R380
                            Site.CaptureRequirementIfIsFalse(
                                nextFragment.IsfcrZero() || nextFragment.IsfcrNil(),
                                380,
                                @"[In FileNodeListFragment] Otherwise [If this is not the last fragment] the value of the nextFragment.stp field MUST specify the location of a valid FileNodeListFragment structure, and the value of the nextFragment.cb field MUST be equal to the size of the referenced fragment including the FileNodeListFragment.header field and the FileNodeListFragment.footer field.");
                        }
                    }
                }
            }

            bool isFileNode = false;

            foreach (FileNode fileDataStoreList in file.RootFileNodeList.FileDataStoreListReference)
            {
                FileDataStoreListReferenceFND fnd = fileDataStoreList.fnd as FileDataStoreListReferenceFND;

                for (int i = 0; i < fnd.fileNodeListFragment.rgFileNodes.Count - 1; i++)
                {
                    for (int j = i + 1; j < fnd.fileNodeListFragment.rgFileNodes.Count; j++)
                    {
                        FileDataStoreObjectReferenceFND objfnd1 = fnd.fileNodeListFragment.rgFileNodes[i].fnd as FileDataStoreObjectReferenceFND;
                        FileDataStoreObjectReferenceFND objfnd2 = fnd.fileNodeListFragment.rgFileNodes[j].fnd as FileDataStoreObjectReferenceFND;

                        // Verify MS-ONESTORE requirement: MS-ONESTORE_R63701
                        Site.CaptureRequirementIfAreNotEqual <Guid>(
                            objfnd1.guidReference,
                            objfnd2.guidReference,
                            63701,
                            @"[In FileDataStoreObjectReferenceFND] The guidReference is different for two FileDataStoreObjectReferenceFND structures.");
                    }
                }

                isFileNode = true;

                for (int k = 0; k < fnd.fileNodeListFragment.rgFileNodes.Count; k++)
                {
                    FileNode fileNode = fnd.fileNodeListFragment.rgFileNodes[k];
                    if ((uint)fileNode.FileNodeID != 0x094)
                    {
                        isFileNode = false;
                        break;
                    }

                    // Verify MS-ONESTORE requirement: MS-ONESTORE_R628
                    Site.CaptureRequirementIfIsTrue(
                        isFileNode,
                        628,
                        @"[In FileDataStoreListReferenceFND] The referenced file node list MUST contain only FileNode structures with a FileNodeID field value equal to 00x094 (FileDataStoreObjectReferenceFND structure). ");

                    //If MS-ONESTORE_R628 is verified successfully and according to the definition of FileDataStoreObjectReferenceFND, MS-ONESTORE_R33 can be verified directlly.
                    //Verify MS-ONESTORE requirement: MS-ONESTORE_R633
                    Site.CaptureRequirement(
                        633,
                        @"[[In FileDataStoreObjectReferenceFND] All such FileNode structures MUST be contained in the file node list (section 2.4) specified by a FileDataStoreListReferenceFND structure (section 2.5.21).");
                }
            }

            int objectSpaceCount = file.RootFileNodeList.ObjectSpaceManifestList.Count;

            for (int i = 0; i < file.RootFileNodeList.ObjectSpaceManifestList.Count; i++)
            {
                ObjectSpaceManifestList objectSpace = file.RootFileNodeList.ObjectSpaceManifestList[i];

                for (int j = 0; j < objectSpace.RevisionManifestList[0].ObjectGroupList.Count; j++)
                {
                    ObjectGroupList objectGroupList = objectSpace.RevisionManifestList[0].ObjectGroupList[j];
                    FileNode[]      fileNodes       = objectGroupList.FileNodeSequence.Where(f => f.FileNodeID == FileNodeIDValues.ReadOnlyObjectDeclaration2RefCountFND).ToArray();

                    foreach (FileNode node in fileNodes)
                    {
                        ReadOnlyObjectDeclaration2RefCountFND fnd = node.fnd as ReadOnlyObjectDeclaration2RefCountFND;

                        // Verify MS-ONESTORE requirement: MS-ONESTORE_R68
                        Site.CaptureRequirementIfIsTrue(
                            (uint)node.FileNodeID == 0x0C4 && fnd.Base.body.jcid.IsReadOnly == 1,
                            68,
                            @"[In Object Space Object] If the value of the JCID.IsReadOnly field is ""true"" then the value of the FileNode.FileNodeID field MUST be 0x0C4 (ReadOnlyObjectDeclaration2RefCountFND structure, section 2.5.29) [or 0x0C5 (ReadOnlyObjectDeclaration2LargeRefCountFND structure, section 2.5.30).]");

                        // Verify MS-ONESTORE requirement: MS-ONESTORE_R703
                        Site.CaptureRequirementIfIsNotNull(
                            fnd.Base,
                            703,
                            @"[In ReadOnlyObjectDeclaration2RefCountFND] If this object is revised, all declarations of this object MUST specify identical data. ");
                    }

                    fileNodes = objectGroupList.FileNodeSequence.Where(f => f.FileNodeID == FileNodeIDValues.ObjectDeclarationFileData3RefCountFND).ToArray();

                    foreach (FileNode node in fileNodes)
                    {
                        ObjectDeclarationFileData3RefCountFND fnd = node.fnd as ObjectDeclarationFileData3RefCountFND;

                        // Verify MS-ONESTORE requirement: MS-ONESTORE_R71
                        Site.CaptureRequirementIfIsTrue(
                            (uint)node.FileNodeID == 0x072 && fnd.jcid.IsFileData == 1,
                            71,
                            @"[In Object Space Object]If the value of the JCID.IsFileData field is ""true"" then the value of the FileNode.FileNodeID field MUST be 0x072 (ObjectDeclarationFileData3RefCountFND structure, section 2.5.27) [or 0x073 (ObjectDeclarationFileData3LargeRefCountFND structure, section 2.5.28). ]");
                    }

                    fileNodes = objectGroupList.FileNodeSequence.Where(f => f.FileNodeID == FileNodeIDValues.ReadOnlyObjectDeclaration2LargeRefCountFND).ToArray();

                    foreach (FileNode node in fileNodes)
                    {
                        ReadOnlyObjectDeclaration2LargeRefCountFND fnd = node.fnd as ReadOnlyObjectDeclaration2LargeRefCountFND;

                        // Verify MS-ONESTORE requirement: MS-ONESTORE_R710
                        Site.CaptureRequirementIfIsNotNull(
                            fnd.Base,
                            710,
                            @"[In ReadOnlyObjectDeclaration2LargeRefCountFND] If this object is revised, all declarations of this object MUST specify identical data. ");
                    }
                    fileNodes = objectGroupList.FileNodeSequence.Where(f => f.FileNodeID == FileNodeIDValues.DataSignatureGroupDefinitionFND).ToArray();

                    List <ExtendedGUID> dataSignatureGroupdefinitionFND = new List <ExtendedGUID>();

                    for (int k = 0; k < fileNodes.Length - 1; k++)
                    {
                        DataSignatureGroupDefinitionFND fnd = fileNodes[k].fnd as DataSignatureGroupDefinitionFND;
                        if (!fnd.DataSignatureGroup.Equals(zeroExtendGuid))
                        {
                            dataSignatureGroupdefinitionFND.Add(fnd.DataSignatureGroup);
                        }
                    }

                    for (int k = 0; k < dataSignatureGroupdefinitionFND.Count - 1; k++)
                    {
                        for (int h = k + 1; h < dataSignatureGroupdefinitionFND.Count; h++)
                        {
                            // Verify MS-ONESTORE requirement: MS-ONESTORE_R72701
                            Site.CaptureRequirementIfAreEqual <ExtendedGUID>(
                                dataSignatureGroupdefinitionFND[k],
                                dataSignatureGroupdefinitionFND[h],
                                72701,
                                @"[In DataSignatureGroupDefinitionFND] DataSignatureGroup (20 bytes):All declarations of an object (section 2.1.5) with the same identity and the same DataSignatureGroup field not equal to {{00000000-0000-0000-0000-000000000000}, 0} MUST have the same data.");
                        }
                    }
                }
            }
        }
        /// This method is used to deserialize the Revision Manifest List from the specified byte array and start index.
        /// </summary>
        /// <param name="byteArray">Specify the byte array.</param>
        /// <param name="reference">Specify the reference of Revision Manifest List.</param>
        public void DoDeserializeFromByteArray(byte[] byteArray, FileNodeChunkReference reference)
        {
            FileNodeListFragment fragment = new FileNodeListFragment(reference.CbValue);

            fragment.DoDeserializeFromByteArray(byteArray, (int)reference.StpValue);
            this.FileNodeListFragments.Add(fragment);
            this.FileNodeSequence.AddRange(fragment.rgFileNodes.Where(f => f.FileNodeID != FileNodeIDValues.ChunkTerminatorFND).ToArray());
            FileChunkReference64x32 nextFragmentRef = fragment.nextFragment;

            while (nextFragmentRef.IsfcrNil() == false && nextFragmentRef.IsfcrZero() == false)
            {
                FileNodeListFragment nextFragment = new FileNodeListFragment(nextFragmentRef.Cb);
                nextFragment.DoDeserializeFromByteArray(byteArray, (int)nextFragmentRef.Stp);
                nextFragmentRef = nextFragment.nextFragment;
                this.FileNodeListFragments.Add(nextFragment);
                this.FileNodeSequence.AddRange(nextFragment.rgFileNodes.Where(f => f.FileNodeID != FileNodeIDValues.ChunkTerminatorFND).ToArray());
            }

            RevisionManifest revisionManifest = null;

            foreach (FileNode fileNode in this.FileNodeSequence)
            {
                if (fileNode.FileNodeID == FileNodeIDValues.RevisionRoleDeclarationFND)
                {
                    this.RevisionRoleDeclaration.Add(fileNode);
                    continue;
                }
                if (fileNode.FileNodeID == FileNodeIDValues.RevisionRoleAndContextDeclarationFND)
                {
                    this.RevisionRoleAndContextDeclaration.Add(fileNode);
                    continue;
                }
                if (fileNode.FileNodeID == FileNodeIDValues.RevisionManifestStart6FND ||
                    fileNode.FileNodeID == FileNodeIDValues.RevisionManifestStart7FND ||
                    fileNode.FileNodeID == FileNodeIDValues.RevisionManifestStart4FND)
                {
                    revisionManifest = new RevisionManifest();
                    revisionManifest.FileNodeSequence.Add(fileNode);
                }
                else if (fileNode.FileNodeID == FileNodeIDValues.RevisionManifestEndFND)
                {
                    revisionManifest.FileNodeSequence.Add(fileNode);
                    this.RevisionManifests.Add(revisionManifest);
                    revisionManifest = new RevisionManifest();
                }
                else if (fileNode.FileNodeID != FileNodeIDValues.ChunkTerminatorFND &&
                         fileNode.FileNodeID != FileNodeIDValues.RevisionManifestListStartFND)
                {
                    if (fileNode.FileNodeID == FileNodeIDValues.ObjectDataEncryptionKeyV2FNDX)
                    {
                        OneNoteRevisionStoreFile.IsEncryption = true;
                    }

                    revisionManifest.FileNodeSequence.Add(fileNode);
                    if (fileNode.FileNodeID == FileNodeIDValues.ObjectGroupListReferenceFND)
                    {
                        ObjectGroupListReferenceFND objectGroupListRef = fileNode.fnd as ObjectGroupListReferenceFND;
                        ObjectGroupList             objectGroupList    = new ObjectGroupList();
                        objectGroupList.DoDeserializeFromByteArray(byteArray, objectGroupListRef.Ref);
                        this.ObjectGroupList.Add(objectGroupList);
                    }
                }
            }
        }
        public void DoDeserializeFromByteArray(byte[] byteArray)
        {
            int index = 0;

            this.Header = new Header();
            int len = this.Header.DoDeserializeFromByteArray(byteArray, index);

            index += len;
            this.FreeChunkList = new List <FreeChunkListFragment>();
            FileChunkReference64x32 freeChunkRef = this.Header.fcrFreeChunkList;

            if (freeChunkRef.IsfcrNil() == false && freeChunkRef.IsfcrZero() == false)
            {
                do
                {
                    FreeChunkListFragment freeChunkListFragment = new FreeChunkListFragment(freeChunkRef.Cb);
                    len    = freeChunkListFragment.DoDeserializeFromByteArray(byteArray, (int)freeChunkRef.Stp);
                    index += len;
                    this.FreeChunkList.Add(freeChunkListFragment);
                    freeChunkRef = freeChunkListFragment.fcrNextChunk;
                }while (freeChunkRef.IsfcrNil() == false && freeChunkRef.IsfcrZero() == false);
            }
            this.TransactionLog = new List <TransactionLogFragment>();
            FileChunkReference64x32 transLogRef = this.Header.fcrTransactionLog;

            do
            {
                TransactionLogFragment transLogFragment = new TransactionLogFragment(transLogRef.Cb);
                len         = transLogFragment.DoDeserializeFromByteArray(byteArray, (int)transLogRef.Stp);
                transLogRef = transLogFragment.nextFragment;
                this.TransactionLog.Add(transLogFragment);
                foreach (TransactionEntry entry in transLogFragment.sizeTable.Where(t => t.srcID != 0x00000001).ToArray())
                {
                    if (FileNodeCountMapping.ContainsKey(entry.srcID))
                    {
                        if (FileNodeCountMapping[entry.srcID] < entry.TransactionEntrySwitch)
                        {
                            FileNodeCountMapping[entry.srcID] = entry.TransactionEntrySwitch;
                        }
                    }
                    else
                    {
                        FileNodeCountMapping.Add(entry.srcID, entry.TransactionEntrySwitch);
                    }
                }
            }while (transLogRef.IsfcrNil() == false && transLogRef.IsfcrZero() == false);

            this.HashedChunkList = new List <FileNodeListFragment>();
            FileChunkReference64x32 hashChunkRef = this.Header.fcrHashedChunkList;

            if (hashChunkRef.IsfcrNil() == false && hashChunkRef.IsfcrZero() == false)
            {
                do
                {
                    FileNodeListFragment hashChunkList = new FileNodeListFragment(hashChunkRef.Cb);
                    hashChunkList.DoDeserializeFromByteArray(byteArray, (int)hashChunkRef.Stp);
                    this.HashedChunkList.Add(hashChunkList);
                    hashChunkRef = hashChunkList.nextFragment;
                }while (hashChunkRef.IsfcrNil() == false && hashChunkRef.IsfcrZero() == false);
            }

            this.FileNodeList = new List <FileNodeListFragment>();
            if (Header.fcrFileNodeListRoot.IsfcrNil() == false && Header.fcrFileNodeListRoot.IsfcrZero() == false)
            {
                this.RootFileNodeList = new RootFileNodeList();
                this.RootFileNodeList.DoDeserializeFromByteArray(byteArray, Header.fcrFileNodeListRoot);
            }
        }