mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 08:00:24 +00:00
- Add itss and msimtf from Wine
- Update README.WINE svn path=/trunk/; revision=38995
This commit is contained in:
parent
d4835adc0b
commit
928873cf85
22 changed files with 6234 additions and 0 deletions
|
@ -271,6 +271,7 @@ dll\win32\imm32\imm32.dll 1
|
|||
dll\win32\inetcomm\inetcomm.dll 1
|
||||
dll\win32\inetmib1\inetmib1.dll 1
|
||||
dll\win32\iphlpapi\iphlpapi.dll 1
|
||||
dll\win32\itss\itss.dll 1
|
||||
dll\win32\jscript\jscript.dll 1
|
||||
dll\win32\kernel32\kernel32.dll 1
|
||||
dll\win32\localui\localui.dll 1
|
||||
|
@ -290,6 +291,7 @@ dll\win32\mshtml\mshtml.dll 1
|
|||
dll\win32\mshtml.tlb\mshtml.tlb 1
|
||||
dll\win32\msi\msi.dll 1
|
||||
dll\win32\msimg32\msimg32.dll 1
|
||||
dll\win32\msimtf\msimtf.dll 1
|
||||
dll\win32\mstask\mstask.dll 1
|
||||
dll\win32\msvcrt\msvcrt.dll 1
|
||||
dll\win32\msvcrt20\msvcrt20.dll 1
|
||||
|
|
1651
reactos/dll/win32/itss/chm_lib.c
Normal file
1651
reactos/dll/win32/itss/chm_lib.c
Normal file
File diff suppressed because it is too large
Load diff
136
reactos/dll/win32/itss/chm_lib.h
Normal file
136
reactos/dll/win32/itss/chm_lib.h
Normal file
|
@ -0,0 +1,136 @@
|
|||
/***************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/*
|
||||
* This function is specific to Unix-systems. Do not remove it!
|
||||
*/
|
||||
static inline int
|
||||
ffs(int field)
|
||||
{
|
||||
static const int index[] = { 1, 2, 29, 3, 30, 15, 25, 4, 31, 23, 21,
|
||||
16, 26, 18, 5, 9, 32, 28, 14, 24, 22, 20,
|
||||
17, 8, 27, 13, 19, 7, 12, 6, 11, 10 };
|
||||
unsigned int w = field;
|
||||
if (w == 0)
|
||||
return (0);
|
||||
w &= -w;
|
||||
w *= 125613361U;
|
||||
w >>= 27;
|
||||
return index[w];
|
||||
}
|
||||
|
||||
#endif /* INCLUDED_CHMLIB_H */
|
447
reactos/dll/win32/itss/itss.c
Normal file
447
reactos/dll/win32/itss/itss.c
Normal file
|
@ -0,0 +1,447 @@
|
|||
/*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "ole2.h"
|
||||
#include "advpub.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "itsstor.h"
|
||||
|
||||
#include "initguid.h"
|
||||
#include "wine/itss.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(itss);
|
||||
|
||||
static HRESULT ITSS_create(IUnknown *pUnkOuter, LPVOID *ppObj);
|
||||
|
||||
LONG dll_count = 0;
|
||||
static HINSTANCE hInst;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||
{
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hInstDLL);
|
||||
hInst = hInstDLL;
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ITSS ClassFactory
|
||||
*/
|
||||
typedef struct {
|
||||
const IClassFactoryVtbl *lpVtbl;
|
||||
HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
|
||||
} IClassFactoryImpl;
|
||||
|
||||
static HRESULT WINAPI
|
||||
ITSSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
|
||||
{
|
||||
IClassFactoryImpl *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)
|
||||
{
|
||||
ITSS_LockModule();
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSSCF_Release(LPCLASSFACTORY iface)
|
||||
{
|
||||
ITSS_UnlockModule();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI ITSSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
|
||||
REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
HRESULT hres;
|
||||
LPUNKNOWN punk;
|
||||
|
||||
TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj);
|
||||
|
||||
*ppobj = NULL;
|
||||
hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk);
|
||||
if (SUCCEEDED(hres)) {
|
||||
hres = IUnknown_QueryInterface(punk, riid, ppobj);
|
||||
IUnknown_Release(punk);
|
||||
}
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
|
||||
{
|
||||
TRACE("(%p)->(%d)\n", iface, dolock);
|
||||
|
||||
if (dolock)
|
||||
ITSS_LockModule();
|
||||
else
|
||||
ITSS_UnlockModule();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IClassFactoryVtbl ITSSCF_Vtbl =
|
||||
{
|
||||
ITSSCF_QueryInterface,
|
||||
ITSSCF_AddRef,
|
||||
ITSSCF_Release,
|
||||
ITSSCF_CreateInstance,
|
||||
ITSSCF_LockServer
|
||||
};
|
||||
|
||||
static const IClassFactoryImpl ITStorage_factory = { &ITSSCF_Vtbl, ITSS_create };
|
||||
static const IClassFactoryImpl MSITStore_factory = { &ITSSCF_Vtbl, ITS_IParseDisplayName_create };
|
||||
static const IClassFactoryImpl ITSProtocol_factory = { &ITSSCF_Vtbl, ITSProtocol_create };
|
||||
|
||||
/***********************************************************************
|
||||
* DllGetClassObject (ITSS.@)
|
||||
*/
|
||||
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
||||
{
|
||||
const IClassFactoryImpl *factory;
|
||||
|
||||
TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
|
||||
|
||||
if (IsEqualGUID(&CLSID_ITStorage, rclsid))
|
||||
factory = &ITStorage_factory;
|
||||
else if (IsEqualGUID(&CLSID_MSITStore, rclsid))
|
||||
factory = &MSITStore_factory;
|
||||
else if (IsEqualGUID(&CLSID_ITSProtocol, rclsid))
|
||||
factory = &ITSProtocol_factory;
|
||||
else
|
||||
{
|
||||
FIXME("%s: no class found.\n", debugstr_guid(rclsid));
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
return IUnknown_QueryInterface( (IUnknown*) factory, iid, ppv );
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
const IITStorageVtbl *vtbl_IITStorage;
|
||||
LONG ref;
|
||||
} ITStorageImpl;
|
||||
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_QueryInterface(
|
||||
IITStorage* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
ITStorageImpl *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;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITStorageImpl_AddRef(
|
||||
IITStorage* iface)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
TRACE("%p\n", This);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITStorageImpl_Release(
|
||||
IITStorage* iface)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (ref == 0) {
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
ITSS_UnlockModule();
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_StgCreateDocfile(
|
||||
IITStorage* iface,
|
||||
const WCHAR* pwcsName,
|
||||
DWORD grfMode,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
|
||||
TRACE("%p %s %u %u %p\n", This,
|
||||
debugstr_w(pwcsName), grfMode, reserved, ppstgOpen );
|
||||
|
||||
return ITSS_StgOpenStorage( pwcsName, NULL, grfMode,
|
||||
0, reserved, ppstgOpen);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_StgCreateDocfileOnILockBytes(
|
||||
IITStorage* iface,
|
||||
ILockBytes* plkbyt,
|
||||
DWORD grfMode,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_StgIsStorageFile(
|
||||
IITStorage* iface,
|
||||
const WCHAR* pwcsName)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_StgIsStorageILockBytes(
|
||||
IITStorage* iface,
|
||||
ILockBytes* plkbyt)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_StgOpenStorage(
|
||||
IITStorage* iface,
|
||||
const WCHAR* pwcsName,
|
||||
IStorage* pstgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
|
||||
TRACE("%p %s %p %d %p\n", This, debugstr_w( pwcsName ),
|
||||
pstgPriority, grfMode, snbExclude );
|
||||
|
||||
return ITSS_StgOpenStorage( pwcsName, pstgPriority, grfMode,
|
||||
snbExclude, reserved, ppstgOpen);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_StgOpenStorageOnILockBytes(
|
||||
IITStorage* iface,
|
||||
ILockBytes* plkbyt,
|
||||
IStorage* pStgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_StgSetTimes(
|
||||
IITStorage* iface,
|
||||
const WCHAR* lpszName,
|
||||
const FILETIME* pctime,
|
||||
const FILETIME* patime,
|
||||
const FILETIME* pmtime)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_SetControlData(
|
||||
IITStorage* iface,
|
||||
PITS_Control_Data pControlData)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_DefaultControlData(
|
||||
IITStorage* iface,
|
||||
PITS_Control_Data* ppControlData)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITStorageImpl_Compact(
|
||||
IITStorage* iface,
|
||||
const WCHAR* pwcsName,
|
||||
ECompactionLev iLev)
|
||||
{
|
||||
ITStorageImpl *This = (ITStorageImpl *)iface;
|
||||
FIXME("%p\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const 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;
|
||||
|
||||
if( pUnkOuter )
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
|
||||
its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITStorageImpl) );
|
||||
its->vtbl_IITStorage = &ITStorageImpl_Vtbl;
|
||||
its->ref = 1;
|
||||
|
||||
TRACE("-> %p\n", its);
|
||||
*ppObj = (LPVOID) its;
|
||||
|
||||
ITSS_LockModule();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
HRESULT WINAPI DllCanUnloadNow(void)
|
||||
{
|
||||
TRACE("dll_count = %u\n", dll_count);
|
||||
return dll_count ? S_FALSE : S_OK;
|
||||
}
|
||||
|
||||
#define INF_SET_ID(id) \
|
||||
do \
|
||||
{ \
|
||||
static CHAR name[] = #id; \
|
||||
\
|
||||
pse[i].pszName = name; \
|
||||
clsids[i++] = &id; \
|
||||
} while (0)
|
||||
|
||||
#define INF_SET_CLSID(clsid) INF_SET_ID(CLSID_ ## clsid)
|
||||
|
||||
static HRESULT register_server(BOOL do_register)
|
||||
{
|
||||
HRESULT hres;
|
||||
HMODULE hAdvpack;
|
||||
HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
|
||||
STRTABLEA strtable;
|
||||
STRENTRYA pse[4];
|
||||
static CLSID const *clsids[4];
|
||||
DWORD i = 0;
|
||||
|
||||
static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0};
|
||||
|
||||
INF_SET_CLSID(ITStorage);
|
||||
INF_SET_CLSID(MSFSStore);
|
||||
INF_SET_CLSID(MSITStore);
|
||||
INF_SET_CLSID(ITSProtocol);
|
||||
|
||||
strtable.cEntries = sizeof(pse)/sizeof(pse[0]);
|
||||
strtable.pse = pse;
|
||||
|
||||
for(i=0; i < strtable.cEntries; i++) {
|
||||
pse[i].pszValue = HeapAlloc(GetProcessHeap(), 0, 39);
|
||||
sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
||||
clsids[i]->Data1, clsids[i]->Data2, clsids[i]->Data3, clsids[i]->Data4[0],
|
||||
clsids[i]->Data4[1], clsids[i]->Data4[2], clsids[i]->Data4[3], clsids[i]->Data4[4],
|
||||
clsids[i]->Data4[5], clsids[i]->Data4[6], clsids[i]->Data4[7]);
|
||||
}
|
||||
|
||||
hAdvpack = LoadLibraryW(wszAdvpack);
|
||||
pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
|
||||
|
||||
hres = pRegInstall(hInst, do_register ? "RegisterDll" : "UnregisterDll", &strtable);
|
||||
|
||||
for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++)
|
||||
HeapFree(GetProcessHeap(), 0, pse[i].pszValue);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
#undef INF_SET_CLSID
|
||||
#undef INF_SET_ID
|
||||
|
||||
/***********************************************************************
|
||||
* DllRegisterServer (ITSS.@)
|
||||
*/
|
||||
HRESULT WINAPI DllRegisterServer(void)
|
||||
{
|
||||
return register_server(TRUE);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllUnregisterServer (ITSS.@)
|
||||
*/
|
||||
HRESULT WINAPI DllUnregisterServer(void)
|
||||
{
|
||||
return register_server(FALSE);
|
||||
}
|
79
reactos/dll/win32/itss/itss.inf
Normal file
79
reactos/dll/win32/itss/itss.inf
Normal file
|
@ -0,0 +1,79 @@
|
|||
[version]
|
||||
Signature="$CHICAGO$"
|
||||
|
||||
|
||||
[RegisterDll]
|
||||
AddReg=Classes.Reg, Misc.Reg
|
||||
|
||||
|
||||
[UnregisterDll]
|
||||
DelReg=Classes.Reg, Misc.Reg
|
||||
|
||||
|
||||
[Classes.Reg]
|
||||
|
||||
;; ITStorage
|
||||
HKCR,"CLSID\%CLSID_ITStorage%",,,"Microsoft InfoTech IStorage System"
|
||||
HKCR,"CLSID\%CLSID_ITStorage%\InProcServer32",,,"itss.dll"
|
||||
HKCR,"CLSID\%CLSID_ITStorage%\InProcServer32","ThreadingModel",,"Both"
|
||||
HKCR,"CLSID\%CLSID_ITStorage%\NotInsertable",,,""
|
||||
HKCR,"CLSID\%CLSID_ITStorage%\ProgID",,,"MSITFS1.0"
|
||||
HKCR,"CLSID\%CLSID_ITStorage%\VersionIndependentProgID",,,"MSITFS"
|
||||
|
||||
HKCR,"MSITFS",,,"Microsoft InfoTech IStorage System"
|
||||
HKCR,"MSITFS\CLSID",,,"%CLSID_ITStorage%"
|
||||
HKCR,"MSITFS\CurVer",,,"MSITFS1.0"
|
||||
|
||||
;; ITSProtocol for IE 3.0
|
||||
HKCR,"CLSID\%CLSID_MSITStore%",,,"Microsoft InfoTech Protocol for IE 3.0"
|
||||
HKCR,"CLSID\%CLSID_MSITStore%\InProcServer32",,,"itss.dll"
|
||||
HKCR,"CLSID\%CLSID_MSITStore%\InProcServer32","ThreadingModel",,"Both"
|
||||
HKCR,"CLSID\%CLSID_MSITStore%\NotInsertable",,,""
|
||||
HKCR,"CLSID\%CLSID_MSITStore%\ProgID",,,"MSITFS1.0"
|
||||
HKCR,"CLSID\%CLSID_MSITStore%\VersionIndependentProgID",,,"MSITFS"
|
||||
|
||||
HKCR,"MSITStore",,,"Microsoft InfoTech Protocol for IE 3.0"
|
||||
HKCR,"MSITStore\CLSID",,,"%CLSID_MSITStore%"
|
||||
HKCR,"MSITStore\CurVer",,,"MSITStore1.0"
|
||||
|
||||
|
||||
;; ITSProtocol for IE 4.0
|
||||
HKCR,"CLSID\%CLSID_ITSProtocol%",,,"Microsoft InfoTech Protocol for IE 4.0"
|
||||
HKCR,"CLSID\%CLSID_ITSProtocol%\InProcServer32",,,"itss.dll"
|
||||
HKCR,"CLSID\%CLSID_ITSProtocol%\InProcServer32","ThreadingModel",,"Both"
|
||||
HKCR,"CLSID\%CLSID_ITSProtocol%\NotInsertable",,,""
|
||||
HKCR,"CLSID\%CLSID_ITSProtocol%\ProgID",,,"MSITFS1.0"
|
||||
HKCR,"CLSID\%CLSID_ITSProtocol%%\VersionIndependentProgID",,,"MSITFS"
|
||||
|
||||
HKCR,"ITSProtocol","Microsoft InfoTech Protocols for IE 4.0"
|
||||
HKCR,"ITSProtocol\CLSID",,,"%CLSID_ITSProtocol%"
|
||||
HKCR,"ITSProtocol\CurVer",,,"ITSProtocol1.0"
|
||||
|
||||
|
||||
;; MSFSStore
|
||||
HKCR,"CLSID\%CLSID_MSFSStore%",,,"Microsoft InfoTech IStorage for Win32 Files"
|
||||
HKCR,"CLSID\%CLSID_MSFSStore%\InProcServer32",,,"itss.dll"
|
||||
HKCR,"CLSID\%CLSID_MSFSStore%\InProcServer32","ThreadingModel",,"Both"
|
||||
HKCR,"CLSID\%CLSID_MSFSStore%\NotInsertable",,,""
|
||||
HKCR,"CLSID\%CLSID_MSFSStore%\ProgID",,,"MSITFS1.0"
|
||||
HKCR,"CLSID\%CLSID_MSFSStore%\VersionIndependentProgID",,,"MSITFS"
|
||||
|
||||
HKCR,"MSFSStore",,,"Microsoft InfoTech IStorage for Win32 Files"
|
||||
HKCR,"MSFSStore\CLSID",,,"%CLSID_MSFSStore%"
|
||||
HKCR,"MSFSStore\CurVer",,,"MSFSStore1.0"
|
||||
|
||||
|
||||
[Misc.Reg]
|
||||
|
||||
HKCR,".its",,,"ITS File"
|
||||
HKCR,"ITS FILE",,,"Internet Document Set"
|
||||
HKCR,"ITS FILE\DefaultIcon",,,"itss.dll,0"
|
||||
;; HKCR "ITS FILE\shell\open\command",,,"FIXME"
|
||||
|
||||
HKCR,"PROTOCOLS\Handler\its",,,"its: Asychronous Pluggable Protocol Handler"
|
||||
HKCR,"PROTOCOLS\Handler\its","CLSID",,"%CLSID_ITSProtocol%"
|
||||
HKCR,"PROTOCOLS\Handler\ms-its",,,"ms-its: Asychronous Pluggable Protocol Handler"
|
||||
HKCR,"PROTOCOLS\Handler\ms-its","CLSID",,"%CLSID_ITSProtocol%"
|
||||
|
||||
HKCR,"PROTOCOLS\Name-Space Handler\mk",,,"NameSpace Filter for MK:@MSITStore:..."
|
||||
HKCR,"PROTOCOLS\Name-Space Handler\mk\*","CLSID",,"%CLSID_ITSProtocol%"
|
23
reactos/dll/win32/itss/itss.rbuild
Normal file
23
reactos/dll/win32/itss/itss.rbuild
Normal file
|
@ -0,0 +1,23 @@
|
|||
<group>
|
||||
<module name="itss" type="win32dll" baseaddress="${BASEADDRESS_ITSS}" installbase="system32" installname="itss.dll" crt="msvcrt">
|
||||
<autoregister infsection="OleControlDlls" type="DllRegisterServer" />
|
||||
<importlibrary definition="itss.spec" />
|
||||
<include base="itss">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<define name="__WINESRC__" />
|
||||
<file>chm_lib.c</file>
|
||||
<file>lzx.c</file>
|
||||
<file>itss.c</file>
|
||||
<file>moniker.c</file>
|
||||
<file>protocol.c</file>
|
||||
<file>storage.c</file>
|
||||
<file>rsrc.rc</file>
|
||||
<library>wine</library>
|
||||
<library>uuid</library>
|
||||
<library>urlmon</library>
|
||||
<library>shlwapi</library>
|
||||
<library>ole32</library>
|
||||
<library>kernel32</library>
|
||||
<library>ntdll</library>
|
||||
</module>
|
||||
</group>
|
6
reactos/dll/win32/itss/itss.spec
Normal file
6
reactos/dll/win32/itss/itss.spec
Normal file
|
@ -0,0 +1,6 @@
|
|||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||
@ stub DllInstall
|
||||
@ stdcall -private DllMain(long long ptr)
|
||||
@ stdcall -private DllRegisterServer()
|
||||
@ stdcall -private DllUnregisterServer()
|
46
reactos/dll/win32/itss/itsstor.h
Normal file
46
reactos/dll/win32/itss/itsstor.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_ITS_STORAGE_PRIVATE__
|
||||
#define __WINE_ITS_STORAGE_PRIVATE__
|
||||
|
||||
extern HRESULT ITSS_StgOpenStorage(
|
||||
const WCHAR* pwcsName,
|
||||
IStorage* pstgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstgOpen);
|
||||
|
||||
extern HRESULT ITS_IParseDisplayName_create(
|
||||
IUnknown *pUnkOuter,
|
||||
LPVOID *ppObj);
|
||||
|
||||
extern HRESULT ITSProtocol_create(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
|
||||
extern LONG dll_count;
|
||||
static inline void ITSS_LockModule(void) { InterlockedIncrement(&dll_count); }
|
||||
static inline void ITSS_UnlockModule(void) { InterlockedDecrement(&dll_count); }
|
||||
|
||||
#define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl)))
|
||||
|
||||
#endif /* __WINE_ITS_STORAGE_PRIVATE__ */
|
832
reactos/dll/win32/itss/lzx.c
Normal file
832
reactos/dll/win32/itss/lzx.c
Normal file
|
@ -0,0 +1,832 @@
|
|||
/***************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#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 = malloc(sizeof(struct LZXstate));
|
||||
if (!(pState->window = 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)
|
||||
{
|
||||
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
|
60
reactos/dll/win32/itss/lzx.h
Normal file
60
reactos/dll/win32/itss/lzx.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/***************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#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 */
|
480
reactos/dll/win32/itss/moniker.c
Normal file
480
reactos/dll/win32/itss/moniker.c
Normal file
|
@ -0,0 +1,480 @@
|
|||
/*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "ole2.h"
|
||||
|
||||
#include "wine/itss.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "itsstor.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(itss);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
const IMonikerVtbl *vtbl_ITS_IMoniker;
|
||||
LONG ref;
|
||||
LPWSTR szHtml;
|
||||
WCHAR szFile[1];
|
||||
} ITS_IMonikerImpl;
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_QueryInterface(
|
||||
IMoniker* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
ITS_IMonikerImpl *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)
|
||||
{
|
||||
ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
|
||||
TRACE("%p\n", This);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITS_IMonikerImpl_Release(
|
||||
IMoniker* iface)
|
||||
{
|
||||
ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (ref == 0) {
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
ITSS_UnlockModule();
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/*** IPersist methods ***/
|
||||
static HRESULT WINAPI ITS_IMonikerImpl_GetClassID(
|
||||
IMoniker* iface,
|
||||
CLSID* pClassID)
|
||||
{
|
||||
ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
|
||||
|
||||
TRACE("%p %p\n", This, pClassID);
|
||||
*pClassID = CLSID_ITStorage;
|
||||
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)
|
||||
{
|
||||
ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface;
|
||||
DWORD grfMode = STGM_SIMPLE | STGM_READ | STGM_SHARE_EXCLUSIVE;
|
||||
HRESULT r;
|
||||
IStorage *stg = NULL;
|
||||
|
||||
TRACE("%p %p %p %s %p\n", This,
|
||||
pbc, pmkToLeft, debugstr_guid(riid), ppvObj);
|
||||
|
||||
r = ITSS_StgOpenStorage( This->szFile, NULL, grfMode, 0, 0, &stg );
|
||||
if( r == S_OK )
|
||||
{
|
||||
TRACE("Opened storage %s\n", debugstr_w( This->szFile ) );
|
||||
if (IsEqualGUID(riid, &IID_IStream))
|
||||
r = IStorage_OpenStream( stg, This->szHtml,
|
||||
NULL, grfMode, 0, (IStream**)ppvObj );
|
||||
else if (IsEqualGUID(riid, &IID_IStorage))
|
||||
r = IStorage_OpenStorage( stg, This->szHtml,
|
||||
NULL, grfMode, NULL, 0, (IStorage**)ppvObj );
|
||||
else
|
||||
r = STG_E_ACCESSDENIED;
|
||||
IStorage_Release( stg );
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ITS_IMonikerImpl *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 const 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, LPCWSTR 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;
|
||||
|
||||
ITSS_LockModule();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
const IParseDisplayNameVtbl *vtbl_ITS_IParseDisplayName;
|
||||
LONG ref;
|
||||
} ITS_IParseDisplayNameImpl;
|
||||
|
||||
static HRESULT WINAPI ITS_IParseDisplayNameImpl_QueryInterface(
|
||||
IParseDisplayName* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
ITS_IParseDisplayNameImpl *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)
|
||||
{
|
||||
ITS_IParseDisplayNameImpl *This = (ITS_IParseDisplayNameImpl *)iface;
|
||||
TRACE("%p\n", This);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITS_IParseDisplayNameImpl_Release(
|
||||
IParseDisplayName* iface)
|
||||
{
|
||||
ITS_IParseDisplayNameImpl *This = (ITS_IParseDisplayNameImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (ref == 0) {
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
ITSS_UnlockModule();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ITS_IParseDisplayNameImpl *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 const 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;
|
||||
|
||||
if( pUnkOuter )
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
|
||||
its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITS_IParseDisplayNameImpl) );
|
||||
its->vtbl_ITS_IParseDisplayName = &ITS_IParseDisplayNameImpl_Vtbl;
|
||||
its->ref = 1;
|
||||
|
||||
TRACE("-> %p\n", its);
|
||||
*ppObj = (LPVOID) its;
|
||||
|
||||
ITSS_LockModule();
|
||||
return S_OK;
|
||||
}
|
488
reactos/dll/win32/itss/protocol.c
Normal file
488
reactos/dll/win32/itss/protocol.c
Normal file
|
@ -0,0 +1,488 @@
|
|||
/*
|
||||
* Copyright 2006-2007 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "ole2.h"
|
||||
#include "urlmon.h"
|
||||
#include "shlwapi.h"
|
||||
#include "itsstor.h"
|
||||
#include "chm_lib.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(itss);
|
||||
|
||||
typedef struct {
|
||||
const IInternetProtocolVtbl *lpInternetProtocolVtbl;
|
||||
const IInternetProtocolInfoVtbl *lpInternetProtocolInfoVtbl;
|
||||
|
||||
LONG ref;
|
||||
|
||||
ULONG offset;
|
||||
struct chmFile *chm_file;
|
||||
struct chmUnitInfo chm_object;
|
||||
} ITSProtocol;
|
||||
|
||||
#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
|
||||
#define PROTINFO(x) ((IInternetProtocolInfo*) &(x)->lpInternetProtocolInfoVtbl)
|
||||
|
||||
static void release_chm(ITSProtocol *This)
|
||||
{
|
||||
if(This->chm_file) {
|
||||
chm_close(This->chm_file);
|
||||
This->chm_file = NULL;
|
||||
}
|
||||
This->offset = 0;
|
||||
}
|
||||
|
||||
#define PROTOCOL_THIS(iface) DEFINE_THIS(ITSProtocol, InternetProtocol, iface)
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
*ppv = NULL;
|
||||
if(IsEqualGUID(&IID_IUnknown, riid)) {
|
||||
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
|
||||
*ppv = PROTOCOL(This);
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
|
||||
*ppv = PROTOCOL(This);
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
|
||||
*ppv = PROTOCOL(This);
|
||||
}else if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
|
||||
TRACE("(%p)->(IID_IInternetProtocolInfo %p)\n", This, ppv);
|
||||
*ppv = PROTINFO(This);
|
||||
}
|
||||
|
||||
if(*ppv) {
|
||||
IInternetProtocol_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("not supported interface %s\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSProtocol_AddRef(IInternetProtocol *iface)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSProtocol_Release(IInternetProtocol *iface)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
release_chm(This);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
ITSS_UnlockModule();
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static LPCWSTR skip_schema(LPCWSTR url)
|
||||
{
|
||||
static const WCHAR its_schema[] = {'i','t','s',':'};
|
||||
static const WCHAR msits_schema[] = {'m','s','-','i','t','s',':'};
|
||||
static const WCHAR mk_schema[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':'};
|
||||
|
||||
if(!strncmpiW(its_schema, url, sizeof(its_schema)/sizeof(WCHAR)))
|
||||
return url+sizeof(its_schema)/sizeof(WCHAR);
|
||||
if(!strncmpiW(msits_schema, url, sizeof(msits_schema)/sizeof(WCHAR)))
|
||||
return url+sizeof(msits_schema)/sizeof(WCHAR);
|
||||
if(!strncmpiW(mk_schema, url, sizeof(mk_schema)/sizeof(WCHAR)))
|
||||
return url+sizeof(mk_schema)/sizeof(WCHAR);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HRESULT report_result(IInternetProtocolSink *sink, HRESULT hres)
|
||||
{
|
||||
IInternetProtocolSink_ReportResult(sink, hres, 0, NULL);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
|
||||
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
|
||||
DWORD grfPI, DWORD dwReserved)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
BINDINFO bindinfo;
|
||||
DWORD bindf = 0, len;
|
||||
LPWSTR file_name, mime, object_name, p;
|
||||
LPCWSTR ptr;
|
||||
struct chmFile *chm_file;
|
||||
struct chmUnitInfo chm_object;
|
||||
int res;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR separator[] = {':',':',0};
|
||||
|
||||
TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
|
||||
pOIBindInfo, grfPI, dwReserved);
|
||||
|
||||
ptr = skip_schema(szUrl);
|
||||
if(!ptr)
|
||||
return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
|
||||
|
||||
memset(&bindinfo, 0, sizeof(bindinfo));
|
||||
bindinfo.cbSize = sizeof(BINDINFO);
|
||||
hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
|
||||
if(FAILED(hres)) {
|
||||
WARN("GetBindInfo failed: %08x\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
ReleaseBindInfo(&bindinfo);
|
||||
|
||||
len = strlenW(ptr)+3;
|
||||
file_name = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
|
||||
memcpy(file_name, ptr, len*sizeof(WCHAR));
|
||||
hres = UrlUnescapeW(file_name, NULL, &len, URL_UNESCAPE_INPLACE);
|
||||
if(FAILED(hres)) {
|
||||
WARN("UrlUnescape failed: %08x\n", hres);
|
||||
HeapFree(GetProcessHeap(), 0, file_name);
|
||||
return hres;
|
||||
}
|
||||
|
||||
p = strstrW(file_name, separator);
|
||||
if(!p) {
|
||||
WARN("invalid url\n");
|
||||
HeapFree(GetProcessHeap(), 0, file_name);
|
||||
return report_result(pOIProtSink, STG_E_FILENOTFOUND);
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
chm_file = chm_openW(file_name);
|
||||
if(!chm_file) {
|
||||
WARN("Could not open chm file\n");
|
||||
HeapFree(GetProcessHeap(), 0, file_name);
|
||||
return report_result(pOIProtSink, STG_E_FILENOTFOUND);
|
||||
}
|
||||
|
||||
object_name = p+2;
|
||||
len = strlenW(object_name);
|
||||
|
||||
if(*object_name != '/' && *object_name != '\\') {
|
||||
memmove(object_name+1, object_name, (len+1)*sizeof(WCHAR));
|
||||
*object_name = '/';
|
||||
len++;
|
||||
}
|
||||
|
||||
if(object_name[len-1] == '/')
|
||||
object_name[--len] = 0;
|
||||
|
||||
for(p=object_name; *p; p++) {
|
||||
if(*p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
|
||||
TRACE("Resolving %s\n", debugstr_w(object_name));
|
||||
|
||||
memset(&chm_object, 0, sizeof(chm_object));
|
||||
res = chm_resolve_object(chm_file, object_name, &chm_object);
|
||||
if(res != CHM_RESOLVE_SUCCESS) {
|
||||
WARN("Could not resolve chm object\n");
|
||||
HeapFree(GetProcessHeap(), 0, file_name);
|
||||
chm_close(chm_file);
|
||||
return report_result(pOIProtSink, STG_E_FILENOTFOUND);
|
||||
}
|
||||
|
||||
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST,
|
||||
strrchrW(object_name, '/')+1);
|
||||
|
||||
/* FIXME: Native doesn't use FindMimeFromData */
|
||||
hres = FindMimeFromData(NULL, object_name, NULL, 0, NULL, 0, &mime, 0);
|
||||
HeapFree(GetProcessHeap(), 0, file_name);
|
||||
if(SUCCEEDED(hres)) {
|
||||
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
|
||||
CoTaskMemFree(mime);
|
||||
}
|
||||
|
||||
release_chm(This); /* Native leaks handle here */
|
||||
This->chm_file = chm_file;
|
||||
This->chm_object = chm_object;
|
||||
|
||||
hres = IInternetProtocolSink_ReportData(pOIProtSink,
|
||||
BSCF_FIRSTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE,
|
||||
chm_object.length, chm_object.length);
|
||||
if(FAILED(hres)) {
|
||||
WARN("ReportData failed: %08x\n", hres);
|
||||
release_chm(This);
|
||||
return report_result(pOIProtSink, hres);
|
||||
}
|
||||
|
||||
hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
|
||||
|
||||
return report_result(pOIProtSink, hres);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%p)\n", This, pProtocolData);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
|
||||
DWORD dwOptions)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%08x)\n", This, dwOptions);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_Suspend(IInternetProtocol *iface)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_Resume(IInternetProtocol *iface)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)\n", This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_Read(IInternetProtocol *iface, void *pv,
|
||||
ULONG cb, ULONG *pcbRead)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
|
||||
|
||||
if(!This->chm_file)
|
||||
return INET_E_DATA_NOT_AVAILABLE;
|
||||
|
||||
*pcbRead = chm_retrieve_object(This->chm_file, &This->chm_object, pv, This->offset, cb);
|
||||
This->offset += *pcbRead;
|
||||
|
||||
return *pcbRead ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
|
||||
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%08x)\n", This, dwOptions);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocol_UnlockRequest(IInternetProtocol *iface)
|
||||
{
|
||||
ITSProtocol *This = PROTOCOL_THIS(iface);
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#undef PROTOCOL_THIS
|
||||
|
||||
static const IInternetProtocolVtbl ITSProtocolVtbl = {
|
||||
ITSProtocol_QueryInterface,
|
||||
ITSProtocol_AddRef,
|
||||
ITSProtocol_Release,
|
||||
ITSProtocol_Start,
|
||||
ITSProtocol_Continue,
|
||||
ITSProtocol_Abort,
|
||||
ITSProtocol_Terminate,
|
||||
ITSProtocol_Suspend,
|
||||
ITSProtocol_Resume,
|
||||
ITSProtocol_Read,
|
||||
ITSProtocol_Seek,
|
||||
ITSProtocol_LockRequest,
|
||||
ITSProtocol_UnlockRequest
|
||||
};
|
||||
|
||||
#define PROTINFO_THIS(iface) DEFINE_THIS(ITSProtocol, InternetProtocolInfo, iface)
|
||||
|
||||
static HRESULT WINAPI ITSProtocolInfo_QueryInterface(IInternetProtocolInfo *iface,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
ITSProtocol *This = PROTINFO_THIS(iface);
|
||||
return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSProtocolInfo_AddRef(IInternetProtocolInfo *iface)
|
||||
{
|
||||
ITSProtocol *This = PROTINFO_THIS(iface);
|
||||
return IInternetProtocol_AddRef(PROTOCOL(This));
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSProtocolInfo_Release(IInternetProtocolInfo *iface)
|
||||
{
|
||||
ITSProtocol *This = PROTINFO_THIS(iface);
|
||||
return IInternetProtocol_Release(PROTOCOL(This));
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
|
||||
PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
|
||||
DWORD *pcchResult, DWORD dwReserved)
|
||||
{
|
||||
ITSProtocol *This = PROTINFO_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%s %x %08x %p %d %p %d)\n", This, debugstr_w(pwzUrl), ParseAction,
|
||||
dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);
|
||||
|
||||
switch(ParseAction) {
|
||||
case PARSE_CANONICALIZE:
|
||||
FIXME("PARSE_CANONICALIZE\n");
|
||||
return E_NOTIMPL;
|
||||
case PARSE_SECURITY_URL:
|
||||
FIXME("PARSE_SECURITY_URL\n");
|
||||
return E_NOTIMPL;
|
||||
default:
|
||||
return INET_E_DEFAULT_ACTION;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
|
||||
LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult,
|
||||
DWORD cchResult, DWORD* pcchResult, DWORD dwReserved)
|
||||
{
|
||||
ITSProtocol *This = PROTINFO_THIS(iface);
|
||||
LPCWSTR base_end, ptr;
|
||||
DWORD rel_len;
|
||||
|
||||
static const WCHAR separator[] = {':',':',0};
|
||||
|
||||
TRACE("(%p)->(%s %s %08x %p %d %p %d)\n", This, debugstr_w(pwzBaseUrl),
|
||||
debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult,
|
||||
pcchResult, dwReserved);
|
||||
|
||||
base_end = strstrW(pwzBaseUrl, separator);
|
||||
if(!base_end)
|
||||
return 0x80041001;
|
||||
base_end += 2;
|
||||
|
||||
if(!skip_schema(pwzBaseUrl))
|
||||
return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
|
||||
|
||||
if(strchrW(pwzRelativeUrl, ':'))
|
||||
return STG_E_INVALIDNAME;
|
||||
|
||||
if(pwzRelativeUrl[0] != '/') {
|
||||
ptr = strrchrW(base_end, '/');
|
||||
if(ptr)
|
||||
base_end = ptr+1;
|
||||
else
|
||||
base_end += strlenW(base_end);
|
||||
}
|
||||
|
||||
rel_len = strlenW(pwzRelativeUrl)+1;
|
||||
|
||||
*pcchResult = rel_len + (base_end-pwzBaseUrl);
|
||||
|
||||
if(*pcchResult > cchResult)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
memcpy(pwzResult, pwzBaseUrl, (base_end-pwzBaseUrl)*sizeof(WCHAR));
|
||||
strcpyW(pwzResult + (base_end-pwzBaseUrl), pwzRelativeUrl);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocolInfo_CompareUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl1,
|
||||
LPCWSTR pwzUrl2, DWORD dwCompareFlags)
|
||||
{
|
||||
ITSProtocol *This = PROTINFO_THIS(iface);
|
||||
FIXME("%p)->(%s %s %08x)\n", This, debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
|
||||
QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf,
|
||||
DWORD dwReserved)
|
||||
{
|
||||
ITSProtocol *This = PROTINFO_THIS(iface);
|
||||
FIXME("(%p)->(%s %08x %08x %p %d %p %d)\n", This, debugstr_w(pwzUrl), QueryOption,
|
||||
dwQueryFlags, pBuffer, cbBuffer, pcbBuf, dwReserved);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
#undef PROTINFO_THIS
|
||||
|
||||
static const IInternetProtocolInfoVtbl ITSProtocolInfoVtbl = {
|
||||
ITSProtocolInfo_QueryInterface,
|
||||
ITSProtocolInfo_AddRef,
|
||||
ITSProtocolInfo_Release,
|
||||
ITSProtocolInfo_ParseUrl,
|
||||
ITSProtocolInfo_CombineUrl,
|
||||
ITSProtocolInfo_CompareUrl,
|
||||
ITSProtocolInfo_QueryInfo
|
||||
};
|
||||
|
||||
HRESULT ITSProtocol_create(IUnknown *pUnkOuter, LPVOID *ppobj)
|
||||
{
|
||||
ITSProtocol *ret;
|
||||
|
||||
TRACE("(%p %p)\n", pUnkOuter, ppobj);
|
||||
|
||||
ITSS_LockModule();
|
||||
|
||||
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ITSProtocol));
|
||||
|
||||
ret->lpInternetProtocolVtbl = &ITSProtocolVtbl;
|
||||
ret->lpInternetProtocolInfoVtbl = &ITSProtocolInfoVtbl;
|
||||
ret->ref = 1;
|
||||
|
||||
*ppobj = PROTOCOL(ret);
|
||||
|
||||
return S_OK;
|
||||
}
|
20
reactos/dll/win32/itss/rsrc.rc
Normal file
20
reactos/dll/win32/itss/rsrc.rc
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2006 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* @makedep: itss.inf */
|
||||
REGINST REGINST itss.inf
|
840
reactos/dll/win32/itss/storage.c
Normal file
840
reactos/dll/win32/itss/storage.c
Normal file
|
@ -0,0 +1,840 @@
|
|||
/*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "ole2.h"
|
||||
|
||||
#include "chm_lib.h"
|
||||
#include "itsstor.h"
|
||||
|
||||
#include "wine/itss.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(itss);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
typedef struct _ITSS_IStorageImpl
|
||||
{
|
||||
const IStorageVtbl *vtbl_IStorage;
|
||||
LONG ref;
|
||||
struct chmFile *chmfile;
|
||||
WCHAR dir[1];
|
||||
} ITSS_IStorageImpl;
|
||||
|
||||
struct enum_info
|
||||
{
|
||||
struct enum_info *next, *prev;
|
||||
struct chmUnitInfo ui;
|
||||
};
|
||||
|
||||
typedef struct _IEnumSTATSTG_Impl
|
||||
{
|
||||
const IEnumSTATSTGVtbl *vtbl_IEnumSTATSTG;
|
||||
LONG ref;
|
||||
struct enum_info *first, *last, *current;
|
||||
} IEnumSTATSTG_Impl;
|
||||
|
||||
typedef struct _IStream_Impl
|
||||
{
|
||||
const IStreamVtbl *vtbl_IStream;
|
||||
LONG 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)
|
||||
{
|
||||
IEnumSTATSTG_Impl *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)
|
||||
{
|
||||
IEnumSTATSTG_Impl *This = (IEnumSTATSTG_Impl *)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSS_IEnumSTATSTG_Release(
|
||||
IEnumSTATSTG* iface)
|
||||
{
|
||||
IEnumSTATSTG_Impl *This = (IEnumSTATSTG_Impl *)iface;
|
||||
|
||||
ULONG ref = InterlockedDecrement(&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);
|
||||
ITSS_UnlockModule();
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IEnumSTATSTG_Next(
|
||||
IEnumSTATSTG* iface,
|
||||
ULONG celt,
|
||||
STATSTG* rgelt,
|
||||
ULONG* pceltFetched)
|
||||
{
|
||||
IEnumSTATSTG_Impl *This = (IEnumSTATSTG_Impl *)iface;
|
||||
DWORD len, n;
|
||||
struct enum_info *cur;
|
||||
|
||||
TRACE("%p %u %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)
|
||||
{
|
||||
IEnumSTATSTG_Impl *This = (IEnumSTATSTG_Impl *)iface;
|
||||
DWORD n;
|
||||
struct enum_info *cur;
|
||||
|
||||
TRACE("%p %u\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)
|
||||
{
|
||||
IEnumSTATSTG_Impl *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;
|
||||
}
|
||||
|
||||
static const 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;
|
||||
|
||||
ITSS_LockModule();
|
||||
TRACE(" -> %p\n", stgenum );
|
||||
|
||||
return stgenum;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_QueryInterface(
|
||||
IStorage* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
ITSS_IStorageImpl *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;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSS_IStorageImpl_AddRef(
|
||||
IStorage* iface)
|
||||
{
|
||||
ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSS_IStorageImpl_Release(
|
||||
IStorage* iface)
|
||||
{
|
||||
ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
|
||||
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
chm_close(This->chmfile);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
ITSS_UnlockModule();
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_CreateStream(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
DWORD grfMode,
|
||||
DWORD reserved1,
|
||||
DWORD reserved2,
|
||||
IStream** ppstm)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_OpenStream(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
void* reserved1,
|
||||
DWORD grfMode,
|
||||
DWORD reserved2,
|
||||
IStream** ppstm)
|
||||
{
|
||||
ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
|
||||
IStream_Impl *stm;
|
||||
DWORD len;
|
||||
struct chmUnitInfo ui;
|
||||
int r;
|
||||
WCHAR *path, *p;
|
||||
|
||||
TRACE("%p %s %p %u %u %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 );
|
||||
|
||||
if( pwcsName[0] == '/' || pwcsName[0] == '\\' )
|
||||
{
|
||||
p = &path[strlenW( path ) - 1];
|
||||
while( ( path <= p ) && ( *p == '/' ) )
|
||||
*p-- = 0;
|
||||
}
|
||||
strcatW( path, pwcsName );
|
||||
|
||||
for(p=path; *p; p++) {
|
||||
if(*p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
|
||||
if(*--p == '/')
|
||||
*p = 0;
|
||||
|
||||
TRACE("Resolving %s\n", debugstr_w(path));
|
||||
|
||||
r = chm_resolve_object(This->chmfile, path, &ui);
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
|
||||
if( r != CHM_RESOLVE_SUCCESS ) {
|
||||
WARN("Could not resolve object\n");
|
||||
return STG_E_FILENOTFOUND;
|
||||
}
|
||||
|
||||
stm = ITSS_create_stream( This, &ui );
|
||||
if( !stm )
|
||||
return E_FAIL;
|
||||
|
||||
*ppstm = (IStream*) stm;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_CreateStorage(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
DWORD grfMode,
|
||||
DWORD dwStgFmt,
|
||||
DWORD reserved2,
|
||||
IStorage** ppstg)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_OpenStorage(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
IStorage* pstgPriority,
|
||||
DWORD grfMode,
|
||||
SNB snbExclude,
|
||||
DWORD reserved,
|
||||
IStorage** ppstg)
|
||||
{
|
||||
ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
|
||||
|
||||
FIXME("%p %s %p %u %p %u %p\n", This, debugstr_w(pwcsName),
|
||||
pstgPriority, grfMode, snbExclude, reserved, ppstg);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_CopyTo(
|
||||
IStorage* iface,
|
||||
DWORD ciidExclude,
|
||||
const IID* rgiidExclude,
|
||||
SNB snbExclude,
|
||||
IStorage* pstgDest)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_MoveElementTo(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
IStorage* pstgDest,
|
||||
LPCOLESTR pwcsNewName,
|
||||
DWORD grfFlags)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_Commit(
|
||||
IStorage* iface,
|
||||
DWORD grfCommitFlags)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static 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) );
|
||||
info->ui = *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;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_EnumElements(
|
||||
IStorage* iface,
|
||||
DWORD reserved1,
|
||||
void* reserved2,
|
||||
DWORD reserved3,
|
||||
IEnumSTATSTG** ppenum)
|
||||
{
|
||||
ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
|
||||
IEnumSTATSTG_Impl* stgenum;
|
||||
|
||||
TRACE("%p %d %p %d %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;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_DestroyElement(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_RenameElement(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsOldName,
|
||||
LPCOLESTR pwcsNewName)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_SetElementTimes(
|
||||
IStorage* iface,
|
||||
LPCOLESTR pwcsName,
|
||||
const FILETIME* pctime,
|
||||
const FILETIME* patime,
|
||||
const FILETIME* pmtime)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_SetClass(
|
||||
IStorage* iface,
|
||||
REFCLSID clsid)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_SetStateBits(
|
||||
IStorage* iface,
|
||||
DWORD grfStateBits,
|
||||
DWORD grfMask)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStorageImpl_Stat(
|
||||
IStorage* iface,
|
||||
STATSTG* pstatstg,
|
||||
DWORD grfStatFlag)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const 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;
|
||||
|
||||
ITSS_LockModule();
|
||||
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)
|
||||
{
|
||||
IStream_Impl *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)
|
||||
{
|
||||
IStream_Impl *This = (IStream_Impl *)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ITSS_IStream_Release(
|
||||
IStream* iface)
|
||||
{
|
||||
IStream_Impl *This = (IStream_Impl *)iface;
|
||||
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
IStorage_Release( (IStorage*) This->stg );
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
ITSS_UnlockModule();
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_Read(
|
||||
IStream* iface,
|
||||
void* pv,
|
||||
ULONG cb,
|
||||
ULONG* pcbRead)
|
||||
{
|
||||
IStream_Impl *This = (IStream_Impl *)iface;
|
||||
ULONG count;
|
||||
|
||||
TRACE("%p %p %u %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 count ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
IStream_Impl *This = (IStream_Impl *)iface;
|
||||
LONGLONG newpos;
|
||||
|
||||
TRACE("%p %s %u %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)
|
||||
{
|
||||
IStream_Impl *This = (IStream_Impl *)iface;
|
||||
|
||||
TRACE("%p %p %d\n", This, pstatstg, grfStatFlag);
|
||||
|
||||
memset( pstatstg, 0, sizeof *pstatstg );
|
||||
if( !( grfStatFlag & STATFLAG_NONAME ) )
|
||||
{
|
||||
FIXME("copy the name\n");
|
||||
}
|
||||
pstatstg->type = STGTY_STREAM;
|
||||
pstatstg->cbSize.QuadPart = This->ui.length;
|
||||
pstatstg->grfMode = STGM_READ;
|
||||
pstatstg->clsid = CLSID_ITStorage;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ITSS_IStream_Clone(
|
||||
IStream* iface,
|
||||
IStream** ppstm)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const 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;
|
||||
stm->ui = *ui;
|
||||
stm->stg = stg;
|
||||
IStorage_AddRef( (IStorage*) stg );
|
||||
|
||||
ITSS_LockModule();
|
||||
|
||||
TRACE(" -> %p\n", stm );
|
||||
|
||||
return stm;
|
||||
}
|
827
reactos/dll/win32/msimtf/activeimmapp.c
Normal file
827
reactos/dll/win32/msimtf/activeimmapp.c
Normal file
|
@ -0,0 +1,827 @@
|
|||
/*
|
||||
* ActiveIMMApp Interface
|
||||
*
|
||||
* Copyright 2008 CodeWeavers, Aric Stewart
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winreg.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "objbase.h"
|
||||
#include "advpub.h"
|
||||
#include "dimm.h"
|
||||
#include "imm.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msimtf);
|
||||
|
||||
typedef struct tagActiveIMMApp {
|
||||
const IActiveIMMAppVtbl *vtbl;
|
||||
LONG refCount;
|
||||
} ActiveIMMApp;
|
||||
|
||||
static void ActiveIMMApp_Destructor(ActiveIMMApp* This)
|
||||
{
|
||||
TRACE("\n");
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_QueryInterface (IActiveIMMApp* iface,
|
||||
REFIID iid, LPVOID *ppvOut)
|
||||
{
|
||||
ActiveIMMApp *This = (ActiveIMMApp*)iface;
|
||||
*ppvOut = NULL;
|
||||
|
||||
if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IActiveIMMApp))
|
||||
{
|
||||
*ppvOut = This;
|
||||
}
|
||||
|
||||
if (*ppvOut)
|
||||
{
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("unsupported interface: %s\n", debugstr_guid(iid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ActiveIMMApp_AddRef(IActiveIMMApp* iface)
|
||||
{
|
||||
ActiveIMMApp *This = (ActiveIMMApp*)iface;
|
||||
return InterlockedIncrement(&This->refCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ActiveIMMApp_Release(IActiveIMMApp* iface)
|
||||
{
|
||||
ActiveIMMApp *This = (ActiveIMMApp*)iface;
|
||||
ULONG ret;
|
||||
|
||||
ret = InterlockedDecrement(&This->refCount);
|
||||
if (ret == 0)
|
||||
ActiveIMMApp_Destructor(This);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_AssociateContext(IActiveIMMApp* iface,
|
||||
HWND hWnd, HIMC hIME, HIMC *phPrev)
|
||||
{
|
||||
*phPrev = ImmAssociateContext(hWnd,hIME);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_ConfigureIMEA(IActiveIMMApp* This,
|
||||
HKL hKL, HWND hwnd, DWORD dwMode, REGISTERWORDA *pData)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmConfigureIMEA(hKL, hwnd, dwMode, pData);
|
||||
if (rc)
|
||||
return E_FAIL;
|
||||
else
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_ConfigureIMEW(IActiveIMMApp* This,
|
||||
HKL hKL, HWND hWnd, DWORD dwMode, REGISTERWORDW *pData)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmConfigureIMEW(hKL, hWnd, dwMode, pData);
|
||||
if (rc)
|
||||
return E_FAIL;
|
||||
else
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_CreateContext(IActiveIMMApp* This,
|
||||
HIMC *phIMC)
|
||||
{
|
||||
*phIMC = ImmCreateContext();
|
||||
if (*phIMC)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_DestroyContext(IActiveIMMApp* This,
|
||||
HIMC hIME)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmDestroyContext(hIME);
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_EnumRegisterWordA(IActiveIMMApp* This,
|
||||
HKL hKL, LPSTR szReading, DWORD dwStyle, LPSTR szRegister,
|
||||
LPVOID pData, IEnumRegisterWordA **pEnum)
|
||||
{
|
||||
FIXME("Stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_EnumRegisterWordW(IActiveIMMApp* This,
|
||||
HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szRegister,
|
||||
LPVOID pData, IEnumRegisterWordW **pEnum)
|
||||
{
|
||||
FIXME("Stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_EscapeA(IActiveIMMApp* This,
|
||||
HKL hKL, HIMC hIMC, UINT uEscape, LPVOID pData, LRESULT *plResult)
|
||||
{
|
||||
*plResult = ImmEscapeA(hKL, hIMC, uEscape, pData);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_EscapeW(IActiveIMMApp* This,
|
||||
HKL hKL, HIMC hIMC, UINT uEscape, LPVOID pData, LRESULT *plResult)
|
||||
{
|
||||
*plResult = ImmEscapeW(hKL, hIMC, uEscape, pData);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCandidateListA(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwIndex, UINT uBufLen, CANDIDATELIST *pCandList,
|
||||
UINT *puCopied)
|
||||
{
|
||||
*puCopied = ImmGetCandidateListA(hIMC, dwIndex, pCandList, uBufLen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCandidateListW(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwIndex, UINT uBufLen, CANDIDATELIST *pCandList,
|
||||
UINT *puCopied)
|
||||
{
|
||||
*puCopied = ImmGetCandidateListW(hIMC, dwIndex, pCandList, uBufLen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCandidateListCountA(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD *pdwListSize, DWORD *pdwBufLen)
|
||||
{
|
||||
*pdwBufLen = ImmGetCandidateListCountA(hIMC, pdwListSize);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCandidateListCountW(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD *pdwListSize, DWORD *pdwBufLen)
|
||||
{
|
||||
*pdwBufLen = ImmGetCandidateListCountA(hIMC, pdwListSize);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCandidateWindow(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwIndex, CANDIDATEFORM *pCandidate)
|
||||
{
|
||||
BOOL rc;
|
||||
rc = ImmGetCandidateWindow(hIMC,dwIndex,pCandidate);
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCompositionFontA(IActiveIMMApp* This,
|
||||
HIMC hIMC, LOGFONTA *plf)
|
||||
{
|
||||
BOOL rc;
|
||||
rc = ImmGetCompositionFontA(hIMC,plf);
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCompositionFontW(IActiveIMMApp* This,
|
||||
HIMC hIMC, LOGFONTW *plf)
|
||||
{
|
||||
BOOL rc;
|
||||
rc = ImmGetCompositionFontW(hIMC,plf);
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCompositionStringA(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LONG *plCopied, LPVOID pBuf)
|
||||
{
|
||||
*plCopied = ImmGetCompositionStringA(hIMC, dwIndex, pBuf, dwBufLen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCompositionStringW(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LONG *plCopied, LPVOID pBuf)
|
||||
{
|
||||
*plCopied = ImmGetCompositionStringW(hIMC, dwIndex, pBuf, dwBufLen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCompositionWindow(IActiveIMMApp* This,
|
||||
HIMC hIMC, COMPOSITIONFORM *pCompForm)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmGetCompositionWindow(hIMC,pCompForm);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetContext(IActiveIMMApp* This,
|
||||
HWND hwnd, HIMC *phIMC)
|
||||
{
|
||||
*phIMC = ImmGetContext(hwnd);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetConversionListA(IActiveIMMApp* This,
|
||||
HKL hKL, HIMC hIMC, LPSTR pSrc, UINT uBufLen, UINT uFlag,
|
||||
CANDIDATELIST *pDst, UINT *puCopied)
|
||||
{
|
||||
*puCopied = ImmGetConversionListA(hKL, hIMC, pSrc, pDst, uBufLen, uFlag);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetConversionListW(IActiveIMMApp* This,
|
||||
HKL hKL, HIMC hIMC, LPWSTR pSrc, UINT uBufLen, UINT uFlag,
|
||||
CANDIDATELIST *pDst, UINT *puCopied)
|
||||
{
|
||||
*puCopied = ImmGetConversionListW(hKL, hIMC, pSrc, pDst, uBufLen, uFlag);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetConversionStatus(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD *pfdwConversion, DWORD *pfdwSentence)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmGetConversionStatus(hIMC, pfdwConversion, pfdwSentence);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetDefaultIMEWnd(IActiveIMMApp* This,
|
||||
HWND hWnd, HWND *phDefWnd)
|
||||
{
|
||||
*phDefWnd = ImmGetDefaultIMEWnd(hWnd);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetDescriptionA(IActiveIMMApp* This,
|
||||
HKL hKL, UINT uBufLen, LPSTR szDescription, UINT *puCopied)
|
||||
{
|
||||
*puCopied = ImmGetDescriptionA(hKL, szDescription, uBufLen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetDescriptionW(IActiveIMMApp* This,
|
||||
HKL hKL, UINT uBufLen, LPWSTR szDescription, UINT *puCopied)
|
||||
{
|
||||
*puCopied = ImmGetDescriptionW(hKL, szDescription, uBufLen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetGuideLineA(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LPSTR pBuf,
|
||||
DWORD *pdwResult)
|
||||
{
|
||||
*pdwResult = ImmGetGuideLineA(hIMC, dwIndex, pBuf, dwBufLen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetGuideLineW(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LPWSTR pBuf,
|
||||
DWORD *pdwResult)
|
||||
{
|
||||
*pdwResult = ImmGetGuideLineW(hIMC, dwIndex, pBuf, dwBufLen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetIMEFileNameA(IActiveIMMApp* This,
|
||||
HKL hKL, UINT uBufLen, LPSTR szFileName, UINT *puCopied)
|
||||
{
|
||||
*puCopied = ImmGetIMEFileNameA(hKL, szFileName, uBufLen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetIMEFileNameW(IActiveIMMApp* This,
|
||||
HKL hKL, UINT uBufLen, LPWSTR szFileName, UINT *puCopied)
|
||||
{
|
||||
*puCopied = ImmGetIMEFileNameW(hKL, szFileName, uBufLen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetOpenStatus(IActiveIMMApp* This,
|
||||
HIMC hIMC)
|
||||
{
|
||||
return ImmGetOpenStatus(hIMC);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetProperty(IActiveIMMApp* This,
|
||||
HKL hKL, DWORD fdwIndex, DWORD *pdwProperty)
|
||||
{
|
||||
*pdwProperty = ImmGetProperty(hKL, fdwIndex);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetRegisterWordStyleA(IActiveIMMApp* This,
|
||||
HKL hKL, UINT nItem, STYLEBUFA *pStyleBuf, UINT *puCopied)
|
||||
{
|
||||
*puCopied = ImmGetRegisterWordStyleA(hKL, nItem, pStyleBuf);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetRegisterWordStyleW(IActiveIMMApp* This,
|
||||
HKL hKL, UINT nItem, STYLEBUFW *pStyleBuf, UINT *puCopied)
|
||||
{
|
||||
*puCopied = ImmGetRegisterWordStyleW(hKL, nItem, pStyleBuf);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetStatusWindowPos(IActiveIMMApp* This,
|
||||
HIMC hIMC, POINT *pptPos)
|
||||
{
|
||||
BOOL rc;
|
||||
rc = ImmGetStatusWindowPos(hIMC, pptPos);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetVirtualKey(IActiveIMMApp* This,
|
||||
HWND hWnd, UINT *puVirtualKey)
|
||||
{
|
||||
*puVirtualKey = ImmGetVirtualKey(hWnd);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_InstallIMEA(IActiveIMMApp* This,
|
||||
LPSTR szIMEFileName, LPSTR szLayoutText, HKL *phKL)
|
||||
{
|
||||
*phKL = ImmInstallIMEA(szIMEFileName,szLayoutText);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_InstallIMEW(IActiveIMMApp* This,
|
||||
LPWSTR szIMEFileName, LPWSTR szLayoutText, HKL *phKL)
|
||||
{
|
||||
*phKL = ImmInstallIMEW(szIMEFileName,szLayoutText);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_IsIME(IActiveIMMApp* This,
|
||||
HKL hKL)
|
||||
{
|
||||
return ImmIsIME(hKL);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_IsUIMessageA(IActiveIMMApp* This,
|
||||
HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return ImmIsUIMessageA(hWndIME,msg,wParam,lParam);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_IsUIMessageW(IActiveIMMApp* This,
|
||||
HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return ImmIsUIMessageW(hWndIME,msg,wParam,lParam);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_NotifyIME(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmNotifyIME(hIMC,dwAction,dwIndex,dwValue);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_RegisterWordA(IActiveIMMApp* This,
|
||||
HKL hKL, LPSTR szReading, DWORD dwStyle, LPSTR szRegister)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmRegisterWordA(hKL,szReading,dwStyle,szRegister);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_RegisterWordW(IActiveIMMApp* This,
|
||||
HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szRegister)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmRegisterWordW(hKL,szReading,dwStyle,szRegister);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_ReleaseContext(IActiveIMMApp* This,
|
||||
HWND hWnd, HIMC hIMC)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmReleaseContext(hWnd,hIMC);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_SetCandidateWindow(IActiveIMMApp* This,
|
||||
HIMC hIMC, CANDIDATEFORM *pCandidate)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmSetCandidateWindow(hIMC,pCandidate);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_SetCompositionFontA(IActiveIMMApp* This,
|
||||
HIMC hIMC, LOGFONTA *plf)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmSetCompositionFontA(hIMC,plf);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_SetCompositionFontW(IActiveIMMApp* This,
|
||||
HIMC hIMC, LOGFONTW *plf)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmSetCompositionFontW(hIMC,plf);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_SetCompositionStringA(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwIndex, LPVOID pComp, DWORD dwCompLen,
|
||||
LPVOID pRead, DWORD dwReadLen)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmSetCompositionStringA(hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_SetCompositionStringW(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwIndex, LPVOID pComp, DWORD dwCompLen,
|
||||
LPVOID pRead, DWORD dwReadLen)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmSetCompositionStringW(hIMC,dwIndex,pComp,dwCompLen,pRead,dwReadLen);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_SetCompositionWindow(IActiveIMMApp* This,
|
||||
HIMC hIMC, COMPOSITIONFORM *pCompForm)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmSetCompositionWindow(hIMC,pCompForm);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_SetConversionStatus(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmSetConversionStatus(hIMC,fdwConversion,fdwSentence);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_SetOpenStatus(IActiveIMMApp* This,
|
||||
HIMC hIMC, BOOL fOpen)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmSetOpenStatus(hIMC,fOpen);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_SetStatusWindowPos(IActiveIMMApp* This,
|
||||
HIMC hIMC, POINT *pptPos)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmSetStatusWindowPos(hIMC,pptPos);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_SimulateHotKey(IActiveIMMApp* This,
|
||||
HWND hwnd, DWORD dwHotKeyID)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmSimulateHotKey(hwnd,dwHotKeyID);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_UnregisterWordA(IActiveIMMApp* This,
|
||||
HKL hKL, LPSTR szReading, DWORD dwStyle, LPSTR szUnregister)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmUnregisterWordA(hKL,szReading,dwStyle,szUnregister);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_UnregisterWordW(IActiveIMMApp* This,
|
||||
HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szUnregister)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmUnregisterWordW(hKL,szReading,dwStyle,szUnregister);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_Activate(IActiveIMMApp* This,
|
||||
BOOL fRestoreLayout)
|
||||
{
|
||||
FIXME("Stub\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_Deactivate(IActiveIMMApp* This)
|
||||
{
|
||||
FIXME("Stub\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_OnDefWindowProc(IActiveIMMApp* This,
|
||||
HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
|
||||
{
|
||||
FIXME("Stub (%p %x %lx %lx)\n",hWnd,Msg,wParam,lParam);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_FilterClientWindows(IActiveIMMApp* This,
|
||||
ATOM *aaClassList, UINT uSize)
|
||||
{
|
||||
FIXME("Stub\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetCodePageA(IActiveIMMApp* This,
|
||||
HKL hKL, UINT *uCodePage)
|
||||
{
|
||||
FIXME("Stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetLangId(IActiveIMMApp* This,
|
||||
HKL hKL, LANGID *plid)
|
||||
{
|
||||
FIXME("Stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_AssociateContextEx(IActiveIMMApp* This,
|
||||
HWND hWnd, HIMC hIMC, DWORD dwFlags)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmAssociateContextEx(hWnd,hIMC,dwFlags);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_DisableIME(IActiveIMMApp* This,
|
||||
DWORD idThread)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
rc = ImmDisableIME(idThread);
|
||||
|
||||
if (rc)
|
||||
return S_OK;
|
||||
else
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetImeMenuItemsA(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwFlags, DWORD dwType,
|
||||
IMEMENUITEMINFOA *pImeParentMenu, IMEMENUITEMINFOA *pImeMenu,
|
||||
DWORD dwSize, DWORD *pdwResult)
|
||||
{
|
||||
*pdwResult = ImmGetImeMenuItemsA(hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_GetImeMenuItemsW(IActiveIMMApp* This,
|
||||
HIMC hIMC, DWORD dwFlags, DWORD dwType,
|
||||
IMEMENUITEMINFOW *pImeParentMenu, IMEMENUITEMINFOW *pImeMenu,
|
||||
DWORD dwSize, DWORD *pdwResult)
|
||||
{
|
||||
*pdwResult = ImmGetImeMenuItemsW(hIMC,dwFlags,dwType,pImeParentMenu,pImeMenu,dwSize);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ActiveIMMApp_EnumInputContext(IActiveIMMApp* This,
|
||||
DWORD idThread, IEnumInputContext **ppEnum)
|
||||
{
|
||||
FIXME("Stub\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IActiveIMMAppVtbl ActiveIMMAppVtbl =
|
||||
{
|
||||
ActiveIMMApp_QueryInterface,
|
||||
ActiveIMMApp_AddRef,
|
||||
ActiveIMMApp_Release,
|
||||
|
||||
ActiveIMMApp_AssociateContext,
|
||||
ActiveIMMApp_ConfigureIMEA,
|
||||
ActiveIMMApp_ConfigureIMEW,
|
||||
ActiveIMMApp_CreateContext,
|
||||
ActiveIMMApp_DestroyContext,
|
||||
ActiveIMMApp_EnumRegisterWordA,
|
||||
ActiveIMMApp_EnumRegisterWordW,
|
||||
ActiveIMMApp_EscapeA,
|
||||
ActiveIMMApp_EscapeW,
|
||||
ActiveIMMApp_GetCandidateListA,
|
||||
ActiveIMMApp_GetCandidateListW,
|
||||
ActiveIMMApp_GetCandidateListCountA,
|
||||
ActiveIMMApp_GetCandidateListCountW,
|
||||
ActiveIMMApp_GetCandidateWindow,
|
||||
ActiveIMMApp_GetCompositionFontA,
|
||||
ActiveIMMApp_GetCompositionFontW,
|
||||
ActiveIMMApp_GetCompositionStringA,
|
||||
ActiveIMMApp_GetCompositionStringW,
|
||||
ActiveIMMApp_GetCompositionWindow,
|
||||
ActiveIMMApp_GetContext,
|
||||
ActiveIMMApp_GetConversionListA,
|
||||
ActiveIMMApp_GetConversionListW,
|
||||
ActiveIMMApp_GetConversionStatus,
|
||||
ActiveIMMApp_GetDefaultIMEWnd,
|
||||
ActiveIMMApp_GetDescriptionA,
|
||||
ActiveIMMApp_GetDescriptionW,
|
||||
ActiveIMMApp_GetGuideLineA,
|
||||
ActiveIMMApp_GetGuideLineW,
|
||||
ActiveIMMApp_GetIMEFileNameA,
|
||||
ActiveIMMApp_GetIMEFileNameW,
|
||||
ActiveIMMApp_GetOpenStatus,
|
||||
ActiveIMMApp_GetProperty,
|
||||
ActiveIMMApp_GetRegisterWordStyleA,
|
||||
ActiveIMMApp_GetRegisterWordStyleW,
|
||||
ActiveIMMApp_GetStatusWindowPos,
|
||||
ActiveIMMApp_GetVirtualKey,
|
||||
ActiveIMMApp_InstallIMEA,
|
||||
ActiveIMMApp_InstallIMEW,
|
||||
ActiveIMMApp_IsIME,
|
||||
ActiveIMMApp_IsUIMessageA,
|
||||
ActiveIMMApp_IsUIMessageW,
|
||||
ActiveIMMApp_NotifyIME,
|
||||
ActiveIMMApp_RegisterWordA,
|
||||
ActiveIMMApp_RegisterWordW,
|
||||
ActiveIMMApp_ReleaseContext,
|
||||
ActiveIMMApp_SetCandidateWindow,
|
||||
ActiveIMMApp_SetCompositionFontA,
|
||||
ActiveIMMApp_SetCompositionFontW,
|
||||
ActiveIMMApp_SetCompositionStringA,
|
||||
ActiveIMMApp_SetCompositionStringW,
|
||||
ActiveIMMApp_SetCompositionWindow,
|
||||
ActiveIMMApp_SetConversionStatus,
|
||||
ActiveIMMApp_SetOpenStatus,
|
||||
ActiveIMMApp_SetStatusWindowPos,
|
||||
ActiveIMMApp_SimulateHotKey,
|
||||
ActiveIMMApp_UnregisterWordA,
|
||||
ActiveIMMApp_UnregisterWordW,
|
||||
|
||||
ActiveIMMApp_Activate,
|
||||
ActiveIMMApp_Deactivate,
|
||||
ActiveIMMApp_OnDefWindowProc,
|
||||
ActiveIMMApp_FilterClientWindows,
|
||||
ActiveIMMApp_GetCodePageA,
|
||||
ActiveIMMApp_GetLangId,
|
||||
ActiveIMMApp_AssociateContextEx,
|
||||
ActiveIMMApp_DisableIME,
|
||||
ActiveIMMApp_GetImeMenuItemsA,
|
||||
ActiveIMMApp_GetImeMenuItemsW,
|
||||
ActiveIMMApp_EnumInputContext
|
||||
};
|
||||
|
||||
HRESULT ActiveIMMApp_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
|
||||
{
|
||||
ActiveIMMApp *This;
|
||||
if (pUnkOuter)
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ActiveIMMApp));
|
||||
if (This == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->vtbl = &ActiveIMMAppVtbl;
|
||||
This->refCount = 1;
|
||||
|
||||
TRACE("returning %p\n",This);
|
||||
*ppOut = (IUnknown *)This;
|
||||
return S_OK;
|
||||
}
|
219
reactos/dll/win32/msimtf/main.c
Normal file
219
reactos/dll/win32/msimtf/main.c
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Copyright 2007 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "advpub.h"
|
||||
#include "ole2.h"
|
||||
#include "dimm.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msimtf);
|
||||
|
||||
extern HRESULT ActiveIMMApp_Constructor(IUnknown *punkOuter, IUnknown **ppOut);
|
||||
|
||||
static HINSTANCE msimtf_instance;
|
||||
|
||||
/******************************************************************
|
||||
* DllMain (msimtf.@)
|
||||
*/
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||
{
|
||||
switch(fdwReason)
|
||||
{
|
||||
case DLL_WINE_PREATTACH:
|
||||
return FALSE; /* prefer native version */
|
||||
case DLL_PROCESS_ATTACH:
|
||||
msimtf_instance = hInstDLL;
|
||||
DisableThreadLibraryCalls(hInstDLL);
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const IClassFactoryVtbl *lpClassFactoryVtbl;
|
||||
|
||||
HRESULT (*cf)(IUnknown*,IUnknown**);
|
||||
} ClassFactory;
|
||||
|
||||
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
|
||||
if(IsEqualGUID(&IID_IUnknown, riid)) {
|
||||
TRACE("(IID_IUnknown %p)\n", ppv);
|
||||
*ppv = iface;
|
||||
}else if(IsEqualGUID(&IID_IClassFactory, riid)) {
|
||||
TRACE("IID_IClassFactory %p)\n", ppv);
|
||||
*ppv = iface;
|
||||
}
|
||||
|
||||
if(*ppv) {
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
FIXME("(%s %p)\n", debugstr_guid(riid), ppv);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface,
|
||||
IUnknown *pOuter, REFIID riid, void **ppv)
|
||||
{
|
||||
ClassFactory *This = (ClassFactory*)iface;
|
||||
HRESULT ret;
|
||||
IUnknown *obj;
|
||||
TRACE("(%p, %p, %s, %p)\n", iface, pOuter, debugstr_guid(riid), ppv);
|
||||
|
||||
ret = This->cf(pOuter, &obj);
|
||||
if (FAILED(ret))
|
||||
return ret;
|
||||
|
||||
ret = IUnknown_QueryInterface(obj,riid,ppv);
|
||||
IUnknown_Release(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
|
||||
{
|
||||
FIXME("(%d)\n", dolock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IClassFactoryVtbl ClassFactoryVtbl = {
|
||||
ClassFactory_QueryInterface,
|
||||
ClassFactory_AddRef,
|
||||
ClassFactory_Release,
|
||||
ClassFactory_CreateInstance,
|
||||
ClassFactory_LockServer
|
||||
};
|
||||
|
||||
/******************************************************************
|
||||
* DllGetClassObject (msimtf.@)
|
||||
*/
|
||||
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
if(IsEqualGUID(&CLSID_CActiveIMM, rclsid)) {
|
||||
static ClassFactory cf = {
|
||||
&ClassFactoryVtbl,
|
||||
ActiveIMMApp_Constructor,
|
||||
};
|
||||
|
||||
return IClassFactory_QueryInterface((IClassFactory*)&cf, riid, ppv);
|
||||
}
|
||||
|
||||
FIXME("(%s %s %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* DllCanUnloadNow (msimtf.@)
|
||||
*/
|
||||
HRESULT WINAPI DllCanUnloadNow(void)
|
||||
{
|
||||
FIXME("()\n");
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
#define INF_SET_CLSID(clsid) \
|
||||
do \
|
||||
{ \
|
||||
static CHAR name[] = "CLSID_" #clsid; \
|
||||
\
|
||||
pse[i].pszName = name; \
|
||||
clsids[i++] = &CLSID_ ## clsid; \
|
||||
} while (0)
|
||||
|
||||
static HRESULT register_server(BOOL doregister)
|
||||
{
|
||||
HRESULT hres;
|
||||
HMODULE hAdvpack;
|
||||
HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
|
||||
STRTABLEA strtable;
|
||||
STRENTRYA pse[1];
|
||||
static CLSID const *clsids[34];
|
||||
unsigned int i = 0;
|
||||
|
||||
static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0};
|
||||
|
||||
INF_SET_CLSID(CActiveIMM);
|
||||
|
||||
for(i = 0; i < sizeof(pse)/sizeof(pse[0]); i++) {
|
||||
pse[i].pszValue = HeapAlloc(GetProcessHeap(), 0, 39);
|
||||
sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
||||
clsids[i]->Data1, clsids[i]->Data2, clsids[i]->Data3, clsids[i]->Data4[0],
|
||||
clsids[i]->Data4[1], clsids[i]->Data4[2], clsids[i]->Data4[3], clsids[i]->Data4[4],
|
||||
clsids[i]->Data4[5], clsids[i]->Data4[6], clsids[i]->Data4[7]);
|
||||
}
|
||||
|
||||
strtable.cEntries = sizeof(pse)/sizeof(pse[0]);
|
||||
strtable.pse = pse;
|
||||
|
||||
hAdvpack = LoadLibraryW(wszAdvpack);
|
||||
pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
|
||||
|
||||
hres = pRegInstall(msimtf_instance, doregister ? "RegisterDll" : "UnregisterDll", &strtable);
|
||||
|
||||
for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++)
|
||||
HeapFree(GetProcessHeap(), 0, pse[i].pszValue);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
#undef INF_SET_CLSID
|
||||
|
||||
/***********************************************************************
|
||||
* DllRegisterServer (msimtf.@)
|
||||
*/
|
||||
HRESULT WINAPI DllRegisterServer(void)
|
||||
{
|
||||
return register_server(TRUE);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllUnregisterServer (msimtf.@)
|
||||
*/
|
||||
HRESULT WINAPI DllUnregisterServer(void)
|
||||
{
|
||||
return register_server(FALSE);
|
||||
}
|
26
reactos/dll/win32/msimtf/msimtf.inf
Normal file
26
reactos/dll/win32/msimtf/msimtf.inf
Normal file
|
@ -0,0 +1,26 @@
|
|||
[version]
|
||||
Signature="$CHICAGO$"
|
||||
|
||||
|
||||
[RegisterDll]
|
||||
AddReg=Classes.Reg
|
||||
|
||||
|
||||
[UnregisterDll]
|
||||
DelReg=Classes.Reg
|
||||
|
||||
|
||||
[Classes.Reg]
|
||||
HKCR,"CLSID\%CLSID_CActiveIMM%",,,"CActiveIMMApp"
|
||||
HKCR,"CLSID\%CLSID_CActiveIMM%\InProcServer32",,,"msimtf.dll"
|
||||
HKCR,"CLSID\%CLSID_CActiveIMM%\InProcServer32","ThreadingModel",,"Apartment"
|
||||
HKCR,"CLSID\%CLSID_CActiveIMMAppEx_Trident%",,,"CActiveIMMAppEx_Trident"
|
||||
HKCR,"CLSID\%CLSID_CActiveIMMAppEx_Trident%\InProcServer32",,,"msimtf.dll"
|
||||
HKCR,"CLSID\%CLSID_CActiveIMMAppEx_Trident%\InProcServer32","ThreadingModel",,"Apartment"
|
||||
HKCR,"CLSID\%CLSID_CActiveIMMAppEx%",,,"CActiveIMMAppEx"
|
||||
HKCR,"CLSID\%CLSID_CActiveIMMAppEx%\InProcServer32",,,"msimtf.dll"
|
||||
HKCR,"CLSID\%CLSID_CActiveIMMAppEx%\InProcServer32","ThreadingModel",,"Apartment"
|
||||
|
||||
[Strings]
|
||||
CLSID_CActiveIMMAppEx_Trident={50D5107A-D278-4871-8989-F4CEAAF59CFC}
|
||||
CLSID_CActiveIMMAppEx="{C1EE01F2-B3B6-4A6A-9DDD-E988C088EC82}"
|
17
reactos/dll/win32/msimtf/msimtf.rbuild
Normal file
17
reactos/dll/win32/msimtf/msimtf.rbuild
Normal file
|
@ -0,0 +1,17 @@
|
|||
<group>
|
||||
<module name="msimtf" type="win32dll" baseaddress="${BASEADDRESS_MSIMTF}" installbase="system32" installname="msimtf.dll">
|
||||
<autoregister infsection="OleControlDlls" type="DllRegisterServer" />
|
||||
<importlibrary definition="msimtf.spec" />
|
||||
<include base="msimtf">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<define name="__WINESRC__" />
|
||||
<file>activeimmapp.c</file>
|
||||
<file>main.c</file>
|
||||
<file>rsrc.rc</file>
|
||||
<library>wine</library>
|
||||
<library>uuid</library>
|
||||
<library>imm32</library>
|
||||
<library>kernel32</library>
|
||||
<library>ntdll</library>
|
||||
</module>
|
||||
</group>
|
6
reactos/dll/win32/msimtf/msimtf.spec
Normal file
6
reactos/dll/win32/msimtf/msimtf.spec
Normal file
|
@ -0,0 +1,6 @@
|
|||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||
@ stdcall -private DllRegisterServer()
|
||||
@ stdcall -private DllUnregisterServer()
|
||||
@ stub MsimtfIsGuidMapEnable
|
||||
@ stub MsimtfIsWindowFiltered
|
20
reactos/dll/win32/msimtf/rsrc.rc
Normal file
20
reactos/dll/win32/msimtf/rsrc.rc
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2007 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* @makedep: msimtf.inf */
|
||||
REGINST REGINST msimtf.inf
|
|
@ -133,6 +133,9 @@
|
|||
<directory name="iphlpapi">
|
||||
<xi:include href="iphlpapi/iphlpapi.rbuild" />
|
||||
</directory>
|
||||
<directory name="itss">
|
||||
<xi:include href="itss/itss.rbuild" />
|
||||
</directory>
|
||||
<directory name="jscript">
|
||||
<xi:include href="jscript/jscript.rbuild" />
|
||||
</directory>
|
||||
|
@ -193,6 +196,9 @@
|
|||
<directory name="msimg32">
|
||||
<xi:include href="msimg32/msimg32.rbuild" />
|
||||
</directory>
|
||||
<directory name="msimtf">
|
||||
<xi:include href="msimtf/msimtf.rbuild" />
|
||||
</directory>
|
||||
<directory name="mstask">
|
||||
<xi:include href="mstask/mstask.rbuild" />
|
||||
</directory>
|
||||
|
|
|
@ -56,6 +56,8 @@ reactos/dll/win32/imagehlp # Patches for BindImage need review and submis
|
|||
reactos/dll/win32/inetcomm # Autosync
|
||||
reactos/dll/win32/inetmib1 # Autosync
|
||||
reactos/dll/win32/iphlpapi # Out of sync
|
||||
reactos/dll/win32/itss # Autosync
|
||||
reactos/dll/win32/jscript # Autosync
|
||||
reactos/dll/win32/localui # Autosync
|
||||
reactos/dll/win32/lz32 # Autosync
|
||||
reactos/dll/win32/mapi32 # Autosync
|
||||
|
@ -66,6 +68,7 @@ reactos/dll/win32/mscoree # Autosync
|
|||
reactos/dll/win32/mshtml # Autosync
|
||||
reactos/dll/win32/msimg32 # Autosync
|
||||
reactos/dll/win32/msi # Autosync
|
||||
reactos/dll/win32/msimtf # Autosync
|
||||
reactos/dll/win32/mstask # Autosync
|
||||
reactos/dll/win32/msvcrt20 # Autosync
|
||||
reactos/dll/win32/msvfw32 # Autosync
|
||||
|
|
Loading…
Reference in a new issue