// File: /workspace/github_c_makefile_star2_O0/inflex[P]ripMIME/ripOLE/ole.c
// Function: OLE_load_FAT
int OLE_load_FAT( struct OLE_object *ole )
{
	unsigned int FAT_size;

	FAT_size = ole->header.fat_sector_count << ole->header.sector_shift;
	DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG:Allocating for %d sectors (%d bytes) \n"
			,FL,ole->header.fat_sector_count, FAT_size);

	ole->FAT = malloc( FAT_size *sizeof(unsigned char));
	ole->FAT_limit = ole->FAT +FAT_size;
	if (ole->FAT != NULL)
	{
		unsigned int i;
		unsigned char *fat_position = ole->FAT;
		unsigned int sector_count = ole->header.fat_sector_count;

		if (sector_count > OLE_HEADER_FAT_SECTOR_COUNT_LIMIT)
		{
			sector_count = OLE_HEADER_FAT_SECTOR_COUNT_LIMIT;
			DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: sector count greater than limit; set to %d",FL, sector_count);
		}

		// Load in all our primary-FAT sectors from the OLE file
		for (i = 0; i < sector_count; i++)
		{
			int getblock_result = 0;

			DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Loading sector %d",FL, i);
			getblock_result = OLE_get_block(ole, ole->header.FAT[i], fat_position);
			if (getblock_result != 0)
			{
				// if the get block fails, return the error - but keep the FAT
				//		pointer alive - so that we can facilitate debugging
				//		otherwise the caller is always going to get a NULL pointer
				//		and have no idea to what extent the data was read.
				//
				// This behavior may be changed later - but for now (beta development)
				//		it'll be okay to leave it here - just make sure we know to
				//		free the FAT block later.

				return getblock_result;
			}

			fat_position += ole->header.sector_size;
			if (fat_position > ole->FAT_limit)
			{ 
				LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: FAT boundary limit exceeded %p > %p", FL, fat_position, ole->FAT_limit); 
				return -1;
			}
		}

		// If our DIF count is > 0, this means we have a pretty big
		//		file on hand (> 7Mb) and thus we now have to do some
		//		fancy double-dereferenced sector request - enough to 
		//		twist your brain if you're not alert, you have been
		//		warned.

		if (ole->header.dif_sector_count > 0)
		{
			unsigned char *fat_block;
			unsigned char *fat_block_end;
			unsigned int current_sector = ole->header.dif_start_sector;

			DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Allocating %d bytes to fat_block\n",FL, ole->header.sector_size);

			fat_block = malloc( ole->header.sector_size );

			if (fat_block == NULL) 
			{
				LOGGER_log("%s:%d:OLE_load_FAT:ERROR: Unable to allocate %d bytes\n", FL, ole->header.sector_size);
				return -1;
				//			exit(1);
			}

			// We need to know where the end of this block is - because it's
			//		used to show us where the NEXT FAT block is going to come from
			//		NOTE - this only occurs if we do have another block, else 
			//		we'll simply have to just realise that we don't need any more
			//		blocks and stop with this one.

			fat_block_end = fat_block +ole->header.sector_size -LEN_ULONG;

			// We know we've got 'dif_sector_count' blocks to read, each of
			//		these blocks hold no more than 127 sector addresses which
			//		contain the actual FAT data we're after (this is the double
			//		dereference bit that twists your brain )

			DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Loading DIF sectors (count = %d)",FL,ole->header.dif_sector_count);

			for (i = 0; i < ole->header.dif_sector_count; i++)
			{
				int import_sector;
				unsigned char *DIF = fat_block;
				int tick = 0;
				int getblock_result;

				DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Reading DIF/XBAT index-data[%d] from sector 0x%x",FL,i,current_sector);
				getblock_result = OLE_get_block(ole, current_sector, fat_block);
				if (getblock_result != OLE_OK)
				{
					if (fat_block) free(fat_block);
					return getblock_result;
				}

				if (OLE_DPEDANTIC(ole->debug)) OLE_print_sector(ole, (char *)fat_block, ole->header.sector_size);

				// Now, traverse this block until we hit a < 0
				//		If we get what is a non-valid sector value
				//		we know we've reached the end of the valid
				//		sectors from which to read more extended FAT
				//		data.

				do {
					import_sector = get_int32( (char *) DIF );
					DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: import sector = 0x%x",FL,import_sector);
					if (import_sector >= 0)
					{
						if (fat_position +ole->header.sector_size <= ole->FAT_limit)
						{
							DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Reading DIF/XBAT-data[%d] from sector 0x%x",FL,tick,import_sector);
							getblock_result = OLE_get_block(ole, import_sector, fat_position);
							if (getblock_result != OLE_OK)
							{
								LOGGER_log("%s:%d:OLE_load_FAT:ERROR: Not able to load block, import sector = 0x%x, fat position = 0x%x",FL, import_sector, fat_position);
								if (fat_block) free(fat_block);
								return getblock_result;
							}

							fat_position += ole->header.sector_size;
							DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: FAT position = 0x%x (start = 0x%x, end = 0x%x)"
									,FL
									,fat_position
									,fat_block
									,ole->FAT_limit
									);

							//if (fat_position +ole->header.sector_size > ole->FAT_limit)
							if (fat_position > ole->FAT_limit)
							{ 
								DOLE LOGGER_log("%s:%d:OLE_load_FAT:ERROR: FAT memory boundary limit exceeded %p >= %p",FL,fat_position,ole->FAT_limit); 
								if (fat_block) free(fat_block);
								return OLEER_MEMORY_OVERFLOW;
							}
							tick++;
							DIF += LEN_ULONG;
						}  else {
							LOGGER_log("%s:%d:OLE_load_FAT:ERROR: FAT memory boundary limit exceeded %p >= %p",FL,fat_position,ole->FAT_limit); 
							if (fat_block) free(fat_block);
							return OLEER_MEMORY_OVERFLOW;
						}
					} else {
						VOLE LOGGER_log("%s:%d:OLE_load_FAT:ERROR: sector request was negative (%d)",FL, import_sector);
					}

					DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: DIF = 0x%x",FL,DIF);
				} while ((import_sector >= 0)&&(DIF < fat_block_end));

				// Get the next sector of DIF/XBAT data ...
				//
				// If we still have more sectors full of extended FAT
				//		sectors that we have to read, then we neet to
				//		obtain the address of the next FAT-sector filled
				//		sector

				if ( i < ole->header.dif_sector_count -1 )
				{
					current_sector = get_uint32((char *) fat_block_end );
					DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Next DIF/XBAT index sector located at 0x%x",FL,current_sector);
					if (current_sector < 0) break;
				}
			} // For every DIF/XBAT sector we're supposed to read

			if (fat_block) free(fat_block);
		} // If we have DIF/XBAT sectors to read into the FAT

	} // If we managed to allocate memory for our FAT table

	return OLE_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl 0x274(%rax), %eax
movq -0x10(%rbp), %rcx
movl 0x264(%rcx), %ecx
shll %cl, %eax
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x1580a
movq -0x10(%rbp), %rax
movl 0x274(%rax), %ecx
movl -0x14(%rbp), %r8d
leaq 0xa92a(%rip), %rdi      # 0x20121
leaq 0xa44d(%rip), %rsi      # 0x1fc4b
movl $0x38c, %edx            # imm = 0x38C
movb $0x0, %al
callq 0x117c0
movl -0x14(%rbp), %eax
movl %eax, %edi
shlq $0x0, %rdi
callq 0x2290
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rcx
movl -0x14(%rbp), %eax
addq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x28(%rax)
je 0x15de7
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movl 0x274(%rax), %eax
movl %eax, -0x24(%rbp)
cmpl $0x6d, -0x24(%rbp)
jbe 0x1589a
movl $0x6d, -0x24(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x15898
movl -0x24(%rbp), %ecx
leaq 0xa8dc(%rip), %rdi      # 0x20161
leaq 0xa3bf(%rip), %rsi      # 0x1fc4b
movl $0x399, %edx            # imm = 0x399
movb $0x0, %al
callq 0x117c0
jmp 0x1589a
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x24(%rbp), %eax
jae 0x15974
movl $0x0, -0x28(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x158de
movl -0x18(%rbp), %ecx
leaq 0xa8db(%rip), %rdi      # 0x201a6
leaq 0xa379(%rip), %rsi      # 0x1fc4b
movl $0x3a1, %edx            # imm = 0x3A1
movb $0x0, %al
callq 0x117c0
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movl -0x18(%rbp), %ecx
movl 0x290(%rax,%rcx,4), %esi
movq -0x20(%rbp), %rdx
callq 0x14ae0
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
je 0x1590d
movl -0x28(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x15dee
movq -0x10(%rbp), %rax
movl 0x268(%rax), %ecx
movq -0x20(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jbe 0x15964
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %r8
leaq 0xa88d(%rip), %rdi      # 0x201d2
leaq 0xa2ff(%rip), %rsi      # 0x1fc4b
movl $0x3b4, %edx            # imm = 0x3B4
movb $0x0, %al
callq 0x117c0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x15dee
jmp 0x15966
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x158a1
movq -0x10(%rbp), %rax
cmpl $0x0, 0x28c(%rax)
jbe 0x15de5
movq -0x10(%rbp), %rax
movl 0x288(%rax), %eax
movl %eax, -0x3c(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x159c3
movq -0x10(%rbp), %rax
movl 0x268(%rax), %ecx
leaq 0xa860(%rip), %rdi      # 0x20210
leaq 0xa294(%rip), %rsi      # 0x1fc4b
movl $0x3c5, %edx            # imm = 0x3C5
movb $0x0, %al
callq 0x117c0
movq -0x10(%rbp), %rax
movl 0x268(%rax), %eax
movl %eax, %edi
callq 0x2290
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x15a0f
movq -0x10(%rbp), %rax
movl 0x268(%rax), %ecx
leaq 0xa85c(%rip), %rdi      # 0x2024c
leaq 0xa254(%rip), %rsi      # 0x1fc4b
movl $0x3cb, %edx            # imm = 0x3CB
movb $0x0, %al
callq 0x117c0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x15dee
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
movl 0x268(%rcx), %ecx
addq %rcx, %rax
addq $-0x4, %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x15a59
movq -0x10(%rbp), %rax
movl 0x28c(%rax), %ecx
leaq 0xa83d(%rip), %rdi      # 0x20283
leaq 0xa1fe(%rip), %rsi      # 0x1fc4b
movl $0x3dd, %edx            # imm = 0x3DD
movb $0x0, %al
callq 0x117c0
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x28c(%rcx), %eax
jae 0x15dd3
movq -0x30(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x15ab0
movl -0x18(%rbp), %ecx
movl -0x3c(%rbp), %r8d
leaq 0xa821(%rip), %rdi      # 0x202be
leaq 0xa1a7(%rip), %rsi      # 0x1fc4b
movl $0x3e6, %edx            # imm = 0x3E6
movb $0x0, %al
callq 0x117c0
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %esi
movq -0x30(%rbp), %rdx
callq 0x14ae0
movl %eax, -0x50(%rbp)
cmpl $0x0, -0x50(%rbp)
je 0x15ae4
cmpq $0x0, -0x30(%rbp)
je 0x15ad9
movq -0x30(%rbp), %rdi
callq 0x2030
movl -0x50(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x15dee
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x15b08
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x10(%rbp), %rax
movl 0x268(%rax), %edx
callq 0x14ff0
jmp 0x15b0a
movq -0x48(%rbp), %rdi
callq 0x181a0
movl %eax, -0x40(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x15b40
movl -0x40(%rbp), %ecx
leaq 0xa7dc(%rip), %rdi      # 0x20309
leaq 0xa117(%rip), %rsi      # 0x1fc4b
movl $0x3f8, %edx            # imm = 0x3F8
movb $0x0, %al
callq 0x117c0
cmpl $0x0, -0x40(%rbp)
jl 0x15cf2
movq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
movl 0x268(%rcx), %ecx
addq %rcx, %rax
movq -0x10(%rbp), %rcx
cmpq 0x30(%rcx), %rax
ja 0x15cae
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x15b97
movl -0x4c(%rbp), %ecx
movl -0x40(%rbp), %r8d
leaq 0xa7b4(%rip), %rdi      # 0x20338
leaq 0xa0c0(%rip), %rsi      # 0x1fc4b
movl $0x3fd, %edx            # imm = 0x3FD
movb $0x0, %al
callq 0x117c0
movq -0x10(%rbp), %rdi
movl -0x40(%rbp), %esi
movq -0x20(%rbp), %rdx
callq 0x14ae0
movl %eax, -0x50(%rbp)
cmpl $0x0, -0x50(%rbp)
je 0x15bec
movl -0x40(%rbp), %ecx
movq -0x20(%rbp), %r8
leaq 0xa7bf(%rip), %rdi      # 0x2037d
leaq 0xa086(%rip), %rsi      # 0x1fc4b
movl $0x401, %edx            # imm = 0x401
movb $0x0, %al
callq 0x117c0
cmpq $0x0, -0x30(%rbp)
je 0x15be1
movq -0x30(%rbp), %rdi
callq 0x2030
movl -0x50(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x15dee
movq -0x10(%rbp), %rax
movl 0x268(%rax), %ecx
movq -0x20(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x15c3a
movq -0x20(%rbp), %rcx
movq -0x30(%rbp), %r8
movq -0x10(%rbp), %rax
movq 0x30(%rax), %r9
leaq 0xa7b2(%rip), %rdi      # 0x203d9
leaq 0xa01d(%rip), %rsi      # 0x1fc4b
movl $0x408, %edx            # imm = 0x408
movb $0x0, %al
callq 0x117c0
movq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jbe 0x15c97
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x15c7b
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %r8
leaq 0xa7ba(%rip), %rdi      # 0x20422
leaq 0x9fdc(%rip), %rsi      # 0x1fc4b
movl $0x411, %edx            # imm = 0x411
movb $0x0, %al
callq 0x117c0
cmpq $0x0, -0x30(%rbp)
je 0x15c8b
movq -0x30(%rbp), %rdi
callq 0x2030
movl $0x32, -0x4(%rbp)
jmp 0x15dee
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
movq -0x48(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x48(%rbp)
jmp 0x15cf0
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %r8
leaq 0xa761(%rip), %rdi      # 0x20422
leaq 0x9f83(%rip), %rsi      # 0x1fc4b
movl $0x418, %edx            # imm = 0x418
movb $0x0, %al
callq 0x117c0
cmpq $0x0, -0x30(%rbp)
je 0x15ce4
movq -0x30(%rbp), %rdi
callq 0x2030
movl $0x32, -0x4(%rbp)
jmp 0x15dee
jmp 0x15d1e
movq -0x10(%rbp), %rax
cmpl $0x0, 0x448(%rax)
je 0x15d1c
movl -0x40(%rbp), %ecx
leaq 0xa75f(%rip), %rdi      # 0x20468
leaq 0x9f3b(%rip), %rsi      # 0x1fc4b
movl $0x41d, %edx            # imm = 0x41D
movb $0x0, %al
callq 0x117c0
jmp 0x15d1e
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x15d49
movq -0x48(%rbp), %rcx
leaq 0xa76d(%rip), %rdi      # 0x204a3
leaq 0x9f0e(%rip), %rsi      # 0x1fc4b
movl $0x420, %edx            # imm = 0x420
movb $0x0, %al
callq 0x117c0
jmp 0x15d4b
xorl %eax, %eax
cmpl $0x0, -0x40(%rbp)
movb %al, -0x51(%rbp)
jl 0x15d64
movq -0x48(%rbp), %rax
cmpq -0x38(%rbp), %rax
setb %al
movb %al, -0x51(%rbp)
movb -0x51(%rbp), %al
testb $0x1, %al
jne 0x15b0a
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
movl 0x28c(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jae 0x15dc3
movq -0x38(%rbp), %rdi
callq 0x181f0
movl %eax, -0x3c(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x444(%rax)
je 0x15db9
movl -0x3c(%rbp), %ecx
leaq 0xa722(%rip), %rdi      # 0x204c8
leaq 0x9e9e(%rip), %rsi      # 0x1fc4b
movl $0x42d, %edx            # imm = 0x42D
movb $0x0, %al
callq 0x117c0
cmpl $0x0, -0x3c(%rbp)
jae 0x15dc1
jmp 0x15dd3
jmp 0x15dc3
jmp 0x15dc5
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x15a60
cmpq $0x0, -0x30(%rbp)
je 0x15de3
movq -0x30(%rbp), %rdi
callq 0x2030
jmp 0x15de5
jmp 0x15de7
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nopw (%rax,%rax)