ReactOS  0.4.15-dev-1206-g731eddf
chm_lib.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  chmUnitInfo
 

Macros

#define CHM_UNCOMPRESSED   (0)
 
#define CHM_COMPRESSED   (1)
 
#define CHM_MAX_PATHLEN   (256)
 
#define CHM_RESOLVE_SUCCESS   (0)
 
#define CHM_RESOLVE_FAILURE   (1)
 
#define CHM_ENUMERATE_NORMAL   (1)
 
#define CHM_ENUMERATE_META   (2)
 
#define CHM_ENUMERATE_SPECIAL   (4)
 
#define CHM_ENUMERATE_FILES   (8)
 
#define CHM_ENUMERATE_DIRS   (16)
 
#define CHM_ENUMERATE_ALL   (31)
 
#define CHM_ENUMERATOR_FAILURE   (0)
 
#define CHM_ENUMERATOR_CONTINUE   (1)
 
#define CHM_ENUMERATOR_SUCCESS   (2)
 

Typedefs

typedef ULONGLONG LONGUINT64
 
typedef LONGLONG LONGINT64
 
typedef int(* CHM_ENUMERATOR) (struct chmFile *h, struct chmUnitInfo *ui, void *context)
 

Functions

struct chmFilechm_openW (const WCHAR *filename) DECLSPEC_HIDDEN
 
struct chmFilechm_dup (struct chmFile *oldHandle) DECLSPEC_HIDDEN
 
void chm_close (struct chmFile *h) DECLSPEC_HIDDEN
 
int chm_resolve_object (struct chmFile *h, const WCHAR *objPath, struct chmUnitInfo *ui) DECLSPEC_HIDDEN
 
LONGINT64 chm_retrieve_object (struct chmFile *h, struct chmUnitInfo *ui, unsigned char *buf, LONGUINT64 addr, LONGINT64 len) DECLSPEC_HIDDEN
 
BOOL chm_enumerate_dir (struct chmFile *h, const WCHAR *prefix, int what, CHM_ENUMERATOR e, void *context) DECLSPEC_HIDDEN
 

Macro Definition Documentation

◆ CHM_COMPRESSED

#define CHM_COMPRESSED   (1)

Definition at line 60 of file chm_lib.h.

◆ CHM_ENUMERATE_ALL

#define CHM_ENUMERATE_ALL   (31)

Definition at line 104 of file chm_lib.h.

◆ CHM_ENUMERATE_DIRS

#define CHM_ENUMERATE_DIRS   (16)

Definition at line 103 of file chm_lib.h.

◆ CHM_ENUMERATE_FILES

#define CHM_ENUMERATE_FILES   (8)

Definition at line 102 of file chm_lib.h.

◆ CHM_ENUMERATE_META

#define CHM_ENUMERATE_META   (2)

Definition at line 100 of file chm_lib.h.

◆ CHM_ENUMERATE_NORMAL

#define CHM_ENUMERATE_NORMAL   (1)

Definition at line 99 of file chm_lib.h.

◆ CHM_ENUMERATE_SPECIAL

#define CHM_ENUMERATE_SPECIAL   (4)

Definition at line 101 of file chm_lib.h.

◆ CHM_ENUMERATOR_CONTINUE

#define CHM_ENUMERATOR_CONTINUE   (1)

Definition at line 106 of file chm_lib.h.

◆ CHM_ENUMERATOR_FAILURE

#define CHM_ENUMERATOR_FAILURE   (0)

Definition at line 105 of file chm_lib.h.

◆ CHM_ENUMERATOR_SUCCESS

#define CHM_ENUMERATOR_SUCCESS   (2)

Definition at line 107 of file chm_lib.h.

◆ CHM_MAX_PATHLEN

#define CHM_MAX_PATHLEN   (256)

Definition at line 66 of file chm_lib.h.

◆ CHM_RESOLVE_FAILURE

#define CHM_RESOLVE_FAILURE   (1)

Definition at line 83 of file chm_lib.h.

◆ CHM_RESOLVE_SUCCESS

#define CHM_RESOLVE_SUCCESS   (0)

Definition at line 82 of file chm_lib.h.

◆ CHM_UNCOMPRESSED

#define CHM_UNCOMPRESSED   (0)

Definition at line 59 of file chm_lib.h.

Typedef Documentation

◆ CHM_ENUMERATOR

typedef int(* CHM_ENUMERATOR) (struct chmFile *h, struct chmUnitInfo *ui, void *context)

Definition at line 96 of file chm_lib.h.

◆ LONGINT64

Definition at line 54 of file chm_lib.h.

◆ LONGUINT64

Definition at line 53 of file chm_lib.h.

Function Documentation

◆ chm_close()

void chm_close ( struct chmFile h)

Definition at line 863 of file chm_lib.c.

864 {
865  if (h != NULL)
866  {
867  if (h->fd != CHM_NULL_FD)
868  CHM_CLOSE_FILE(h->fd);
869  h->fd = CHM_NULL_FD;
870 
871  h->mutex.DebugInfo->Spare[0] = 0;
872  DeleteCriticalSection(&h->mutex);
873  h->lzx_mutex.DebugInfo->Spare[0] = 0;
874  DeleteCriticalSection(&h->lzx_mutex);
875  h->cache_mutex.DebugInfo->Spare[0] = 0;
876  DeleteCriticalSection(&h->cache_mutex);
877 
878  if (h->lzx_state)
879  LZXteardown(h->lzx_state);
880  h->lzx_state = NULL;
881 
882  if (h->cache_blocks)
883  {
884  int i;
885  for (i=0; i<h->cache_num_blocks; i++)
886  {
887  HeapFree(GetProcessHeap(), 0, h->cache_blocks[i]);
888  }
889  HeapFree(GetProcessHeap(), 0, h->cache_blocks);
890  h->cache_blocks = NULL;
891  }
892 
893  HeapFree(GetProcessHeap(), 0, h->cache_block_indices);
894  h->cache_block_indices = NULL;
895 
896  HeapFree(GetProcessHeap(), 0, h);
897  }
898 }
void LZXteardown(struct LZXstate *pState)
Definition: lzx.c:209
#define CHM_CLOSE_FILE(fd)
Definition: chm_lib.c:78
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define CHM_NULL_FD
Definition: chm_lib.c:77
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:595
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define HeapFree(x, y, z)
Definition: compat.h:594

Referenced by chm_openW(), ITSProtocol_Start(), ITSS_IStorageImpl_Release(), and release_chm().

◆ chm_dup()

struct chmFile* chm_dup ( struct chmFile oldHandle)

Definition at line 831 of file chm_lib.c.

832 {
833  struct chmFile *newHandle=NULL;
834 
835  newHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(struct chmFile));
836  *newHandle = *oldHandle;
837 
838  /* duplicate fd handle */
839  DuplicateHandle(GetCurrentProcess(), oldHandle->fd,
840  GetCurrentProcess(), &(newHandle->fd),
842  newHandle->lzx_state = NULL;
843  newHandle->cache_blocks = NULL;
844  newHandle->cache_block_indices = NULL;
845  newHandle->cache_num_blocks = 0;
846 
847  /* initialize mutexes, if needed */
848  InitializeCriticalSection(&newHandle->mutex);
849  newHandle->mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.mutex");
851  newHandle->lzx_mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.lzx_mutex");
853  newHandle->cache_mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.cache_mutex");
854 
855  /* initialize cache */
858 
859  return newHandle;
860 }
struct LZXstate * lzx_state
Definition: chm_lib.c:552
CRITICAL_SECTION lzx_mutex
Definition: chm_lib.c:530
#define DWORD_PTR
Definition: treelist.c:76
CRITICAL_SECTION cache_mutex
Definition: chm_lib.c:531
Int64 * cache_block_indices
Definition: chm_lib.c:557
UChar ** cache_blocks
Definition: chm_lib.c:556
HANDLE fd
Definition: chm_lib.c:527
Int32 cache_num_blocks
Definition: chm_lib.c:558
#define DUPLICATE_SAME_ACCESS
#define FALSE
Definition: types.h:117
#define CHM_PARAM_MAX_BLOCKS_CACHED
Definition: chm_lib.c:86
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
CRITICAL_SECTION mutex
Definition: chm_lib.c:529
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:872
#define GetCurrentProcess()
Definition: compat.h:618
static void chm_set_param(struct chmFile *h, int paramType, int paramVal)
Definition: chm_lib.c:613
#define CHM_MAX_BLOCKS_CACHED
Definition: chm_lib.c:84
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:865

Referenced by ITSS_IStorageImpl_OpenStorage().

◆ chm_enumerate_dir()

BOOL chm_enumerate_dir ( struct chmFile h,
const WCHAR prefix,
int  what,
CHM_ENUMERATOR  e,
void context 
)

Definition at line 1400 of file chm_lib.c.

1405 {
1406  /*
1407  * XXX: do this efficiently (i.e. using the tree index)
1408  */
1409 
1410  Int32 curPage;
1411 
1412  /* buffer to hold whatever page we're looking at */
1413  UChar *page_buf = HeapAlloc(GetProcessHeap(), 0, h->block_len);
1414  struct chmPmglHeader header;
1415  UChar *end;
1416  UChar *cur;
1417  unsigned int lenRemain;
1418 
1419  /* set to TRUE once we've started */
1420  BOOL it_has_begun = FALSE;
1421 
1422  /* the current ui */
1423  struct chmUnitInfo ui;
1424  int flag;
1425  UInt64 ui_path_len;
1426 
1427  /* the length of the prefix */
1428  WCHAR prefixRectified[CHM_MAX_PATHLEN+1];
1429  int prefixLen;
1430  WCHAR lastPath[CHM_MAX_PATHLEN];
1431  int lastPathLen;
1432 
1433  /* starting page */
1434  curPage = h->index_head;
1435 
1436  /* initialize pathname state */
1437  lstrcpynW(prefixRectified, prefix, CHM_MAX_PATHLEN);
1438  prefixLen = lstrlenW(prefixRectified);
1439  if (prefixLen != 0)
1440  {
1441  if (prefixRectified[prefixLen-1] != '/')
1442  {
1443  prefixRectified[prefixLen] = '/';
1444  prefixRectified[prefixLen+1] = '\0';
1445  ++prefixLen;
1446  }
1447  }
1448  lastPath[0] = '\0';
1449  lastPathLen = -1;
1450 
1451  /* until we have either returned or given up */
1452  while (curPage != -1)
1453  {
1454 
1455  /* try to fetch the index page */
1456  if (_chm_fetch_bytes(h,
1457  page_buf,
1458  h->dir_offset + (UInt64)curPage*h->block_len,
1459  h->block_len) != h->block_len)
1460  {
1461  HeapFree(GetProcessHeap(), 0, page_buf);
1462  return FALSE;
1463  }
1464 
1465  /* figure out start and end for this page */
1466  cur = page_buf;
1467  lenRemain = _CHM_PMGL_LEN;
1468  if (! _unmarshal_pmgl_header(&cur, &lenRemain, &header))
1469  {
1470  HeapFree(GetProcessHeap(), 0, page_buf);
1471  return FALSE;
1472  }
1473  end = page_buf + h->block_len - (header.free_space);
1474 
1475  /* loop over this page */
1476  while (cur < end)
1477  {
1478  if (! _chm_parse_PMGL_entry(&cur, &ui))
1479  {
1480  HeapFree(GetProcessHeap(), 0, page_buf);
1481  return FALSE;
1482  }
1483 
1484  /* check if we should start */
1485  if (! it_has_begun)
1486  {
1487  if (ui.length == 0 && _wcsnicmp(ui.path, prefixRectified, prefixLen) == 0)
1488  it_has_begun = TRUE;
1489  else
1490  continue;
1491 
1492  if (ui.path[prefixLen] == '\0')
1493  continue;
1494  }
1495 
1496  /* check if we should stop */
1497  else
1498  {
1499  if (_wcsnicmp(ui.path, prefixRectified, prefixLen) != 0)
1500  {
1501  HeapFree(GetProcessHeap(), 0, page_buf);
1502  return TRUE;
1503  }
1504  }
1505 
1506  /* check if we should include this path */
1507  if (lastPathLen != -1)
1508  {
1509  if (_wcsnicmp(ui.path, lastPath, lastPathLen) == 0)
1510  continue;
1511  }
1512  lstrcpyW(lastPath, ui.path);
1513  lastPathLen = lstrlenW(lastPath);
1514 
1515  /* get the length of the path */
1516  ui_path_len = lstrlenW(ui.path)-1;
1517 
1518  /* check for DIRS */
1519  if (ui.path[ui_path_len] == '/' && !(what & CHM_ENUMERATE_DIRS))
1520  continue;
1521 
1522  /* check for FILES */
1523  if (ui.path[ui_path_len] != '/' && !(what & CHM_ENUMERATE_FILES))
1524  continue;
1525 
1526  /* check for NORMAL vs. META */
1527  if (ui.path[0] == '/')
1528  {
1529 
1530  /* check for NORMAL vs. SPECIAL */
1531  if (ui.path[1] == '#' || ui.path[1] == '$')
1533  else
1535  }
1536  else
1538  if (! (what & flag))
1539  continue;
1540 
1541  /* call the enumerator */
1542  {
1543  int status = (*e)(h, &ui, context);
1544  switch (status)
1545  {
1547  HeapFree(GetProcessHeap(), 0, page_buf);
1548  return FALSE;
1550  break;
1552  HeapFree(GetProcessHeap(), 0, page_buf);
1553  return TRUE;
1554  default:
1555  break;
1556  }
1557  }
1558  }
1559 
1560  /* advance to next page */
1561  curPage = header.block_next;
1562  }
1563 
1564  HeapFree(GetProcessHeap(), 0, page_buf);
1565  return TRUE;
1566 }
#define CHM_MAX_PATHLEN
Definition: chm_lib.h:66
#define CHM_ENUMERATE_DIRS
Definition: chm_lib.h:103
Definition: http.c:7094
#define TRUE
Definition: types.h:120
#define CHM_ENUMERATE_META
Definition: chm_lib.h:100
UINT ui
Definition: oleauto.h:49
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
ULONGLONG UInt64
Definition: chm_lib.c:106
BYTE UChar
Definition: chm_lib.c:100
GLuint GLuint end
Definition: gl.h:1545
#define lstrlenW
Definition: compat.h:609
#define lstrcpynW
Definition: compat.h:597
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define CHM_ENUMERATOR_FAILURE
Definition: chm_lib.h:105
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define CHM_ENUMERATE_FILES
Definition: chm_lib.h:102
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
static Int64 _chm_fetch_bytes(struct chmFile *h, UChar *buf, UInt64 os, Int64 len)
Definition: chm_lib.c:566
#define _CHM_PMGL_LEN
Definition: chm_lib.c:371
static BOOL _unmarshal_pmgl_header(unsigned char **pData, unsigned int *pDataLen, struct chmPmglHeader *dest)
Definition: chm_lib.c:381
#define lstrcpyW
Definition: compat.h:608
static BOOL _chm_parse_PMGL_entry(UChar **pEntry, struct chmUnitInfo *ui)
Definition: chm_lib.c:943
LONG Int32
Definition: chm_lib.c:103
#define CHM_ENUMERATOR_CONTINUE
Definition: chm_lib.h:106
#define CHM_ENUMERATE_SPECIAL
Definition: chm_lib.h:101
#define CHM_ENUMERATE_NORMAL
Definition: chm_lib.h:99
#define HeapFree(x, y, z)
Definition: compat.h:594
#define CHM_ENUMERATOR_SUCCESS
Definition: chm_lib.h:107
Definition: ps.c:97

Referenced by ITSS_IStorageImpl_EnumElements().

◆ chm_openW()

struct chmFile* chm_openW ( const WCHAR filename)

Definition at line 678 of file chm_lib.c.

679 {
680  unsigned char sbuffer[256];
681  unsigned int sremain;
682  unsigned char *sbufpos;
683  struct chmFile *newHandle=NULL;
684  struct chmItsfHeader itsfHeader;
685  struct chmItspHeader itspHeader;
686 #if 0
687  struct chmUnitInfo uiSpan;
688 #endif
689  struct chmUnitInfo uiLzxc;
690  struct chmLzxcControlData ctlData;
691 
692  /* allocate handle */
693  newHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(struct chmFile));
694  newHandle->fd = CHM_NULL_FD;
695  newHandle->lzx_state = NULL;
696  newHandle->cache_blocks = NULL;
697  newHandle->cache_block_indices = NULL;
698  newHandle->cache_num_blocks = 0;
699 
700  /* open file */
701  if ((newHandle->fd=CreateFileW(filename,
702  GENERIC_READ,
704  NULL,
707  NULL)) == CHM_NULL_FD)
708  {
709  HeapFree(GetProcessHeap(), 0, newHandle);
710  return NULL;
711  }
712 
713  /* initialize mutexes, if needed */
714  InitializeCriticalSection(&newHandle->mutex);
715  newHandle->mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.mutex");
716  InitializeCriticalSection(&newHandle->lzx_mutex);
717  newHandle->lzx_mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.lzx_mutex");
718  InitializeCriticalSection(&newHandle->cache_mutex);
719  newHandle->cache_mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.cache_mutex");
720 
721  /* read and verify header */
722  sremain = _CHM_ITSF_V3_LEN;
723  sbufpos = sbuffer;
724  if (_chm_fetch_bytes(newHandle, sbuffer, 0, sremain) != sremain ||
725  !_unmarshal_itsf_header(&sbufpos, &sremain, &itsfHeader))
726  {
727  chm_close(newHandle);
728  return NULL;
729  }
730 
731  /* stash important values from header */
732  newHandle->dir_offset = itsfHeader.dir_offset;
733  newHandle->dir_len = itsfHeader.dir_len;
734  newHandle->data_offset = itsfHeader.data_offset;
735 
736  /* now, read and verify the directory header chunk */
737  sremain = _CHM_ITSP_V1_LEN;
738  sbufpos = sbuffer;
739  if (_chm_fetch_bytes(newHandle, sbuffer,
740  itsfHeader.dir_offset, sremain) != sremain ||
741  !_unmarshal_itsp_header(&sbufpos, &sremain, &itspHeader))
742  {
743  chm_close(newHandle);
744  return NULL;
745  }
746 
747  /* grab essential information from ITSP header */
748  newHandle->dir_offset += itspHeader.header_len;
749  newHandle->dir_len -= itspHeader.header_len;
750  newHandle->index_root = itspHeader.index_root;
751  newHandle->index_head = itspHeader.index_head;
752  newHandle->block_len = itspHeader.block_len;
753 
754  /* if the index root is -1, this means we don't have any PMGI blocks.
755  * as a result, we must use the sole PMGL block as the index root
756  */
757  if (newHandle->index_root == -1)
758  newHandle->index_root = newHandle->index_head;
759 
760  /* initialize cache */
763 
764  /* By default, compression is enabled. */
765  newHandle->compression_enabled = 1;
766 
767  /* prefetch most commonly needed unit infos */
768  if (CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle,
770  &newHandle->rt_unit) ||
771  newHandle->rt_unit.space == CHM_COMPRESSED ||
774  &newHandle->cn_unit) ||
775  newHandle->cn_unit.space == CHM_COMPRESSED ||
778  &uiLzxc) ||
779  uiLzxc.space == CHM_COMPRESSED)
780  {
781  newHandle->compression_enabled = 0;
782  }
783 
784  /* read reset table info */
785  if (newHandle->compression_enabled)
786  {
787  sremain = _CHM_LZXC_RESETTABLE_V1_LEN;
788  sbufpos = sbuffer;
789  if (chm_retrieve_object(newHandle, &newHandle->rt_unit, sbuffer,
790  0, sremain) != sremain ||
791  !_unmarshal_lzxc_reset_table(&sbufpos, &sremain,
792  &newHandle->reset_table))
793  {
794  newHandle->compression_enabled = 0;
795  }
796  }
797 
798  /* read control data */
799  if (newHandle->compression_enabled)
800  {
801  sremain = (unsigned long)uiLzxc.length;
802  sbufpos = sbuffer;
803  if (chm_retrieve_object(newHandle, &uiLzxc, sbuffer,
804  0, sremain) != sremain ||
805  !_unmarshal_lzxc_control_data(&sbufpos, &sremain,
806  &ctlData))
807  {
808  newHandle->compression_enabled = 0;
809  }
810 
811  newHandle->window_size = ctlData.windowSize;
812  newHandle->reset_interval = ctlData.resetInterval;
813 
814 /* Jed, Mon Jun 28: Experimentally, it appears that the reset block count */
815 /* must be multiplied by this formerly unknown ctrl data field in */
816 /* order to decompress some files. */
817 #if 0
818  newHandle->reset_blkcount = newHandle->reset_interval /
819  (newHandle->window_size / 2);
820 #else
821  newHandle->reset_blkcount = newHandle->reset_interval /
822  (newHandle->window_size / 2) *
823  ctlData.windowsPerReset;
824 #endif
825  }
826 
827  return newHandle;
828 }
#define DWORD_PTR
Definition: treelist.c:76
static BOOL _unmarshal_itsp_header(unsigned char **pData, unsigned int *pDataLen, struct chmItspHeader *dest)
Definition: chm_lib.c:333
static BOOL _unmarshal_lzxc_control_data(unsigned char **pData, unsigned int *pDataLen, struct chmLzxcControlData *dest)
Definition: chm_lib.c:482
const char * filename
Definition: ioapi.h:135
#define _CHM_LZXC_RESETTABLE_V1_LEN
Definition: chm_lib.c:432
#define FILE_SHARE_READ
Definition: compat.h:136
#define CHM_NULL_FD
Definition: chm_lib.c:77
void chm_close(struct chmFile *h)
Definition: chm_lib.c:863
static BOOL _unmarshal_lzxc_reset_table(unsigned char **pData, unsigned int *pDataLen, struct chmLzxcResetTable *dest)
Definition: chm_lib.c:444
#define _CHM_ITSF_V3_LEN
Definition: chm_lib.c:237
#define CHM_PARAM_MAX_BLOCKS_CACHED
Definition: chm_lib.c:86
#define _CHM_ITSP_V1_LEN
Definition: chm_lib.c:313
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
smooth NULL
Definition: ftsmooth.c:416
int chm_resolve_object(struct chmFile *h, const WCHAR *objPath, struct chmUnitInfo *ui)
Definition: chm_lib.c:1048
#define OPEN_EXISTING
Definition: compat.h:634
LONGINT64 chm_retrieve_object(struct chmFile *h, struct chmUnitInfo *ui, unsigned char *buf, LONGUINT64 addr, LONGINT64 len)
Definition: chm_lib.c:1342
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define CHM_RESOLVE_SUCCESS
Definition: chm_lib.h:82
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define GENERIC_READ
Definition: compat.h:135
static Int64 _chm_fetch_bytes(struct chmFile *h, UChar *buf, UInt64 os, Int64 len)
Definition: chm_lib.c:566
static const WCHAR _CHMU_CONTENT[]
Definition: chm_lib.c:224
static void chm_set_param(struct chmFile *h, int paramType, int paramVal)
Definition: chm_lib.c:613
#define CHM_MAX_BLOCKS_CACHED
Definition: chm_lib.c:84
#define long
Definition: qsort.c:33
static const WCHAR _CHMU_RESET_TABLE[]
Definition: chm_lib.c:207
#define CreateFileW
Definition: compat.h:600
static const WCHAR _CHMU_LZXC_CONTROLDATA[]
Definition: chm_lib.c:218
static BOOL _unmarshal_itsf_header(unsigned char **pData, unsigned int *pDataLen, struct chmItsfHeader *dest)
Definition: chm_lib.c:255
#define CHM_COMPRESSED
Definition: chm_lib.h:60
#define HeapFree(x, y, z)
Definition: compat.h:594

Referenced by ITSProtocol_Start(), and ITSS_StgOpenStorage().

◆ chm_resolve_object()

int chm_resolve_object ( struct chmFile h,
const WCHAR objPath,
struct chmUnitInfo ui 
)

Definition at line 1048 of file chm_lib.c.

1051 {
1052  /*
1053  * XXX: implement caching scheme for dir pages
1054  */
1055 
1056  Int32 curPage;
1057 
1058  /* buffer to hold whatever page we're looking at */
1059  UChar *page_buf = HeapAlloc(GetProcessHeap(), 0, h->block_len);
1060 
1061  /* starting page */
1062  curPage = h->index_root;
1063 
1064  /* until we have either returned or given up */
1065  while (curPage != -1)
1066  {
1067 
1068  /* try to fetch the index page */
1069  if (_chm_fetch_bytes(h, page_buf,
1070  h->dir_offset + (UInt64)curPage*h->block_len,
1071  h->block_len) != h->block_len)
1072  {
1073  HeapFree(GetProcessHeap(), 0, page_buf);
1074  return CHM_RESOLVE_FAILURE;
1075  }
1076 
1077  /* now, if it is a leaf node: */
1078  if (memcmp(page_buf, _chm_pmgl_marker, 4) == 0)
1079  {
1080  /* scan block */
1081  UChar *pEntry = _chm_find_in_PMGL(page_buf,
1082  h->block_len,
1083  objPath);
1084  if (pEntry == NULL)
1085  {
1086  HeapFree(GetProcessHeap(), 0, page_buf);
1087  return CHM_RESOLVE_FAILURE;
1088  }
1089 
1090  /* parse entry and return */
1091  _chm_parse_PMGL_entry(&pEntry, ui);
1092  HeapFree(GetProcessHeap(), 0, page_buf);
1093  return CHM_RESOLVE_SUCCESS;
1094  }
1095 
1096  /* else, if it is a branch node: */
1097  else if (memcmp(page_buf, _chm_pmgi_marker, 4) == 0)
1098  curPage = _chm_find_in_PMGI(page_buf, h->block_len, objPath);
1099 
1100  /* else, we are confused. give up. */
1101  else
1102  {
1103  HeapFree(GetProcessHeap(), 0, page_buf);
1104  return CHM_RESOLVE_FAILURE;
1105  }
1106  }
1107 
1108  /* didn't find anything. fail. */
1109  HeapFree(GetProcessHeap(), 0, page_buf);
1110  return CHM_RESOLVE_FAILURE;
1111 }
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
UINT ui
Definition: oleauto.h:49
ULONGLONG UInt64
Definition: chm_lib.c:106
BYTE UChar
Definition: chm_lib.c:100
static Int32 _chm_find_in_PMGI(UChar *page_buf, UInt32 block_len, const WCHAR *objPath)
Definition: chm_lib.c:1006
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define CHM_RESOLVE_SUCCESS
Definition: chm_lib.h:82
#define CHM_RESOLVE_FAILURE
Definition: chm_lib.h:83
static const char _chm_pmgi_marker[4]
Definition: chm_lib.c:404
static Int64 _chm_fetch_bytes(struct chmFile *h, UChar *buf, UInt64 os, Int64 len)
Definition: chm_lib.c:566
static UChar * _chm_find_in_PMGL(UChar *page_buf, UInt32 block_len, const WCHAR *objPath)
Definition: chm_lib.c:964
static BOOL _chm_parse_PMGL_entry(UChar **pEntry, struct chmUnitInfo *ui)
Definition: chm_lib.c:943
LONG Int32
Definition: chm_lib.c:103
static const char _chm_pmgl_marker[4]
Definition: chm_lib.c:370
#define HeapFree(x, y, z)
Definition: compat.h:594

Referenced by chm_openW(), ITSProtocol_Start(), and ITSS_IStorageImpl_OpenStream().

◆ chm_retrieve_object()

LONGINT64 chm_retrieve_object ( struct chmFile h,
struct chmUnitInfo ui,
unsigned char buf,
LONGUINT64  addr,
LONGINT64  len 
)

Definition at line 1342 of file chm_lib.c.

1347 {
1348  /* must be valid file handle */
1349  if (h == NULL)
1350  return 0;
1351 
1352  /* starting address must be in correct range */
1353  if (addr >= ui->length)
1354  return 0;
1355 
1356  /* clip length */
1357  if (addr + len > ui->length)
1358  len = ui->length - addr;
1359 
1360  /* if the file is uncompressed, it's simple */
1361  if (ui->space == CHM_UNCOMPRESSED)
1362  {
1363  /* read data */
1364  return _chm_fetch_bytes(h,
1365  buf,
1366  h->data_offset + ui->start + addr,
1367  len);
1368  }
1369 
1370  /* else if the file is compressed, it's a little trickier */
1371  else /* ui->space == CHM_COMPRESSED */
1372  {
1373  Int64 swath=0, total=0;
1374 
1375  /* if compression is not enabled for this file... */
1376  if (! h->compression_enabled)
1377  return total;
1378 
1379  do {
1380 
1381  /* swill another mouthful */
1382  swath = _chm_decompress_region(h, buf, ui->start + addr, len);
1383 
1384  /* if we didn't get any... */
1385  if (swath == 0)
1386  return total;
1387 
1388  /* update stats */
1389  total += swath;
1390  len -= swath;
1391  addr += swath;
1392  buf += swath;
1393 
1394  } while (len != 0);
1395 
1396  return total;
1397  }
1398 }
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
UINT ui
Definition: oleauto.h:49
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
smooth NULL
Definition: ftsmooth.c:416
static Int64 _chm_decompress_region(struct chmFile *h, UChar *buf, UInt64 start, Int64 len)
Definition: chm_lib.c:1290
GLenum const GLvoid * addr
Definition: glext.h:9621
GLenum GLsizei len
Definition: glext.h:6722
static Int64 _chm_fetch_bytes(struct chmFile *h, UChar *buf, UInt64 os, Int64 len)
Definition: chm_lib.c:566
#define CHM_UNCOMPRESSED
Definition: chm_lib.h:59
LONGLONG Int64
Definition: chm_lib.c:105

Referenced by chm_openW(), ITSProtocol_Read(), and ITSS_IStream_Read().