- Add itss and msimtf from Wine

- Update README.WINE

svn path=/trunk/; revision=38995
This commit is contained in:
Dmitry Chapyshev 2009-01-21 14:10:09 +00:00
parent d4835adc0b
commit 928873cf85
22 changed files with 6234 additions and 0 deletions

View file

@ -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

File diff suppressed because it is too large Load diff

View 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 */

View 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);
}

View 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%"

View 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>

View 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()

View 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__ */

View 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

View 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 */

View 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;
}

View 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;
}

View 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

View 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;
}

View 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;
}

View 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);
}

View 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}"

View 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>

View file

@ -0,0 +1,6 @@
@ stdcall -private DllCanUnloadNow()
@ stdcall -private DllGetClassObject(ptr ptr ptr)
@ stdcall -private DllRegisterServer()
@ stdcall -private DllUnregisterServer()
@ stub MsimtfIsGuidMapEnable
@ stub MsimtfIsWindowFiltered

View 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

View file

@ -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>

View file

@ -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