321 lines
9.9 KiB
C
321 lines
9.9 KiB
C
/*************************************************************************
|
|
* *
|
|
* SCATALOG.C *
|
|
* *
|
|
* Copyright (C) Microsoft Corporation 1990-1994 *
|
|
* All Rights reserved. *
|
|
* *
|
|
**************************************************************************
|
|
* *
|
|
* Module Intent *
|
|
* Catalog retrieval *
|
|
* *
|
|
**************************************************************************
|
|
* *
|
|
* Current Owner: BinhN *
|
|
* *
|
|
**************************************************************************
|
|
* *
|
|
* Released by Development: (date) *
|
|
* *
|
|
*************************************************************************/
|
|
|
|
#include <mvopsys.h>
|
|
#include <mem.h>
|
|
#include <mvsearch.h>
|
|
#include "common.h"
|
|
#include "search.h"
|
|
|
|
#ifdef _DEBUG
|
|
static BYTE NEAR s_aszModule[] = __FILE__; /* Used by error return functions.*/
|
|
#endif
|
|
|
|
/*************************************************************************
|
|
*
|
|
* API FUNCTIONS
|
|
* Those functions should be exported in a .DEF file
|
|
*************************************************************************/
|
|
PUBLIC LPCAT EXPORT_API PASCAL FAR CatalogOpen (GHANDLE, LSZ, PHRESULT);
|
|
PUBLIC HRESULT EXPORT_API PASCAL FAR CatalogLookUp (LPCAT, LPB, DWORD);
|
|
PUBLIC DWORD EXPORT_API PASCAL FAR Catalog1stItemId(LPCAT);
|
|
PUBLIC DWORD EXPORT_API PASCAL FAR CatalogItemCount(LPCAT);
|
|
PUBLIC VOID EXPORT_API PASCAL FAR CatalogClose(LPCAT);
|
|
|
|
#define cELEMENT_READ 100
|
|
|
|
/*************************************************************************
|
|
* @doc API RETRIEVAL
|
|
*
|
|
* @func LPCAT PASCAL FAR | CatalogOpen |
|
|
* Open the catalog, allocate memory to handle future catalog's
|
|
* searches
|
|
*
|
|
* @parm HANDLE | hfpbSysFile |
|
|
* If non-zero, this is the handle of an already opened system file
|
|
*
|
|
* @parm LSZ | lszFilename |
|
|
* If hpfbSysFile is non-zero, this is the name of the catalog's subfile
|
|
* else this is the combined filename with the format
|
|
* "dos_filename[!catalog_filename]"
|
|
* If the subfile's name is not specified, the default catalog's file
|
|
* name will be used. The '!' is not part of the subfile's name
|
|
*
|
|
* @parm PHRESULT | phr |
|
|
* Error buffer to be used in subsequent catalog retrieval function calls
|
|
*
|
|
* @rdesc Pointer to catalog structure if succeeded, NULL if failed. In
|
|
* case of failure, the error buffer will contain descriptions about
|
|
* the cause of the failure
|
|
*************************************************************************/
|
|
|
|
PUBLIC LPCAT EXPORT_API PASCAL FAR CatalogOpen (GHANDLE hfpbSysFile,
|
|
LSZ lszCatName, PHRESULT phr)
|
|
{
|
|
CAT_RETRIEV FAR *lpCat;
|
|
GHANDLE handle; // Temporary variable
|
|
GHANDLE hfpbCatFile;
|
|
HFPB hfpb = NULL;
|
|
|
|
/* Open subfile, (and system file if necessary) */
|
|
|
|
if ((hfpbCatFile = (GHANDLE)FileOpen(hfpb,
|
|
lszCatName, FS_SUBFILE, READ, phr)) == 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/* Initialization phase. */
|
|
|
|
if ((handle = _GLOBALALLOC(GMEM_MOVEABLE | GMEM_ZEROINIT,
|
|
sizeof(CAT_RETRIEV))) == NULL) {
|
|
SetErrCode(phr, E_OUTOFMEMORY);
|
|
exit00:
|
|
FileClose(hfpbCatFile);
|
|
if (hfpb) {
|
|
/* FileClose will free hfpb */
|
|
FileClose (hfpb);
|
|
hfpb = 0;
|
|
}
|
|
// FreeTempFPB(hfpb);
|
|
return NULL;
|
|
}
|
|
|
|
lpCat = (CAT_RETRIEV FAR *)_GLOBALLOCK(handle);
|
|
lpCat->hCat = handle;
|
|
lpCat->lperrb = phr;
|
|
lpCat->hfpbSysFile = (HFPB)hfpb;
|
|
lpCat->hfpbCatalog = (HFPB)hfpbCatFile;
|
|
lpCat->dwCurElem = (DWORD)-1;
|
|
|
|
/* Read in the catalog information header */
|
|
|
|
if (FileSeekRead (lpCat->hfpbCatalog, lpCat, foNil,
|
|
sizeof(CAT_HEADER), phr) == cbIO_ERROR)
|
|
{
|
|
exit01:
|
|
FreeHandle(lpCat->hCat);
|
|
goto exit00;
|
|
}
|
|
|
|
/* MAC codes. They will optimizaed out for Windows */
|
|
|
|
lpCat->FileStamp = SWAPWORD(lpCat->FileStamp);
|
|
lpCat->version = SWAPWORD(lpCat->version);
|
|
lpCat->wElemSize = SWAPWORD(lpCat->wElemSize);
|
|
lpCat->cElement = SWAPLONG(lpCat->cElement);
|
|
lpCat->dwFirstElem = SWAPLONG(lpCat->dwFirstElem);
|
|
|
|
/* Check for file validity */
|
|
|
|
if (lpCat->FileStamp != CATALOG_STAMP ||
|
|
(lpCat->version <7 || lpCat->version > VERCURRENT)) {
|
|
SetErrCode(phr, E_BADVERSION);
|
|
goto exit01;
|
|
}
|
|
|
|
/* Allocate cache */
|
|
if ((lpCat->hCatBuf = _GLOBALALLOC(GMEM_MOVEABLE,
|
|
lpCat->wElemSize * cELEMENT_READ)) == NULL) {
|
|
SetErrCode(phr, E_OUTOFMEMORY);
|
|
goto exit01;
|
|
}
|
|
|
|
lpCat->lpCatBuf = _GLOBALLOCK(lpCat->hCatBuf);
|
|
return lpCat;
|
|
}
|
|
|
|
/*************************************************************************
|
|
* @doc API RETRIEVAL
|
|
*
|
|
* @func HRESULT PASCAL FAR | CatalogLookUp |
|
|
* Look for the value of a catalog's item
|
|
*
|
|
* @parm LPCAT | lpCat |
|
|
* Pointer to catalog structure (returned by CatalogOpen())
|
|
*
|
|
* @parm LPB | lpBuffer |
|
|
* Buffer to store the retrieved value of the catalog's item
|
|
*
|
|
* @parm DWORD | dwItem |
|
|
* Catalog's item number
|
|
*
|
|
* @rdesc S_OK if succeeded, else other errors. In case of E_FAIL,
|
|
* the error buffer provided in CatalogOpen() will contain
|
|
* descriptions about the cause of the failure
|
|
*
|
|
* @xref CatalogOpen()
|
|
*************************************************************************/
|
|
|
|
PUBLIC HRESULT EXPORT_API PASCAL FAR CatalogLookUp (CAT_RETRIEV FAR *lpCat,
|
|
LPB lpBuffer, DWORD dwItem)
|
|
{
|
|
register WORD i;
|
|
register WORD wElemSize;
|
|
DWORD lfo;
|
|
WORD fUpdateCache;
|
|
LPB lpb;
|
|
PHRESULT phr;
|
|
#if 0
|
|
int fRet;
|
|
#endif
|
|
|
|
if (lpCat == NULL || lpBuffer == NULL) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
phr = lpCat->lperrb;
|
|
if (dwItem < lpCat->dwFirstElem ||
|
|
dwItem >= lpCat->dwFirstElem + lpCat->cElement) {
|
|
return E_OUTOFRANGE;
|
|
}
|
|
|
|
/* We have to get new data if the item is out-of-range, or if
|
|
there is nothing in the cache yet
|
|
*/
|
|
|
|
fUpdateCache = ((lpCat->dwCurElem == -1) ||
|
|
(dwItem < lpCat->dwCurElem) ||
|
|
(dwItem >= lpCat->dwCurElem + (DWORD)cELEMENT_READ)) ;
|
|
|
|
wElemSize = lpCat->wElemSize;
|
|
|
|
if (fUpdateCache) {
|
|
lpCat->dwCurElem = dwItem;
|
|
|
|
/* Calculate the starting file offset */
|
|
lfo = CATALOG_HDR_SIZE +
|
|
(dwItem - lpCat->dwFirstElem) * wElemSize;
|
|
|
|
/* Fill up the cache buffer */
|
|
if ((i = (WORD)FileSeekRead(lpCat->hfpbCatalog, lpCat->lpCatBuf,
|
|
MakeFo (lfo, 0), (WORD)(wElemSize * cELEMENT_READ),
|
|
phr)) == cbIO_ERROR) {
|
|
return E_FAIL;
|
|
}
|
|
|
|
#if 0
|
|
/* Do MAC swaps */
|
|
if ((wElemSize & 1) == 0) { /* Make sure that it is an even number */
|
|
|
|
if ((fRet = SwapBuffer ((LPW)lpCat->lpCatBuf,
|
|
(DWORD)i)) != S_OK)
|
|
return fRet;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
/* Now transfer the data */
|
|
lpb = lpCat->lpCatBuf + (dwItem - lpCat->dwCurElem) * wElemSize;
|
|
for (i = 0; i < wElemSize; i++)
|
|
*lpBuffer ++ = *lpb++;
|
|
return S_OK;
|
|
}
|
|
|
|
/*************************************************************************
|
|
* @doc API RETRIEVAL
|
|
*
|
|
* @func VOID PASCAL FAR | CatalogClose |
|
|
* Close a catalog and release all memory associated with it
|
|
*
|
|
* @parm LPCAT | lpCat |
|
|
* Pointer to catalog structure (returned by CatalogOpen())
|
|
*
|
|
* @xref CatalogOpen()
|
|
*************************************************************************/
|
|
|
|
PUBLIC VOID EXPORT_API PASCAL FAR CatalogClose(CAT_RETRIEV FAR *lpCat)
|
|
{
|
|
if (lpCat == NULL)
|
|
return;
|
|
|
|
FileClose(lpCat->hfpbCatalog);
|
|
|
|
|
|
/* Free catalog buffer */
|
|
|
|
if (lpCat->hCatBuf)
|
|
FreeHandle(lpCat->hCatBuf);
|
|
|
|
/* Free catalog structure */
|
|
|
|
if (lpCat->hCat)
|
|
FreeHandle(lpCat->hCat);
|
|
}
|
|
|
|
/*************************************************************************
|
|
* @doc API RETRIEVAL
|
|
*
|
|
* @func DWORD PASCAL FAR | Catalog1stItemId |
|
|
* Return the catalog's first item's id
|
|
*
|
|
* @parm LPCAT | lpCat |
|
|
* Pointer to catalog structure (returned by CatalogOpen())
|
|
*
|
|
* @rdesc The first item's id is returned, -1 if error
|
|
*
|
|
* @xref CatalogOpen()
|
|
*************************************************************************/
|
|
PUBLIC DWORD EXPORT_API PASCAL FAR Catalog1stItemId(CAT_RETRIEV FAR *lpCat)
|
|
{
|
|
return (lpCat == NULL? -1L: lpCat->dwFirstElem);
|
|
}
|
|
|
|
/*************************************************************************
|
|
* @doc API RETRIEVAL
|
|
*
|
|
* @func DWORD PASCAL FAR | CatalogItemCount |
|
|
* Return the catalog's total number of item.
|
|
*
|
|
* @parm LPCAT | lpCat |
|
|
* Pointer to catalog structure (returned by CatalogOpen())
|
|
*
|
|
* @rdesc The total number of items in the catalog is returned, -1 if
|
|
* error
|
|
*
|
|
* @xref CatalogOpen()
|
|
*************************************************************************/
|
|
PUBLIC DWORD EXPORT_API PASCAL FAR CatalogItemCount(CAT_RETRIEV FAR *lpCat)
|
|
{
|
|
return (lpCat == NULL ? -1L : lpCat->cElement);
|
|
}
|
|
|
|
/*************************************************************************
|
|
* @doc API RETRIEVAL
|
|
*
|
|
* @func WORD PASCAL FAR | CatalogItemSize |
|
|
* Return the catalog item's size.
|
|
*
|
|
* @parm LPCAT | lpCat |
|
|
* Pointer to catalog structure (returned by CatalogOpen())
|
|
*
|
|
* @rdesc Return the catalog item's size, -1 if error
|
|
*
|
|
* @xref CatalogOpen()
|
|
*************************************************************************/
|
|
PUBLIC DWORD EXPORT_API PASCAL FAR CatalogItemSize(CAT_RETRIEV FAR *lpCat)
|
|
{
|
|
return (lpCat == NULL ? -1L : lpCat->wElemSize);
|
|
}
|
|
|