// File: /workspace/github_c_makefile_star2_O1/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 %rbx
subq $0x408, %rsp            # imm = 0x408
movq %rdi, %r14
movl 0x4596(%rip), %esi      # 0x60c4
shll $0x9, %esi
addl $0x400, %esi            # imm = 0x400
xorl %ebx, %ebx
xorl %edx, %edx
callq 0x1100
testl %eax, %eax
jne 0x1f65
movq %rsp, %rdi
movl $0x1, %esi
movl $0x200, %edx            # imm = 0x200
movq %r14, %rcx
callq 0x1070
cmpq $0x200, %rax            # imm = 0x200
jne 0x1f73
movl 0x4555(%rip), %esi      # 0x60c4
shll $0x9, %esi
addl $0x400, %esi            # imm = 0x400
leaq 0x1701(%rip), %rdi      # 0x3280
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x1090
movzbl (%rsp), %esi
movzbl 0x1(%rsp), %edx
movzbl 0x2(%rsp), %ecx
movzbl 0x3(%rsp), %r8d
leaq 0x16a2(%rip), %rdi      # 0x3245
xorl %eax, %eax
callq 0x1090
cmpb $0x48, (%rsp)
jne 0x1f49
cmpb $0x2b, 0x1(%rsp)
jne 0x1f49
movl 0x4503(%rip), %esi      # 0x60c8
addl 0x44f9(%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 0x1f65
leaq 0x200(%rsp), %rdi
movl $0x1, %esi
movl $0x200, %edx            # imm = 0x200
movq %r14, %rcx
callq 0x1070
cmpq $0x200, %rax            # imm = 0x200
jne 0x1f7a
movl 0x44b4(%rip), %esi      # 0x60c8
addl 0x44aa(%rip), %esi      # 0x60c4
shll $0x9, %esi
addl $0xfffffc00, %esi       # imm = 0xFFFFFC00
leaq 0x164c(%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 0x1c8a
leaq 0x1e42(%rip), %rdi      # 0x3a93
callq 0x1060
movdqa (%rsp), %xmm0
movd 0x10(%rsp), %xmm1
movd 0x210(%rsp), %xmm2
pcmpeqb 0x200(%rsp), %xmm0
pcmpeqb %xmm1, %xmm2
pand %xmm2, %xmm0
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x1f8b
movq %rsp, %rbx
movq %rbx, %rdi
movl $0x80, %esi
xorl %edx, %edx
callq 0x19e8
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 0x161d(%rip), %rdi      # 0x32e0
xorl %eax, %eax
callq 0x1090
testb $0x1, %bpl
je 0x1cde
leaq 0x161c(%rip), %rdi      # 0x32f3
xorl %eax, %eax
callq 0x1090
testb $0x2, %bpl
je 0x1cf2
leaq 0x1620(%rip), %rdi      # 0x330b
xorl %eax, %eax
callq 0x1090
testb $0x4, %bpl
je 0x1d06
leaq 0x1627(%rip), %rdi      # 0x3326
xorl %eax, %eax
callq 0x1090
testb $0x8, %bpl
je 0x1d1a
leaq 0x1631(%rip), %rdi      # 0x3344
xorl %eax, %eax
callq 0x1090
testb $0x10, %bpl
je 0x1d2e
leaq 0x163c(%rip), %rdi      # 0x3363
xorl %eax, %eax
callq 0x1090
testb $0x20, %bpl
je 0x1d42
leaq 0x1645(%rip), %rdi      # 0x3380
xorl %eax, %eax
callq 0x1090
testb %bpl, %bpl
jns 0x1d55
leaq 0x164a(%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 0x1642(%rip), %rdi      # 0x33b3
xorl %eax, %eax
callq 0x1090
movl 0xc(%rsp), %esi
bswapl %esi
leaq 0x1651(%rip), %rdi      # 0x33d6
xorl %eax, %eax
callq 0x1090
movl 0x10(%rsp), %esi
bswapl %esi
leaq 0x1654(%rip), %rdi      # 0x33ed
xorl %eax, %eax
callq 0x1090
movl 0x14(%rsp), %esi
bswapl %esi
leaq 0x1652(%rip), %rdi      # 0x33ff
xorl %eax, %eax
callq 0x1090
movl 0x18(%rsp), %esi
bswapl %esi
leaq 0x164f(%rip), %rdi      # 0x3410
xorl %eax, %eax
callq 0x1090
movl 0x1c(%rsp), %esi
bswapl %esi
leaq 0x164d(%rip), %rdi      # 0x3422
xorl %eax, %eax
callq 0x1090
movl 0x20(%rsp), %esi
bswapl %esi
leaq 0x164b(%rip), %rdi      # 0x3434
xorl %eax, %eax
callq 0x1090
movl 0x24(%rsp), %esi
bswapl %esi
leaq 0x1647(%rip), %rdi      # 0x3444
xorl %eax, %eax
callq 0x1090
movl 0x28(%rsp), %ebx
movl 0x2c(%rsp), %ebp
bswapl %ebx
movl %ebx, 0x42b8(%rip)      # 0x60cc
bswapl %ebp
leaq 0x1638(%rip), %rdi      # 0x3455
movl %ebx, %esi
xorl %eax, %eax
callq 0x1090
imull %ebp, %ebx
leaq 0x1635(%rip), %rdi      # 0x3465
movl %ebp, %esi
movl %ebx, %edx
xorl %eax, %eax
callq 0x1090
movl 0x4287(%rip), %eax      # 0x60c8
shll $0x9, %eax
cmpl %eax, %ebx
jne 0x1f81
movl 0x30(%rsp), %esi
bswapl %esi
leaq 0x1665(%rip), %rdi      # 0x34be
xorl %eax, %eax
callq 0x1090
movl 0x40(%rsp), %esi
bswapl %esi
leaq 0x1662(%rip), %rdi      # 0x34cf
xorl %eax, %eax
callq 0x1090
leaq 0x1668(%rip), %rbx      # 0x34e3
leaq 0x1677(%rip), %r14      # 0x34f9
xorl %r15d, %r15d
movl 0x50(%rsp,%r15,4), %edx
bswapl %edx
movq %rbx, %rdi
movl %r15d, %esi
xorl %eax, %eax
callq 0x1090
cmpq $0x2, %r15
jne 0x1ea9
movq %r14, %rdi
xorl %eax, %eax
callq 0x1090
movl $0xa, %edi
callq 0x1040
incq %r15
cmpq $0x8, %r15
jne 0x1e85
leaq 0x1c02(%rip), %rdi      # 0x3ac5
callq 0x1060
movl 0x120(%rsp), %edx
movl 0x124(%rsp), %eax
bswapl %edx
movl %edx, 0x41f2(%rip)      # 0x60d0
bswapl %eax
movl %eax, 0x41ee(%rip)      # 0x60d4
leaq 0x162e(%rip), %rdi      # 0x351b
movl %edx, %esi
xorl %eax, %eax
callq 0x1090
movl 0x41d0(%rip), %esi      # 0x60cc
imull 0x41cd(%rip), %esi      # 0x60d0
leaq 0x162a(%rip), %rdi      # 0x3534
xorl %eax, %eax
callq 0x1090
movl 0x41bd(%rip), %edx      # 0x60d4
leaq 0x1626(%rip), %rdi      # 0x3544
movl %edx, %esi
xorl %eax, %eax
callq 0x1090
movl 0x419f(%rip), %esi      # 0x60cc
imull 0x41a0(%rip), %esi      # 0x60d4
leaq 0x1622(%rip), %rdi      # 0x355d
xorl %eax, %eax
callq 0x1090
movl $0x1, %ebx
jmp 0x1f55
leaq 0x12bf(%rip), %rdi      # 0x320f
callq 0x1060
movl %ebx, %eax
addq $0x408, %rsp            # imm = 0x408
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1098(%rip), %rdi      # 0x3004
callq 0x1120
jmp 0x1f55
callq 0x12c5
jmp 0x1f55
callq 0x12e1
jmp 0x1f55
callq 0x135b
jmp 0x1e4c
movq %rsp, %rdi
leaq 0x200(%rsp), %rsi
callq 0x12fd
xorl %ebx, %ebx
jmp 0x1f55