public static byte[] MakeVMSExtraBlock(RecordTypes recordType, RecordLayouts layout, FileAttributes attributes,
                                               ushort recordSize, uint fileSize, byte bucketSize, ushort maxRecordSize, ushort defaultExtend,
                                               DateTime created,
                                               DateTime modified, uint ownerId, FileProtection system, FileProtection owner, FileProtection group,
                                               FileProtection world)
        {
            var headerResult = new PK_header
            {
                tag = VMSAttributeHeader, size = VMSAttributeSize, data = new List <PK_field>()
            };
            var    evenFileSize = Math.DivRem(fileSize, 512, out var fileSizeRemainder) + 1;
            FatDef fatDef       = new FatDef
            {
                b_rtype   = MakeRecordType(recordType, layout),
                b_rattrib = (byte)attributes,
                w_rsize   = recordSize,
                l_hiblk   = (uint)(((evenFileSize + 1) << 16) | ((evenFileSize + 1) >> 16)),
                l_efblk   = (uint)((evenFileSize << 16) | (evenFileSize >> 16)),
                w_ffbyte  = (ushort)fileSizeRemainder,
                b_bktsize = bucketSize,
                b_vfcsize = (byte)(recordType == RecordTypes.C_VFC ? 2 : 0),
                w_maxrec  = maxRecordSize,
                w_defext  = defaultExtend,
                w_gbc     = 0
            };

            headerResult.data.Add(new PK_field {
                size = 32, tag = 4, value = WriteFATDef(fatDef)
            });
            headerResult.data.Add(new PK_field {
                size = 4, tag = 3, value = BitConverter.GetBytes((int)0)
            });
            headerResult.data.Add(new PK_field {
                size = 8, tag = 17, value = ConvertToSmithsonianTime(created)
            });
            headerResult.data.Add(new PK_field {
                size = 8, tag = 18, value = ConvertToSmithsonianTime(modified)
            });
            headerResult.data.Add(new PK_field {
                size = 8, tag = 19, value = BitConverter.GetBytes((long)0)
            });
            headerResult.data.Add(new PK_field {
                size = 8, tag = 20, value = BitConverter.GetBytes((long)0)
            });
            headerResult.data.Add(new PK_field {
                size = 2, tag = 13, value = new byte[] { 1, 0 }
            });
            headerResult.data.Add(new PK_field {
                size = 4, tag = 21, value = BitConverter.GetBytes(ownerId)
            });
            headerResult.data.Add(
                new PK_field {
                size = 2, tag = 22, value = MakeProtection(system, owner, group, world)
            });
            headerResult.data.Add(new PK_field {
                size = 2, tag = 23, value = new byte[] { 0, 0 }
            });
            headerResult.data.Add(new PK_field {
                size = 1, tag = 29, value = new byte[] { 0 }
            });

            return(WriteHeader(headerResult));
        }
 public static byte MakeRecordType(RecordTypes type, RecordLayouts layout)
 {
     return((byte)((int)type | (((int)layout) << 4)));
 }