Authors: Stewart Caie<kyz@uklinux.net>, Jed Wing <jedwin@ugcs.caltech.edu>, Mike McCormack <mike@codeweavers.com>
Added an implemenation of ITSS.DLL.
This commit is contained in:
parent
47c94c0e4d
commit
5f6e3c88bd
|
@ -1576,6 +1576,7 @@ dlls/imagehlp/Makefile
|
|||
dlls/imm32/Makefile
|
||||
dlls/iphlpapi/Makefile
|
||||
dlls/iphlpapi/tests/Makefile
|
||||
dlls/itss/Makefile
|
||||
dlls/kernel/Makefile
|
||||
dlls/kernel/tests/Makefile
|
||||
dlls/lzexpand/Makefile
|
||||
|
|
|
@ -63,6 +63,7 @@ BASEDIRS = \
|
|||
imagehlp \
|
||||
imm32 \
|
||||
iphlpapi \
|
||||
itss \
|
||||
kernel \
|
||||
lzexpand \
|
||||
mapi32 \
|
||||
|
@ -287,6 +288,7 @@ SYMLINKS_SO = \
|
|||
imagehlp.dll.so \
|
||||
imm32.dll.so \
|
||||
iphlpapi.dll.so \
|
||||
itss.dll.so \
|
||||
joystick.drv.so \
|
||||
kernel32.dll.so \
|
||||
libdxerr8.a \
|
||||
|
@ -578,6 +580,9 @@ imm.dll.so : imm32.dll.so
|
|||
iphlpapi.dll.so: iphlpapi/iphlpapi.dll.so
|
||||
$(RM) $@ && $(LN_S) iphlpapi/iphlpapi.dll.so $@
|
||||
|
||||
itss.dll.so: itss/itss.dll.so
|
||||
$(RM) $@ && $(LN_S) itss/itss.dll.so $@
|
||||
|
||||
joystick.drv.so: winmm/joystick/joystick.drv.so
|
||||
$(RM) $@ && $(LN_S) winmm/joystick/joystick.drv.so $@
|
||||
|
||||
|
@ -1013,6 +1018,7 @@ IMPORT_LIBS = \
|
|||
libimagehlp.$(IMPLIBEXT) \
|
||||
libimm32.$(IMPLIBEXT) \
|
||||
libiphlpapi.$(IMPLIBEXT) \
|
||||
libitss.$(IMPLIBEXT) \
|
||||
libkernel32.$(IMPLIBEXT) \
|
||||
liblz32.$(IMPLIBEXT) \
|
||||
libmapi32.$(IMPLIBEXT) \
|
||||
|
@ -1348,6 +1354,11 @@ libiphlpapi.def: iphlpapi/iphlpapi.spec.def
|
|||
libiphlpapi.a: iphlpapi/iphlpapi.spec.def
|
||||
$(DLLTOOL) -k -l $@ -d iphlpapi/iphlpapi.spec.def
|
||||
|
||||
libitss.def: itss/itss.spec.def
|
||||
$(RM) $@ && $(LN_S) itss/itss.spec.def $@
|
||||
libitss.a: itss/itss.spec.def
|
||||
$(DLLTOOL) -k -l $@ -d itss/itss.spec.def
|
||||
|
||||
libkernel32.def: kernel/kernel32.spec.def
|
||||
$(RM) $@ && $(LN_S) kernel/kernel32.spec.def $@
|
||||
libkernel32.a: kernel/kernel32.spec.def
|
||||
|
@ -1759,6 +1770,7 @@ icmp/icmp.spec.def: $(WINEBUILD)
|
|||
imagehlp/imagehlp.spec.def: $(WINEBUILD)
|
||||
imm32/imm32.spec.def: $(WINEBUILD)
|
||||
iphlpapi/iphlpapi.spec.def: $(WINEBUILD)
|
||||
itss/itss.spec.def: $(WINEBUILD)
|
||||
kernel/kernel32.spec.def: $(WINEBUILD)
|
||||
lzexpand/lz32.spec.def: $(WINEBUILD)
|
||||
mapi32/mapi32.spec.def: $(WINEBUILD)
|
||||
|
@ -1891,6 +1903,7 @@ msacm/imaadp32/imaadp32.acm.so: msacm/imaadp32
|
|||
imagehlp/imagehlp.dll.so: imagehlp
|
||||
imm32/imm32.dll.so: imm32
|
||||
iphlpapi/iphlpapi.dll.so: iphlpapi
|
||||
itss/itss.dll.so: itss
|
||||
winmm/joystick/joystick.drv.so: winmm/joystick
|
||||
kernel/kernel32.dll.so: kernel
|
||||
lzexpand/lz32.dll.so: lzexpand
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Makefile
|
||||
itss.dll.dbg.c
|
||||
itss.spec.def
|
|
@ -0,0 +1,29 @@
|
|||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = itss.dll
|
||||
IMPORTS = ole32 user32 advapi32 kernel32 ntdll
|
||||
EXTRALIBS = $(LIBUNICODE) -luuid
|
||||
EXTRADEFS = -DCOM_NO_WINDOWS_H
|
||||
|
||||
C_SRCS = \
|
||||
chm_lib.c \
|
||||
lzx.c \
|
||||
itss.c \
|
||||
moniker.c \
|
||||
storage.c
|
||||
|
||||
IDL_SRCS = \
|
||||
itss.idl
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
.SUFFIXES: .idl .h
|
||||
|
||||
.idl.h:
|
||||
$(WIDL) $(IDLFLAGS) -b -h -H $@ $<
|
||||
|
||||
idl: $(IDL_SRCS:.idl=.h)
|
||||
|
||||
### Dependencies:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,116 @@
|
|||
/* $Id$ */
|
||||
/***************************************************************************
|
||||
* chm_lib.h - CHM archive manipulation routines *
|
||||
* ------------------- *
|
||||
* *
|
||||
* author: Jed Wing <jedwin@ugcs.caltech.edu> *
|
||||
* version: 0.3 *
|
||||
* notes: These routines are meant for the manipulation of microsoft *
|
||||
* .chm (compiled html help) files, but may likely be used *
|
||||
* for the manipulation of any ITSS archive, if ever ITSS *
|
||||
* archives are used for any other purpose. *
|
||||
* *
|
||||
* Note also that the section names are statically handled. *
|
||||
* To be entirely correct, the section names should be read *
|
||||
* from the section names meta-file, and then the various *
|
||||
* content sections and the "transforms" to apply to the data *
|
||||
* they contain should be inferred from the section name and *
|
||||
* the meta-files referenced using that name; however, all of *
|
||||
* the files I've been able to get my hands on appear to have *
|
||||
* only two sections: Uncompressed and MSCompressed. *
|
||||
* Additionally, the ITSS.DLL file included with Windows does *
|
||||
* not appear to handle any different transforms than the *
|
||||
* simple LZX-transform. Furthermore, the list of transforms *
|
||||
* to apply is broken, in that only half the required space *
|
||||
* is allocated for the list. (It appears as though the *
|
||||
* space is allocated for ASCII strings, but the strings are *
|
||||
* written as unicode. As a result, only the first half of *
|
||||
* the string appears.) So this is probably not too big of *
|
||||
* a deal, at least until CHM v4 (MS .lit files), which also *
|
||||
* incorporate encryption, of some description. *
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation; either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef INCLUDED_CHMLIB_H
|
||||
#define INCLUDED_CHMLIB_H
|
||||
|
||||
typedef ULONGLONG LONGUINT64;
|
||||
typedef LONGLONG LONGINT64;
|
||||
|
||||
/* the two available spaces in a CHM file */
|
||||
/* N.B.: The format supports arbitrarily many spaces, but only */
|
||||
/* two appear to be used at present. */
|
||||
#define CHM_UNCOMPRESSED (0)
|
||||
#define CHM_COMPRESSED (1)
|
||||
|
||||
/* structure representing an ITS (CHM) file stream */
|
||||
struct chmFile;
|
||||
|
||||
/* structure representing an element from an ITS file stream */
|
||||
#define CHM_MAX_PATHLEN (256)
|
||||
struct chmUnitInfo
|
||||
{
|
||||
LONGUINT64 start;
|
||||
LONGUINT64 length;
|
||||
int space;
|
||||
WCHAR path[CHM_MAX_PATHLEN+1];
|
||||
};
|
||||
|
||||
struct chmFile* chm_openW(const WCHAR *filename);
|
||||
|
||||
/* close an ITS archive */
|
||||
void chm_close(struct chmFile *h);
|
||||
|
||||
/* methods for ssetting tuning parameters for particular file */
|
||||
#define CHM_PARAM_MAX_BLOCKS_CACHED 0
|
||||
void chm_set_param(struct chmFile *h,
|
||||
int paramType,
|
||||
int paramVal);
|
||||
|
||||
/* resolve a particular object from the archive */
|
||||
#define CHM_RESOLVE_SUCCESS (0)
|
||||
#define CHM_RESOLVE_FAILURE (1)
|
||||
int chm_resolve_object(struct chmFile *h,
|
||||
const WCHAR *objPath,
|
||||
struct chmUnitInfo *ui);
|
||||
|
||||
/* retrieve part of an object from the archive */
|
||||
LONGINT64 chm_retrieve_object(struct chmFile *h,
|
||||
struct chmUnitInfo *ui,
|
||||
unsigned char *buf,
|
||||
LONGUINT64 addr,
|
||||
LONGINT64 len);
|
||||
|
||||
/* enumerate the objects in the .chm archive */
|
||||
typedef int (*CHM_ENUMERATOR)(struct chmFile *h,
|
||||
struct chmUnitInfo *ui,
|
||||
void *context);
|
||||
#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)
|
||||
int chm_enumerate(struct chmFile *h,
|
||||
int what,
|
||||
CHM_ENUMERATOR e,
|
||||
void *context);
|
||||
|
||||
int chm_enumerate_dir(struct chmFile *h,
|
||||
const WCHAR *prefix,
|
||||
int what,
|
||||
CHM_ENUMERATOR e,
|
||||
void *context);
|
||||
|
||||
#endif /* INCLUDED_CHMLIB_H */
|
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
* ITSS Class Factory
|
||||
*
|
||||
* Copyright 2002 Lionel Ulmer
|
||||
* Copyright 2004 Mike McCormack
|
||||
*
|
||||
* see http://bonedaddy.net/pabs3/hhm/#chmspec
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "winreg.h"
|
||||
#include "ole2.h"
|
||||
|
||||
#include "itss.h"
|
||||
#include "uuids.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(itss);
|
||||
|
||||
#include "initguid.h"
|
||||
|
||||
DEFINE_GUID(CLSID_ITStorage,0x5d02926a,0x212e,0x11d0,0x9d,0xf9,0x00,0xa0,0xc9,0x22,0xe6,0xec );
|
||||
DEFINE_GUID(CLSID_ITSProtocol,0x9d148290,0xb9c8,0x11d0,0xa4,0xcc,0x00,0x00,0xf8,0x01,0x49,0xf6);
|
||||
DEFINE_GUID(IID_IITStorage, 0x88cc31de, 0x27ab, 0x11d0, 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
|
||||
|
||||
static HRESULT ITSS_create(IUnknown *pUnkOuter, LPVOID *ppObj);
|
||||
extern HRESULT ITS_IParseDisplayName_create(IUnknown *pUnkOuter, LPVOID *ppObj);
|
||||
extern HRESULT ITSS_StgOpenStorage( const WCHAR*, IStorage*, DWORD, SNB, DWORD, IStorage** );
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||
{
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hInstDLL);
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ITSS ClassFactory
|
||||
*/
|
||||
typedef struct {
|
||||
IClassFactory ITF_IClassFactory;
|
||||
|
||||
DWORD ref;
|
||||
HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
|
||||
} IClassFactoryImpl;
|
||||
|
||||
struct object_creation_info
|
||||
{
|
||||
const CLSID *clsid;
|
||||
LPCSTR szClassName;
|
||||
HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
|
||||
};
|
||||
|
||||
static const struct object_creation_info object_creation[] =
|
||||
{
|
||||
{ &CLSID_ITStorage, "ITStorage", ITSS_create },
|
||||
{ &CLSID_ITSProtocol, "ITSProtocol", ITS_IParseDisplayName_create },
|
||||
};
|
||||
|
||||
static HRESULT WINAPI
|
||||
ITSSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
|
||||
{
|
||||
ICOM_THIS(IClassFactoryImpl,iface);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IClassFactory))
|
||||
{
|
||||
IClassFactory_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSSCF_AddRef(LPCLASSFACTORY iface) {
|
||||
ICOM_THIS(IClassFactoryImpl,iface);
|
||||
return ++(This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSSCF_Release(LPCLASSFACTORY iface) {
|
||||
ICOM_THIS(IClassFactoryImpl,iface);
|
||||
|
||||
ULONG ref = --This->ref;
|
||||
|
||||
if (ref == 0)
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI ITSSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
|
||||
REFIID riid, LPVOID *ppobj) {
|
||||
ICOM_THIS(IClassFactoryImpl,iface);
|
||||
HRESULT hres;
|
||||
LPUNKNOWN punk;
|
||||
|
||||
TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
|
||||
|
||||
hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk);
|
||||
if (FAILED(hres)) {
|
||||
*ppobj = NULL;
|
||||
return hres;
|
||||
}
|
||||
hres = IUnknown_QueryInterface(punk, riid, ppobj);
|
||||
if (FAILED(hres)) {
|
||||
*ppobj = NULL;
|
||||
return hres;
|
||||
}
|
||||
IUnknown_Release(punk);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSSCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
|
||||
ICOM_THIS(IClassFactoryImpl,iface);
|
||||
FIXME("(%p)->(%d),stub!\n",This,dolock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IClassFactoryVtbl ITSSCF_Vtbl =
|
||||
{
|
||||
ITSSCF_QueryInterface,
|
||||
ITSSCF_AddRef,
|
||||
ITSSCF_Release,
|
||||
ITSSCF_CreateInstance,
|
||||
ITSSCF_LockServer
|
||||
};
|
||||
|
||||
|
||||
HRESULT WINAPI ITSS_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
||||
{
|
||||
int i;
|
||||
IClassFactoryImpl *factory;
|
||||
|
||||
TRACE("%s %s %p\n",debugstr_guid(rclsid), debugstr_guid(iid), ppv);
|
||||
|
||||
if ( !IsEqualGUID( &IID_IClassFactory, iid )
|
||||
&& ! IsEqualGUID( &IID_IUnknown, iid) )
|
||||
return E_NOINTERFACE;
|
||||
|
||||
for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
|
||||
{
|
||||
if (IsEqualGUID(object_creation[i].clsid, rclsid))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == sizeof(object_creation)/sizeof(object_creation[0]))
|
||||
{
|
||||
FIXME("%s: no class found.\n", debugstr_guid(rclsid));
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
TRACE("Creating a class factory for %s\n",object_creation[i].szClassName);
|
||||
|
||||
factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));
|
||||
if (factory == NULL) return E_OUTOFMEMORY;
|
||||
|
||||
factory->ITF_IClassFactory.lpVtbl = &ITSSCF_Vtbl;
|
||||
factory->ref = 1;
|
||||
|
||||
factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
|
||||
|
||||
*ppv = &(factory->ITF_IClassFactory);
|
||||
|
||||
TRACE("(%p) <- %p\n", ppv, &(factory->ITF_IClassFactory) );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
IITStorageVtbl *vtbl_IITStorage;
|
||||
DWORD ref;
|
||||
} ITStorageImpl;
|
||||
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_QueryInterface(
|
||||
IITStorage* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IITStorage))
|
||||
{
|
||||
IClassFactory_AddRef(iface);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG WINAPI ITStorageImpl_AddRef(
|
||||
IITStorage* iface)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
TRACE("%p\n", This);
|
||||
return ++(This->ref);
|
||||
}
|
||||
|
||||
ULONG WINAPI ITStorageImpl_Release(
|
||||
IITStorage* iface)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
ULONG ref = --This->ref;
|
||||
|
||||
if (ref == 0)
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_StgCreateDocfile(
|
||||
IITStorage* iface,
|
||||
const WCHAR* pwcsName,
|
||||
DWORD grfMode,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
|
||||
TRACE("%p %s %lu %lu %p\n", This,
|
||||
debugstr_w(pwcsName), grfMode, reserved, ppstgOpen );
|
||||
|
||||
return ITSS_StgOpenStorage( pwcsName, NULL, grfMode,
|
||||
0, reserved, ppstgOpen);
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_StgCreateDocfileOnILockBytes(
|
||||
IITStorage* iface,
|
||||
ILockBytes* plkbyt,
|
||||
DWORD grfMode,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_StgIsStorageFile(
|
||||
IITStorage* iface,
|
||||
const WCHAR* pwcsName)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_StgIsStorageILockBytes(
|
||||
IITStorage* iface,
|
||||
ILockBytes* plkbyt)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_StgOpenStorage(
|
||||
IITStorage* iface,
|
||||
const WCHAR* pwcsName,
|
||||
IStorage* pstgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
|
||||
TRACE("%p %s %p %ld %p\n", This, debugstr_w( pwcsName ),
|
||||
pstgPriority, grfMode, snbExclude );
|
||||
|
||||
return ITSS_StgOpenStorage( pwcsName, pstgPriority, grfMode,
|
||||
snbExclude, reserved, ppstgOpen);
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_StgOpenStorageOnILockBytes(
|
||||
IITStorage* iface,
|
||||
ILockBytes* plkbyt,
|
||||
IStorage* pStgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_StgSetTimes(
|
||||
IITStorage* iface,
|
||||
WCHAR* lpszName,
|
||||
FILETIME* pctime,
|
||||
FILETIME* patime,
|
||||
FILETIME* pmtime)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_SetControlData(
|
||||
IITStorage* iface,
|
||||
PITS_Control_Data pControlData)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_DefaultControlData(
|
||||
IITStorage* iface,
|
||||
PITS_Control_Data* ppControlData)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITStorageImpl_Compact(
|
||||
IITStorage* iface,
|
||||
const WCHAR* pwcsName,
|
||||
ECompactionLev iLev)
|
||||
{
|
||||
ICOM_THIS(ITStorageImpl,iface);
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static IITStorageVtbl ITStorageImpl_Vtbl =
|
||||
{
|
||||
ITStorageImpl_QueryInterface,
|
||||
ITStorageImpl_AddRef,
|
||||
ITStorageImpl_Release,
|
||||
ITStorageImpl_StgCreateDocfile,
|
||||
ITStorageImpl_StgCreateDocfileOnILockBytes,
|
||||
ITStorageImpl_StgIsStorageFile,
|
||||
ITStorageImpl_StgIsStorageILockBytes,
|
||||
ITStorageImpl_StgOpenStorage,
|
||||
ITStorageImpl_StgOpenStorageOnILockBytes,
|
||||
ITStorageImpl_StgSetTimes,
|
||||
ITStorageImpl_SetControlData,
|
||||
ITStorageImpl_DefaultControlData,
|
||||
ITStorageImpl_Compact,
|
||||
};
|
||||
|
||||
static HRESULT ITSS_create(IUnknown *pUnkOuter, LPVOID *ppObj)
|
||||
{
|
||||
ITStorageImpl *its;
|
||||
|
||||
its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITStorageImpl) );
|
||||
its->vtbl_IITStorage = &ITStorageImpl_Vtbl;
|
||||
its->ref = 1;
|
||||
|
||||
TRACE("-> %p\n", its);
|
||||
*ppObj = (LPVOID) its;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
HRESULT WINAPI ITSS_DllRegisterServer(void)
|
||||
{
|
||||
FIXME("\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
BOOL WINAPI ITSS_DllCanUnloadNow(void)
|
||||
{
|
||||
FIXME("\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,315 @@
|
|||
/*** Autogenerated by WIDL 0.1 from itss.idl - Do not edit ***/
|
||||
#include <rpc.h>
|
||||
#include <rpcndr.h>
|
||||
|
||||
#ifndef __WIDL_ITSS_H
|
||||
#define __WIDL_ITSS_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <oaidl.h>
|
||||
typedef struct _ITS_Control_Data {
|
||||
UINT cdwControlData;
|
||||
UINT adwControlData[1];
|
||||
} ITS_Control_Data, *PITS_Control_Data;
|
||||
|
||||
typedef enum ECompactionLev {
|
||||
COMPACT_DATA = 0,
|
||||
COMPACT_DATA_AND_PATH
|
||||
} ECompactionLev;
|
||||
|
||||
#ifndef __IITStorage_FWD_DEFINED__
|
||||
#define __IITStorage_FWD_DEFINED__
|
||||
typedef struct IITStorage IITStorage;
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* IITStorage interface
|
||||
*/
|
||||
#ifndef __IITStorage_INTERFACE_DEFINED__
|
||||
#define __IITStorage_INTERFACE_DEFINED__
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
struct IITStorage : public IUnknown
|
||||
{
|
||||
virtual HRESULT STDMETHODCALLTYPE StgCreateDocfile(
|
||||
const WCHAR* pwcsName,
|
||||
DWORD grfMode,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE StgCreateDocfileOnILockBytes(
|
||||
ILockBytes* plkbyt,
|
||||
DWORD grfMode,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE StgIsStorageFile(
|
||||
const WCHAR* pwcsName) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE StgIsStorageILockBytes(
|
||||
ILockBytes* plkbyt) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE StgOpenStorage(
|
||||
const WCHAR* pwcsName,
|
||||
IStorage* pstgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE StgOpenStorageOnILockBytes(
|
||||
ILockBytes* plkbyt,
|
||||
IStorage* pStgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE StgSetTimes(
|
||||
WCHAR* lpszName,
|
||||
FILETIME* pctime,
|
||||
FILETIME* patime,
|
||||
FILETIME* pmtime) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetControlData(
|
||||
PITS_Control_Data pControlData) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE DefaultControlData(
|
||||
PITS_Control_Data* ppControlData) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Compact(
|
||||
const WCHAR* pwcsName,
|
||||
ECompactionLev iLev) = 0;
|
||||
|
||||
};
|
||||
#else
|
||||
typedef struct IITStorageVtbl IITStorageVtbl;
|
||||
struct IITStorage {
|
||||
const IITStorageVtbl* lpVtbl;
|
||||
};
|
||||
struct IITStorageVtbl {
|
||||
BEGIN_INTERFACE
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *QueryInterface)(
|
||||
IITStorage* This,
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
|
||||
ULONG (STDMETHODCALLTYPE *AddRef)(
|
||||
IITStorage* This);
|
||||
|
||||
ULONG (STDMETHODCALLTYPE *Release)(
|
||||
IITStorage* This);
|
||||
|
||||
/*** IITStorage methods ***/
|
||||
HRESULT (STDMETHODCALLTYPE *StgCreateDocfile)(
|
||||
IITStorage* This,
|
||||
const WCHAR* pwcsName,
|
||||
DWORD grfMode,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *StgCreateDocfileOnILockBytes)(
|
||||
IITStorage* This,
|
||||
ILockBytes* plkbyt,
|
||||
DWORD grfMode,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *StgIsStorageFile)(
|
||||
IITStorage* This,
|
||||
const WCHAR* pwcsName);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *StgIsStorageILockBytes)(
|
||||
IITStorage* This,
|
||||
ILockBytes* plkbyt);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *StgOpenStorage)(
|
||||
IITStorage* This,
|
||||
const WCHAR* pwcsName,
|
||||
IStorage* pstgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *StgOpenStorageOnILockBytes)(
|
||||
IITStorage* This,
|
||||
ILockBytes* plkbyt,
|
||||
IStorage* pStgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *StgSetTimes)(
|
||||
IITStorage* This,
|
||||
WCHAR* lpszName,
|
||||
FILETIME* pctime,
|
||||
FILETIME* patime,
|
||||
FILETIME* pmtime);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *SetControlData)(
|
||||
IITStorage* This,
|
||||
PITS_Control_Data pControlData);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *DefaultControlData)(
|
||||
IITStorage* This,
|
||||
PITS_Control_Data* ppControlData);
|
||||
|
||||
HRESULT (STDMETHODCALLTYPE *Compact)(
|
||||
IITStorage* This,
|
||||
const WCHAR* pwcsName,
|
||||
ECompactionLev iLev);
|
||||
|
||||
END_INTERFACE
|
||||
};
|
||||
|
||||
#ifdef COBJMACROS
|
||||
/*** IUnknown methods ***/
|
||||
#define IITStorage_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IITStorage_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IITStorage_Release(p) (p)->lpVtbl->Release(p)
|
||||
/*** IITStorage methods ***/
|
||||
#define IITStorage_StgCreateDocfile(p,a,b,c,d) (p)->lpVtbl->StgCreateDocfile(p,a,b,c,d)
|
||||
#define IITStorage_StgCreateDocfileOnILockBytes(p,a,b,c,d) (p)->lpVtbl->StgCreateDocfileOnILockBytes(p,a,b,c,d)
|
||||
#define IITStorage_StgIsStorageFile(p,a) (p)->lpVtbl->StgIsStorageFile(p,a)
|
||||
#define IITStorage_StgIsStorageILockBytes(p,a) (p)->lpVtbl->StgIsStorageILockBytes(p,a)
|
||||
#define IITStorage_StgOpenStorage(p,a,b,c,d,e,f) (p)->lpVtbl->StgOpenStorage(p,a,b,c,d,e,f)
|
||||
#define IITStorage_StgOpenStorageOnILockBytes(p,a,b,c,d,e,f) (p)->lpVtbl->StgOpenStorageOnILockBytes(p,a,b,c,d,e,f)
|
||||
#define IITStorage_StgSetTimes(p,a,b,c,d) (p)->lpVtbl->StgSetTimes(p,a,b,c,d)
|
||||
#define IITStorage_SetControlData(p,a) (p)->lpVtbl->SetControlData(p,a)
|
||||
#define IITStorage_DefaultControlData(p,a) (p)->lpVtbl->DefaultControlData(p,a)
|
||||
#define IITStorage_Compact(p,a,b) (p)->lpVtbl->Compact(p,a,b)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define IITStorage_METHODS \
|
||||
/*** IUnknown methods ***/ \
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; \
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE; \
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE; \
|
||||
/*** IITStorage methods ***/ \
|
||||
STDMETHOD_(HRESULT,StgCreateDocfile)(THIS_ const WCHAR* pwcsName, DWORD grfMode, DWORD reserved, IStorage** ppstgOpen) PURE; \
|
||||
STDMETHOD_(HRESULT,StgCreateDocfileOnILockBytes)(THIS_ ILockBytes* plkbyt, DWORD grfMode, DWORD reserved, IStorage** ppstgOpen) PURE; \
|
||||
STDMETHOD_(HRESULT,StgIsStorageFile)(THIS_ const WCHAR* pwcsName) PURE; \
|
||||
STDMETHOD_(HRESULT,StgIsStorageILockBytes)(THIS_ ILockBytes* plkbyt) PURE; \
|
||||
STDMETHOD_(HRESULT,StgOpenStorage)(THIS_ const WCHAR* pwcsName, IStorage* pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage** ppstgOpen) PURE; \
|
||||
STDMETHOD_(HRESULT,StgOpenStorageOnILockBytes)(THIS_ ILockBytes* plkbyt, IStorage* pStgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage** ppstgOpen) PURE; \
|
||||
STDMETHOD_(HRESULT,StgSetTimes)(THIS_ WCHAR* lpszName, FILETIME* pctime, FILETIME* patime, FILETIME* pmtime) PURE; \
|
||||
STDMETHOD_(HRESULT,SetControlData)(THIS_ PITS_Control_Data pControlData) PURE; \
|
||||
STDMETHOD_(HRESULT,DefaultControlData)(THIS_ PITS_Control_Data* ppControlData) PURE; \
|
||||
STDMETHOD_(HRESULT,Compact)(THIS_ const WCHAR* pwcsName, ECompactionLev iLev) PURE;
|
||||
|
||||
HRESULT CALLBACK IITStorage_StgCreateDocfile_Proxy(
|
||||
IITStorage* This,
|
||||
const WCHAR* pwcsName,
|
||||
DWORD grfMode,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen);
|
||||
void __RPC_STUB IITStorage_StgCreateDocfile_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IITStorage_StgCreateDocfileOnILockBytes_Proxy(
|
||||
IITStorage* This,
|
||||
ILockBytes* plkbyt,
|
||||
DWORD grfMode,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen);
|
||||
void __RPC_STUB IITStorage_StgCreateDocfileOnILockBytes_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IITStorage_StgIsStorageFile_Proxy(
|
||||
IITStorage* This,
|
||||
const WCHAR* pwcsName);
|
||||
void __RPC_STUB IITStorage_StgIsStorageFile_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IITStorage_StgIsStorageILockBytes_Proxy(
|
||||
IITStorage* This,
|
||||
ILockBytes* plkbyt);
|
||||
void __RPC_STUB IITStorage_StgIsStorageILockBytes_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IITStorage_StgOpenStorage_Proxy(
|
||||
IITStorage* This,
|
||||
const WCHAR* pwcsName,
|
||||
IStorage* pstgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen);
|
||||
void __RPC_STUB IITStorage_StgOpenStorage_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IITStorage_StgOpenStorageOnILockBytes_Proxy(
|
||||
IITStorage* This,
|
||||
ILockBytes* plkbyt,
|
||||
IStorage* pStgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen);
|
||||
void __RPC_STUB IITStorage_StgOpenStorageOnILockBytes_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IITStorage_StgSetTimes_Proxy(
|
||||
IITStorage* This,
|
||||
WCHAR* lpszName,
|
||||
FILETIME* pctime,
|
||||
FILETIME* patime,
|
||||
FILETIME* pmtime);
|
||||
void __RPC_STUB IITStorage_StgSetTimes_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IITStorage_SetControlData_Proxy(
|
||||
IITStorage* This,
|
||||
PITS_Control_Data pControlData);
|
||||
void __RPC_STUB IITStorage_SetControlData_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IITStorage_DefaultControlData_Proxy(
|
||||
IITStorage* This,
|
||||
PITS_Control_Data* ppControlData);
|
||||
void __RPC_STUB IITStorage_DefaultControlData_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
HRESULT CALLBACK IITStorage_Compact_Proxy(
|
||||
IITStorage* This,
|
||||
const WCHAR* pwcsName,
|
||||
ECompactionLev iLev);
|
||||
void __RPC_STUB IITStorage_Compact_Stub(
|
||||
struct IRpcStubBuffer* This,
|
||||
struct IRpcChannelBuffer* pRpcChannelBuffer,
|
||||
PRPC_MESSAGE pRpcMessage,
|
||||
DWORD* pdwStubPhase);
|
||||
|
||||
#endif /* __IITStorage_INTERFACE_DEFINED__ */
|
||||
|
||||
DEFINE_GUID(CLSID_ITStorage,0x5d02926a,0x212e,0x11d0,0x9d,0xf9,0x00,0xa0,0xc9,0x22,0xe6,0xec );
|
||||
DEFINE_GUID(IID_IITStorage, 0x88cc31de, 0x27ab, 0x11d0, 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __WIDL_ITSS_H */
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Mike McCormack
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
import "oaidl.idl";
|
||||
|
||||
typedef struct _ITS_Control_Data
|
||||
{
|
||||
UINT cdwControlData;
|
||||
UINT adwControlData[1];
|
||||
|
||||
} ITS_Control_Data, *PITS_Control_Data;
|
||||
|
||||
typedef enum ECompactionLev {
|
||||
COMPACT_DATA = 0,
|
||||
COMPACT_DATA_AND_PATH
|
||||
} ECompactionLev;
|
||||
|
||||
[
|
||||
object,
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface IITStorage : IUnknown
|
||||
{
|
||||
HRESULT StgCreateDocfile(
|
||||
[in] const WCHAR * pwcsName,
|
||||
[in] DWORD grfMode,
|
||||
[in] DWORD reserved,
|
||||
[out] IStorage ** ppstgOpen);
|
||||
|
||||
HRESULT StgCreateDocfileOnILockBytes(
|
||||
[in] ILockBytes * plkbyt,
|
||||
[in] DWORD grfMode,
|
||||
[in] DWORD reserved,
|
||||
[out] IStorage ** ppstgOpen);
|
||||
|
||||
|
||||
HRESULT StgIsStorageFile(
|
||||
[in] const WCHAR * pwcsName);
|
||||
|
||||
HRESULT StgIsStorageILockBytes(
|
||||
[in] ILockBytes * plkbyt);
|
||||
|
||||
HRESULT StgOpenStorage(
|
||||
[in] const WCHAR * pwcsName,
|
||||
[in] IStorage * pstgPriority,
|
||||
[in] DWORD grfMode,
|
||||
[in] SNB snbExclude,
|
||||
[in] DWORD reserved,
|
||||
[out] IStorage ** ppstgOpen);
|
||||
|
||||
HRESULT StgOpenStorageOnILockBytes(
|
||||
[in] ILockBytes * plkbyt,
|
||||
[in] IStorage * pStgPriority,
|
||||
[in] DWORD grfMode,
|
||||
[in] SNB snbExclude,
|
||||
[in] DWORD reserved,
|
||||
[out] IStorage ** ppstgOpen);
|
||||
|
||||
HRESULT StgSetTimes(
|
||||
[in] WCHAR const * lpszName,
|
||||
[in] FILETIME const * pctime,
|
||||
[in] FILETIME const * patime,
|
||||
[in] FILETIME const * pmtime);
|
||||
|
||||
HRESULT SetControlData(
|
||||
[in] PITS_Control_Data pControlData);
|
||||
|
||||
HRESULT DefaultControlData(
|
||||
[out] PITS_Control_Data * ppControlData);
|
||||
|
||||
HRESULT Compact(
|
||||
[in] const WCHAR * pwcsName,
|
||||
[in] ECompactionLev iLev);
|
||||
}
|
||||
|
||||
cpp_quote("DEFINE_GUID(CLSID_ITStorage,0x5d02926a,0x212e,0x11d0,0x9d,0xf9,0x00,0xa0,0xc9,0x22,0xe6,0xec );");
|
||||
cpp_quote("DEFINE_GUID(IID_IITStorage, 0x88cc31de, 0x27ab, 0x11d0, 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);");
|
|
@ -0,0 +1,5 @@
|
|||
@ stdcall -private DllCanUnloadNow() ITSS_DllCanUnloadNow
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr) ITSS_DllGetClassObject
|
||||
@ stub DllInstall
|
||||
@ stdcall -private DllRegisterServer() ITSS_DllRegisterServer
|
||||
@ stub DllUnregisterServer
|
|
@ -0,0 +1,825 @@
|
|||
/* $Id$ */
|
||||
/***************************************************************************
|
||||
* lzx.c - LZX decompression routines *
|
||||
* ------------------- *
|
||||
* *
|
||||
* maintainer: Jed Wing <jedwin@ugcs.caltech.edu> *
|
||||
* source: modified lzx.c from cabextract v0.5 *
|
||||
* notes: This file was taken from cabextract v0.5, which was, *
|
||||
* itself, a modified version of the lzx decompression code *
|
||||
* from unlzx. *
|
||||
* *
|
||||
* platforms: In its current incarnation, this file has been tested on *
|
||||
* two different Linux platforms (one, redhat-based, with a *
|
||||
* 2.1.2 glibc and gcc 2.95.x, and the other, Debian, with *
|
||||
* 2.2.4 glibc and both gcc 2.95.4 and gcc 3.0.2). Both were *
|
||||
* Intel x86 compatible machines. *
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* Copyright(C) Stuart Caie *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation; either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "lzx.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* sized types */
|
||||
typedef unsigned char UBYTE; /* 8 bits exactly */
|
||||
typedef unsigned short UWORD; /* 16 bits (or more) */
|
||||
typedef unsigned int ULONG; /* 32 bits (or more) */
|
||||
typedef signed int LONG; /* 32 bits (or more) */
|
||||
|
||||
/* some constants defined by the LZX specification */
|
||||
#define LZX_MIN_MATCH (2)
|
||||
#define LZX_MAX_MATCH (257)
|
||||
#define LZX_NUM_CHARS (256)
|
||||
#define LZX_BLOCKTYPE_INVALID (0) /* also blocktypes 4-7 invalid */
|
||||
#define LZX_BLOCKTYPE_VERBATIM (1)
|
||||
#define LZX_BLOCKTYPE_ALIGNED (2)
|
||||
#define LZX_BLOCKTYPE_UNCOMPRESSED (3)
|
||||
#define LZX_PRETREE_NUM_ELEMENTS (20)
|
||||
#define LZX_ALIGNED_NUM_ELEMENTS (8) /* aligned offset tree #elements */
|
||||
#define LZX_NUM_PRIMARY_LENGTHS (7) /* this one missing from spec! */
|
||||
#define LZX_NUM_SECONDARY_LENGTHS (249) /* length tree #elements */
|
||||
|
||||
/* LZX huffman defines: tweak tablebits as desired */
|
||||
#define LZX_PRETREE_MAXSYMBOLS (LZX_PRETREE_NUM_ELEMENTS)
|
||||
#define LZX_PRETREE_TABLEBITS (6)
|
||||
#define LZX_MAINTREE_MAXSYMBOLS (LZX_NUM_CHARS + 50*8)
|
||||
#define LZX_MAINTREE_TABLEBITS (12)
|
||||
#define LZX_LENGTH_MAXSYMBOLS (LZX_NUM_SECONDARY_LENGTHS+1)
|
||||
#define LZX_LENGTH_TABLEBITS (12)
|
||||
#define LZX_ALIGNED_MAXSYMBOLS (LZX_ALIGNED_NUM_ELEMENTS)
|
||||
#define LZX_ALIGNED_TABLEBITS (7)
|
||||
|
||||
#define LZX_LENTABLE_SAFETY (64) /* we allow length table decoding overruns */
|
||||
|
||||
#define LZX_DECLARE_TABLE(tbl) \
|
||||
UWORD tbl##_table[(1<<LZX_##tbl##_TABLEBITS) + (LZX_##tbl##_MAXSYMBOLS<<1)];\
|
||||
UBYTE tbl##_len [LZX_##tbl##_MAXSYMBOLS + LZX_LENTABLE_SAFETY]
|
||||
|
||||
struct LZXstate
|
||||
{
|
||||
UBYTE *window; /* the actual decoding window */
|
||||
ULONG window_size; /* window size (32Kb through 2Mb) */
|
||||
ULONG actual_size; /* window size when it was first allocated */
|
||||
ULONG window_posn; /* current offset within the window */
|
||||
ULONG R0, R1, R2; /* for the LRU offset system */
|
||||
UWORD main_elements; /* number of main tree elements */
|
||||
int header_read; /* have we started decoding at all yet? */
|
||||
UWORD block_type; /* type of this block */
|
||||
ULONG block_length; /* uncompressed length of this block */
|
||||
ULONG block_remaining; /* uncompressed bytes still left to decode */
|
||||
ULONG frames_read; /* the number of CFDATA blocks processed */
|
||||
LONG intel_filesize; /* magic header value used for transform */
|
||||
LONG intel_curpos; /* current offset in transform space */
|
||||
int intel_started; /* have we seen any translatable data yet? */
|
||||
|
||||
LZX_DECLARE_TABLE(PRETREE);
|
||||
LZX_DECLARE_TABLE(MAINTREE);
|
||||
LZX_DECLARE_TABLE(LENGTH);
|
||||
LZX_DECLARE_TABLE(ALIGNED);
|
||||
};
|
||||
|
||||
/* LZX decruncher */
|
||||
|
||||
/* Microsoft's LZX document and their implementation of the
|
||||
* com.ms.util.cab Java package do not concur.
|
||||
*
|
||||
* In the LZX document, there is a table showing the correlation between
|
||||
* window size and the number of position slots. It states that the 1MB
|
||||
* window = 40 slots and the 2MB window = 42 slots. In the implementation,
|
||||
* 1MB = 42 slots, 2MB = 50 slots. The actual calculation is 'find the
|
||||
* first slot whose position base is equal to or more than the required
|
||||
* window size'. This would explain why other tables in the document refer
|
||||
* to 50 slots rather than 42.
|
||||
*
|
||||
* The constant NUM_PRIMARY_LENGTHS used in the decompression pseudocode
|
||||
* is not defined in the specification.
|
||||
*
|
||||
* The LZX document does not state the uncompressed block has an
|
||||
* uncompressed length field. Where does this length field come from, so
|
||||
* we can know how large the block is? The implementation has it as the 24
|
||||
* bits following after the 3 blocktype bits, before the alignment
|
||||
* padding.
|
||||
*
|
||||
* The LZX document states that aligned offset blocks have their aligned
|
||||
* offset huffman tree AFTER the main and length trees. The implementation
|
||||
* suggests that the aligned offset tree is BEFORE the main and length
|
||||
* trees.
|
||||
*
|
||||
* The LZX document decoding algorithm states that, in an aligned offset
|
||||
* block, if an extra_bits value is 1, 2 or 3, then that number of bits
|
||||
* should be read and the result added to the match offset. This is
|
||||
* correct for 1 and 2, but not 3, where just a huffman symbol (using the
|
||||
* aligned tree) should be read.
|
||||
*
|
||||
* Regarding the E8 preprocessing, the LZX document states 'No translation
|
||||
* may be performed on the last 6 bytes of the input block'. This is
|
||||
* correct. However, the pseudocode provided checks for the *E8 leader*
|
||||
* up to the last 6 bytes. If the leader appears between -10 and -7 bytes
|
||||
* from the end, this would cause the next four bytes to be modified, at
|
||||
* least one of which would be in the last 6 bytes, which is not allowed
|
||||
* according to the spec.
|
||||
*
|
||||
* The specification states that the huffman trees must always contain at
|
||||
* least one element. However, many CAB files contain blocks where the
|
||||
* length tree is completely empty (because there are no matches), and
|
||||
* this is expected to succeed.
|
||||
*/
|
||||
|
||||
|
||||
/* LZX uses what it calls 'position slots' to represent match offsets.
|
||||
* What this means is that a small 'position slot' number and a small
|
||||
* offset from that slot are encoded instead of one large offset for
|
||||
* every match.
|
||||
* - position_base is an index to the position slot bases
|
||||
* - extra_bits states how many bits of offset-from-base data is needed.
|
||||
*/
|
||||
static const UBYTE extra_bits[51] = {
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
|
||||
15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17
|
||||
};
|
||||
|
||||
static const ULONG position_base[51] = {
|
||||
0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
|
||||
256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
|
||||
65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360, 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
|
||||
1835008, 1966080, 2097152
|
||||
};
|
||||
|
||||
struct LZXstate *LZXinit(int window)
|
||||
{
|
||||
struct LZXstate *pState=NULL;
|
||||
ULONG wndsize = 1 << window;
|
||||
int i, posn_slots;
|
||||
|
||||
/* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
|
||||
/* if a previously allocated window is big enough, keep it */
|
||||
if (window < 15 || window > 21) return NULL;
|
||||
|
||||
/* allocate state and associated window */
|
||||
pState = (struct LZXstate *)malloc(sizeof(struct LZXstate));
|
||||
if (!(pState->window = (UBYTE *)malloc(wndsize)))
|
||||
{
|
||||
free(pState);
|
||||
return NULL;
|
||||
}
|
||||
pState->actual_size = wndsize;
|
||||
pState->window_size = wndsize;
|
||||
|
||||
/* calculate required position slots */
|
||||
if (window == 20) posn_slots = 42;
|
||||
else if (window == 21) posn_slots = 50;
|
||||
else posn_slots = window << 1;
|
||||
|
||||
/** alternatively **/
|
||||
/* posn_slots=i=0; while (i < wndsize) i += 1 << extra_bits[posn_slots++]; */
|
||||
|
||||
/* initialize other state */
|
||||
pState->R0 = pState->R1 = pState->R2 = 1;
|
||||
pState->main_elements = LZX_NUM_CHARS + (posn_slots << 3);
|
||||
pState->header_read = 0;
|
||||
pState->frames_read = 0;
|
||||
pState->block_remaining = 0;
|
||||
pState->block_type = LZX_BLOCKTYPE_INVALID;
|
||||
pState->intel_curpos = 0;
|
||||
pState->intel_started = 0;
|
||||
pState->window_posn = 0;
|
||||
|
||||
/* initialise tables to 0 (because deltas will be applied to them) */
|
||||
for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++) pState->MAINTREE_len[i] = 0;
|
||||
for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++) pState->LENGTH_len[i] = 0;
|
||||
|
||||
return pState;
|
||||
}
|
||||
|
||||
void LZXteardown(struct LZXstate *pState)
|
||||
{
|
||||
if (pState)
|
||||
{
|
||||
if (pState->window)
|
||||
free(pState->window);
|
||||
free(pState);
|
||||
}
|
||||
}
|
||||
|
||||
int LZXreset(struct LZXstate *pState)
|
||||
{
|
||||
int i;
|
||||
|
||||
pState->R0 = pState->R1 = pState->R2 = 1;
|
||||
pState->header_read = 0;
|
||||
pState->frames_read = 0;
|
||||
pState->block_remaining = 0;
|
||||
pState->block_type = LZX_BLOCKTYPE_INVALID;
|
||||
pState->intel_curpos = 0;
|
||||
pState->intel_started = 0;
|
||||
pState->window_posn = 0;
|
||||
|
||||
for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY; i++) pState->MAINTREE_len[i] = 0;
|
||||
for (i = 0; i < LZX_LENGTH_MAXSYMBOLS + LZX_LENTABLE_SAFETY; i++) pState->LENGTH_len[i] = 0;
|
||||
|
||||
return DECR_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Bitstream reading macros:
|
||||
*
|
||||
* INIT_BITSTREAM should be used first to set up the system
|
||||
* READ_BITS(var,n) takes N bits from the buffer and puts them in var
|
||||
*
|
||||
* ENSURE_BITS(n) ensures there are at least N bits in the bit buffer
|
||||
* PEEK_BITS(n) extracts (without removing) N bits from the bit buffer
|
||||
* REMOVE_BITS(n) removes N bits from the bit buffer
|
||||
*
|
||||
* These bit access routines work by using the area beyond the MSB and the
|
||||
* LSB as a free source of zeroes. This avoids having to mask any bits.
|
||||
* So we have to know the bit width of the bitbuffer variable. This is
|
||||
* sizeof(ULONG) * 8, also defined as ULONG_BITS
|
||||
*/
|
||||
|
||||
/* number of bits in ULONG. Note: This must be at multiple of 16, and at
|
||||
* least 32 for the bitbuffer code to work (ie, it must be able to ensure
|
||||
* up to 17 bits - that's adding 16 bits when there's one bit left, or
|
||||
* adding 32 bits when there are no bits left. The code should work fine
|
||||
* for machines where ULONG >= 32 bits.
|
||||
*/
|
||||
#define ULONG_BITS (sizeof(ULONG)<<3)
|
||||
|
||||
#define INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0)
|
||||
|
||||
#define ENSURE_BITS(n) \
|
||||
while (bitsleft < (n)) { \
|
||||
bitbuf |= ((inpos[1]<<8)|inpos[0]) << (ULONG_BITS-16 - bitsleft); \
|
||||
bitsleft += 16; inpos+=2; \
|
||||
}
|
||||
|
||||
#define PEEK_BITS(n) (bitbuf >> (ULONG_BITS - (n)))
|
||||
#define REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n)))
|
||||
|
||||
#define READ_BITS(v,n) do { \
|
||||
ENSURE_BITS(n); \
|
||||
(v) = PEEK_BITS(n); \
|
||||
REMOVE_BITS(n); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Huffman macros */
|
||||
|
||||
#define TABLEBITS(tbl) (LZX_##tbl##_TABLEBITS)
|
||||
#define MAXSYMBOLS(tbl) (LZX_##tbl##_MAXSYMBOLS)
|
||||
#define SYMTABLE(tbl) (pState->tbl##_table)
|
||||
#define LENTABLE(tbl) (pState->tbl##_len)
|
||||
|
||||
/* BUILD_TABLE(tablename) builds a huffman lookup table from code lengths.
|
||||
* In reality, it just calls make_decode_table() with the appropriate
|
||||
* values - they're all fixed by some #defines anyway, so there's no point
|
||||
* writing each call out in full by hand.
|
||||
*/
|
||||
#define BUILD_TABLE(tbl) \
|
||||
if (make_decode_table( \
|
||||
MAXSYMBOLS(tbl), TABLEBITS(tbl), LENTABLE(tbl), SYMTABLE(tbl) \
|
||||
)) { return DECR_ILLEGALDATA; }
|
||||
|
||||
|
||||
/* READ_HUFFSYM(tablename, var) decodes one huffman symbol from the
|
||||
* bitstream using the stated table and puts it in var.
|
||||
*/
|
||||
#define READ_HUFFSYM(tbl,var) do { \
|
||||
ENSURE_BITS(16); \
|
||||
hufftbl = SYMTABLE(tbl); \
|
||||
if ((i = hufftbl[PEEK_BITS(TABLEBITS(tbl))]) >= MAXSYMBOLS(tbl)) { \
|
||||
j = 1 << (ULONG_BITS - TABLEBITS(tbl)); \
|
||||
do { \
|
||||
j >>= 1; i <<= 1; i |= (bitbuf & j) ? 1 : 0; \
|
||||
if (!j) { return DECR_ILLEGALDATA; } \
|
||||
} while ((i = hufftbl[i]) >= MAXSYMBOLS(tbl)); \
|
||||
} \
|
||||
j = LENTABLE(tbl)[(var) = i]; \
|
||||
REMOVE_BITS(j); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols
|
||||
* first to last in the given table. The code lengths are stored in their
|
||||
* own special LZX way.
|
||||
*/
|
||||
#define READ_LENGTHS(tbl,first,last) do { \
|
||||
lb.bb = bitbuf; lb.bl = bitsleft; lb.ip = inpos; \
|
||||
if (lzx_read_lens(pState, LENTABLE(tbl),(first),(last),&lb)) { \
|
||||
return DECR_ILLEGALDATA; \
|
||||
} \
|
||||
bitbuf = lb.bb; bitsleft = lb.bl; inpos = lb.ip; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* make_decode_table(nsyms, nbits, length[], table[])
|
||||
*
|
||||
* This function was coded by David Tritscher. It builds a fast huffman
|
||||
* decoding table out of just a canonical huffman code lengths table.
|
||||
*
|
||||
* nsyms = total number of symbols in this huffman tree.
|
||||
* nbits = any symbols with a code length of nbits or less can be decoded
|
||||
* in one lookup of the table.
|
||||
* length = A table to get code lengths from [0 to syms-1]
|
||||
* table = The table to fill up with decoded symbols and pointers.
|
||||
*
|
||||
* Returns 0 for OK or 1 for error
|
||||
*/
|
||||
|
||||
static int make_decode_table(ULONG nsyms, ULONG nbits, UBYTE *length, UWORD *table) {
|
||||
register UWORD sym;
|
||||
register ULONG leaf;
|
||||
register UBYTE bit_num = 1;
|
||||
ULONG fill;
|
||||
ULONG pos = 0; /* the current position in the decode table */
|
||||
ULONG table_mask = 1 << nbits;
|
||||
ULONG bit_mask = table_mask >> 1; /* don't do 0 length codes */
|
||||
ULONG next_symbol = bit_mask; /* base of allocation for long codes */
|
||||
|
||||
/* fill entries for codes short enough for a direct mapping */
|
||||
while (bit_num <= nbits) {
|
||||
for (sym = 0; sym < nsyms; sym++) {
|
||||
if (length[sym] == bit_num) {
|
||||
leaf = pos;
|
||||
|
||||
if((pos += bit_mask) > table_mask) return 1; /* table overrun */
|
||||
|
||||
/* fill all possible lookups of this symbol with the symbol itself */
|
||||
fill = bit_mask;
|
||||
while (fill-- > 0) table[leaf++] = sym;
|
||||
}
|
||||
}
|
||||
bit_mask >>= 1;
|
||||
bit_num++;
|
||||
}
|
||||
|
||||
/* if there are any codes longer than nbits */
|
||||
if (pos != table_mask) {
|
||||
/* clear the remainder of the table */
|
||||
for (sym = pos; sym < table_mask; sym++) table[sym] = 0;
|
||||
|
||||
/* give ourselves room for codes to grow by up to 16 more bits */
|
||||
pos <<= 16;
|
||||
table_mask <<= 16;
|
||||
bit_mask = 1 << 15;
|
||||
|
||||
while (bit_num <= 16) {
|
||||
for (sym = 0; sym < nsyms; sym++) {
|
||||
if (length[sym] == bit_num) {
|
||||
leaf = pos >> 16;
|
||||
for (fill = 0; fill < bit_num - nbits; fill++) {
|
||||
/* if this path hasn't been taken yet, 'allocate' two entries */
|
||||
if (table[leaf] == 0) {
|
||||
table[(next_symbol << 1)] = 0;
|
||||
table[(next_symbol << 1) + 1] = 0;
|
||||
table[leaf] = next_symbol++;
|
||||
}
|
||||
/* follow the path and select either left or right for next bit */
|
||||
leaf = table[leaf] << 1;
|
||||
if ((pos >> (15-fill)) & 1) leaf++;
|
||||
}
|
||||
table[leaf] = sym;
|
||||
|
||||
if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
|
||||
}
|
||||
}
|
||||
bit_mask >>= 1;
|
||||
bit_num++;
|
||||
}
|
||||
}
|
||||
|
||||
/* full table? */
|
||||
if (pos == table_mask) return 0;
|
||||
|
||||
/* either erroneous table, or all elements are 0 - let's find out. */
|
||||
for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lzx_bits {
|
||||
ULONG bb;
|
||||
int bl;
|
||||
UBYTE *ip;
|
||||
};
|
||||
|
||||
static int lzx_read_lens(struct LZXstate *pState, UBYTE *lens, ULONG first, ULONG last, struct lzx_bits *lb) {
|
||||
ULONG i,j, x,y;
|
||||
int z;
|
||||
|
||||
register ULONG bitbuf = lb->bb;
|
||||
register int bitsleft = lb->bl;
|
||||
UBYTE *inpos = lb->ip;
|
||||
UWORD *hufftbl;
|
||||
|
||||
for (x = 0; x < 20; x++) {
|
||||
READ_BITS(y, 4);
|
||||
LENTABLE(PRETREE)[x] = y;
|
||||
}
|
||||
BUILD_TABLE(PRETREE);
|
||||
|
||||
for (x = first; x < last; ) {
|
||||
READ_HUFFSYM(PRETREE, z);
|
||||
if (z == 17) {
|
||||
READ_BITS(y, 4); y += 4;
|
||||
while (y--) lens[x++] = 0;
|
||||
}
|
||||
else if (z == 18) {
|
||||
READ_BITS(y, 5); y += 20;
|
||||
while (y--) lens[x++] = 0;
|
||||
}
|
||||
else if (z == 19) {
|
||||
READ_BITS(y, 1); y += 4;
|
||||
READ_HUFFSYM(PRETREE, z);
|
||||
z = lens[x] - z; if (z < 0) z += 17;
|
||||
while (y--) lens[x++] = z;
|
||||
}
|
||||
else {
|
||||
z = lens[x] - z; if (z < 0) z += 17;
|
||||
lens[x++] = z;
|
||||
}
|
||||
}
|
||||
|
||||
lb->bb = bitbuf;
|
||||
lb->bl = bitsleft;
|
||||
lb->ip = inpos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LZXdecompress(struct LZXstate *pState, unsigned char *inpos, unsigned char *outpos, int inlen, int outlen) {
|
||||
UBYTE *endinp = inpos + inlen;
|
||||
UBYTE *window = pState->window;
|
||||
UBYTE *runsrc, *rundest;
|
||||
UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
|
||||
|
||||
ULONG window_posn = pState->window_posn;
|
||||
ULONG window_size = pState->window_size;
|
||||
ULONG R0 = pState->R0;
|
||||
ULONG R1 = pState->R1;
|
||||
ULONG R2 = pState->R2;
|
||||
|
||||
register ULONG bitbuf;
|
||||
register int bitsleft;
|
||||
ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
|
||||
struct lzx_bits lb; /* used in READ_LENGTHS macro */
|
||||
|
||||
int togo = outlen, this_run, main_element, aligned_bits;
|
||||
int match_length, length_footer, extra, verbatim_bits;
|
||||
int copy_length;
|
||||
|
||||
INIT_BITSTREAM;
|
||||
|
||||
/* read header if necessary */
|
||||
if (!pState->header_read) {
|
||||
i = j = 0;
|
||||
READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
|
||||
pState->intel_filesize = (i << 16) | j; /* or 0 if not encoded */
|
||||
pState->header_read = 1;
|
||||
}
|
||||
|
||||
/* main decoding loop */
|
||||
while (togo > 0) {
|
||||
/* last block finished, new block expected */
|
||||
if (pState->block_remaining == 0) {
|
||||
if (pState->block_type == LZX_BLOCKTYPE_UNCOMPRESSED) {
|
||||
if (pState->block_length & 1) inpos++; /* realign bitstream to word */
|
||||
INIT_BITSTREAM;
|
||||
}
|
||||
|
||||
READ_BITS(pState->block_type, 3);
|
||||
READ_BITS(i, 16);
|
||||
READ_BITS(j, 8);
|
||||
pState->block_remaining = pState->block_length = (i << 8) | j;
|
||||
|
||||
switch (pState->block_type) {
|
||||
case LZX_BLOCKTYPE_ALIGNED:
|
||||
for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
|
||||
BUILD_TABLE(ALIGNED);
|
||||
/* rest of aligned header is same as verbatim */
|
||||
|
||||
case LZX_BLOCKTYPE_VERBATIM:
|
||||
READ_LENGTHS(MAINTREE, 0, 256);
|
||||
READ_LENGTHS(MAINTREE, 256, pState->main_elements);
|
||||
BUILD_TABLE(MAINTREE);
|
||||
if (LENTABLE(MAINTREE)[0xE8] != 0) pState->intel_started = 1;
|
||||
|
||||
READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS);
|
||||
BUILD_TABLE(LENGTH);
|
||||
break;
|
||||
|
||||
case LZX_BLOCKTYPE_UNCOMPRESSED:
|
||||
pState->intel_started = 1; /* because we can't assume otherwise */
|
||||
ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
|
||||
if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
|
||||
R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
|
||||
R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
|
||||
R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
|
||||
break;
|
||||
|
||||
default:
|
||||
return DECR_ILLEGALDATA;
|
||||
}
|
||||
}
|
||||
|
||||
/* buffer exhaustion check */
|
||||
if (inpos > endinp) {
|
||||
/* it's possible to have a file where the next run is less than
|
||||
* 16 bits in size. In this case, the READ_HUFFSYM() macro used
|
||||
* in building the tables will exhaust the buffer, so we should
|
||||
* allow for this, but not allow those accidentally read bits to
|
||||
* be used (so we check that there are at least 16 bits
|
||||
* remaining - in this boundary case they aren't really part of
|
||||
* the compressed data)
|
||||
*/
|
||||
if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
|
||||
}
|
||||
|
||||
while ((this_run = pState->block_remaining) > 0 && togo > 0) {
|
||||
if (this_run > togo) this_run = togo;
|
||||
togo -= this_run;
|
||||
pState->block_remaining -= this_run;
|
||||
|
||||
/* apply 2^x-1 mask */
|
||||
window_posn &= window_size - 1;
|
||||
/* runs can't straddle the window wraparound */
|
||||
if ((window_posn + this_run) > window_size)
|
||||
return DECR_DATAFORMAT;
|
||||
|
||||
switch (pState->block_type) {
|
||||
|
||||
case LZX_BLOCKTYPE_VERBATIM:
|
||||
while (this_run > 0) {
|
||||
READ_HUFFSYM(MAINTREE, main_element);
|
||||
|
||||
if (main_element < LZX_NUM_CHARS) {
|
||||
/* literal: 0 to LZX_NUM_CHARS-1 */
|
||||
window[window_posn++] = main_element;
|
||||
this_run--;
|
||||
}
|
||||
else {
|
||||
/* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
|
||||
main_element -= LZX_NUM_CHARS;
|
||||
|
||||
match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
|
||||
if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
|
||||
READ_HUFFSYM(LENGTH, length_footer);
|
||||
match_length += length_footer;
|
||||
}
|
||||
match_length += LZX_MIN_MATCH;
|
||||
|
||||
match_offset = main_element >> 3;
|
||||
|
||||
if (match_offset > 2) {
|
||||
/* not repeated offset */
|
||||
if (match_offset != 3) {
|
||||
extra = extra_bits[match_offset];
|
||||
READ_BITS(verbatim_bits, extra);
|
||||
match_offset = position_base[match_offset] - 2 + verbatim_bits;
|
||||
}
|
||||
else {
|
||||
match_offset = 1;
|
||||
}
|
||||
|
||||
/* update repeated offset LRU queue */
|
||||
R2 = R1; R1 = R0; R0 = match_offset;
|
||||
}
|
||||
else if (match_offset == 0) {
|
||||
match_offset = R0;
|
||||
}
|
||||
else if (match_offset == 1) {
|
||||
match_offset = R1;
|
||||
R1 = R0; R0 = match_offset;
|
||||
}
|
||||
else /* match_offset == 2 */ {
|
||||
match_offset = R2;
|
||||
R2 = R0; R0 = match_offset;
|
||||
}
|
||||
|
||||
rundest = window + window_posn;
|
||||
this_run -= match_length;
|
||||
|
||||
/* copy any wrapped around source data */
|
||||
if (window_posn >= match_offset) {
|
||||
/* no wrap */
|
||||
runsrc = rundest - match_offset;
|
||||
} else {
|
||||
runsrc = rundest + (window_size - match_offset);
|
||||
copy_length = match_offset - window_posn;
|
||||
if (copy_length < match_length) {
|
||||
match_length -= copy_length;
|
||||
window_posn += copy_length;
|
||||
while (copy_length-- > 0) *rundest++ = *runsrc++;
|
||||
runsrc = window;
|
||||
}
|
||||
}
|
||||
window_posn += match_length;
|
||||
|
||||
/* copy match data - no worries about destination wraps */
|
||||
while (match_length-- > 0) *rundest++ = *runsrc++;
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LZX_BLOCKTYPE_ALIGNED:
|
||||
while (this_run > 0) {
|
||||
READ_HUFFSYM(MAINTREE, main_element);
|
||||
|
||||
if (main_element < LZX_NUM_CHARS) {
|
||||
/* literal: 0 to LZX_NUM_CHARS-1 */
|
||||
window[window_posn++] = main_element;
|
||||
this_run--;
|
||||
}
|
||||
else {
|
||||
/* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
|
||||
main_element -= LZX_NUM_CHARS;
|
||||
|
||||
match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
|
||||
if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
|
||||
READ_HUFFSYM(LENGTH, length_footer);
|
||||
match_length += length_footer;
|
||||
}
|
||||
match_length += LZX_MIN_MATCH;
|
||||
|
||||
match_offset = main_element >> 3;
|
||||
|
||||
if (match_offset > 2) {
|
||||
/* not repeated offset */
|
||||
extra = extra_bits[match_offset];
|
||||
match_offset = position_base[match_offset] - 2;
|
||||
if (extra > 3) {
|
||||
/* verbatim and aligned bits */
|
||||
extra -= 3;
|
||||
READ_BITS(verbatim_bits, extra);
|
||||
match_offset += (verbatim_bits << 3);
|
||||
READ_HUFFSYM(ALIGNED, aligned_bits);
|
||||
match_offset += aligned_bits;
|
||||
}
|
||||
else if (extra == 3) {
|
||||
/* aligned bits only */
|
||||
READ_HUFFSYM(ALIGNED, aligned_bits);
|
||||
match_offset += aligned_bits;
|
||||
}
|
||||
else if (extra > 0) { /* extra==1, extra==2 */
|
||||
/* verbatim bits only */
|
||||
READ_BITS(verbatim_bits, extra);
|
||||
match_offset += verbatim_bits;
|
||||
}
|
||||
else /* extra == 0 */ {
|
||||
/* ??? */
|
||||
match_offset = 1;
|
||||
}
|
||||
|
||||
/* update repeated offset LRU queue */
|
||||
R2 = R1; R1 = R0; R0 = match_offset;
|
||||
}
|
||||
else if (match_offset == 0) {
|
||||
match_offset = R0;
|
||||
}
|
||||
else if (match_offset == 1) {
|
||||
match_offset = R1;
|
||||
R1 = R0; R0 = match_offset;
|
||||
}
|
||||
else /* match_offset == 2 */ {
|
||||
match_offset = R2;
|
||||
R2 = R0; R0 = match_offset;
|
||||
}
|
||||
|
||||
rundest = window + window_posn;
|
||||
this_run -= match_length;
|
||||
|
||||
/* copy any wrapped around source data */
|
||||
if (window_posn >= match_offset) {
|
||||
/* no wrap */
|
||||
runsrc = rundest - match_offset;
|
||||
} else {
|
||||
runsrc = rundest + (window_size - match_offset);
|
||||
copy_length = match_offset - window_posn;
|
||||
if (copy_length < match_length) {
|
||||
match_length -= copy_length;
|
||||
window_posn += copy_length;
|
||||
while (copy_length-- > 0) *rundest++ = *runsrc++;
|
||||
runsrc = window;
|
||||
}
|
||||
}
|
||||
window_posn += match_length;
|
||||
|
||||
/* copy match data - no worries about destination wraps */
|
||||
while (match_length-- > 0) *rundest++ = *runsrc++;
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LZX_BLOCKTYPE_UNCOMPRESSED:
|
||||
if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
|
||||
memcpy(window + window_posn, inpos, (size_t) this_run);
|
||||
inpos += this_run; window_posn += this_run;
|
||||
break;
|
||||
|
||||
default:
|
||||
return DECR_ILLEGALDATA; /* might as well */
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (togo != 0) return DECR_ILLEGALDATA;
|
||||
memcpy(outpos, window + ((!window_posn) ? window_size : window_posn) - outlen, (size_t) outlen);
|
||||
|
||||
pState->window_posn = window_posn;
|
||||
pState->R0 = R0;
|
||||
pState->R1 = R1;
|
||||
pState->R2 = R2;
|
||||
|
||||
/* intel E8 decoding */
|
||||
if ((pState->frames_read++ < 32768) && pState->intel_filesize != 0) {
|
||||
if (outlen <= 6 || !pState->intel_started) {
|
||||
pState->intel_curpos += outlen;
|
||||
}
|
||||
else {
|
||||
UBYTE *data = outpos;
|
||||
UBYTE *dataend = data + outlen - 10;
|
||||
LONG curpos = pState->intel_curpos;
|
||||
LONG filesize = pState->intel_filesize;
|
||||
LONG abs_off, rel_off;
|
||||
|
||||
pState->intel_curpos = curpos + outlen;
|
||||
|
||||
while (data < dataend) {
|
||||
if (*data++ != 0xE8) { curpos++; continue; }
|
||||
abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
|
||||
if ((abs_off >= -curpos) && (abs_off < filesize)) {
|
||||
rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
|
||||
data[0] = (UBYTE) rel_off;
|
||||
data[1] = (UBYTE) (rel_off >> 8);
|
||||
data[2] = (UBYTE) (rel_off >> 16);
|
||||
data[3] = (UBYTE) (rel_off >> 24);
|
||||
}
|
||||
data += 4;
|
||||
curpos += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DECR_OK;
|
||||
}
|
||||
|
||||
#ifdef LZX_CHM_TESTDRIVER
|
||||
int main(int c, char **v)
|
||||
{
|
||||
FILE *fin, *fout;
|
||||
struct LZXstate state;
|
||||
UBYTE ibuf[16384];
|
||||
UBYTE obuf[32768];
|
||||
int ilen, olen;
|
||||
int status;
|
||||
int i;
|
||||
int count=0;
|
||||
int w = atoi(v[1]);
|
||||
LZXinit(&state, w);
|
||||
fout = fopen(v[2], "wb");
|
||||
for (i=3; i<c; i++)
|
||||
{
|
||||
fin = fopen(v[i], "rb");
|
||||
ilen = fread(ibuf, 1, 16384, fin);
|
||||
status = LZXdecompress(&state, ibuf, obuf, ilen, 32768);
|
||||
switch (status)
|
||||
{
|
||||
case DECR_OK:
|
||||
printf("ok\n");
|
||||
fwrite(obuf, 1, 32768, fout);
|
||||
break;
|
||||
case DECR_DATAFORMAT:
|
||||
printf("bad format\n");
|
||||
break;
|
||||
case DECR_ILLEGALDATA:
|
||||
printf("illegal data\n");
|
||||
break;
|
||||
case DECR_NOMEMORY:
|
||||
printf("no memory\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fclose(fin);
|
||||
if (++count == 2)
|
||||
{
|
||||
count = 0;
|
||||
LZXreset(&state);
|
||||
}
|
||||
}
|
||||
fclose(fout);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
/* $Id$ */
|
||||
/***************************************************************************
|
||||
* lzx.h - LZX decompression routines *
|
||||
* ------------------- *
|
||||
* *
|
||||
* maintainer: Jed Wing <jedwin@ugcs.caltech.edu> *
|
||||
* source: modified lzx.c from cabextract v0.5 *
|
||||
* notes: This file was taken from cabextract v0.5, which was, *
|
||||
* itself, a modified version of the lzx decompression code *
|
||||
* from unlzx. *
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* Copyright(C) Stuart Caie *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation; either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef INCLUDED_LZX_H
|
||||
#define INCLUDED_LZX_H
|
||||
|
||||
/* return codes */
|
||||
#define DECR_OK (0)
|
||||
#define DECR_DATAFORMAT (1)
|
||||
#define DECR_ILLEGALDATA (2)
|
||||
#define DECR_NOMEMORY (3)
|
||||
|
||||
/* opaque state structure */
|
||||
struct LZXstate;
|
||||
|
||||
/* create an lzx state object */
|
||||
struct LZXstate *LZXinit(int window);
|
||||
|
||||
/* destroy an lzx state object */
|
||||
void LZXteardown(struct LZXstate *pState);
|
||||
|
||||
/* reset an lzx stream */
|
||||
int LZXreset(struct LZXstate *pState);
|
||||
|
||||
/* decompress an LZX compressed block */
|
||||
int LZXdecompress(struct LZXstate *pState,
|
||||
unsigned char *inpos,
|
||||
unsigned char *outpos,
|
||||
int inlen,
|
||||
int outlen);
|
||||
|
||||
#endif /* INCLUDED_LZX_H */
|
|
@ -0,0 +1,449 @@
|
|||
/*
|
||||
* ITSS Moniker implementation
|
||||
*
|
||||
* Copyright 2004 Mike McCormack
|
||||
*
|
||||
* Implementation of the infamous mk:@MSITStore moniker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "winreg.h"
|
||||
#include "ole2.h"
|
||||
|
||||
#include "itss.h"
|
||||
#include "uuids.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(itss);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
IMonikerVtbl *vtbl_ITS_IMoniker;
|
||||
DWORD ref;
|
||||
LPWSTR szHtml;
|
||||
WCHAR szFile[1];
|
||||
} ITS_IMonikerImpl;
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_QueryInterface(
|
||||
IMoniker* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
ICOM_THIS(ITS_IMonikerImpl,iface);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IParseDisplayName))
|
||||
{
|
||||
IClassFactory_AddRef(iface);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITS_IMonikerImpl_AddRef(
|
||||
IMoniker* iface)
|
||||
{
|
||||
ICOM_THIS(ITS_IMonikerImpl,iface);
|
||||
TRACE("%p\n", This);
|
||||
return ++(This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITS_IMonikerImpl_Release(
|
||||
IMoniker* iface)
|
||||
{
|
||||
ICOM_THIS(ITS_IMonikerImpl,iface);
|
||||
ULONG ref = --This->ref;
|
||||
|
||||
if (ref == 0)
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/*** IPersist methods ***/
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_GetClassID(
|
||||
IMoniker* iface,
|
||||
CLSID* pClassID)
|
||||
{
|
||||
ICOM_THIS(ITS_IMonikerImpl,iface);
|
||||
|
||||
TRACE("%p %p\n", This, pClassID);
|
||||
memcpy( pClassID, &CLSID_ITStorage, sizeof (CLSID) );
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*** IPersistStream methods ***/
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_IsDirty(
|
||||
IMoniker* iface)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_Load(
|
||||
IMoniker* iface,
|
||||
IStream* pStm)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_Save(
|
||||
IMoniker* iface,
|
||||
IStream* pStm,
|
||||
BOOL fClearDirty)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_GetSizeMax(
|
||||
IMoniker* iface,
|
||||
ULARGE_INTEGER* pcbSize)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/*** IMoniker methods ***/
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_BindToObject(
|
||||
IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
REFIID riidResult,
|
||||
void** ppvResult)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_BindToStorage(
|
||||
IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
REFIID riid,
|
||||
void** ppvObj)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_Reduce(
|
||||
IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
DWORD dwReduceHowFar,
|
||||
IMoniker** ppmkToLeft,
|
||||
IMoniker** ppmkReduced)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_ComposeWith(
|
||||
IMoniker* iface,
|
||||
IMoniker* pmkRight,
|
||||
BOOL fOnlyIfNotGeneric,
|
||||
IMoniker** ppmkComposite)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_Enum(
|
||||
IMoniker* iface,
|
||||
BOOL fForward,
|
||||
IEnumMoniker** ppenumMoniker)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_IsEqual(
|
||||
IMoniker* iface,
|
||||
IMoniker* pmkOtherMoniker)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_Hash(
|
||||
IMoniker* iface,
|
||||
DWORD* pdwHash)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_IsRunning(
|
||||
IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
IMoniker* pmkNewlyRunning)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_GetTimeOfLastChange(
|
||||
IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
FILETIME* pFileTime)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_Inverse(
|
||||
IMoniker* iface,
|
||||
IMoniker** ppmk)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_CommonPrefixWith(
|
||||
IMoniker* iface,
|
||||
IMoniker* pmkOther,
|
||||
IMoniker** ppmkPrefix)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_RelativePathTo(
|
||||
IMoniker* iface,
|
||||
IMoniker* pmkOther,
|
||||
IMoniker** ppmkRelPath)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_GetDisplayName(
|
||||
IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
LPOLESTR* ppszDisplayName)
|
||||
{
|
||||
ICOM_THIS(ITS_IMonikerImpl,iface);
|
||||
static const WCHAR szFormat[] = {
|
||||
'm','s','-','i','t','s',':','%','s',':',':','%','s',0 };
|
||||
DWORD len = sizeof szFormat / sizeof(WCHAR);
|
||||
LPWSTR str;
|
||||
|
||||
TRACE("%p %p %p %p\n", iface, pbc, pmkToLeft, ppszDisplayName);
|
||||
|
||||
len = strlenW( This->szFile ) + strlenW( This->szHtml );
|
||||
str = CoTaskMemAlloc( len*sizeof(WCHAR) );
|
||||
sprintfW( str, szFormat, This->szFile, This->szHtml );
|
||||
|
||||
*ppszDisplayName = str;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_ParseDisplayName(
|
||||
IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
LPOLESTR pszDisplayName,
|
||||
ULONG* pchEaten,
|
||||
IMoniker** ppmkOut)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_IsSystemMoniker(
|
||||
IMoniker* iface,
|
||||
DWORD* pdwMksys)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static IMonikerVtbl ITS_IMonikerImpl_Vtbl =
|
||||
{
|
||||
ITS_IMonikerImpl_QueryInterface,
|
||||
ITS_IMonikerImpl_AddRef,
|
||||
ITS_IMonikerImpl_Release,
|
||||
ITS_IMonikerImpl_GetClassID,
|
||||
ITS_IMonikerImpl_IsDirty,
|
||||
ITS_IMonikerImpl_Load,
|
||||
ITS_IMonikerImpl_Save,
|
||||
ITS_IMonikerImpl_GetSizeMax,
|
||||
ITS_IMonikerImpl_BindToObject,
|
||||
ITS_IMonikerImpl_BindToStorage,
|
||||
ITS_IMonikerImpl_Reduce,
|
||||
ITS_IMonikerImpl_ComposeWith,
|
||||
ITS_IMonikerImpl_Enum,
|
||||
ITS_IMonikerImpl_IsEqual,
|
||||
ITS_IMonikerImpl_Hash,
|
||||
ITS_IMonikerImpl_IsRunning,
|
||||
ITS_IMonikerImpl_GetTimeOfLastChange,
|
||||
ITS_IMonikerImpl_Inverse,
|
||||
ITS_IMonikerImpl_CommonPrefixWith,
|
||||
ITS_IMonikerImpl_RelativePathTo,
|
||||
ITS_IMonikerImpl_GetDisplayName,
|
||||
ITS_IMonikerImpl_ParseDisplayName,
|
||||
ITS_IMonikerImpl_IsSystemMoniker
|
||||
};
|
||||
|
||||
static HRESULT ITS_IMoniker_create( IMoniker **ppObj, LPWSTR name, DWORD n )
|
||||
{
|
||||
ITS_IMonikerImpl *itsmon;
|
||||
DWORD sz;
|
||||
|
||||
/* szFile[1] has space for one character already */
|
||||
sz = sizeof(ITS_IMonikerImpl) + strlenW( name )*sizeof(WCHAR);
|
||||
|
||||
itsmon = HeapAlloc( GetProcessHeap(), 0, sz );
|
||||
itsmon->vtbl_ITS_IMoniker = &ITS_IMonikerImpl_Vtbl;
|
||||
itsmon->ref = 1;
|
||||
strcpyW( itsmon->szFile, name );
|
||||
itsmon->szHtml = &itsmon->szFile[n];
|
||||
|
||||
while( *itsmon->szHtml == ':' )
|
||||
*itsmon->szHtml++ = 0;
|
||||
|
||||
TRACE("-> %p %s %s\n", itsmon,
|
||||
debugstr_w(itsmon->szFile), debugstr_w(itsmon->szHtml) );
|
||||
*ppObj = (IMoniker*) itsmon;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
IParseDisplayNameVtbl *vtbl_ITS_IParseDisplayName;
|
||||
DWORD ref;
|
||||
} ITS_IParseDisplayNameImpl;
|
||||
|
||||
static HRESULT WINAPI ITS_IParseDisplayNameImpl_QueryInterface(
|
||||
IParseDisplayName* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
ICOM_THIS(ITS_IParseDisplayNameImpl,iface);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IParseDisplayName))
|
||||
{
|
||||
IClassFactory_AddRef(iface);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITS_IParseDisplayNameImpl_AddRef(
|
||||
IParseDisplayName* iface)
|
||||
{
|
||||
ICOM_THIS(ITS_IParseDisplayNameImpl,iface);
|
||||
TRACE("%p\n", This);
|
||||
return ++(This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITS_IParseDisplayNameImpl_Release(
|
||||
IParseDisplayName* iface)
|
||||
{
|
||||
ICOM_THIS(ITS_IParseDisplayNameImpl,iface);
|
||||
ULONG ref = --This->ref;
|
||||
|
||||
if (ref == 0)
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITS_IParseDisplayNameImpl_ParseDisplayName(
|
||||
IParseDisplayName *iface,
|
||||
IBindCtx * pbc,
|
||||
LPOLESTR pszDisplayName,
|
||||
ULONG * pchEaten,
|
||||
IMoniker ** ppmkOut)
|
||||
{
|
||||
static const WCHAR szPrefix[] = {
|
||||
'@','M','S','I','T','S','t','o','r','e',':',0 };
|
||||
const DWORD prefix_len = (sizeof szPrefix/sizeof szPrefix[0])-1;
|
||||
DWORD n;
|
||||
|
||||
ICOM_THIS(ITS_IParseDisplayNameImpl,iface);
|
||||
|
||||
TRACE("%p %s %p %p\n", This,
|
||||
debugstr_w( pszDisplayName ), pchEaten, ppmkOut );
|
||||
|
||||
if( strncmpW( pszDisplayName, szPrefix, prefix_len ) )
|
||||
return MK_E_SYNTAX;
|
||||
|
||||
/* search backwards for a double colon */
|
||||
for( n = strlenW( pszDisplayName ) - 3; prefix_len <= n; n-- )
|
||||
if( ( pszDisplayName[n] == ':' ) && ( pszDisplayName[n+1] == ':' ) )
|
||||
break;
|
||||
|
||||
if( n < prefix_len )
|
||||
return MK_E_SYNTAX;
|
||||
|
||||
if( !pszDisplayName[n+2] )
|
||||
return MK_E_SYNTAX;
|
||||
|
||||
*pchEaten = strlenW( pszDisplayName ) - n - 3;
|
||||
|
||||
return ITS_IMoniker_create( ppmkOut,
|
||||
&pszDisplayName[prefix_len], n-prefix_len );
|
||||
}
|
||||
|
||||
static IParseDisplayNameVtbl ITS_IParseDisplayNameImpl_Vtbl =
|
||||
{
|
||||
ITS_IParseDisplayNameImpl_QueryInterface,
|
||||
ITS_IParseDisplayNameImpl_AddRef,
|
||||
ITS_IParseDisplayNameImpl_Release,
|
||||
ITS_IParseDisplayNameImpl_ParseDisplayName
|
||||
};
|
||||
|
||||
HRESULT ITS_IParseDisplayName_create(IUnknown *pUnkOuter, LPVOID *ppObj)
|
||||
{
|
||||
ITS_IParseDisplayNameImpl *its;
|
||||
|
||||
its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITS_IParseDisplayNameImpl) );
|
||||
its->vtbl_ITS_IParseDisplayName = &ITS_IParseDisplayNameImpl_Vtbl;
|
||||
its->ref = 1;
|
||||
|
||||
TRACE("-> %p\n", its);
|
||||
*ppObj = (LPVOID) its;
|
||||
|
||||
return S_OK;
|
||||
}
|
|
@ -0,0 +1,798 @@
|
|||
/*
|
||||
* ITSS Storage implementation
|
||||
*
|
||||
* Copyright 2004 Mike McCormack
|
||||
*
|
||||
* see http://bonedaddy.net/pabs3/hhm/#chmspec
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "winreg.h"
|
||||
#include "ole2.h"
|
||||
|
||||
#include "uuids.h"
|
||||
|
||||
#include "itss.h"
|
||||
#include "chm_lib.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(itss);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
typedef struct _ITSS_IStorageImpl
|
||||
{
|
||||
IStorageVtbl *vtbl_IStorage;
|
||||
DWORD ref;
|
||||
struct chmFile *chmfile;
|
||||
WCHAR dir[1];
|
||||
} ITSS_IStorageImpl;
|
||||
|
||||
struct enum_info
|
||||
{
|
||||
struct enum_info *next, *prev;
|
||||
struct chmUnitInfo ui;
|
||||
};
|
||||
|
||||
typedef struct _IEnumSTATSTG_Impl
|
||||
{
|
||||
IEnumSTATSTGVtbl *vtbl_IEnumSTATSTG;
|
||||
DWORD ref;
|
||||
struct enum_info *first, *last, *current;
|
||||
} IEnumSTATSTG_Impl;
|
||||
|
||||
typedef struct _IStream_Impl
|
||||
{
|
||||
IStreamVtbl *vtbl_IStream;
|
||||
DWORD ref;
|
||||
ITSS_IStorageImpl *stg;
|
||||
ULONGLONG addr;
|
||||
struct chmUnitInfo ui;
|
||||
} IStream_Impl;
|
||||
|
||||
static HRESULT ITSS_create_chm_storage(
|
||||
struct chmFile *chmfile, const WCHAR *dir, IStorage** ppstgOpen );
|
||||
static IStream_Impl* ITSS_create_stream(
|
||||
ITSS_IStorageImpl *stg, struct chmUnitInfo *ui );
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static HRESULT WINAPI ITSS_IEnumSTATSTG_QueryInterface(
|
||||
IEnumSTATSTG* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
ICOM_THIS(IEnumSTATSTG_Impl,iface);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IEnumSTATSTG))
|
||||
{
|
||||
IEnumSTATSTG_AddRef(iface);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSS_IEnumSTATSTG_AddRef(
|
||||
IEnumSTATSTG* iface)
|
||||
{
|
||||
ICOM_THIS(IEnumSTATSTG_Impl,iface);
|
||||
return ++(This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSS_IEnumSTATSTG_Release(
|
||||
IEnumSTATSTG* iface)
|
||||
{
|
||||
ICOM_THIS(IEnumSTATSTG_Impl,iface);
|
||||
|
||||
ULONG ref = --This->ref;
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
while( This->first )
|
||||
{
|
||||
struct enum_info *t = This->first->next;
|
||||
HeapFree( GetProcessHeap(), 0, This->first );
|
||||
This->first = t;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IEnumSTATSTG_Next(
|
||||
IEnumSTATSTG* iface,
|
||||
ULONG celt,
|
||||
STATSTG* rgelt,
|
||||
ULONG* pceltFetched)
|
||||
{
|
||||
ICOM_THIS(IEnumSTATSTG_Impl,iface);
|
||||
DWORD len, n;
|
||||
struct enum_info *cur;
|
||||
|
||||
TRACE("%p %lu %p %p\n", This, celt, rgelt, pceltFetched );
|
||||
|
||||
cur = This->current;
|
||||
n = 0;
|
||||
while( (n<celt) && cur)
|
||||
{
|
||||
WCHAR *str;
|
||||
|
||||
memset( rgelt, 0, sizeof *rgelt );
|
||||
|
||||
/* copy the name */
|
||||
str = cur->ui.path;
|
||||
if( *str == '/' )
|
||||
str++;
|
||||
len = strlenW( str ) + 1;
|
||||
rgelt->pwcsName = CoTaskMemAlloc( len*sizeof(WCHAR) );
|
||||
strcpyW( rgelt->pwcsName, str );
|
||||
|
||||
/* determine the type */
|
||||
if( rgelt->pwcsName[len-2] == '/' )
|
||||
{
|
||||
rgelt->pwcsName[len-2] = 0;
|
||||
rgelt->type = STGTY_STORAGE;
|
||||
}
|
||||
else
|
||||
rgelt->type = STGTY_STREAM;
|
||||
|
||||
/* copy the size */
|
||||
rgelt->cbSize.QuadPart = cur->ui.length;
|
||||
|
||||
/* advance to the next item if it exists */
|
||||
n++;
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
This->current = cur;
|
||||
*pceltFetched = n;
|
||||
|
||||
if( n < celt )
|
||||
return S_FALSE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IEnumSTATSTG_Skip(
|
||||
IEnumSTATSTG* iface,
|
||||
ULONG celt)
|
||||
{
|
||||
ICOM_THIS(IEnumSTATSTG_Impl,iface);
|
||||
DWORD n;
|
||||
struct enum_info *cur;
|
||||
|
||||
TRACE("%p %lu\n", This, celt );
|
||||
|
||||
cur = This->current;
|
||||
n = 0;
|
||||
while( (n<celt) && cur)
|
||||
{
|
||||
n++;
|
||||
cur = cur->next;
|
||||
}
|
||||
This->current = cur;
|
||||
|
||||
if( n < celt )
|
||||
return S_FALSE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IEnumSTATSTG_Reset(
|
||||
IEnumSTATSTG* iface)
|
||||
{
|
||||
ICOM_THIS(IEnumSTATSTG_Impl,iface);
|
||||
|
||||
TRACE("%p\n", This );
|
||||
|
||||
This->current = This->first;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IEnumSTATSTG_Clone(
|
||||
IEnumSTATSTG* iface,
|
||||
IEnumSTATSTG** ppenum)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
struct IEnumSTATSTGVtbl IEnumSTATSTG_vtbl =
|
||||
{
|
||||
ITSS_IEnumSTATSTG_QueryInterface,
|
||||
ITSS_IEnumSTATSTG_AddRef,
|
||||
ITSS_IEnumSTATSTG_Release,
|
||||
ITSS_IEnumSTATSTG_Next,
|
||||
ITSS_IEnumSTATSTG_Skip,
|
||||
ITSS_IEnumSTATSTG_Reset,
|
||||
ITSS_IEnumSTATSTG_Clone
|
||||
};
|
||||
|
||||
static IEnumSTATSTG_Impl *ITSS_create_enum( void )
|
||||
{
|
||||
IEnumSTATSTG_Impl *stgenum;
|
||||
|
||||
stgenum = HeapAlloc( GetProcessHeap(), 0, sizeof (IEnumSTATSTG_Impl) );
|
||||
stgenum->vtbl_IEnumSTATSTG = &IEnumSTATSTG_vtbl;
|
||||
stgenum->ref = 1;
|
||||
stgenum->first = NULL;
|
||||
stgenum->last = NULL;
|
||||
stgenum->current = NULL;
|
||||
|
||||
TRACE(" -> %p\n", stgenum );
|
||||
|
||||
return stgenum;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_QueryInterface(
|
||||
IStorage* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
ICOM_THIS(ITSS_IStorageImpl,iface);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IStorage))
|
||||
{
|
||||
IStorage_AddRef(iface);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG WINAPI ITSS_IStorageImpl_AddRef(
|
||||
IStorage* iface)
|
||||
{
|
||||
ICOM_THIS(ITSS_IStorageImpl,iface);
|
||||
return ++(This->ref);
|
||||
}
|
||||
|
||||
ULONG WINAPI ITSS_IStorageImpl_Release(
|
||||
IStorage* iface)
|
||||
{
|
||||
ICOM_THIS(ITSS_IStorageImpl,iface);
|
||||
|
||||
ULONG ref = --This->ref;
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_CreateStream(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
DWORD grfMode,
|
||||
DWORD reserved1,
|
||||
DWORD reserved2,
|
||||
IStream** ppstm)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_OpenStream(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
void* reserved1,
|
||||
DWORD grfMode,
|
||||
DWORD reserved2,
|
||||
IStream** ppstm)
|
||||
{
|
||||
ICOM_THIS(ITSS_IStorageImpl,iface);
|
||||
IStream_Impl *stm;
|
||||
DWORD len;
|
||||
struct chmUnitInfo ui;
|
||||
int r;
|
||||
WCHAR *path;
|
||||
|
||||
TRACE("%p %s %p %lu %lu %p\n", This, debugstr_w(pwcsName),
|
||||
reserved1, grfMode, reserved2, ppstm );
|
||||
|
||||
len = strlenW( This->dir ) + strlenW( pwcsName ) + 1;
|
||||
path = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
|
||||
strcpyW( path, This->dir );
|
||||
strcatW( path, pwcsName );
|
||||
|
||||
r = chm_resolve_object(This->chmfile, path, &ui);
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
|
||||
if( r != CHM_RESOLVE_SUCCESS )
|
||||
return STG_E_FILENOTFOUND;
|
||||
|
||||
stm = ITSS_create_stream( This, &ui );
|
||||
if( !stm )
|
||||
return E_FAIL;
|
||||
|
||||
*ppstm = (IStream*) stm;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_CreateStorage(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
DWORD grfMode,
|
||||
DWORD dwStgFmt,
|
||||
DWORD reserved2,
|
||||
IStorage** ppstg)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_OpenStorage(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
IStorage* pstgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstg)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_CopyTo(
|
||||
IStorage* iface,
|
||||
DWORD ciidExclude,
|
||||
const IID* rgiidExclude,
|
||||
SNB snbExclude,
|
||||
IStorage* pstgDest)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_MoveElementTo(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
IStorage* pstgDest,
|
||||
LPCOLESTR pwcsNewName,
|
||||
DWORD grfFlags)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_Commit(
|
||||
IStorage* iface,
|
||||
DWORD grfCommitFlags)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_Revert(
|
||||
IStorage* iface)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static int ITSS_chm_enumerator(
|
||||
struct chmFile *h,
|
||||
struct chmUnitInfo *ui,
|
||||
void *context)
|
||||
{
|
||||
struct enum_info *info;
|
||||
IEnumSTATSTG_Impl* stgenum = context;
|
||||
|
||||
TRACE("adding %s to enumeration\n", debugstr_w(ui->path) );
|
||||
|
||||
info = HeapAlloc( GetProcessHeap(), 0, sizeof (struct enum_info) );
|
||||
memcpy( &info->ui, ui, sizeof info->ui );
|
||||
|
||||
info->next = NULL;
|
||||
info->prev = stgenum->last;
|
||||
if( stgenum->last )
|
||||
stgenum->last->next = info;
|
||||
else
|
||||
stgenum->first = info;
|
||||
stgenum->last = info;
|
||||
|
||||
return CHM_ENUMERATOR_CONTINUE;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_EnumElements(
|
||||
IStorage* iface,
|
||||
DWORD reserved1,
|
||||
void* reserved2,
|
||||
DWORD reserved3,
|
||||
IEnumSTATSTG** ppenum)
|
||||
{
|
||||
ICOM_THIS(ITSS_IStorageImpl,iface);
|
||||
IEnumSTATSTG_Impl* stgenum;
|
||||
|
||||
TRACE("%p %ld %p %ld %p\n", This, reserved1, reserved2, reserved3, ppenum );
|
||||
|
||||
stgenum = ITSS_create_enum();
|
||||
if( !stgenum )
|
||||
return E_FAIL;
|
||||
|
||||
chm_enumerate_dir(This->chmfile,
|
||||
This->dir,
|
||||
CHM_ENUMERATE_ALL,
|
||||
ITSS_chm_enumerator,
|
||||
stgenum );
|
||||
|
||||
stgenum->current = stgenum->first;
|
||||
|
||||
*ppenum = (IEnumSTATSTG*) stgenum;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_DestroyElement(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_RenameElement(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsOldName,
|
||||
LPCOLESTR pwcsNewName)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_SetElementTimes(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
const FILETIME* pctime,
|
||||
const FILETIME* patime,
|
||||
const FILETIME* pmtime)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_SetClass(
|
||||
IStorage* iface,
|
||||
REFCLSID clsid)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_SetStateBits(
|
||||
IStorage* iface,
|
||||
DWORD grfStateBits,
|
||||
DWORD grfMask)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI ITSS_IStorageImpl_Stat(
|
||||
IStorage* iface,
|
||||
STATSTG* pstatstg,
|
||||
DWORD grfStatFlag)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static IStorageVtbl ITSS_IStorageImpl_Vtbl =
|
||||
{
|
||||
ITSS_IStorageImpl_QueryInterface,
|
||||
ITSS_IStorageImpl_AddRef,
|
||||
ITSS_IStorageImpl_Release,
|
||||
ITSS_IStorageImpl_CreateStream,
|
||||
ITSS_IStorageImpl_OpenStream,
|
||||
ITSS_IStorageImpl_CreateStorage,
|
||||
ITSS_IStorageImpl_OpenStorage,
|
||||
ITSS_IStorageImpl_CopyTo,
|
||||
ITSS_IStorageImpl_MoveElementTo,
|
||||
ITSS_IStorageImpl_Commit,
|
||||
ITSS_IStorageImpl_Revert,
|
||||
ITSS_IStorageImpl_EnumElements,
|
||||
ITSS_IStorageImpl_DestroyElement,
|
||||
ITSS_IStorageImpl_RenameElement,
|
||||
ITSS_IStorageImpl_SetElementTimes,
|
||||
ITSS_IStorageImpl_SetClass,
|
||||
ITSS_IStorageImpl_SetStateBits,
|
||||
ITSS_IStorageImpl_Stat,
|
||||
};
|
||||
|
||||
static HRESULT ITSS_create_chm_storage(
|
||||
struct chmFile *chmfile, const WCHAR *dir, IStorage** ppstgOpen )
|
||||
{
|
||||
ITSS_IStorageImpl *stg;
|
||||
DWORD len;
|
||||
|
||||
TRACE("%p %s\n", chmfile, debugstr_w( dir ) );
|
||||
|
||||
len = strlenW( dir ) + 1;
|
||||
stg = HeapAlloc( GetProcessHeap(), 0,
|
||||
sizeof (ITSS_IStorageImpl) + len*sizeof(WCHAR) );
|
||||
stg->vtbl_IStorage = &ITSS_IStorageImpl_Vtbl;
|
||||
stg->ref = 1;
|
||||
stg->chmfile = chmfile;
|
||||
strcpyW( stg->dir, dir );
|
||||
|
||||
*ppstgOpen = (IStorage*) stg;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ITSS_StgOpenStorage(
|
||||
const WCHAR* pwcsName,
|
||||
IStorage* pstgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen)
|
||||
{
|
||||
struct chmFile *chmfile;
|
||||
static const WCHAR szRoot[] = { '/', 0 };
|
||||
|
||||
TRACE("%s\n", debugstr_w(pwcsName) );
|
||||
|
||||
chmfile = chm_openW( pwcsName );
|
||||
if( !chmfile )
|
||||
return E_FAIL;
|
||||
|
||||
return ITSS_create_chm_storage( chmfile, szRoot, ppstgOpen );
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_QueryInterface(
|
||||
IStream* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
ICOM_THIS(IStream_Impl,iface);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_ISequentialStream)
|
||||
|| IsEqualGUID(riid, &IID_IStream))
|
||||
{
|
||||
IStream_AddRef(iface);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSS_IStream_AddRef(
|
||||
IStream* iface)
|
||||
{
|
||||
ICOM_THIS(IStream_Impl,iface);
|
||||
return ++(This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSS_IStream_Release(
|
||||
IStream* iface)
|
||||
{
|
||||
ICOM_THIS(IStream_Impl,iface);
|
||||
|
||||
ULONG ref = --This->ref;
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
IStorage_Release( (IStorage*) This->stg );
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_Read(
|
||||
IStream* iface,
|
||||
void* pv,
|
||||
ULONG cb,
|
||||
ULONG* pcbRead)
|
||||
{
|
||||
ICOM_THIS(IStream_Impl,iface);
|
||||
ULONG count;
|
||||
|
||||
TRACE("%p %p %lu %p\n", This, pv, cb, pcbRead);
|
||||
|
||||
count = chm_retrieve_object(This->stg->chmfile,
|
||||
&This->ui, pv, This->addr, cb);
|
||||
This->addr += count;
|
||||
if( pcbRead )
|
||||
*pcbRead = count;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_Write(
|
||||
IStream* iface,
|
||||
const void* pv,
|
||||
ULONG cb,
|
||||
ULONG* pcbWritten)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_Seek(
|
||||
IStream* iface,
|
||||
LARGE_INTEGER dlibMove,
|
||||
DWORD dwOrigin,
|
||||
ULARGE_INTEGER* plibNewPosition)
|
||||
{
|
||||
ICOM_THIS(IStream_Impl,iface);
|
||||
LONGLONG newpos;
|
||||
|
||||
TRACE("%p %s %lu %p\n", This,
|
||||
wine_dbgstr_longlong( dlibMove.QuadPart ), dwOrigin, plibNewPosition );
|
||||
|
||||
newpos = This->addr;
|
||||
switch( dwOrigin )
|
||||
{
|
||||
case STREAM_SEEK_CUR:
|
||||
newpos = This->addr + dlibMove.QuadPart;
|
||||
break;
|
||||
case STREAM_SEEK_SET:
|
||||
newpos = dlibMove.QuadPart;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
newpos = This->ui.length + dlibMove.QuadPart;
|
||||
break;
|
||||
}
|
||||
|
||||
if( ( newpos < 0 ) || ( newpos > This->ui.length ) )
|
||||
return STG_E_INVALIDPOINTER;
|
||||
|
||||
This->addr = newpos;
|
||||
if( plibNewPosition )
|
||||
plibNewPosition->QuadPart = This->addr;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_SetSize(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libNewSize)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_CopyTo(
|
||||
IStream* iface,
|
||||
IStream* pstm,
|
||||
ULARGE_INTEGER cb,
|
||||
ULARGE_INTEGER* pcbRead,
|
||||
ULARGE_INTEGER* pcbWritten)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_Commit(
|
||||
IStream* iface,
|
||||
DWORD grfCommitFlags)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_Revert(
|
||||
IStream* iface)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_LockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset,
|
||||
ULARGE_INTEGER cb,
|
||||
DWORD dwLockType)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_UnlockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset,
|
||||
ULARGE_INTEGER cb,
|
||||
DWORD dwLockType)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_Stat(
|
||||
IStream* iface,
|
||||
STATSTG* pstatstg,
|
||||
DWORD grfStatFlag)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_Clone(
|
||||
IStream* iface,
|
||||
IStream** ppstm)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
struct IStreamVtbl ITSS_IStream_vtbl =
|
||||
{
|
||||
ITSS_IStream_QueryInterface,
|
||||
ITSS_IStream_AddRef,
|
||||
ITSS_IStream_Release,
|
||||
ITSS_IStream_Read,
|
||||
ITSS_IStream_Write,
|
||||
ITSS_IStream_Seek,
|
||||
ITSS_IStream_SetSize,
|
||||
ITSS_IStream_CopyTo,
|
||||
ITSS_IStream_Commit,
|
||||
ITSS_IStream_Revert,
|
||||
ITSS_IStream_LockRegion,
|
||||
ITSS_IStream_UnlockRegion,
|
||||
ITSS_IStream_Stat,
|
||||
ITSS_IStream_Clone,
|
||||
};
|
||||
|
||||
static IStream_Impl *ITSS_create_stream(
|
||||
ITSS_IStorageImpl *stg, struct chmUnitInfo *ui )
|
||||
{
|
||||
IStream_Impl *stm;
|
||||
|
||||
stm = HeapAlloc( GetProcessHeap(), 0, sizeof (IStream_Impl) );
|
||||
stm->vtbl_IStream = &ITSS_IStream_vtbl;
|
||||
stm->ref = 1;
|
||||
stm->addr = 0;
|
||||
memcpy( &stm->ui, ui, sizeof stm->ui );
|
||||
stm->stg = stg;
|
||||
IStorage_AddRef( (IStorage*) stg );
|
||||
|
||||
TRACE(" -> %p\n", stm );
|
||||
|
||||
return stm;
|
||||
}
|
Loading…
Reference in New Issue