// File: /workspace/github_c_makefile_star2_O1/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, %rbx
movl 0x274(%rdi), %eax
movb 0x264(%rdi), %cl
movl %eax, %ebp
shll %cl, %ebp
cmpl $0x0, 0x444(%rdi)
je 0xf29a
leaq 0xa09d(%rip), %rdi      # 0x1931f
leaq 0x9bc0(%rip), %rsi      # 0x18e49
movl $0x38c, %edx            # imm = 0x38C
movl %eax, %ecx
movl %ebp, %r8d
xorl %eax, %eax
callq 0xc960
movl %ebp, %r15d
movq %r15, %rdi
callq 0x22b0
movq %rax, 0x28(%rbx)
addq %rax, %r15
movq %r15, 0x30(%rbx)
testq %rax, %rax
je 0xf742
movq %rax, %r14
movl 0x274(%rbx), %ebp
cmpl $0x6e, %ebp
jb 0xf2fb
cmpl $0x0, 0x444(%rbx)
je 0xf2f6
leaq 0xa088(%rip), %rdi      # 0x1935f
leaq 0x9b6b(%rip), %rsi      # 0x18e49
movl $0x6d, %ebp
movl $0x399, %edx            # imm = 0x399
movl $0x6d, %ecx
xorl %eax, %eax
callq 0xc960
jmp 0xf2fb
movl $0x6d, %ebp
testl %ebp, %ebp
je 0xf39d
movl %ebp, %r15d
xorl %ebp, %ebp
cmpl $0x0, 0x444(%rbx)
je 0xf32d
leaq 0xa08c(%rip), %rdi      # 0x193a4
leaq 0x9b2a(%rip), %rsi      # 0x18e49
movl $0x3a1, %edx            # imm = 0x3A1
movl %ebp, %ecx
xorl %eax, %eax
callq 0xc960
movl 0x290(%rbx,%rbp,4), %esi
movq %rbx, %rdi
movq %r14, %rdx
callq 0xe9bd
testl %eax, %eax
je 0xf34b
xorl %r13d, %r13d
movl %eax, %r12d
jmp 0xf386
movl 0x268(%rbx), %eax
addq %rax, %r14
movq 0x30(%rbx), %r8
movb $0x1, %r13b
cmpq %r8, %r14
jbe 0xf386
xorl %r13d, %r13d
leaq 0xa066(%rip), %rdi      # 0x193d0
leaq 0x9ad8(%rip), %rsi      # 0x18e49
movl $0x3b4, %edx            # imm = 0x3B4
movq %r14, %rcx
xorl %eax, %eax
callq 0xc960
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
testb %r13b, %r13b
je 0xf70d
incq %rbp
cmpq %rbp, %r15
jne 0xf308
jmp 0xf39d
movb $0x1, %al
cmpl $0x0, 0x28c(%rbx)
movl %r12d, %r13d
je 0xf73e
movl 0x288(%rbx), %ebp
cmpl $0x0, 0x444(%rbx)
je 0xf3de
movl 0x268(%rbx), %ecx
leaq 0xa043(%rip), %rdi      # 0x1940e
leaq 0x9a77(%rip), %rsi      # 0x18e49
movl $0x3c5, %edx            # imm = 0x3C5
xorl %eax, %eax
callq 0xc960
movl 0x268(%rbx), %r15d
movq %r15, %rdi
callq 0x22b0
testq %rax, %rax
je 0xf714
movq %rax, %r12
cmpl $0x0, 0x444(%rbx)
je 0xf422
movl 0x28c(%rbx), %ecx
leaq 0xa072(%rip), %rdi      # 0x19481
leaq 0x9a33(%rip), %rsi      # 0x18e49
movl $0x3dd, %edx            # imm = 0x3DD
xorl %eax, %eax
callq 0xc960
cmpl $0x0, 0x28c(%rbx)
je 0xf701
leaq (%r12,%r15), %rax
addq $-0x4, %rax
movq %rax, 0x20(%rsp)
movl %ebp, %r15d
xorl %ebp, %ebp
movq %r12, 0x10(%rsp)
cmpl $0x0, 0x444(%rbx)
je 0xf46e
leaq 0xa066(%rip), %rdi      # 0x194bc
leaq 0x99ec(%rip), %rsi      # 0x18e49
movl $0x3e6, %edx            # imm = 0x3E6
movl %ebp, %ecx
movl %r15d, %r8d
xorl %eax, %eax
callq 0xc960
movl %ebp, 0x1c(%rsp)
movq %rbx, %rdi
movl %r15d, %esi
movq %r12, %rdx
callq 0xe9bd
testl %eax, %eax
je 0xf499
movl %eax, %ebp
movq %r12, %rdi
callq 0x2030
xorl %r12d, %r12d
movl %ebp, %r13d
jmp 0xf6e5
movl %r15d, 0xc(%rsp)
movl %r13d, 0x18(%rsp)
cmpl $0x0, 0x444(%rbx)
je 0xf4ba
movl 0x268(%rbx), %edx
movq %r12, %rsi
callq 0xed56
xorl %r13d, %r13d
leaq 0x9985(%rip), %rbp      # 0x18e49
movq %r12, %rdi
callq 0x110f8
movl %eax, %r15d
cmpl $0x0, 0x444(%rbx)
je 0xf4f1
leaq 0xa028(%rip), %rdi      # 0x19507
movq %rbp, %rsi
movl $0x3f8, %edx            # imm = 0x3F8
movl %r15d, %ecx
xorl %eax, %eax
callq 0xc960
testl %r15d, %r15d
js 0xf59c
movl 0x268(%rbx), %eax
addq %r14, %rax
movq 0x30(%rbx), %r8
cmpq %r8, %rax
ja 0xf642
cmpl $0x0, 0x444(%rbx)
je 0xf535
leaq 0xa016(%rip), %rdi      # 0x19536
movq %rbp, %rsi
movl $0x3fd, %edx            # imm = 0x3FD
movl %r13d, %ecx
movl %r15d, %r8d
xorl %eax, %eax
callq 0xc960
movq %rbx, %rdi
movl %r15d, %esi
movq %r14, %rdx
callq 0xe9bd
testl %eax, %eax
jne 0xf670
movl 0x268(%rbx), %eax
addq %rax, %r14
cmpl $0x0, 0x444(%rbx)
leaq 0x98e7(%rip), %rbp      # 0x18e49
je 0xf586
movq 0x30(%rbx), %r9
leaq 0xa068(%rip), %rdi      # 0x195d7
movq %rbp, %rsi
movl $0x408, %edx            # imm = 0x408
movq %r14, %rcx
movq 0x10(%rsp), %r8
xorl %eax, %eax
callq 0xc960
movq 0x30(%rbx), %r8
cmpq %r8, %r14
ja 0xf6a4
incl %r13d
addq $0x4, %r12
jmp 0xf5be
cmpl $0x0, 0x448(%rbx)
je 0xf5be
leaq 0xa0ba(%rip), %rdi      # 0x19666
movq %rbp, %rsi
movl $0x41d, %edx            # imm = 0x41D
movl %r15d, %ecx
xorl %eax, %eax
callq 0xc960
cmpl $0x0, 0x444(%rbx)
je 0xf5e0
leaq 0xa0d3(%rip), %rdi      # 0x196a1
movq %rbp, %rsi
movl $0x420, %edx            # imm = 0x420
movq %r12, %rcx
xorl %eax, %eax
callq 0xc960
testl %r15d, %r15d
js 0xf5f0
cmpq 0x20(%rsp), %r12
jb 0xf4c4
movl 0x28c(%rbx), %eax
decl %eax
movb $0x1, %r12b
cmpl %eax, 0x1c(%rsp)
jae 0xf6db
movq 0x20(%rsp), %rdi
callq 0x110fb
movl %eax, %r15d
cmpl $0x0, 0x444(%rbx)
movl 0x18(%rsp), %r13d
je 0xf6e5
leaq 0xa09b(%rip), %rdi      # 0x196c6
movq %rbp, %rsi
movl $0x42d, %edx            # imm = 0x42D
movl %r15d, %ecx
xorl %eax, %eax
callq 0xc960
jmp 0xf6e5
xorl %r12d, %r12d
leaq 0x9fd4(%rip), %rdi      # 0x19620
movq %rbp, %rsi
movl $0x418, %edx            # imm = 0x418
movq %r14, %rcx
xorl %eax, %eax
callq 0xc960
movq 0x10(%rsp), %rdi
callq 0x2030
movl $0x32, %r13d
jmp 0xf6e0
movl %eax, %ebp
xorl %r12d, %r12d
leaq 0x9eff(%rip), %rdi      # 0x1957b
leaq 0x97c6(%rip), %rsi      # 0x18e49
movl $0x401, %edx            # imm = 0x401
movl %r15d, %ecx
movq %r14, %r8
xorl %eax, %eax
callq 0xc960
movq 0x10(%rsp), %rdi
callq 0x2030
movl %ebp, %r13d
jmp 0xf6e0
cmpl $0x0, 0x444(%rbx)
je 0xf6c6
leaq 0x9f6c(%rip), %rdi      # 0x19620
movq %rbp, %rsi
movl $0x411, %edx            # imm = 0x411
movq %r14, %rcx
xorl %eax, %eax
callq 0xc960
movq 0x10(%rsp), %rdi
callq 0x2030
movl $0x32, %r13d
xorl %r12d, %r12d
jmp 0xf6e0
movl 0x18(%rsp), %r13d
movl 0xc(%rsp), %r15d
testb %r12b, %r12b
movl 0x1c(%rsp), %ebp
je 0xf73b
incl %ebp
cmpl 0x28c(%rbx), %ebp
movq 0x10(%rsp), %r12
jb 0xf446
movq %r12, %rdi
callq 0x2030
movb $0x1, %al
jmp 0xf73e
xorl %eax, %eax
movl %r12d, %r13d
jmp 0xf73e
leaq 0x9d2f(%rip), %rdi      # 0x1944a
leaq 0x9727(%rip), %rsi      # 0x18e49
movl $0x3cb, %edx            # imm = 0x3CB
movl %r15d, %ecx
xorl %eax, %eax
callq 0xc960
xorl %eax, %eax
movl $0xffffffff, %r13d      # imm = 0xFFFFFFFF
jmp 0xf73e
movl %r12d, %eax
testb %al, %al
je 0xf745
xorl %r13d, %r13d
movl %r13d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq