📄 os2zip.c
字号:
ULONG cbList; /* length of value + 22 */
#ifdef __32BIT__
ULONG oNext;
#endif
BYTE fEA; /* 0 */
BYTE cbName; /* length of ".LONGNAME" = 9 */
USHORT cbValue; /* length of value + 4 */
BYTE szName[10]; /* ".LONGNAME" */
USHORT eaType; /* 0xFFFD for length-preceded ASCII */
USHORT eaSize; /* length of value */
BYTE szValue[CCHMAXPATH];
}
FEALST;
typedef struct
{
ULONG cbList;
#ifdef __32BIT__
ULONG oNext;
#endif
BYTE cbName;
BYTE szName[10]; /* ".LONGNAME" */
}
GEALST;
char *GetLongNameEA(char *name)
{
EAOP eaop;
GEALST gealst;
static FEALST fealst;
if ( _osmode == DOS_MODE )
return NULL;
eaop.fpGEAList = (PGEALIST) &gealst;
eaop.fpFEAList = (PFEALIST) &fealst;
eaop.oError = 0;
strcpy(gealst.szName, ".LONGNAME");
gealst.cbName = (BYTE) strlen(gealst.szName);
#ifdef __32BIT__
gealst.oNext = 0;
#endif
gealst.cbList = sizeof(gealst);
fealst.cbList = sizeof(fealst);
if ( DosQueryPathInfo(name, FIL_QUERYEASFROMLIST,
(PBYTE) &eaop, sizeof(eaop)) )
return NULL;
if ( fealst.cbValue > 4 && fealst.eaType == 0xFFFD )
{
fealst.szValue[fealst.eaSize] = 0;
return fealst.szValue;
}
return NULL;
}
char *GetLongPathEA(char *name)
{
static char nbuf[CCHMAXPATH + 1];
char *comp, *next, *ea, sep;
BOOL bFound = FALSE;
nbuf[0] = 0;
next = name;
while ( *next )
{
comp = next;
while ( *next != '\\' && *next != '/' && *next != 0 )
next++;
sep = *next;
*next = 0;
ea = GetLongNameEA(name);
strcat(nbuf, ea ? ea : comp);
bFound = bFound || (ea != NULL);
*next = sep;
if ( *next )
{
strcat(nbuf, "\\");
next++;
}
}
return nbuf[0] && bFound ? nbuf : NULL;
}
/* general EA code */
typedef struct
{
USHORT nID;
USHORT nSize;
ULONG lSize;
}
EAHEADER, *PEAHEADER;
#ifdef __32BIT__
/* Perhaps due to bugs in the current OS/2 2.0 kernel, the success or
failure of the DosEnumAttribute() and DosQueryPathInfo() system calls
depends on the area where the return buffers are allocated. This
differs for the various compilers, for some alloca() works, for some
malloc() works, for some, both work. We'll have to live with that. */
/* The use of malloc() is not very convenient, because it requires
backtracking (i.e. free()) at error returns. We do that for system
calls that may fail, but not for malloc() calls, because they are VERY
unlikely to fail. If ever, we just leave some memory allocated ... */
#if defined(__GNUC__)
#define alloc alloca
#endif
#if defined(__WATCOMC__) || defined(__IBMC__)
#define alloc malloc
#define __FREE__
#endif
#ifndef alloc
#error memory allocation type (alloca or malloc) not specified
#endif
void GetEAs(char *path, char **bufptr, unsigned *size,
char **cbufptr, unsigned *csize)
{
FILESTATUS4 fs;
PDENA2 pDENA, pFound;
EAOP2 eaop;
PGEA2 pGEA;
PGEA2LIST pGEAlist;
PFEA2LIST pFEAlist;
PEAHEADER pEAblock;
ULONG ulAttributes, ulMemoryBlock;
ULONG nLength;
char szName[CCHMAXPATH];
*size = *csize = 0;
if ( _osmode == DOS_MODE )
return;
strcpy(szName, path);
nLength = strlen(szName);
if ( szName[nLength - 1] == '/' )
szName[nLength - 1] = 0;
if ( DosQueryPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &fs, sizeof(fs))
|| fs.cbList <= 2 * sizeof(ULONG)
|| (pDENA = alloc((size_t) fs.cbList)) == NULL )
return;
ulAttributes = -1;
if ( DosEnumAttribute(ENUMEA_REFTYPE_PATH, szName, 1, pDENA, fs.cbList,
&ulAttributes, ENUMEA_LEVEL_NO_VALUE)
|| ulAttributes == 0
|| (pGEAlist = alloc((size_t) fs.cbList)) == NULL )
{
#ifdef __FREE__
free(pDENA);
#endif
return;
}
pGEA = pGEAlist -> list;
pFound = pDENA;
while ( ulAttributes-- )
{
if ( !(strcmp(pFound -> szName, ".LONGNAME") == 0 && use_longname_ea) )
{
pGEA -> cbName = pFound -> cbName;
strcpy(pGEA -> szName, pFound -> szName);
nLength = sizeof(GEA2) + strlen(pGEA -> szName);
nLength = ((nLength - 1) / sizeof(ULONG) + 1) * sizeof(ULONG);
pGEA -> oNextEntryOffset = ulAttributes ? nLength : 0;
pGEA = (PGEA2) ((PCH) pGEA + nLength);
}
pFound = (PDENA2) ((PCH) pFound + pFound -> oNextEntryOffset);
}
if ( pGEA == pGEAlist -> list ) /* no attributes to save */
{
#ifdef __FREE__
free(pDENA);
free(pGEAlist);
#endif
return;
}
pGEAlist -> cbList = (PCH) pGEA - (PCH) pGEAlist;
pFEAlist = (PVOID) pDENA; /* reuse buffer */
pFEAlist -> cbList = fs.cbList;
eaop.fpGEA2List = pGEAlist;
eaop.fpFEA2List = pFEAlist;
eaop.oError = 0;
if ( DosQueryPathInfo(szName, FIL_QUERYEASFROMLIST,
(PBYTE) &eaop, sizeof(eaop)) )
{
#ifdef __FREE__
free(pDENA);
free(pGEAlist);
#endif
return;
}
/* The maximum compressed size is (in case of STORE type) the
uncompressed size plus the size of the compression type field
plus the size of the CRC field. */
ulAttributes = pFEAlist -> cbList;
ulMemoryBlock = ulAttributes + sizeof(USHORT) + sizeof(ULONG);
pEAblock = (PEAHEADER) malloc(sizeof(EAHEADER) + ulMemoryBlock);
if ( pEAblock == NULL )
return;
*bufptr = (char *) pEAblock;
*size = sizeof(EAHEADER);
pEAblock -> nID = EAID;
pEAblock -> nSize = sizeof(pEAblock -> lSize);
pEAblock -> lSize = ulAttributes; /* uncompressed size */
nLength = memcompress((char *) (pEAblock + 1), ulMemoryBlock,
(char *) pFEAlist, ulAttributes);
*size += nLength;
pEAblock -> nSize += nLength;
if ( (pEAblock = (PEAHEADER) malloc(sizeof(EAHEADER))) == NULL )
return;
*cbufptr = (char *) pEAblock;
*csize = sizeof(EAHEADER);
pEAblock -> nID = EAID;
pEAblock -> nSize = sizeof(pEAblock -> lSize);
pEAblock -> lSize = ulAttributes;
if ( noisy )
printf(" (%ld bytes EA's)", ulAttributes);
}
#else /* !__32BIT__ */
typedef struct
{
ULONG oNextEntryOffset;
BYTE fEA;
BYTE cbName;
USHORT cbValue;
CHAR szName[1];
}
FEA2, *PFEA2;
typedef struct
{
ULONG cbList;
FEA2 list[1];
}
FEA2LIST, *PFEA2LIST;
void GetEAs(char *path, char **bufptr, unsigned *size,
char **cbufptr, unsigned *csize)
{
FILESTATUS2 fs;
PDENA1 pDENA, pFound;
EAOP eaop;
PGEALIST pGEAlist;
PGEA pGEA;
PFEALIST pFEAlist;
PFEA pFEA;
PFEA2LIST pFEA2list;
PFEA2 pFEA2;
EAHEADER *pEAblock;
ULONG ulAttributes;
USHORT nLength, nMaxSize;
char szName[CCHMAXPATH];
*size = *csize = 0;
if ( _osmode == DOS_MODE )
return;
strcpy(szName, path);
nLength = strlen(szName);
if ( szName[nLength - 1] == '/' )
szName[nLength - 1] = 0;
if ( DosQueryPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &fs, sizeof(fs))
|| fs.cbList <= 2 * sizeof(ULONG) )
return;
ulAttributes = -1;
nMaxSize = (USHORT) min(fs.cbList * 2, 65520L);
if ( (pDENA = malloc((size_t) nMaxSize)) == NULL )
return;
if ( DosEnumAttribute(ENUMEA_REFTYPE_PATH, szName, 1, pDENA, fs.cbList,
&ulAttributes, ENUMEA_LEVEL_NO_VALUE)
|| ulAttributes == 0
|| (pGEAlist = malloc(nMaxSize)) == NULL )
{
free(pDENA);
return;
}
pGEA = pGEAlist -> list;
pFound = pDENA;
while ( ulAttributes-- )
{
nLength = strlen(pFound -> szName);
if ( !(strcmp(pFound -> szName, ".LONGNAME") == 0 && use_longname_ea) )
{
pGEA -> cbName = pFound -> cbName;
strcpy(pGEA -> szName, pFound -> szName);
pGEA = (PGEA) ((PCH) (pGEA++) + nLength);
}
pFound = (PDENA1) ((PCH) (pFound++) + nLength);
}
if ( pGEA == pGEAlist -> list )
{
free(pDENA);
free(pGEAlist);
return;
}
pGEAlist -> cbList = (PCH) pGEA - (PCH) pGEAlist;
pFEAlist = (PFEALIST) pDENA; /* reuse buffer */
pFEAlist -> cbList = fs.cbList;
pFEA = pFEAlist -> list;
eaop.fpGEAList = pGEAlist;
eaop.fpFEAList = pFEAlist;
eaop.oError = 0;
if ( DosQueryPathInfo(szName, FIL_QUERYEASFROMLIST,
(PBYTE) &eaop, sizeof(eaop)) )
{
free(pDENA);
free(pGEAlist);
return;
}
/* now convert into new OS/2 2.0 32-bit format */
pFEA2list = (PFEA2LIST) pGEAlist; /* reuse buffer */
pFEA2 = pFEA2list -> list;
while ( (PCH) pFEA - (PCH) pFEAlist < pFEAlist -> cbList )
{
nLength = sizeof(FEA) + pFEA -> cbName + 1 + pFEA -> cbValue;
memcpy((PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset), pFEA, nLength);
memset((PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset) + nLength, 0, 3);
pFEA = (PFEA) ((PCH) pFEA + nLength);
nLength = sizeof(FEA2) + pFEA2 -> cbName + 1 + pFEA2 -> cbValue;
nLength = ((nLength - 1) / sizeof(ULONG) + 1) * sizeof(ULONG);
/* rounded up to 4-byte boundary */
pFEA2 -> oNextEntryOffset =
((PCH) pFEA - (PCH) pFEAlist < pFEAlist -> cbList) ? nLength : 0;
pFEA2 = (PFEA2) ((PCH) pFEA2 + nLength);
}
pFEA2list -> cbList = (PCH) pFEA2 - (PCH) pFEA2list;
ulAttributes = pFEA2list -> cbList;
pEAblock = (PEAHEADER) pDENA; /* reuse buffer */
*bufptr = (char *) pEAblock;
*size = sizeof(EAHEADER);
pEAblock -> nID = EAID;
pEAblock -> nSize = sizeof(pEAblock -> lSize);
pEAblock -> lSize = ulAttributes; /* uncompressed size */
nLength = (USHORT) memcompress((char *) (pEAblock + 1),
nMaxSize - sizeof(EAHEADER), (char *) pFEA2list, ulAttributes);
*size += nLength;
pEAblock -> nSize += nLength;
pEAblock = (PEAHEADER) pGEAlist;
*cbufptr = (char *) pEAblock;
*csize = sizeof(EAHEADER);
pEAblock -> nID = EAID;
pEAblock -> nSize = sizeof(pEAblock -> lSize);
pEAblock -> lSize = ulAttributes;
if ( noisy )
printf(" (%ld bytes EA's)", ulAttributes);
}
#endif /* __32BIT__ */
#endif /* UTIL */
/* Initialize the table of uppercase characters including handling of
country dependent characters. */
void init_upper()
{
COUNTRYCODE cc;
unsigned nCnt, nU;
for ( nCnt = 0; nCnt < sizeof(upper); nCnt++ )
upper[nCnt] = lower[nCnt] = (unsigned char) nCnt;
cc.country = cc.codepage = 0;
DosMapCase(sizeof(upper), &cc, (PCHAR) upper);
for ( nCnt = 0; nCnt < 256; nCnt++ )
{
nU = upper[nCnt];
if (nU != nCnt && lower[nU] == (unsigned char) nU)
lower[nU] = (unsigned char) nCnt;
}
for ( nCnt = 'A'; nCnt <= 'Z'; nCnt++ )
lower[nCnt] = (unsigned char) (nCnt - 'A' + 'a');
}
char *StringLower(char *szArg)
{
unsigned char *szPtr;
for ( szPtr = szArg; *szPtr; szPtr++ )
*szPtr = lower[*szPtr];
return szArg;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -