// File: /workspace/github_c_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %r14
movl 0x274(%rdi), %eax
movb 0x264(%rdi), %cl
movl %eax, %ebx
shll %cl, %ebx
cmpl $0x0, 0x444(%rdi)
je 0xeb24
leaq 0x9803(%rip), %rdi      # 0x1830f
leaq 0x9326(%rip), %rsi      # 0x17e39
movl $0x38c, %edx            # imm = 0x38C
movl %eax, %ecx
movl %ebx, %r8d
xorl %eax, %eax
callq 0xc2a1
movl %ebx, %r15d
movq %r15, %rdi
callq 0x22a0
movq %rax, 0x28(%r14)
addq %rax, %r15
movq %r15, 0x30(%r14)
testq %rax, %rax
je 0xef60
movq %rax, %rbx
movl 0x274(%r14), %ebp
cmpl $0x6e, %ebp
jb 0xeb80
cmpl $0x0, 0x444(%r14)
je 0xeb7d
leaq 0x97ec(%rip), %rdi      # 0x1834f
leaq 0x92cf(%rip), %rsi      # 0x17e39
pushq $0x6d
popq %rbp
movl $0x399, %edx            # imm = 0x399
movl %ebp, %ecx
xorl %eax, %eax
callq 0xc2a1
jmp 0xeb80
pushq $0x6d
popq %rbp
movl %ebp, %r15d
leaq 0x92af(%rip), %r12      # 0x17e39
xorl %ebp, %ebp
cmpq %rbp, %r15
je 0xec0a
cmpl $0x0, 0x444(%r14)
je 0xebb3
leaq 0x97f2(%rip), %rdi      # 0x18394
movq %r12, %rsi
movl $0x3a1, %edx            # imm = 0x3A1
movl %ebp, %ecx
xorl %eax, %eax
callq 0xc2a1
movl 0x290(%r14,%rbp,4), %esi
movq %r14, %rdi
movq %rbx, %rdx
callq 0xe24a
testl %eax, %eax
jne 0xeeb2
movl 0x268(%r14), %eax
addq %rax, %rbx
movq 0x30(%r14), %r8
incq %rbp
cmpq %r8, %rbx
jbe 0xeb8c
leaq 0x97d5(%rip), %rdi      # 0x183c0
leaq 0x9247(%rip), %rsi      # 0x17e39
movl $0x3b4, %edx            # imm = 0x3B4
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc2a1
pushq $-0x1
popq %r13
jmp 0xef63
cmpl $0x0, 0x28c(%r14)
je 0xef60
movl 0x268(%r14), %ecx
movl 0x288(%r14), %ebp
cmpl $0x0, 0x444(%r14)
je 0xec51
leaq 0x97c7(%rip), %rdi      # 0x183fe
leaq 0x91fb(%rip), %rsi      # 0x17e39
movl $0x3c5, %edx            # imm = 0x3C5
xorl %eax, %eax
callq 0xc2a1
movl 0x268(%r14), %ecx
movl %ecx, %r15d
movq %r15, %rdi
callq 0x22a0
testq %rax, %rax
je 0xeeba
movq %rax, %r12
cmpl $0x0, 0x444(%r14)
je 0xec93
movl 0x28c(%r14), %ecx
leaq 0x97f1(%rip), %rdi      # 0x18471
leaq 0x91b2(%rip), %rsi      # 0x17e39
movl $0x3dd, %edx            # imm = 0x3DD
xorl %eax, %eax
callq 0xc2a1
leaq (%r12,%r15), %rax
addq $-0x4, %rax
movq %rax, 0x20(%rsp)
leaq 0x9192(%rip), %r13      # 0x17e39
leaq 0x97fe(%rip), %r15      # 0x184ac
xorl %ecx, %ecx
movq %r12, 0x10(%rsp)
cmpl 0x28c(%r14), %ecx
jae 0xef58
movl %ecx, 0xc(%rsp)
cmpl $0x0, 0x444(%r14)
je 0xece9
movq %r15, %rdi
movq %r13, %rsi
movl $0x3e6, %edx            # imm = 0x3E6
movl 0xc(%rsp), %ecx
movl %ebp, %r8d
xorl %eax, %eax
callq 0xc2a1
movq %r14, %rdi
movl %ebp, %esi
movq %r12, %rdx
callq 0xe24a
testl %eax, %eax
jne 0xef75
movl %ebp, 0x1c(%rsp)
cmpl $0x0, 0x444(%r14)
je 0xed1b
movl 0x268(%r14), %edx
movq %r12, %rsi
callq 0xe5e3
xorl %ebp, %ebp
movq %r12, %r15
leaq 0x9112(%rip), %r13      # 0x17e39
movq %r15, %rdi
callq 0x1082c
movl %eax, %r12d
cmpl $0x0, 0x444(%r14)
je 0xed55
leaq 0x97b4(%rip), %rdi      # 0x184f7
movq %r13, %rsi
movl $0x3f8, %edx            # imm = 0x3F8
movl %r12d, %ecx
xorl %eax, %eax
callq 0xc2a1
testl %r12d, %r12d
js 0xee02
movl 0x268(%r14), %eax
addq %rbx, %rax
movq 0x30(%r14), %r8
cmpq %r8, %rax
ja 0xeedc
cmpl $0x0, 0x444(%r14)
je 0xed9a
leaq 0x97a0(%rip), %rdi      # 0x18526
movq %r13, %rsi
movl $0x3fd, %edx            # imm = 0x3FD
movl %ebp, %ecx
movl %r12d, %r8d
xorl %eax, %eax
callq 0xc2a1
movq %r14, %rdi
movl %r12d, %esi
movq %rbx, %rdx
callq 0xe24a
testl %eax, %eax
jne 0xeef1
movl 0x268(%r14), %eax
addq %rax, %rbx
cmpl $0x0, 0x444(%r14)
leaq 0x9070(%rip), %r13      # 0x17e39
je 0xeded
movq 0x30(%r14), %r9
leaq 0x97f1(%rip), %rdi      # 0x185c7
movq %r13, %rsi
movl $0x408, %edx            # imm = 0x408
movq %rbx, %rcx
movq 0x10(%rsp), %r8
xorl %eax, %eax
callq 0xc2a1
movq 0x30(%r14), %r8
cmpq %r8, %rbx
ja 0xef20
incl %ebp
addq $0x4, %r15
jmp 0xee25
cmpl $0x0, 0x448(%r14)
je 0xee25
leaq 0x9843(%rip), %rdi      # 0x18656
movq %r13, %rsi
movl $0x41d, %edx            # imm = 0x41D
movl %r12d, %ecx
xorl %eax, %eax
callq 0xc2a1
cmpl $0x0, 0x444(%r14)
je 0xee48
leaq 0x985b(%rip), %rdi      # 0x18691
movq %r13, %rsi
movl $0x420, %edx            # imm = 0x420
movq %r15, %rcx
xorl %eax, %eax
callq 0xc2a1
testl %r12d, %r12d
js 0xee58
cmpq 0x20(%rsp), %r15
jb 0xed27
movl 0x28c(%r14), %eax
decl %eax
movl 0xc(%rsp), %ecx
cmpl %eax, %ecx
movl 0x1c(%rsp), %ebp
leaq 0x963a(%rip), %r15      # 0x184ac
jae 0xeea6
movq 0x20(%rsp), %rdi
callq 0x1082f
movl %eax, %ebp
cmpl $0x0, 0x444(%r14)
je 0xeea2
leaq 0x9825(%rip), %rdi      # 0x186b6
movq %r13, %rsi
movl $0x42d, %edx            # imm = 0x42D
movl %ebp, %ecx
xorl %eax, %eax
callq 0xc2a1
movl 0xc(%rsp), %ecx
incl %ecx
movq 0x10(%rsp), %r12
jmp 0xecb5
movl %eax, %r13d
jmp 0xef63
leaq 0x9579(%rip), %rdi      # 0x1843a
leaq 0x8f71(%rip), %rsi      # 0x17e39
movl $0x3cb, %edx            # imm = 0x3CB
movl %r15d, %ecx
xorl %eax, %eax
callq 0xc2a1
jmp 0xec01
leaq 0x972d(%rip), %rdi      # 0x18610
leaq 0x8f4f(%rip), %rsi      # 0x17e39
movl $0x418, %edx            # imm = 0x418
jmp 0xef3d
movl %eax, %r13d
leaq 0x9670(%rip), %rdi      # 0x1856b
leaq 0x8f37(%rip), %rsi      # 0x17e39
movl $0x401, %edx            # imm = 0x401
movl %r12d, %ecx
movq %rbx, %r8
xorl %eax, %eax
callq 0xc2a1
movq 0x10(%rsp), %rdi
callq 0x2030
jmp 0xef63
cmpl $0x0, 0x444(%r14)
je 0xef47
leaq 0x96df(%rip), %rdi      # 0x18610
leaq 0x8f01(%rip), %rsi      # 0x17e39
movl $0x411, %edx            # imm = 0x411
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc2a1
movq 0x10(%rsp), %rdi
callq 0x2030
pushq $0x32
jmp 0xec03
movq %r12, %rdi
callq 0x2030
xorl %r13d, %r13d
movl %r13d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %eax, %r13d
movq %r12, %rdi
jmp 0xef19