📄 lzexpand_main.c
字号:
return LZERROR_BADVALUE;
}
WideCharToMultiByte( CP_ACP, 0, in, -1, xin, len, NULL, NULL );
if ((ret = GetExpandedNameA( xin, xout )) > 0)
MultiByteToWideChar( CP_ACP, 0, xout, -1, out, wcslen(in)+4 );
RtlFreeHeap( RtlGetProcessHeap(), 0, xin );
RtlFreeHeap( RtlGetProcessHeap(), 0, xout );
return ret;
}
/***********************************************************************
* LZRead (LZ32.@)
*
* @implemented
*/
INT WINAPI LZRead( HFILE fd, LPSTR vbuf, INT toread )
{
int howmuch;
BYTE b,*buf;
struct lzstate *lzs;
buf=(LPBYTE)vbuf;
DPRINT("(%d,%p,%d)\n",fd,buf,toread);
howmuch=toread;
if (!(lzs = GET_LZ_STATE(fd))) return _hread(fd,buf,toread);
/* The decompressor itself is in a define, cause we need it twice
* in this function. (the decompressed byte will be in b)
*/
#define DECOMPRESS_ONE_BYTE \
if (lzs->stringlen) { \
b = lzs->table[lzs->stringpos]; \
lzs->stringpos = (lzs->stringpos+1)&0xFFF; \
lzs->stringlen--; \
} else { \
if (!(lzs->bytetype&0x100)) { \
if (1!=GET(lzs,b)) \
return toread-howmuch; \
lzs->bytetype = b|0xFF00; \
} \
if (lzs->bytetype & 1) { \
if (1!=GET(lzs,b)) \
return toread-howmuch; \
} else { \
BYTE b1,b2; \
\
if (1!=GET(lzs,b1)) \
return toread-howmuch; \
if (1!=GET(lzs,b2)) \
return toread-howmuch; \
/* Format: \
* b1 b2 \
* AB CD \
* where CAB is the stringoffset in the table\
* and D+3 is the len of the string \
*/ \
lzs->stringpos = b1|((b2&0xf0)<<4); \
lzs->stringlen = (b2&0xf)+2; \
/* 3, but we use a byte already below ... */\
b = lzs->table[lzs->stringpos];\
lzs->stringpos = (lzs->stringpos+1)&0xFFF;\
} \
lzs->bytetype>>=1; \
} \
/* store b in table */ \
lzs->table[lzs->curtabent++]= b; \
lzs->curtabent &= 0xFFF; \
lzs->realcurrent++;
/* if someone has seeked, we have to bring the decompressor
* to that position
*/
if (lzs->realcurrent!=lzs->realwanted) {
/* if the wanted position is before the current position
* I see no easy way to unroll ... We have to restart at
* the beginning. *sigh*
*/
if (lzs->realcurrent>lzs->realwanted) {
/* flush decompressor state */
_llseek(lzs->realfd,14,SEEK_SET);
GET_FLUSH(lzs);
lzs->realcurrent= 0;
lzs->bytetype = 0;
lzs->stringlen = 0;
memset(lzs->table,' ',0x1000);
lzs->curtabent = 0xFF0;
}
while (lzs->realcurrent<lzs->realwanted) {
DECOMPRESS_ONE_BYTE;
}
}
while (howmuch) {
DECOMPRESS_ONE_BYTE;
lzs->realwanted++;
*buf++ = b;
howmuch--;
}
return toread;
#undef DECOMPRESS_ONE_BYTE
}
/***********************************************************************
* LZSeek (LZ32.@)
*
* @implemented
*/
LONG WINAPI LZSeek( HFILE fd, LONG off, INT type )
{
struct lzstate *lzs;
LONG newwanted;
DPRINT("(%d,%ld,%d)\n",fd,off,type);
/* not compressed? just use normal _llseek() */
if (!(lzs = GET_LZ_STATE(fd))) return _llseek(fd,off,type);
newwanted = lzs->realwanted;
switch (type) {
case 1: /* SEEK_CUR */
newwanted += off;
break;
case 2: /* SEEK_END */
newwanted = lzs->reallength-off;
break;
default:/* SEEK_SET */
newwanted = off;
break;
}
if (newwanted>(LONG)lzs->reallength)
return LZERROR_BADVALUE;
if (newwanted<0)
return LZERROR_BADVALUE;
lzs->realwanted = newwanted;
return newwanted;
}
/***********************************************************************
* LZCopy (LZ32.@)
*
* Copies everything from src to dest
* if src is a LZ compressed file, it will be uncompressed.
* will return the number of bytes written to dest or errors.
*
* @implemented
*/
LONG WINAPI LZCopy( HFILE src, HFILE dest )
{
int usedlzinit=0,ret,wret;
LONG len;
HFILE oldsrc = src, srcfd;
FILETIME filetime;
struct lzstate *lzs;
#define BUFLEN 1000
CHAR buf[BUFLEN];
/* we need that weird typedef, for i can't seem to get function pointer
* casts right. (Or they probably just do not like WINAPI in general)
*/
typedef UINT (WINAPI *_readfun)(HFILE,LPVOID,UINT);
_readfun xread;
DPRINT("(%d,%d)\n",src,dest);
if (!IS_LZ_HANDLE(src)) {
src = LZInit(src);
if ((INT)src <= 0) return 0;
if (src != oldsrc) usedlzinit=1;
}
/* not compressed? just copy */
if (!IS_LZ_HANDLE(src))
xread=(_readfun)_hread;
else
xread=(_readfun)LZRead;
len=0;
while (1) {
ret=xread(src,buf,BUFLEN);
if (ret<=0) {
if (ret==0)
break;
if (ret==-1)
return LZERROR_READ;
return ret;
}
len += ret;
wret = _hwrite(dest,buf,ret);
if (wret!=ret)
return LZERROR_WRITE;
}
/* Maintain the timestamp of source file to destination file */
srcfd = (!(lzs = GET_LZ_STATE(src))) ? src : lzs->realfd;
GetFileTime((HANDLE)srcfd, NULL, NULL, &filetime);
SetFileTime((HANDLE)dest, NULL, NULL, &filetime);
/* close handle */
if (usedlzinit)
LZClose(src);
return len;
#undef BUFLEN
}
/* reverses GetExpandedPathname */
static LPSTR LZEXPAND_MangleName( LPCSTR fn )
{
char *p;
char *mfn = (char *)RtlAllocateHeap( GetProcessHeap(), 0,
strlen(fn) + 3 ); /* "._" and \0 */
if(mfn == NULL) return NULL;
strcpy( mfn, fn );
if (!(p = strrchr( mfn, '\\' ))) p = mfn;
if ((p = strchr( p, '.' )))
{
p++;
if (strlen(p) < 3) strcat( p, "_" ); /* append '_' */
else p[strlen(p)-1] = '_'; /* replace last character */
}
else strcat( mfn, "._" ); /* append "._" */
return mfn;
}
/***********************************************************************
* LZOpenFileA (LZ32.@)
*
* Opens a file. If not compressed, open it as a normal file.
*
* @implemented
*/
HFILE WINAPI LZOpenFileA( LPSTR fn, LPOFSTRUCT ofs, WORD mode )
{
HFILE fd,cfd;
DPRINT("(%s,%p,%d)\n",fn,ofs,mode);
/* 0x70 represents all OF_SHARE_* flags, ignore them for the check */
fd=OpenFile(fn,ofs,mode);
if (fd==HFILE_ERROR)
{
LPSTR mfn = LZEXPAND_MangleName(fn);
fd = OpenFile(mfn,ofs,mode);
RtlFreeHeap( GetProcessHeap(), 0, mfn );
}
if ((mode&~0x70)!=OF_READ)
return fd;
if (fd==HFILE_ERROR)
return HFILE_ERROR;
cfd=LZInit(fd);
if ((INT)cfd <= 0) return fd;
return cfd;
}
/***********************************************************************
* LZOpenFileW (LZ32.@)
*
* @implemented
*/
HFILE WINAPI LZOpenFileW( LPWSTR fn, LPOFSTRUCT ofs, WORD mode )
{
HFILE ret;
DWORD len = WideCharToMultiByte( CP_ACP, 0, fn, -1, NULL, 0, NULL, NULL );
LPSTR xfn = RtlAllocateHeap( GetProcessHeap(), 0, len );
WideCharToMultiByte( CP_ACP, 0, fn, -1, xfn, len, NULL, NULL );
ret = LZOpenFileA(xfn,ofs,mode);
RtlFreeHeap( GetProcessHeap(), 0, xfn );
return ret;
}
/***********************************************************************
* LZClose (LZ32.@)
*
* @implemented
*/
void WINAPI LZClose( HFILE fd )
{
struct lzstate *lzs;
DPRINT("(%d)\n",fd);
if (!(lzs = GET_LZ_STATE(fd))) _lclose(fd);
else
{
if (lzs->get) RtlFreeHeap( GetProcessHeap(), 0, lzs->get );
CloseHandle((HANDLE)lzs->realfd);
lzstates[fd - 0x400] = NULL;
RtlFreeHeap( GetProcessHeap(), 0, lzs );
}
}
/***********************************************************************
* CopyLZFile (LZ32.@)
*
* Copy src to dest (including uncompressing src).
* NOTE: Yes. This is exactly the same function as LZCopy.
*
* @implemented
*/
LONG WINAPI CopyLZFile( HFILE src, HFILE dest )
{
DPRINT("(%d,%d)\n",src,dest);
return LZCopy(src,dest);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -