// File: /workspace/github_c_makefile_star2_O3/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 0xf191
leaq 0xa196(%rip), %rdi      # 0x1930f
leaq 0x9cb9(%rip), %rsi      # 0x18e39
movl $0x38c, %edx            # imm = 0x38C
movl %eax, %ecx
movl %ebx, %r8d
xorl %eax, %eax
callq 0xc84f
movl %ebx, %r15d
movq %r15, %rdi
callq 0x22a0
movq %rax, %rbx
movq %rax, 0x28(%r14)
addq %rax, %r15
movq %r15, 0x30(%r14)
xorl %eax, %eax
testq %rbx, %rbx
je 0xf570
movl 0x274(%r14), %ebp
cmpl $0x6e, %ebp
jb 0xf1f1
cmpl $0x0, 0x444(%r14)
je 0xf1f7
leaq 0xa17d(%rip), %rdi      # 0x1934f
leaq 0x9c60(%rip), %rsi      # 0x18e39
movl $0x6d, %ebp
movl $0x399, %edx            # imm = 0x399
movl $0x6d, %ecx
xorl %eax, %eax
callq 0xc84f
jmp 0xf1fc
testl %ebp, %ebp
jne 0xf1fc
jmp 0xf268
movl $0x6d, %ebp
movl %ebp, %ebp
leaq 0xa18f(%rip), %r15      # 0x19394
leaq 0x9c2d(%rip), %r12      # 0x18e39
xorl %r13d, %r13d
cmpl $0x0, 0x444(%r14)
je 0xf22e
movq %r15, %rdi
movq %r12, %rsi
movl $0x3a1, %edx            # imm = 0x3A1
movl %r13d, %ecx
xorl %eax, %eax
callq 0xc84f
movl 0x290(%r14,%r13,4), %esi
movq %r14, %rdi
movq %rbx, %rdx
callq 0xe895
testl %eax, %eax
jne 0xf570
movl 0x268(%r14), %eax
addq %rax, %rbx
movq 0x30(%r14), %r8
cmpq %r8, %rbx
ja 0xf52f
incq %r13
cmpq %r13, %rbp
jne 0xf20f
cmpl $0x0, 0x28c(%r14)
je 0xf52b
movl 0x288(%r14), %r13d
cmpl $0x0, 0x444(%r14)
je 0xf2a8
movl 0x268(%r14), %ecx
leaq 0xa169(%rip), %rdi      # 0x193fe
leaq 0x9b9d(%rip), %rsi      # 0x18e39
movl $0x3c5, %edx            # imm = 0x3C5
xorl %eax, %eax
callq 0xc84f
movl 0x268(%r14), %r15d
movq %r15, %rdi
callq 0x22a0
testq %rax, %rax
je 0xf54e
movq %rax, %r12
cmpl $0x0, 0x444(%r14)
movl 0x28c(%r14), %ecx
je 0xf2f5
leaq 0xa196(%rip), %rdi      # 0x19471
leaq 0x9b57(%rip), %rsi      # 0x18e39
movl $0x3dd, %edx            # imm = 0x3DD
xorl %eax, %eax
callq 0xc84f
movl 0x28c(%r14), %ecx
testl %ecx, %ecx
je 0xf523
leaq (%r12,%r15), %rax
addq $-0x4, %rax
movq %rax, 0x20(%rsp)
leaq 0x9b28(%rip), %rbp      # 0x18e39
leaq 0xa194(%rip), %r15      # 0x194ac
movl $0x0, 0xc(%rsp)
movq %r12, 0x10(%rsp)
cmpl $0x0, 0x444(%r14)
je 0xf348
movq %r15, %rdi
movq %rbp, %rsi
movl $0x3e6, %edx            # imm = 0x3E6
movl 0xc(%rsp), %ecx
movl %r13d, %r8d
xorl %eax, %eax
callq 0xc84f
movq %r14, %rdi
movl %r13d, %esi
movq %r12, %rdx
callq 0xe895
testl %eax, %eax
jne 0xf5ff
movl %r13d, 0x1c(%rsp)
cmpl $0x0, 0x444(%r14)
je 0xf37c
movl 0x268(%r14), %edx
movq %r12, %rsi
callq 0xec4d
xorl %r15d, %r15d
movq %r12, %r13
leaq 0x9ab0(%rip), %rbp      # 0x18e39
movq %r13, %rdi
callq 0x10ee8
movl %eax, %r12d
cmpl $0x0, 0x444(%r14)
je 0xf3b7
leaq 0xa152(%rip), %rdi      # 0x194f7
movq %rbp, %rsi
movl $0x3f8, %edx            # imm = 0x3F8
movl %r12d, %ecx
xorl %eax, %eax
callq 0xc84f
testl %r12d, %r12d
js 0xf466
movl 0x268(%r14), %eax
addq %rbx, %rax
movq 0x30(%r14), %r8
cmpq %r8, %rax
ja 0xf57f
cmpl $0x0, 0x444(%r14)
je 0xf3fd
leaq 0xa13e(%rip), %rdi      # 0x19526
movq %rbp, %rsi
movl $0x3fd, %edx            # imm = 0x3FD
movl %r15d, %ecx
movl %r12d, %r8d
xorl %eax, %eax
callq 0xc84f
movq %r14, %rdi
movl %r12d, %esi
movq %rbx, %rdx
callq 0xe895
testl %eax, %eax
jne 0xf594
movl 0x268(%r14), %eax
addq %rax, %rbx
cmpl $0x0, 0x444(%r14)
leaq 0x9a0d(%rip), %rbp      # 0x18e39
je 0xf450
movq 0x30(%r14), %r9
leaq 0xa18e(%rip), %rdi      # 0x195c7
movq %rbp, %rsi
movl $0x408, %edx            # imm = 0x408
movq %rbx, %rcx
movq 0x10(%rsp), %r8
xorl %eax, %eax
callq 0xc84f
movq 0x30(%r14), %r8
cmpq %r8, %rbx
ja 0xf5c4
incl %r15d
addq $0x4, %r13
jmp 0xf489
cmpl $0x0, 0x448(%r14)
je 0xf489
leaq 0xa1df(%rip), %rdi      # 0x19656
movq %rbp, %rsi
movl $0x41d, %edx            # imm = 0x41D
movl %r12d, %ecx
xorl %eax, %eax
callq 0xc84f
cmpl $0x0, 0x444(%r14)
je 0xf4ac
leaq 0xa1f7(%rip), %rdi      # 0x19691
movq %rbp, %rsi
movl $0x420, %edx            # imm = 0x420
movq %r13, %rcx
xorl %eax, %eax
callq 0xc84f
testl %r12d, %r12d
js 0xf4bc
cmpq 0x20(%rsp), %r13
jb 0xf389
movl 0x28c(%r14), %eax
decl %eax
cmpl %eax, 0xc(%rsp)
movq 0x10(%rsp), %r12
movl 0x1c(%rsp), %r13d
leaq 0x9fd2(%rip), %r15      # 0x194ac
jae 0xf50c
movq 0x20(%rsp), %rdi
callq 0x10eeb
movl %eax, %r13d
cmpl $0x0, 0x444(%r14)
je 0xf50c
leaq 0xa1bc(%rip), %rdi      # 0x196b6
movq %rbp, %rsi
movl $0x42d, %edx            # imm = 0x42D
movl %r13d, %ecx
xorl %eax, %eax
callq 0xc84f
movl 0xc(%rsp), %eax
incl %eax
movl %eax, 0xc(%rsp)
cmpl 0x28c(%r14), %eax
jb 0xf325
movq %r12, %rdi
callq 0x2030
xorl %eax, %eax
jmp 0xf570
leaq 0x9e8a(%rip), %rdi      # 0x193c0
leaq 0x98fc(%rip), %rsi      # 0x18e39
movl $0x3b4, %edx            # imm = 0x3B4
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc84f
jmp 0xf56b
leaq 0x9ee5(%rip), %rdi      # 0x1943a
leaq 0x98dd(%rip), %rsi      # 0x18e39
movl $0x3cb, %edx            # imm = 0x3CB
movl %r15d, %ecx
xorl %eax, %eax
callq 0xc84f
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xa08a(%rip), %rdi      # 0x19610
leaq 0x98ac(%rip), %rsi      # 0x18e39
movl $0x418, %edx            # imm = 0x418
jmp 0xf5e1
movl %eax, %ebp
leaq 0x9fce(%rip), %rdi      # 0x1956b
leaq 0x9895(%rip), %rsi      # 0x18e39
movl $0x401, %edx            # imm = 0x401
movl %r12d, %ecx
movq %rbx, %r8
xorl %eax, %eax
callq 0xc84f
movq 0x10(%rsp), %rdi
callq 0x2030
movl %ebp, %eax
jmp 0xf570
cmpl $0x0, 0x444(%r14)
je 0xf5eb
leaq 0xa03b(%rip), %rdi      # 0x19610
leaq 0x985d(%rip), %rsi      # 0x18e39
movl $0x411, %edx            # imm = 0x411
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc84f
movq 0x10(%rsp), %rdi
callq 0x2030
movl $0x32, %eax
jmp 0xf570
movl %eax, %ebp
movq %r12, %rdi
jmp 0xf5bb