// File: /workspace/github_c_makefile_star2_O2/miniupnp[P]hfsplustools/src/hfscommon.c
// Function: read_hfs_volume_header
int read_hfs_volume_header (FILE * f)
{
	unsigned char buffer[512];
	unsigned char a_buffer[512];
	uint32_t attributes;
	int i;
	uint32_t bsize;
	uint32_t bcount;

	if(fseek(f, hfs_part_sector * SECTOR_SIZE + HFS_VOLUME_HEADER_OFFSET, SEEK_SET) != 0) {
		perror("fseek");
		return 0;
	}
	if(fread(buffer, 1, sizeof(buffer), f) != sizeof(buffer)) {
		fprintf(stderr, "reading error\n");
		return 0;
	}
	printf("VOLUME HEADER (offset %08x)\n",
		hfs_part_sector * SECTOR_SIZE + HFS_VOLUME_HEADER_OFFSET);
	printf("SIGNATURE %c%c version %02x%02x (4=HFS+ 5=HFSX)\n",
	       buffer[0], buffer[1], buffer[2], buffer[3]);
	if(buffer[0] != 'H' || buffer[1] != '+') {
		printf("Not HFS+\n");
		return 0;
	}
	if(fseek(f, (hfs_part_sector + hfs_part_sector_count) * SECTOR_SIZE - HFS_VOLUME_HEADER_OFFSET, SEEK_SET) != 0) {
		perror("fseek");
		return 0;
	}
	if(fread(a_buffer, 1, sizeof(a_buffer), f) != sizeof(a_buffer)) {
		fprintf(stderr, "reading error\n");
		return 0;
	}
	printf("ALTERNATE VOLUME HEADER (offset %08x)\n",
		(hfs_part_sector + hfs_part_sector_count) * SECTOR_SIZE - HFS_VOLUME_HEADER_OFFSET);
	if(memcmp(buffer, a_buffer, sizeof(buffer)) != 0) {
		printf("WARNING: main and alternate Volume Headers differ\n");
		if(memcmp(buffer, a_buffer, 20) != 0) {
			fprintf(stderr, "ERROR: first 20 bytes of main and alternate Volume Headers differ\n");
			printf("Main:\n");
			hexdump(buffer, 32, 0);
			printf("Alternate:\n");
			hexdump(a_buffer, 32, 0);
			return 0;
		}
	}
	hexdump(buffer, 128, 0);
	attributes = readu32(buffer + 4);
	printf("attributes = %08x ", attributes);
	if(attributes&(1<<8)) printf("|kHFSVolumeUnmountedBit");
	if(attributes&(1<<9)) printf("|kHFSVolumeSparedBlocksBit");
	if(attributes&(1<<10)) printf("|kHFSVolumeNoCacheRequiredBit");
	if(attributes&(1<<11)) printf("|kHFSBootVolumeInconsistentBit");
	if(attributes&(1<<12)) printf("|kHFSCatalogNodeIDsReusedBit");
	if(attributes&(1<<13)) printf("|kHFSVolumeJournaledBit");
	if(attributes&(1<<15)) printf("|kHFSVolumeSoftwareLockBit");
	printf("\nlast mounted version '%c%c%c%c', ", buffer[8], buffer[9], buffer[10], buffer[11]);
	printf("journalInfoBlock %08x\n", readu32(buffer + 12));
	printf("createDate %08x, ", readu32(buffer + 16));
	printf("modifyDate %08x\n", readu32(buffer + 20));
	printf("backupDate %08x, ", readu32(buffer + 24));
	printf("checkedDate %08x\n", readu32(buffer + 28));
	printf("file count %u, ", readu32(buffer + 32));
	printf("folder count %u\n", readu32(buffer + 36));
	bsize = readu32(buffer + 40);
	block_size = bsize;
	bcount = readu32(buffer + 44);
	printf("block size %u, ", bsize);
	printf("total blocks %u (total %u bytes)\n",
		bcount, bsize * bcount);
	if(bsize * bcount != hfs_part_sector_count * SECTOR_SIZE)
		fprintf(stderr, "*** Partion size inconsistency with Partition Map ***\n");
	printf("free blocks %u, ", readu32(buffer + 48));
	printf("next catalog id %u\n", readu32(buffer + 64));
	for(i = 0; i < 8; i++) {
		printf("finderInfo[%d] = %08x", i, readu32(buffer + 80 + i * 4));
		if(i==2) printf(" directory ID auto Finder display");
		putchar('\n');
	}
	/* 80 + 8*4 = 112 */
	/* struct HFSPlusForkData {
    UInt64                  logicalSize;
    UInt32                  clumpSize;
    UInt32                  totalBlocks;
    HFSPlusExtentRecord     extents;
};
	8 + 4 + 4 + 8 * 8 = 16 + 64 = 80
	typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[8];
	struct HFSPlusExtentDescriptor {
    UInt32                  startBlock;
    UInt32                  blockCount;
};
 */
	/* HFSPlusForkData     allocationFile;
    HFSPlusForkData     extentsFile;
    HFSPlusForkData     catalogFile;
    HFSPlusForkData     attributesFile;
    HFSPlusForkData     startupFile;*/
	printf("catalogFile:\n");
	//hexdump(buffer+112+80*2, 80, 0);
	catalog_start_block = readu32(buffer+112+80*2+16);
	catalog_block_count = readu32(buffer+112+80*2+20);
	printf("  startBlock = %08x (%u)", catalog_start_block, catalog_start_block);
	printf("\toffset 0x%08x\n", catalog_start_block * block_size);
	printf("  blockCount = %08x (%u)", catalog_block_count, catalog_block_count);
	printf("\tsize = %u bytes\n", catalog_block_count * block_size);
	return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x400, %rsp            # imm = 0x400
movq %rdi, %r14
movl 0x4818(%rip), %esi      # 0x60c4
shll $0x9, %esi
addl $0x400, %esi            # imm = 0x400
xorl %ebx, %ebx
xorl %edx, %edx
callq 0x1100
testl %eax, %eax
jne 0x1cd3
movq %rsp, %rdi
pushq $0x1
popq %rsi
movl $0x200, %edx            # imm = 0x200
movq %r14, %rcx
callq 0x1070
cmpq $0x200, %rax            # imm = 0x200
jne 0x1ce1
movl 0x47d9(%rip), %esi      # 0x60c4
shll $0x9, %esi
addl $0x400, %esi            # imm = 0x400
leaq 0x1985(%rip), %rdi      # 0x3280
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x1090
movzbl (%rsp), %ebp
movzbl 0x1(%rsp), %r15d
movzbl 0x2(%rsp), %ecx
movzbl 0x3(%rsp), %r8d
leaq 0x1925(%rip), %rdi      # 0x3245
movl %ebp, %esi
movl %r15d, %edx
xorl %eax, %eax
callq 0x1090
xorb $0x48, %bpl
xorb $0x2b, %r15b
orb %bpl, %r15b
je 0x194a
leaq 0x18cf(%rip), %rdi      # 0x320f
callq 0x1060
jmp 0x1cc1
movl 0x4778(%rip), %esi      # 0x60c8
addl 0x476e(%rip), %esi      # 0x60c4
shll $0x9, %esi
addl $0xfffffc00, %esi       # imm = 0xFFFFFC00
xorl %ebx, %ebx
movq %r14, %rdi
xorl %edx, %edx
callq 0x1100
testl %eax, %eax
jne 0x1cd3
leaq 0x200(%rsp), %rdi
pushq $0x1
popq %rsi
movl $0x200, %edx            # imm = 0x200
movq %r14, %rcx
callq 0x1070
cmpq $0x200, %rax            # imm = 0x200
jne 0x1ce1
movl 0x472b(%rip), %esi      # 0x60c8
addl 0x4721(%rip), %esi      # 0x60c4
shll $0x9, %esi
addl $0xfffffc00, %esi       # imm = 0xFFFFFC00
leaq 0x18c3(%rip), %rdi      # 0x3276
xorl %eax, %eax
callq 0x1090
movq %rsp, %rdi
leaq 0x200(%rsp), %rsi
movl $0x200, %edx            # imm = 0x200
callq 0x10f0
testl %eax, %eax
je 0x19fa
leaq 0x20b9(%rip), %rdi      # 0x3a93
callq 0x1060
movq %rsp, %rdi
leaq 0x200(%rsp), %rsi
pushq $0x14
popq %rdx
callq 0x10f0
testl %eax, %eax
jne 0x1d20
movq %rsp, %rbx
movq %rbx, %rdi
movl $0x80, %esi
xorl %edx, %edx
callq 0x179c
movl 0x4(%rbx), %eax
shll $0x18, %eax
movzbl 0x5(%rbx), %ecx
shll $0x10, %ecx
orl %eax, %ecx
movzbl 0x6(%rbx), %ebp
movl %ebp, %eax
shll $0x8, %eax
movzbl 0x7(%rbx), %esi
orl %ecx, %esi
orl %eax, %esi
leaq 0x18ad(%rip), %rdi      # 0x32e0
xorl %eax, %eax
callq 0x1090
testb $0x1, %bpl
je 0x1a4e
leaq 0x18ac(%rip), %rdi      # 0x32f3
xorl %eax, %eax
callq 0x1090
testb $0x2, %bpl
je 0x1a62
leaq 0x18b0(%rip), %rdi      # 0x330b
xorl %eax, %eax
callq 0x1090
testb $0x4, %bpl
je 0x1a76
leaq 0x18b7(%rip), %rdi      # 0x3326
xorl %eax, %eax
callq 0x1090
testb $0x8, %bpl
je 0x1a8a
leaq 0x18c1(%rip), %rdi      # 0x3344
xorl %eax, %eax
callq 0x1090
testb $0x10, %bpl
je 0x1a9e
leaq 0x18cc(%rip), %rdi      # 0x3363
xorl %eax, %eax
callq 0x1090
testb $0x20, %bpl
je 0x1ab2
leaq 0x18d5(%rip), %rdi      # 0x3380
xorl %eax, %eax
callq 0x1090
testb %bpl, %bpl
jns 0x1ac5
leaq 0x18da(%rip), %rdi      # 0x3398
xorl %eax, %eax
callq 0x1090
movzbl 0x8(%rsp), %esi
movzbl 0x9(%rsp), %edx
movzbl 0xa(%rsp), %ecx
movzbl 0xb(%rsp), %r8d
leaq 0x18d2(%rip), %rdi      # 0x33b3
xorl %eax, %eax
callq 0x1090
movl 0xc(%rsp), %esi
bswapl %esi
leaq 0x18e1(%rip), %rdi      # 0x33d6
xorl %eax, %eax
callq 0x1090
movl 0x10(%rsp), %esi
bswapl %esi
leaq 0x18e4(%rip), %rdi      # 0x33ed
xorl %eax, %eax
callq 0x1090
movl 0x14(%rsp), %esi
bswapl %esi
leaq 0x18e2(%rip), %rdi      # 0x33ff
xorl %eax, %eax
callq 0x1090
movl 0x18(%rsp), %esi
bswapl %esi
leaq 0x18df(%rip), %rdi      # 0x3410
xorl %eax, %eax
callq 0x1090
movl 0x1c(%rsp), %esi
bswapl %esi
leaq 0x18dd(%rip), %rdi      # 0x3422
xorl %eax, %eax
callq 0x1090
movl 0x20(%rsp), %esi
bswapl %esi
leaq 0x18db(%rip), %rdi      # 0x3434
xorl %eax, %eax
callq 0x1090
movl 0x24(%rsp), %esi
bswapl %esi
leaq 0x18d7(%rip), %rdi      # 0x3444
xorl %eax, %eax
callq 0x1090
movl 0x28(%rsp), %ebx
movl 0x2c(%rsp), %ebp
bswapl %ebx
movl %ebx, 0x4548(%rip)      # 0x60cc
bswapl %ebp
leaq 0x18c8(%rip), %rdi      # 0x3455
movl %ebx, %esi
xorl %eax, %eax
callq 0x1090
imull %ebp, %ebx
leaq 0x18c5(%rip), %rdi      # 0x3465
movl %ebp, %esi
movl %ebx, %edx
xorl %eax, %eax
callq 0x1090
movl 0x4517(%rip), %eax      # 0x60c8
shll $0x9, %eax
cmpl %eax, %ebx
jne 0x1cff
leaq 0x50(%rsp), %rbx
movl -0x20(%rbx), %esi
bswapl %esi
leaq 0x18f1(%rip), %rdi      # 0x34be
xorl %eax, %eax
callq 0x1090
movl -0x10(%rbx), %esi
bswapl %esi
leaq 0x18ef(%rip), %rdi      # 0x34cf
xorl %eax, %eax
callq 0x1090
leaq 0x18f5(%rip), %r14      # 0x34e3
leaq 0x1904(%rip), %r15      # 0x34f9
pushq $0xa
popq %rbp
xorl %r12d, %r12d
cmpq $0x8, %r12
je 0x1c38
movq %rbx, %rdi
callq 0x188f
movq %r14, %rdi
movl %r12d, %esi
movl %eax, %edx
xorl %eax, %eax
callq 0x1090
cmpq $0x2, %r12
jne 0x1c28
movq %r15, %rdi
xorl %eax, %eax
callq 0x1090
movl %ebp, %edi
callq 0x1040
incq %r12
addq $0x4, %rbx
jmp 0x1bfb
leaq 0x1e86(%rip), %rdi      # 0x3ac5
callq 0x1060
movl 0x120(%rsp), %edx
movl 0x124(%rsp), %eax
bswapl %edx
movl %edx, 0x4476(%rip)      # 0x60d0
bswapl %eax
movl %eax, 0x4472(%rip)      # 0x60d4
leaq 0x18b2(%rip), %rdi      # 0x351b
movl %edx, %esi
xorl %eax, %eax
callq 0x1090
movl 0x4454(%rip), %esi      # 0x60cc
imull 0x4451(%rip), %esi      # 0x60d0
leaq 0x18ae(%rip), %rdi      # 0x3534
xorl %eax, %eax
callq 0x1090
movl 0x4441(%rip), %edx      # 0x60d4
leaq 0x18aa(%rip), %rdi      # 0x3544
movl %edx, %esi
xorl %eax, %eax
callq 0x1090
movl 0x4423(%rip), %esi      # 0x60cc
imull 0x4424(%rip), %esi      # 0x60d4
leaq 0x18a6(%rip), %rdi      # 0x355d
xorl %eax, %eax
callq 0x1090
pushq $0x1
popq %rbx
movl %ebx, %eax
addq $0x400, %rsp            # imm = 0x400
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x132a(%rip), %rdi      # 0x3004
callq 0x1120
jmp 0x1cc1
movq 0x4310(%rip), %rax      # 0x5ff8
movq (%rax), %rcx
leaq 0x1318(%rip), %rdi      # 0x300a
pushq $0xe
popq %rsi
pushq $0x1
popq %rdx
callq 0x1140
jmp 0x1cc1
movq 0x42f2(%rip), %rax      # 0x5ff8
movq (%rax), %rcx
leaq 0x1777(%rip), %rdi      # 0x3487
pushq $0x36
popq %rsi
pushq $0x1
popq %rdx
callq 0x1140
jmp 0x1bbc
movq 0x42d1(%rip), %rax      # 0x5ff8
movq (%rax), %rcx
leaq 0x156c(%rip), %rdi      # 0x329d
pushq $0x42
popq %rsi
pushq $0x1
popq %rdx
callq 0x1140
leaq 0x1d8f(%rip), %rdi      # 0x3ad2
callq 0x1060
movq %rsp, %rdi
pushq $0x20
popq %rbp
xorl %ebx, %ebx
movl %ebp, %esi
xorl %edx, %edx
callq 0x179c
leaq 0x1d78(%rip), %rdi      # 0x3ad8
callq 0x1060
leaq 0x200(%rsp), %rdi
movl %ebp, %esi
xorl %edx, %edx
callq 0x179c
jmp 0x1cc1