ReactOS 0.4.17-dev-966-gf06eace
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 chmFile * chm_openW (const WCHAR *filename)
 
struct chmFile * chm_dup (struct chmFile *oldHandle)
 
void chm_close (struct chmFile *h)
 
int chm_resolve_object (struct chmFile *h, const WCHAR *objPath, struct chmUnitInfo *ui)
 
LONGINT64 chm_retrieve_object (struct chmFile *h, struct chmUnitInfo *ui, unsigned char *buf, LONGUINT64 addr, LONGINT64 len)
 
BOOL chm_enumerate_dir (struct chmFile *h, const WCHAR *prefix, int what, CHM_ENUMERATOR e, void *context)
 

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 99 of file chm_lib.h.

◆ CHM_ENUMERATE_DIRS

#define CHM_ENUMERATE_DIRS   (16)

Definition at line 98 of file chm_lib.h.

◆ CHM_ENUMERATE_FILES

#define CHM_ENUMERATE_FILES   (8)

Definition at line 97 of file chm_lib.h.

◆ CHM_ENUMERATE_META

#define CHM_ENUMERATE_META   (2)

Definition at line 95 of file chm_lib.h.

◆ CHM_ENUMERATE_NORMAL

#define CHM_ENUMERATE_NORMAL   (1)

Definition at line 94 of file chm_lib.h.

◆ CHM_ENUMERATE_SPECIAL

#define CHM_ENUMERATE_SPECIAL   (4)

Definition at line 96 of file chm_lib.h.

◆ CHM_ENUMERATOR_CONTINUE

#define CHM_ENUMERATOR_CONTINUE   (1)

Definition at line 101 of file chm_lib.h.

◆ CHM_ENUMERATOR_FAILURE

#define CHM_ENUMERATOR_FAILURE   (0)

Definition at line 100 of file chm_lib.h.

◆ CHM_ENUMERATOR_SUCCESS

#define CHM_ENUMERATOR_SUCCESS   (2)

Definition at line 102 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 91 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 835 of file chm_lib.c.

836{
837 if (h != NULL)
838 {
839 if (h->fd != CHM_NULL_FD)
840 CHM_CLOSE_FILE(h->fd);
841 h->fd = CHM_NULL_FD;
842
843 h->mutex.DebugInfo->Spare[0] = 0;
844 DeleteCriticalSection(&h->mutex);
845 h->lzx_mutex.DebugInfo->Spare[0] = 0;
846 DeleteCriticalSection(&h->lzx_mutex);
847 h->cache_mutex.DebugInfo->Spare[0] = 0;
848 DeleteCriticalSection(&h->cache_mutex);
849
850 if (h->lzx_state)
851 LZXteardown(h->lzx_state);
852 h->lzx_state = NULL;
853
854 if (h->cache_blocks)
855 {
856 int i;
857 for (i=0; i<h->cache_num_blocks; i++)
858 {
859 HeapFree(GetProcessHeap(), 0, h->cache_blocks[i]);
860 }
861 HeapFree(GetProcessHeap(), 0, h->cache_blocks);
862 h->cache_blocks = NULL;
863 }
864
865 HeapFree(GetProcessHeap(), 0, h->cache_block_indices);
866 h->cache_block_indices = NULL;
867
869 }
870}
#define CHM_CLOSE_FILE(fd)
Definition: chm_lib.c:78
#define CHM_NULL_FD
Definition: chm_lib.c:77
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define HeapFree(x, y, z)
Definition: compat.h:735
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
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
void LZXteardown(struct LZXstate *pState)
Definition: lzx.c:209
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

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

◆ chm_dup()

struct chmFile * chm_dup ( struct chmFile *  oldHandle)

Definition at line 803 of file chm_lib.c.

804{
805 struct chmFile *newHandle=NULL;
806
807 newHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(struct chmFile));
808 *newHandle = *oldHandle;
809
810 /* duplicate fd handle */
812 GetCurrentProcess(), &(newHandle->fd),
814 newHandle->lzx_state = NULL;
815 newHandle->cache_blocks = NULL;
816 newHandle->cache_block_indices = NULL;
817 newHandle->cache_num_blocks = 0;
818
819 /* initialize mutexes, if needed */
821 newHandle->mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.mutex");
823 newHandle->lzx_mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.lzx_mutex");
825 newHandle->cache_mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.cache_mutex");
826
827 /* initialize cache */
830
831 return newHandle;
832}
static void chm_set_param(struct chmFile *h, int paramType, int paramVal)
Definition: chm_lib.c:588
#define CHM_MAX_BLOCKS_CACHED
Definition: chm_lib.c:84
#define CHM_PARAM_MAX_BLOCKS_CACHED
Definition: chm_lib.c:86
#define FALSE
Definition: types.h:117
#define HeapAlloc
Definition: compat.h:733
#define GetCurrentProcess()
Definition: compat.h:759
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
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
PRTL_CRITICAL_SECTION_DEBUG DebugInfo
Definition: rtltypes.h:1478
Int64 * cache_block_indices
Definition: chm_lib.c:532
Int32 cache_num_blocks
Definition: chm_lib.c:533
HANDLE fd
Definition: chm_lib.c:502
CRITICAL_SECTION cache_mutex
Definition: chm_lib.c:506
UChar ** cache_blocks
Definition: chm_lib.c:531
struct LZXstate * lzx_state
Definition: chm_lib.c:527
CRITICAL_SECTION lzx_mutex
Definition: chm_lib.c:505
CRITICAL_SECTION mutex
Definition: chm_lib.c:504
#define DWORD_PTR
Definition: treelist.c:76
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156
#define DUPLICATE_SAME_ACCESS

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 1372 of file chm_lib.c.

1377{
1378 /*
1379 * XXX: do this efficiently (i.e. using the tree index)
1380 */
1381
1382 Int32 curPage;
1383
1384 /* buffer to hold whatever page we're looking at */
1385 UChar *page_buf = HeapAlloc(GetProcessHeap(), 0, h->block_len);
1386 struct chmPmglHeader header;
1387 UChar *end;
1388 UChar *cur;
1389 unsigned int lenRemain;
1390
1391 /* set to TRUE once we've started */
1392 BOOL it_has_begun = FALSE;
1393
1394 /* the current ui */
1395 struct chmUnitInfo ui;
1396 int flag;
1397 UInt64 ui_path_len;
1398
1399 /* the length of the prefix */
1400 WCHAR prefixRectified[CHM_MAX_PATHLEN+1];
1401 int prefixLen;
1402 WCHAR lastPath[CHM_MAX_PATHLEN];
1403 int lastPathLen;
1404
1405 /* starting page */
1406 curPage = h->index_head;
1407
1408 /* initialize pathname state */
1409 lstrcpynW(prefixRectified, prefix, CHM_MAX_PATHLEN);
1410 prefixLen = lstrlenW(prefixRectified);
1411 if (prefixLen != 0)
1412 {
1413 if (prefixRectified[prefixLen-1] != '/')
1414 {
1415 prefixRectified[prefixLen] = '/';
1416 prefixRectified[prefixLen+1] = '\0';
1417 ++prefixLen;
1418 }
1419 }
1420 lastPath[0] = '\0';
1421 lastPathLen = -1;
1422
1423 /* until we have either returned or given up */
1424 while (curPage != -1)
1425 {
1426
1427 /* try to fetch the index page */
1428 if (_chm_fetch_bytes(h,
1429 page_buf,
1430 h->dir_offset + (UInt64)curPage*h->block_len,
1431 h->block_len) != h->block_len)
1432 {
1433 HeapFree(GetProcessHeap(), 0, page_buf);
1434 return FALSE;
1435 }
1436
1437 /* figure out start and end for this page */
1438 cur = page_buf;
1439 lenRemain = _CHM_PMGL_LEN;
1440 if (! _unmarshal_pmgl_header(&cur, &lenRemain, &header))
1441 {
1442 HeapFree(GetProcessHeap(), 0, page_buf);
1443 return FALSE;
1444 }
1445 end = page_buf + h->block_len - (header.free_space);
1446
1447 /* loop over this page */
1448 while (cur < end)
1449 {
1450 if (! _chm_parse_PMGL_entry(&cur, &ui))
1451 {
1452 HeapFree(GetProcessHeap(), 0, page_buf);
1453 return FALSE;
1454 }
1455
1456 /* check if we should start */
1457 if (! it_has_begun)
1458 {
1459 if (ui.length == 0 && wcsnicmp(ui.path, prefixRectified, prefixLen) == 0)
1460 it_has_begun = TRUE;
1461 else
1462 continue;
1463
1464 if (ui.path[prefixLen] == '\0')
1465 continue;
1466 }
1467
1468 /* check if we should stop */
1469 else
1470 {
1471 if (wcsnicmp(ui.path, prefixRectified, prefixLen) != 0)
1472 {
1473 HeapFree(GetProcessHeap(), 0, page_buf);
1474 return TRUE;
1475 }
1476 }
1477
1478 /* check if we should include this path */
1479 if (lastPathLen != -1)
1480 {
1481 if (wcsnicmp(ui.path, lastPath, lastPathLen) == 0)
1482 continue;
1483 }
1484 lstrcpyW(lastPath, ui.path);
1485 lastPathLen = lstrlenW(lastPath);
1486
1487 /* get the length of the path */
1488 ui_path_len = lstrlenW(ui.path)-1;
1489
1490 /* check for DIRS */
1491 if (ui.path[ui_path_len] == '/' && !(what & CHM_ENUMERATE_DIRS))
1492 continue;
1493
1494 /* check for FILES */
1495 if (ui.path[ui_path_len] != '/' && !(what & CHM_ENUMERATE_FILES))
1496 continue;
1497
1498 /* check for NORMAL vs. META */
1499 if (ui.path[0] == '/')
1500 {
1501
1502 /* check for NORMAL vs. SPECIAL */
1503 if (ui.path[1] == '#' || ui.path[1] == '$')
1505 else
1507 }
1508 else
1510 if (! (what & flag))
1511 continue;
1512
1513 /* call the enumerator */
1514 {
1515 int status = (*e)(h, &ui, context);
1516 switch (status)
1517 {
1519 HeapFree(GetProcessHeap(), 0, page_buf);
1520 return FALSE;
1522 break;
1524 HeapFree(GetProcessHeap(), 0, page_buf);
1525 return TRUE;
1526 default:
1527 break;
1528 }
1529 }
1530 }
1531
1532 /* advance to next page */
1533 curPage = header.block_next;
1534 }
1535
1536 HeapFree(GetProcessHeap(), 0, page_buf);
1537 return TRUE;
1538}
static BOOL _unmarshal_pmgl_header(unsigned char **pData, unsigned int *pDataLen, struct chmPmglHeader *dest)
Definition: chm_lib.c:356
LONG Int32
Definition: chm_lib.c:103
BYTE UChar
Definition: chm_lib.c:100
ULONGLONG UInt64
Definition: chm_lib.c:106
#define _CHM_PMGL_LEN
Definition: chm_lib.c:346
static BOOL _chm_parse_PMGL_entry(UChar **pEntry, struct chmUnitInfo *ui)
Definition: chm_lib.c:915
static Int64 _chm_fetch_bytes(struct chmFile *h, UChar *buf, UInt64 os, Int64 len)
Definition: chm_lib.c:541
#define CHM_ENUMERATE_NORMAL
Definition: chm_lib.h:94
#define CHM_ENUMERATOR_CONTINUE
Definition: chm_lib.h:101
#define CHM_ENUMERATE_META
Definition: chm_lib.h:95
#define CHM_ENUMERATE_SPECIAL
Definition: chm_lib.h:96
#define CHM_ENUMERATE_DIRS
Definition: chm_lib.h:98
#define CHM_MAX_PATHLEN
Definition: chm_lib.h:66
#define CHM_ENUMERATE_FILES
Definition: chm_lib.h:97
#define CHM_ENUMERATOR_SUCCESS
Definition: chm_lib.h:102
#define CHM_ENUMERATOR_FAILURE
Definition: chm_lib.h:100
#define TRUE
Definition: types.h:120
#define wcsnicmp
Definition: compat.h:14
#define lstrcpyW
Definition: compat.h:749
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
unsigned int BOOL
Definition: ntddk_ex.h:94
FxCollectionEntry * cur
GLuint GLuint end
Definition: gl.h:1545
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
UINT ui
Definition: oleauto.h:49
short WCHAR
Definition: pedump.c:58
Definition: http.c:7252
Definition: ps.c:97
Character const *const prefix
Definition: tempnam.cpp:195

Referenced by ITSS_IStorageImpl_EnumElements().

◆ chm_openW()

struct chmFile * chm_openW ( const WCHAR *  filename)

Definition at line 653 of file chm_lib.c.

654{
655 unsigned char sbuffer[256];
656 unsigned int sremain;
657 unsigned char *sbufpos;
658 struct chmFile *newHandle=NULL;
659 struct chmItsfHeader itsfHeader;
660 struct chmItspHeader itspHeader;
661#if 0
662 struct chmUnitInfo uiSpan;
663#endif
664 struct chmUnitInfo uiLzxc;
665 struct chmLzxcControlData ctlData;
666
667 /* allocate handle */
668 newHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(struct chmFile));
669 newHandle->fd = CHM_NULL_FD;
670 newHandle->lzx_state = NULL;
671 newHandle->cache_blocks = NULL;
672 newHandle->cache_block_indices = NULL;
673 newHandle->cache_num_blocks = 0;
674
675 /* open file */
676 if ((newHandle->fd=CreateFileW(filename,
679 NULL,
682 NULL)) == CHM_NULL_FD)
683 {
684 HeapFree(GetProcessHeap(), 0, newHandle);
685 return NULL;
686 }
687
688 /* initialize mutexes, if needed */
690 newHandle->mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.mutex");
692 newHandle->lzx_mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.lzx_mutex");
694 newHandle->cache_mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": chmFile.cache_mutex");
695
696 /* read and verify header */
697 sremain = _CHM_ITSF_V3_LEN;
698 sbufpos = sbuffer;
699 if (_chm_fetch_bytes(newHandle, sbuffer, 0, sremain) != sremain ||
700 !_unmarshal_itsf_header(&sbufpos, &sremain, &itsfHeader))
701 {
702 chm_close(newHandle);
703 return NULL;
704 }
705
706 /* stash important values from header */
707 newHandle->dir_offset = itsfHeader.dir_offset;
708 newHandle->dir_len = itsfHeader.dir_len;
709 newHandle->data_offset = itsfHeader.data_offset;
710
711 /* now, read and verify the directory header chunk */
712 sremain = _CHM_ITSP_V1_LEN;
713 sbufpos = sbuffer;
714 if (_chm_fetch_bytes(newHandle, sbuffer,
715 itsfHeader.dir_offset, sremain) != sremain ||
716 !_unmarshal_itsp_header(&sbufpos, &sremain, &itspHeader))
717 {
718 chm_close(newHandle);
719 return NULL;
720 }
721
722 /* grab essential information from ITSP header */
723 newHandle->dir_offset += itspHeader.header_len;
724 newHandle->dir_len -= itspHeader.header_len;
725 newHandle->index_root = itspHeader.index_root;
726 newHandle->index_head = itspHeader.index_head;
727 newHandle->block_len = itspHeader.block_len;
728
729 /* if the index root is -1, this means we don't have any PMGI blocks.
730 * as a result, we must use the sole PMGL block as the index root
731 */
732 if (newHandle->index_root == -1)
733 newHandle->index_root = newHandle->index_head;
734
735 /* initialize cache */
738
739 /* By default, compression is enabled. */
740 newHandle->compression_enabled = 1;
741
742 /* prefetch most commonly needed unit infos */
744 L"::DataSpace/Storage/MSCompressed/Transform/"
745 "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/"
746 "InstanceData/ResetTable",
747 &newHandle->rt_unit) ||
748 newHandle->rt_unit.space == CHM_COMPRESSED ||
750 L"::DataSpace/Storage/MSCompressed/Content",
751 &newHandle->cn_unit) ||
752 newHandle->cn_unit.space == CHM_COMPRESSED ||
754 L"::DataSpace/Storage/MSCompressed/ControlData",
755 &uiLzxc) ||
756 uiLzxc.space == CHM_COMPRESSED)
757 {
758 newHandle->compression_enabled = 0;
759 }
760
761 /* read reset table info */
762 if (newHandle->compression_enabled)
763 {
765 sbufpos = sbuffer;
766 if (chm_retrieve_object(newHandle, &newHandle->rt_unit, sbuffer,
767 0, sremain) != sremain ||
768 !_unmarshal_lzxc_reset_table(&sbufpos, &sremain,
769 &newHandle->reset_table))
770 {
771 newHandle->compression_enabled = 0;
772 }
773 }
774
775 /* read control data */
776 if (newHandle->compression_enabled)
777 {
778 sremain = (unsigned long)uiLzxc.length;
779 sbufpos = sbuffer;
780 if (chm_retrieve_object(newHandle, &uiLzxc, sbuffer,
781 0, sremain) != sremain ||
782 !_unmarshal_lzxc_control_data(&sbufpos, &sremain,
783 &ctlData))
784 {
785 newHandle->compression_enabled = 0;
786 }
787 else
788 {
789 newHandle->window_size = ctlData.windowSize;
790 newHandle->reset_interval = ctlData.resetInterval;
791/* Jed, Mon Jun 28: Experimentally, it appears that the reset block count */
792/* must be multiplied by this formerly unknown ctrl data field in */
793/* order to decompress some files. */
794 newHandle->reset_blkcount = newHandle->reset_interval / (newHandle->window_size / 2) *
795 ctlData.windowsPerReset;
796 }
797 }
798
799 return newHandle;
800}
#define _CHM_LZXC_RESETTABLE_V1_LEN
Definition: chm_lib.c:407
LONGINT64 chm_retrieve_object(struct chmFile *h, struct chmUnitInfo *ui, unsigned char *buf, LONGUINT64 addr, LONGINT64 len)
Definition: chm_lib.c:1314
int chm_resolve_object(struct chmFile *h, const WCHAR *objPath, struct chmUnitInfo *ui)
Definition: chm_lib.c:1020
static BOOL _unmarshal_itsp_header(unsigned char **pData, unsigned int *pDataLen, struct chmItspHeader *dest)
Definition: chm_lib.c:308
static BOOL _unmarshal_lzxc_reset_table(unsigned char **pData, unsigned int *pDataLen, struct chmLzxcResetTable *dest)
Definition: chm_lib.c:419
#define _CHM_ITSP_V1_LEN
Definition: chm_lib.c:288
static BOOL _unmarshal_lzxc_control_data(unsigned char **pData, unsigned int *pDataLen, struct chmLzxcControlData *dest)
Definition: chm_lib.c:457
#define _CHM_ITSF_V3_LEN
Definition: chm_lib.c:212
static BOOL _unmarshal_itsf_header(unsigned char **pData, unsigned int *pDataLen, struct chmItsfHeader *dest)
Definition: chm_lib.c:230
void chm_close(struct chmFile *h)
Definition: chm_lib.c:835
#define CHM_COMPRESSED
Definition: chm_lib.h:60
#define CHM_RESOLVE_SUCCESS
Definition: chm_lib.h:82
#define OPEN_EXISTING
Definition: compat.h:775
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
#define L(x)
Definition: resources.c:13
const char * filename
Definition: ioapi.h:137
if(dx< 0)
Definition: linetemp.h:194
#define long
Definition: qsort.c:33
UInt32 reset_blkcount
Definition: chm_lib.c:524
UInt32 window_size
Definition: chm_lib.c:522
Int32 index_root
Definition: chm_lib.c:511
UInt64 dir_offset
Definition: chm_lib.c:508
struct chmUnitInfo rt_unit
Definition: chm_lib.c:516
struct chmUnitInfo cn_unit
Definition: chm_lib.c:517
int compression_enabled
Definition: chm_lib.c:521
Int32 index_head
Definition: chm_lib.c:512
UInt32 reset_interval
Definition: chm_lib.c:523
UInt64 dir_len
Definition: chm_lib.c:509
UInt64 data_offset
Definition: chm_lib.c:510
UInt32 block_len
Definition: chm_lib.c:513
struct chmLzxcResetTable reset_table
Definition: chm_lib.c:518

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 1020 of file chm_lib.c.

1023{
1024 /*
1025 * XXX: implement caching scheme for dir pages
1026 */
1027
1028 Int32 curPage;
1029
1030 /* buffer to hold whatever page we're looking at */
1031 UChar *page_buf = HeapAlloc(GetProcessHeap(), 0, h->block_len);
1032
1033 /* starting page */
1034 curPage = h->index_root;
1035
1036 /* until we have either returned or given up */
1037 while (curPage != -1)
1038 {
1039
1040 /* try to fetch the index page */
1041 if (_chm_fetch_bytes(h, page_buf,
1042 h->dir_offset + (UInt64)curPage*h->block_len,
1043 h->block_len) != h->block_len)
1044 {
1045 HeapFree(GetProcessHeap(), 0, page_buf);
1046 return CHM_RESOLVE_FAILURE;
1047 }
1048
1049 /* now, if it is a leaf node: */
1050 if (memcmp(page_buf, _chm_pmgl_marker, 4) == 0)
1051 {
1052 /* scan block */
1053 UChar *pEntry = _chm_find_in_PMGL(page_buf,
1054 h->block_len,
1055 objPath);
1056 if (pEntry == NULL)
1057 {
1058 HeapFree(GetProcessHeap(), 0, page_buf);
1059 return CHM_RESOLVE_FAILURE;
1060 }
1061
1062 /* parse entry and return */
1064 HeapFree(GetProcessHeap(), 0, page_buf);
1065 return CHM_RESOLVE_SUCCESS;
1066 }
1067
1068 /* else, if it is a branch node: */
1069 else if (memcmp(page_buf, _chm_pmgi_marker, 4) == 0)
1070 curPage = _chm_find_in_PMGI(page_buf, h->block_len, objPath);
1071
1072 /* else, we are confused. give up. */
1073 else
1074 {
1075 HeapFree(GetProcessHeap(), 0, page_buf);
1076 return CHM_RESOLVE_FAILURE;
1077 }
1078 }
1079
1080 /* didn't find anything. fail. */
1081 HeapFree(GetProcessHeap(), 0, page_buf);
1082 return CHM_RESOLVE_FAILURE;
1083}
static Int32 _chm_find_in_PMGI(UChar *page_buf, UInt32 block_len, const WCHAR *objPath)
Definition: chm_lib.c:978
static const char _chm_pmgi_marker[4]
Definition: chm_lib.c:379
static UChar * _chm_find_in_PMGL(UChar *page_buf, UInt32 block_len, const WCHAR *objPath)
Definition: chm_lib.c:936
static const char _chm_pmgl_marker[4]
Definition: chm_lib.c:345
#define CHM_RESOLVE_FAILURE
Definition: chm_lib.h:83
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

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 1314 of file chm_lib.c.

1319{
1320 /* must be valid file handle */
1321 if (h == NULL)
1322 return 0;
1323
1324 /* starting address must be in correct range */
1325 if (addr >= ui->length)
1326 return 0;
1327
1328 /* clip length */
1329 if (addr + len > ui->length)
1330 len = ui->length - addr;
1331
1332 /* if the file is uncompressed, it's simple */
1333 if (ui->space == CHM_UNCOMPRESSED)
1334 {
1335 /* read data */
1336 return _chm_fetch_bytes(h,
1337 buf,
1338 h->data_offset + ui->start + addr,
1339 len);
1340 }
1341
1342 /* else if the file is compressed, it's a little trickier */
1343 else /* ui->space == CHM_COMPRESSED */
1344 {
1345 Int64 swath=0, total=0;
1346
1347 /* if compression is not enabled for this file... */
1348 if (! h->compression_enabled)
1349 return total;
1350
1351 do {
1352
1353 /* swill another mouthful */
1354 swath = _chm_decompress_region(h, buf, ui->start + addr, len);
1355
1356 /* if we didn't get any... */
1357 if (swath == 0)
1358 return total;
1359
1360 /* update stats */
1361 total += swath;
1362 len -= swath;
1363 addr += swath;
1364 buf += swath;
1365
1366 } while (len != 0);
1367
1368 return total;
1369 }
1370}
static Int64 _chm_decompress_region(struct chmFile *h, UChar *buf, UInt64 start, Int64 len)
Definition: chm_lib.c:1262
LONGLONG Int64
Definition: chm_lib.c:105
#define CHM_UNCOMPRESSED
Definition: chm_lib.h:59
size_t total
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum const GLvoid * addr
Definition: glext.h:9621
GLenum GLsizei len
Definition: glext.h:6722

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