# HG changeset patch # User Pascal Bellard # Date 1299960449 -3600 # Node ID 2372be9d040cbe7ec4656d6f12f92a8310fe95af # Parent 47a1cb961c67dd4733aea1dfbb7137d8c5af5bb2 grub4dos: add lzma support diff -r 47a1cb961c67 -r 2372be9d040c grub4dos/stuff/lzma.diff --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/grub4dos/stuff/lzma.diff Sat Mar 12 21:07:29 2011 +0100 @@ -0,0 +1,1761 @@ +From http://code.google.com/p/grub4dos-chenall/issues/detail?id=6 + +diff -Naur ../grub4dos-chenall-r63/stage2/common.c ./stage2/common.c +--- grub4dos-chenall-r63/stage2/common.c 2010-11-19 12:41:03.196955000 +0700 ++++ grub4dos/stage2/common.c 2010-11-23 21:28:26.509102100 +0700 +@@ -143,6 +143,7 @@ + [ERR_WRITE_GZIP_FILE] = "Attempt to write a gzip file", + [ERR_FUNC_CALL] = "Invalid function call", + // [ERR_WRITE_TO_NON_MEM_DRIVE] = "Only RAM drives can be written when running in a script", ++ [ERR_NOT_ENOUGH_MEMORY] = "Not enough memory", + + }; + +diff -Naur ../grub4dos-chenall-r63/stage2/dec_lzma.c ./stage2/dec_lzma.c +--- grub4dos-chenall-r63/stage2/dec_lzma.c 1970-01-01 07:00:00.000000000 +0700 ++++ grub4dos/stage2/dec_lzma.c 2010-11-28 22:12:06.452791800 +0700 +@@ -0,0 +1,1384 @@ ++/* ++ * GRUB4DOS -- GRand Unified Bootloader ++ * Copyright (C) 1999 Free Software Foundation, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++/* ++ * Most of this file is derives from LZMA SDK 9.12 beta ++ * files Types.h, LzmaDec.h, LzmaDec.c by Igor Pavlov ++ * It has been modified for used in GRUB4DOS. ++ */ ++ ++#ifndef NO_DECOMPRESSION ++ ++#include "shared.h" ++#include "decomp.h" ++ ++/* Types.h -- Basic types ++2010-03-11 : Igor Pavlov : Public domain */ ++ ++#define SZ_OK 0 ++ ++#define SZ_ERROR_DATA 1 ++#define SZ_ERROR_MEM 2 ++#define SZ_ERROR_CRC 3 ++#define SZ_ERROR_UNSUPPORTED 4 ++#define SZ_ERROR_PARAM 5 ++#define SZ_ERROR_INPUT_EOF 6 ++#define SZ_ERROR_OUTPUT_EOF 7 ++#define SZ_ERROR_READ 8 ++#define SZ_ERROR_WRITE 9 ++#define SZ_ERROR_PROGRESS 10 ++#define SZ_ERROR_FAIL 11 ++#define SZ_ERROR_THREAD 12 ++ ++#define SZ_ERROR_ARCHIVE 16 ++#define SZ_ERROR_NO_ARCHIVE 17 ++ ++typedef int SRes; ++typedef int WRes; ++ ++#ifndef RINOK ++#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } ++#endif ++ ++typedef unsigned char Byte; ++typedef short Int16; ++typedef unsigned short UInt16; ++ ++typedef int Int32; ++typedef unsigned int UInt32; ++ ++typedef long long int Int64; ++typedef unsigned long long int UInt64; ++ ++typedef UInt32 SizeT; ++typedef int ptrdiff_t; ++ ++typedef int Bool; ++#define True 1 ++#define False 0 ++ ++#define MY_STD_CALL ++#define MY_CDECL ++#define MY_FAST_CALL ++ ++typedef struct ++{ ++ void *(*Alloc)(void *p, SizeT size); ++ void (*Free)(void *p, void *address); /* address can be 0 */ ++} ISzAlloc; ++ ++#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) ++#define IAlloc_Free(p, a) (p)->Free((p), a) ++ ++/* -------------------------------------------------------------------------- */ ++ ++/* LzmaDec.h -- LZMA Decoder ++2009-02-07 : Igor Pavlov : Public domain */ ++ ++/* #define _LZMA_PROB32 */ ++/* _LZMA_PROB32 can increase the speed on some CPUs, ++ but memory usage for CLzmaDec::probs will be doubled in that case */ ++ ++#ifdef _LZMA_PROB32 ++#define UIntLzmaProb UInt32 ++#else ++#define UIntLzmaProb UInt16 ++#endif ++ ++ ++/* ---------- LZMA Properties ---------- */ ++ ++#define LZMA_PROPS_SIZE 5 ++ ++typedef struct _CLzmaProps ++{ ++ unsigned lc, lp, pb; ++ UInt32 dicSize; ++} CLzmaProps; ++ ++/* LzmaProps_Decode - decodes properties ++Returns: ++ SZ_OK ++ SZ_ERROR_UNSUPPORTED - Unsupported properties ++*/ ++ ++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); ++ ++ ++/* ---------- LZMA Decoder state ---------- */ ++ ++/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. ++ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ ++ ++#define LZMA_REQUIRED_INPUT_MAX 20 ++ ++typedef struct ++{ ++ CLzmaProps prop; ++ UIntLzmaProb *probs; ++ const Byte *buf; ++ UInt32 range, code; ++ Byte *dic; ++ UInt32 dicPos; ++ UInt32 dicBufSize; ++ Byte *inp; ++ UInt32 inpPos, inpSize; ++ UInt32 inpBufSize; ++ UInt32 processedPos; ++ UInt32 checkDicSize; ++ unsigned state; ++ UInt32 reps[4]; ++ unsigned remainLen; ++ int needFlush; ++ int needInitState; ++ UInt32 numProbs; ++ unsigned tempBufSize; ++ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; ++ UInt64 inpFilePos; ++ UInt64 dicFilePos; ++ struct { ++ UInt64 fmax, fpos; ++ } filec, fileu; ++} CLzmaDec; ++ ++#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } ++ ++void LzmaDec_Init(CLzmaDec *p); ++ ++/* There are two types of LZMA streams: ++ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. ++ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ ++ ++typedef enum ++{ ++ LZMA_FINISH_ANY, /* finish at any point */ ++ LZMA_FINISH_END /* block must be finished at the end */ ++} ELzmaFinishMode; ++ ++/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! ++ ++ You must use LZMA_FINISH_END, when you know that current output buffer ++ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. ++ ++ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, ++ and output value of destLen will be less than output buffer size limit. ++ You can check status result also. ++ ++ You can use multiple checks to test data integrity after full decompression: ++ 1) Check Result and "status" variable. ++ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. ++ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. ++ You must use correct finish mode in that case. */ ++ ++typedef enum ++{ ++ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ ++ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ ++ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ ++ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ ++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ ++} ELzmaStatus; ++ ++/* ELzmaStatus is used only as output value for function call */ ++ ++ ++/* ---------- Interfaces ---------- */ ++ ++/* There are 3 levels of interfaces: ++ 1) Dictionary Interface ++ 2) Buffer Interface ++ 3) One Call Interface ++ You can select any of these interfaces, but don't mix functions from different ++ groups for same object. */ ++ ++ ++/* There are two variants to allocate state for Dictionary Interface: ++ 1) LzmaDec_Allocate / LzmaDec_Free ++ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs ++ You can use variant 2, if you set dictionary buffer manually. ++ For Buffer Interface you must always use variant 1. ++ ++LzmaDec_Allocate* can return: ++ SZ_OK ++ SZ_ERROR_MEM - Memory allocation error ++ SZ_ERROR_UNSUPPORTED - Unsupported properties ++*/ ++ ++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); ++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); ++ ++SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); ++void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); ++ ++/* ---------- Dictionary Interface ---------- */ ++ ++/* You can use it, if you want to eliminate the overhead for data copying from ++ dictionary to some other external buffer. ++ You must work with CLzmaDec variables directly in this interface. ++ ++ STEPS: ++ LzmaDec_Constr() ++ LzmaDec_Allocate() ++ for (each new stream) ++ { ++ LzmaDec_Init() ++ while (it needs more decompression) ++ { ++ LzmaDec_DecodeToDic() ++ use data from CLzmaDec::dic and update CLzmaDec::dicPos ++ } ++ } ++ LzmaDec_Free() ++*/ ++ ++/* LzmaDec_DecodeToDic ++ ++ The decoding to internal dictionary buffer (CLzmaDec::dic). ++ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! ++ ++finishMode: ++ It has meaning only if the decoding reaches output limit (dicLimit). ++ LZMA_FINISH_ANY - Decode just dicLimit bytes. ++ LZMA_FINISH_END - Stream must be finished after dicLimit. ++ ++Returns: ++ SZ_OK ++ status: ++ LZMA_STATUS_FINISHED_WITH_MARK ++ LZMA_STATUS_NOT_FINISHED ++ LZMA_STATUS_NEEDS_MORE_INPUT ++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ++ SZ_ERROR_DATA - Data error ++*/ ++ ++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, ++ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); ++ ++ ++/* ---------- Buffer Interface ---------- */ ++ ++/* It's zlib-like interface. ++ See LzmaDec_DecodeToDic description for information about STEPS and return results, ++ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need ++ to work with CLzmaDec variables manually. ++ ++finishMode: ++ It has meaning only if the decoding reaches output limit (*destLen). ++ LZMA_FINISH_ANY - Decode just destLen bytes. ++ LZMA_FINISH_END - Stream must be finished after (*destLen). ++*/ ++ ++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, ++ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); ++ ++ ++/* ---------- One Call Interface ---------- */ ++ ++/* LzmaDecode ++ ++finishMode: ++ It has meaning only if the decoding reaches output limit (*destLen). ++ LZMA_FINISH_ANY - Decode just destLen bytes. ++ LZMA_FINISH_END - Stream must be finished after (*destLen). ++ ++Returns: ++ SZ_OK ++ status: ++ LZMA_STATUS_FINISHED_WITH_MARK ++ LZMA_STATUS_NOT_FINISHED ++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ++ SZ_ERROR_DATA - Data error ++ SZ_ERROR_MEM - Memory allocation error ++ SZ_ERROR_UNSUPPORTED - Unsupported properties ++ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). ++*/ ++ ++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ++ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, ++ ELzmaStatus *status, ISzAlloc *alloc); ++ ++/* -------------------------------------------------------------------------- */ ++ ++/* LzmaDec.c -- LZMA Decoder ++2009-09-20 : Igor Pavlov : Public domain */ ++ ++//#include "LzmaDec.h" ++ ++//#include ++ ++#define kNumTopBits 24 ++#define kTopValue ((UInt32)1 << kNumTopBits) ++ ++#define kNumBitModelTotalBits 11 ++#define kBitModelTotal (1 << kNumBitModelTotalBits) ++#define kNumMoveBits 5 ++ ++#define RC_INIT_SIZE 5 ++ ++#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } ++ ++#define TEST_BIT_0(p) ({ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; (code < bound);}) ++#define UPDATE_0(p) range = bound; *(p) = (UIntLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); ++#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (UIntLzmaProb)(ttt - (ttt >> kNumMoveBits)); ++#define GET_BIT2(p, i, A0, A1) if(TEST_BIT_0(p)) \ ++ { UPDATE_0(p); i = (i + i); A0; } else \ ++ { UPDATE_1(p); i = (i + i) + 1; A1; } ++#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) ++ ++#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } ++#define TREE_DECODE(probs, limit, i) \ ++ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } ++ ++/* #define _LZMA_SIZE_OPT */ ++ ++#ifdef _LZMA_SIZE_OPT ++#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) ++#else ++#define TREE_6_DECODE(probs, i) \ ++ { i = 1; \ ++ TREE_GET_BIT(probs, i); \ ++ TREE_GET_BIT(probs, i); \ ++ TREE_GET_BIT(probs, i); \ ++ TREE_GET_BIT(probs, i); \ ++ TREE_GET_BIT(probs, i); \ ++ TREE_GET_BIT(probs, i); \ ++ i -= 0x40; } ++#endif ++ ++#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } ++ ++#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) ++#define UPDATE_0_CHECK range = bound; ++#define UPDATE_1_CHECK range -= bound; code -= bound; ++#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ ++ { UPDATE_0_CHECK; i = (i + i); A0; } else \ ++ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } ++#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) ++#define TREE_DECODE_CHECK(probs, limit, i) \ ++ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } ++ ++ ++#define kNumPosBitsMax 4 ++#define kNumPosStatesMax (1 << kNumPosBitsMax) ++ ++#define kLenNumLowBits 3 ++#define kLenNumLowSymbols (1 << kLenNumLowBits) ++#define kLenNumMidBits 3 ++#define kLenNumMidSymbols (1 << kLenNumMidBits) ++#define kLenNumHighBits 8 ++#define kLenNumHighSymbols (1 << kLenNumHighBits) ++ ++#define LenChoice 0 ++#define LenChoice2 (LenChoice + 1) ++#define LenLow (LenChoice2 + 1) ++#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) ++#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) ++#define kNumLenProbs (LenHigh + kLenNumHighSymbols) ++ ++ ++#define kNumStates 12 ++#define kNumLitStates 7 ++ ++#define kStartPosModelIndex 4 ++#define kEndPosModelIndex 14 ++#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) ++ ++#define kNumPosSlotBits 6 ++#define kNumLenToPosStates 4 ++ ++#define kNumAlignBits 4 ++#define kAlignTableSize (1 << kNumAlignBits) ++ ++#define kMatchMinLen 2 ++#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) ++ ++#define IsMatch 0 ++#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) ++#define IsRepG0 (IsRep + kNumStates) ++#define IsRepG1 (IsRepG0 + kNumStates) ++#define IsRepG2 (IsRepG1 + kNumStates) ++#define IsRep0Long (IsRepG2 + kNumStates) ++#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) ++#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) ++#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) ++#define LenCoder (Align + kAlignTableSize) ++#define RepLenCoder (LenCoder + kNumLenProbs) ++#define Literal (RepLenCoder + kNumLenProbs) ++ ++#define LZMA_BASE_SIZE 1846 ++#define LZMA_LIT_SIZE 768 ++ ++#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) ++ ++#if Literal != LZMA_BASE_SIZE ++StopCompilingDueBUG ++#endif ++ ++#define LZMA_DIC_MIN (1 << 12) ++ ++/* First LZMA-symbol is always decoded. ++And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization ++Out: ++ Result: ++ SZ_OK - OK ++ SZ_ERROR_DATA - Error ++ p->remainLen: ++ < kMatchSpecLenStart : normal remain ++ = kMatchSpecLenStart : finished ++ = kMatchSpecLenStart + 1 : Flush marker ++ = kMatchSpecLenStart + 2 : State Init Marker ++*/ ++ ++static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) ++{ ++ UIntLzmaProb *probs = p->probs; ++ ++ unsigned state = p->state; ++ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; ++ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; ++ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; ++ unsigned lc = p->prop.lc; ++ ++ Byte *dic = p->dic; ++ SizeT dicBufSize = p->dicBufSize; ++ SizeT dicPos = p->dicPos; ++ ++ UInt32 processedPos = p->processedPos; ++ UInt32 checkDicSize = p->checkDicSize; ++ unsigned len = 0; ++ ++ const Byte *buf = p->buf; ++ UInt32 range = p->range; ++ UInt32 code = p->code; ++ ++ do ++ { ++ UIntLzmaProb *prob; ++ UInt32 bound; ++ unsigned ttt; ++ unsigned posState = processedPos & pbMask; ++ ++ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; ++ if(TEST_BIT_0(prob)) ++ { ++ unsigned symbol; ++ UPDATE_0(prob); ++ prob = probs + Literal; ++ if (checkDicSize != 0 || processedPos != 0) ++ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + ++ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); ++ ++ if (state < kNumLitStates) ++ { ++ state -= (state < 4) ? state : 3; ++ symbol = 1; ++ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); ++ } ++ else ++ { ++ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; ++ unsigned offs = 0x100; ++ state -= (state < 10) ? 3 : 6; ++ symbol = 1; ++ do ++ { ++ unsigned bit; ++ UIntLzmaProb *probLit; ++ matchByte <<= 1; ++ bit = (matchByte & offs); ++ probLit = prob + offs + bit + symbol; ++ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) ++ } ++ while (symbol < 0x100); ++ } ++ dic[dicPos++] = (Byte)symbol; ++ processedPos++; ++ continue; ++ } ++ else ++ { ++ UPDATE_1(prob); ++ prob = probs + IsRep + state; ++ if(TEST_BIT_0(prob)) ++ { ++ UPDATE_0(prob); ++ state += kNumStates; ++ prob = probs + LenCoder; ++ } ++ else ++ { ++ UPDATE_1(prob); ++ if (checkDicSize == 0 && processedPos == 0) ++ return SZ_ERROR_DATA; ++ prob = probs + IsRepG0 + state; ++ if(TEST_BIT_0(prob)) ++ { ++ UPDATE_0(prob); ++ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; ++ if(TEST_BIT_0(prob)) ++ { ++ UPDATE_0(prob); ++ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; ++ dicPos++; ++ processedPos++; ++ state = state < kNumLitStates ? 9 : 11; ++ continue; ++ } ++ UPDATE_1(prob); ++ } ++ else ++ { ++ UInt32 distance; ++ UPDATE_1(prob); ++ prob = probs + IsRepG1 + state; ++ if(TEST_BIT_0(prob)) ++ { ++ UPDATE_0(prob); ++ distance = rep1; ++ } ++ else ++ { ++ UPDATE_1(prob); ++ prob = probs + IsRepG2 + state; ++ if(TEST_BIT_0(prob)) ++ { ++ UPDATE_0(prob); ++ distance = rep2; ++ } ++ else ++ { ++ UPDATE_1(prob); ++ distance = rep3; ++ rep3 = rep2; ++ } ++ rep2 = rep1; ++ } ++ rep1 = rep0; ++ rep0 = distance; ++ } ++ state = state < kNumLitStates ? 8 : 11; ++ prob = probs + RepLenCoder; ++ } ++ { ++ unsigned limit, offset; ++ UIntLzmaProb *probLen = prob + LenChoice; ++ if(TEST_BIT_0(probLen)) ++ { ++ UPDATE_0(probLen); ++ probLen = prob + LenLow + (posState << kLenNumLowBits); ++ offset = 0; ++ limit = (1 << kLenNumLowBits); ++ } ++ else ++ { ++ UPDATE_1(probLen); ++ probLen = prob + LenChoice2; ++ if(TEST_BIT_0(probLen)) ++ { ++ UPDATE_0(probLen); ++ probLen = prob + LenMid + (posState << kLenNumMidBits); ++ offset = kLenNumLowSymbols; ++ limit = (1 << kLenNumMidBits); ++ } ++ else ++ { ++ UPDATE_1(probLen); ++ probLen = prob + LenHigh; ++ offset = kLenNumLowSymbols + kLenNumMidSymbols; ++ limit = (1 << kLenNumHighBits); ++ } ++ } ++ TREE_DECODE(probLen, limit, len); ++ len += offset; ++ } ++ ++ if (state >= kNumStates) ++ { ++ UInt32 distance; ++ prob = probs + PosSlot + ++ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); ++ TREE_6_DECODE(prob, distance); ++ if (distance >= kStartPosModelIndex) ++ { ++ unsigned posSlot = (unsigned)distance; ++ int numDirectBits = (int)(((distance >> 1) - 1)); ++ distance = (2 | (distance & 1)); ++ if (posSlot < kEndPosModelIndex) ++ { ++ distance <<= numDirectBits; ++ prob = probs + SpecPos + distance - posSlot - 1; ++ { ++ UInt32 mask = 1; ++ unsigned i = 1; ++ do ++ { ++ GET_BIT2(prob + i, i, ; , distance |= mask); ++ mask <<= 1; ++ } ++ while (--numDirectBits != 0); ++ } ++ } ++ else ++ { ++ numDirectBits -= kNumAlignBits; ++ do ++ { ++ NORMALIZE ++ range >>= 1; ++ ++ { ++ UInt32 t; ++ code -= range; ++ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ ++ distance = (distance << 1) + (t + 1); ++ code += range & t; ++ } ++ /* ++ distance <<= 1; ++ if (code >= range) ++ { ++ code -= range; ++ distance |= 1; ++ } ++ */ ++ } ++ while (--numDirectBits != 0); ++ prob = probs + Align; ++ distance <<= kNumAlignBits; ++ { ++ unsigned i = 1; ++ GET_BIT2(prob + i, i, ; , distance |= 1); ++ GET_BIT2(prob + i, i, ; , distance |= 2); ++ GET_BIT2(prob + i, i, ; , distance |= 4); ++ GET_BIT2(prob + i, i, ; , distance |= 8); ++ } ++ if (distance == (UInt32)0xFFFFFFFF) ++ { ++ len += kMatchSpecLenStart; ++ state -= kNumStates; ++ break; ++ } ++ } ++ } ++ rep3 = rep2; ++ rep2 = rep1; ++ rep1 = rep0; ++ rep0 = distance + 1; ++ if (checkDicSize == 0) ++ { ++ if (distance >= processedPos) ++ return SZ_ERROR_DATA; ++ } ++ else if (distance >= checkDicSize) ++ return SZ_ERROR_DATA; ++ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; ++ } ++ ++ len += kMatchMinLen; ++ ++ if (limit == dicPos) ++ return SZ_ERROR_DATA; ++ { ++ SizeT rem = limit - dicPos; ++ unsigned curLen = ((rem < len) ? (unsigned)rem : len); ++ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); ++ ++ processedPos += curLen; ++ ++ len -= curLen; ++ if (pos + curLen <= dicBufSize) ++ { ++ Byte *dest = dic + dicPos; ++ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; ++ const Byte *lim = dest + curLen; ++ dicPos += curLen; ++ do ++ *(dest) = (Byte)(*(dest + src)); ++ while (++dest != lim); ++ } ++ else ++ { ++ do ++ { ++ dic[dicPos++] = dic[pos]; ++ if (++pos == dicBufSize) ++ pos = 0; ++ } ++ while (--curLen != 0); ++ } ++ } ++ } ++ } ++ while (dicPos < limit && buf < bufLimit); ++ NORMALIZE; ++ p->buf = buf; ++ p->range = range; ++ p->code = code; ++ p->remainLen = len; ++ p->dicPos = dicPos; ++ p->processedPos = processedPos; ++ p->reps[0] = rep0; ++ p->reps[1] = rep1; ++ p->reps[2] = rep2; ++ p->reps[3] = rep3; ++ p->state = state; ++ ++ return SZ_OK; ++} ++ ++static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) ++{ ++ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) ++ { ++ Byte *dic = p->dic; ++ SizeT dicPos = p->dicPos; ++ SizeT dicBufSize = p->dicBufSize; ++ unsigned len = p->remainLen; ++ UInt32 rep0 = p->reps[0]; ++ if (limit - dicPos < len) ++ len = (unsigned)(limit - dicPos); ++ ++ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) ++ p->checkDicSize = p->prop.dicSize; ++ ++ p->processedPos += len; ++ p->remainLen -= len; ++ while (len-- != 0) ++ { ++ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; ++ dicPos++; ++ } ++ p->dicPos = dicPos; ++ } ++} ++ ++static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) ++{ ++ do ++ { ++ SizeT limit2 = limit; ++ if (p->checkDicSize == 0) ++ { ++ UInt32 rem = p->prop.dicSize - p->processedPos; ++ if (limit - p->dicPos > rem) ++ limit2 = p->dicPos + rem; ++ } ++ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); ++ if (p->processedPos >= p->prop.dicSize) ++ p->checkDicSize = p->prop.dicSize; ++ LzmaDec_WriteRem(p, limit); ++ } ++ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); ++ ++ if (p->remainLen > kMatchSpecLenStart) ++ { ++ p->remainLen = kMatchSpecLenStart; ++ } ++ return 0; ++} ++ ++typedef enum ++{ ++ DUMMY_ERROR, /* unexpected end of input stream */ ++ DUMMY_LIT, ++ DUMMY_MATCH, ++ DUMMY_REP ++} ELzmaDummy; ++ ++static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) ++{ ++ UInt32 range = p->range; ++ UInt32 code = p->code; ++ const Byte *bufLimit = buf + inSize; ++ UIntLzmaProb *probs = p->probs; ++ unsigned state = p->state; ++ ELzmaDummy res; ++ ++ { ++ UIntLzmaProb *prob; ++ UInt32 bound; ++ unsigned ttt; ++ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); ++ ++ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK ++ ++ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ ++ ++ prob = probs + Literal; ++ if (p->checkDicSize != 0 || p->processedPos != 0) ++ prob += (LZMA_LIT_SIZE * ++ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + ++ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); ++ ++ if (state < kNumLitStates) ++ { ++ unsigned symbol = 1; ++ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); ++ } ++ else ++ { ++ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + ++ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; ++ unsigned offs = 0x100; ++ unsigned symbol = 1; ++ do ++ { ++ unsigned bit; ++ UIntLzmaProb *probLit; ++ matchByte <<= 1; ++ bit = (matchByte & offs); ++ probLit = prob + offs + bit + symbol; ++ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) ++ } ++ while (symbol < 0x100); ++ } ++ res = DUMMY_LIT; ++ } ++ else ++ { ++ unsigned len; ++ UPDATE_1_CHECK; ++ ++ prob = probs + IsRep + state; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK; ++ state = 0; ++ prob = probs + LenCoder; ++ res = DUMMY_MATCH; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ res = DUMMY_REP; ++ prob = probs + IsRepG0 + state; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK; ++ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK; ++ NORMALIZE_CHECK; ++ return DUMMY_REP; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ } ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ prob = probs + IsRepG1 + state; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ prob = probs + IsRepG2 + state; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ } ++ } ++ } ++ state = kNumStates; ++ prob = probs + RepLenCoder; ++ } ++ { ++ unsigned limit, offset; ++ UIntLzmaProb *probLen = prob + LenChoice; ++ IF_BIT_0_CHECK(probLen) ++ { ++ UPDATE_0_CHECK; ++ probLen = prob + LenLow + (posState << kLenNumLowBits); ++ offset = 0; ++ limit = 1 << kLenNumLowBits; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ probLen = prob + LenChoice2; ++ IF_BIT_0_CHECK(probLen) ++ { ++ UPDATE_0_CHECK; ++ probLen = prob + LenMid + (posState << kLenNumMidBits); ++ offset = kLenNumLowSymbols; ++ limit = 1 << kLenNumMidBits; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ probLen = prob + LenHigh; ++ offset = kLenNumLowSymbols + kLenNumMidSymbols; ++ limit = 1 << kLenNumHighBits; ++ } ++ } ++ TREE_DECODE_CHECK(probLen, limit, len); ++ len += offset; ++ } ++ ++ if (state < 4) ++ { ++ unsigned posSlot; ++ prob = probs + PosSlot + ++ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << ++ kNumPosSlotBits); ++ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); ++ if (posSlot >= kStartPosModelIndex) ++ { ++ int numDirectBits = ((posSlot >> 1) - 1); ++ ++ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ ++ ++ if (posSlot < kEndPosModelIndex) ++ { ++ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; ++ } ++ else ++ { ++ numDirectBits -= kNumAlignBits; ++ do ++ { ++ NORMALIZE_CHECK ++ range >>= 1; ++ code -= range & (((code - range) >> 31) - 1); ++ /* if (code >= range) code -= range; */ ++ } ++ while (--numDirectBits != 0); ++ prob = probs + Align; ++ numDirectBits = kNumAlignBits; ++ } ++ { ++ unsigned i = 1; ++ do ++ { ++ GET_BIT_CHECK(prob + i, i); ++ } ++ while (--numDirectBits != 0); ++ } ++ } ++ } ++ } ++ } ++ NORMALIZE_CHECK; ++ return res; ++} ++ ++ ++static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) ++{ ++ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); ++ p->range = 0xFFFFFFFF; ++ p->needFlush = 0; ++} ++ ++void LzmaDec_Init(CLzmaDec *p) ++{ ++ p->dicFilePos = 0; ++ p->dicPos = 0; ++ p->needFlush = 1; ++ p->remainLen = 0; ++ p->tempBufSize = 0; ++ p->processedPos = 0; ++ p->checkDicSize = 0; ++ p->needInitState = 1; ++ p->needInitState = 1; ++} ++ ++static void LzmaDec_InitStateReal(CLzmaDec *p) ++{ ++ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); ++ UInt32 i; ++ UIntLzmaProb *probs = p->probs; ++ for (i = 0; i < numProbs; i++) ++ probs[i] = kBitModelTotal >> 1; ++ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; ++ p->state = 0; ++ p->needInitState = 0; ++} ++ ++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, ++ ELzmaFinishMode finishMode, ELzmaStatus *status) ++{ ++ SizeT inSize = *srcLen; ++ (*srcLen) = 0; ++ LzmaDec_WriteRem(p, dicLimit); ++ ++ *status = LZMA_STATUS_NOT_SPECIFIED; ++ ++ while (p->remainLen != kMatchSpecLenStart) ++ { ++ int checkEndMarkNow; ++ ++ if (p->needFlush != 0) ++ { ++ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) ++ p->tempBuf[p->tempBufSize++] = *src++; ++ if (p->tempBufSize < RC_INIT_SIZE) ++ { ++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; ++ return SZ_OK; ++ } ++ if (p->tempBuf[0] != 0) ++ return SZ_ERROR_DATA; ++ ++ LzmaDec_InitRc(p, p->tempBuf); ++ p->tempBufSize = 0; ++ } ++ ++ checkEndMarkNow = 0; ++ if (p->dicPos >= dicLimit) ++ { ++ if (p->remainLen == 0 && p->code == 0) ++ { ++ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; ++ return SZ_OK; ++ } ++ if (finishMode == LZMA_FINISH_ANY) ++ { ++ *status = LZMA_STATUS_NOT_FINISHED; ++ return SZ_OK; ++ } ++ if (p->remainLen != 0) ++ { ++ *status = LZMA_STATUS_NOT_FINISHED; ++ return SZ_ERROR_DATA; ++ } ++ checkEndMarkNow = 1; ++ } ++ ++ if (p->needInitState) ++ LzmaDec_InitStateReal(p); ++ ++ if (p->tempBufSize == 0) ++ { ++ SizeT processed; ++ const Byte *bufLimit; ++ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) ++ { ++ int dummyRes = LzmaDec_TryDummy(p, src, inSize); ++ if (dummyRes == DUMMY_ERROR) ++ { ++ memcpy(p->tempBuf, src, inSize); ++ p->tempBufSize = (unsigned)inSize; ++ (*srcLen) += inSize; ++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; ++ return SZ_OK; ++ } ++ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) ++ { ++ *status = LZMA_STATUS_NOT_FINISHED; ++ return SZ_ERROR_DATA; ++ } ++ bufLimit = src; ++ } ++ else ++ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; ++ p->buf = src; ++ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) ++ return SZ_ERROR_DATA; ++ processed = (SizeT)(p->buf - src); ++ (*srcLen) += processed; ++ src += processed; ++ inSize -= processed; ++ } ++ else ++ { ++ unsigned rem = p->tempBufSize, lookAhead = 0; ++ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) ++ p->tempBuf[rem++] = src[lookAhead++]; ++ p->tempBufSize = rem; ++ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) ++ { ++ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); ++ if (dummyRes == DUMMY_ERROR) ++ { ++ (*srcLen) += lookAhead; ++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; ++ return SZ_OK; ++ } ++ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) ++ { ++ *status = LZMA_STATUS_NOT_FINISHED; ++ return SZ_ERROR_DATA; ++ } ++ } ++ p->buf = p->tempBuf; ++ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) ++ return SZ_ERROR_DATA; ++ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); ++ (*srcLen) += lookAhead; ++ src += lookAhead; ++ inSize -= lookAhead; ++ p->tempBufSize = 0; ++ } ++ } ++ if (p->code == 0) ++ *status = LZMA_STATUS_FINISHED_WITH_MARK; ++ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; ++} ++ ++/* -------------------------------------------------------------------------- */ ++ ++#define ReadUnalignedUInt32(p) ((UInt32)((Byte*)(p))[0] | ((UInt32)((Byte*)(p))[1]<<8) | ((UInt32)((Byte*)(p))[2]<<16) | ((UInt32)((Byte*)(p))[3]<<24)) ++#define ReadUnalignedUInt64(p) (ReadUnalignedUInt32(p) | ((UInt64)ReadUnalignedUInt32((Byte*)(p)+4)<<32)) ++ ++CLzmaDec lzmadec; ++ ++static unsigned long malloc_top = 0; ++static void *grub_malloc(unsigned long size) ++{ ++ if (!malloc_top) ++ malloc_top = RAW_ADDR ((saved_mem_upper << 10) + 0x100000); ++ malloc_top = (malloc_top - size) & ~3; ++ return (void *) malloc_top; ++} ++#define grub_free(x) ++ ++int ++dec_lzma_open (void) ++// return 1=success or 0=failure ++{ ++ unsigned char header[13]; ++ unsigned char d; ++ ++ if (no_decompression) return 0; ++ ++ // Now it does not support openning more than 1 file at a time. ++ // Make sure previously allocated memory blocks is freed. ++ // Don't need this line if grub_close is called for every openned file before grub_open is called for next file. ++ dec_lzma_close(); ++ ++ filepos = 0; ++ if (grub_read ((char *)header, 13, 0xedde0d90) == 13) ++ { ++ // check header ++ lzmadec.prop.dicSize = ReadUnalignedUInt32(header+1); ++ if (lzmadec.prop.dicSize < LZMA_DIC_MIN) ++ lzmadec.prop.dicSize = LZMA_DIC_MIN; ++ d = header[0]; ++ if (d < 9*5*5) ++ { ++ // valid LZMA file ++ lzmadec.prop.lc = d % 9; d /= 9; ++ lzmadec.prop.lp = d % 5; ++ lzmadec.prop.pb = d / 5; ++ lzmadec.fileu.fmax = ReadUnalignedUInt64(header+5); ++ lzmadec.fileu.fpos = 0; ++ lzmadec.dicBufSize = lzmadec.prop.dicSize; ++ lzmadec.dic = (Byte*) grub_malloc(lzmadec.dicBufSize); ++ //grub_printf("LZMA allocate memory\n"); ++ if (lzmadec.dic) ++ { ++ lzmadec.numProbs = LzmaProps_GetNumProbs(&lzmadec.prop); ++ lzmadec.probs = (UIntLzmaProb *) grub_malloc(lzmadec.numProbs * sizeof(UIntLzmaProb)); ++ if (lzmadec.probs) ++ { ++ lzmadec.inpBufSize = 0x8000; ++ lzmadec.inp = (Byte*) grub_malloc(lzmadec.inpBufSize); ++ if (lzmadec.inp) ++ { ++ lzmadec.inpFilePos = 0; ++ lzmadec.inpPos = 0; ++ lzmadec.inpSize = 0; ++ LzmaDec_Init(&lzmadec); ++ decomp_type = 1; ++ compressed_file = 1; ++ lzmadec.filec.fmax = filemax; filemax = lzmadec.fileu.fmax; ++ lzmadec.filec.fpos = filepos; filepos = lzmadec.fileu.fpos; ++ // success ++ //grub_printf("LZMA open success\n"); ++ errnum = 0; ++ return 1; ++ } ++ else ++ { ++ errnum = ERR_NOT_ENOUGH_MEMORY; ++ } ++ grub_free(lzmadec.probs); lzmadec.probs = 0; ++ } ++ else ++ { ++ errnum = ERR_NOT_ENOUGH_MEMORY; ++ } ++ grub_free(lzmadec.dic); lzmadec.dic = 0; ++ } ++ else ++ { ++ errnum = ERR_NOT_ENOUGH_MEMORY; ++ } ++ } ++ else ++ { ++ //grub_printf("LZMA allocate memory\n"); ++ errnum = ERR_BAD_GZIP_HEADER; ++ } ++ } ++ else ++ { ++ //grub_printf("LZMA error reading header\n"); ++ errnum = ERR_BAD_GZIP_HEADER; ++ } ++ //grub_printf("LZMA open fail\n"); ++ filepos = 0; ++ return 0; ++} ++ ++void ++dec_lzma_close (void) ++{ ++ if (lzmadec.inp ) { grub_free(lzmadec.inp ); lzmadec.inp = 0; } ++ if (lzmadec.dic ) { grub_free(lzmadec.dic ); lzmadec.dic = 0; } ++ if (lzmadec.probs) { grub_free(lzmadec.probs); lzmadec.probs = 0; } ++} ++ ++unsigned long ++dec_lzma_read (char *buf, unsigned long len, unsigned long write) ++{ ++ UInt64 outTx, outSkip; ++ //grub_printf("LZMA read buf=%ld len=%ld dic=%d inp=%d\n",buf,len,lzmadec.dic,lzmadec.inp); ++ ++ compressed_file = 0; ++ lzmadec.fileu.fmax = filemax; filemax = lzmadec.filec.fmax; ++ lzmadec.fileu.fpos = filepos; filepos = lzmadec.filec.fpos; ++ /* Now filepos, filemax is of compressed file ++ * fileu.fpos, fileu.fmax is of uncompressed data ++ * filec is not used ++ */ ++ ++ /* ++ * When dicPos>0, ++ * dic[0 ... dicPos-1] contains ++ * uncompressed_data [dicFilePos ... dicFilePos+dicPos-1]. ++ * When dicFilePos>0, ++ * dic[dicPos ... dicBufSize-1] contains ++ * uncompressed_data [dicFilePos-dicBufSize+dicFilePos ... dicFilePos-1] ++ */ ++ /* do we reset decompression to the beginning of the file? */ ++ if (lzmadec.dicFilePos && (lzmadec.fileu.fpos < lzmadec.dicFilePos-lzmadec.dicBufSize+lzmadec.dicFilePos)) ++ { ++ LzmaDec_Init(&lzmadec); ++ filepos = 13; ++ lzmadec.inpPos = lzmadec.inpSize = 0; ++ } ++ ++ outTx = 0; ++ outSkip = lzmadec.fileu.fpos - lzmadec.dicFilePos; ++ //grub_printf("fileu.fpos=%ld dicFilePos=%ld\n",lzmadec.fileu.fpos,lzmadec.dicFilePos); ++ ++ /* Copy uncompressed data from upper part of dic. dic[dicPos]...dic[dicBufSize-1] */ ++ if (lzmadec.dicFilePos > lzmadec.fileu.fpos) ++ { ++ UInt32 outTxCur = lzmadec.dicFilePos - lzmadec.fileu.fpos; ++ if (outTxCur > len) outTxCur = len; ++ if (buf) ++ { ++ grub_memmove(buf, lzmadec.dic+outSkip+lzmadec.dicBufSize, outTxCur); ++ buf += outTxCur; ++ } ++ outSkip = 0; ++ outTx += outTxCur; ++ lzmadec.fileu.fpos += outTxCur; ++ len -= outTxCur; ++ } ++ ++ while (len!=0) ++ { ++ SizeT inSizeCur, dicLimit; ++ UInt32 dicPos; ++ ELzmaStatus status; ++ SRes res; ++ ++ /* Copy uncompressed data from lower part of dic. dic[0]...dic[dicPos-1] */ ++ //grub_printf("Loop len=%ld outSkip=%ld dicPos=%d\n",len,outSkip,lzmadec.dicPos); ++ if (outSkip < lzmadec.dicPos) ++ { ++ UInt32 outTxCur = lzmadec.dicPos - outSkip; ++ //grub_printf("Copy %d byte ",outTxCur); ++ if (buf) ++ { ++ grub_memmove(buf, lzmadec.dic+outSkip, outTxCur); ++ buf += outTxCur; ++ } ++ outSkip = lzmadec.dicPos; ++ outTx += outTxCur; ++ lzmadec.fileu.fpos += outTxCur; ++ len -= outTxCur; ++ //grub_printf(" remaining len=%ld\n",len); ++ if (len==0) break; ++ } ++ /* All existing wanted data from dic have been copied. We will add more data to dic. */ ++ /* Read more input if there is no unprocessed input left. */ ++ if (lzmadec.inpPos == lzmadec.inpSize) ++ { ++ UInt32 inTxCur = (filemax-filepos%d\n",lzmadec.inpSize); ++ } ++ inSizeCur = lzmadec.inpSize - lzmadec.inpPos; ++ ++ /* Prepare output dicPos, dicLimit. */ ++ if (lzmadec.dicPos == lzmadec.dicBufSize) ++ { ++ lzmadec.dicPos = 0; ++ outSkip -= lzmadec.dicBufSize; ++ } ++ dicPos = lzmadec.dicPos; ++ dicLimit = (lzmadec.dicBufSize-dicPos < len)? lzmadec.dicBufSize: dicPos+len; ++ ++ /* Do decompression. */ ++ //grub_printf("DecodeToDic dicPos=%d limit=%d inPos=%d inSize=%d ",dicPos,dicLimit,lzmadec.inpPos,inSizeCur); ++ status = LZMA_STATUS_NOT_SPECIFIED; ++ res = LzmaDec_DecodeToDic(&lzmadec, dicLimit, lzmadec.inp+lzmadec.inpPos, &inSizeCur, LZMA_FINISH_ANY, &status); ++ //grub_printf("->%d\n",inSizeCur); ++ lzmadec.inpPos += inSizeCur; ++ if (inSizeCur==0 && lzmadec.dicPos==dicPos) ++ { ++ /* Error */ ++ //grub_printf("No more input and output\n"); ++ break; ++ } ++ } ++ compressed_file = 1; ++ lzmadec.filec.fmax = filemax; filemax = lzmadec.fileu.fmax; ++ lzmadec.filec.fpos = filepos; filepos = lzmadec.fileu.fpos; ++ /* Now filepos, file max is of uncompressed data ++ * filec.fpos, filwc.fmax is of compressed file ++ * fileu is not used ++ */ ++ ++ //grub_printf("LZMA read end %ld\n",outTx); ++ return outTx; ++} ++ ++#endif /* ! NO_DECOMPRESSION */ +diff -Naur ../grub4dos-chenall-r63/stage2/decomp.h ./stage2/decomp.h +--- grub4dos-chenall-r63/stage2/decomp.h 1970-01-01 07:00:00.000000000 +0700 ++++ grub4dos/stage2/decomp.h 2010-11-28 13:51:54.687217000 +0700 +@@ -0,0 +1,36 @@ ++/* decomp.h - abstract decompression interface */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 1999,2000,2001,2004 Free Software Foundation, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef ASM_FILE ++ ++struct decomp_entry ++{ ++ char *name; ++ int (*open_func) (void); ++ void (*close_func) (void); ++ unsigned long (*read_func) (char *buf, unsigned long len, unsigned long write); ++}; ++ ++#define NUM_DECOM 2 ++ ++extern struct decomp_entry decomp_table[NUM_DECOM]; ++extern int decomp_type; ++ ++#endif +\ No newline at end of file +diff -Naur ../grub4dos-chenall-r63/stage2/disk_io.c ./stage2/disk_io.c +--- grub4dos-chenall-r63/stage2/disk_io.c 2010-08-12 14:22:47.111207000 +0700 ++++ grub4dos/stage2/disk_io.c 2010-11-28 20:26:39.089887300 +0700 +@@ -21,6 +21,7 @@ + + #include + #include ++#include + #include + + #ifdef SUPPORT_NETBOOT +@@ -1872,7 +1873,16 @@ + #ifdef NO_DECOMPRESSION + return 1; + #else +- return gunzip_test_header (); ++ if (no_decompression) ++ return 1; ++ int i; ++ i = strlen(open_filename); ++ if (i>=5 && strcmp(open_filename+i-5,".lzma")==0) ++ dec_lzma_open (); ++ else ++ gunzip_test_header (); ++ errnum = 0; ++ return 1; + #endif + } + +@@ -1903,7 +1903,7 @@ + { + if (write == 0x900ddeed) + return !(errnum = ERR_WRITE_GZIP_FILE); +- return gunzip_read (buf, len); ++ return decomp_table[decomp_type].read_func (buf, len, write); + } + #endif /* NO_DECOMPRESSION */ + +@@ -1978,6 +1982,12 @@ + void + grub_close (void) + { ++#ifndef NO_DECOMPRESSION ++ if (compressed_file) ++ decomp_table[decomp_type].close_func (); ++ compressed_file = 0; ++#endif /* NO_DECOMPRESSION */ ++ + #ifndef NO_BLOCK_FILES + if (block_file) + return; +diff -Naur ../grub4dos-chenall-r63/stage2/gunzip.c ./stage2/gunzip.c +--- grub4dos-chenall-r63/stage2/gunzip.c 2010-07-26 19:35:48.440546000 +0700 ++++ grub4dos/stage2/gunzip.c 2010-11-28 14:20:56.983870700 +0700 +@@ -129,6 +129,8 @@ + + #include "filesys.h" + ++#include "decomp.h" ++ + /* so we can disable decompression */ + #ifdef GRUB_UTIL + int no_decompression = 0; +@@ -137,6 +139,15 @@ + /* used to tell if "read" should be redirected to "gunzip_read" */ + int compressed_file; + ++/* identify active decompressor */ ++int decomp_type; ++ ++struct decomp_entry decomp_table[NUM_DECOM] = ++{ ++ {"gz",gunzip_test_header,gunzip_close,gunzip_read}, ++ {"lzma",dec_lzma_open,dec_lzma_close,dec_lzma_read} ++}; ++ + /* internal variables only */ + static unsigned long long gzip_data_offset; + static unsigned long long gzip_filepos; +@@ -227,6 +238,7 @@ + /* Little-Endian defines for the 2-byte magic number for gzip files */ + #define GZIP_HDR_LE 0x8B1F + #define OLD_GZIP_HDR_LE 0x9E1F ++#define LZMA_HDR_LE 0x005D + + /* Compression methods (see algorithm.doc) */ + #define STORED 0 +@@ -281,10 +292,18 @@ + if (no_decompression + || grub_read ((char *)buf, 10, 0xedde0d90) != 10 + || ((*((unsigned short *) buf) != GZIP_HDR_LE) +- && (*((unsigned short *) buf) != OLD_GZIP_HDR_LE))) ++ && (*((unsigned short *) buf) != OLD_GZIP_HDR_LE) ++ && (*((unsigned short *) buf) != LZMA_HDR_LE))) + { + filepos = 0; + return ! errnum; ++ } ++ ++ if (*((unsigned short *) buf) == LZMA_HDR_LE) ++ { ++ filepos = 0; ++ dec_lzma_open(); ++ return 1; + } + + /* +@@ -323,6 +334,7 @@ + + initialize_tables (); + ++ decomp_type = 0; + compressed_file = 1; + gunzip_swap_values (); + /* +@@ -334,6 +346,11 @@ + return 1; + } + ++void ++gunzip_close (void) ++{ ++} ++ + + /* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). +@@ -1190,7 +1226,7 @@ + + + unsigned long +-gunzip_read (char *buf, unsigned long len) ++gunzip_read (char *buf, unsigned long len, unsigned long write) + { + unsigned long ret = 0; + +diff -Naur ../grub4dos-chenall-r63/stage2/Makefile.am ./stage2/Makefile.am +--- grub4dos-chenall-r63/stage2/Makefile.am 2010-08-12 14:22:47.111207000 +0700 ++++ grub4dos/stage2/Makefile.am 2010-11-28 16:35:18.724975900 +0700 +@@ -16,6 +16,7 @@ + # The library for /sbin/grub. + noinst_LIBRARIES = libgrub.a + libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \ ++ dec_lzma.c \ + disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ntfs.c fsys_ffs.c fsys_iso9660.c \ + fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \ + fsys_vstafs.c fsys_xfs.c fsys_pxe.c gunzip.c md5.c serial.c stage2.c \ +@@ -100,7 +101,7 @@ + + # For stage2 target. + pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \ +- cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \ ++ cmdline.c common.c console.c dec_lzma.c disk_io.c fsys_ext2fs.c \ + fsys_fat.c fsys_ntfs.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \ + fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c fsys_pxe.c gunzip.c \ + hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c graphics.c +diff -Naur ../grub4dos-chenall-r63/stage2/Makefile.in ./stage2/Makefile.in +--- grub4dos-chenall-r63/stage2/Makefile.in 2010-08-12 14:22:47.111207000 +0700 ++++ grub4dos/stage2/Makefile.in 2010-11-28 16:38:22.871508400 +0700 +@@ -104,10 +104,11 @@ + am_libgrub_a_OBJECTS = libgrub_a-boot.$(OBJEXT) \ + libgrub_a-builtins.$(OBJEXT) libgrub_a-char_io.$(OBJEXT) \ + libgrub_a-cmdline.$(OBJEXT) libgrub_a-common.$(OBJEXT) \ +- libgrub_a-disk_io.$(OBJEXT) libgrub_a-fsys_ext2fs.$(OBJEXT) \ +- libgrub_a-fsys_fat.$(OBJEXT) libgrub_a-fsys_ntfs.$(OBJEXT) \ +- libgrub_a-fsys_ffs.$(OBJEXT) libgrub_a-fsys_iso9660.$(OBJEXT) \ +- libgrub_a-fsys_jfs.$(OBJEXT) libgrub_a-fsys_minix.$(OBJEXT) \ ++ libgrub_a-dec_lzma.$(OBJEXT) libgrub_a-disk_io.$(OBJEXT) \ ++ libgrub_a-fsys_ext2fs.$(OBJEXT) libgrub_a-fsys_fat.$(OBJEXT) \ ++ libgrub_a-fsys_ntfs.$(OBJEXT) libgrub_a-fsys_ffs.$(OBJEXT) \ ++ libgrub_a-fsys_iso9660.$(OBJEXT) libgrub_a-fsys_jfs.$(OBJEXT) \ ++ libgrub_a-fsys_minix.$(OBJEXT) \ + libgrub_a-fsys_reiserfs.$(OBJEXT) \ + libgrub_a-fsys_ufs2.$(OBJEXT) libgrub_a-fsys_vstafs.$(OBJEXT) \ + libgrub_a-fsys_xfs.$(OBJEXT) libgrub_a-fsys_pxe.$(OBJEXT) \ +@@ -131,6 +132,7 @@ + diskless_exec-char_io.$(OBJEXT) \ + diskless_exec-cmdline.$(OBJEXT) diskless_exec-common.$(OBJEXT) \ + diskless_exec-console.$(OBJEXT) \ ++ diskless_exec-dec_lzma.$(OBJEXT) \ + diskless_exec-disk_io.$(OBJEXT) \ + diskless_exec-fsys_ext2fs.$(OBJEXT) \ + diskless_exec-fsys_fat.$(OBJEXT) \ +@@ -247,6 +249,7 @@ + pre_stage2_exec-cmdline.$(OBJEXT) \ + pre_stage2_exec-common.$(OBJEXT) \ + pre_stage2_exec-console.$(OBJEXT) \ ++ pre_stage2_exec-dec_lzma.$(OBJEXT) \ + pre_stage2_exec-disk_io.$(OBJEXT) \ + pre_stage2_exec-fsys_ext2fs.$(OBJEXT) \ + pre_stage2_exec-fsys_fat.$(OBJEXT) \ +@@ -512,6 +513,7 @@ + # The library for /sbin/grub. + noinst_LIBRARIES = libgrub.a + libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \ ++ dec_lzma.c \ + disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ntfs.c fsys_ffs.c fsys_iso9660.c \ + fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \ + fsys_vstafs.c fsys_xfs.c fsys_pxe.c gunzip.c md5.c serial.c stage2.c \ +@@ -559,7 +563,7 @@ + + # For stage2 target. + pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \ +- cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \ ++ cmdline.c common.c console.c dec_lzma.c disk_io.c fsys_ext2fs.c \ + fsys_fat.c fsys_ntfs.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \ + fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c fsys_pxe.c gunzip.c \ + hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c graphics.c +@@ -878,6 +882,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-cmdline.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-common.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-console.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-dec_lzma.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-disk_io.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_ext2fs.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_fat.Po@am__quote@ +@@ -935,6 +940,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-char_io.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-cmdline.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-common.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-dec_lzma.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-disk_io.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_ext2fs.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_fat.Po@am__quote@ +@@ -974,6 +980,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-cmdline.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-common.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-console.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-dec_lzma.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-disk_io.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_ext2fs.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_fat.Po@am__quote@ +@@ -1315,6 +1322,20 @@ + @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` + ++libgrub_a-dec_lzma.o: dec_lzma.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-dec_lzma.o -MD -MP -MF "$(DEPDIR)/libgrub_a-dec_lzma.Tpo" -c -o libgrub_a-dec_lzma.o `test -f 'dec_lzma.c' || echo '$(srcdir)/'`dec_lzma.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgrub_a-dec_lzma.Tpo" "$(DEPDIR)/libgrub_a-dec_lzma.Po"; else rm -f "$(DEPDIR)/libgrub_a-dec_lzma.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_lzma.c' object='libgrub_a-dec_lzma.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-dec_lzma.o `test -f 'dec_lzma.c' || echo '$(srcdir)/'`dec_lzma.c ++ ++libgrub_a-dec_lzma.obj: dec_lzma.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-dec_lzma.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-dec_lzma.Tpo" -c -o libgrub_a-dec_lzma.obj `if test -f 'dec_lzma.c'; then $(CYGPATH_W) 'dec_lzma.c'; else $(CYGPATH_W) '$(srcdir)/dec_lzma.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgrub_a-dec_lzma.Tpo" "$(DEPDIR)/libgrub_a-dec_lzma.Po"; else rm -f "$(DEPDIR)/libgrub_a-dec_lzma.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_lzma.c' object='libgrub_a-dec_lzma.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-dec_lzma.obj `if test -f 'dec_lzma.c'; then $(CYGPATH_W) 'dec_lzma.c'; else $(CYGPATH_W) '$(srcdir)/dec_lzma.c'; fi` ++ + libgrub_a-disk_io.o: disk_io.c + @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-disk_io.o -MD -MP -MF "$(DEPDIR)/libgrub_a-disk_io.Tpo" -c -o libgrub_a-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \ + @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgrub_a-disk_io.Tpo" "$(DEPDIR)/libgrub_a-disk_io.Po"; else rm -f "$(DEPDIR)/libgrub_a-disk_io.Tpo"; exit 1; fi +@@ -1693,6 +1714,20 @@ + @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi` + ++diskless_exec-dec_lzma.o: dec_lzma.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-dec_lzma.o -MD -MP -MF "$(DEPDIR)/diskless_exec-dec_lzma.Tpo" -c -o diskless_exec-dec_lzma.o `test -f 'dec_lzma.c' || echo '$(srcdir)/'`dec_lzma.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/diskless_exec-dec_lzma.Tpo" "$(DEPDIR)/diskless_exec-dec_lzma.Po"; else rm -f "$(DEPDIR)/diskless_exec-dec_lzma.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_lzma.c' object='diskless_exec-dec_lzma.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-dec_lzma.o `test -f 'dec_lzma.c' || echo '$(srcdir)/'`dec_lzma.c ++ ++diskless_exec-dec_lzma.obj: dec_lzma.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-dec_lzma.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-dec_lzma.Tpo" -c -o diskless_exec-dec_lzma.obj `if test -f 'dec_lzma.c'; then $(CYGPATH_W) 'dec_lzma.c'; else $(CYGPATH_W) '$(srcdir)/dec_lzma.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/diskless_exec-dec_lzma.Tpo" "$(DEPDIR)/diskless_exec-dec_lzma.Po"; else rm -f "$(DEPDIR)/diskless_exec-dec_lzma.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_lzma.c' object='diskless_exec-dec_lzma.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-dec_lzma.obj `if test -f 'dec_lzma.c'; then $(CYGPATH_W) 'dec_lzma.c'; else $(CYGPATH_W) '$(srcdir)/dec_lzma.c'; fi` ++ + diskless_exec-disk_io.o: disk_io.c + @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/diskless_exec-disk_io.Tpo" -c -o diskless_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \ + @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/diskless_exec-disk_io.Tpo" "$(DEPDIR)/diskless_exec-disk_io.Po"; else rm -f "$(DEPDIR)/diskless_exec-disk_io.Tpo"; exit 1; fi +@@ -2687,6 +2722,20 @@ + @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi` + ++pre_stage2_exec-dec_lzma.o: dec_lzma.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-dec_lzma.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-dec_lzma.Tpo" -c -o pre_stage2_exec-dec_lzma.o `test -f 'dec_lzma.c' || echo '$(srcdir)/'`dec_lzma.c; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/pre_stage2_exec-dec_lzma.Tpo" "$(DEPDIR)/pre_stage2_exec-dec_lzma.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-dec_lzma.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_lzma.c' object='pre_stage2_exec-dec_lzma.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-dec_lzma.o `test -f 'dec_lzma.c' || echo '$(srcdir)/'`dec_lzma.c ++ ++pre_stage2_exec-dec_lzma.obj: dec_lzma.c ++@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-dec_lzma.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-dec_lzma.Tpo" -c -o pre_stage2_exec-dec_lzma.obj `if test -f 'dec_lzma.c'; then $(CYGPATH_W) 'dec_lzma.c'; else $(CYGPATH_W) '$(srcdir)/dec_lzma.c'; fi`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/pre_stage2_exec-dec_lzma.Tpo" "$(DEPDIR)/pre_stage2_exec-dec_lzma.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-dec_lzma.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dec_lzma.c' object='pre_stage2_exec-dec_lzma.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-dec_lzma.obj `if test -f 'dec_lzma.c'; then $(CYGPATH_W) 'dec_lzma.c'; else $(CYGPATH_W) '$(srcdir)/dec_lzma.c'; fi` ++ + pre_stage2_exec-disk_io.o: disk_io.c + @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-disk_io.Tpo" -c -o pre_stage2_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \ + @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/pre_stage2_exec-disk_io.Tpo" "$(DEPDIR)/pre_stage2_exec-disk_io.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-disk_io.Tpo"; exit 1; fi +diff -Naur ../grub4dos-chenall-r63/stage2/shared.h ./stage2/shared.h +--- grub4dos-chenall-r63/stage2/shared.h 2010-11-17 15:33:51.826683000 +0700 ++++ grub4dos/stage2/shared.h 2010-11-27 01:16:46.996893700 +0700 +@@ -640,6 +640,7 @@ + ERR_WRITE_GZIP_FILE, + ERR_FUNC_CALL, + // ERR_WRITE_TO_NON_MEM_DRIVE, ++ ERR_NOT_ENOUGH_MEMORY, + + MAX_ERR_NUM + } grub_error_t; +@@ -1185,7 +1186,11 @@ + #ifndef NO_DECOMPRESSION + /* Compression support. */ + int gunzip_test_header (void); +-unsigned long gunzip_read (char *buf, unsigned long len); ++void gunzip_close (void); ++unsigned long gunzip_read (char *buf, unsigned long len, unsigned long write); ++int dec_lzma_open (void); ++void dec_lzma_close (void); ++unsigned long dec_lzma_read (char *buf, unsigned long len, unsigned long write); + #endif /* NO_DECOMPRESSION */ + + int rawread (unsigned long drive, unsigned long sector, unsigned long byte_offset, unsigned long byte_len, char *buf, unsigned long write);