diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ole32/olethunk/olethk32 | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/ole32/olethunk/olethk32')
62 files changed, 30946 insertions, 0 deletions
diff --git a/private/ole32/olethunk/olethk32/alias.cxx b/private/ole32/olethunk/olethk32/alias.cxx new file mode 100644 index 000000000..0f60dd989 --- /dev/null +++ b/private/ole32/olethunk/olethk32/alias.cxx @@ -0,0 +1,405 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: alias.cxx +// +// Contents: Alias implementations +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +//+--------------------------------------------------------------------------- +// +// Member: CAliasBlock::CAliasBlock, public +// +// Synopsis: Constructor +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +CAliasBlock::CAliasBlock(ALIAS aliasBase, + CAliasBlock *pabNext) +{ + _aliasBase = aliasBase; + _iFilled = 0; + _pabNext = pabNext; + + // Since INVALID_VALUE is a DWORD we can't directly memset it, + // but we'd like to use memset so assert that it's a known value + // and go ahead + thkAssert(INVALID_VALUE == 0); + memset(_dwValues, 0, sizeof(_dwValues)); +} + +//+--------------------------------------------------------------------------- +// +// Member: CAliasBlock::ValueAlias, public +// +// Synopsis: Find the alias for a value +// +// Arguments: [dwValue] - Value +// +// Returns: Alias or INVALID_ALIAS +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +ALIAS CAliasBlock::ValueAlias(DWORD dwValue) +{ + int i; + DWORD *pdw; + + thkAssert(dwValue != INVALID_VALUE); + +#if DBG == 1 + CheckFree(); +#endif + + if (_iFilled == 0) + { + return INVALID_ALIAS; + } + + pdw = _dwValues; + for (i = 0; i < ALIAS_BLOCK_SIZE; i++) + { + if (*pdw == dwValue) + { + return IndexAlias(i); + } + + pdw++; + } + + return INVALID_ALIAS; +} + +//+--------------------------------------------------------------------------- +// +// Member: CAliasBlock::AddValue, public +// +// Synopsis: Adds a new value +// +// Arguments: [dwValue] - New value +// +// Returns: Alias for block or INVALID_ALIAS +// +// History: 26-May-94 DrewB Created +// +// Notes: Duplicates are not allowed +// +//---------------------------------------------------------------------------- + +ALIAS CAliasBlock::AddValue(DWORD dwValue) +{ + int i; + DWORD *pdw; + + thkAssert(dwValue != INVALID_VALUE); + +#if DBG == 1 + CheckFree(); +#endif + + if (_iFilled == ALIAS_BLOCK_SIZE) + { + return INVALID_ALIAS; + } + + // Check for duplicates + thkAssert(ValueAlias(dwValue) == INVALID_ALIAS); + + pdw = _dwValues; + for (i = 0; i < ALIAS_BLOCK_SIZE; i++) + { + if (*pdw == INVALID_VALUE) + { + break; + } + + pdw++; + } + + thkAssert(i < ALIAS_BLOCK_SIZE); + + _iFilled++; + _dwValues[i] = dwValue; + + return IndexAlias(i); +} + +//+--------------------------------------------------------------------------- +// +// Member: CAliasBlock::CheckFree, public debug +// +// Synopsis: Checks to make sure that _iFilled is correct +// +// History: 30-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +void CAliasBlock::CheckFree(void) +{ + int i, iFilled; + DWORD *pdw; + + iFilled = 0; + pdw = _dwValues; + for (i = 0; i < ALIAS_BLOCK_SIZE; i++) + { + if (*pdw != INVALID_VALUE) + { + iFilled++; + } + + pdw++; + } + + thkAssert(iFilled == _iFilled); +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: CAliases::~CAliases, public +// +// Synopsis: Destructor +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +CAliases::~CAliases(void) +{ + CAliasBlock *pab; + + while (_pabAliases) + { + pab = _pabAliases->GetNext(); + // + // The first alias block added to the list is a static one. We + // cannot call the heap to deallocate it. + // + if (_pabAliases != &_abStatic) + { + delete _pabAliases; + } + + _pabAliases = pab; + } +} + +//+--------------------------------------------------------------------------- +// +// Member: CAliases::AliasValue, public +// +// Synopsis: Returns the value for an alias +// +// Arguments: [alias] - Alias +// +// Returns: Value +// +// History: 26-May-94 DrewB Created +// +// Notes: Alias must be valid +// +//---------------------------------------------------------------------------- + +DWORD CAliases::AliasValue(ALIAS alias) +{ + CAliasBlock *pab; + + for (pab = _pabAliases; pab; pab = pab->GetNext()) + { + if (pab->ContainsAlias(alias)) + { + return pab->AliasValue(alias); + } + } + + thkAssert(!"Invalid alias in CAliases::AliasValue"); + + return 0xffffffff; +} + +//+--------------------------------------------------------------------------- +// +// Function: CAliases::ValueAlias, public +// +// Synopsis: Returns the alias for a value +// +// Arguments: [dwValue] - Value +// +// Returns: Alias +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +ALIAS CAliases::ValueAlias(DWORD dwValue) +{ + CAliasBlock *pab; + ALIAS alias; + + for (pab = _pabAliases; pab; pab = pab->GetNext()) + { + alias = pab->ValueAlias(dwValue); + if (alias != INVALID_ALIAS) + { + return alias; + } + } + + return INVALID_ALIAS; +} + +//+--------------------------------------------------------------------------- +// +// Function: CAliases::AddValue, public +// +// Synopsis: Adds a value and returns its alias +// +// Arguments: [dwValue] - Value +// +// Returns: Alias or INVALID_ALIAS +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +ALIAS CAliases::AddValue(DWORD dwValue) +{ + CAliasBlock *pab; + ALIAS alias; + + for (pab = _pabAliases; pab; pab = pab->GetNext()) + { + alias = pab->AddValue(dwValue); + if (alias != INVALID_ALIAS) + { + return alias; + } + } + + if ((long)_aliasBase+ALIAS_BLOCK_SIZE >= INVALID_ALIAS) + { + return INVALID_ALIAS; + } + + pab = new CAliasBlock(_aliasBase+ALIAS_BLOCK_SIZE, _pabAliases); + if (pab == NULL) + { + return INVALID_ALIAS; + } + + _aliasBase += ALIAS_BLOCK_SIZE; + _pabAliases = pab; + + alias = pab->AddValue(dwValue); + + thkAssert(alias != INVALID_ALIAS); + + return alias; +} + +//+--------------------------------------------------------------------------- +// +// Function: CAliases::RemoveAlias, public +// +// Synopsis: Removes an alias +// +// Arguments: [alias] - Alias +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CAliases::RemoveAlias(ALIAS alias) +{ + CAliasBlock *pab, *pabPrev; + + pabPrev = NULL; + for (pab = _pabAliases; pab; pabPrev = pab, pab = pab->GetNext()) + { + if (pab->ContainsAlias(alias)) + { + pab->RemoveAlias(alias); + + if (pab->AliasesFilled() == 0) + { + DeleteBlock(pab, pabPrev); + } + + return; + } + } + + thkAssert(!"Invalid alias in CAliases::RemoveAlias"); +} + +//+--------------------------------------------------------------------------- +// +// Function: CAliases::SetValue, public +// +// Synopsis: Sets the value for an alias +// +// Arguments: [alias] - Alias +// [dwValue] - Value +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CAliases::SetValue(ALIAS alias, DWORD dwValue) +{ + CAliasBlock *pab; + + for (pab = _pabAliases; pab; pab = pab->GetNext()) + { + if (pab->ContainsAlias(alias)) + { + pab->SetValue(alias, dwValue); + } + } +} + +//+--------------------------------------------------------------------------- +// +// Member: CAliases::DeleteBlock, private +// +// Synopsis: Deletes an alias block if it's not the static block +// +// Arguments: [pab] - Alias block +// [pabPrev] - Previous alias block +// +// History: 27-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CAliases::DeleteBlock(CAliasBlock *pab, CAliasBlock *pabPrev) +{ + if (pab == &_abStatic) + { + return; + } + + if (pabPrev) + { + pabPrev->SetNext(pab->GetNext()); + } + else + { + _pabAliases = pab->GetNext(); + } + + delete pab; +} diff --git a/private/ole32/olethunk/olethk32/alias.hxx b/private/ole32/olethunk/olethk32/alias.hxx new file mode 100644 index 000000000..0718e84b9 --- /dev/null +++ b/private/ole32/olethunk/olethk32/alias.hxx @@ -0,0 +1,163 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: alias.hxx +// +// Classes: CAliasBlock +// CAliases +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#ifndef __ALIAS_HXX__ +#define __ALIAS_HXX__ + +// Number of alias slots to allocate in a chunk +#define ALIAS_BLOCK_SIZE 64 + +typedef WORD ALIAS; +#define INVALID_ALIAS ((ALIAS)0xffff) + +// Aliases should not be zero because this causes error detection problems +#define INITIAL_ALIAS ((ALIAS)1) + +// Values cannot be zero, this allows us to detect free slots in the +// value array +#define INVALID_VALUE ((DWORD)0) + +//+--------------------------------------------------------------------------- +// +// Class: CAliasBlock (ab) +// +// Purpose: A block of values indexed by alias +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +class CAliasBlock +{ +public: + CAliasBlock(ALIAS aliasBase, + CAliasBlock *pabNext); + + BOOL ContainsAlias(ALIAS alias) + { + return alias >= _aliasBase && alias < _aliasBase+ALIAS_BLOCK_SIZE; + } + DWORD AliasValue(ALIAS alias) + { + thkAssert(!IsFree(alias)); + + return _dwValues[AliasIndex(alias)]; + } + void RemoveAlias(ALIAS alias) + { + thkAssert(!IsFree(alias)); +#if DBG == 1 + CheckFree(); +#endif + thkAssert(_iFilled > 0); + + _iFilled--; + _dwValues[AliasIndex(alias)] = INVALID_VALUE; + } + void SetValue(ALIAS alias, DWORD dwValue) + { + thkAssert(!IsFree(alias)); + thkAssert(dwValue != INVALID_VALUE); + + _dwValues[AliasIndex(alias)] = dwValue; + } + + ALIAS ValueAlias(DWORD dwValue); + ALIAS AddValue(DWORD dwValue); + + CAliasBlock *GetNext(void) + { + return _pabNext; + } + void SetNext(CAliasBlock *pab) + { + _pabNext = pab; + } + int AliasesFilled(void) + { + return _iFilled; + } + +#if DBG == 1 + BOOL IsFree(ALIAS alias) + { + return _dwValues[AliasIndex(alias)] == INVALID_VALUE; + } +#endif + +private: + int AliasIndex(ALIAS alias) + { + thkAssert(ContainsAlias(alias)); + + return (int)(alias-_aliasBase); + } + ALIAS IndexAlias(int iIndex) + { + thkAssert(iIndex >= 0 && iIndex < ALIAS_BLOCK_SIZE); + + return (ALIAS)(iIndex+_aliasBase); + } + +#if DBG == 1 + void CheckFree(void); +#endif + + ALIAS _aliasBase; + int _iFilled; + DWORD _dwValues[ALIAS_BLOCK_SIZE]; + CAliasBlock *_pabNext; +}; + +//+--------------------------------------------------------------------------- +// +// Class: CAliases (aliases) +// +// Purpose: Maintains a set of aliases for values +// +// History: 26-May-94 DrewB Created +// +// Notes: Values must be unique +// +//---------------------------------------------------------------------------- + +class CAliases +{ +public: + CAliases(void) + : _abStatic(INITIAL_ALIAS, NULL) + { + // Start alias list with the static block + _pabAliases = &_abStatic; + + // The static block takes the first block of aliases + _aliasBase = INITIAL_ALIAS+ALIAS_BLOCK_SIZE; + } + ~CAliases(void); + + DWORD AliasValue(ALIAS alias); + ALIAS ValueAlias(DWORD dwValue); + ALIAS AddValue(DWORD dwValue); + void RemoveAlias(ALIAS alias); + void SetValue(ALIAS alias, DWORD dwValue); + +private: + void DeleteBlock(CAliasBlock *pab, CAliasBlock *pabPrev); + + CAliasBlock _abStatic; + CAliasBlock *_pabAliases; + ALIAS _aliasBase; +}; + +#endif // #ifndef __ALIAS_HXX__ diff --git a/private/ole32/olethunk/olethk32/apinot.cxx b/private/ole32/olethunk/olethk32/apinot.cxx new file mode 100644 index 000000000..de850d67e --- /dev/null +++ b/private/ole32/olethunk/olethk32/apinot.cxx @@ -0,0 +1,990 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: apinot.cxx +// +// Contents: Implementation of non-API thunks +// +// History: 11-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +#include <thunkapi.hxx> +#include <wownt32.h> +#include "olethk32.hxx" +#include "apinot.hxx" +#include "tlsthk.hxx" + +// +// The following is a global static used by OLE32 to call back into +// this DLL. There is no static data associated with the static, so +// it merely defines a virtual interface that OLE32 can use. +// + +OleThunkWOW g_thkOleThunkWOW; + +// +// The following API is exported from WOW32.DLL. There is no global include +// file that it exists in yet. +// +#if defined(_CHICAGO_) +#define WOWFreeMetafile(x) (0) /* BUGBUGCHICAGO - Not supported under Chicago yet. */ +#else +extern "C" BOOL WINAPI WOWFreeMetafile( HANDLE h32 ); +#endif + +//+--------------------------------------------------------------------------- +// +// Function: CoInitializeNot, public +// +// Synopsis: Thunks for the 16-bit applications call to CoInitialize +// +// Arguments: [lpmalloc] - Parameter from the 16-bit world +// +// Returns: Appropriate status code +// +// History: 11-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +STDAPI_(DWORD) CoInitializeNot( LPMALLOC lpMalloc ) +{ + HRESULT hresult; + + hresult = CoInitializeWOW( lpMalloc, &g_thkOleThunkWOW ); + + return (DWORD)hresult; +} + +//+--------------------------------------------------------------------------- +// +// Function: OleInitializeNot, public +// +// Synopsis: Thunks for the 16-bit applications call to OleInitialize +// +// Arguments: [lpmalloc] - Parameter from the 16-bit world +// +// Returns: Appropriate status code +// +// History: 11-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +STDAPI_(DWORD) OleInitializeNot( LPMALLOC lpMalloc ) +{ + HRESULT hresult; + + hresult = OleInitializeWOW( lpMalloc, &g_thkOleThunkWOW ); + + return (DWORD)hresult; +} + +//+--------------------------------------------------------------------------- +// +// Function: RegisterDelayedClassFactories +// +// Synopsis: This function is called to actually do the registration of +// the delayed class factories. +// +// Effects: When the application specific 'trigger' is hit +// (ie OleRegGetUserType for WordPerfect), this routine is +// called to actually do all of the delayed class factory +// registrations. +// +// Arguments: (none) +// +// Requires: +// +// Returns: nothing +// +// History: 4-18-95 kevinro Created +// +//---------------------------------------------------------------------------- +void RegisterDelayedClassFactories() +{ + thkDebugOut((DEB_ITRACE, + "_IN RegisterDelayedClassFactories()\n")); + + PThreadData pdata; + IUnknown *punk; + HRESULT hr; + DelayedRegistrationTable *pTable = NULL; + DelayRegistration *pdelayed; + DWORD dwReg; + + int i; + // + // Get the thread specific data and table to determine if there are + // any delayed registrations. If not, just call the real routine. + // + pdata = TlsThkGetData(); + + if (pdata == NULL) + { + goto exitRtn; + } + + if ((pTable = pdata->pDelayedRegs) == NULL) + { + goto exitRtn; + } + + // + // + // + for (i = 0 ; i < MAX_DELAYED_REGISTRATIONS ; i++) + { + pdelayed = &(pTable->_Entries[i]); + + if((pdelayed->_punk != NULL) && (pdelayed->_dwRealKey == 0)) + { + hr = CoRegisterClassObject(pdelayed->_clsid, + pdelayed->_punk, + pdelayed->_dwClsContext, + pdelayed->_flags, + &(pdelayed->_dwRealKey)); + if (FAILED(hr)) + { + thkDebugOut((DEB_ERROR, + "RegisterDelayedClassFactory gets %x\n",hr)); + } + } + } + +exitRtn: + + thkDebugOut((DEB_ITRACE, + "OUT RegisterDelayedClassFactories()\n")); + +} +//+--------------------------------------------------------------------------- +// +// Function: CoRevokeClassObjectNot +// +// Synopsis: Unregisters a class object that might have been delayed +// +// Effects: The 16-bit API CoRevokeClassObject has been directed to this +// routine. This routine will check the list of interfaces that +// have been registered, and will try to determine if the key +// needs to be translated. +// +// Arguments: [dwKey] -- Key to revoke +// +// History: 4-18-95 kevinro Created +// +// Notes: +// +//---------------------------------------------------------------------------- +HRESULT CoRevokeClassObjectNot( DWORD dwKey) +{ + thkDebugOut((DEB_ITRACE, + "_IN CoRevokeClassObjectNot(dwKey = %x)\n", + dwKey)); + + PThreadData pdata; + IUnknown *punk; + HRESULT hr; + DelayedRegistrationTable *pTable = NULL; + + DWORD dwReg = ~dwKey; + + // + // Get the thread specific data and table to determine if there are + // any delayed registrations. If not, just call the real routine. + // + pdata = TlsThkGetData(); + + if (pdata == NULL) + { + goto exitRtn; + } + + if ((pTable = pdata->pDelayedRegs) == NULL) + { + goto exitRtn; + } + + // + // the 'fake' key is really the bitwise not of the index + // + + if ( dwReg >= MAX_DELAYED_REGISTRATIONS) + { + goto exitRtn; + } + + if(pTable->_Entries[dwReg]._punk != NULL) + { + punk = pTable->_Entries[dwReg]._punk; + pTable->_Entries[dwReg]._punk = NULL; + + dwKey = pTable->_Entries[dwReg]._dwRealKey; + pTable->_Entries[dwReg]._dwRealKey = 0; + + // + // The class object table normally does an addref on the class factory. + // We are also holding an addref on the punk. Release it. + // + if (punk != NULL) + { + punk->Release(); + + // + // If the real key is zero, then we never did actually finish + // the registration. In this case, we return S_OK, because we + // are faking the app out anyway. This might happen if the app + // decides to shutdown for some reason without triggering the + // operation that causes us to register its class objects + // + if (dwKey == 0) + { + hr = S_OK; + goto exitNow; + } + } + } + +exitRtn: + + hr = CoRevokeClassObject(dwKey); + +exitNow: + thkDebugOut((DEB_ITRACE,"OUT CoRevokeClassObjectNot():%x\n",hr)); + return(hr); + +} +//+--------------------------------------------------------------------------- +// +// Function: CoRegisterClassObjectDelayed +// +// Synopsis: Delay the registration of class objects. Some applications, +// such as Word Perfect 6.1, register their class objects then +// do peek message operations BEFORE they are fully initialized. +// This causes problems because we can call in and do +// CreateInstance calls before they are ready for them. This +// wonderful hack will delay the registration of class objects +// until someone calls RegisterClassObjectsNow(), which is +// called when we know it is safe. +// +// Novell knows about this hack, and promised not to change +// the 16-bit code on us. +// +// Effects: Store all of the registration information in an array, and +// return a special key value. +// +// +// Arguments: ( Same as CoRegisterClassObject) +// +// Requires: The associated routine CoUnregisterClassObjectDelayed needs +// to be called in the CoRevokeClassObject path to check to see +// if the key being passed in is a special key. That way we +// can translate the key before calling the real routine. +// +// The special key value is not of the key +// +// Returns: S_OK or E_UNEXPECTED +// +// History: 4-14-95 kevinro Created +// +// Notes: +// +//---------------------------------------------------------------------------- +HRESULT CoRegisterClassObjectDelayed( REFCLSID refclsid, LPUNKNOWN punk, + DWORD dwClsContext, DWORD flags, DWORD *pdwReg) +{ + thkDebugOut((DEB_ITRACE,"_IN CoRegisterClassObjectDelayed\n")); + PThreadData pdata; + int i; + DelayedRegistrationTable *pTable = NULL; + + // + // Assume this is going to fail + // + HRESULT hr = E_UNEXPECTED; + *pdwReg = 0; + + pdata = TlsThkGetData(); + if (pdata == NULL) + { + goto exitRtn; + } + + if ((pTable = pdata->pDelayedRegs) == NULL) + { + pTable = pdata->pDelayedRegs = new DelayedRegistrationTable(); + } + + if (pTable != NULL) + { + for (i = 0 ; i < MAX_DELAYED_REGISTRATIONS ; i++) + { + if(pTable->_Entries[i]._punk == NULL) + { + pTable->_Entries[i]._punk = punk; + pTable->_Entries[i]._clsid = refclsid; + pTable->_Entries[i]._dwClsContext = dwClsContext; + pTable->_Entries[i]._flags = flags; + // + // The class object table normally does an + // addref on the class factory. We will hang on to this + // to keep the class factory and the 3216 proxy alive + // + punk->AddRef(); + *pdwReg = ~i; + hr = S_OK; + break; + } + } + } + +exitRtn: + thkDebugOut((DEB_ITRACE,"OUT CoRegisterClassObjectDelayed() : %x\n",hr)); + return(hr); +} + + +//+--------------------------------------------------------------------------- +// +// Function: CoRegisterClassObjectNot, public +// +// Synopsis: Thunks for the 16-bit applications call CoRegisterClassObject +// Here we check for the registered class objects to set the +// thread's compatability bits. +// +// Arguments: [refclsid] - CLSID for the class to register +// [punk] - ClassFactory interface +// [dwClsContext] - Class context +// [flags] - flags +// [lpdwreg] - register +// +// Returns: Appropriate status code +// +// History: 18-Jul-94 BobDay Created +// +//---------------------------------------------------------------------------- + +EXTERN_C const CLSID CDECL CLSID_EXCEL5_WORKSHEET = + { 0x020810, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}}; + +EXTERN_C const CLSID CDECL CLSID_WORD6_DOCUMENT = + { 0x020900, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}}; + +EXTERN_C const CLSID CDECL CLSID_WPWIN61 = + { 0x89FE3FE3, 0x9FF6, 0x101B, {0xB6, 0x78, 0x04, 0x02, 0x1C, 0x00, 0x70, 0x02}}; + +EXTERN_C const CLSID CDECL CLSID_WPWIN61_FILE = + { 0x1395F281, 0x4326, 0x101b, {0x8B, 0x9A, 0xCE, 0x29, 0x3E, 0xF3, 0x84, 0x49}}; + +EXTERN_C const CLSID CDECL CLSID_IKITARO_130 = + { 0x02B501, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}}; + + +DEFINE_OLEGUID(CLSID_EXCEL5_WORKSHEET, 0x20810, 0, 0); + + + +STDAPI_(DWORD) CoRegisterClassObjectNot( REFCLSID refclsid, LPUNKNOWN punk, + DWORD dwClsContext, DWORD flags, + LPDWORD lpdwreg ) +{ + // + // Excel didn't AddRef the IOleObjectClientSite returned from + // the IOleObject::GetClientSite method. + // + if ( IsEqualCLSID(refclsid,CLSID_EXCEL5_WORKSHEET) ) + { + DWORD dw; + + dw = TlsThkGetAppCompatFlags(); + TlsThkSetAppCompatFlags(dw | OACF_CLIENTSITE_REF); + + thkDebugOut((DEB_WARN,"AppCompatFlag: OACF_CLIENTSITE_REF enabled\n")); + } + + // + // WinWord didn't call OleSetMenuDescriptor(NULL) during + // IOleInPlaceFrame::RemoveMenus. We do it for them. + // + // Also WinWord thinks GDI objects like palettes and bitmaps can be + // transferred on HGLOBALs during GetData calls. In order to thunk + // them properly, we need to patch up the STGMEDIUMS given to use + // by word. This is controlled by OACF_USEGDI. + // + // YAWC: Word chokes and dies because it fails to disconnect some of its + // objects. During shutdown of a link, for example, cleaning up the stdid + // table causes WORD to fault. + // + else if ( IsEqualCLSID(refclsid,CLSID_WORD6_DOCUMENT) ) + { + DWORD dw; + + dw = TlsThkGetAppCompatFlags(); + TlsThkSetAppCompatFlags(dw | OACF_RESETMENU | OACF_USEGDI | OACF_NO_UNINIT_CLEANUP); + + thkDebugOut((DEB_WARN,"AppCompatFlag: OACF_RESETMENU enabled\n")); + thkDebugOut((DEB_WARN,"AppCompatFlag: OACF_USEGDI enabled\n")); + thkDebugOut((DEB_WARN,"AppCompatFlag: OACF_NO_UNINIT_CLEANUP enabled\n")); + } + else if ( IsEqualCLSID(refclsid,CLSID_WPWIN61) ) + { + thkDebugOut((DEB_WARN,"WordPerfect hack triggered\n")); + thkDebugOut((DEB_WARN,"Intercepting CoRegisterClassObject(WPWIN61)\n")); + + return CoRegisterClassObjectDelayed( refclsid,punk,dwClsContext,flags,lpdwreg); + + } + else if ( IsEqualCLSID(refclsid,CLSID_WPWIN61_FILE) ) + { + thkDebugOut((DEB_WARN,"WordPerfect hack triggered\n")); + thkDebugOut((DEB_WARN,"Intercepting CoRegisterClassObject(WPWIN61_FILE)\n")); + return CoRegisterClassObjectDelayed( refclsid,punk,dwClsContext,flags,lpdwreg); + } + else if ( IsEqualCLSID(refclsid,CLSID_IKITARO_130) ) + { + // Note: Ikitaro queries for IViewObject and uses it as IViewObject2 + DWORD dw = TlsThkGetAppCompatFlags(); + thkDebugOut((DEB_WARN,"Ikitaro hack triggered\n")); + TlsThkSetAppCompatFlags(dw | OACF_IVIEWOBJECT2); + } + + return (DWORD)CoRegisterClassObject( refclsid, punk, dwClsContext, + flags, lpdwreg ); +} + + +//+--------------------------------------------------------------------------- +// +// Function: OleRegGetUserTypeNot +// +// Synopsis: Adds a hook for a WordPerfect hack. Check out the functions +// CoRegisterClassObjectDelayed and +// RegisterDelayedClassFactories for details. In essence, when +// this function is called for the WPWIN61 classID, we know +// that it is safe to register all of the delayed class objects. +// This determination was done by debugging Wordperfect. When +// they call this API, then are actually done initializing the +// internals of their app. +// +// Effects: +// +// History: 4-18-95 kevinro Created +// +// Notes: +// +//---------------------------------------------------------------------------- +STDAPI_(DWORD) +OleRegGetUserTypeNot(REFCLSID clsid,DWORD dwFormOfType,LPOLESTR *pszUserType) +{ + // + // Wordperfect has a bug. When they call OleRegGetUserType for their + // classid, we know that it is safe to register their class objects for + // real. + // + // See CoRegisterClassObjectDelayed for details + // + if ( IsEqualCLSID(clsid,CLSID_WPWIN61) ) + { + thkDebugOut((DEB_WARN,"Registering WordPerfects class objects\n")); + RegisterDelayedClassFactories(); + } + return OleRegGetUserType(clsid,dwFormOfType,pszUserType); +} +//+--------------------------------------------------------------------------- +// +// Member: OleThunkWOW::LoadProcDll, public +// +// Synopsis: Callback function for 32-bit OLE to load a 16-bit DLL +// +// Arguments: [pszDllName] - Name of 16-bit DLL +// [lpvpfnGetClassObject] - returned 16:16 address of +// "DllGetClassObject" +// [lpvpfnCanUnloadNow] - returned 16:16 address of +// "DllCanUnloadNow" +// [lpvhmodule] - returned 16-bit hmodule +// +// Returns: Appropriate status code +// +// History: 11-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +STDMETHODIMP +OleThunkWOW::LoadProcDll( + LPCTSTR pszDllName, + LPDWORD lpvpfnGetClassObject, + LPDWORD lpvpfnCanUnloadNow, + LPDWORD lpvhmodule +) +{ + HRESULT hr; + UINT uiSize; + VPSTR vpstr16; + VPVOID vplpds16; + LOADPROCDLLSTRUCT UNALIGNED *lplpds16; + + uiSize = lstrlen(pszDllName) + 1; + + vpstr16 = STACKALLOC16(uiSize*sizeof(TCHAR)); + if (vpstr16 == 0) + { + hr = E_OUTOFMEMORY; + goto Exit; + } + +#ifndef _CHICAGO_ + hr = Convert_LPOLESTR_to_VPSTR(pszDllName, vpstr16, + uiSize, uiSize*sizeof(TCHAR)); +#else + hr = Convert_LPSTR_to_VPSTR(pszDllName, vpstr16, + uiSize, uiSize*sizeof(TCHAR)); +#endif + + if (FAILED(hr)) + { + goto EH_vpstr16; + } + + vplpds16 = STACKALLOC16(sizeof(LOADPROCDLLSTRUCT)); + if (vplpds16 == 0) + { + hr = E_OUTOFMEMORY; + goto EH_vpstr16; + } + + lplpds16 = FIXVDMPTR(vplpds16, LOADPROCDLLSTRUCT); + + lplpds16->vpDllName = vpstr16; + lplpds16->vpfnGetClassObject = 0; + lplpds16->vpfnCanUnloadNow = 0; + lplpds16->vhmodule = 0; + + RELVDMPTR(vplpds16); + + hr = CallbackTo16( gdata16Data.fnLoadProcDll, vplpds16 ); + + if (SUCCEEDED(hr)) + { + lplpds16 = FIXVDMPTR(vplpds16, LOADPROCDLLSTRUCT); + *lpvpfnGetClassObject = lplpds16->vpfnGetClassObject; + *lpvpfnCanUnloadNow = lplpds16->vpfnCanUnloadNow; + *lpvhmodule = lplpds16->vhmodule; + RELVDMPTR(vplpds16); + } + else + { + hr = CO_E_DLLNOTFOUND; + } + + STACKFREE16(vplpds16, sizeof(LOADPROCDLLSTRUCT)); + + EH_vpstr16: + STACKFREE16(vpstr16,uiSize*sizeof(TCHAR)); + + Exit: + return hr; +} + +//+--------------------------------------------------------------------------- +// +// Member: OleThunkWOW::UnloadProcDll, public +// +// Synopsis: Callback function for 32-bit OLE to unload a 16-bit DLL +// +// Arguments: [vhmodule] - 16-bit hmodule +// +// Returns: Appropriate status code +// +// History: 11-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +STDMETHODIMP +OleThunkWOW::UnloadProcDll( + DWORD vhmodule +) +{ + return CallbackTo16( gdata16Data.fnUnloadProcDll, vhmodule ); +} + +//+--------------------------------------------------------------------------- +// +// Member: OleThunkWOW::CallGetClassObject, public +// +// Synopsis: Callback function for 32-bit OLE to call 16-bit +// DllGetClassObject +// +// Arguments: [vpfnGetClassObject] - 16:16 address of DllGetClassObject +// [rclsid] - CLSID of object +// [riid] - IID of interface on object +// [ppv] - returned object interface +// +// Returns: Appropriate status code +// +// History: 11-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +STDMETHODIMP +OleThunkWOW::CallGetClassObject( + DWORD vpfnGetClassObject, + REFCLSID rclsid, + REFIID riid, + LPVOID FAR *ppv +) +{ + DWORD dwResult; + VPVOID vpcgcos16; + CALLGETCLASSOBJECTSTRUCT UNALIGNED *lpcgcos16; + VPVOID iface16; + IIDIDX iidx; + IUnknown *punkThis32; + CThkMgr *pThkMgr; + ThreadData *ptd; + + ptd = TlsThkGetData(); + if (ptd == NULL) + { + thkDebugOut((DEB_WARN, "WARNING: CallGetClassObject refused\n")); + + dwResult = (DWORD)E_FAIL; + goto Exit; + } + pThkMgr = ptd->pCThkMgr; + + vpcgcos16 = STACKALLOC16(sizeof(CALLGETCLASSOBJECTSTRUCT)); + if (vpcgcos16 == 0) + { + dwResult = (DWORD)E_OUTOFMEMORY; + goto Exit; + } + + lpcgcos16 = FIXVDMPTR(vpcgcos16, CALLGETCLASSOBJECTSTRUCT); + + lpcgcos16->vpfnGetClassObject = vpfnGetClassObject; + lpcgcos16->clsid = rclsid; + lpcgcos16->iid = riid; + lpcgcos16->iface = 0; + + RELVDMPTR(vpcgcos16); + + dwResult = CallbackTo16( gdata16Data.fnCallGetClassObject, vpcgcos16 ); + + if ( SUCCEEDED(dwResult) ) + { + lpcgcos16 = FIXVDMPTR(vpcgcos16, CALLGETCLASSOBJECTSTRUCT); + iface16 = lpcgcos16->iface; + + iidx = IidToIidIdx(riid); + + // We're on the way out creating a proxy so set the state + // appropriately + pThkMgr->SetThkState(THKSTATE_INVOKETHKOUT32); + + // Get a 32-bit proxy object for the 16-bit object + punkThis32 = pThkMgr->FindProxy3216(NULL, iface16, iidx, NULL); + + pThkMgr->SetThkState(THKSTATE_NOCALL); + + // Set the out param + *(IUnknown **)ppv = punkThis32; + + if (punkThis32 == NULL) + { + // Release the class object we just retrieved + ReleaseOnObj16(iface16); + + dwResult = (DWORD)E_OUTOFMEMORY; + } + + RELVDMPTR(vpcgcos16); + } + + STACKFREE16(vpcgcos16, sizeof(CALLGETCLASSOBJECTSTRUCT)); + + Exit: + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Member: OleThunkWOW::CallCanUnloadNow, public +// +// Synopsis: Callback function for 32-bit OLE to call 16-bit +// CanUnloadNow +// +// Arguments: [vpfnCanUnloadNow] - 16:16 address of DllCanUnloadNow +// +// Returns: Appropriate status code +// +// History: 11-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +STDMETHODIMP OleThunkWOW::CallCanUnloadNow( + DWORD vpfnCanUnloadNow) +{ + return CallbackTo16( gdata16Data.fnCallCanUnloadNow, vpfnCanUnloadNow ); +} + +//+--------------------------------------------------------------------------- +// +// Member: OleThunkWOW::GetThunkManager, public +// +// Synopsis: Callback function for 32-bit OLE to retrieve the thunkmanager +// +// Arguments: [ppThkMgr] - Thunk manager return +// +// Returns: Appropriate status code +// +// History: 11-May-94 JohannP Created +// +//---------------------------------------------------------------------------- + +STDMETHODIMP OleThunkWOW::GetThunkManager(IThunkManager **ppThkMgr) +{ + thkDebugOut((DEB_THUNKMGR, "%sIn OleThunkWOW::GetThunkManager\n", + NestingLevelString())); + + thkAssert(ppThkMgr != NULL); + + IUnknown *pUnk = TlsThkGetThkMgr(); + thkAssert(pUnk && "Invalid Thunkmanager"); + + *ppThkMgr = (IThunkManager *)pUnk; + pUnk->AddRef(); + + thkDebugOut((DEB_THUNKMGR, "%sOut OleThunkWOW::GetThunkManager: (%p)\n", + NestingLevelString(), pUnk)); + + return NOERROR; +} + +//+--------------------------------------------------------------------------- +// +// Member: OleThunkWOW::WinExec16, public +// +// Synopsis: Callback function for 32-bit OLE to run an application +// +// Arguments: [pszCommandLine] - command line for WinExec +// [usShow] - fShow for WinExec +// +// Returns: Appropriate status code +// +// History: 27-Jul-94 AlexT Created +// +//---------------------------------------------------------------------------- + +STDMETHODIMP OleThunkWOW::WinExec16( + LPCOLESTR pszCommandLine, + USHORT usShow +) +{ + HRESULT hr; + UINT uiSize; + VPSTR vpstr16; + VPVOID vplpds16; + WINEXEC16STRUCT UNALIGNED *lpwes16; + ULONG ulRet; + + uiSize = lstrlenW(pszCommandLine) + 1; + + vpstr16 = STACKALLOC16(uiSize*2); + if (vpstr16 == 0) + { + hr = E_OUTOFMEMORY; + goto Exit; + } + + hr = Convert_LPOLESTR_to_VPSTR(pszCommandLine, vpstr16, + uiSize, uiSize*2); + if (FAILED(hr)) + { + goto EH_vpstr16; + } + + vplpds16 = STACKALLOC16(sizeof(WINEXEC16STRUCT)); + if (vplpds16 == 0) + { + hr = E_OUTOFMEMORY; + goto EH_vpstr16; + } + + lpwes16 = FIXVDMPTR(vplpds16, WINEXEC16STRUCT); + + lpwes16->vpCommandLine = vpstr16; + lpwes16->vusShow = usShow; + + RELVDMPTR(vplpds16); + + ulRet = CallbackTo16( gdata16Data.fnWinExec16, vplpds16 ); + thkDebugOut((DEB_ITRACE, + "CallbackTo16(WinExec16) returned %ld\n", ulRet)); + + // According to the Windows spec, return values greater than 31 indicate + // success. + + if (ulRet > 31) + { + hr = S_OK; + } + else if (0 == ulRet) + { + // 0 indicates lack of some kind of resource + hr = E_OUTOFMEMORY; + } + else + { + hr = HRESULT_FROM_WIN32(ulRet); + } + + STACKFREE16(vplpds16, sizeof(WINEXEC16STRUCT)); + + EH_vpstr16: + STACKFREE16(vpstr16, uiSize*2); + + Exit: + return hr; +} + + +//+--------------------------------------------------------------------------- +// +// Method: OleThunkWOW::ConvertHwndToFullHwnd +// +// Synopsis: Converts a 16 bit HWND into a 32-bit HWND +// +// Effects: Since OLE32 doesn't directly link to WOW, this function allows +// the DDE layer to access the routine that maps 16 bit HWND to +// full 32-bit HWND's. +// +// Arguments: [hwnd] -- HWND to convert +// +// History: 8-03-94 kevinro Created +// +// Notes: +// +//---------------------------------------------------------------------------- +STDMETHODIMP_(HWND) OleThunkWOW::ConvertHwndToFullHwnd(HWND hwnd) +{ + return(FULLHWND_32((USHORT)hwnd)); +} + +//+--------------------------------------------------------------------------- +// +// Method: OleThunkWOW::FreeMetaFile +// +// Synopsis: Calls wow to delete a metafile that has memory reserved in +// the 16 bit address space +// +// Effects: Since OLE32 doesn't directly link to WOW, this function allows +// the DDE layer to access the routine in WOW +// +// Arguments: [hmf] -- HANDLE to delete +// +// History: 8-03-94 kevinro Created +// +// Notes: +// +//---------------------------------------------------------------------------- +STDMETHODIMP_(BOOL) OleThunkWOW::FreeMetaFile(HANDLE hmf) +{ + return(WOWFreeMetafile(hmf)); +} + + + +//+--------------------------------------------------------------------------- +// +// Member: OleThunkWOW::YieldTask16, public +// +// Synopsis: Callback function for 32-bit OLE to yield +// +// History: 08-Aug-94 Ricksa Created +// +//---------------------------------------------------------------------------- +STDMETHODIMP OleThunkWOW::YieldTask16(void) +{ + WOWYield16(); + return S_OK; +} + + +//+--------------------------------------------------------------------------- +// +// Member: OleThunkWOW::DirectedYield, public +// +// Synopsis: Does a directed yield in the VDM. +// +// History: 08-Aug-94 Rickhi Created +// +//---------------------------------------------------------------------------- +STDMETHODIMP OleThunkWOW::DirectedYield(DWORD dwCalleeTID) +{ + WORD hTask16 = WOWHandle16((void *)dwCalleeTID, WOW_TYPE_HTASK); + + thkDebugOut((DEB_ITRACE, "WOWDirectedYield16(%x)\n", hTask16)); + + WOWDirectedYield16(hTask16); + + thkDebugOut((DEB_ITRACE, "WOWDirectedYield16() returned\n")); + + return S_OK; +} + +//+--------------------------------------------------------------------------- +// +// Method: OleThunkWOW::PrepareForCleanup +// +// Synopsis: Prepares OLETHK32 for OLE32.DLL's cleanup. +// +// Effects: It does this by taking all of the remaining 3216 proxies +// and marking them such that no callbacks into the 16-bit +// world are possible. +// +// Arguments: -none- +// +// History: 24-Aug-94 bobday Created +// +// Notes: +// +//---------------------------------------------------------------------------- +STDMETHODIMP_(void) OleThunkWOW::PrepareForCleanup(void) +{ + CThkMgr *pcthkmgr; + + if ( TlsThkGetData() != NULL ) + { + pcthkmgr = (CThkMgr*)TlsThkGetThkMgr(); + + // + // Tell the thkmgr to prepare for cleaning itself up + // + pcthkmgr->PrepareForCleanup(); + } +} + + +//+--------------------------------------------------------------------------- +// +// Method: OleThunkWOW::GetAppCompatibilityFlags +// +// Synopsis: Used to return the current THK app compatibility flags to +// OLE32.DLL +// Arguments: [void] -- +// +// Requires: +// +// Returns: Flags defined in ih\thunkapi.hxx +// +// History: 1-11-96 kevinro Created +// +//---------------------------------------------------------------------------- +STDMETHODIMP_(DWORD) OleThunkWOW::GetAppCompatibilityFlags(void) +{ + return(TlsThkGetAppCompatFlags()); +} diff --git a/private/ole32/olethunk/olethk32/apinot.hxx b/private/ole32/olethunk/olethk32/apinot.hxx new file mode 100644 index 000000000..be02e1e45 --- /dev/null +++ b/private/ole32/olethunk/olethk32/apinot.hxx @@ -0,0 +1,25 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: apinot.hxx +// +// Contents: Function header for thunks which are not direct APIs +// +// History: 11-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +#ifndef __APINOT_HXX__ +#define __APINOT_HXX__ + +STDAPI_(DWORD) OleRegGetUserTypeNot(REFCLSID clsid,DWORD dwFormOfType,LPOLESTR *pszUserType); +STDAPI_(DWORD) CoInitializeNot( LPMALLOC lpMalloc ); +STDAPI_(DWORD) OleInitializeNot( LPMALLOC lpMalloc ); +STDAPI_(DWORD) CoRegisterClassObjectNot( REFCLSID refclsid, LPUNKNOWN punk, + DWORD dwClsContext, DWORD flags, + LPDWORD lpdwreg ); +STDAPI CoRevokeClassObjectNot( DWORD dwKey ); + +#endif // #ifndef __APINOT_HXX__ diff --git a/private/ole32/olethunk/olethk32/cthkmgr.cxx b/private/ole32/olethunk/olethk32/cthkmgr.cxx new file mode 100644 index 000000000..1753c56c4 --- /dev/null +++ b/private/ole32/olethunk/olethk32/cthkmgr.cxx @@ -0,0 +1,3031 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: cthkmgr.cxx +// +// Contents: cthunkmanager for an apartment +// +// Classes: CThkMgr derived from IThunkManager +// +// Functions: +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +#include "headers.cxx" +#pragma hdrstop +#include <olepfn.hxx> +#if DBG == 1 +BOOL fDebugDump = FALSE; +#define DBG_DUMP(x) if (fDebugDump) { x; } +#else +#define DBG_DUMP(x) +#endif + +#define PprxNull(pprx) ((pprx).dwPtrVal = 0) +#define PprxIsNull(pprx) ((pprx).dwPtrVal == 0) +#define Pprx16(vpv) PROXYPTR((DWORD)vpv, PPRX_16) +#define Pprx32(pto) PROXYPTR((DWORD)pto, PPRX_32) + +//+--------------------------------------------------------------------------- +// +// Function: ResolvePprx, public +// +// Synopsis: Converts a PROXYPTR to a CProxy * +// +// Arguments: [ppprx] - PROXYPTR +// +// Returns: Pointer or NULL +// +// History: 15-Jul-94 DrewB Created +// +//---------------------------------------------------------------------------- + +CProxy *ResolvePprx(PROXYPTR *ppprx) +{ + if (ppprx->wType == PPRX_32) + { + return (CProxy *)ppprx->dwPtrVal; + } + else + { + // Get a pointer to all of the proxy rather than just the CProxy part + return FIXVDMPTR(ppprx->dwPtrVal, THUNK1632OBJ); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: ReleasePprx, public +// +// Synopsis: Releases a resolved PROXYPTR +// +// Arguments: [ppprx] - PROXYPTR +// +// History: 10-Oct-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void ReleasePprx(PROXYPTR *ppprx) +{ + if (ppprx->wType == PPRX_16) + { + RELVDMPTR(ppprx->dwPtrVal); + } +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::NewHolder, public +// +// Synopsis: Creates a new proxy holder +// +// Arguments: [dwFlags] - Flags +// +// Returns: Holder or NULL +// +// History: 16-Jul-94 DrewB Created +// +//---------------------------------------------------------------------------- + +PROXYHOLDER *CThkMgr::NewHolder(DWORD dwFlags) +{ + PROXYHOLDER *pph; + + thkDebugOut((DEB_THUNKMGR, "In CThkMgr::NewHolder(0x%X)\n", + dwFlags)); + + pph = (PROXYHOLDER *)flHolderFreeList.AllocElement(); + if (pph == NULL) + { + goto Exit; + } + + pph->dwFlags = dwFlags; + + // Start out without any listed proxies + pph->cProxies = 0; + PprxNull(pph->pprxProxies); + + // Add to list of holders + pph->pphNext = _pphHolders; + _pphHolders = pph; + + Exit: + thkDebugOut((DEB_THUNKMGR, "Out CThkMgr::NewHolder => %p\n", + pph)); + + return pph; +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::AddProxyToHolder, public +// +// Synopsis: Adds a new proxy to a holder +// +// Arguments: [pph] - Holder +// [pprxReal] - Proxy +// [pprx] - Abstract pointer +// +// History: 07-Jul-94 DrewB Extracted +// +//---------------------------------------------------------------------------- + +void CThkMgr::AddProxyToHolder(PROXYHOLDER *pph,CProxy *pprxReal, + PROXYPTR &pprx) +{ + thkDebugOut((DEB_THUNKMGR, "In AddProxyToHolder(%p, %p) cProxies %d\n", + pph, pprx.dwPtrVal, pph->cProxies)); + + thkAssert(ResolvePprx(&pprx) == pprxReal && + (ReleasePprx(&pprx), TRUE)); + + // Bump count of held proxies + AddRefHolder(pph); + + // Add proxy into list of object proxies + thkAssert(PprxIsNull(pprxReal->pprxObject)); + pprxReal->pprxObject = pph->pprxProxies; + pph->pprxProxies = pprx; + + thkAssert(pprxReal->pphHolder == NULL); + pprxReal->pphHolder = pph; + + thkDebugOut((DEB_THUNKMGR, "out AddProxyToHolder(%p, %p) cProxies %d\n", + pph, pprx.dwPtrVal, pph->cProxies)); +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::AddRefHolder, public +// +// Synopsis: Increments the proxy count for a holder +// +// Arguments: [pph] - Holder +// +// History: 07-Jul-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CThkMgr::AddRefHolder(PROXYHOLDER *pph) +{ + pph->cProxies++; + + thkDebugOut((DEB_THUNKMGR, "AddRefHolder(%p) cProxies %d\n", + pph, pph->cProxies)); +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::ReleaseHolder, public +// +// Synopsis: Releases a proxy reference on the holder +// Cleans up the holder if it was the last reference +// +// Arguments: [pph] - Holder +// +// History: 06-21-94 JohannP Created ReleaseAggregateProxies +// 07-Jul-94 DrewB Modified +// +//---------------------------------------------------------------------------- + +void CThkMgr::ReleaseHolder(PROXYHOLDER *pph) +{ + PROXYHOLDER *pphTmp, *pphPrev; + + thkDebugOut((DEB_THUNKMGR, "ReleaseHolder(%p) pre cProxies %d\n", + pph, pph->cProxies)); + + thkAssert(pph->cProxies > 0); + + // Decrement the holder's proxy count + pph->cProxies--; + + if (pph->cProxies == 0) + { + CProxy *pprxReal; + PROXYPTR pprx, pprxNext; + + // All interfaces for the object have been freed so we can + // clean up the object + + pprx = pph->pprxProxies; + while (!PprxIsNull(pprx)) + { + pprxReal = ResolvePprx(&pprx); + pprxNext = pprxReal->pprxObject; + + thkAssert(pprxReal->cRefLocal == 0); + thkAssert(pprxReal->pphHolder == pph); + + if (pprx.wType == PPRX_16) + { + // Releases pointer + RemoveProxy1632((VPVOID)pprx.dwPtrVal, + (THUNK1632OBJ *)pprxReal); + } + else + { + RemoveProxy3216((THUNK3216OBJ *)pprxReal); + } + + pprx = pprxNext; + } + + // Remove holder from list + + pphPrev = NULL; + for (pphTmp = _pphHolders; + pphTmp && pphTmp != pph; + pphPrev = pphTmp, pphTmp = pphTmp->pphNext) + { + NULL; + } + + // If we didn't find the holder in the holder list then our + // list is trashed + thkAssert(pphTmp == pph); + + if (pphPrev == NULL) + { + _pphHolders = pph->pphNext; + } + else + { + pphPrev->pphNext = pph->pphNext; + } + + flHolderFreeList.FreeElement((DWORD)pph); + } +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::Create +// +// Synopsis: static member - creates complete thunkmanager +// +// Arguments: [void] -- +// +// Returns: pointer to cthkmgr +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +// Notes: +// +//---------------------------------------------------------------------------- +CThkMgr *CThkMgr::Create(void) +{ + CThkMgr *pcthkmgr = NULL; + CMapDwordPtr *pPT1632 = new CMapDwordPtr(MEMCTX_TASK); + CMapDwordPtr *pPT3216 = new CMapDwordPtr(MEMCTX_TASK); + + if ( (pPT1632 != NULL) + && (pPT3216 != NULL) + && (pcthkmgr = new CThkMgr( pPT1632, pPT3216 )) ) + { + // install the new thunkmanager + TlsThkSetThkMgr(pcthkmgr); + } + else + { + if (pPT1632) + { + delete pPT1632; + } + if (pPT3216) + { + delete pPT3216; + } + } + return pcthkmgr; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::CThkMgr +// +// Synopsis: private constructor - called by Create +// +// Arguments: [pPT1632] -- 16/32 proxy table +// [pPT3216] -- 32/16 proxy table +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +CThkMgr::CThkMgr(CMapDwordPtr *pPT1632, + CMapDwordPtr *pPT3216) + +{ + _cRefs = 1; + _thkstate = THKSTATE_NOCALL; + _piidnode = NULL; + + _pProxyTbl1632 = pPT1632; + _pProxyTbl3216 = pPT3216; + + _pphHolders = NULL; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::~CThkMgr +// +// Synopsis: destructor +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +CThkMgr::~CThkMgr() +{ + PROXYHOLDER *pph; + PIIDNODE pin; + + thkDebugOut((DEB_ITRACE, "_IN CThkMgr::~CThkMgr()\n")); + + RemoveAllProxies(); + delete _pProxyTbl1632; + delete _pProxyTbl3216; + + // Clean up IID requests +#if DBG == 1 + if (_piidnode != NULL) + { + thkDebugOut((DEB_WARN, "WARNING: IID requests active at shutdown\n")); + } +#endif + + while (_piidnode != NULL) + { + pin = _piidnode->pNextNode; + + thkDebugOut((DEB_IWARN, "IID request leak: %p {%s}\n", + _piidnode, IidOrInterfaceString(_piidnode->piid))); + + flRequestFreeList.FreeElement((DWORD)_piidnode); + + _piidnode = pin; + } + +#if DBG == 1 + if (_pphHolders != NULL) + { + thkDebugOut((DEB_WARN, "WARNING: Proxy holders active at shutdown\n")); + } +#endif + + // Clean up any proxy holders + while (_pphHolders) + { + pph = _pphHolders->pphNext; + + thkDebugOut((DEB_IWARN, "Proxy holder leak: %p {%d, 0x%X}\n", + _pphHolders, _pphHolders->cProxies, + _pphHolders->dwFlags)); + + flHolderFreeList.FreeElement((DWORD)_pphHolders); + + _pphHolders = pph; + } + thkDebugOut((DEB_ITRACE, "OUT CThkMgr::~CThkMgr()\n")); +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::RemoveAllProxies, public +// +// Synopsis: Removes all live proxies from the proxy tables +// +// History: 01-Dec-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CThkMgr::RemoveAllProxies(void) +{ + POSITION pos; + DWORD dwKey; + VPVOID vpv; + + thkDebugOut((DEB_ITRACE, "_IN CThkMgr::RemoveAllProxies()\n")); + + // Make sure that we disable 3216 proxies first to guard against calling + // back into 16 bit land. + +#if DBG == 1 + DWORD dwCount; + + dwCount = _pProxyTbl3216->GetCount(); + + if (dwCount > 0) + { + thkDebugOut((DEB_WARN, "WARNING: %d 3216 proxies left\n", dwCount)); + } +#endif + + // delete the 3216 proxy table + while (pos = _pProxyTbl3216->GetStartPosition()) + { + THUNK3216OBJ *pto3216; + + _pProxyTbl3216->GetNextAssoc(pos, dwKey, (void FAR* FAR&) pto3216); + + thkDebugOut((DEB_IWARN, "3216: %p {%d,%d, %p, %p} %s\n", + pto3216, pto3216->cRefLocal, pto3216->cRef, + pto3216->vpvThis16, pto3216->pphHolder, + IidIdxString(pto3216->iidx))); + + pto3216->grfFlags |= PROXYFLAG_CLEANEDUP; + + RemoveProxy3216(pto3216); + } + +#if DBG == 1 + dwCount = _pProxyTbl1632->GetCount(); + + if (dwCount > 0) + { + thkDebugOut((DEB_WARN, "WARNING: %d 1632 proxies left\n", dwCount)); + } +#endif + + // delete the 1632 proxy table + while (pos = _pProxyTbl1632->GetStartPosition()) + { + THUNK1632OBJ *pto1632; + + _pProxyTbl1632->GetNextAssoc(pos, dwKey, (void FAR* FAR&) vpv); + + pto1632 = FIXVDMPTR(vpv, THUNK1632OBJ); + +#if DBG == 1 + thkDebugOut((DEB_IWARN, "1632: %p {%d,%d, %p, %p} %s\n", + vpv, pto1632->cRefLocal, pto1632->cRef, + pto1632->punkThis32, pto1632->pphHolder, + IidIdxString(pto1632->iidx))); +#endif + // + // Determine if this is a 'special' object that we know we want + // to release. If it is, then remove all of the references this + // proxy has on it. + // + if (CoQueryReleaseObject(pto1632->punkThis32) == NOERROR) + { + thkDebugOut((DEB_WARN, + "1632: %p is recognized Releasing object %d times\n", + pto1632->punkThis32,pto1632->cRef)); + + while (pto1632->cRef) + { + IUnknown *punk; + + pto1632->cRef--; + punk = pto1632->punkThis32; + + RELVDMPTR(vpv); + + if (punk->Release() == 0) + { + break; + } + + pto1632 = FIXVDMPTR(vpv, THUNK1632OBJ); + } + } + + // Releases pointer + RemoveProxy1632(vpv, pto1632); + } + + thkDebugOut((DEB_ITRACE, "OUT CThkMgr::RemoveAllProxies()\n")); +} + +// *** IUnknown methods *** +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::QueryInterface +// +// Synopsis: QueryInterface on the thunkmanager itself +// +// Arguments: [riid] -- IID of interface to return +// [ppvObj] -- Interface return +// +// Returns: HRESULT +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +STDMETHODIMP CThkMgr::QueryInterface (REFIID riid, LPVOID FAR* ppvObj) +{ + if (IsBadWritePtr(ppvObj, sizeof(void *))) + { + return E_INVALIDARG; + } + + *ppvObj = NULL; + + // There is no IID_IThunkManager because nobody needs it + + if (IsEqualIID(riid, IID_IUnknown)) + { + *ppvObj = (IUnknown *) this; + AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +//+--------------------------------------------------------------------------- +// +// Methode: CThkMgr::AddRef +// +// Synopsis: Adds a reference +// +// Returns: New ref count +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +STDMETHODIMP_(ULONG) CThkMgr::AddRef () +{ + InterlockedIncrement( &_cRefs ); + return _cRefs; +} + +//+--------------------------------------------------------------------------- +// +// Methode: CThkMgr::Release +// +// Synopsis: Releases a reference +// +// Returns: New ref count +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +STDMETHODIMP_(ULONG) CThkMgr::Release() +{ + if (InterlockedDecrement( &_cRefs ) == 0) + { + + return 0; + } + return _cRefs; +} + +// *** IThunkManager methods *** +// +// +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::IsIIDRequested +// +// Synopsis: checks if given refiid was requested by WOW +// +// Arguments: [riid] -- refiid +// +// Returns: true if requested by 16 bit +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +STDMETHODIMP_ (BOOL) CThkMgr::IsIIDRequested(REFIID riid) +{ + PIIDNODE piidnode = _piidnode; + BOOL fRet = FALSE; + + while (piidnode) + { + if (*piidnode->piid == riid) + { + fRet = TRUE; + break; + } + + piidnode = piidnode->pNextNode; + } + + thkDebugOut((DEB_THUNKMGR, "IsIIDRequested(%s) => %d\n", + GuidString(&riid), fRet)); + + return fRet; +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::IsCustom3216Proxy, public +// +// Synopsis: Attempts to identify the given IUnknown as a 32->16 proxy +// and also checks whether it is a thunked interface or not +// +// Arguments: [punk] - Object +// +// Returns: BOOL +// +// History: 11-Jul-94 DrewB Created +// +//---------------------------------------------------------------------------- + +STDMETHODIMP_(BOOL) CThkMgr::IsCustom3216Proxy(IUnknown *punk, + REFIID riid) +{ + return !IsIIDSupported(riid) && IsProxy3216(punk) != 0; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::IsIIDSupported +// +// Synopsis: Return whether the given interface is thunked or not +// +// Arguments: [riid] -- Interface +// +// Returns: BOOL +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +BOOL CThkMgr::IsIIDSupported(REFIID riid) +{ + return IIDIDX_IS_INDEX(IidToIidIdx(riid)); +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::AddIIDRequest +// +// Synopsis: adds the refiid to the request list +// +// Arguments: [riid] -- Interface +// +// Returns: true on success +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +BOOL CThkMgr::AddIIDRequest(REFIID riid) +{ + PIIDNODE piidnode = _piidnode; + + thkAssert(!IsIIDSupported(riid)); + + // create a new node and add at front + piidnode = (PIIDNODE)flRequestFreeList.AllocElement(); + if (piidnode == NULL) + { + return FALSE; + } + + piidnode->pNextNode = _piidnode; + _piidnode = piidnode; + + // IID requests are only valid for the lifetime of the call that + // requested a custom interface, so there's no need to copy + // the IID's memory since it must remain valid for the same time + // period + piidnode->piid = (IID *)&riid; + + thkDebugOut((DEB_THUNKMGR, "AddIIDRequest(%s)\n", GuidString(&riid))); + + return TRUE; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::RemoveIIDRequest +// +// Synopsis: removes a request for the request list +// +// Arguments: [riid] -- Interface +// +// Returns: true on success +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +void CThkMgr::RemoveIIDRequest(REFIID riid) +{ + PIIDNODE piidnode; + PIIDNODE pinPrev; + + thkAssert(!IsIIDSupported(riid)); + + pinPrev = NULL; + piidnode = _piidnode; + while (piidnode) + { + if (*piidnode->piid == riid) + { + break; + } + + pinPrev = piidnode; + piidnode = piidnode->pNextNode; + } + + thkAssert(piidnode != NULL && "RemoveIIDRequest: IID not found"); + + thkDebugOut((DEB_THUNKMGR, "RemoveIIDRequest(%s)\n", GuidString(&riid))); + + if (pinPrev == NULL) + { + _piidnode = piidnode->pNextNode; + } + else + { + pinPrev->pNextNode = piidnode->pNextNode; + } + + flRequestFreeList.FreeElement((DWORD)piidnode); +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::CanGetNewProxy1632 +// +// Synopsis: Preallocates proxy memory +// +// Arguments: [iidx] - Custom interface or known index +// +// Returns: vpv pointer if proxy is available, fails otherwise +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +VPVOID CThkMgr::CanGetNewProxy1632(IIDIDX iidx) +{ + VPVOID vpv; + THUNK1632OBJ UNALIGNED *pto; + + thkDebugOut((DEB_THUNKMGR, "%sIn CanGetNewProxy1632(%s)\n", + NestingLevelString(), IidIdxString(iidx))); + + // Allocate proxy memory + vpv = (VPVOID)flFreeList16.AllocElement(); + if (vpv == NULL) + { + thkDebugOut((DEB_WARN, "WARNING: Failed to allocate memory " + "for 16-bit proxies\n")); + goto Exit; + } + + // Add custom interface request if necessary + if (vpv && IIDIDX_IS_IID(iidx)) + { + // add the request for the unknown interface + if ( !AddIIDRequest(*IIDIDX_IID(iidx)) ) + { + flFreeList16.FreeElement( (DWORD)vpv ); + vpv = 0; + } + } + + // Set up the preallocated proxy as a temporary proxy so that + // we can hand it out for nested callbacks + pto = FIXVDMPTR(vpv, THUNK1632OBJ); + thkAssert(pto != NULL); + + pto->pfnVtbl = gdata16Data.atfnProxy1632Vtbl; + pto->cRefLocal = 0; + pto->cRef = 0; + pto->iidx = iidx; + pto->punkThis32 = NULL; + pto->pphHolder = NULL; + PprxNull(pto->pprxObject); + pto->grfFlags = PROXYFLAG_TEMPORARY; +#if DBG == 1 + // Deliberately make this an invalid proxy. We want it to be used + // in as few places as possible + pto->dwSignature = PSIG1632TEMP; +#endif + + RELVDMPTR(vpv); + + Exit: + thkDebugOut((DEB_THUNKMGR, "%sOut CanGetNewProxy1632: %p\n", + NestingLevelString(), vpv)); + + return vpv; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::FreeNewProxy1632 +// +// Synopsis: frees unused preallocated proxies +// +// Arguments: [iidx] - Custom interface or known index +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +void CThkMgr::FreeNewProxy1632(VPVOID vpv, IIDIDX iidx) +{ + thkDebugOut((DEB_THUNKMGR, "%sIn FreeNewProxy1632(%s)\n", + NestingLevelString(), IidIdxString(iidx))); + + thkAssert(vpv != 0); + + if (IIDIDX_IS_IID(iidx)) + { + // remove the request for the unknown interface + RemoveIIDRequest(*IIDIDX_IID(iidx)); + } + +#if DBG == 1 + // Ensure that we're not getting rid of a temporary proxy that's + // in use + THUNK1632OBJ UNALIGNED *pto; + + pto = FIXVDMPTR(vpv, THUNK1632OBJ); + if (pto->grfFlags & PROXYFLAG_TEMPORARY) + { + thkAssert(pto->cRefLocal == 0 && pto->cRef == 0); + } + RELVDMPTR(vpv); +#endif + + // add element to free list + flFreeList16.FreeElement( (DWORD)vpv ); + + thkDebugOut((DEB_THUNKMGR, "%sOut FreeNewProxy1632\n", + NestingLevelString())); +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::IsProxy1632 +// +// Synopsis: checks if given object is an 16/32 object +// +// Arguments: [vpvObj16] -- Object to check +// +// Returns: 32-bit object being proxied or NULL +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +IUnknown *CThkMgr::IsProxy1632(VPVOID vpvObj16) +{ + VPVOID vpvProxy; + DWORD dwKey; + POSITION pos; + THUNK1632OBJ UNALIGNED *pto; + THUNKINFO ti; + + // First check and see if the vtable pointer is the one for + // 16-bit proxies. If it's not, this can't be a proxy + // Since we don't know anything about this pointer, we need + // to do safe translation + pto = (THUNK1632OBJ UNALIGNED *) + GetReadPtr16(&ti, vpvObj16, sizeof(THUNK1632OBJ)); + if (pto != NULL && pto->pfnVtbl == gdata16Data.atfnProxy1632Vtbl) + { + // The proxy may be freed memory or just random memory which + // happens to have the right value, so make sure that it's + // a proxy by looking it up in the proxy table + + pos = _pProxyTbl1632->GetStartPosition(); + while (pos) + { + _pProxyTbl1632->GetNextAssoc(pos, dwKey, + (void FAR* FAR&) vpvProxy); + if (vpvProxy == vpvObj16) + { + RELVDMPTR(vpvObj16); + return (IUnknown *)dwKey; + } + } + + // Check to see if we're returning no for what we think is + // a valid proxy + // It's possible for this to occur if somebody made a copy + // of a proxy's memory, but in general this assert should + // be extremely unlikely + thkAssert(pto->dwSignature != PSIG1632); + } + + if (pto != NULL) + { + RELVDMPTR(vpvObj16); + } + + return NULL; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::FindProxy1632 +// +// Synopsis: retrieves a 16/32 object (most cases proxy) for a given +// 32 bit IUnknown, it can be a real object -> shortcut +// +// Arguments: [vpvPrealloc] -- preallocated proxy +// [punkThis32] -- 32 bit object to be proxied +// [iidx] - Interface index or IID +// [pfst] - Return what kind of object was found +// +// Returns: 16/32 object (proxy or real object) +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +VPVOID CThkMgr::FindProxy1632(VPVOID vpvPrealloc, + IUnknown *punkThis32, + IIDIDX iidx, + DWORD *pfst) +{ + THUNK1632OBJ UNALIGNED *pto; + VPVOID vpv; + + thkDebugOut((DEB_THUNKMGR, "%sIn FindProxy1632(%p, %p, %s)\n", + NestingLevelString(), vpvPrealloc, punkThis32, + IidIdxString(iidx))); + DebugIncrementNestingLevel(); + + thkAssert(punkThis32 != NULL); + +#if DBG == 1 + // Ensure that we're not reusing a temporary proxy that's in use + if (vpvPrealloc) + { + pto = FIXVDMPTR(vpvPrealloc, THUNK1632OBJ); + if (pto->grfFlags & PROXYFLAG_TEMPORARY) + { + thkAssert(pto->cRefLocal == 0 && pto->cRef == 0); + } + RELVDMPTR(vpvPrealloc); + } +#endif + + // If we preallocated a proxy with an IID then a request was added + // in CanGetNewProxy. Clean it up now + if (vpvPrealloc != 0 && IIDIDX_IS_IID(iidx)) + { + RemoveIIDRequest(*IIDIDX_IID(iidx)); + } + + // Check the proxy table for an existing proxy for the given object pointer + // the 32 bit pointer is the key to the 16/32 proxy + vpv = LookupProxy1632(punkThis32); + if (vpv != NULL) + { + thkDebugOut((DEB_THUNKMGR, + "%sFindProxy1632 found existing proxy,(%p)->%p\n", + NestingLevelString(), punkThis32, vpv)); + + // We found an existing proxy, so reuse it + + pto = FIXVDMPTR(vpv, THUNK1632OBJ); + + // If a proxy's refcount is zero, it must be part of an aggregate + thkAssert(pto->cRefLocal > 0 || + (pto->pphHolder != NULL && + (pto->pphHolder->dwFlags & PH_AGGREGATE) != 0)); + + //Note: IIDIDXs are related to interfaces in our tables + // we have our table organized such that more derived + // interfaces are higher than less derived + // * Custom interfaces will have an IID rather than an index + // and will never be promoted above IUnknown in the + // below statement (johannp) + if (IIDIDX_IS_INDEX(iidx) && + IIDIDX_INDEX(iidx) > IIDIDX_INDEX(pto->iidx)) + { + // 16-bit proxy vtables are all the same so there's no + // need to manipulate the vtable pointer here as we + // do in the 32-bit case + + pto->iidx = iidx; + } + + RELVDMPTR(vpv); + + // AddRef the proxy we found since we're passing out a new reference + AddRefProxy1632(vpv); + + if (pfst) + { + *pfst = FST_USED_EXISTING; + } + + goto Exit; + } + + // Check and see whether the object we're supposed to proxy is + // actually a proxy itself + if ( (vpv = IsProxy3216(punkThis32)) != NULL) + { + thkDebugOut((DEB_THUNKMGR, + "%sFindProxy1632 shortcut proxy,(%p)->%p\n", + NestingLevelString(), punkThis32, vpv)); + + // We've discovered that the object that we're supposed to + // proxy is actually a proxy itself. In that case, we can + // avoid creating a full-circle proxy chain by returning + // the real pointer rather than creating a new proxy + // + // If we're shortcutting proxies for in parameters, we + // don't need to manipulate the reference count + // In the out parameter case, though, we're actually transferring + // ownership so we need to AddRef the real object and clean + // up the proxy we shortcut around + if (IsOutParamObj()) + { + THKSTATE thkstate; + + // We want to temporarily suspend our out state since + // we want this AddRef to really occur if it comes + // back to a proxy + thkstate = GetThkState(); + SetThkState(THKSTATE_NOCALL); + + AddRefOnObj16(vpv); + + SetThkState(thkstate); + + // Release the ignored proxy + // This avoids leaking proxies in round-trip calls + // where nobody holds a pointer to the proxy + ReleaseProxy3216((THUNK3216OBJ *)punkThis32); + } + + if (pfst) + { + *pfst = FST_SHORTCUT; + } + + goto Exit; + } + + // We didn't find an existing proxy and the object to be proxied + // is a real object so we need to fill out a new proxy for it + // We might have a preallocated proxy provided; if we don't + // we need to go to the free list and get a new one + + if (vpvPrealloc != NULL) + { + vpv = vpvPrealloc; + + // If we successfully created a proxy using the preallocated + // proxy, mark the preallocated proxy as used so it's not cleaned up + vpvPrealloc = NULL; + } + else + { + vpv = (VPVOID)flFreeList16.AllocElement(); + } + + if (vpv != NULL) + { + // Put the new proxy in the proxy list + if (!_pProxyTbl1632->SetAt((DWORD)punkThis32, (void *&)vpv)) + { + // Note that we can put vpv on the free list even it's + // the preallocated proxy since that's what the prealloc + // cleanup does + flFreeList16.FreeElement(vpv); + + vpv = NULL; + goto Exit; + } + + if (IIDIDX_IS_IID(iidx)) + { + // We're creating a proxy for a custom interface + // so just hand out an IUnknown + iidx = INDEX_IIDIDX(THI_IUnknown); + } + + pto = FIXVDMPTR(vpv, THUNK1632OBJ); + thkAssert(pto != NULL); + + pto->pfnVtbl = gdata16Data.atfnProxy1632Vtbl; + pto->cRefLocal = 1; + pto->cRef = (IsOutParamObj()) ? 1 : 0; + pto->iidx = iidx; + pto->punkThis32 = punkThis32; + pto->pphHolder = NULL; + PprxNull(pto->pprxObject); + pto->grfFlags = PROXYFLAG_NORMAL; + +#if DBG == 1 + pto->dwSignature = PSIG1632; +#endif + + RELVDMPTR(vpv); + + if (pfst) + { + *pfst = FST_CREATED_NEW; + } + + thkDebugOut((DEB_THUNKMGR, + "%sFindProxy1632 added new proxy, %s (%p)->%p (%d,%d)\n", + NestingLevelString(), + inInterfaceNames[pto->iidx].pszInterface, + punkThis32, vpv, + pto->cRefLocal, pto->cRef)); + } + + Exit: + // If we didn't use the preallocated proxy for some reason + // then put it back on the free list + if (vpvPrealloc != NULL) + { + flFreeList16.FreeElement( (DWORD)vpvPrealloc ); + } + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, "%sOut FindProxy1632: (%p)->%p\n", + NestingLevelString(), punkThis32, vpv)); + + return vpv; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::FindAggregate1632 +// +// Synopsis: retrieves an aggregate for 1632 with the given cntrl. unknown +// +// Arguments: [vpvPrealloc] - Preallocated proxy or NULL +// [punkOuter3216] -- the controlling unknown +// [punkThis32] -- the 32 bit interface - key +// [iidx] -- Index or IID of interface +// +// Returns: 16/32 proxy object +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +VPVOID CThkMgr::FindAggregate1632(VPVOID vpvPrealloc, + IUnknown *punkOuter3216, + IUnknown *punkThis32, + IIDIDX iidx) +{ + THUNK1632OBJ UNALIGNED *pto1632; + VPVOID vpv; + DWORD fst; + BOOL fMarkPUnk1632 = FALSE; + + + thkDebugOut((DEB_THUNKMGR, + "%sIn FindAggregate1632(%p, %p, %p, %s)\n", + NestingLevelString(), vpvPrealloc, punkOuter3216, punkThis32, + IidIdxString(iidx))); + DebugIncrementNestingLevel(); + + thkAssert(punkOuter3216 != NULL && punkThis32 != NULL); + + // Get back an object for the object to be proxied + // This may be a proxy or a real object from a shortcut + vpv = FindProxy1632(vpvPrealloc, punkThis32, iidx, &fst); + if (vpv == 0) + { + goto Exit; + } + + // If we got an object and it's not a proxy, we're done + // There's nothing we can do since we can't link a real object to + // a holder; we can only hope that things work out right + if (fst & FST_OBJECT_STATUS) + { + goto Exit; + } + + // Otherwise, we need to set up a holder for whatever proxies we + // have + + THUNK3216OBJ *ptoUnkOuter3216; + PROXYHOLDER *pph; + VPVOID vpvProxiedUnkOuter3216; + + // Determine whether the outer unknown is a proxy or not + vpvProxiedUnkOuter3216 = IsProxy3216(punkOuter3216); + + // This cast is only valid if vpvProxiedUnkOuter3216 is non-NULL + ptoUnkOuter3216 = (THUNK3216OBJ *)punkOuter3216; + + if (vpvProxiedUnkOuter3216 != 0 && ptoUnkOuter3216->pphHolder != NULL) + { + // Use the existing holder if there is one + pph = ptoUnkOuter3216->pphHolder; + } + else + { + // Create a new holder + pph = NewHolder(PH_AGGREGATE); + if (pph == NULL) + { + FreeProxy1632(punkThis32); + vpv = NULL; + goto Exit; + } + + // If the outer unknown is a proxy we know its holder hasn't + // been set, so add it to the holder we created + if (vpvProxiedUnkOuter3216 != 0) + { + AddProxyToHolder(pph, ptoUnkOuter3216, Pprx32(ptoUnkOuter3216)); + // Mark the pUnkOuter3216 as such; needed for aggregation rules + thkDebugOut((DEB_THUNKMGR, + "%s FindAggregate1632,(%p)->%p marked as pUnkOuter3216\n", + NestingLevelString(), ptoUnkOuter3216,Pprx32(ptoUnkOuter3216) )); + ptoUnkOuter3216->grfFlags |= PROXYFLAG_PUNKOUTER; + fMarkPUnk1632 = TRUE; + } + } + + thkAssert(vpvProxiedUnkOuter3216 == 0 || ptoUnkOuter3216->pphHolder == pph); + + // Add the new interface to the holder + // Since this proxy was just created, we know its holder + // hasn't been set yet + pto1632 = FIXVDMPTR(vpv, THUNK1632OBJ); + AddProxyToHolder(pph, pto1632, Pprx16(vpv)); + if (fMarkPUnk1632) + { + pto1632->grfFlags |= PROXYFLAG_PUNK; + thkDebugOut((DEB_THUNKMGR, + "%s FindAggregate1632,(%p)->%p marked as pUnk1632\n", + NestingLevelString(), punkThis32, vpv)); + } + + RELVDMPTR(vpv); + + Exit: + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, + "%sOut FindAggregate1632,(%p)->%p\n", + NestingLevelString(), punkThis32, vpv)); + + return vpv; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::QueryInterfaceProxy1632 +// +// Synopsis: QueryInterface on 32 bit object +// +// Arguments: [vpvThis16] -- Proxy +// [refiid] -- IID +// [ppv] -- new object (proxy or real object) for queried +// interface +// +// Returns: HRESULT +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +SCODE CThkMgr::QueryInterfaceProxy1632(VPVOID vpvThis16, + REFIID refiidIn, + LPVOID *ppv) +{ + SCODE scRet; + THUNK1632OBJ UNALIGNED *ptoThis; + THUNK1632OBJ UNALIGNED *ptoProxy; + VPVOID vpvProxy; + IIDIDX iidx; + IUnknown *punk32, *punkThis32; + DWORD fst; + BOOL fNotSupported = FALSE; + + thkDebugOut((DEB_THUNKMGR, "%sIn QueryInterfaceProxy1632(%p)\n", + NestingLevelString(), vpvThis16)); + DebugIncrementNestingLevel(); + + ptoThis = FIXVDMPTR(vpvThis16, THUNK1632OBJ); + thkAssert(ptoThis != NULL); + + // Don't validate temporary proxies + // We need to support temporary proxies in this method since + // Corel Draw 5.0 QI's on a temporary proxy + // + // BUGBUG - There are many potential problems with object identity, + // for example QI'ing where the return is the same object as the + // souce. Since the source is temporary it doesn't exist in the + // tables so identity will be broken. Of course, this won't cause + // any regressions for apps which don't use temporary proxies, + // so I think this is acceptable + if ((ptoThis->grfFlags & PROXYFLAG_TEMPORARY) == 0) + { + DebugValidateProxy1632(vpvThis16); + } + else + { + thkDebugOut((DEB_WARN, "WARNING: QueryInterfaceProxy1632 on " + "temporary %s proxy\n", IidIdxString(ptoThis->iidx))); + } + + *ppv = NULL; + // Note: Ikitaro queries for IViewObject and uses it as IViewObject2 + REFIID refiid = ( (TlsThkGetAppCompatFlags() & OACF_IVIEWOBJECT2) && IsEqualIID(refiidIn, IID_IViewObject)) + ? IID_IViewObject2 : refiidIn; + +#if DBG==1 + if ( (TlsThkGetAppCompatFlags() & OACF_IVIEWOBJECT2) + && IsEqualIID(refiidIn, IID_IViewObject)) + { + thkDebugOut((DEB_WARN,"Ikitaro: return IViewObject2 instead IViewObject\n")); + } +#endif // DBG==1 + + iidx = IidToIidIdx(refiid); + + // see if this a supported interface + if (IIDIDX_IS_IID(iidx)) + { + // add the request for the unknown interface + if (!AddIIDRequest(refiid)) + { + RELVDMPTR(vpvThis16); + return E_OUTOFMEMORY; + } + fNotSupported = TRUE; + + thkDebugOut((DEB_THUNKMGR, + "%sQueryInterfaceProxy1632: unknown iid %s\n", + NestingLevelString(), IidIdxString(iidx))); + } + + // We force the object we're QI'ing to have a holder so that + // all objects have object refcounting. This should only be + // necessary for aggregation but it seems that some apps rely + // on all objects having aggregation-like refcounting qualities + // BobDay identified PowerPoint as one + // We only want to do this in cases where we've identified it's + // necessary, which presently is only for + // IDataObject + // so we only do it then + + if (ptoThis->pphHolder == NULL && + (ptoThis->grfFlags & PROXYFLAG_TEMPORARY) == 0 && + IsEqualIID(refiid, IID_IDataObject)) + { + PROXYHOLDER *pph; + + pph = NewHolder(PH_NONAGGREGATE); + if (pph == NULL) + { + RELVDMPTR(vpvThis16); + scRet = E_OUTOFMEMORY; + goto Exit; + } + + AddProxyToHolder(pph, ptoThis, Pprx16(vpvThis16)); + + // It's not necessary to clean this up if later calls fail + // since it doesn't alter the lifetime of the proxy if there's + // only one proxy for the holder + } + + if (ptoThis->grfFlags & PROXYFLAG_TEMPORARY) + { + punkThis32 = *(IUnknown **)ptoThis->punkThis32; + } + else + { + punkThis32 = ptoThis->punkThis32; + } + + RELVDMPTR(vpvThis16); + + if (punkThis32 == NULL) + { + scRet = E_NOINTERFACE; + goto Exit; + } + thkDebugOut((DEB_THUNKMGR, + "%sQueryInterfaceProxy1632: on iid %s\n", + NestingLevelString(), IidIdxString(iidx))); + + scRet = punkThis32->QueryInterface(refiid, (void **)&punk32); + + if (FAILED(scRet)) + { + goto Exit; + } + + SetThkState(THKSTATE_INVOKETHKOUT16); + + vpvProxy = FindProxy1632(NULL, punk32, iidx, &fst); + if (vpvProxy == NULL) + { + // we were unable to create a proxy for the new interface so + // clean up the interface and quit + + punk32->Release(); + + scRet = E_OUTOFMEMORY; + goto ResetState; + } + + if (fNotSupported && !(fst & FST_SHORTCUT)) + { + // proxy of unknow interface can not be promoted + // clean up the interface and quit + + ReleaseProxy1632(vpvProxy); + + scRet = E_NOINTERFACE; + goto ResetState; + } + + + *ppv = (LPVOID)vpvProxy; + + // If we're returning a proxy, we need to make sure that + // it is listed in the proxy holder for this object + if (fst & FST_PROXY_STATUS) + { + // We are returning a proxy. If its holder isn't set, + // add it to the holder of the object that was QI'ed + + // Reconvert 16:16 pointer since calls may have caused + // nested calls and flat remapping + ptoThis = FIXVDMPTR(vpvThis16, THUNK1632OBJ); + + ptoProxy = FIXVDMPTR(vpvProxy, THUNK1632OBJ); + if (ptoProxy->pphHolder == NULL) + { + if (ptoThis->pphHolder != NULL) + { + AddProxyToHolder(ptoThis->pphHolder, ptoProxy, + Pprx16(vpvProxy)); + } + } + else if (ptoThis->pphHolder == NULL && + (ptoThis->grfFlags & PROXYFLAG_TEMPORARY) == 0) + { + // ptoThis may not have a holder because it was produced + // by a non-QI method such as IOleItemContainer::GetObject + // If we find that an interface returned by it does + // have a holder, hook it up to the holder + + // It shouldn't be necessary to do anything unusual with + // local references even if ptoThis is really part of an + // aggregate since ptoThis must have been produced by + // a method where aggregation can't be assumed and all + // references must be released on ptoThis itself + AddProxyToHolder(ptoProxy->pphHolder, ptoThis, + Pprx16(vpvThis16)); + } + +#if DBG == 1 + // It's possible for holders to not match because of the above + // case with interfaces being returned from non-QI methods + // The lifetime for such interfaces must be defined by + // strong references, though, so it's not catastrophic + // Still, we'd like to be aware of such mismatches just in case + if (ptoProxy->pphHolder != ptoThis->pphHolder) + { + thkDebugOut((DEB_WARN, "WARNING: QueryInterfaceProxy1632: " + "this %p has holder %p, proxy %p has holder %p\n", + vpvThis16, ptoThis->pphHolder, + vpvProxy, ptoProxy->pphHolder)); + } +#endif + + RELVDMPTR(vpvThis16); + RELVDMPTR(vpvProxy); + } + + ResetState: + SetThkState(THKSTATE_NOCALL); + + Exit: + // Clean up our custom interface request if there is one + if (IIDIDX_IS_IID(iidx)) + { + RemoveIIDRequest(refiid); + } + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, + "%sOut QueryInterfaceProxy1632(%p) => %p, 0x%08lX\n", + NestingLevelString(), vpvThis16, *ppv, scRet)); + + return scRet; +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::LocalAddRefProxy, public +// +// Synopsis: Increment a proxy's local refcount +// +// Arguments: [pprx] - Proxy +// +// History: 02-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CThkMgr::LocalAddRefProxy(CProxy *pprx) +{ + pprx->cRefLocal++; + + thkDebugOut(( DEB_THUNKMGR, + "%s LocalAddRefProxy1632 <%08lX> RefCounts: %d,%d\n", + NestingLevelString(), + pprx, pprx->cRefLocal, pprx->cRef )); + + // Check for proxies rising from the dead + + // If we're not part of an aggregate our refcount shouldn't be + // one or lower. If it is we're reviving a dead proxy which won't + // be in the proxy list and this could cause problems + // + // Note: With the new proxy stabilization code this can and does + // happen so this is only a debug out +#if DBG == 1 + if (!(pprx->cRefLocal > 1 || + (pprx->pphHolder != NULL && + (pprx->pphHolder->dwFlags & PH_AGGREGATE) != 0))) + { + thkDebugOut((DEB_WARN, "WARNING: Proxy %p unlisted with refs %d,%d\n", + pprx, pprx->cRefLocal, pprx->cRef)); + } +#endif + + if (pprx->cRefLocal == 1) + { + // We just resurrected a proxy with a zero refcount, + // so increment its holder's proxy count since it + // was decremented when the proxy released to zero + if (pprx->pphHolder != NULL) + { + AddRefHolder(pprx->pphHolder); + } + } +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::LockProxy, public +// +// Synopsis: Locks a proxy so that it can't be freed +// +// Arguments: [pprx] - Proxy +// +// History: 11-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CThkMgr::LockProxy(CProxy *pprx) +{ + pprx->grfFlags |= PROXYFLAG_LOCKED; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::AddRefProxy1632 +// +// Synopsis: addrefs proxy object - delegate call on to real object +// +// Arguments: [vpvThis16] -- 16/32 proxy +// +// Returns: local refcount +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +// Notes: AddRef rules +// * cRef is the addref passed on to the real object +// * cRefLocal is the addref collected locally +// - the refcount can be 0 if the object was created as on in-param +//---------------------------------------------------------------------------- +DWORD CThkMgr::AddRefProxy1632(VPVOID vpvThis16) +{ + THUNK1632OBJ UNALIGNED *ptoThis; + BOOL fAggregate; + LONG cRef; + + thkDebugOut((DEB_THUNKMGR, "%sIn AddRefProxy1632(%p)\n", + NestingLevelString(), vpvThis16)); + DebugIncrementNestingLevel(); + + DebugValidateProxy1632(vpvThis16); + + ptoThis = FIXVDMPTR(vpvThis16, THUNK1632OBJ); + + thkDebugOut(( DEB_THUNKMGR, + "%s AddRefProxy1632 %08lX RefCounts: %d,%d\n", + NestingLevelString(), + vpvThis16, ptoThis->cRefLocal, ptoThis->cRef )); + + // Always increment the proxy local refcount + LocalAddRefProxy(ptoThis); + + // Aggregations rely on all reference counts being forwarded on + // to the controlling unknown. Therefore, if we have a proxy + // that is part of an aggregate, we must ensure that the proxy + // doesn't collect references locally. If it did, they would + // not be passed on to the controlling unknown (via the real object) + // and the controlling unknown's refcount would be too low + if (ptoThis->pphHolder == NULL) + { + fAggregate = FALSE; + } + else + { + fAggregate = (ptoThis->pphHolder->dwFlags & PH_AGGREGATE) != 0; + } + + if (IsOutParamObj()) + { + // If we're on the way out we're assuming that the object + // given to us has its own reference so we bump cRef to + // indicate that but we don't call the real object + ptoThis->cRef++; + } + else if (ptoThis->cRef == 0 || fAggregate) + { + DWORD dwRet; + IUnknown *punk; + + // It's also necessary to pass on real references when the + // ref count is zero. This handles the case where an + // in parameter, created as 1,0, is AddRef'ed after + // its creation, in which case the reference needs to + // be passed on to the real object so that the proxy has + // at least one real reference since it will stay alive + ptoThis->cRef++; + punk = ptoThis->punkThis32; + RELVDMPTR(vpvThis16); + dwRet = punk->AddRef(); + + thkDebugOut((DEB_THUNKMGR, + "%s AddRefProxy1632: AddRef called on (%p):%ld\n", + NestingLevelString(), punk, dwRet)); + + // Reconvert 16:16 pointer since real AddRef may have caused + // nested calls and flat remapping + ptoThis = FIXVDMPTR(vpvThis16, THUNK1632OBJ); + } + else + { + // Just a local addref + } + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, "%sOut AddRefProxy1632(%p), (%ld,%ld)\n", + NestingLevelString(), vpvThis16, + ptoThis->cRefLocal, ptoThis->cRef)); + + cRef = ptoThis->cRefLocal; + RELVDMPTR(vpvThis16); + + return cRef; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::ReleaseProxy1632 +// +// Synopsis: release on 16/32 proxy - delegate call on to real object +// +// Arguments: [vpvThis16] -- proxy +// +// Returns: local refcount +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +DWORD CThkMgr::ReleaseProxy1632(VPVOID vpvThis16) +{ + THUNK1632OBJ UNALIGNED *ptoThis; + PROXYHOLDER *pph; + LONG cRef, cRefLocal; + + thkDebugOut((DEB_THUNKMGR, "%sIn ReleaseProxy1632(%p)\n", + NestingLevelString(), vpvThis16)); + DebugIncrementNestingLevel(); + + DebugValidateProxy1632(vpvThis16); + + ptoThis = FIXVDMPTR(vpvThis16, THUNK1632OBJ); + + // There are cases where releasing the real object causes + // an entire object to go away so the proxy is gone after + // that call. Fortunately these cases only occur when + // cRef == cRefLocal == 0, so we can avoid problems by + // copying them locally + + cRef = ptoThis->cRef; + cRefLocal = ptoThis->cRefLocal; + + thkDebugOut(( DEB_THUNKMGR, + "%s ReleaseProxy1632 %08lX RefCounts: %d,%d\n", + NestingLevelString(), + vpvThis16, ptoThis->cRefLocal, ptoThis->cRef )); + + + if (cRef <= 0 && cRefLocal == cRef) + { + thkDebugOut((DEB_ERROR, "ERROR: ReleaseProxy1632(%p) cRef: %d; cRef: %d\n", + vpvThis16, ptoThis->cRef, ptoThis->cRefLocal)); + + goto Done; + } + + // If our local refcount is the same as the count of references + // that we've passed on to the object, then we need to pass + // on this release to the real object + if (ptoThis->cRef == ptoThis->cRefLocal) + { + DWORD dwRet; + IUnknown *punk; + +#if DBG == 1 + // We'd like to assert this but some apps (Works is one) + // release an aggregated object too many times through one + // interface. The overall aggregate refcount is ok, though, + // so this doesn't cause a problem + + // thkAssert(ptoThis->cRef > 0); + + if (ptoThis->cRef <= 0) + { + thkDebugOut((DEB_WARN, "WARNING: ReleaseProxy1632(%p) cRef: %d\n", + vpvThis16, ptoThis->cRef)); + } +#endif + + // Use local cRef here for safety + if (cRef > 0) + { + // Decrement cRef after making the real call to ensure that + // the proxy lives throughout the call + --ptoThis->cRef; + } + + + + punk = ptoThis->punkThis32; + RELVDMPTR(vpvThis16); + + // check if this is an pUnk proxy in an aggregation + // if so mark the pUnkOuter for cleanup + if (ptoThis->grfFlags & PROXYFLAG_PUNK) + { + thkDebugOut((DEB_THUNKMGR, + "%s ReleaseProxy1632: Release called on (%p)->%p\n", + NestingLevelString(), punk, vpvThis16)); + pph = ptoThis->pphHolder; + pph->dwFlags |= PH_AGGREGATE_RELEASE; + } + + // Decremente cRefLocal to prevent loops in release + --ptoThis->cRefLocal; + + dwRet = punk->Release(); + + // Refresh pointer + ptoThis = FIXVDMPTR(vpvThis16, THUNK1632OBJ); + + // Increment cRefLocal after making the real call to ensure that + // the proxy lives throughout the call + ++ptoThis->cRefLocal; + + // rese the aggreagation flag + if (ptoThis->grfFlags & PROXYFLAG_PUNK) + { + pph = ptoThis->pphHolder; + pph->dwFlags &= !PH_AGGREGATE_RELEASE; + } + + + thkDebugOut((DEB_THUNKMGR, + "%s ReleaseProxy1632: Release called on (%p):%ld \n", + NestingLevelString(), ptoThis->punkThis32, dwRet)); + } + + // Now that we've handled the real object's refcount, decrement + // the proxy's refcount and clean it up if necessary + // We need to use the local cRefLocal in case the proxy has gone away + +#if DBG == 1 + // We'd like to assert this but some apps (Works is one) + // release an aggregated object too many times through one + // interface. The overall aggregate refcount is ok, though, + // so this doesn't cause a problem + + thkAssert(cRefLocal > 0); + + if (cRefLocal <= 0) + { + thkDebugOut((DEB_WARN, "WARNING: ReleaseProxy1632(%p) cRefLocal: %d\n", + vpvThis16, cRefLocal)); + } +#endif + + if (cRefLocal <= 0) + { + ptoThis = NULL; + } + else if (--ptoThis->cRefLocal == 0) + { + + // Proxies that have no outer unknown can be cleaned + // up immediately. If they do have an outer unknown then + // they must live as long as the entire object lives, + // so we don't clean them up here. They'll be cleaned up + // when the object dies + + pph = ptoThis->pphHolder; + if (pph) + { + // If this proxy isn't part of an aggregate, remove it + // from the proxy list so it can't be reused + // The only thing this proxy will be good for is + // calling through + if ((pph->dwFlags & PH_AGGREGATE) == 0) + { + _pProxyTbl1632->RemoveKey((DWORD)ptoThis->punkThis32); + } + + RELVDMPTR(vpvThis16); + + // We have a holder, so notify it that one of its + // proxies just died + // This can cause cleanup of all proxies if the + // holder releases to zero + ReleaseHolder(pph); + } + else + { + // We don't have a holder so we can clean up this proxy + // immediately + + // Releases pointer + RemoveProxy1632(vpvThis16, ptoThis); + } + + ptoThis = NULL; + + DBG_DUMP(DebugDump1632()); + } + +Done: + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, "%sOut ReleaseProxy1632(%p) => %d,%d\n", + NestingLevelString(), vpvThis16, + ptoThis ? ptoThis->cRefLocal : 0, + ptoThis ? ptoThis->cRef : 0)); + + if (ptoThis) + { + cRef = ptoThis->cRefLocal; + RELVDMPTR(vpvThis16); + } + else + { + cRef = 0; + } + + return cRef; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::FreeProxy1632 +// +// Synopsis: frees object for given pUnk (key) +// +// Arguments: [punkThis32] -- 32 bit unknown - key +// +// Returns: Refcount +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +DWORD CThkMgr::FreeProxy1632(IUnknown *punkThis32) +{ + thkDebugOut((DEB_THUNKMGR, "%sIn FreeProxy1632(%p)\n", + NestingLevelString(), punkThis32)); + DebugIncrementNestingLevel(); + + thkAssert(punkThis32 != NULL && "FreeProxy1632: invalid object pointer."); + + DWORD dwRet = 0; + VPVOID vpv; + + vpv = LookupProxy1632(punkThis32); + if (vpv != NULL) + { + thkDebugOut((DEB_THUNKMGR, + "%sFreeProxy1632(%p) found existing proxy %p\n", + NestingLevelString(), punkThis32, vpv)); + + // punkThis32 is a proxy and not a real object, so release it + dwRet = ReleaseProxy1632(vpv); + } + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, "%sOut FreeProxy1632(%p):%ld \n", + NestingLevelString(), punkThis32, dwRet)); + + return dwRet; +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::RemoveProxy1632, public +// +// Synopsis: Destroys the given proxy +// +// Arguments: [vpv] - 16-bit proxy pointer +// [pto] - Flat proxy pointer +// +// History: 11-Aug-94 DrewB Created +// +// Notes: Unfixes fixed pointer passed in +// +//---------------------------------------------------------------------------- + +void CThkMgr::RemoveProxy1632(VPVOID vpv, THUNK1632OBJ *pto) +{ + _pProxyTbl1632->RemoveKey((DWORD)pto->punkThis32); + + if ((pto->grfFlags & PROXYFLAG_LOCKED) == 0) + { +#if DBG == 1 + pto->dwSignature = PSIG1632DEAD; +#endif + + RELVDMPTR(vpv); + +#if DBG == 1 + if (!fSaveProxy) +#endif + { + flFreeList16.FreeElement((DWORD)vpv); + } + } + else + { + RELVDMPTR(vpv); + } +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::CanGetNewProxy3216 +// +// Synopsis: checks if new proxy is available +// +// Arguments: [iidx] - Custom interface or known index +// +// Returns: Preallocated proxy or NULL +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +THUNK3216OBJ *CThkMgr::CanGetNewProxy3216(IIDIDX iidx) +{ + thkDebugOut((DEB_THUNKMGR, "%sIn CanGetNewProxy3216(%s)\n", + NestingLevelString(), IidIdxString(iidx))); + + LPVOID pvoid; + + pvoid = (LPVOID)flFreeList32.AllocElement(); + if ( pvoid == NULL) + { + thkDebugOut((DEB_WARN, "WARNING: CThkMgr::CanGetNewProxy3216, " + "AllocElement failed\n")); + return NULL; + } + + // check if the proxy is requested for a no-thop-interface + if (pvoid && IIDIDX_IS_IID(iidx)) + { + // add the request for the unknown interface + if ( !AddIIDRequest(*IIDIDX_IID(iidx)) ) + { + flFreeList32.FreeElement( (DWORD)pvoid ); + pvoid = NULL; + } + } + + thkDebugOut((DEB_THUNKMGR, "%sOut CanGetNewProxy3216: %p \n", + NestingLevelString(), pvoid)); + + return (THUNK3216OBJ *)pvoid; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::FreeNewProxy3216 +// +// Synopsis: frees previous reserved proxy +// +// Arguments: [pto] - Proxy +// [iidx] - Custom interface or known index +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +void CThkMgr::FreeNewProxy3216(THUNK3216OBJ *pto, IIDIDX iidx) +{ + thkDebugOut((DEB_THUNKMGR, "%sIn FreeNewProxy3216(%p, %s)\n", + NestingLevelString(), pto, IidIdxString(iidx))); + + thkAssert(pto != NULL); + + if (IIDIDX_IS_IID(iidx)) + { + // add the request for the unknown interface + RemoveIIDRequest(*IIDIDX_IID(iidx)); + } + + thkAssert(pto != NULL); + flFreeList32.FreeElement( (DWORD)pto ); + + thkDebugOut((DEB_THUNKMGR, "%sOut FreeNewProxy3216\n", + NestingLevelString())); +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::IsProxy3216 +// +// Synopsis: checks if the given object is a 32/16 proxy +// +// Arguments: [punk] -- punk of 32 bit object +// +// Returns: Object being proxied or NULL +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +VPVOID CThkMgr::IsProxy3216(IUnknown *punk) +{ + LPVOID pvVtbl, pvFn; + THUNK3216OBJ *pto3216; + + // First check the initial entry in the vtable + // If it's not QueryInterfaceProxy3216 then this can't possibly + // be a 32/16 proxy + pvVtbl = *(void **)punk; + pvFn = *(void **)pvVtbl; + if (pvFn == ::QueryInterfaceProxy3216) + { + DWORD dwKey; + POSITION pos; + + // This object has a proxy's vtable but it may be dead, copied + // or coincidentally correct random memory, so look for it in + // the table + + pos = _pProxyTbl3216->GetStartPosition(); + while (pos) + { + _pProxyTbl3216->GetNextAssoc(pos, dwKey, (void FAR* FAR&) pto3216); + + if (pto3216 == (THUNK3216OBJ *)punk) + { + return (VPVOID)dwKey; + } + } + + // Check to see if we're returning no for what we think is + // a valid proxy + // It's possible for this to occur but it's very unlikely + thkAssert(pto3216->dwSignature != PSIG3216); + } + + return 0; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::FindProxy3216 +// +// Synopsis: retrieves a 32/16 proxy +// +// Arguments: [ptoPrealloc] - Preallocated proxy or NULL +// [vpvThis16] -- 16 bit object (key) +// [iidx] - Custom interface or known index +// [pfst] - Status return +// +// Returns: pointer to 32/16 proxy or real object +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +IUnknown *CThkMgr::FindProxy3216(THUNK3216OBJ *ptoPrealloc, + VPVOID vpvThis16, + IIDIDX iidx, + DWORD *pfst) +{ + IUnknown *punk; + THUNK3216OBJ *pto; + THKSTATE thkstate; + + thkDebugOut((DEB_THUNKMGR, "%sIn FindProxy3216(%p, %p, %s)\n", + NestingLevelString(), ptoPrealloc, vpvThis16, + IidIdxString(iidx))); + DebugIncrementNestingLevel(); + + thkAssert(vpvThis16 != 0); + + // If we preallocated a proxy with an IID then a request was added + // in CanGetNewProxy. Clean it up now + if (ptoPrealloc != 0 && IIDIDX_IS_IID(iidx)) + { + RemoveIIDRequest(*IIDIDX_IID(iidx)); + } + + thkstate = GetThkState(); + + // Check and see whether a proxy already exists for this object + pto = LookupProxy3216(vpvThis16); + if (pto != NULL) + { + thkDebugOut((DEB_THUNKMGR, + "%sFindProxy3216 found existing proxy,(%p)->%p\n", + NestingLevelString(), vpvThis16, pto)); + + // If a proxy's refcount is zero, it must be part of an aggregate + thkAssert(pto->cRefLocal > 0 || + (pto->pphHolder != NULL && + (pto->pphHolder->dwFlags & PH_AGGREGATE) != 0)); + + // We found an existing proxy, so use it + punk = (IUnknown *)pto; + + // Check and see whether we need to promote the proxy + // This occurs in derivation situations where a less-specialized + // proxy already exists for the given object. For example, + // we might already have an IPersist proxy for this object when + // we're looking up IPersistFile. In such cases, we promote + // the proxy to the most derived interface + if (IIDIDX_IS_INDEX(iidx) && + IIDIDX_INDEX(iidx) > IIDIDX_INDEX(pto->iidx)) + { + pto->pfnVtbl = + (DWORD)athopiInterfaceThopis[IIDIDX_INDEX(iidx)].pt3216fn; + pto->iidx = iidx; + } + + // AddRef the proxy we found since we're passing out a reference + AddRefProxy3216(pto); + + if (pfst) + { + *pfst = FST_USED_EXISTING; + } + + goto Exit; + } + + // Check and see whether the object to be proxied is in fact a + // proxy itself. If it is, we can just return the real object + // rather than creating chains of proxies + if ( ( punk = IsProxy1632(vpvThis16)) != NULL) + { + thkDebugOut((DEB_THUNKMGR, + "%sFindProxy3216 shortcut proxy,(%p)->%p\n", + NestingLevelString(), vpvThis16, punk)); + + // In the out parameter case, we are transferring ownership + // so we need to AddRef the thing we're returning + // Since we're shortcutting around a proxy we lose a reference + // to the proxy so release it + if (IsOutParamObj()) + { + // vpvThis16 is a pointer to a proxy + // addref the real object and release the proxy + + // We want to temporarily suspend our out state since + // we want this AddRef to really occur if it comes back + // to a proxy + SetThkState(THKSTATE_NOCALL); + + punk->AddRef(); + + SetThkState(thkstate); + + // Excel lands here with one too few addrefs so don't release + if (thkstate != THKSTATE_INVOKETHKOUT16_CLIENTSITE) + { + ReleaseProxy1632(vpvThis16); + } + } + + if (pfst) + { + *pfst = FST_SHORTCUT; + } + + goto Exit; + } + + // We didn't find an existing proxy or shortcut so we need + // to create a new proxy for the given object + // We use preallocated memory if possible, otherwise we + // get a new proxy from the free list + + if (ptoPrealloc != NULL) + { + pto = ptoPrealloc; + + // Since we're using the preallocated proxy, mark it as used + // so we don't clean it up later + ptoPrealloc = NULL; + } + else + { + pto = (THUNK3216OBJ *)flFreeList32.AllocElement(); + } + + if (pto != NULL) + { + // Put the new proxy in the proxy table + if (!_pProxyTbl3216->SetAt(vpvThis16, pto)) + { + // Note that we can put the new proxy back on the free + // list even if it's the preallocated proxy because + // that's what the prealloc cleanup does + flFreeList32.FreeElement((DWORD)pto); + + pto = NULL; + goto Exit; + } + + if (IIDIDX_IS_IID(iidx)) + { + // give out IUnknown for custom interfaces + iidx = INDEX_IIDIDX(THI_IUnknown); + } + + punk = (IUnknown *)pto; + + pto->pfnVtbl = (DWORD)athopiInterfaceThopis[iidx].pt3216fn; + pto->cRefLocal = 1; + pto->cRef = (IsOutParamObj()) ? 1 : 0; + pto->iidx = iidx; + pto->vpvThis16 = vpvThis16; + pto->pphHolder = NULL; + PprxNull(pto->pprxObject); + pto->grfFlags = PROXYFLAG_NORMAL; + + +#if DBG == 1 + pto->dwSignature = PSIG3216; +#endif + + if (pfst) + { + *pfst = FST_CREATED_NEW; + } + + thkDebugOut((DEB_THUNKMGR, + "%sFindProxy3216 created new proxy, %s (%p)->%p:(%d,%d)\n", + NestingLevelString(), + inInterfaceNames[pto->iidx].pszInterface, + vpvThis16, pto, pto->cRefLocal, pto->cRef)); + + } + + Exit: + // + // If we are succeeding punk will not be NULL. Then do this hack for Excel + // + if ( punk != NULL && thkstate == THKSTATE_INVOKETHKOUT16_CLIENTSITE ) + { + SetThkState(THKSTATE_NOCALL); + // + // Excel 5.0a has a bug where it doesn't addref the proxy + // that it returns from the IOleObject::GetClientSite call + // this means that we can't release the proxy or we'd kill it + // prematurely. + // + thkDebugOut((DEB_WARN, "FindProxy1632: " + "Addrefing proxy for compatability\n")); + AddRefOnObj16( vpvThis16 ); + + SetThkState(thkstate); + } + + // If we haven't used the preallocated proxy, return it to the freelist + if (ptoPrealloc) + { + flFreeList32.FreeElement( (DWORD)ptoPrealloc ); + } + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, "%sOut FindProxy3216: (%p)->%p\n", + NestingLevelString(), vpvThis16, punk)); + + return punk; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::FindAggregate3216 +// +// Synopsis: finds/creates an aggregate +// +// Arguments: [ptoPrealloc] - Preallocated proxy or NULL +// [vpvOuter16] -- controlling unknown +// [vpvThis16] -- 16 bit object (key) +// [iidx] - IID or index of interface +// +// Returns: 32/16 proxy object +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +IUnknown *CThkMgr::FindAggregate3216(THUNK3216OBJ *ptoPrealloc, + VPVOID vpvOuter16, + VPVOID vpvThis16, + IIDIDX iidx) +{ + THUNK3216OBJ *pto3216; + IUnknown *punk; + DWORD fst; + + thkDebugOut((DEB_THUNKMGR, "%sIn FindAggregate3216(%p, %p, %p, %s)\n", + NestingLevelString(), ptoPrealloc, vpvOuter16, + vpvThis16, IidIdxString(iidx))); + DebugIncrementNestingLevel(); + + thkAssert(vpvThis16 != NULL && vpvOuter16 != NULL); + + // Get back an object for the object to be proxied + // This may be a proxy or a real object from a shortcut + punk = FindProxy3216(ptoPrealloc, vpvThis16, iidx, &fst); + if (punk == NULL) + { + goto Exit; + } + + // If we got an object and it's not a proxy, we're done + // There's nothing we can do since we can't link a real object to + // a holder; we can only hope that things work out right + if (fst & FST_OBJECT_STATUS) + { + goto Exit; + } + + // Otherwise, we need to set up a holder for whatever proxies we + // have + + THUNK1632OBJ UNALIGNED *pto1632; + PROXYHOLDER *pph; + IUnknown *punkProxiedObject; + + // We know punk is a proxy + pto3216 = (THUNK3216OBJ *)punk; + + // Determine whether the outer unknown is a proxy or not + punkProxiedObject = IsProxy1632(vpvOuter16); + + // Get the proxy pointer if it is + if (punkProxiedObject != 0) + { + pto1632 = FIXVDMPTR(vpvOuter16, THUNK1632OBJ); + } + + if (punkProxiedObject != 0 && pto1632->pphHolder != NULL) + { + // Use the existing holder if there is one + pph = pto1632->pphHolder; + } + else + { + // Create a new holder + pph = NewHolder(PH_AGGREGATE); + if (pph == NULL) + { + FreeProxy3216(vpvThis16); + punk = NULL; + goto Exit; + } + + // If the outer unknown is a proxy we know its holder hasn't + // been set, so add it to the holder we created + if (punkProxiedObject != 0) + { + AddProxyToHolder(pph, pto1632, Pprx16(vpvOuter16)); + } + } + + thkAssert(punkProxiedObject == 0 || pto1632->pphHolder == pph); + + // Add the new interface to the holder + // Since this proxy was just created, we know its holder + // hasn't been set yet + AddProxyToHolder(pph, pto3216, Pprx32(pto3216)); + + Exit: + if (punkProxiedObject != 0) + { + RELVDMPTR(vpvOuter16); + } + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, "%sOut FindAggregate3216,(%p)->%p\n", + NestingLevelString(), vpvThis16, pto3216)); + + return punk; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::QueryInterfaceProxy3216 +// +// Synopsis: QueryInterface on the given proxy +// +// Arguments: [ptoThis] -- proxy object +// [refiid] -- interface +// [ppv] -- out parameter +// +// Returns: HRESULT +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +SCODE CThkMgr::QueryInterfaceProxy3216(THUNK3216OBJ *ptoThis, + REFIID refiid, + LPVOID *ppv) +{ + SCODE scRet; + IUnknown *punkProxy; + VPVOID vpvUnk; + DWORD fst; + + + thkDebugOut((DEB_THUNKMGR, "%sIn QueryInterfaceProxy3216(%p)\n", + NestingLevelString(), ptoThis)); + DebugIncrementNestingLevel(); + + DebugValidateProxy3216(ptoThis); + + *ppv = NULL; + + IIDIDX iidx = IidToIidIdx(refiid); + + if (IIDIDX_IS_IID(iidx)) + { + // add the request for the unknown interface + if (!AddIIDRequest(refiid)) + { + return E_OUTOFMEMORY; + } + thkDebugOut((DEB_THUNKMGR, + "%sQueryInterfaceProxy3216: unknown iid %s\n", + NestingLevelString(), IidIdxString(iidx))); + + } + + // We force the object we're QI'ing to have a holder so that + // all objects have object refcounting. This should only be + // necessary for aggregation but it seems that some apps rely + // on all objects having aggregation-like refcounting qualities + // BobDay identified PowerPoint as one + // We only want to do this in cases where we've identified it's + // necessary, which presently is only for + // IDataObject + // so we only do it then + + if (ptoThis->pphHolder == NULL && IsEqualIID(refiid, IID_IDataObject)) + { + PROXYHOLDER *pph; + + pph = NewHolder(PH_NONAGGREGATE); + if (pph == NULL) + { + scRet = E_OUTOFMEMORY; + goto Exit; + } + + AddProxyToHolder(pph, ptoThis, Pprx32(ptoThis)); + + // It's not necessary to clean this up if later calls fail + // since it doesn't alter the lifetime of the proxy if there's + // only one proxy for the holder + } + + // see if the interface is supported + scRet = QueryInterfaceOnObj16(ptoThis->vpvThis16, refiid, + (void **)&vpvUnk); + if (FAILED(scRet)) + { + goto Exit; + } + + if (NULL == vpvUnk) + { + // Although it is invalid, an app can return NULL for the + // output interface and NOERROR for the result on a QueryInterface. + // Corel draw has this behavior. Anyway, we nullify these errors + // here. + scRet = E_NOINTERFACE; + goto Exit; + } + + SetThkState(THKSTATE_INVOKETHKOUT32); + + punkProxy = FindProxy3216(NULL, vpvUnk, iidx, &fst); + if (punkProxy == NULL) + { + // We were unable to create a proxy for the new interface so + // clean up the interface and quit + + ReleaseOnObj16(vpvUnk); + + scRet = E_OUTOFMEMORY; + goto ResetState; + } + + *ppv = punkProxy; + + // If we're returning a proxy, we need to make sure that + // it is listed in the proxy holder for this object + if (fst & FST_PROXY_STATUS) + { + THUNK3216OBJ *ptoProxy; + + // We are returning a proxy. If its holder isn't set, + // add it to the holder of the object that was QI'ed + + ptoProxy = (THUNK3216OBJ *)punkProxy; + if (ptoProxy->pphHolder == NULL) + { + if (ptoThis->pphHolder != NULL) + { + AddProxyToHolder(ptoThis->pphHolder, ptoProxy, + Pprx32(ptoProxy)); + } + } + else if (ptoThis->pphHolder == NULL) + { + // ptoThis may not have a holder because it was produced + // by a non-QI method such as IOleItemContainer::GetObject + // If we find that an interface returned by it does + // have a holder, hook it up to the holder + + // It shouldn't be necessary to do anything unusual with + // local references even if ptoThis is really part of an + // aggregate since ptoThis must have been produced by + // a method where aggregation can't be assumed and all + // references must be released on ptoThis itself + AddProxyToHolder(ptoProxy->pphHolder, ptoThis, + Pprx32(ptoThis)); + } + +#if DBG == 1 + // It's possible for holders to not match because of the above + // case with interfaces being returned from non-QI methods + // The lifetime for such interfaces must be defined by + // strong references, though, so it's not catastrophic + // Still, we'd like to be aware of such mismatches just in case + if (ptoProxy->pphHolder != ptoThis->pphHolder) + { + thkDebugOut((DEB_WARN, "WARNING: QueryInterfaceProxy3216: " + "this %p has holder %p, proxy %p has holder %p\n", + ptoThis, ptoThis->pphHolder, + ptoProxy, ptoProxy->pphHolder)); + } +#endif + } + + ResetState: + SetThkState(THKSTATE_NOCALL); + + Exit: + // Clean up our custom interface request if necessary + if (IIDIDX_IS_IID(iidx)) + { + // add the request for the unknown interface + RemoveIIDRequest(refiid); + } + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, + "%sOut QueryInterfaceProxy3216(%p) => %p, 0x%08lX\n", + NestingLevelString(), ptoThis, *ppv, scRet)); + + return scRet; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::AddRefProxy3216 +// +// Synopsis: addref on the given object - can addref the real object +// +// Arguments: [ptoThis] -- proxy object +// +// Returns: local refcount +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +DWORD CThkMgr::AddRefProxy3216(THUNK3216OBJ *ptoThis) +{ + PROXYHOLDER *pph; + BOOL fAggregate; + + thkDebugOut((DEB_THUNKMGR, "%sIn AddRefProxy3216(%p)\n", + NestingLevelString(), ptoThis)); + DebugIncrementNestingLevel(); + + DebugValidateProxy3216(ptoThis); + + thkDebugOut(( DEB_THUNKMGR, + "%s AddRefProxy3216 %08lX RefCounts: %d,%d\n", + NestingLevelString(), + ptoThis, ptoThis->cRefLocal, ptoThis->cRef )); + + + pph = ptoThis->pphHolder; + if (pph && (pph->dwFlags & PH_AGGREGATE_RELEASE)) + { + // we are about to call release on pUnkOuter + // Release on PUnk was called and addref or release + // calls to pUnkOuter are not supposted to be passed + // on any more + thkDebugOut((DEB_THUNKMGR, "%s About to addref pUnkOuter3216(%p)\n", + NestingLevelString(), ptoThis)); + + goto Exit; + } + + // Always increment the proxy local refcount + LocalAddRefProxy(ptoThis); + + // Aggregations rely on all reference counts being forwarded on + // to the controlling unknown. Therefore, if we have a proxy + // that is part of an aggregate, we must ensure that the proxy + // doesn't collect references locally. If it did, they would + // not be passed on to the controlling unknown (via the real object) + // and the controlling unknown's refcount would be too low + if (ptoThis->pphHolder == NULL) + { + fAggregate = FALSE; + } + else + { + fAggregate = (ptoThis->pphHolder->dwFlags & PH_AGGREGATE) != 0; + } + + if (IsOutParamObj()) + { + // If we're on the way out we're assuming that the object + // given to us has its own reference so we bump cRef to + // indicate that but we don't call the real object + ptoThis->cRef++; + } + else if (ptoThis->cRef == 0 || fAggregate) + { + DWORD dwRet; + + // It's also necessary to pass on real references when the + // ref count is zero. This handles the case where an + // in parameter, created as 1,0, is AddRef'ed after + // its creation, in which case the reference needs to + // be passed on to the real object so that the proxy has + // at least one real reference since it will stay alive + ptoThis->cRef++; + dwRet = AddRefOnObj16(ptoThis->vpvThis16); + + thkDebugOut((DEB_THUNKMGR, + "%s AddRefProxy3216: AddRef called on (%p):%ld\n", + NestingLevelString(), ptoThis->vpvThis16, dwRet)); + } + else + { + // Local-only AddRef + } + +Exit: + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, "%sOut AddRefProxy3216(%p),(%ld,%ld)\n", + NestingLevelString(), ptoThis, ptoThis->cRefLocal, + ptoThis->cRef)); + + return ptoThis->cRefLocal; +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::ReleaseProxy3216 +// +// Synopsis: release on the proxy or aggregate +// +// Arguments: [ptoThis] -- proxy object +// +// Returns: local refcount +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +DWORD CThkMgr::ReleaseProxy3216(THUNK3216OBJ *ptoThis) +{ + PROXYHOLDER *pph; + + thkDebugOut((DEB_THUNKMGR, "%sIn ReleaseProxy3216(%p)\n", + NestingLevelString(), ptoThis)); + DebugIncrementNestingLevel(); + + DebugValidateProxy3216(ptoThis); + + thkDebugOut(( DEB_THUNKMGR, + "%s ReleaseProxy3216 %08lX RefCounts: %d,%d\n", + NestingLevelString(), + ptoThis, ptoThis->cRefLocal, ptoThis->cRef )); + + pph = ptoThis->pphHolder; + if (pph && (pph->dwFlags & PH_AGGREGATE_RELEASE)) + { + // we are about to call release on pUnkOuter + // Release on PUnk was called and addref and + // release calls to pUnkOuter are not supposted + // to be passed on any more + thkDebugOut((DEB_THUNKMGR, "%s About to release pUnkOuter3216(%p)\n", + NestingLevelString(), ptoThis)); + thkDebugOut((DEB_THUNKMGR, "%s ReleaseProxy3216 pUnkOuter stop passing releases on(%p) => %ld,%ld\n", + NestingLevelString(), ptoThis, + ptoThis ? ptoThis->cRefLocal : 0 , + ptoThis ? ptoThis->cRef : 0)); + + if (ptoThis->cRef == 0 && ptoThis->cRef == ptoThis->cRefLocal) + { + goto Done; + } + } + + + // If our local refcount is the same as the count of references + // that we've passed on to the object, then we need to pass + // on this release to the real object + if (ptoThis->cRef == ptoThis->cRefLocal) + { + DWORD dwRet; + + thkAssert(ptoThis->cRef > 0); + + dwRet = ReleaseOnObj16(ptoThis->vpvThis16); + + // Decrement cRef after making the real call to ensure that + // the proxy lives throughout the call + --ptoThis->cRef; + + thkDebugOut((DEB_THUNKMGR, + "%s ReleaseProxy3216: Release called on (%p):%ld \n", + NestingLevelString(), ptoThis->vpvThis16, dwRet)); + } + + // Now that we've handled the real object's refcount, decrement + // the proxy's refcount and clean it up if necessary + thkAssert(ptoThis->cRefLocal > 0); + if (--ptoThis->cRefLocal == 0) + { + // Proxies that have no outer unknown can be cleaned + // up immediately. If they do have an outer unknown then + // they must live as long as the entire object lives, + // so we don't clean them up here. They'll be cleaned up + // when the object dies + + if (ptoThis->pphHolder) + { + // If this proxy isn't part of an aggregate, remove it + // from the proxy list so it can't be reused + // The only thing this proxy will be good for is + // calling through + if ((ptoThis->pphHolder->dwFlags & PH_AGGREGATE) == 0) + { + _pProxyTbl3216->RemoveKey((DWORD)ptoThis->vpvThis16); + } + + // We have a holder, so notify it that one of its + // proxies just died + // This can cause cleanup of all proxies if the + // holder releases to zero + ReleaseHolder(ptoThis->pphHolder); + } + else + { + // We don't have a holder so we can clean up this proxy + // immediately + + RemoveProxy3216(ptoThis); + } + + ptoThis = NULL; + + DBG_DUMP(DebugDump3216()); + } +Done: + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, "%sOut ReleaseProxy3216(%p) => %ld,%ld\n", + NestingLevelString(), ptoThis, + ptoThis ? ptoThis->cRefLocal : 0 , + ptoThis ? ptoThis->cRef : 0)); + + return ptoThis ? ptoThis->cRefLocal : 0; +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::ReleaseUnreferencedProxy3216, public +// +// Synopsis: Releases a proxy in the special case where the proxy +// was created for a non-addrefed object +// +// Arguments: [ptoThis] - 32/16 proxy +// +// History: 11-Jul-94 DrewB Created +// +// Notes: Needed to clean up proxies from DebugServerQueryInterface +// in DebugServerRelease +// +//---------------------------------------------------------------------------- + +void CThkMgr::ReleaseUnreferencedProxy3216(THUNK3216OBJ *ptoThis) +{ + thkAssert(IsProxy3216((IUnknown *)ptoThis) != 0); + + // Since the object is non-addref'ed, we have to be careful + // to ensure that the ReleaseProxy call doesn't end up releasing + // the real object, so we force cRef to be different from + // cRefLocal. We know that DebugServerQueryInterface gave the + // proxy a cRef because it's an out parameter, so we should + // always be able to decrement cRef and achieve the desired + // effect + + thkAssert(ptoThis->cRef > 0); + ptoThis->cRef--; + + // Now release the proxy to clean it up + // If it was addref'ed, this will just remove a local reference + // If it wasn't, this will clean up the proxy + // In both cases, no Release should occur on the real object + + thkAssert(ptoThis->cRefLocal != ptoThis->cRef); + + ReleaseProxy3216(ptoThis); +} + +//+--------------------------------------------------------------------------- +// +// Method: CThkMgr::FreeProxy3216 +// +// Synopsis: releases the object for the given vpUnk16 (key) +// +// Arguments: [vpvObj16] - Proxy or object +// +// Returns: local refcount +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +DWORD CThkMgr::FreeProxy3216(VPVOID vpvObj16) +{ + thkDebugOut((DEB_THUNKMGR, "%sIn FreeProxy3216(%p)\n", + NestingLevelString(), vpvObj16)); + + DWORD dwRet = 0; + THUNK3216OBJ *pto; + + thkAssert(vpvObj16 != 0); + + // get the object by the 16 bit this pointer + pto = LookupProxy3216(vpvObj16); + if (pto != NULL) + { + thkDebugOut((DEB_THUNKMGR, "%sFreeProxy3216(%p) " + "found existing proxy %p\n", + NestingLevelString(), vpvObj16, pto)); + + dwRet = ReleaseProxy3216(pto); + } + + thkDebugOut((DEB_THUNKMGR, "%sOut FreeProxy3216(%p):%ld \n", + NestingLevelString(), vpvObj16, dwRet)); + + return dwRet; +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::RemoveProxy3216, public +// +// Synopsis: Destroys the given proxy +// +// Arguments: [pto] - Flat proxy pointer +// +// History: 11-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CThkMgr::RemoveProxy3216(THUNK3216OBJ *pto) +{ + _pProxyTbl3216->RemoveKey((DWORD)pto->vpvThis16); + + if ((pto->grfFlags & PROXYFLAG_LOCKED) == 0) + { +#if DBG == 1 + pto->dwSignature = PSIG3216DEAD; + if (!fSaveProxy) +#endif + { + flFreeList32.FreeElement((DWORD)pto); + } + } +} + +//+--------------------------------------------------------------------------- +// +// Member: CThkMgr::PrepareForCleanup, public +// +// Synopsis: Marks the 3216 Proxies so that OLE32 cannot call them. +// +// Arguments: -none- +// +// History: 24-Aug-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void CThkMgr::PrepareForCleanup( void ) +{ + POSITION pos; + DWORD dwKey; + THUNK3216OBJ *pto3216; + + // + // CODEWORK: OLE32 should be setup so that it doesn't callback while the + // thread is detaching. Then this function becomes obsolete. + // + + // delete the 3216 proxy table + pos = _pProxyTbl3216->GetStartPosition(); + + while (pos) + { + _pProxyTbl3216->GetNextAssoc(pos, dwKey, (void FAR* FAR&) pto3216); + + thkDebugOut((DEB_IWARN, "Preparing 3216 Proxy for cleanup: " + "%08lX %08lX %s\n", + pto3216, + pto3216->vpvThis16, + IidIdxString(pto3216->iidx))); + + pto3216->grfFlags |= PROXYFLAG_CLEANEDUP; + } +} + +#if DBG == 1 +void CThkMgr::DebugDump3216() +{ + THUNK3216OBJ *pto3216; + DWORD dwKey; + POSITION pos; + + thkDebugOut((DEB_THUNKMGR, "%s DebugDump3216\n",NestingLevelString())); + + pos = _pProxyTbl3216->GetStartPosition(); + while (pos) + { + _pProxyTbl3216->GetNextAssoc(pos, dwKey, (void FAR* FAR&) pto3216); + thkDebugOut((DEB_THUNKMGR, + "%s Proxy3216:Key:%p->%p, (%s) (%d,%d)\n", + NestingLevelString(), dwKey, pto3216, + IidIdxString(pto3216->iidx), pto3216->cRefLocal, + pto3216->cRef)); + } +} + + +void CThkMgr::DebugDump1632() +{ + THUNK1632OBJ UNALIGNED *pto1632; + DWORD dwKey; + VPVOID vpv; + POSITION pos; + + thkDebugOut((DEB_THUNKMGR, "%s DebugDump1632\n",NestingLevelString())); + + pos = _pProxyTbl1632->GetStartPosition(); + while (pos) + { + _pProxyTbl1632->GetNextAssoc(pos, dwKey, (void FAR* FAR&) vpv); + pto1632 = FIXVDMPTR(vpv, THUNK1632OBJ); + thkDebugOut((DEB_THUNKMGR, + "%s Proxy1632:key:%p->%p, (%s) (%d,%d)\n", + NestingLevelString(), dwKey, pto1632, + IidIdxString(pto1632->iidx), pto1632->cRefLocal, + pto1632->cRef)); + RELVDMPTR(vpv); + } +} +#endif diff --git a/private/ole32/olethunk/olethk32/cthkmgr.hxx b/private/ole32/olethunk/olethk32/cthkmgr.hxx new file mode 100644 index 000000000..affb7a206 --- /dev/null +++ b/private/ole32/olethunk/olethk32/cthkmgr.hxx @@ -0,0 +1,243 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: cthkmgr.hxx +// +// Contents: CThkMgr deklaration +// +// Classes: CThkMgr +// +// Functions: +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- + +#ifndef __CTHKMGR_HXX__ +#define __CTHKMGR_HXX__ + +// +// Describes a request for a custom interface +// +typedef struct tagIIDNODE IIDNODE, *PIIDNODE; +struct tagIIDNODE +{ + IID *piid; + PIIDNODE pNextNode; +}; + +// +// state of thunk call - before or after the 32 or 16 bit call +// +typedef enum +{ + THKSTATE_NOCALL = 0x0000, + THKSTATE_INVOKETHKIN32 = 0x0001, + THKSTATE_INVOKETHKOUT32 = 0x0002, + THKSTATE_INVOKETHKIN16 = 0x0004, + THKSTATE_INVOKETHKOUT16 = 0x0008, + THKSTATE_INVOKETHKOUT16_CLIENTSITE = 0x0010 +} THKSTATE; + +#define THKSTATE_OUT (THKSTATE_INVOKETHKOUT32 | THKSTATE_INVOKETHKOUT16 | \ + THKSTATE_INVOKETHKOUT16_CLIENTSITE) + +//+--------------------------------------------------------------------------- +// +// Class: CThkMgr () +// +// Purpose: +// +// Interface: QueryInterface -- +// AddRef -- +// Release -- +// IsIIDRequested -- +// SetThkState -- +// IsIIDSupported -- +// AddIIDRequest -- +// RemoveIIDRequest -- +// ResetThkState -- +// GetThkState -- +// IsOutParamObj -- +// IsProxy1632 -- +// FreeProxy1632 -- +// QueryInterfaceProxy1632 -- +// AddRefProxy1632 -- +// ReleaseProxy1632 -- +// IsProxy3216 -- +// FreeProxy3216 -- +// QueryInterfaceProxy3216 -- +// AddRefProxy3216 -- +// ReleaseProxy3216 -- +// PrepareForCleanup -- +// DebugDump3216 -- +// Create -- +// ~CThkMgr -- +// CThkMgr -- +// _cRefs -- +// _thkstate -- +// _pProxyTbl3216 -- +// _pProxyTbl1632 -- +// _pCFL1632 -- +// _pCFL3216 -- +// _piidnode -- +// +// History: 6-01-94 JohannP (Johann Posch) Created +// +// Notes: +// +//---------------------------------------------------------------------------- + +// Returns from FindProxy +#define FST_CREATED_NEW 1 +#define FST_USED_EXISTING 2 +#define FST_SHORTCUT 4 + +#define FST_PROXY_STATUS (FST_CREATED_NEW | FST_USED_EXISTING) +#define FST_OBJECT_STATUS (FST_SHORTCUT) + +class CThkMgr : public IThunkManager +{ +public: + // *** IUnknown methods *** + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj); + STDMETHOD_(ULONG,AddRef) (THIS); + STDMETHOD_(ULONG,Release) (THIS); + + // *** IThunkManager methods *** + STDMETHOD_(BOOL, IsIIDRequested) (THIS_ REFIID riid); + STDMETHOD_(BOOL, IsCustom3216Proxy) (THIS_ IUnknown *punk, + REFIID riid); + + // private methods + THKSTATE GetThkState(void) + { + return _thkstate; + }; + void SetThkState(THKSTATE thkstate) + { + _thkstate = thkstate; + }; + BOOL IsOutParamObj(void) + { + return (_thkstate & THKSTATE_OUT) != 0; + } + + BOOL IsIIDSupported (REFIID riid); + BOOL AddIIDRequest (REFIID riid); + void RemoveIIDRequest (REFIID riid); + + void LocalAddRefProxy(CProxy *pprx); + void LockProxy(CProxy *pprx); + + VPVOID CanGetNewProxy1632(IIDIDX iidx); + void FreeNewProxy1632(VPVOID vpv, IIDIDX iidx); + + IUnknown *IsProxy1632(VPVOID vpvObj16); + VPVOID LookupProxy1632(IUnknown *punkThis32) + { + VPVOID vpv; + + if (_pProxyTbl1632->Lookup((DWORD)punkThis32, (void*&)vpv)) + { + return vpv; + } + else + { + return 0; + } + } + + VPVOID FindProxy1632(VPVOID vpvPrealloc, + IUnknown *punkThis32, + IIDIDX iidx, + DWORD *pfst); + VPVOID FindAggregate1632(VPVOID vpvPrealloc, + IUnknown *punkOuter32, + IUnknown *punkThis32, + IIDIDX iidx); + DWORD FreeProxy1632(IUnknown *pUnk32); + void RemoveProxy1632(VPVOID vpv, THUNK1632OBJ *pto); + + SCODE QueryInterfaceProxy1632(VPVOID vpvThis16, + REFIID refiid, + LPVOID *ppv); + DWORD AddRefProxy1632(VPVOID vpvThis16); + DWORD ReleaseProxy1632(VPVOID vpvThis16); + + THUNK3216OBJ *CanGetNewProxy3216(IIDIDX iidx); + void FreeNewProxy3216(THUNK3216OBJ *ptoProxy, IIDIDX iidx); + + VPVOID IsProxy3216(IUnknown *punkObj); + THUNK3216OBJ *LookupProxy3216(VPVOID vpvObj16) + { + THUNK3216OBJ *pto; + + if (_pProxyTbl3216->Lookup((DWORD)vpvObj16, (void *&)pto)) + { + return pto; + } + else + { + return NULL; + } + } + + IUnknown *FindProxy3216(THUNK3216OBJ *ptoPrealloc, + VPVOID vpvThis16, + IIDIDX iidx, + DWORD *pfst); + IUnknown *FindAggregate3216(THUNK3216OBJ *ptoPrealloc, + VPVOID vpvOuter16, + VPVOID vpvThis16, + IIDIDX iidx); + DWORD FreeProxy3216(VPVOID vpUnk16); + void RemoveProxy3216(THUNK3216OBJ *pto); + + SCODE QueryInterfaceProxy3216(THUNK3216OBJ *pto, + REFIID refiid, + LPVOID *ppv); + DWORD AddRefProxy3216(THUNK3216OBJ *pto); + DWORD ReleaseProxy3216(THUNK3216OBJ *pto); + void ReleaseUnreferencedProxy3216(THUNK3216OBJ *pto); + + void PrepareForCleanup( void ); + +#if DBG == 1 + void DebugDump1632(void); + void DebugDump3216(void); +#endif + + void RemoveAllProxies(void); + + // creation + static CThkMgr * Create(void); + ~CThkMgr(); + +private: + CThkMgr(CMapDwordPtr *pPT1632, CMapDwordPtr *pPT3216); + + LONG _cRefs; + THKSTATE _thkstate; + + CMapDwordPtr *_pProxyTbl3216; + CMapDwordPtr *_pProxyTbl1632; + + // list of requested iids + PIIDNODE _piidnode; + + // List of proxy holders for controlling unknowns + PROXYHOLDER *_pphHolders; + + // Holder manipulation routines + void ReleaseHolder(PROXYHOLDER *pph); + inline void AddRefHolder(PROXYHOLDER *pph); + void AddProxyToHolder(PROXYHOLDER *pph, + CProxy *pprxReal, + PROXYPTR &pprx); + PROXYHOLDER *NewHolder(DWORD dwFlags); +}; + +#endif // ifndef __CTHKMGR_HXX__ diff --git a/private/ole32/olethunk/olethk32/daytona/makefile b/private/ole32/olethunk/olethk32/daytona/makefile new file mode 100644 index 000000000..734e18727 --- /dev/null +++ b/private/ole32/olethunk/olethk32/daytona/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the subcomponents of NTOS. +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/ole32/olethunk/olethk32/daytona/olethk32.def b/private/ole32/olethunk/olethk32/daytona/olethk32.def new file mode 100644 index 000000000..722e5dbdc --- /dev/null +++ b/private/ole32/olethunk/olethk32/daytona/olethk32.def @@ -0,0 +1,27 @@ +#ifdef FLAT + +LIBRARY OLETHK32 + +DESCRIPTION '32-bit Ole 2.0 Interoperability Code' + +EXPORTS + InvokeOn32 @3 + IntOpInitialize @4 + CallbackProcessing_3216 @5 + IUnknownObj32 @6 + CSm16ReleaseHandler_Release32 @8 + ThkMgrInitialize @9 + ThkMgrUninitialize @10 + TransformHRESULT_1632 @11 + TransformHRESULT_3216 @12 + ConvertObjDescriptor @13 + ConvertHr1632Thunk @14 + ConvertHr3216Thunk @15 + IntOpUninitialize @16 + ThkAddAppCompatFlag @18 +#if DBG == 1 + ThkCallOutputFunctions @19 +#endif + +#endif // FLAT + diff --git a/private/ole32/olethunk/olethk32/daytona/sources b/private/ole32/olethunk/olethk32/daytona/sources new file mode 100644 index 000000000..d838f82b5 --- /dev/null +++ b/private/ole32/olethunk/olethk32/daytona/sources @@ -0,0 +1,103 @@ +!IF 0 + +Copyright (c) 1994 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + Standard definitions file for olethk32.dll, the OLE 2.0 interoperability + 32-bit thunk handler. + +Author: + + Bob Day (bobday) 18-Feb-1994 + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl +# ..\..\com\coll\daytona\obj\*\coll.lib + +!ENDIF + +MAJORCOMP=cairole +MINORCOMP=interop + +TARGETNAME=olethk32 +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=DYNLINK +TARGETLIBS= \ + $(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\gdi32.lib \ + $(BASEDIR)\public\sdk\lib\*\user32.lib \ + $(BASEDIR)\public\sdk\lib\*\advapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\ntvdm.lib \ + $(BASEDIR)\public\sdk\lib\*\oemuni.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + $(BASEDIR)\public\sdk\lib\*\wow32.lib \ + $(BASEDIR)\public\sdk\lib\*\ole32.lib \ + $(BASEDIR)\public\sdk\lib\*\uuid.lib \ + ..\..\..\common\cruntime\daytona\obj\*\cruntime.lib \ + $(BASEDIR)\public\sdk\lib\*\ntdll.lib + +INCLUDES=..\.; \ + $(BASEDIR)\public\sdk\inc; \ + ..\..\h; \ + ..\..\..\ih; + + +# +# 0x6000000 should be fairly safe even though it is in usermode address range. +# This DLL should only be loaded by WOW and since WOW doesn't normally load any +# usermode DLLs, we can get away with loading it wherever we want. Feel free +# to move it about if you really understand coffbase.txt. -BobDay +# +DLLBASE=0x6000000 +DLLENTRY=DllEntryPoint +DLLDEF=obj\*\olethk32.def + +C_DEFINES=$(C_DEFINES) \ + -DFLAT \ + -DWIN32=100 \ + -D_NT1X_=100 \ + -DUNICODE \ + -D_UNICODE + +!IF $(386) +USE_NOLIBS=1 +!ELSE +USE_CRTDLL=1 +!ENDIF + +SOURCES=\ + ..\dllentry.cxx \ + ..\tlsthk.cxx \ + ..\thkmgr.cxx \ + ..\freelist.cxx \ + ..\cthkmgr.cxx \ + ..\olethk32.cxx \ + ..\inv16.cxx \ + ..\inv32.cxx \ + ..\thoputil.cxx \ + ..\thop16.cxx \ + ..\thop32.cxx \ + ..\thopiint.cxx \ + ..\tc1632.cxx \ + ..\thtblapi.cxx \ + ..\vtblapi.cxx \ + ..\iidtothi.cxx \ + ..\dbgapi.cxx \ + ..\dbgitbl.cxx \ + ..\map_kv.cxx \ + ..\plex.cxx \ + ..\apinot.cxx \ + ..\olethk32.rc \ + ..\alias.cxx \ + ..\mmodel.cxx \ + ..\stalloc.cxx \ + ..\heap.cxx + +PRECOMPILED_INCLUDE=..\headers.cxx +PRECOMPILED_PCH=headers.pch +PRECOMPILED_OBJ=headers.obj diff --git a/private/ole32/olethunk/olethk32/dbgapi.cxx b/private/ole32/olethunk/olethk32/dbgapi.cxx new file mode 100644 index 000000000..f69ec776c --- /dev/null +++ b/private/ole32/olethunk/olethk32/dbgapi.cxx @@ -0,0 +1,127 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: dbgapi.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +#include <headers.cxx> +#pragma hdrstop + +#if DBG == 1 + +char *apszApiNames[] = +{ + "CoInitialize" +, "CoUninitialize" +, "CoGetClassObject" +, "CoRegisterClassObject" +, "CoRevokeClassObject" +, "CoMarshalInterface" +, "CoUnmarshalInterface" +, "CoReleaseMarshalData" +, "CoDisconnectObject" +, "CoLockObjectExternal" +, "CoGetStandardMarshal" +, "CoIsHandlerConnected" +, "CoFreeAllLibraries" +, "CoFreeUnusedLibraries" +, "CoCreateInstance" +, "CLSIDFromString" +, "CoIsOle1Class" +, "ProgIDFromCLSID" +, "CLSIDFromProgID" +, "CoCreateGuid" +, "CoFileTimeToDosDateTime" +, "CoDosDateTimeToFileTime" +, "CoFileTimeNow" +, "CoRegisterMessageFilter" +, "CoGetTreatAsClass" +, "CoTreatAsClass" +, "DllGetClassObject" +, "StgCreateDocfile" +, "StgCreateDocfileOnILockBytes" +, "StgOpenStorage" +, "StgOpenStorageOnILockBytes" +, "StgIsStorageFile" +, "StgIsStorageILockBytes" +, "StgSetTimes" +, "CreateDataAdviseHolder" +, "CreateDataCache" +, "BindMoniker" +, "MkParseDisplayName" +, "MonikerRelativePathTo" +, "MonikerCommonPrefixWith" +, "CreateBindCtx" +, "CreateGenericComposite" +, "GetClassFile" +, "CreateFileMoniker" +, "CreateItemMoniker" +, "CreateAntiMoniker" +, "CreatePointerMoniker" +, "GetRunningObjectTable" +, "ReadClassStg" +, "WriteClassStg" +, "ReadClassStm" +, "WriteClassStm" +, "WriteFmtUserTypeStg" +, "ReadFmtUserTypeStg" +, "OleInitialize" +, "OleUninitialize" +, "OleQueryLinkFromData" +, "OleQueryCreateFromData" +, "OleCreate" +, "OleCreateFromData" +, "OleCreateLinkFromData" +, "OleCreateStaticFromData" +, "OleCreateLink" +, "OleCreateLinkToFile" +, "OleCreateFromFile" +, "OleLoad" +, "OleSave" +, "OleLoadFromStream" +, "OleSaveToStream" +, "OleSetContainedObject" +, "OleNoteObjectVisible" +, "RegisterDragDrop" +, "RevokeDragDrop" +, "DoDragDrop" +, "OleSetClipboard" +, "OleGetClipboard" +, "OleFlushClipboard" +, "OleIsCurrentClipboard" +, "OleCreateMenuDescriptor" +, "OleSetMenuDescriptor" +, "OleDestroyMenuDescriptor" +, "OleDraw" +, "OleRun" +, "OleIsRunning" +, "OleLockRunning" +, "CreateOleAdviseHolder" +, "OleCreateDefaultHandler" +, "OleCreateEmbeddingHelper" +, "OleRegGetUserType" +, "OleRegGetMiscStatus" +, "OleRegEnumFormatEtc" +, "OleRegEnumVerbs" +, "OleConvertIStorageToOLESTREAM" +, "OleConvertOLESTREAMToIStorage" +, "OleConvertIStorageToOLESTREAMEx" +, "OleConvertOLESTREAMToIStorageEx" +, "OleDoAutoConvert" +, "OleGetAutoConvert" +, "OleSetAutoConvert" +, "GetConvertStg" +, "SetConvertStg" +, "ReadOleStg" +, "WriteOleStg" +}; + +#endif // DBG diff --git a/private/ole32/olethunk/olethk32/dbgint.cxx b/private/ole32/olethunk/olethk32/dbgint.cxx new file mode 100644 index 000000000..5dd572448 --- /dev/null +++ b/private/ole32/olethunk/olethk32/dbgint.cxx @@ -0,0 +1,682 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: dbgint.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +#if DBG == 1 + +char *apszIUnknownNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +}; +char *apszIClassFactoryNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "CreateInstance" +, "LockServer" +}; +char *apszIMarshalNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetUnmarshalClass" +, "GetMarshalSizeMax" +, "MarshalInterface" +, "UnmarshalInterface" +, "ReleaseMarshalData" +, "DisconnectObject" +}; +char *apszIStdMarshalInfoNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetClassForHandler" +}; +char *apszIMessageFilterNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "HandleInComingCall" +, "RetryRejectedCall" +, "MessagePending" +}; +char *apszIExternalConnectionNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "AddConnection" +, "ReleaseConnection" +}; +char *apszIEnumStringNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Next" +, "Skip" +, "Reset" +, "Clone" +}; +char *apszIEnumUnknownNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Next" +, "Skip" +, "Reset" +, "Clone" +}; +char *apszIEnumSTATSTGNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Next" +, "Skip" +, "Reset" +, "Clone" +}; +char *apszILockBytesNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "ReadAt" +, "WriteAt" +, "Flush" +, "SetSize" +, "LockRegion" +, "UnlockRegion" +, "Stat" +}; +char *apszIStreamNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Read" +, "Write" +, "Seek" +, "SetSize" +, "CopyTo" +, "Commit" +, "Revert" +, "LockRegion" +, "UnlockRegion" +, "Stat" +, "Clone" +}; +char *apszIStorageNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "CreateStream" +, "OpenStream" +, "CreateStorage" +, "OpenStorage" +, "CopyTo" +, "MoveElementTo" +, "Commit" +, "Revert" +, "EnumElements" +, "DestroyElement" +, "RenameElement" +, "SetElementTimes" +, "SetClass" +, "SetStateBits" +, "Stat" +}; +char *apszIRootStorageNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "SwitchToFile" +}; +char *apszIEnumFORMATETCNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Next" +, "Skip" +, "Reset" +, "Clone" +}; +char *apszIEnumSTATDATANames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Next" +, "Skip" +, "Reset" +, "Clone" +}; +char *apszIDataObjectNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetData" +, "GetDataHere" +, "QueryGetData" +, "GetCanonicalFormatEtc" +, "SetData" +, "EnumFormatEtc" +, "DAdvise" +, "DUnadvise" +, "EnumDAdvise" +}; +char *apszIViewObjectNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Draw" +, "GetColorSet" +, "Freeze" +, "Unfreeze" +, "SetAdvise" +, "GetAdvise" +}; +char *apszIViewObject2Names[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Draw" +, "GetColorSet" +, "Freeze" +, "Unfreeze" +, "SetAdvise" +, "GetAdvise" +, "GetExtent" +}; +char *apszIAdviseSinkNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "OnDataChange" +, "OnViewChange" +, "OnRename" +, "OnSave" +, "OnClose" +}; +char *apszIAdviseSink2Names[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "OnDataChange" +, "OnViewChange" +, "OnRename" +, "OnSave" +, "OnClose" +, "OnLinkSrcChange" +}; +char *apszIDataAdviseHolderNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Advise" +, "Unadvise" +, "EnumAdvise" +, "SendOnDataChange" +}; +char *apszIOleCacheNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Cache" +, "Uncache" +, "EnumCache" +, "InitCache" +, "SetData" +}; +char *apszIOleCache2Names[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Cache" +, "Uncache" +, "EnumCache" +, "InitCache" +, "SetData" +, "UpdateCache" +, "DiscardCache" +}; +char *apszIOleCacheControlNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "OnRun" +, "OnStop" +}; +char *apszIDropTargetNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "DragEnter" +, "DragOver" +, "DragLeave" +, "Drop" +}; +char *apszIDropSourceNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "QueryContinueDrag" +, "GiveFeedback" +}; +char *apszIPersistNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetClassID" +}; +char *apszIPersistStorageNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetClassID" +, "IsDirty" +, "InitNew" +, "Load" +, "Save" +, "SaveCompleted" +, "HandsOffStorage" +}; +char *apszIPersistStreamNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetClassID" +, "IsDirty" +, "Load" +, "Save" +, "GetSizeMax" +}; +char *apszIPersistFileNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetClassID" +, "IsDirty" +, "Load" +, "Save" +, "SaveCompleted" +, "GetCurFile" +}; +char *apszIBindCtxNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "RegisterObjectBound" +, "RevokeObjectBound" +, "ReleaseBoundObjects" +, "SetBindOptions" +, "GetBindOptions" +, "GetRunningObjectTable" +, "RegisterObjectParam" +, "GetObjectParam" +, "EnumObjectParam" +, "RevokeObjectParam" +}; +char *apszIMonikerNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetClassID" +, "IsDirty" +, "Load" +, "Save" +, "GetSizeMax" +, "BindToObject" +, "BindToStorage" +, "Reduce" +, "ComposeWith" +, "Enum" +, "IsEqual" +, "Hash" +, "IsRunning" +, "GetTimeOfLastChange" +, "Inverse" +, "CommonPrefixWith" +, "RelativePathTo" +, "GetDisplayName" +, "ParseDisplayName" +, "IsSystemMoniker" +}; +char *apszIRunningObjectTableNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Register" +, "Revoke" +, "IsRunning" +, "GetObject" +, "NoteChangeTime" +, "GetTimeOfLastChange" +, "EnumRunning" +}; +char *apszIEnumMonikerNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Next" +, "Skip" +, "Reset" +, "Clone" +}; +char *apszIEnumOLEVERBNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Next" +, "Skip" +, "Reset" +, "Clone" +}; +char *apszIOleObjectNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "SetClientSite" +, "GetClientSite" +, "SetHostNames" +, "Close" +, "SetMoniker" +, "GetMoniker" +, "InitFromData" +, "GetClipboardData" +, "DoVerb" +, "EnumVerbs" +, "Update" +, "IsUpToDate" +, "GetUserClassID" +, "GetUserType" +, "SetExtent" +, "GetExtent" +, "Advise" +, "Unadvise" +, "EnumAdvise" +, "GetMiscStatus" +, "SetColorScheme" +}; +char *apszIOleClientSiteNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "SaveObject" +, "GetMoniker" +, "GetContainer" +, "ShowObject" +, "OnShowWindow" +, "RequestNewObjectLayout" +}; +char *apszIRunnableObjectNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetRunningClass" +, "Run" +, "IsRunning" +, "LockRunning" +, "SetContainedObject" +}; +char *apszIParseDisplayNameNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "ParseDisplayName" +}; +char *apszIOleContainerNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "ParseDisplayName" +, "EnumObjects" +, "LockContainer" +}; +char *apszIOleItemContainerNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "ParseDisplayName" +, "EnumObjects" +, "LockContainer" +, "GetObject" +, "GetObjectStorage" +, "IsRunning" +}; +char *apszIOleAdviseHolderNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Advise" +, "Unadvise" +, "EnumAdvise" +, "SendOnRename" +, "SendOnSave" +, "SendOnClose" +}; +char *apszIOleLinkNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "SetUpdateOptions" +, "GetUpdateOptions" +, "SetSourceMoniker" +, "GetSourceMoniker" +, "SetSourceDisplayName" +, "GetSourceDisplayName" +, "BindToSource" +, "BindIfRunning" +, "GetBoundSource" +, "UnbindSource" +, "Update" +}; +char *apszIOleWindowNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetWindow" +, "ContextSensitiveHelp" +}; +char *apszIOleInPlaceObjectNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetWindow" +, "ContextSensitiveHelp" +, "InPlaceDeactivate" +, "UIDeactivate" +, "SetObjectRects" +, "ReactivateAndUndo" +}; +char *apszIOleInPlaceActiveObjectNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetWindow" +, "ContextSensitiveHelp" +, "TranslateAccelerator" +, "OnFrameWindowActivate" +, "OnDocWindowActivate" +, "ResizeBorder" +, "EnableModeless" +}; +char *apszIOleInPlaceUIWindowNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetWindow" +, "ContextSensitiveHelp" +, "GetBorder" +, "RequestBorderSpace" +, "SetBorderSpace" +, "SetActiveObject" +}; +char *apszIOleInPlaceFrameNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetWindow" +, "ContextSensitiveHelp" +, "GetBorder" +, "RequestBorderSpace" +, "SetBorderSpace" +, "SetActiveObject" +, "InsertMenus" +, "SetMenu" +, "RemoveMenus" +, "SetStatusText" +, "EnableModeless" +, "TranslateAccelerator" +}; +char *apszIOleInPlaceSiteNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetWindow" +, "ContextSensitiveHelp" +, "CanInPlaceActivate" +, "OnInPlaceActivate" +, "OnUIActivate" +, "GetWindowContext" +, "Scroll" +, "OnUIDeactivate" +, "OnInPlaceDeactivate" +, "DiscardUndoState" +, "DeactivateAndUndo" +, "OnPosRectChange" +}; +char *apszIRpcChannelBufferNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetBuffer" +, "SendReceive" +, "FreeBuffer" +, "GetDestCtx" +, "IsConnected" +}; +char *apszIRpcProxyBufferNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Connect" +, "Disconnect" +}; +char *apszIRpcStubBufferNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Connect" +, "Disconnect" +, "Invoke" +, "IsIIDSupported" +, "CountRefs" +, "DebugServerQueryInterface" +, "DebugServerRelease" +}; +char *apszIPSFactoryBufferNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "CreateProxy" +, "CreateStub" +}; +char *apszIRpcChannelNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "GetStream" +, "Call" +, "GetDestCtx" +, "IsConnected" +}; +char *apszIRpcProxyNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Connect" +, "Disconnect" +}; +char *apszIRpcStubNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "Connect" +, "Disconnect" +, "Invoke" +, "IsIIDSupported" +, "CountRefs" +}; +char *apszIPSFactoryNames[] = +{ + "QueryInterface" +, "AddRef" +, "Release" +, "CreateProxy" +, "CreateStub" +}; + +#endif // DBG diff --git a/private/ole32/olethunk/olethk32/dbginv.hxx b/private/ole32/olethunk/olethk32/dbginv.hxx new file mode 100644 index 000000000..274e0dd09 --- /dev/null +++ b/private/ole32/olethunk/olethk32/dbginv.hxx @@ -0,0 +1,26 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: dbginv.hxx +// +// Contents: Header for invocation debugging +// +// History: 08-Mar-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#ifndef __DBGINV_HXX__ +#define __DBGINV_HXX__ + +typedef struct _INTERFACENAMES +{ + char *pszInterface; + char **ppszMethodNames; +} INTERFACENAMES; + +extern INTERFACENAMES inInterfaceNames[]; +extern char *apszApiNames[]; + +#endif // #ifndef __DBGINV_HXX__ diff --git a/private/ole32/olethunk/olethk32/dbgitbl.cxx b/private/ole32/olethunk/olethk32/dbgitbl.cxx new file mode 100644 index 000000000..2c0c78cb6 --- /dev/null +++ b/private/ole32/olethunk/olethk32/dbgitbl.cxx @@ -0,0 +1,82 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: dbgitbl.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +#include <headers.cxx> +#pragma hdrstop + +#include "dbgint.cxx" +#if DBG == 1 + +INTERFACENAMES inInterfaceNames[] = +{ + "IUnknown", apszIUnknownNames +, "IClassFactory", apszIClassFactoryNames +, "IMarshal", apszIMarshalNames +, "IStdMarshalInfo", apszIStdMarshalInfoNames +, "IMessageFilter", apszIMessageFilterNames +, "IExternalConnection", apszIExternalConnectionNames +, "IEnumString", apszIEnumStringNames +, "IEnumUnknown", apszIEnumUnknownNames +, "IEnumSTATSTG", apszIEnumSTATSTGNames +, "ILockBytes", apszILockBytesNames +, "IStream", apszIStreamNames +, "IStorage", apszIStorageNames +, "IRootStorage", apszIRootStorageNames +, "IEnumFORMATETC", apszIEnumFORMATETCNames +, "IEnumSTATDATA", apszIEnumSTATDATANames +, "IDataObject", apszIDataObjectNames +, "IViewObject", apszIViewObjectNames +, "IViewObject2", apszIViewObject2Names +, "IAdviseSink", apszIAdviseSinkNames +, "IAdviseSink2", apszIAdviseSink2Names +, "IDataAdviseHolder", apszIDataAdviseHolderNames +, "IOleCache", apszIOleCacheNames +, "IOleCache2", apszIOleCache2Names +, "IOleCacheControl", apszIOleCacheControlNames +, "IDropTarget", apszIDropTargetNames +, "IDropSource", apszIDropSourceNames +, "IPersist", apszIPersistNames +, "IPersistStorage", apszIPersistStorageNames +, "IPersistStream", apszIPersistStreamNames +, "IPersistFile", apszIPersistFileNames +, "IBindCtx", apszIBindCtxNames +, "IMoniker", apszIMonikerNames +, "IRunningObjectTable", apszIRunningObjectTableNames +, "IEnumMoniker", apszIEnumMonikerNames +, "IEnumOLEVERB", apszIEnumOLEVERBNames +, "IOleObject", apszIOleObjectNames +, "IOleClientSite", apszIOleClientSiteNames +, "IRunnableObject", apszIRunnableObjectNames +, "IParseDisplayName", apszIParseDisplayNameNames +, "IOleContainer", apszIOleContainerNames +, "IOleItemContainer", apszIOleItemContainerNames +, "IOleAdviseHolder", apszIOleAdviseHolderNames +, "IOleLink", apszIOleLinkNames +, "IOleWindow", apszIOleWindowNames +, "IOleInPlaceObject", apszIOleInPlaceObjectNames +, "IOleInPlaceActiveObject", apszIOleInPlaceActiveObjectNames +, "IOleInPlaceUIWindow", apszIOleInPlaceUIWindowNames +, "IOleInPlaceFrame", apszIOleInPlaceFrameNames +, "IOleInPlaceSite", apszIOleInPlaceSiteNames +, "IRpcChannelBuffer", apszIRpcChannelBufferNames +, "IRpcProxyBuffer", apszIRpcProxyBufferNames +, "IRpcStubBuffer", apszIRpcStubBufferNames +, "IPSFactoryBuffer", apszIPSFactoryBufferNames +, "IRpcChannel", apszIRpcChannelNames +, "IRpcProxy", apszIRpcProxyNames +, "IRpcStub", apszIRpcStubNames +, "IPSFactory", apszIPSFactoryNames +}; + +#endif // DBG diff --git a/private/ole32/olethunk/olethk32/dirs b/private/ole32/olethunk/olethk32/dirs new file mode 100644 index 000000000..b7d4cd275 --- /dev/null +++ b/private/ole32/olethunk/olethk32/dirs @@ -0,0 +1,40 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + dirs. + +Abstract: + + This file specifies the subdirectories of the current directory that + contain component makefiles. + + +Author: + + Drew Bliss (DrewB) 21-Dec-1993 + +!ENDIF + +# +# This is a list of all subdirectories that build required components. +# Each subdirectory name should appear on a line by itself. The build +# follows the order in which the subdirectories are specified. +# + +DIRS= + +# +# This is a list of all subdirectories that build optional components. +# Each subdirectory name should appear on a line by itself. The build +# follows the order in which the subdirectories are specified. +# + +# +# Note that is currently omitted because there is no difference +# from the daytona binary. +OPTIONAL_DIRS= \ + \ + daytona diff --git a/private/ole32/olethunk/olethk32/dllentry.cxx b/private/ole32/olethunk/olethk32/dllentry.cxx new file mode 100644 index 000000000..394b4bc8b --- /dev/null +++ b/private/ole32/olethunk/olethk32/dllentry.cxx @@ -0,0 +1,56 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: dllentry.cxx +// +// Contents: DLL entry point code +// +// History: 24-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +extern "C" +{ +BOOL WINAPI _CRT_INIT (HANDLE hDll, DWORD dwReason, LPVOID lpReserved); +BOOL _CRTAPI1 LibMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved); +}; + +extern "C" BOOL __stdcall DllEntryPoint (HANDLE hDll, DWORD dwReason, + LPVOID lpReserved) +{ + BOOL fRc; + + if ((dwReason == DLL_PROCESS_ATTACH) || (dwReason == DLL_THREAD_ATTACH)) + { + // If this is an attach, initialize the Cruntimes first + if (fRc = _CRT_INIT(hDll, dwReason, lpReserved)) + { + fRc = LibMain(hDll, dwReason, lpReserved); + } + } + else + { + // This is a detach so call the Cruntimes second + LibMain(hDll, dwReason, lpReserved); + fRc = _CRT_INIT(hDll, dwReason, lpReserved); + } + + return fRc; +} + +extern "C" BOOL __stdcall DllMain (HANDLE hDll, DWORD dwReason, + LPVOID lpReserved) +{ + // This is not currently used...but must be present to avoid + // an undefined symbol + + return FALSE; +} + + + diff --git a/private/ole32/olethunk/olethk32/fntomthd.cxx b/private/ole32/olethunk/olethk32/fntomthd.cxx new file mode 100644 index 000000000..ec62999e6 --- /dev/null +++ b/private/ole32/olethunk/olethk32/fntomthd.cxx @@ -0,0 +1,2082 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: fntomthd.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +BYTE CONST ftmIClassFactory[] = +{ + 3, + 4 +}; +BYTE CONST ftmIMarshal[] = +{ + 6, + 0, + 0, + 0, + 8, + 7, + 0, + 3, + 4, + 5 +}; +BYTE CONST ftmIStdMarshalInfo[] = +{ + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIMessageFilter[] = +{ + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 5 +}; +BYTE CONST ftmIExternalConnection[] = +{ + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4 +}; +BYTE CONST ftmIEnumString[] = +{ + 0, + 0, + 0, + 0, + 6, + 4, + 5, + 0, + 0, + 0, + 0, + 3 +}; +BYTE CONST ftmIEnumUnknown[] = +{ + 0, + 0, + 0, + 0, + 6, + 4, + 5, + 0, + 0, + 0, + 0, + 3 +}; +BYTE CONST ftmIEnumSTATSTG[] = +{ + 0, + 0, + 0, + 0, + 6, + 4, + 5, + 0, + 0, + 0, + 0, + 3 +}; +BYTE CONST ftmILockBytes[] = +{ + 0, + 0, + 9, + 0, + 0, + 0, + 5, + 0, + 0, + 0, + 0, + 0, + 3, + 4, + 6, + 7, + 8 +}; +BYTE CONST ftmIStream[] = +{ + 4, + 0, + 12, + 0, + 13, + 8, + 9, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 6, + 11, + 10, + 5, + 7 +}; +BYTE CONST ftmIStorage[] = +{ + 0, + 0, + 13, + 15, + 12, + 9, + 10, + 0, + 0, + 6, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 4, + 5, + 8, + 11, + 14, + 16, + 17 +}; +BYTE CONST ftmIRootStorage[] = +{ + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIEnumFORMATETC[] = +{ + 0, + 0, + 0, + 0, + 6, + 4, + 5, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIEnumSTATDATA[] = +{ + 0, + 0, + 0, + 0, + 6, + 4, + 5, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIDataObject[] = +{ + 0, + 0, + 6, + 11, + 10, + 5, + 0, + 0, + 0, + 0, + 0, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9, + 4, + 3, + 8 +}; +BYTE CONST ftmIViewObject[] = +{ + 8, + 0, + 0, + 0, + 0, + 6, + 0, + 0, + 0, + 4, + 0, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 0, + 0, + 0, + 3 +}; +BYTE CONST ftmIViewObject2[] = +{ + 8, + 0, + 0, + 0, + 0, + 6, + 0, + 0, + 0, + 4, + 0, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9, + 5, + 0, + 0, + 0, + 3 +}; +BYTE CONST ftmIAdviseSink[] = +{ + 0, + 0, + 0, + 0, + 0, + 5, + 6, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 3, + 0, + 7 +}; +BYTE CONST ftmIAdviseSink2[] = +{ + 0, + 0, + 0, + 0, + 8, + 5, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 3, + 0, + 6 +}; +BYTE CONST ftmIDataAdviseHolder[] = +{ + 0, + 0, + 0, + 0, + 5, + 4, + 0, + 0, + 0, + 0, + 0, + 6, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIOleCache[] = +{ + 7, + 0, + 0, + 6, + 5, + 4, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIOleCache2[] = +{ + 7, + 9, + 0, + 6, + 5, + 4, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8 +}; +BYTE CONST ftmIOleCacheControl[] = +{ + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 0 +}; +BYTE CONST ftmIDropTarget[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 0, + 3, + 4, + 6 +}; +BYTE CONST ftmIDropSource[] = +{ + 0, + 0, + 0, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIPersist[] = +{ + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIPersistStorage[] = +{ + 0, + 8, + 0, + 6, + 5, + 3, + 9, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7, + 0, + 4, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIPersistStream[] = +{ + 0, + 0, + 0, + 7, + 5, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 0, + 4, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIPersistFile[] = +{ + 0, + 0, + 0, + 8, + 7, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 5, + 0, + 4, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIBindCtx[] = +{ + 0, + 7, + 0, + 6, + 4, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 9, + 0, + 5, + 0, + 0, + 0, + 0, + 8, + 11, + 12 +}; +BYTE CONST ftmIMoniker[] = +{ + 16, + 22, + 19, + 17, + 14, + 13, + 0, + 0, + 0, + 0, + 0, + 15, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 21, + 10, + 9, + 8, + 18, + 12, + 6, + 0, + 4, + 11, + 0, + 0, + 0, + 7, + 5, + 3, + 20 +}; +BYTE CONST ftmIRunningObjectTable[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 8, + 7, + 6, + 0, + 0, + 0, + 0, + 0, + 0, + 9, + 5, + 4, + 0 +}; +BYTE CONST ftmIEnumMoniker[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 0, + 0, + 0, + 0, + 0, + 6, + 4, + 3 +}; +BYTE CONST ftmIEnumOLEVERB[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 0, + 0, + 0, + 0, + 0, + 6, + 4, + 3 +}; +BYTE CONST ftmIOleObject[] = +{ + 0, + 21, + 16, + 20, + 15, + 12, + 14, + 0, + 0, + 11, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 7, + 5, + 0, + 13, + 9, + 0, + 0, + 0, + 6, + 4, + 3, + 8, + 17, + 18, + 19, + 22, + 23 +}; +BYTE CONST ftmIOleClientSite[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 7, + 4, + 0, + 0, + 0, + 0, + 5, + 8 +}; +BYTE CONST ftmIRunnableObject[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7, + 4, + 0, + 0, + 0, + 0, + 6, + 3, + 5 +}; +BYTE CONST ftmIParseDisplayName[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIOleContainer[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 5, + 0 +}; +BYTE CONST ftmIOleItemContainer[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 0, + 7, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8, + 0, + 0, + 0, + 0, + 4, + 5, + 0 +}; +BYTE CONST ftmIOleAdviseHolder[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8, + 0, + 0, + 0, + 0, + 0, + 6, + 5, + 0, + 0, + 0, + 0, + 3, + 4, + 7 +}; +BYTE CONST ftmIOleLink[] = +{ + 0, + 0, + 0, + 13, + 11, + 8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 12, + 0, + 0, + 0, + 0, + 7, + 6, + 4, + 0, + 0, + 0, + 9, + 5, + 3, + 10 +}; +BYTE CONST ftmIOleWindow[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + 0, + 3, + 0 +}; +BYTE CONST ftmIOleInPlaceObject[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + 7, + 3, + 5 +}; +BYTE CONST ftmIOleInPlaceActiveObject[] = +{ + 0, + 0, + 0, + 0, + 9, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 5, + 4, + 8, + 0, + 0, + 0, + 0, + 3, + 0 +}; +BYTE CONST ftmIOleInPlaceUIWindow[] = +{ + 0, + 0, + 0, + 0, + 0, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 5, + 4, + 0, + 0, + 0, + 0, + 8, + 3, + 0 +}; +BYTE CONST ftmIOleInPlaceFrame[] = +{ + 0, + 13, + 0, + 12, + 11, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 5, + 4, + 10, + 0, + 0, + 9, + 8, + 3, + 0, + 14 +}; +BYTE CONST ftmIOleInPlaceSite[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 7, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 0, + 0, + 0, + 0, + 14, + 10, + 4, + 0, + 0, + 0, + 0, + 0, + 3, + 5, + 0, + 9, + 11, + 12, + 13 +}; +BYTE CONST ftmIRpcChannelBuffer[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 4, + 3, + 5, + 0, + 0, + 0, + 0, + 0, + 7 +}; +BYTE CONST ftmIRpcProxyBuffer[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 4 +}; +BYTE CONST ftmIRpcStubBuffer[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 9, + 8, + 6, + 0, + 0, + 0, + 0, + 5, + 3, + 0, + 0, + 0, + 0, + 7, + 4 +}; +BYTE CONST ftmIPSFactoryBuffer[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +BYTE CONST ftmIRpcChannel[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 4, + 0, + 0, + 0, + 0, + 0, + 6 +}; +BYTE CONST ftmIRpcProxy[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 4 +}; +BYTE CONST ftmIRpcStub[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 6, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 7, + 4 +}; +BYTE CONST ftmIPSFactory[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; diff --git a/private/ole32/olethunk/olethk32/freelist.cxx b/private/ole32/olethunk/olethk32/freelist.cxx new file mode 100644 index 000000000..6ba44e5e9 --- /dev/null +++ b/private/ole32/olethunk/olethk32/freelist.cxx @@ -0,0 +1,468 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: freelist.cxx +// +// Contents: CFreeList implementations +// +// History: 07-Jul-94 BobDay Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +// +// Each element, when it is free, has a pointer stored within it that +// points to the next free element. We can do this because we know that +// the element is free, all of its data is unused. These pointers are used +// as DWORDs since they can be virtual pointers (16:16). +// +#define CALC_NEXTPTR(lpElement) \ + ((LPDWORD)((DWORD)(lpElement) + m_iNextPtrOffset)) + +// +// Each block of elements has a pointer to the next block of elements. We +// allocate extra room for this pointer just after all of the elements within +// the block. These pointers are used as DWORDs since they can be virtual +// pointers (16:16). + +#define CALC_BLOCKNEXTPTR(lpBlock,dwElementSectionSize) \ + ((LPDWORD)((DWORD)(lpBlock) + (dwElementSectionSize))) + +// +// Here are our global free lists, created on DLL load +// The block sizes are generally -1 to allow space for block +// list overhead +// +CFreeList flFreeList16( // THUNK1632OBJ free list + &mmodel16Public, + sizeof(THUNK1632OBJ), + 63, + FIELD_OFFSET(THUNK1632OBJ, pphHolder)); + +CFreeList flFreeList32( // THUNK3216OBJ free list + &mmodel32, + sizeof(THUNK3216OBJ), + 63, + FIELD_OFFSET(THUNK3216OBJ, pphHolder)); + +CFreeList flHolderFreeList( // PROXYHOLDER free list + &mmodel32, + sizeof(PROXYHOLDER), + 63, + FIELD_OFFSET(PROXYHOLDER, pphNext)); + +CFreeList flRequestFreeList( // IID request free list + &mmodel32, + sizeof(IIDNODE), + 7, + FIELD_OFFSET(IIDNODE, pNextNode)); + +//+--------------------------------------------------------------------------- +// +// Method: CFreeList::CFreeList +// +// Arguments: pmm - Memory model to use +// iElementSize - The size of the structure being made into a +// free list. e.g. sizeof THUNK1632OBJ +// iElementsPerBlock - How many elements to allocate at a time +// (a block contains this many elements). +// iNextPtrOffset - Offset within the element's structure for +// the place to store the free list's next +// element pointer. Sometimes (for debugging, +// etc.) it is desirable to make this NOT 0 +// (the beginning of the element structure). +// +// Synopsis: constructor for CFreeList class +// +// History: 6-01-94 JohannP (Johann Posch) Created +// 7-05-94 BobDay (Bob Day) Changed it to be list based +// +//---------------------------------------------------------------------------- +CFreeList::CFreeList( CMemoryModel *pmm, + UINT iElementSize, + UINT iElementsPerBlock, + UINT iNextPtrOffset ) +{ + // + // Save away the allocator information + // + m_pmm = pmm; + m_iElementSize = iElementSize; + m_iElementsPerBlock = iElementsPerBlock; + m_iNextPtrOffset = iNextPtrOffset; + + // + // Set the list of elements to empty + // + m_dwHeadElement = 0; + m_dwTailElement = 0; + + // + // Set the list of blocks to empty + // + m_dwHeadBlock = 0; +} + +//+--------------------------------------------------------------------------- +// +// Method: CFreeList::AllocElement +// +// Synopsis: Allocates an element from the various blocks of elements +// and allocates a new block if necessary. +// +// Returns: 0 if failed to alloc an element, +// otherwise the DWORD representing the alloc'd element. +// +// History: 7-05-94 BobDay (Bob Day) Created +// +//---------------------------------------------------------------------------- +DWORD CFreeList::AllocElement( void ) +{ + DWORD dwNewHeadBlock; + DWORD dwElementSectionSize; + DWORD dwBlockSize; + LPVOID lpBlock; + UINT iCnt; + DWORD dwElement; + LPVOID lpElement; + LPDWORD lpElementNextPtr; + + // + // If the list of available elements is empty, callback to the derived + // class and make them add an entire new block of elements. + // + if ( m_dwHeadElement == 0 ) + { + // + // Allocate a new block + // + iCnt = m_iElementsPerBlock; + dwElementSectionSize = m_iElementSize * m_iElementsPerBlock; + + // + // Here we allocate an extra DWORD so that we can store in the block + // the address of the next block. In this way we have a list of + // blocks so that when the time comes to free them, we can find them + // all. + // + dwBlockSize = dwElementSectionSize + sizeof(DWORD); + + dwNewHeadBlock = m_pmm->AllocMemory( dwBlockSize ); + + if ( dwNewHeadBlock == 0 ) + { + // + // Yikes, the block allocator failed! + // + thkDebugOut((DEB_ERROR, + "CFreeList::AllocElement, AllocMemory failed\n")); + return 0; + } + // + // Now initialize the block and link it into the block list. + // + + lpBlock = m_pmm->ResolvePtr( dwNewHeadBlock, dwBlockSize ); + if ( lpBlock == NULL ) + { + // + // Couldn't get a pointer to the block, some memory mapping + // problem? + // + thkDebugOut((DEB_ERROR, + "CFreeList::AllocElement, " + "ResolvePtr for block failed " + "for address %08lX, size %08lX\n", + dwNewHeadBlock, dwBlockSize )); + // Try to return bad block to pool + m_pmm->FreeMemory( dwNewHeadBlock ); + return 0; + } + +#if DBG == 1 + // 0xDE = Alloc'd but not init'd + memset( lpBlock, 0xDE, dwBlockSize ); +#endif + + // + // Make this block point to the previous block + // + *CALC_BLOCKNEXTPTR(lpBlock,dwElementSectionSize) = m_dwHeadBlock; + m_dwHeadBlock = dwNewHeadBlock; // Update block list + + m_pmm->ReleasePtr(dwNewHeadBlock); + + // + // Now initialize all of the elements within the block to be free. + // + // The below loop skips the first element, free's all of the remaining + // ones. This way we can return the first one and all of the rest will + // be in accending order; The order doesn't really matter, but its + // nice. + // + dwElement = dwNewHeadBlock; + + while ( iCnt > 1 ) // Free n-1 items (we skip the first) + { + --iCnt; + dwElement += m_iElementSize; // Skip to next one (miss 1st one) + + FreeElement( dwElement ); + } + + dwElement = dwNewHeadBlock; // Use the first one as our alloc'd one + } + else + { + // We better have some blocks by now + thkAssert( m_dwHeadBlock != 0 ); + + // Better have a "end of list" too! + thkAssert( m_dwTailElement != 0 ); + + // + // Grab an available element off the top (head) of the list. + // + dwElement = m_dwHeadElement; + + lpElement = m_pmm->ResolvePtr( dwElement, m_iElementSize ); + if ( lpElement == NULL ) + { + // + // Yikes, we weren't able to get a pointer to the element! + // + thkDebugOut((DEB_ERROR, + "CFreeList::AllocElement, " + "ResolvePtr for element failed " + "for address %08lX, size %08lX\n", + dwElement, m_iElementSize )); + return 0; + } + + // + // Update the list to reflect the fact that we just removed the head + // and replace it with the one which was pointed to by the head. + // + lpElementNextPtr = CALC_NEXTPTR(lpElement); + m_dwHeadElement = *lpElementNextPtr; + + m_pmm->ReleasePtr(dwElement); + + // + // Also, if we are now at the end of the list, then the tail element + // should point to nowhere (i.e. there is nothing to insert after). + // + if ( m_dwHeadElement == 0 ) + { + m_dwTailElement = 0; + } + } + +#if DBG == 1 + // Erase the memory being returned to highlight reuse of dead values + + lpElement = m_pmm->ResolvePtr( dwElement, m_iElementSize ); + memset( lpElement, 0xED, m_iElementSize ); + m_pmm->ReleasePtr(dwElement); + + thkDebugOut((DEB_ITRACE, + "CFreeList::AllocElement, allocated element at %08lX\n", + dwElement )); +#endif + + return dwElement; +} + +//+--------------------------------------------------------------------------- +// +// Method: CFreeList::FreeElement +// +// Synopsis: Un-Allocates an element from the various blocks of elements, +// basically put the element back on the free list. +// +// Arguments: dwElement - Element to free +// +// Returns: -none- Asserts if failed. +// +// History: 7-05-94 BobDay (Bob Day) Created +// +//---------------------------------------------------------------------------- +void CFreeList::FreeElement( DWORD dwElement ) +{ + LPVOID lpElement; + LPDWORD lpElementNextPtr; + DWORD dwResolved; + + // + // First, make sure we can set this new element's next element pointer + // to zero (he's going to be a the end of the list). + // + lpElement = m_pmm->ResolvePtr( dwElement, m_iElementSize ); + if ( lpElement == NULL ) + { + // + // Yikes, we couldn't get a pointer to this element's place to store + // its next pointer. + // + thkDebugOut((DEB_ERROR, + "CFreeList::FreeElement, " + "ResolvePtr failed for free'd element\n" + "for address %08lX, size %08lX\n", + dwElement, m_iElementSize )); + thkAssert(FALSE && "CFreeList::FreeElement, " + "Resolve Ptr failed for free'd element\n"); + return; + } + +#if DBG == 1 + // Fill memory so its values can't be reused + if ( fZapProxy ) // Not doing this is important for + // the "PrepareForCleanup" processing the OLE32 + // does on thread detach. ZapProxy can be used + // to turn it back on. + { + memset(lpElement, 0xDD, m_iElementSize); + } +#endif + + lpElementNextPtr = CALC_NEXTPTR(lpElement); + + *lpElementNextPtr = 0; // Zap his next pointer since he'll be on the end + + m_pmm->ReleasePtr(dwElement); + + // + // Add this element back onto the end (tail) of the list. + // + if ( m_dwTailElement == 0 ) + { + // + // Well, the list was empty, time to set it up + // + thkAssert( m_dwHeadElement == 0 ); + + lpElementNextPtr = &m_dwHeadElement; + dwResolved = 0; + } + else + { + // + // Ok, the list wasn't empty, so we add this new one onto the end. + // + thkAssert( m_dwHeadElement != 0 ); + + dwResolved = m_dwTailElement; + lpElement = m_pmm->ResolvePtr( m_dwTailElement, m_iElementSize ); + if ( lpElement == NULL ) + { + // + // Oh no, we couldn't get a pointer to the next element pointer for + // the guy who is currently the tail of the list. + // + thkDebugOut((DEB_ERROR, + "CFreeList::FreeElement, " + "ResolvePtr failed for last element\n" + "for address %08lX, size %08lX\n", + m_dwTailElement, m_iElementSize )); + thkAssert(FALSE && "CFreeList::FreeElement, " + "Resolve Ptr failed for last element\n"); + return; + } + + lpElementNextPtr = CALC_NEXTPTR(lpElement); + } + + // + // Update our tail pointer to point to our newly free'd guy. + // + m_dwTailElement = dwElement; + + // + // Make the last guy point to this newly free'd guy + // + *lpElementNextPtr = dwElement; + + if (dwResolved != 0) + { + m_pmm->ReleasePtr(dwResolved); + } + + thkDebugOut((DEB_ITRACE, + "CFreeList::FreeElement, free'd element at %08lX\n", + dwElement )); +} + +//+--------------------------------------------------------------------------- +// +// Method: CFreeList::FreeMemoryBlocks +// +// Arguments: -none- +// +// Returns: -nothing- +// +// Synopsis: Called by derived destructors to allow them to free up their +// contents before going away. +// +// History: 7-05-94 BobDay (Bob Day) Created it +// +//---------------------------------------------------------------------------- + +void CFreeList::FreeMemoryBlocks( void ) +{ + DWORD dwBlock; + DWORD dwElementSectionSize; + DWORD dwBlockSize; + DWORD dwNextBlock; + LPVOID lpBlock; + + // + // Compute some constants for this list ahead of time + // + dwElementSectionSize = m_iElementSize * m_iElementsPerBlock; + + // + // Add room for that extra DWORD, block next pointer. (See comment in + // AllocElement where it allocates an extra DWORD) + // + dwBlockSize = dwElementSectionSize + sizeof(DWORD); + + // + // Iterate through the list of blocks free'ing them + // + dwBlock = m_dwHeadBlock; + + while( dwBlock != 0 ) + { + // + // Find the next block ptr + // + lpBlock = m_pmm->ResolvePtr( dwBlock, dwBlockSize ); + if ( lpBlock == NULL ) + { + // + // If we get an error here, we just drop out of loop + // + dwNextBlock = 0; + } + else + { + dwNextBlock = *CALC_BLOCKNEXTPTR(lpBlock,dwElementSectionSize); + +#if DBG == 1 + memset(lpBlock, 0xEE, dwBlockSize); +#endif + + m_pmm->ReleasePtr(dwBlock); + m_pmm->FreeMemory( dwBlock ); + } + dwBlock = dwNextBlock; + } + + m_dwHeadElement = 0; + m_dwTailElement = 0; + m_dwHeadBlock = 0; +} diff --git a/private/ole32/olethunk/olethk32/freelist.hxx b/private/ole32/olethunk/olethk32/freelist.hxx new file mode 100644 index 000000000..139de795a --- /dev/null +++ b/private/ole32/olethunk/olethk32/freelist.hxx @@ -0,0 +1,65 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: freelist.hxx +// +// Contents: CFreeList classes +// +// History: 07-Jul-94 BobDay Created +// +//---------------------------------------------------------------------------- + +#ifndef __FREELIST_HXX__ +#define __FREELIST_HXX__ + +//+--------------------------------------------------------------------------- +// +// Class: CFreeList (fl) +// +// Purpose: Implements a block allocator with replaceable underlying +// memory strategies +// +// Interface: AllocElement - To allocate a proxy +// ReleaseElement - To return an element to the free pool +// AllocBlock - Callback for block allocation +// GetElementNextPtr - Callback for list traversal +// +// Notes: At some point we might want to make this have one free list per +// block. Then we would easily be able to tell which blocks have +// all free elements within them and we able to be freed. +// +// History: 6-01-94 JohannP (Johann Posch) Created +// 6-29-94 BobDay (Bob Day) Made list based +// +//---------------------------------------------------------------------------- +class CFreeList +{ +public: + DWORD AllocElement( void ); + void FreeElement( DWORD dwElement ); + void FreeMemoryBlocks( void ); + + CFreeList( CMemoryModel *pmm, + UINT iElementSize, + UINT iElementsPerBlock, + UINT iNextPtrOffset ); +private: + CMemoryModel *m_pmm; + + DWORD m_iElementSize; + DWORD m_iElementsPerBlock; + DWORD m_iNextPtrOffset; + DWORD m_dwHeadElement; + DWORD m_dwTailElement; + DWORD m_dwHeadBlock; +}; + +// Free lists +extern CFreeList flFreeList16; +extern CFreeList flFreeList32; +extern CFreeList flHolderFreeList; +extern CFreeList flRequestFreeList; + +#endif // #ifndef __FREELIST_HXX__ diff --git a/private/ole32/olethunk/olethk32/headers.cxx b/private/ole32/olethunk/olethk32/headers.cxx new file mode 100644 index 000000000..50f0513e8 --- /dev/null +++ b/private/ole32/olethunk/olethk32/headers.cxx @@ -0,0 +1,59 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: headers.cxx +// +// Contents: Precompiled headers file +// +// History: 21-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +extern "C" { +#include <malloc.h> +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#include <windows.h> +#include <wownt32.h> +} + +#include <ole2.h> +#include <olecoll.h> +#include <privguid.h> +#include <ole2sp.h> +#include <ole2com.h> +#include <utils.h> +#include <memapi.hxx> + +#include <interop.hxx> +#include <wow32fn.h> +#include <thunkapi.hxx> +#include <stksw.hxx> +#include "mmodel.hxx" +#include "stalloc.hxx" +#include "nest.hxx" +#include "olethk32.hxx" +#include "map_kv.h" +#include "map_dwp.h" +#include "obj16.hxx" +#include "thkmgr.hxx" +#include "freelist.hxx" +#include "cthkmgr.hxx" + +#include "tlsthk.hxx" +#include "thop.hxx" +#include "thi.hxx" +#include "the.hxx" +#include "thopapi.hxx" +#include "thopint.hxx" +#include "inv16.hxx" +#include "alias.hxx" +#include "thoputil.hxx" +#include "apinot.hxx" + +#if DBG == 1 +#include "dbginv.hxx" +#endif diff --git a/private/ole32/olethunk/olethk32/heap.cxx b/private/ole32/olethunk/olethk32/heap.cxx new file mode 100644 index 000000000..9268967cc --- /dev/null +++ b/private/ole32/olethunk/olethk32/heap.cxx @@ -0,0 +1,63 @@ +//+------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1995. +// +// File: heap.cxx +// +// Contents: memory management +// +// Classes: +// +// Functions: operator new +// operator delete +// +// History: 5-Dec-95 JeffE Created +// +//-------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +//+--------------------------------------------------------------------------- +// +// Function: operator new, public +// +// Synopsis: Global operator new which does not throw exceptions. +// +// Arguments: [size] -- Size of the memory to allocate. +// +// Returns: A pointer to the allocated memory. Is *NOT* initialized to 0! +// +// Notes: We override new to make delete easier. +// +//---------------------------------------------------------------------------- +void* _CRTAPI1 +operator new (size_t size) +{ + return(CoTaskMemAlloc(size)); +} + + +//+------------------------------------------------------------------------- +// +// Function: ::operator delete +// +// Synopsis: Free a block of memory +// +// Arguments: [lpv] - block to free. +// +// History: 18-Nov-92 Ricksa Created +// +//-------------------------------------------------------------------------- + +void _CRTAPI1 operator delete(void FAR* lpv) +{ + CoTaskMemFree (lpv); +} + + + + + + diff --git a/private/ole32/olethunk/olethk32/ichannel.cxx b/private/ole32/olethunk/olethk32/ichannel.cxx new file mode 100644 index 000000000..7896e04e6 --- /dev/null +++ b/private/ole32/olethunk/olethk32/ichannel.cxx @@ -0,0 +1,49 @@ +//+------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: ichannel.cxx +// +// Contents: Maps the RpcChannel to RpcChannelBuffer +// This is required to support custom interface marshalling. +// +// History: 24-Mar-94 JohannP Created +// +//-------------------------------------------------------------------------- + + +// +// the new 32 bit channel interface - buffer based +// +class CRpcChannelBuffer : public IPpcChannelBuffer +{ +public: + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppvObject); + ULONG STDMETHODCALLTYPE AddRef(void); + ULONG STDMETHODCALLTYPE Release(void); + + HRESULT STDMETHODCALLTYPE GetBuffer(RPCOLEMESSAGE *pMessage,REFIID riid); + HRESULT STDMETHODCALLTYPE SendReceive(RPCOLEMESSAGE *pMessage,ULONG *pStatus); + HRESULT STDMETHODCALLTYPE FreeBuffer(RPCOLEMESSAGE *pMessage); + HRESULT STDMETHODCALLTYPE GetDestCtx(DWORD *pdwDestContext,void **ppvDestContext); + HRESULT STDMETHODCALLTYPE IsConnected( void); +}; + +// 16 bit channel interface - stream based +// class see by the 16 bit implemantation +// needs to be mapped to the RpcChannelBuffer +class CRpcChannel : public IRpcChannel +{ + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppvObject); + ULONG STDMETHODCALLTYPE AddRef(void); + ULONG STDMETHODCALLTYPE Release(void); + + STDMETHOD(GetStream)(REFIID iid, int iMethod, BOOL fSend, + BOOL fNoWait, DWORD size, IStream FAR* FAR* ppIStream); + STDMETHOD(Call)(IStream FAR* pIStream); + STDMETHOD(GetDestCtx)(DWORD FAR* lpdwDestCtx, LPVOID FAR* lplpvDestCtx); + STDMETHOD(IsConnected)(void); +}; + + diff --git a/private/ole32/olethunk/olethk32/iidtothi.cxx b/private/ole32/olethunk/olethk32/iidtothi.cxx new file mode 100644 index 000000000..54c250227 --- /dev/null +++ b/private/ole32/olethunk/olethk32/iidtothi.cxx @@ -0,0 +1,79 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: iidtothi.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +#include <headers.cxx> +#pragma hdrstop + +#include <coguid.h> +#include <oleguid.h> +IIDTOTHI CONST aittIidToThi[] = +{ + &IID_IUnknown, THI_IUnknown +, &IID_IClassFactory, THI_IClassFactory +, &IID_IMarshal, THI_IMarshal +, &IID_IStdMarshalInfo, THI_IStdMarshalInfo +, &IID_IMessageFilter, THI_IMessageFilter +, &IID_IExternalConnection, THI_IExternalConnection +, &IID_IEnumString, THI_IEnumString +, &IID_IEnumUnknown, THI_IEnumUnknown +, &IID_IEnumSTATSTG, THI_IEnumSTATSTG +, &IID_ILockBytes, THI_ILockBytes +, &IID_IStream, THI_IStream +, &IID_IStorage, THI_IStorage +, &IID_IRootStorage, THI_IRootStorage +, &IID_IEnumFORMATETC, THI_IEnumFORMATETC +, &IID_IEnumSTATDATA, THI_IEnumSTATDATA +, &IID_IDataObject, THI_IDataObject +, &IID_IViewObject, THI_IViewObject +, &IID_IViewObject2, THI_IViewObject2 +, &IID_IAdviseSink, THI_IAdviseSink +, &IID_IAdviseSink2, THI_IAdviseSink2 +, &IID_IDataAdviseHolder, THI_IDataAdviseHolder +, &IID_IOleCache, THI_IOleCache +, &IID_IOleCache2, THI_IOleCache2 +, &IID_IOleCacheControl, THI_IOleCacheControl +, &IID_IDropTarget, THI_IDropTarget +, &IID_IDropSource, THI_IDropSource +, &IID_IPersist, THI_IPersist +, &IID_IPersistStorage, THI_IPersistStorage +, &IID_IPersistStream, THI_IPersistStream +, &IID_IPersistFile, THI_IPersistFile +, &IID_IBindCtx, THI_IBindCtx +, &IID_IMoniker, THI_IMoniker +, &IID_IRunningObjectTable, THI_IRunningObjectTable +, &IID_IEnumMoniker, THI_IEnumMoniker +, &IID_IEnumOLEVERB, THI_IEnumOLEVERB +, &IID_IOleObject, THI_IOleObject +, &IID_IOleClientSite, THI_IOleClientSite +, &IID_IRunnableObject, THI_IRunnableObject +, &IID_IParseDisplayName, THI_IParseDisplayName +, &IID_IOleContainer, THI_IOleContainer +, &IID_IOleItemContainer, THI_IOleItemContainer +, &IID_IOleAdviseHolder, THI_IOleAdviseHolder +, &IID_IOleLink, THI_IOleLink +, &IID_IOleWindow, THI_IOleWindow +, &IID_IOleInPlaceObject, THI_IOleInPlaceObject +, &IID_IOleInPlaceActiveObject, THI_IOleInPlaceActiveObject +, &IID_IOleInPlaceUIWindow, THI_IOleInPlaceUIWindow +, &IID_IOleInPlaceFrame, THI_IOleInPlaceFrame +, &IID_IOleInPlaceSite, THI_IOleInPlaceSite +, &IID_IRpcChannelBuffer, THI_IRpcChannelBuffer +, &IID_IRpcProxyBuffer, THI_IRpcProxyBuffer +, &IID_IRpcStubBuffer, THI_IRpcStubBuffer +, &IID_IPSFactoryBuffer, THI_IPSFactoryBuffer +, &IID_IRpcChannel, THI_IRpcChannel +, &IID_IRpcProxy, THI_IRpcProxy +, &IID_IRpcStub, THI_IRpcStub +, &IID_IPSFactory, THI_IPSFactory +}; diff --git a/private/ole32/olethunk/olethk32/inv16.cxx b/private/ole32/olethunk/olethk32/inv16.cxx new file mode 100644 index 000000000..a381b048d --- /dev/null +++ b/private/ole32/olethunk/olethk32/inv16.cxx @@ -0,0 +1,608 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: inv16.cxx +// +// Contents: 32->16 Call thunking +// +// History: 25-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +#include "..\..\ole232\inplace\inplace.h" // We need CFrameFilter for + // WinWord 6 Hack + +//+--------------------------------------------------------------------------- +// +// Function: InvokeOn16, public +// +// Synopsis: Sets up the THUNKINFO and starts thunking for a 32->16 call +// +// Arguments: [iidx] - Custom interface or known interface index +// [dwMethod] - Method index +// [pvStack32] - 32-bit stack +// +// Returns: Appropriate status code +// +// History: 25-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +extern "C" +{ +ULONG InvokeOn16_count = 0; +ULONG InvokeOn16_break = 0; + +int _iInvokeOn16BreakIidx = -1; +int _iInvokeOn16BreakMethod = -1; +}; +#endif + +// InvokeOn16 uses a lot of local variables so allocate its locals +// rather than declaring them on the stack. This saves roughly +// 150 bytes of stack per call + +struct INVOKE16RECORD +{ + THOP CONST *pThop; + THOP CONST * CONST *ppThop; + UINT uiThop; + VTBLFN UNALIGNED CONST *pvfnVtbl; + VPVOID vpvThis16; + VPVOID vpvVtbl16; + VPVOID UNALIGNED CONST *pvpvThis16; + DWORD dwStack16[MAX_PARAMS]; + THUNKINFO ti; + THUNK3216OBJ *ptoThis32; + ThreadData *ptd; +}; + +DWORD InvokeOn16(IIDIDX iidx, DWORD dwMethod, LPVOID pvStack32) +{ + // NOTE: Do not declare local variables in this routine + // except for debug builds + INVOKE16RECORD *pir; + DWORD dwResult; + +#if DBG == 1 + ULONG ulInvokeOn16_count = ++InvokeOn16_count; + if (InvokeOn16_count == InvokeOn16_break) + { + DebugBreak(); + } + + thkDebugOut((DEB_ITRACE, "%sInvokeOn16(0x%x, 0x%x, %p)\n", + NestingLevelString(), iidx, dwMethod, pvStack32)); +#endif + + pir = (INVOKE16RECORD *)STACKALLOC32(sizeof(INVOKE16RECORD)); + if (pir == NULL) + { + // BUGBUG - This error isn't guaranteed to mean anything for + // this call. Not much else we can do, though + return (DWORD)E_OUTOFMEMORY; + } + + // pvStack32 is a pointer to an array of arguments from the + // 32-bit call. It's always laid out with the first + // argument low and increasing from there + + pir->ti.s32.pbStart = (BYTE *)pvStack32; + pir->ti.s32.pbCurrent = pir->ti.s32.pbStart; + + pir->ti.s16.pbStart = (BYTE *)pir->dwStack16; + pir->ti.s16.pbCurrent = pir->ti.s16.pbStart; + + pir->ti.scResult = S_OK; + pir->ti.fResultThunked = FALSE; + + pir->ptd = TlsThkGetData(); + if (pir->ptd == NULL) + { + thkDebugOut((DEB_WARN, "WARNING: InvokeOn16: Call refused\n")); + + STACKFREE32(pir, sizeof(INVOKE16RECORD)); + return (DWORD)E_FAIL; + } + + pir->ti.pThkMgr = pir->ptd->pCThkMgr; + thkAssert(pir->ti.pThkMgr != NULL); + + thkAssert(iidx >= 0 && iidx < THI_COUNT); + + // For each interface there is an array of thop strings, one for + // each method. The IUnknown methods don't have thop strings so + // bias the thop string pointer to account for that + + thkAssert(dwMethod >= SMI_COUNT); + + pir->ppThop = athopiInterfaceThopis[iidx].ppThops-SMI_COUNT; + pir->uiThop = athopiInterfaceThopis[iidx].uiSize; + + // Methods are cdecl so we need to move upwards in memory to + // get to the next parameter + pir->ti.s16.iDir = 1; + + // We need to look up the appropriate method pointer by + // looking in the 16-bit object's vtable + GET_STACK32(&pir->ti, pir->ptoThis32, THUNK3216OBJ *); + + thkDebugOut((DEB_INVOKES, + "InvokeOn16: ptoThis32 = %08lX\n", pir->ptoThis32 )); + + if ( pir->ptoThis32->grfFlags & PROXYFLAG_CLEANEDUP ) + { + thkDebugOut((DEB_WARN, + "InvokeOn16: Attempt to call %s::%s" + "on cleaned-up proxy %08lX for 16-bit object %08lX\n", + inInterfaceNames[iidx].pszInterface, + inInterfaceNames[iidx].ppszMethodNames[dwMethod], + pir->ptoThis32, pir->ptoThis32->vpvThis16)); + STACKFREE32(pir, sizeof(INVOKE16RECORD)); + return (DWORD)E_FAIL; + } + + // check PROXYFLAG_CLEANEDUP before calling DebugValidateProxy3216. + // Otherwise we might get asserts on checked OLE. + DebugValidateProxy3216(pir->ptoThis32); + + pir->ti.dwCallerProxy = (DWORD)pir->ptoThis32; + pir->vpvThis16 = pir->ptoThis32->vpvThis16; + pir->pvpvThis16 = (VPVOID UNALIGNED *) + GetReadPtr16(&pir->ti, pir->vpvThis16, sizeof(VPVOID)); + if (pir->pvpvThis16 == NULL) + { + dwResult = pir->ti.scResult; + STACKFREE32(pir, sizeof(INVOKE16RECORD)); + return dwResult; + } + + pir->vpvVtbl16 = *pir->pvpvThis16; + pir->pvfnVtbl = (VTBLFN UNALIGNED *) + GetReadPtr16(&pir->ti, pir->vpvVtbl16, sizeof(VPVOID)*pir->uiThop); + + WOWRELVDMPTR(pir->vpvThis16); + + if (pir->pvfnVtbl == NULL) + { + dwResult = pir->ti.scResult; + STACKFREE32(pir, sizeof(INVOKE16RECORD)); + return dwResult; + } + + // Push the 16-bit this pointer on the stack first + TO_STACK16(&pir->ti, pir->vpvThis16, VPVOID); + + thkAssert(dwMethod < pir->uiThop); + + pir->pThop = pir->ppThop[dwMethod]; + + thkAssert(pir->pThop != NULL); + + pir->ti.pThop = pir->pThop; + pir->ti.pvfn = pir->pvfnVtbl[dwMethod]; + pir->ti.iidx = iidx; + pir->ti.dwMethod = dwMethod; + pir->ti.this32 = (IUnknown *)pir->ptoThis32; + + WOWRELVDMPTR(pir->vpvVtbl16); + + thkDebugOut((DEB_INVOKES, "%s#(%04X):InvokeOn16 on %p:%p, %s::%s\n", + NestingLevelString(), ulInvokeOn16_count, + pir->vpvThis16, pir->ti.pvfn, + inInterfaceNames[iidx].pszInterface, + inInterfaceNames[iidx].ppszMethodNames[dwMethod])); + + DebugIncrementNestingLevel(); + + pir->ti.pThkMgr->SetThkState(THKSTATE_INVOKETHKIN16); + +#if DBG == 1 + SStackRecord sr; + + RecordStackState16(&sr); +#endif + +#if DBG == 1 + if ((_iInvokeOn16BreakIidx > 0 && _iInvokeOn16BreakIidx == (int)iidx) && + (_iInvokeOn16BreakMethod < 0 || + _iInvokeOn16BreakMethod == (int)dwMethod)) + { + DebugBreak(); + } +#endif + + dwResult = EXECUTE_THOP3216(&pir->ti); + +#if DBG == 1 + + if ( !pir->ti.fResultThunked && FAILED(dwResult) ) + { + thkDebugOut((DEB_FAILURES, + "InvokeOn16 probable failure %s::%s sc = %08lX\n", + inInterfaceNames[iidx].pszInterface, + inInterfaceNames[iidx].ppszMethodNames[dwMethod], + dwResult)); + } + + CheckStackState16(&sr); + +#endif + + pir->ti.pThkMgr->SetThkState(THKSTATE_NOCALL); + + DebugDecrementNestingLevel(); + + thkDebugOut((DEB_INVOKES, + "%s#(%04X):InvokeOn16 on %p:%p, %s::%s returns 0x%08lX\n", + NestingLevelString(), ulInvokeOn16_count, + pir->vpvThis16, pir->ti.pvfn, + inInterfaceNames[iidx].pszInterface, + inInterfaceNames[iidx].ppszMethodNames[dwMethod], + dwResult)); + + STACKFREE32(pir, sizeof(INVOKE16RECORD)); + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Call3216, private +// +// Synopsis: Sets up stack and transitions to 16-bit +// +// Arguments: [pvfn] - Function to call +// [pbStack] - Stack in 32-bits +// [cbStack] - Size of stack +// +// Returns: Appropriate status code +// +// History: 04-Mar-94 DrewB Created +// +//---------------------------------------------------------------------------- +#if DBG == 1 +extern "C" ULONG Call3216_count = 0; +extern "C" ULONG Call3216_break = 0; +#endif + +DWORD Call3216(VPVOID pvfn, BYTE *pbStack, UINT cbStack) +{ +#if DBG == 1 + ULONG ulCall3216_count = ++Call3216_count; + if (Call3216_count == Call3216_break) + { + DebugBreak(); + } +#endif + + VPVOID vpvStack16; + DWORD dwResult; + void *pvStack16; + + dwResult = (DWORD)S_OK; + + if (cbStack <= WCB16_MAX_CBARGS) + { + thkDebugOut((DEB_ITRACE, "CallbackTo16Ex(%p, %lu, %p) #(%x)\n", + pvfn, cbStack, pbStack, ulCall3216_count)); + + // pbStack must have at least WCB16_MAX_CBARGS bytes of valid memory + // since 16V always copies that many bytes + + // In our case pbStack is from InvokeOn16 which should be large enough + thkAssert(MAX_PARAMS*sizeof(DWORD) >= WCB16_MAX_CBARGS); + + if (!CallbackTo16Ex(pvfn, WCB16_CDECL, cbStack, pbStack, + &dwResult)) + { + dwResult = (DWORD)E_UNEXPECTED; + } + } + else + { + CALLDATA UNALIGNED *pcd; + UINT cbAlloc; + + cbAlloc = cbStack+sizeof(CALLDATA); + + vpvStack16 = STACKALLOC16(cbAlloc); + if (vpvStack16 == 0) + { + dwResult = (DWORD)E_OUTOFMEMORY; + } + else + { + pvStack16 = (void *)WOWFIXVDMPTR(vpvStack16, cbAlloc); + + pcd = (CALLDATA UNALIGNED *)((BYTE *)pvStack16+cbStack); + pcd->vpfn = (DWORD)pvfn; + pcd->vpvStack16 = vpvStack16; + pcd->cbStack = cbStack; + + memcpy(pvStack16, pbStack, cbStack); + + WOWRELVDMPTR(vpvStack16); + + thkDebugOut((DEB_ITRACE, "CallbackTo16(%p, (%p, %p, %lu)) #(%x)\n", + gdata16Data.fnCallStub16, pvfn, vpvStack16, + cbStack, ulCall3216_count)); + dwResult = CallbackTo16(gdata16Data.fnCallStub16, + vpvStack16+cbStack); + + STACKFREE16(vpvStack16, cbAlloc); + } + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: ThunkCall3216, public +// +// Synopsis: Sets up the 16-bit stack and makes a 32->16 call +// +// Arguments: [pti] - Thunk state info +// +// Returns: Appropriate status code +// +// History: 25-Feb-94 DrewB Created +// 08-Aug-94 AlexT Add IOleClientSite::OnShowWindow code +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +extern "C" ULONG ThunkCall3216_count = 0; +extern "C" ULONG ThunkCall3216_break = 0; +#endif + +DWORD ThunkCall3216(THUNKINFO *pti) +{ + DWORD dwReturn; + UINT cbStack; + DWORD dwCallerTID; + HRESULT hrCaller; + + +#if DBG == 1 + ULONG ulThunkCall3216_count = ++ThunkCall3216_count; + thkAssert( (ThunkCall3216_count != ThunkCall3216_break) && + "Break Count Hit"); +#endif + + thkAssert(*pti->pThop == THOP_END); + pti->pThop++; + thkAssert(*pti->pThop == THOP_ROUTINEINDEX); + pti->pThop++; + + thkDebugOut((DEB_ITRACE, "ThunkCall3216 #(%x) %p, index %d\n", + ulThunkCall3216_count, pti->pvfn, *pti->pThop)); + + cbStack = pti->s16.pbCurrent-pti->s16.pbStart; + + // The this pointer should always be on the stack + thkAssert(cbStack >= sizeof(VPVOID)); + + // + // Hacks for specific interface member functions. + // The placement of these hacks here is by no means an optimal solution. + // It just happens to be convienient for now since everything goes through + // here. This section is for pre-processing. + // + if ( IIDIDX_IS_INDEX(pti->iidx) ) + { + switch( IIDIDX_INDEX(pti->iidx) ) + { + case THI_IOleClientSite: +#define METHOD_ONSHOWWINDOW 7 + if ( pti->dwMethod == METHOD_ONSHOWWINDOW ) + { + // + // Here we merge the input queues for the sole reason so that + // we can link the object's window activations into the calling + // thread's window z-order. + // + + hrCaller = CoGetCallerTID( &dwCallerTID ); + + if ( hrCaller == S_FALSE ) + { + AttachThreadInput( dwCallerTID, GetCurrentThreadId(), + TRUE ); + } + } + break; + + case THI_IOleObject: +#define METHOD_DOVERB 11 + if ( pti->dwMethod == METHOD_DOVERB ) + { + // + // Here we merge the input queues for the sole reason so + // that we can link the object's window activations into + // the calling thread's window z-order. + // + + hrCaller = CoGetCallerTID( &dwCallerTID ); + + if ( hrCaller == S_FALSE ) + { + AttachThreadInput( dwCallerTID, GetCurrentThreadId(), + TRUE ); + } + } + break; + + default: + break; + } + } + + pti->pThkMgr->SetThkState(THKSTATE_NOCALL); + + dwReturn = Call3216((VPVOID)pti->pvfn, pti->s16.pbStart, cbStack); + + pti->pThkMgr->SetThkState(THKSTATE_INVOKETHKOUT16); + + // + // Hacks for specific interface member functions. + // Again, the placement of these is by no means an optimal solution. + // They can be moved as long as they have the same effect for just these + // interfaces. This section is for post-processing. + // + if ( IIDIDX_IS_INDEX(pti->iidx) ) + { + switch( IIDIDX_INDEX(pti->iidx) ) + { + case THI_IOleClientSite: + if ( pti->dwMethod == METHOD_ONSHOWWINDOW ) + { + // + // Unmerge the input queues afterward. + // + if ( hrCaller == S_FALSE ) + { + AttachThreadInput( dwCallerTID, GetCurrentThreadId(), + FALSE ); + } + } + break; + + case THI_IOleObject: + if ( pti->dwMethod == METHOD_DOVERB ) + { + // + // Unmerge the input queues afterward. + // + if ( hrCaller == S_FALSE ) + { + AttachThreadInput( dwCallerTID, GetCurrentThreadId(), + FALSE ); + } + } + +#define METHOD_GETCLIENTSITE 4 + if ( pti->dwMethod == METHOD_GETCLIENTSITE ) + { + // + // Excel 5.0a needs to perform some special processing + // on the way out of a IOleObject::GetClientSite call. + // See CTHKMGR.CXX and APINOT.CXX for more details. + // + if ( TlsThkGetAppCompatFlags() & OACF_CLIENTSITE_REF ) + { + // + // Tell the thkmgr that we are thunking a bad + // IOleObject::GetClientSite reference on the way out. + // + thkDebugOut((DEB_WARN,"TC3216: OACF_CLIENTSITE_REF used: " + "Setting to clientsite thunk state\n")); + + pti->pThkMgr->SetThkState( + THKSTATE_INVOKETHKOUT16_CLIENTSITE); + } + } + break; + + case THI_IOleInPlaceFrame: +#define METHOD_REMOVEMENUS 11 + // + // Winword 6.0a didn't call OleSetMenuDescriptor(NULL) + // during its IOleInPlaceFrame::RemoveMenus. This leaves + // OLE's frame filter in place. The frame filter holds references + // to some objects so everybody's refcounting gets thrown off + // Here, when we see a RemoveMenus call completing we force + // the OleSetMenuDescriptor(NULL) call to occur. This shuts + // down the frame filter and corrects the reference counts. + // + // There is one other hack necessary: Word unsubclasses the + // window itself directly rather than going through + // OleSetMenuDescriptor. Therefore the frame filter code + // is patched to only unhook if it detects that it is the + // current hook + // + // See APINOT.CXX for more hack code. + // + if (pti->dwMethod == METHOD_REMOVEMENUS) + { + if ( TlsThkGetAppCompatFlags() & OACF_RESETMENU ) + { + HRESULT hr; + HWND hwnd; + LPOLEINPLACEFRAME lpoipf; + + pti->pThkMgr->SetThkState(THKSTATE_NOCALL); + + lpoipf = (LPOLEINPLACEFRAME)pti->this32; + hr = lpoipf->GetWindow( &hwnd ); + + pti->pThkMgr->SetThkState(THKSTATE_INVOKETHKOUT16); + + if ( FAILED(hr) ) + { + break; + } + + thkDebugOut((DEB_WARN, + "TC3216: OACF_RESETMENU used: " + "Setting menu descriptor " + "to NULL on %p\n", hwnd)); + + OleSetMenuDescriptor(NULL, hwnd, NULL, NULL, NULL); + } + } + break; + + default: + break; + } + } + + if ( !pti->fResultThunked ) + { + dwReturn = TransformHRESULT_1632( dwReturn ); + +#if DBG == 1 + if (FAILED(dwReturn) ) + { + thkDebugOut((DEB_FAILURES, + "Call3216 pvfn = %08lX Probably failed hr = %08lX\n", + pti->pvfn, dwReturn)); + } +#endif + } + + thkDebugOut((DEB_ITRACE, + "ThunkCall3216 #(%x) returns 0x%08lX\n", + ulThunkCall3216_count, + dwReturn)); + + return dwReturn; +} + +//+--------------------------------------------------------------------------- +// +// Function: SetOwnerPublicHMEM16, public +// +// Synopsis: Changes the 16-bit memory handle into a public selector, owned +// by nobody. This prevents any app from taking it away when it +// is cleaned up. +// +// Arguments: [hmem] - 16-bit memory handle +// +// Returns: Appropriate status code +// +// History: 13-Jul-94 BobDay Created it +// +//---------------------------------------------------------------------------- +void SetOwnerPublicHMEM16( DWORD hmem ) +{ + CallbackTo16(gdata16Data.fnSetOwnerPublic16, hmem ); +} diff --git a/private/ole32/olethunk/olethk32/inv16.hxx b/private/ole32/olethunk/olethk32/inv16.hxx new file mode 100644 index 000000000..a317ad370 --- /dev/null +++ b/private/ole32/olethunk/olethk32/inv16.hxx @@ -0,0 +1,21 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: inv16.hxx +// +// Contents: 32->16 invoke function header +// +// History: 25-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#ifndef __INV16_HXX__ +#define __INV16_HXX__ + +DWORD InvokeOn16(IIDIDX iidx, DWORD dwMethod, LPVOID pvStack32); +DWORD ThunkCall3216(THUNKINFO *pti); +void SetOwnerPublicHMEM16( DWORD hMem16 ); + +#endif // #ifndef __INV16_HXX__ diff --git a/private/ole32/olethunk/olethk32/inv32.cxx b/private/ole32/olethunk/olethk32/inv32.cxx new file mode 100644 index 000000000..25245d2fc --- /dev/null +++ b/private/ole32/olethunk/olethk32/inv32.cxx @@ -0,0 +1,496 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: inv32.cxx +// +// Contents: Implementation of InvokeOn32 +// +// History: 22-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +STDAPI_(BOOL) IsValidInterface( void FAR* pv ); + +#include <apilist.hxx> + +//+--------------------------------------------------------------------------- +// +// Function: InvokeOn32, public +// +// Synopsis: Sets up the THUNKINFO and starts thunking for a 16->32 call +// +// Arguments: [dw1] - Ignored +// [dwMethod] - Method index +// [pvStack32] - 32-bit stack +// +// Returns: Appropriate status code +// +// History: 18-Dec-93 JohannP Created +// 21-Feb-94 DrewB Modified +// 09-Dec-94 JohannP added stack switching +// +// Note: On WIN95 this function get is executed on the 32 bit stack. +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +extern "C" +{ +ULONG InvokeOn32_count = 0; +ULONG InvokeOn32_break = 0; + +int _iInvokeOn32BreakIidx = -1; +int _iInvokeOn32BreakMethod = -1; +}; +#endif + + +// InvokeOn32 uses a lot of local variables so allocate its locals +// rather than declaring them on the stack. This saves roughly +// 150 bytes of stack per call + +struct INVOKE32RECORD +{ + THOP CONST *pThop; + THOP CONST * CONST *ppThop; + UINT uiThop; + VTBLFN CONST *pvfnVtbl; + VTBLFN CONST * CONST *ppvfnThis32; + DWORD dwStack32[MAX_PARAMS]; + THUNKINFO ti; + VPVOID vpvThis16; + THUNK1632OBJ UNALIGNED *pto; + IIDIDX iidx; + ThreadData *ptd; +}; + +STDAPI_(DWORD) SSAPI(InvokeOn32)(DWORD dw1, DWORD dwMethod, LPVOID pvStack16) +{ + // NOTE: Do not declare local variables in this routine + // except for debug builds + INVOKE32RECORD *pir; + DWORD dwResult; + +#if DBG == 1 + ULONG ulInvokeOn32_count = ++InvokeOn32_count; + + if (InvokeOn32_count == InvokeOn32_break) + { + DebugBreak(); + } + + thkDebugOut((DEB_ITRACE, "%sInvokeOn32(0x%08x, %p)\n", + NestingLevelString(), + dwMethod, pvStack16)); +#endif // DBG + + pir = (INVOKE32RECORD *)STACKALLOC32(sizeof(INVOKE32RECORD)); + if (pir == NULL) + { + // BUGBUG - This error isn't guaranteed to mean anything for + // this call. Not much else we can do, though + return (DWORD)E_OUTOFMEMORY; + } + + // pvStack16 is the pointer to the first parameter of the 16-bit + // routine. The compiler will adjust it appropriately according + // to the calling convention of the routine so for PASCAL APIs + // it will be high and for CDECL methods it will be low + + pir->ti.s16.pbStart = (BYTE *)pvStack16; + pir->ti.s16.pbCurrent = pir->ti.s16.pbStart; + + pir->ti.s32.pbStart = (BYTE *)pir->dwStack32; + pir->ti.s32.pbCurrent = pir->ti.s32.pbStart; + + pir->ti.scResult = S_OK; + pir->ti.fResultThunked = FALSE; + + if (dwMethod >= THK_API_BASE) + { + dwMethod -= THK_API_BASE; + pir->iidx = IIDIDX_INVALID; + + // APIs are handled as if there were a giant interface which + // contains all the APIs as methods. + pir->ppThop = apthopsApiThops; + pir->uiThop = THK_API_COUNT; + + pir->pvfnVtbl = apfnApiFunctions; + + // APIs are pascal so we need to move downward in memory to + // get to the next parameter + pir->ti.s16.iDir = -1; + + pir->ti.dwCallerProxy = 0; + } + else + { + // For each interface there is an array of thop strings, one for + // each method. The IUnknown methods don't have thop strings so + // bias the thop string pointer to account for that + + thkAssert(dwMethod >= SMI_COUNT); + + // Methods are cdecl so we need to move upwards in memory to + // get to the next parameter + pir->ti.s16.iDir = 1; + + // We need to look up the appropriate method pointer by + // looking in the 32-bit object's vtable + GET_STACK16(&pir->ti, pir->vpvThis16, VPVOID); + + thkDebugOut((DEB_INVOKES, + "InvokeOn32: vpvThis16 = %08lX\n", pir->vpvThis16 )); + + pir->pto = FIXVDMPTR(pir->vpvThis16, THUNK1632OBJ); + if (pir->pto == NULL) + { + STACKFREE32(pir, sizeof(INVOKE32RECORD)); + return (DWORD)E_INVALIDARG; + } + + if ((pir->pto->grfFlags & PROXYFLAG_TEMPORARY) == 0) + { + // Make sure proxy is still valid. + // BUGBUG: After PPC/Win95 we might want to look at using + // a signiture for validating this rather than IsValidInterface + // because it will speed this code path up. + if (!IsValidInterface(pir->pto->punkThis32)) + { + thkDebugOut(( + DEB_ERROR, "InvokeOn32: %p: Invalid proxied object %p\n", + pir->vpvThis16, pir->pto->punkThis32)); + STACKFREE32(pir, sizeof(INVOKE32RECORD)); + RELVDMPTR(pir->vpvThis16); + return (DWORD)E_INVALIDARG; + } + + DebugValidateProxy1632(pir->vpvThis16); + + pir->ppvfnThis32 = (VTBLFN CONST * CONST*)pir->pto->punkThis32; + } + else + { + // Temporary proxies cannot be validated + + // A temporary proxy's this pointer is actually a pointer + // to the real this pointer, so indirect through the this + // pointer to retrieve the real this pointer + pir->ppvfnThis32 = (VTBLFN CONST * CONST *)*(void **)pir->pto->punkThis32; + thkAssert(pir->ppvfnThis32 != NULL); + thkDebugOut((DEB_WARN, "WARNING: InvokeOn32 on temporary " + "%s proxy for %p\n", IidIdxString(pir->pto->iidx), + pir->ppvfnThis32)); + } + + pir->iidx = pir->pto->iidx; + RELVDMPTR(pir->vpvThis16); + + if (pir->ppvfnThis32 == NULL) + { + STACKFREE32(pir, sizeof(INVOKE32RECORD)); + return (DWORD)E_FAIL; + } + + pir->ti.dwCallerProxy = pir->vpvThis16; + + thkAssert(pir->iidx >= 0 && pir->iidx < THI_COUNT); + + pir->ppThop = athopiInterfaceThopis[pir->iidx].ppThops-SMI_COUNT; + pir->uiThop = athopiInterfaceThopis[pir->iidx].uiSize; + + pir->pvfnVtbl = *pir->ppvfnThis32; + + // Push the 32-bit this pointer on the stack first + TO_STACK32(&pir->ti, pir->ppvfnThis32, VTBLFN CONST * CONST*); + } + + thkAssert(dwMethod < pir->uiThop); + + pir->pThop = pir->ppThop[dwMethod]; + + thkAssert(pir->pThop != NULL); + + pir->ti.pThop = pir->pThop; + pir->ti.pvfn = pir->pvfnVtbl[dwMethod]; + pir->ti.iidx = pir->iidx; + pir->ti.dwMethod = dwMethod; + + pir->ptd = TlsThkGetData(); + if (pir->ptd == NULL) + { + thkDebugOut((DEB_WARN, "WARNING: InvokeOn32: Call refused\n")); + + STACKFREE32(pir, sizeof(INVOKE32RECORD)); + return (DWORD)E_FAIL; + } + + pir->ti.pThkMgr = pir->ptd->pCThkMgr; + thkAssert(pir->ti.pThkMgr != NULL); + +#if DBG == 1 + if (pir->iidx == IIDIDX_INVALID) + { + thkDebugOut((DEB_INVOKES, "%s#(%04X):InvokeOn32 on %p, %s\n", + NestingLevelString(), ulInvokeOn32_count, + pir->ti.pvfn, apszApiNames[dwMethod])); + } + else + { + thkDebugOut((DEB_INVOKES, "%s#(%04X):InvokeOn32 on %p:%p, %s::%s (0x%0x:0x%0x)\n", + NestingLevelString(), ulInvokeOn32_count, + pir->ppvfnThis32, pir->ti.pvfn, + inInterfaceNames[pir->iidx].pszInterface, + inInterfaceNames[pir->iidx].ppszMethodNames[dwMethod], + pir->iidx, + dwMethod)); + } +#endif + + DebugIncrementNestingLevel(); + // save and set the new thunk state + + pir->ti.pThkMgr->SetThkState(THKSTATE_INVOKETHKIN32); + +#if DBG == 1 + if ((_iInvokeOn32BreakIidx > 0 && + _iInvokeOn32BreakIidx == (int)pir->iidx) && + (_iInvokeOn32BreakMethod < 0 || + _iInvokeOn32BreakMethod == (int)dwMethod)) + { + DebugBreak(); + } +#endif + +#if DBG == 1 + SStackRecord sr; + + RecordStackState16(&sr); +#endif + +#if DBG == 1 + if (fStabilizeProxies) +#endif + { + // HACK HACK HACK + // Because of changes in the way refcounting rules work between + // 16 and 32-bits, we have to stabilize this pointers for + // 16->32 calls. To effect this, we do a purely local AddRef + // + // Temporary proxies are not valid proxies so they cannot + // be stabilized + if (pir->iidx != IIDIDX_INVALID) + { + pir->pto = FIXVDMPTR(pir->vpvThis16, THUNK1632OBJ); + if ((pir->pto->grfFlags & PROXYFLAG_TEMPORARY) == 0) + { + pir->ti.pThkMgr->LocalAddRefProxy(pir->pto); + } + RELVDMPTR(pir->vpvThis16); + } + } + + dwResult = EXECUTE_THOP1632(&pir->ti); + +#if DBG == 1 + if (fStabilizeProxies) +#endif + { + // Remove our stabilization reference + // Note that we don't really know whether the proxy is + // still valid, so we're just crossing our fingers here + // and hoping that things continue to work + if (pir->iidx != IIDIDX_INVALID) + { + pir->pto = FIXVDMPTR(pir->vpvThis16, THUNK1632OBJ); + if ((pir->pto->grfFlags & PROXYFLAG_TEMPORARY) == 0) + { + RELVDMPTR(pir->vpvThis16); + + DebugValidateProxy1632(pir->vpvThis16); + + pir->ti.pThkMgr->ReleaseProxy1632(pir->vpvThis16); + } + else + { + RELVDMPTR(pir->vpvThis16); + } + } + } + +#if DBG == 1 + + if ( !pir->ti.fResultThunked && FAILED(dwResult) ) + { + if (pir->iidx == IIDIDX_INVALID) + { + thkDebugOut((DEB_FAILURES, + "InvokeOn32 probable failure %s sc = %08lX\n", + apszApiNames[dwMethod], + dwResult)); + } + else + { + thkDebugOut((DEB_FAILURES, + "InvokeOn32 probable failure %s::%s sc = %08lX\n", + inInterfaceNames[pir->iidx].pszInterface, + inInterfaceNames[pir->iidx].ppszMethodNames[dwMethod], + dwResult)); + } + } + + CheckStackState16(&sr); + +#endif + + pir->ti.pThkMgr->SetThkState(THKSTATE_NOCALL); + + DebugDecrementNestingLevel(); + + if ( !pir->ti.fResultThunked ) + { + dwResult = TransformHRESULT_3216( dwResult ); + } + +#if DBG == 1 + if (pir->iidx == IIDIDX_INVALID) + { + thkDebugOut((DEB_INVOKES, + "%s#(%04X):InvokeOn32 on %p, %s returns 0x%08lX\n", + NestingLevelString(), ulInvokeOn32_count, pir->ti.pvfn, + apszApiNames[dwMethod], dwResult )); + } + else + { + thkDebugOut((DEB_INVOKES, + "%s#(%04X):InvokeOn32 on %p:%p, %s::%s returns 0x%08lX\n", + NestingLevelString(), ulInvokeOn32_count, + pir->ppvfnThis32, + pir->ti.pvfn, inInterfaceNames[pir->iidx].pszInterface, + inInterfaceNames[pir->iidx].ppszMethodNames[dwMethod], + dwResult)); + } +#endif + + STACKFREE32(pir, sizeof(INVOKE32RECORD)); + + return dwResult; +} + + +#ifdef _CHICAGO_ +//+--------------------------------------------------------------------------- +// +// Function: SSCallback16 +// +// Synopsis: Switches to 16 bit and calls back to 16 bit. +// +// Arguments: [vpfn16] -- function pointer +// [dwParam] -- pointer to parameter +// +// Returns: +// +// History: 12-08-94 JohannP (Johann Posch) Created +// +// Notes: +// +//---------------------------------------------------------------------------- +DWORD WINAPI SSCallback16(DWORD vpfn16, DWORD dwParam) +{ + DWORD dwRet; + // switch to the 16 bit stack + // + if (SSONBIGSTACK()) + { + StackDebugOut((DEB_STCKSWTCH, "%sSSCallback16 32->16(%p)\n",NestingLevelString(), vpfn16)); + dwRet = SSCall(8, SSF_SmallStack, WOWCallback16, vpfn16, dwParam); + StackDebugOut((DEB_STCKSWTCH, "%sSSCallback16 32<-16 done\n",NestingLevelString() )); + } + else + { + dwRet = WOWCallback16(vpfn16, dwParam); + } + return dwRet; +} + +//+--------------------------------------------------------------------------- +// +// Function: SSCallback16Ex +// +// Synopsis: Like SSCallback16 except can handle up 16 bytes of parametes +// +// Arguments: [vpfn16] -- see Callback16Ex +// [dwFlags] -- +// [cbArgs] -- +// [pArgs] -- +// [pdwRetCode] -- +// +// Returns: +// +// History: 12-08-94 JohannP (Johann Posch) Created +// +// Notes: +// +//---------------------------------------------------------------------------- +BOOL WINAPI SSCallback16Ex(DWORD vpfn16, DWORD dwFlags, + DWORD cbArgs, PVOID pArgs, PDWORD pdwRetCode) +{ + DWORD dwRet; + // switch to the 16 bit stack + // + if (SSONBIGSTACK()) + { + StackDebugOut((DEB_STCKSWTCH, "%sSSCallback16Ex 32->16 (%p)\n",NestingLevelString(), vpfn16)); + dwRet = SSCall(20, SSF_SmallStack, WOWCallback16Ex,vpfn16, dwFlags, cbArgs, pArgs, pdwRetCode); + StackDebugOut((DEB_STCKSWTCH, "%sSSCallback16Ex 32<-16 done\n",NestingLevelString() )); + } + else + { + dwRet = WOWCallback16Ex(vpfn16, dwFlags, cbArgs, pArgs, pdwRetCode); + } + return dwRet; + +} + +//+--------------------------------------------------------------------------- +// +// Function: InvokeOn32 +// +// Synopsis: Switches to the 32 bit stack and calls SSAPI(InvokeOn32) +// +// Arguments: [dw1] -- See SSAPI(InvokeOn32) +// [dwMethod] -- +// [pvStack16] -- +// +// Returns: +// +// History: 12-08-94 JohannP (Johann Posch) Created +// +// Notes: Only executed under WIN95 +// +//---------------------------------------------------------------------------- +STDAPI_(DWORD) InvokeOn32 (DWORD dw1, DWORD dwMethod, LPVOID pvStack16) +{ + DWORD dwRes; + if (SSONSMALLSTACK()) + { + StackDebugOut((DEB_STCKSWTCH, "%sSSInvokeOn32 16->32 (0x%08x, %p)\n", + NestingLevelString(), dwMethod, pvStack16)); + dwRes = SSCall(12 ,SSF_BigStack, SSInvokeOn32, dw1, dwMethod, pvStack16); + StackDebugOut((DEB_STCKSWTCH, "%sSSInvokeOn32 16<-32 done(0x%08x, %p)\n", + NestingLevelString(), dwMethod, pvStack16)); + } + else + dwRes = SSInvokeOn32(dw1, dwMethod, pvStack16); + + return dwRes; +} + +#endif // _CHICAGO_ + diff --git a/private/ole32/olethunk/olethk32/map_dwp.h b/private/ole32/olethunk/olethk32/map_dwp.h new file mode 100644 index 000000000..7c2173143 --- /dev/null +++ b/private/ole32/olethunk/olethk32/map_dwp.h @@ -0,0 +1,66 @@ + + +//////////////////////////////////////////////////////////////////////////// + + + +class FAR CMapDwordPtr +{ +public: + // Construction + CMapDwordPtr(UINT nBlockSize=10) + : m_mkv(sizeof(void FAR*), sizeof(DWORD), nBlockSize) { } + + // Attributes + // number of elements + int GetCount() const + { return m_mkv.GetCount(); } + BOOL IsEmpty() const + { return GetCount() == 0; } + + // Lookup + BOOL Lookup(DWORD key, void FAR* FAR& value) const + { return m_mkv.Lookup((LPVOID) &key, sizeof(DWORD), (LPVOID)&value); } + + BOOL LookupHKey(HMAPKEY hKey, void FAR* FAR& value) const + { return m_mkv.LookupHKey(hKey, (LPVOID)&value); } + + BOOL LookupAdd(DWORD key, void FAR* FAR& value) const + { return m_mkv.LookupAdd((LPVOID)&key, sizeof(DWORD), (LPVOID)&value); } + + // Add/Delete + // add a new (key, value) pair + BOOL SetAt(DWORD key, void FAR* value) + { return m_mkv.SetAt((LPVOID) &key, sizeof(DWORD), (LPVOID)&value); } + BOOL SetAtHKey(HMAPKEY hKey, void FAR* value) + { return m_mkv.SetAtHKey(hKey, (LPVOID)&value); } + + // removing existing (key, ?) pair + BOOL RemoveKey(DWORD key) + { return m_mkv.RemoveKey((LPVOID) &key, sizeof(DWORD)); } + + BOOL RemoveHKey(HMAPKEY hKey) + { return m_mkv.RemoveHKey(hKey); } + + void RemoveAll() + { m_mkv.RemoveAll(); } + + + // iterating all (key, value) pairs + POSITION GetStartPosition() const + { return m_mkv.GetStartPosition(); } + + void GetNextAssoc(POSITION FAR& rNextPosition, DWORD FAR& rKey, void FAR* FAR& rValue) const + { m_mkv.GetNextAssoc(&rNextPosition, (LPVOID)&rKey, NULL, (LPVOID)&rValue); } + + HMAPKEY GetHKey(DWORD key) const + { return m_mkv.GetHKey((LPVOID)&key, sizeof(DWORD)); } + +#ifdef _DEBUG + void AssertValid() const + { m_mkv.AssertValid(); } +#endif + +private: + CMapKeyToValue m_mkv; +}; diff --git a/private/ole32/olethunk/olethk32/map_kv.cxx b/private/ole32/olethunk/olethk32/map_kv.cxx new file mode 100644 index 000000000..152c717d3 --- /dev/null +++ b/private/ole32/olethunk/olethk32/map_kv.cxx @@ -0,0 +1,540 @@ +///////////////////////////////////////////////////////////////////////////// +// class CMapKeyToValue - a mapping from 'KEY's to 'VALUE's, passed in as +// pv/cb pairs. The keys can be variable length, although we optmizize the +// case when they are all the same. +// +///////////////////////////////////////////////////////////////////////////// +#include "headers.cxx" +#pragma hdrstop + +#include <olecoll.h> +#include "map_kv.h" +#include "plex.h" + + +///////////////////////////////////////////////////////////////////////////// + + +//CMapKeyToValue::CMapKeyToValue(DWORD memctx, UINT cbValue, UINT cbKey, +CMapKeyToValue::CMapKeyToValue(UINT cbValue, UINT cbKey, + int nBlockSize, LPFNHASHKEY lpfnHashKey, UINT nHashSize) +{ + Assert(nBlockSize > 0); + + m_cbValue = cbValue; + m_cbKey = cbKey; + m_cbKeyInAssoc = cbKey == 0 ? sizeof(CKeyWrap) : cbKey; + + m_pHashTable = NULL; + m_nHashTableSize = nHashSize; + m_lpfnHashKey = lpfnHashKey; + + m_nCount = 0; + m_pFreeList = NULL; + m_pBlocks = NULL; + m_nBlockSize = nBlockSize; + //if (memctx == MEMCTX_SAME) + // memctx = CoMemctxOf(this); + //m_memctx = memctx; + //Assert(m_memctx != MEMCTX_UNKNOWN); +} + +CMapKeyToValue::~CMapKeyToValue() +{ + ASSERT_VALID(this); + RemoveAll(); + Assert(m_nCount == 0); +} + + +// simple, default hash function +// REVIEW: need to check the value in this for GUIDs and strings +STDAPI_(UINT) MKVDefaultHashKey(LPVOID pKey, UINT cbKey) +{ + UINT hash = 0; + BYTE FAR* lpb = (BYTE FAR*)pKey; + + while (cbKey-- != 0) + hash = 257 * hash + *lpb++; + + return hash; +} + + +BOOL CMapKeyToValue::InitHashTable() +{ + ASSERT_VALID(this); + Assert(m_nHashTableSize > 0); + + if (m_pHashTable != NULL) + return TRUE; + + Assert(m_nCount == 0); + + if ((m_pHashTable = (CAssoc FAR* FAR*)CoTaskMemAlloc(m_nHashTableSize * sizeof(CAssoc FAR*))) == NULL) + return FALSE; + + memset(m_pHashTable, 0, sizeof(CAssoc FAR*) * m_nHashTableSize); + + ASSERT_VALID(this); + + return TRUE; +} + + +void CMapKeyToValue::RemoveAll() +{ + ASSERT_VALID(this); + + // free all key values and then hash table + if (m_pHashTable != NULL) + { + // destroy assocs + for (UINT nHash = 0; nHash < m_nHashTableSize; nHash++) + { + register CAssoc FAR* pAssoc; + for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; + pAssoc = pAssoc->pNext) + // assoc itself is freed by FreeDataChain below + FreeAssocKey(pAssoc); + } + + // free hash table + CoTaskMemFree(m_pHashTable); + m_pHashTable = NULL; + } + + m_nCount = 0; + m_pFreeList = NULL; + m_pBlocks->FreeDataChain(); + m_pBlocks = NULL; + + ASSERT_VALID(this); +} + +///////////////////////////////////////////////////////////////////////////// +// Assoc helpers +// CAssoc's are singly linked all the time + +CMapKeyToValue::CAssoc FAR* + CMapKeyToValue::NewAssoc(UINT hash, LPVOID pKey, UINT cbKey, LPVOID pValue) +{ + if (m_pFreeList == NULL) + { + // add another block + CPlex FAR* newBlock = CPlex::Create(m_pBlocks, m_nBlockSize, SizeAssoc()); + + if (newBlock == NULL) + return NULL; + + // chain them into free list + register BYTE FAR* pbAssoc = (BYTE FAR*) newBlock->data(); + // free in reverse order to make it easier to debug + pbAssoc += (m_nBlockSize - 1) * SizeAssoc(); + for (int i = m_nBlockSize-1; i >= 0; i--, pbAssoc -= SizeAssoc()) + { + ((CAssoc FAR*)pbAssoc)->pNext = m_pFreeList; + m_pFreeList = (CAssoc FAR*)pbAssoc; + } + } + Assert(m_pFreeList != NULL); // we must have something + + CMapKeyToValue::CAssoc FAR* pAssoc = m_pFreeList; + + // init all fields except pNext while still on free list + pAssoc->nHashValue = hash; + if (!SetAssocKey(pAssoc, pKey, cbKey)) + return NULL; + + SetAssocValue(pAssoc, pValue); + + // remove from free list after successfully initializing it (except pNext) + m_pFreeList = m_pFreeList->pNext; + m_nCount++; + Assert(m_nCount > 0); // make sure we don't overflow + + return pAssoc; +} + + +// free individual assoc by freeing key and putting on free list +void CMapKeyToValue::FreeAssoc(CMapKeyToValue::CAssoc FAR* pAssoc) +{ + pAssoc->pNext = m_pFreeList; + m_pFreeList = pAssoc; + m_nCount--; + Assert(m_nCount >= 0); // make sure we don't underflow + + FreeAssocKey(pAssoc); +} + + +// find association (or return NULL) +CMapKeyToValue::CAssoc FAR* +CMapKeyToValue::GetAssocAt(LPVOID pKey, UINT cbKey, UINT FAR& nHash) const +{ + if (m_lpfnHashKey) + nHash = (*m_lpfnHashKey)(pKey, cbKey) % m_nHashTableSize; + else + nHash = MKVDefaultHashKey(pKey, cbKey) % m_nHashTableSize; + + if (m_pHashTable == NULL) + return NULL; + + // see if it exists + register CAssoc FAR* pAssoc; + for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) + { + if (CompareAssocKey(pAssoc, pKey, cbKey)) + return pAssoc; + } + return NULL; +} + + +BOOL CMapKeyToValue::CompareAssocKey(CAssoc FAR* pAssoc, LPVOID pKey2, UINT cbKey2) const +{ + LPVOID pKey1; + UINT cbKey1; + + GetAssocKeyPtr(pAssoc, &pKey1, &cbKey1); + return cbKey1 == cbKey2 && memcmp(pKey1, pKey2, cbKey1) == 0; +} + + +BOOL CMapKeyToValue::SetAssocKey(CAssoc FAR* pAssoc, LPVOID pKey, UINT cbKey) const +{ + Assert(cbKey == m_cbKey || m_cbKey == 0); + + if (m_cbKey == 0) + { + Assert(m_cbKeyInAssoc == sizeof(CKeyWrap)); + + // alloc, set size and pointer + if ((pAssoc->key.pKey = CoTaskMemAlloc(cbKey)) == NULL) + return FALSE; + + pAssoc->key.cbKey = cbKey; + } + + LPVOID pKeyTo; + + GetAssocKeyPtr(pAssoc, &pKeyTo, &cbKey); + + memcpy(pKeyTo, pKey, cbKey); + + return TRUE; +} + + +// gets pointer to key and its length +void CMapKeyToValue::GetAssocKeyPtr(CAssoc FAR* pAssoc, LPVOID FAR* ppKey,UINT FAR* pcbKey) const +{ + if (m_cbKey == 0) + { + // variable length key; go indirect + *ppKey = pAssoc->key.pKey; + *pcbKey = pAssoc->key.cbKey; + } + else + { + // fixed length key; key in assoc + *ppKey = (LPVOID)&pAssoc->key; + *pcbKey = m_cbKey; + } +} + + +void CMapKeyToValue::FreeAssocKey(CAssoc FAR* pAssoc) const +{ + if (m_cbKey == 0) + CoTaskMemFree(pAssoc->key.pKey); +} + + +void CMapKeyToValue::GetAssocValuePtr(CAssoc FAR* pAssoc, LPVOID FAR* ppValue) const +{ + *ppValue = (char FAR*)&pAssoc->key + m_cbKeyInAssoc; +} + + +void CMapKeyToValue::GetAssocValue(CAssoc FAR* pAssoc, LPVOID pValue) const +{ + LPVOID pValueFrom; + GetAssocValuePtr(pAssoc, &pValueFrom); + Assert(pValue != NULL); + memcpy(pValue, pValueFrom, m_cbValue); +} + + +void CMapKeyToValue::SetAssocValue(CAssoc FAR* pAssoc, LPVOID pValue) const +{ + LPVOID pValueTo; + GetAssocValuePtr(pAssoc, &pValueTo); + if (pValue == NULL) + memset(pValueTo, 0, m_cbValue); + else + memcpy(pValueTo, pValue, m_cbValue); +} + + +///////////////////////////////////////////////////////////////////////////// + +// lookup value given key; return FALSE if key not found; in that +// case, the value is set to all zeros +BOOL CMapKeyToValue::Lookup(LPVOID pKey, UINT cbKey, LPVOID pValue) const +{ + UINT nHash; + HMAPKEY hmapkey = (HMAPKEY)GetAssocAt(pKey, cbKey, nHash); + return LookupHKey(hmapkey, pValue); + //return LookupHKey((HMAPKEY)GetAssocAt(pKey, cbKey, nHash), pValue); +} + + +// lookup value given key; return FALSE if NULL (or bad) key; in that +// case, the value is set to all zeros +BOOL CMapKeyToValue::LookupHKey(HMAPKEY hKey, LPVOID pValue) const +{ + // REVIEW: would like some way to verify that hKey is valid + register CAssoc FAR* pAssoc = (CAssoc FAR*)hKey; + if (pAssoc == NULL) + { + memset(pValue, 0, m_cbValue); + return FALSE; // not in map + } + + ASSERT_VALID(this); + + GetAssocValue(pAssoc, pValue); + return TRUE; +} + + +// lookup and if not found add; returns FALSE only if OOM; if added, +// value added and pointer passed are set to zeros. +BOOL CMapKeyToValue::LookupAdd(LPVOID pKey, UINT cbKey, LPVOID pValue) const +{ + if (Lookup(pKey, cbKey, pValue)) + return TRUE; + + // value set to zeros since lookup failed + + return ((CMapKeyToValue FAR*)this)->SetAt(pKey, cbKey, NULL); +} + + +// the only place new assocs are created; return FALSE if OOM; +// never returns FALSE if keys already exists +BOOL CMapKeyToValue::SetAt(LPVOID pKey, UINT cbKey, LPVOID pValue) +{ + UINT nHash; + register CAssoc FAR* pAssoc; + + ASSERT_VALID(this); + + if ((pAssoc = GetAssocAt(pKey, cbKey, nHash)) == NULL) + { + if (!InitHashTable()) + // out of memory + return FALSE; + + // it doesn't exist, add a new Association + if ((pAssoc = NewAssoc(nHash, pKey, cbKey, pValue)) == NULL) + return FALSE; + + // put into hash table + pAssoc->pNext = m_pHashTable[nHash]; + m_pHashTable[nHash] = pAssoc; + + ASSERT_VALID(this); + } + else + { + SetAssocValue(pAssoc, pValue); + } + + return TRUE; +} + + +// set existing hkey to value; return FALSE if NULL or bad key +BOOL CMapKeyToValue::SetAtHKey(HMAPKEY hKey, LPVOID pValue) +{ + // REVIEW: would like some way to verify that hKey is valid + register CAssoc FAR* pAssoc = (CAssoc FAR*)hKey; + if (pAssoc == NULL) + return FALSE; // not in map + + ASSERT_VALID(this); + + SetAssocValue(pAssoc, pValue); + return TRUE; +} + + +// remove key - return TRUE if removed +BOOL CMapKeyToValue::RemoveKey(LPVOID pKey, UINT cbKey) +{ + ASSERT_VALID(this); + + if (m_pHashTable == NULL) + return FALSE; // nothing in the table + + register CAssoc FAR* FAR* ppAssocPrev; + UINT i; + if (m_lpfnHashKey) + i = (*m_lpfnHashKey)(pKey, cbKey) % m_nHashTableSize; + else + i = MKVDefaultHashKey(pKey, cbKey) % m_nHashTableSize; + + ppAssocPrev = &m_pHashTable[i]; + + CAssoc FAR* pAssoc; + for (pAssoc = *ppAssocPrev; pAssoc != NULL; pAssoc = pAssoc->pNext) + { + if (CompareAssocKey(pAssoc, pKey, cbKey)) + { + // remove it + *ppAssocPrev = pAssoc->pNext; // remove from list + FreeAssoc(pAssoc); + ASSERT_VALID(this); + return TRUE; + } + ppAssocPrev = &pAssoc->pNext; + } + return FALSE; // not found +} + + +// remove key based on pAssoc (HMAPKEY) +BOOL CMapKeyToValue::RemoveHKey(HMAPKEY hKey) +{ + ASSERT_VALID(this); + + if (m_pHashTable == NULL) + return FALSE; // nothing in the table + + // REVIEW: would like some way to verify that hKey is valid + CAssoc FAR* pAssoc = (CAssoc FAR*)hKey; + if (pAssoc == NULL || pAssoc->nHashValue >= m_nHashTableSize) + // null hkey or bad hash value + return FALSE; + + register CAssoc FAR* FAR* ppAssocPrev; + ppAssocPrev = &m_pHashTable[pAssoc->nHashValue]; + + while (*ppAssocPrev != NULL) + { + if (*ppAssocPrev == pAssoc) + { + // remove it + *ppAssocPrev = pAssoc->pNext; // remove from list + FreeAssoc(pAssoc); + ASSERT_VALID(this); + return TRUE; + } + ppAssocPrev = &(*ppAssocPrev)->pNext; + } + + return FALSE; // not found (must have a screwed up list or passed + // a key from another list) +} + + +HMAPKEY CMapKeyToValue::GetHKey(LPVOID pKey, UINT cbKey) const +{ + UINT nHash; + + ASSERT_VALID(this); + + return (HMAPKEY)GetAssocAt(pKey, cbKey, nHash); +} + + +///////////////////////////////////////////////////////////////////////////// +// Iterating + +// for fixed length keys, copies key to pKey; pcbKey can be NULL; +// for variable length keys, copies pointer to key to pKey; sets pcbKey. + +void CMapKeyToValue::GetNextAssoc(POSITION FAR* pNextPosition, + LPVOID pKey, UINT FAR* pcbKey, LPVOID pValue) const +{ + ASSERT_VALID(this); + + Assert(m_pHashTable != NULL); // never call on empty map + + register CAssoc FAR* pAssocRet = (CAssoc FAR*)*pNextPosition; + Assert(pAssocRet != NULL); + + if (pAssocRet == (CAssoc FAR*) BEFORE_START_POSITION) + { + // find the first association + for (UINT nBucket = 0; nBucket < m_nHashTableSize; nBucket++) + if ((pAssocRet = m_pHashTable[nBucket]) != NULL) + break; + Assert(pAssocRet != NULL); // must find something + } + + // find next association + CAssoc FAR* pAssocNext; + if ((pAssocNext = pAssocRet->pNext) == NULL) + { + // go to next bucket + for (UINT nBucket = pAssocRet->nHashValue + 1; + nBucket < m_nHashTableSize; nBucket++) + if ((pAssocNext = m_pHashTable[nBucket]) != NULL) + break; + } + + // fill in return data + *pNextPosition = (POSITION) pAssocNext; + + // fill in key/pointer to key + LPVOID pKeyFrom; + UINT cbKey; + GetAssocKeyPtr(pAssocRet, &pKeyFrom, &cbKey); + if (m_cbKey == 0) + // variable length key; just return pointer to key itself + *(void FAR* FAR*)pKey = pKeyFrom; + else + memcpy(pKey, pKeyFrom, cbKey); + + if (pcbKey != NULL) + *pcbKey = cbKey; + + // get value + GetAssocValue(pAssocRet, pValue); +} + +///////////////////////////////////////////////////////////////////////////// + +void CMapKeyToValue::AssertValid() const +{ +#ifdef _DEBUG + Assert(m_cbKeyInAssoc == (m_cbKey == 0 ? sizeof(CKeyWrap) : m_cbKey)); + + Assert(m_nHashTableSize > 0); + Assert(m_nCount == 0 || m_pHashTable != NULL); + + if (m_pHashTable != NULL) + Assert(!IsBadReadPtr(m_pHashTable, m_nHashTableSize * sizeof(CAssoc FAR*))); + + if (m_lpfnHashKey) + Assert(!IsBadCodePtr((FARPROC)m_lpfnHashKey)); + + if (m_pFreeList != NULL) + Assert(!IsBadReadPtr(m_pFreeList, SizeAssoc())); + + if (m_pBlocks != NULL) + Assert(!IsBadReadPtr(m_pBlocks, SizeAssoc() * m_nBlockSize)); + + // some collections live as global variables in the libraries, but + // have their existance in some context. Also, we can't check shared + // collections since we might be checking the etask collection + // which would cause an infinite recursion. + // REVIEW: Assert(m_memctx == MEMCTX_SHARED || + // CoMemctxOf(this) == MEMCTX_UNKNOWN || CoMemctxOf(this) == m_memctx); +#endif //_DEBUG +} + diff --git a/private/ole32/olethunk/olethk32/map_kv.h b/private/ole32/olethunk/olethk32/map_kv.h new file mode 100644 index 000000000..608b6bf32 --- /dev/null +++ b/private/ole32/olethunk/olethk32/map_kv.h @@ -0,0 +1,116 @@ +#ifndef __MAP_KV_H__ +#define __MAP_KV_H__ + +//#include <memapi.hxx> + +///////////////////////////////////////////////////////////////////////////// +// class CMapKeyToValue - a mapping from 'KEY's to 'VALUE's, passed in as +// pv/cb pairs. The keys can be variable length, although we optmizize the +// case when they are all the same. +// +///////////////////////////////////////////////////////////////////////////// + +STDAPI_(UINT) MKVDefaultHashKey(LPVOID pKey, UINT cbKey); + +#ifdef WIN32 +DECLARE_HANDLE(HMAPKEY); +#else +DECLARE_HANDLE32(HMAPKEY); +#endif + +typedef UINT (STDAPICALLTYPE FAR* LPFNHASHKEY)(LPVOID, UINT); + +class FAR CMapKeyToValue +{ +public: + CMapKeyToValue(UINT cbValue, UINT cbKey = 0, + int nBlockSize=10, + LPFNHASHKEY lpfnHashKey = NULL, + UINT nHashSize = 17); + ~CMapKeyToValue(); + + // number of elements + int GetCount() const { return m_nCount; } + BOOL IsEmpty() const { return m_nCount == 0; } + + // Lookup; return FALSE if not found + BOOL Lookup(LPVOID pKey, UINT cbKey, LPVOID pValue) const; + BOOL LookupHKey(HMAPKEY hKey, LPVOID pValue) const; + BOOL LookupAdd(LPVOID pKey, UINT cbKey, LPVOID pValue) const; + + // add a new (key, value) pair; return FALSE if out of memory + BOOL SetAt(LPVOID pKey, UINT cbKey, LPVOID pValue); + BOOL SetAtHKey(HMAPKEY hKey, LPVOID pValue); + + // removing existing (key, ?) pair; return FALSE if no such key + BOOL RemoveKey(LPVOID pKey, UINT cbKey); + BOOL RemoveHKey(HMAPKEY hKey); + void RemoveAll(); + + // iterating all (key, value) pairs + POSITION GetStartPosition() const + { return (m_nCount == 0) ? (POSITION)NULL : BEFORE_START_POSITION; } + void GetNextAssoc(POSITION FAR* pNextPosition, LPVOID pKey, + UINT FAR* pcbKey, LPVOID pValue) const; + + // return HMAPKEY for given key; returns NULL if not currently in map + HMAPKEY GetHKey(LPVOID pKey, UINT cbKey) const; + + void AssertValid() const; + +private: + // abstracts, somewhat, variable and fixed sized keys; size is really + // m_cbKeyInAssoc. + union CKeyWrap + { + BYTE rgbKey[sizeof(LPVOID) + sizeof(UINT)]; + struct + { + LPVOID pKey; + UINT cbKey; + }; + }; + + // Association of one key and one value; NOTE: even though in general + // the size of the key and value varies, for any given map, + // the size of an assoc is fixed. + struct CAssoc + { + CAssoc FAR* pNext; + UINT nHashValue; // needed for efficient iteration + CKeyWrap key; // size is really m_cbKeyInAssoc + // BYTE rgbValue[m_cbValue]; + }; + + UINT SizeAssoc() const + { return sizeof(CAssoc)-sizeof(CKeyWrap) + m_cbKeyInAssoc + m_cbValue; } + CAssoc FAR* NewAssoc(UINT hash, LPVOID pKey, UINT cbKey, LPVOID pValue); + void FreeAssoc(CAssoc FAR* pAssoc); + BOOL CompareAssocKey(CAssoc FAR* pAssoc, LPVOID pKey, UINT cbKey) const; + CAssoc FAR* GetAssocAt(LPVOID pKey, UINT cbKey, UINT FAR& nHash) const; + + BOOL SetAssocKey(CAssoc FAR* pAssoc, LPVOID pKey, UINT cbKey) const; + void GetAssocKeyPtr(CAssoc FAR* pAssoc, LPVOID FAR* ppKey,UINT FAR* pcbKey) const; + void FreeAssocKey(CAssoc FAR* pAssoc) const; + void GetAssocValuePtr(CAssoc FAR* pAssoc, LPVOID FAR* ppValue) const; + void GetAssocValue(CAssoc FAR* pAssoc, LPVOID pValue) const; + void SetAssocValue(CAssoc FAR* pAssoc, LPVOID pValue) const; + + BOOL InitHashTable(); + + UINT m_cbValue; + UINT m_cbKey; // variable length if 0 + UINT m_cbKeyInAssoc; // always non-zero + + CAssoc FAR* FAR* m_pHashTable; + UINT m_nHashTableSize; + LPFNHASHKEY m_lpfnHashKey; + + int m_nCount; + CAssoc FAR* m_pFreeList; + struct CPlex FAR* m_pBlocks; + int m_nBlockSize; +}; + + +#endif // !__MAP_KV_H__ diff --git a/private/ole32/olethunk/olethk32/map_kv.hxx b/private/ole32/olethunk/olethk32/map_kv.hxx new file mode 100644 index 000000000..37e0ed7a1 --- /dev/null +++ b/private/ole32/olethunk/olethk32/map_kv.hxx @@ -0,0 +1,114 @@ +#ifndef __MAP_KV_H__ +#define __MAP_KV_H__ + +///////////////////////////////////////////////////////////////////////////// +// class CMapKeyToValue - a mapping from 'KEY's to 'VALUE's, passed in as +// pv/cb pairs. The keys can be variable length, although we optmizize the +// case when they are all the same. +// +///////////////////////////////////////////////////////////////////////////// + +STDAPI_(UINT) MKVDefaultHashKey(LPVOID pKey, UINT cbKey); + +#ifdef WIN32 +DECLARE_HANDLE(HMAPKEY); +#else +DECLARE_HANDLE32(HMAPKEY); +#endif + +typedef UINT (STDAPICALLTYPE FAR* LPFNHASHKEY)(LPVOID, UINT); + +class FAR CMapKeyToValue +{ +public: + CMapKeyToValue(DWORD memctx, UINT cbValue, UINT cbKey = 0, + int nBlockSize=10, LPFNHASHKEY lpfnHashKey = &MKVDefaultHashKey, + UINT nHashSize = 17); + ~CMapKeyToValue(); + + // number of elements + int GetCount() const { return m_nCount; } + BOOL IsEmpty() const { return m_nCount == 0; } + + // Lookup; return FALSE if not found + BOOL Lookup(LPVOID pKey, UINT cbKey, LPVOID pValue) const; + BOOL LookupHKey(HMAPKEY hKey, LPVOID pValue) const; + BOOL LookupAdd(LPVOID pKey, UINT cbKey, LPVOID pValue) const; + + // add a new (key, value) pair; return FALSE if out of memory + BOOL SetAt(LPVOID pKey, UINT cbKey, LPVOID pValue); + BOOL SetAtHKey(HMAPKEY hKey, LPVOID pValue); + + // removing existing (key, ?) pair; return FALSE if no such key + BOOL RemoveKey(LPVOID pKey, UINT cbKey); + BOOL RemoveHKey(HMAPKEY hKey); + void RemoveAll(); + + // iterating all (key, value) pairs + POSITION GetStartPosition() const + { return (m_nCount == 0) ? (POSITION)NULL : BEFORE_START_POSITION; } + void GetNextAssoc(POSITION FAR* pNextPosition, LPVOID pKey, + UINT FAR* pcbKey, LPVOID pValue) const; + + // return HMAPKEY for given key; returns NULL if not currently in map + HMAPKEY GetHKey(LPVOID pKey, UINT cbKey) const; + + void AssertValid() const; + +private: + // abstracts, somewhat, variable and fixed sized keys; size is really + // m_cbKeyInAssoc. + union CKeyWrap + { + BYTE rgbKey[sizeof(LPVOID) + sizeof(UINT)]; + struct + { + LPVOID pKey; + UINT cbKey; + }; + }; + + // Association of one key and one value; NOTE: even though in general + // the size of the key and value varies, for any given map, + // the size of an assoc is fixed. + struct CAssoc + { + CAssoc FAR* pNext; + UINT nHashValue; // needed for efficient iteration + CKeyWrap key; // size is really m_cbKeyInAssoc + // BYTE rgbValue[m_cbValue]; + }; + + UINT SizeAssoc() const + { return sizeof(CAssoc)-sizeof(CKeyWrap) + m_cbKeyInAssoc + m_cbValue; } + CAssoc FAR* NewAssoc(UINT hash, LPVOID pKey, UINT cbKey, LPVOID pValue); + void FreeAssoc(CAssoc FAR* pAssoc); + BOOL CompareAssocKey(CAssoc FAR* pAssoc, LPVOID pKey, UINT cbKey) const; + CAssoc FAR* GetAssocAt(LPVOID pKey, UINT cbKey, UINT FAR& nHash) const; + + BOOL SetAssocKey(CAssoc FAR* pAssoc, LPVOID pKey, UINT cbKey) const; + void GetAssocKeyPtr(CAssoc FAR* pAssoc, LPVOID FAR* ppKey,UINT FAR* pcbKey) const; + void FreeAssocKey(CAssoc FAR* pAssoc) const; + void GetAssocValuePtr(CAssoc FAR* pAssoc, LPVOID FAR* ppValue) const; + void GetAssocValue(CAssoc FAR* pAssoc, LPVOID pValue) const; + void SetAssocValue(CAssoc FAR* pAssoc, LPVOID pValue) const; + + BOOL InitHashTable(); + + UINT m_cbValue; + UINT m_cbKey; // variable length if 0 + UINT m_cbKeyInAssoc; // always non-zero + + CAssoc FAR* FAR* m_pHashTable; + UINT m_nHashTableSize; + LPFNHASHKEY m_lpfnHashKey; + + int m_nCount; + CAssoc FAR* m_pFreeList; + struct CPlex FAR* m_pBlocks; + int m_nBlockSize; + DWORD m_memctx; +}; + + +#endif // !__MAP_KV_H__ diff --git a/private/ole32/olethunk/olethk32/mmodel.cxx b/private/ole32/olethunk/olethk32/mmodel.cxx new file mode 100644 index 000000000..e097b16cb --- /dev/null +++ b/private/ole32/olethunk/olethk32/mmodel.cxx @@ -0,0 +1,232 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: mmodel.cxx +// +// Contents: CMemoryModel +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +CMemoryModel16 mmodel16Public(TRUE); +CMemoryModel16 mmodel16Owned(FALSE); +CMemoryModel32 mmodel32; + +//+--------------------------------------------------------------------------- +// +// Method: CMemoryModel16::AllocMemory +// +// Synopsis: Allocates memory +// +// Arguments: [cb] - Size of block to allocate +// +// Returns: New address of block or NULL +// +// History: 7-05-94 BobDay (Bob Day) Created +// +//---------------------------------------------------------------------------- + +DWORD CMemoryModel16::AllocMemory(DWORD cb) +{ + VPVOID vpv; + HMEM16 hmem16; + + thkAssert(cb > 0); + + vpv = WgtAllocLock(GMEM_MOVEABLE, cb, &hmem16); + if (vpv == 0) + { + // + // Not able to allocate a 16-bit memory block! + // + thkDebugOut((DEB_ERROR, + "CMemoryModel16::AllocMemory, " + "Allocation failed, size %08lX\n", + cb)); + return 0; + } + + if (_fPublic) + { + SetOwnerPublicHMEM16(hmem16); + } + + return vpv; +} + +//+--------------------------------------------------------------------------- +// +// Method: CMemoryModel16::FreeMemory +// +// Synopsis: Deallocates a block of memory previously allocated +// +// Arguments: [dwMem] - Address of memory block to free +// +// History: 7-05-94 BobDay (Bob Day) Created +// +//---------------------------------------------------------------------------- + +void CMemoryModel16::FreeMemory(DWORD dwMem) +{ + thkAssert(dwMem != 0); + + WgtUnlockFree(dwMem); +} + +//+--------------------------------------------------------------------------- +// +// Method: CMemoryModel16::ResolvePtr +// +// Synopsis: Returns a resolved pointer given an abstract pointer +// +// Arguments: [dwMem] - Address to get pointer from +// [cb] - Length, starting at given address, to make valid +// pointers for. +// +// Returns: LPVOID - A real pointer equivalent to the abstract pointer. +// +// History: 7-05-94 BobDay (Bob Day) Created +// +// Notes: Be careful of alignment issues +// +//---------------------------------------------------------------------------- + +LPVOID CMemoryModel16::ResolvePtr(DWORD dwMem, DWORD cb) +{ + LPVOID pv; + + thkAssert(dwMem != 0 && cb > 0); + + pv = (LPVOID)WOWFIXVDMPTR(dwMem, cb); + if (pv == NULL) + { + thkDebugOut((DEB_ERROR, + "CMemoryModel16::ResolvePtr, " + "WOWGetVDMPointer failed on %08lX, size %08lX\n", + dwMem, cb)); + } + + return pv; +} + +//+--------------------------------------------------------------------------- +// +// Member: CMemoryModel16::ReleasePtr, public +// +// Synopsis: Releases a resolved pointer +// +// Arguments: [dwMem] - Abstract pointer to release +// +// History: 10-Oct-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CMemoryModel16::ReleasePtr(DWORD dwMem) +{ + thkAssert(dwMem != 0); + + WOWRELVDMPTR(dwMem); +} + +//+--------------------------------------------------------------------------- +// +// Method: CMemoryModel32::AllocMemory +// +// Synopsis: Allocates memory +// +// Arguments: [cb] - Size of block to allocate +// +// Returns: New address of block or NULL +// +// History: 7-05-94 BobDay (Bob Day) Created +// +//---------------------------------------------------------------------------- + +DWORD CMemoryModel32::AllocMemory(DWORD cb) +{ + DWORD dwMem; + + thkAssert(cb > 0); + + dwMem = (DWORD)CoTaskMemAlloc(cb); + if (dwMem == 0) + { + // + // Not able to allocate a 32-bit memory block! + // + thkDebugOut((DEB_ERROR, + "CMemoryModel32::AllocBlock, " + "CoTaskMemAlloc failed size %08lX\n", + cb)); + return 0; + } + + return dwMem; +} + +//+--------------------------------------------------------------------------- +// +// Method: CMemoryModel32::FreeMemory +// +// Synopsis: Deallocates a block of memory previously allocated +// +// Arguments: [dwMem] - Address of memory block to free +// +// History: 7-05-94 BobDay (Bob Day) Created +// +//---------------------------------------------------------------------------- + +void CMemoryModel32::FreeMemory(DWORD dwMem) +{ + thkAssert(dwMem != 0); + + CoTaskMemFree((LPVOID)dwMem); +} + +//+--------------------------------------------------------------------------- +// +// Method: CMemoryModel32::ResolvePtr +// +// Synopsis: Returns a resolved pointer given an abstract pointer +// +// Arguments: [dwMem] - Address to get pointer from +// [cb] - Length, starting at given address, to make valid +// pointers for. +// +// Returns: LPVOID - A real pointer equivalent to the abstract pointer. +// +// History: 7-05-94 BobDay (Bob Day) Created +// +// Notes: Be careful of alignment issues +// +//---------------------------------------------------------------------------- + +LPVOID CMemoryModel32::ResolvePtr(DWORD dwMem, DWORD cb) +{ + thkAssert(dwMem != 0 && cb > 0); + + return (LPVOID)dwMem; +} + +//+--------------------------------------------------------------------------- +// +// Member: CMemoryModel32::ReleasePtr, public +// +// Synopsis: Releases a resolved pointer +// +// Arguments: [dwMem] - Abstract pointer to release +// +// History: 10-Oct-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CMemoryModel32::ReleasePtr(DWORD dwMem) +{ + thkAssert(dwMem != 0); +} diff --git a/private/ole32/olethunk/olethk32/mmodel.hxx b/private/ole32/olethunk/olethk32/mmodel.hxx new file mode 100644 index 000000000..be7da2be2 --- /dev/null +++ b/private/ole32/olethunk/olethk32/mmodel.hxx @@ -0,0 +1,88 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: mmodel.hxx +// +// Contents: CMemoryModel +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#ifndef __MMODEL_HXX__ +#define __MMODEL_HXX__ + +//+--------------------------------------------------------------------------- +// +// Class: CMemoryModel (mm) +// +// Purpose: Defines an abstract interface to memory allocation +// so that code can be written which uses both 16 and +// 32-bit memory +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +class CMemoryModel +{ +public: + virtual DWORD AllocMemory(DWORD cb) = 0; + virtual void FreeMemory(DWORD dwMem) = 0; + virtual LPVOID ResolvePtr(DWORD dwMem, DWORD cb) = 0; + virtual void ReleasePtr(DWORD dwMem) = 0; +}; + +//+--------------------------------------------------------------------------- +// +// Class: CMemoryModel16 (mm16) +// +// Purpose: 16-bit memory model +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +class CMemoryModel16 : public CMemoryModel +{ +public: + CMemoryModel16(BOOL fPublic) + { + _fPublic = fPublic; + } + + virtual DWORD AllocMemory(DWORD cb); + virtual void FreeMemory(DWORD dwMem); + virtual LPVOID ResolvePtr(DWORD dwMem, DWORD cb); + virtual void ReleasePtr(DWORD dwMem); + +private: + BOOL _fPublic; +}; + +//+--------------------------------------------------------------------------- +// +// Class: CMemoryModel32 (mm32) +// +// Purpose: 16-bit memory model +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +class CMemoryModel32 : public CMemoryModel +{ +public: + virtual DWORD AllocMemory(DWORD cb); + virtual void FreeMemory(DWORD dwMem); + virtual LPVOID ResolvePtr(DWORD dwMem, DWORD cb); + virtual void ReleasePtr(DWORD dwMem); +}; + +extern CMemoryModel16 mmodel16Public; +extern CMemoryModel16 mmodel16Owned; +extern CMemoryModel32 mmodel32; + +#endif // #ifndef __MMODEL_HXX__ diff --git a/private/ole32/olethunk/olethk32/nest.hxx b/private/ole32/olethunk/olethk32/nest.hxx new file mode 100644 index 000000000..42b3f6aba --- /dev/null +++ b/private/ole32/olethunk/olethk32/nest.hxx @@ -0,0 +1,32 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: nest.hxx +// +// Contents: Nested Log Helping macros & function +// +// History: 17-Jul-94 BobDay Split off from THOPUTIL.HXX due +// to header ordering problems. +// +//---------------------------------------------------------------------------- +#ifndef __NEST_HXX__ +#define __NEST_HXX__ + +#if DBG == 1 + +extern int _iThunkNestingLevel; + +char *NestingLevelString(void); +#define DebugIncrementNestingLevel() (_iThunkNestingLevel++) +#define DebugDecrementNestingLevel() (_iThunkNestingLevel--) + +#else + +#define DebugIncrementNestingLevel() +#define DebugDecrementNestingLevel() + +#endif + +#endif // #ifndef __NEST_HXX__ diff --git a/private/ole32/olethunk/olethk32/olethk32.cxx b/private/ole32/olethunk/olethk32/olethk32.cxx new file mode 100644 index 000000000..520a04b9f --- /dev/null +++ b/private/ole32/olethunk/olethk32/olethk32.cxx @@ -0,0 +1,616 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: olethk32.cxx +// +// Contents: Main routines for olethk32.dll +// +// History: 22-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#include <userapis.h> +#pragma hdrstop + +#include <thkmgr.hxx> +#include <stdio.h> + + +DECLARE_INFOLEVEL(thk); +DECLARE_INFOLEVEL(Stack); + +DATA16 gdata16Data; + +#if DBG == 1 +BOOL fSaveProxy = FALSE; // Used to find apps who call dead proxies +BOOL fStabilizeProxies = TRUE; // Used to easily disable stabilization +BOOL fZapProxy = FALSE; // Used to zap entries in freelist + +#ifdef _CHICAGO_ +BOOL fSSOn = TRUE; +#endif // _CHICAGO_ + +#if defined(__cplusplus) +extern "C" +{ +#endif +void CallOutputFunctions(const char *buffer); +#if defined(__cplusplus) +} +#endif + +#endif + +CLIPFORMAT g_cfLinkSourceDescriptor, g_cfObjectDescriptor; + +BYTE g_abLeadTable[256]; + +//+--------------------------------------------------------------------------- +// +// Function: DoThreadDetach +// +// Synopsis: When a thread is detaching, cleanup for it. +// +// Effects: This is called during both DLL_THREAD_DETACH, and +// DLL_PROCESS_DETACH. +// +// Arguments: (none) +// +// History: 3-18-95 kevinro Created +// +// Notes: +// +//---------------------------------------------------------------------------- +void +DoThreadDetach() +{ + thkDebugOut((DEB_DLL,"_IN DoThreadDetach\n")); + // + // If there is thunk data, clean it up now. + // + if (TlsGetValue(dwTlsThkIndex) != NULL) + { + thkDebugOut((DEB_DLL,"DoThreadDetach calling ThkMgrUninitialize\n")); + ThkMgrUninitialize(0, 0, 0); + } + thkDebugOut((DEB_DLL,"OUT DoThreadDetach\n")); +} +//+--------------------------------------------------------------------------- +// +// Function: LibMain, public +// +// Synopsis: DLL initialization entry point +// +// History: 23-Feb-94 DrewB Created +// +// Notes: +// +// (KevinRo 19-Mar-95) +// +// Caution needs to be exercised during cleanup. OLE32.DLL has +// a pointer that we pass in during CoInitializeWOW. This pointer +// is used to call back into OLETHK32 for cleanup purposes, as well as +// accessing functions exposed by the 16-bit side. It is important that +// when OLETHK32 unloads, the pointer in OLE32 is marked as invalid. +// There is a call during the DLL_PROCESS_DETACH below that causes +// OLE32 to invalidate its pointer. +// +// In addition, the last thread attached to a DLL will not generate +// a DLL_THREAD_DETACH. Instead, it generates a DLL_PROCESS_DETACH. This +// means that DLL_PROCESS_DETACH should perform all the steps that +// DLL_THREAD_DETACH does in addition to whatever DLL_PROCESS_DETACH work +// that needs to be done. +// +// Lastly, OLETHK32.DLL is statically linked to OLE32.DLL. This means +// that OLETHK32.DLL's DLL_PROCESS_DETACH will be called before OLE32's. +// That is why it is safe for us to call the OLE32 entry point during +// DLL_PROCESS_DETACH +//---------------------------------------------------------------------------- + +extern "C" BOOL _CRTAPI1 LibMain(HANDLE hDll, + DWORD dwReason, + LPVOID lpReserved) +{ + switch( dwReason ) + { + case DLL_PROCESS_ATTACH: +#if DBG == 1 + char achInfoLevel[80]; + + if (GetProfileStringA("olethk32", "InfoLevel", "3", achInfoLevel, + sizeof(achInfoLevel)) > 0) + { + thkInfoLevel = strtol (achInfoLevel, NULL, 0); + } +#endif + thkDebugOut((DEB_DLL,"_IN DLL_PROCESS_ATTACH\n")); + + // + // Save a slot in the thread local storage for our PSTACK (pseudo- + // stack) pointer. + // + + if (!TlsThkAlloc()) + { + thkDebugOut((DEB_WARN, "TlsThkAlloc failed\n")); + return FALSE; + } + thkDebugOut((DEB_DLL,"OUT DLL_PROCESS_ATTACH\n")); + break; + + case DLL_THREAD_ATTACH: + thkDebugOut((DEB_DLL,"_IN DLL_THREAD_ATTACH\n")); + TlsSetValue(dwTlsThkIndex, NULL); + thkDebugOut((DEB_DLL,"OUT DLL_THREAD_ATTACH\n")); + break; + + case DLL_THREAD_DETACH: + thkDebugOut((DEB_DLL,"_IN DLL_THREAD_DETACH\n")); + + // + // Call OLE32.DLL and tell it to cleanup for this thread. This will + // not mark OLE32's ptr invalid since this is only a thread detach + // and not a process detach. This is a private API between OLE32 and + // OLETHK32. + // + thkDebugOut((DEB_DLL,"Calling Unload WOW for Thread Detach\n")); + + CoUnloadingWOW(FALSE); + + // + // When the thread for this task goes away, we need to clean out + // the thunk manager. + // + + DoThreadDetach(); + + thkDebugOut((DEB_DLL,"OUT DLL_THREAD_DETACH\n")); + break; + + case DLL_PROCESS_DETACH: + thkDebugOut((DEB_DLL, + "IN DLL_PROCESS_DETACH: %s\n", + lpReserved?"Process Exit":"Dll Unload")); + + // + // The last threads cleanup needs to be done here. + // + if (lpReserved == NULL) + { + // + // Call OLE32.DLL and tell it to cleanup for this thread, and to + // never call us again, since we are going away. This is a private + // API between OLE32 and OLETHK32. This call will mark OLE32's + // private pointer to us as invalid. + // + thkDebugOut((DEB_DLL,"Calling Unload WOW\n")); + + CoUnloadingWOW(TRUE); + + // + // lpReserved being NULL means this cleanup is due to + // a FreeLibrary. If it was due to process exit, there + // is no way for us to determine the state of the data + // structures in the system. Other threads may have been + // right smack in the middle of taking apart data structures. + // + // + // Chicago unloads DLL's differently than NT. On Chicago, the + // 32-bit side cleans up first, plus resources allocated on + // the 32-bit side are released when the 16-bit process goes + // away. On NT, the 16-bit process is treated like a thread, + // so we have to cleanup. + // + +#ifndef _CHICAGO_ + DoThreadDetach(); +#endif + // + // Only cleanup the memory if the process is not going away. + // On Windows NT, there are cases when the NTVDM needs to be + // blown away. We shouldn't be calling back to the 16-bit + // side in this case. Therefore, we explicitly call free here + // instead of putting it in the destructor. + // + flFreeList32.FreeMemoryBlocks(); + flHolderFreeList.FreeMemoryBlocks(); + flRequestFreeList.FreeMemoryBlocks(); + } + + TlsThkFree(); + + // + // Call to cleanup 16-bit memory if we are running on Win95. + // This should free up the 16-bit memory associated with this + // process. This is called in IntOpUninitialize on NT, since it + // needs to be called before the 16-bit side goes away. + // + +#ifdef _CHICAGO_ + flFreeList16.FreeMemoryBlocks(); +#endif + + + thkDebugOut((DEB_DLL,"OUT DLL_PROCESS_DETACH\n")); + break; + } + + return TRUE; +} + +//+--------------------------------------------------------------------------- +// +// Function: IntOpInitialize, public +// +// Synopsis: Initializes the 32-bit interoperability code +// +// Arguments: [lpdata16] - 16-bit call data +// [dw1] - Ignored +// [dw2] - Ignored +// +// Returns: Appropriate status code +// +// History: 22-Feb-94 JohannP Created +// +//---------------------------------------------------------------------------- + +STDAPI IntOpInitialize(LPDATA16 lpdata16, DWORD dw1, DWORD dw2) +{ + int i; + + thkDebugOut((DEB_ITRACE | DEB_THUNKMGR, "_IN IntOpInitialize (%08lX)\n", + lpdata16)); + + thkAssert((THOP_LASTOP & ~THOP_OPMASK) == 0); + +#if DBG == 1 + char achInfoLevel[80]; +#ifdef _CHICAGO_ + if (GetProfileStringA("CairOLE InfoLevels", + "Stack", "3", achInfoLevel, + sizeof(achInfoLevel)) > 0) + { + StackInfoLevel = strtol (achInfoLevel, NULL, 0); + } + + if (GetProfileStringA("CairOLE InfoLevels", + "StackOn", "3", achInfoLevel, + sizeof(achInfoLevel)) > 0) + { + fSSOn = strtol (achInfoLevel, NULL, 0); + } +#endif // _CHICAGO_ + + if (GetProfileIntA("olethk32", "BreakOnInit", FALSE)) + { + // DebugBreak's in WOW are fatal unless the exception + // is handled somehow. If a debugger is hooked up, + // it'll get first crack at the break exception + // If not, our handler will ignore the exception so + // execution can continue + + __try + { + DebugBreak(); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } + } + + fSaveProxy = GetProfileIntA("olethk32", "SaveProxy", FALSE); + fZapProxy = GetProfileIntA("olethk32", "ZapProxy", FALSE); + fStabilizeProxies = GetProfileIntA("olethk32", "Stabilize", TRUE); +#endif + + // Copy passed parameter from 16-bit world... + memcpy( (LPVOID)&gdata16Data, (LPVOID)lpdata16, sizeof( DATA16 ) ); + +#if defined(_CHICAGO_) + g_cfObjectDescriptor = + RegisterClipboardFormatA("Object Descriptor"); + g_cfLinkSourceDescriptor = + RegisterClipboardFormatA("Link Source Descriptor"); +#else + g_cfObjectDescriptor = + RegisterClipboardFormat(__TEXT("Object Descriptor")); + g_cfLinkSourceDescriptor = + RegisterClipboardFormat(__TEXT("Link Source Descriptor")); +#endif + if (g_cfObjectDescriptor == 0 || g_cfLinkSourceDescriptor == 0) + { + thkDebugOut((DEB_WARN, "IntOpInitialize: " + "Unable to register clipboard formats\n")); + return E_UNEXPECTED; + } + + // Create a lookup table for lead-byte-ness + // so we can avoid calling IsDBCSLeadByte on every character + // during string validation + for (i = 0; i < 256; i++) + { + g_abLeadTable[i] = (BYTE)IsDBCSLeadByte((BYTE)i); + } + + thkDebugOut((DEB_THUNKMGR | DEB_ITRACE, "OUT IntOpInitialize (%08lX)\n", + lpdata16)); + return NOERROR; +} + +//+--------------------------------------------------------------------------- +// +// Function: IntOpUninitialize, public +// +// Synopsis: Cleanup initiated by 16-bit DLL unload +// +// Arguments: [dw1] +// [dw2] +// [dw3] +// +// History: 29-Nov-94 DrewB Created +// +// Notes: (KevinRo) This routine is only called by compobj.dll. To make +// things even more interesting, it is only called on Windows/NT. Win95 +// does the flFreeList16.FreeMemoryBlocks during PROCESS_DETACH. Cleanup +// of the proxies is not neccessary on Win95, since the 16-bit process will +// clean them up for us. +// +//---------------------------------------------------------------------------- + +STDAPI IntOpUninitialize(DWORD dw1, DWORD dw2, DWORD dw3) +{ + thkDebugOut((DEB_THUNKMGR | DEB_ITRACE, "_IN IntOpUninitialize\n")); +#ifndef _CHICAGO_ + // Remove all existing proxies since we're going to free the + // proxy memory in the next step + if (TlsThkGetData() != NULL) + { + CThkMgr *ptm = TlsThkGetThkMgr(); + + if (ptm) + { + ptm->RemoveAllProxies(); + } + } + + // Clean up the 16-bit freelist at this time because we know + // that 16-bit code is still active and available for callback + // If we waited for the freelist destructor to be called, 16-bit + // code would already be cleaned up and the WOWGlobalFree calls + // would fail + flFreeList16.FreeMemoryBlocks(); + + WgtDump(); +#else + thkAssert(!"IntOpUninitialize called on Win95"); +#endif + thkDebugOut((DEB_THUNKMGR | DEB_ITRACE, "OUT IntOpUninitialize\n")); + return 0; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertHr1632Thunk, public +// +// Synopsis: Trivial function to allow calling HRESULT conversion +// functions from 16-bit +// +// Arguments: [hr] - HRESULT to convert +// [dw1] +// [dw2] +// +// Returns: Appropriate status code +// +// History: 26-Sep-94 DrewB Created +// +// Notes: Required because 16-bit calls to CallProc32W use three +// arguments +// +//---------------------------------------------------------------------------- + +STDAPI ConvertHr1632Thunk(HRESULT hr, DWORD dw1, DWORD dw2) +{ + return TransformHRESULT_1632(hr); +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertHr3216Thunk, public +// +// Synopsis: Trivial function to allow calling HRESULT conversion +// functions from 16-bit +// +// Arguments: [hr] - HRESULT to convert +// [dw1] +// [dw2] +// +// Returns: Appropriate status code +// +// History: 26-Sep-94 DrewB Created +// +// Notes: Required because 16-bit calls to CallProc32W use three +// arguments +// +//---------------------------------------------------------------------------- + +STDAPI ConvertHr3216Thunk(HRESULT hr, DWORD dw1, DWORD dw2) +{ + return TransformHRESULT_3216(hr); +} + +//+------------------------------------------------------------------------- +// +// Function: ThkAddAppCompatFlag +// +// Synopsis: Takes the given flag and ORs it into the current app +// compatibility flag set +// +// Effects: +// +// Arguments: [dwFlag] -- flag to set +// +// Requires: +// +// Returns: void +// +// Signals: +// +// Modifies: +// +// Algorithm: +// +// History: dd-mmm-yy Author Comment +// 15-Mar-95 alexgo author +// +// Notes: This function exists so that 16bit thunk dll's may +// also set app compatibility flags. olethk32 code typically +// sets the flags directly via TlsThkSetAppCompatFlags +// +//-------------------------------------------------------------------------- + +STDAPI_(void) ThkAddAppCompatFlag( DWORD dwFlag ) +{ + DWORD dw; + + dw = TlsThkGetAppCompatFlags(); + + dw |= dwFlag; + + TlsThkSetAppCompatFlags(dw); +} + + +#if DBG == 1 +static LONG _wgtAllocated = 0; + +//+--------------------------------------------------------------------------- +// +// Function: WgtAllocLock, public debug +// +// Synopsis: Tracking for WOWGlobalAllocLock16 +// +// History: 29-Nov-94 DrewB Created +// +//---------------------------------------------------------------------------- + +VPVOID WgtAllocLock(WORD wFlags, DWORD cb, HMEM16 *ph) +{ + HMEM16 h; + VPVOID vpv; + + vpv = WOWGlobalAllocLock16(wFlags, cb, &h); + if (vpv != 0) + { +#ifdef WGT_TRACK + if (WOWGlobalLockSize16(h, &cb) != 0) + { + _wgtAllocated += cb; + WOWGlobalUnlock16(h); + } + else + { + thkDebugOut((DEB_WARN, + "Unable to get size of allocated block 0x%04lX\n", + h)); + + // This is a guess at how big a block Win16 will allocate + _wgtAllocated += (cb+31) & 31; + } +#endif + + if (ph != NULL) + { + *ph = h; + } + } + else + { + thkDebugOut((DEB_WARN, + "Unable to allocate %d bytes of 16-bit memory\n", + cb)); + } + + return vpv; +} + +//+--------------------------------------------------------------------------- +// +// Function: WgtUnlockFree, public +// +// Synopsis: Tracking for WOWGlobalUnlockFree16 +// +// History: 29-Nov-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void WgtUnlockFree(VPVOID vpv) +{ + HMEM16 h; + DWORD cb; + + if (vpv == 0) + { + thkDebugOut((DEB_WARN, "Attempt to free NULL\n")); + } + else + { +#ifdef WGT_TRACK + // BUGBUG - Total hack, incorrect + h = (HMEM16)(vpv >> 16); + + if (WOWGlobalLockSize16(h, &cb) != 0) + { + _wgtAllocated -= cb; + WOWGlobalUnlock16(h); + } + else + { + thkDebugOut((DEB_WARN, + "Unable to get size of allocated block 0x%04lX\n", + h)); + } +#endif + + WOWGlobalUnlockFree16(vpv); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: WgtDump, public +// +// Synopsis: Dumps global tracking information +// +// History: 29-Nov-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void WgtDump(void) +{ + if (_wgtAllocated != 0) + { + thkDebugOut((DEB_WARN, + "%d bytes of 16-bit memory currently allocated\n", + _wgtAllocated)); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: ThkCallOutputFunctions, public +// +// Synopsis: thunked pass-thru to Ole32 CallOutputFunctions for 16-bit land +// +// History: 23-Jan-95 murthys Created +// +//---------------------------------------------------------------------------- + +void ThkCallOutputFunctions(const char * buffer, PVOID dummy1, PVOID dummy2) +{ + CallOutputFunctions(buffer); +} + +#endif // DBG == 1 diff --git a/private/ole32/olethunk/olethk32/olethk32.hxx b/private/ole32/olethunk/olethk32/olethk32.hxx new file mode 100644 index 000000000..f78d48232 --- /dev/null +++ b/private/ole32/olethunk/olethk32/olethk32.hxx @@ -0,0 +1,31 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: olethk32.hxx +// +// Contents: Global definitions +// +// History: 23-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#ifndef __OLETHK32_HXX__ +#define __OLETHK32_HXX__ + +extern DATA16 gdata16Data; + +#if DBG == 1 +extern BOOL fSaveProxy; +extern BOOL fStabilizeProxies; +extern BOOL fZapProxy; +#endif + +extern CLIPFORMAT g_cfLinkSourceDescriptor, g_cfObjectDescriptor; + +extern BYTE g_abLeadTable[]; + +extern DWORD dwTlsThkIndex; + +#endif // #ifndef __OLETHK32_HXX__ diff --git a/private/ole32/olethunk/olethk32/olethk32.rc b/private/ole32/olethunk/olethk32/olethk32.rc new file mode 100644 index 000000000..87034fe3b --- /dev/null +++ b/private/ole32/olethunk/olethk32/olethk32.rc @@ -0,0 +1,14 @@ +#include <windows.h> + +// +// Version resources +// +#include <ntverp.h> +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT2_UNKNOWN +#define VER_FILEDESCRIPTION_STR "Microsoft OLE for Windows and Windows NT" +#define VER_INTERNALNAME_STR "OLETHK32.DLL" +#define VER_ORIGINALFILENAME_STR "OLETHK32.DLL" +#include <common.ver> + + diff --git a/private/ole32/olethunk/olethk32/plex.cxx b/private/ole32/olethunk/olethk32/plex.cxx new file mode 100644 index 000000000..a00245bf2 --- /dev/null +++ b/private/ole32/olethunk/olethk32/plex.cxx @@ -0,0 +1,45 @@ +// This is a part of the Microsoft Foundation Classes C++ library. +// Copyright (C) 1992 Microsoft Corporation +// All rights reserved. +// +// This source code is only intended as a supplement to the +// Microsoft Foundation Classes Reference and Microsoft +// QuickHelp documentation provided with the library. +// See these sources for detailed information regarding the +// Microsoft Foundation Classes product. + +#include "headers.cxx" +#pragma hdrstop + +//#include <ole2int.h> +#include "plex.h" + +// Collection support + +#define CairoleAssert(x) thkAssert(x) + +CPlex FAR* CPlex::Create(CPlex FAR* FAR& pHead, UINT nMax, UINT cbElement) +{ + CairoleAssert(nMax > 0 && cbElement > 0); + CPlex FAR* p = (CPlex FAR*)CoTaskMemAlloc(sizeof(CPlex) + nMax * cbElement); + if (p == NULL) + return NULL; + + p->nMax = nMax; + p->nCur = 0; + p->pNext = pHead; + pHead = p; // change head (adds in reverse order for simplicity) + return p; +} + +void CPlex::FreeDataChain() // free this one and links +{ + CPlex FAR* pThis; + CPlex FAR* pNext; + + for (pThis = this; pThis != NULL; pThis = pNext) { + pNext = pThis->pNext; + pThis->pNext = NULL; // So compiler won't do nasty optimizations + CoTaskMemFree(pThis); + } +} diff --git a/private/ole32/olethunk/olethk32/plex.h b/private/ole32/olethunk/olethk32/plex.h new file mode 100644 index 000000000..7095bb7ae --- /dev/null +++ b/private/ole32/olethunk/olethk32/plex.h @@ -0,0 +1,30 @@ +// This is a part of the Microsoft Foundation Classes C++ library. +// Copyright (C) 1992 Microsoft Corporation +// All rights reserved. +// +// This source code is only intended as a supplement to the +// Microsoft Foundation Classes Reference and Microsoft +// QuickHelp documentation provided with the library. +// See these sources for detailed information regarding the +// Microsoft Foundation Classes product. + +#ifndef __PLEX_H__ +#define __PLEX_H__ + +#define INTERNAL_(x) x + +struct FAR CPlex // warning variable length structure +{ + CPlex FAR* pNext; + UINT nMax; + UINT nCur; + /* BYTE data[maxNum*elementSize]; */ + + INTERNAL_(void FAR*) data() { return this+1; } + + static INTERNAL_(CPlex FAR*) Create(CPlex FAR* FAR& head, UINT nMax, UINT cbElement); + + INTERNAL_(void) FreeDataChain(); // free this one and links +}; + +#endif //__PLEX_H__ diff --git a/private/ole32/olethunk/olethk32/stalloc.cxx b/private/ole32/olethunk/olethk32/stalloc.cxx new file mode 100644 index 000000000..363d49d9a --- /dev/null +++ b/private/ole32/olethunk/olethk32/stalloc.cxx @@ -0,0 +1,397 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: stalloc.cxx +// +// Contents: CStackAllocator +// +// History: 29-Sep-94 DrewB Created +// +// Notes: Loosely based on BobDay's original PSTACK implementation +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +// Pad a count to the given alignment +// Alignment must be 2^n-1 +#define ALIGN_CB(cb, align) \ + (((cb)+(align)) & ~(align)) + +//+--------------------------------------------------------------------------- +// +// Structure: SStackBlock (sb) +// +// Purpose: Header information for stack blocks +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +struct SStackBlock +{ + DWORD dwNextBlock; + DWORD dwStackTop; +}; + +#define BLOCK_OVERHEAD (sizeof(SStackBlock)) +#define BLOCK_START(mem) ((mem)+BLOCK_OVERHEAD) +#define BLOCK_AVAILABLE(cb) ((cb)-BLOCK_OVERHEAD) + +//+--------------------------------------------------------------------------- +// +// Function: CStackAllocator::CStackAllocator, public +// +// Arguments: [pmm] - Memory model to use +// [cbBlock] - Size of chunk to allocate when necessary +// [cbAlignment] - Alignment size, must be 2^N +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +CStackAllocator::CStackAllocator(CMemoryModel *pmm, + DWORD cbBlock, + DWORD cbAlignment) +{ + thkAssert(BLOCK_AVAILABLE(cbBlock) > 0); + + // Ensure that the alignment is a power of two + thkAssert((cbAlignment & (cbAlignment-1)) == 0); + // Store alignment - 1 since that's the actual value we need for + // alignment computations + _cbAlignment = cbAlignment-1; + + // Ensure that overhead and tracking will not affect alignment + thkAssert(ALIGN_CB(BLOCK_OVERHEAD, _cbAlignment) == BLOCK_OVERHEAD && + ALIGN_CB(sizeof(SStackMemTrace), _cbAlignment) == + sizeof(SStackMemTrace)); + + _pmm = pmm; + _cbBlock = cbBlock; + _dwBlocks = 0; + _dwCurrent = 0; + _cbAvailable = 0; + + _psaNext = NULL; + _fActive = TRUE; +} + +//+--------------------------------------------------------------------------- +// +// Member: CStackAllocator::~CStackAllocator, public virtual +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +CStackAllocator::~CStackAllocator(void) +{ + Reset(); +} + +//+--------------------------------------------------------------------------- +// +// Function: CStackAllocator::Alloc, public +// +// Synopsis: Allocates a chunk of memory from the stack +// +// Arguments: [cb] - Amount of memory to allocate +// +// Returns: Pointer to memory or NULL +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD CStackAllocator::Alloc(DWORD cb) +{ + DWORD dwMem; + + thkAssert(cb > 0); + + // Round size up to maintain alignment of stack + cb = ALIGN_CB(cb, _cbAlignment); + +#if DBG == 1 + // Reserve space to record caller + cb += sizeof(SStackMemTrace); +#endif + + thkAssert(cb <= BLOCK_AVAILABLE(_cbBlock)); + + // Check to see if the current block can hold the new allocation + if (cb > _cbAvailable) + { + DWORD dwBlock; + SStackBlock UNALIGNED *psb; + + // It's too big, so allocate a new block + dwBlock = _pmm->AllocMemory(_cbBlock); + if (dwBlock == 0) + { + return 0; + } + + if (_dwBlocks != 0) + { + // Update current top block + psb = (SStackBlock UNALIGNED *) + _pmm->ResolvePtr(_dwBlocks, sizeof(SStackBlock)); + psb->dwStackTop = _dwCurrent; + _pmm->ReleasePtr(_dwBlocks); + } + + // Make the new block the top block + psb = (SStackBlock UNALIGNED *) + _pmm->ResolvePtr(dwBlock, sizeof(SStackBlock)); + psb->dwNextBlock = _dwBlocks; + _dwBlocks = dwBlock; + _pmm->ReleasePtr(dwBlock); + + _dwCurrent = BLOCK_START(dwBlock); + _cbAvailable = BLOCK_AVAILABLE(_cbBlock); + } + + thkAssert(_cbAvailable >= cb); + + dwMem = _dwCurrent; + _dwCurrent += cb; + _cbAvailable -= cb; + +#if DBG == 1 + void *pvMem; + + // Fill memory to show reuse problems + pvMem = _pmm->ResolvePtr(dwMem, cb); + memset(pvMem, 0xED, cb); + _pmm->ReleasePtr(dwMem); +#endif + +#if DBG == 1 + SStackMemTrace UNALIGNED *psmt; + + psmt = (SStackMemTrace UNALIGNED *) + _pmm->ResolvePtr(_dwCurrent-sizeof(SStackMemTrace), + sizeof(SStackMemTrace)); + psmt->cbSize = cb-sizeof(SStackMemTrace); + +#if !defined(_CHICAGO_) + // + // On RISC platforms, psmt points to an unaligned structure. + // Use a temp variable so we don't get an alignment fault + // when RtlGetCallersAddress returns the value. + // + void *pv; + void *pvCaller; + RtlGetCallersAddress(&pvCaller, &pv); + psmt->pvCaller = pvCaller; +#else + // Depends on return address being directly below first argument + psmt->pvCaller = *((void **)&cb-1); +#endif + + thkDebugOut((DEB_MEMORY, "Stack: %p alloc 0x%08lX:%3d, avail %d\n", + psmt->pvCaller, dwMem, cb, _cbAvailable)); + + _pmm->ReleasePtr(_dwCurrent-sizeof(SStackMemTrace)); +#endif + + return dwMem; +} + +//+--------------------------------------------------------------------------- +// +// Function: CStackAllocator::Free, public +// +// Synopsis: Frees allocated memory +// +// Arguments: [dwMem] - Memory +// [cb] - Amount of memory allocated +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CStackAllocator::Free(DWORD dwMem, DWORD cb) +{ + thkAssert(dwMem != 0); + thkAssert(cb > 0); + + // Round size up to maintain alignment of stack + cb = ALIGN_CB(cb, _cbAlignment); + +#if DBG == 1 + cb += sizeof(SStackMemTrace); +#endif + + thkAssert(cb <= BLOCK_AVAILABLE(_cbBlock)); + +#if DBG == 1 + void *pvCaller; + +#if !defined(_CHICAGO_) + void *pv; + RtlGetCallersAddress(&pvCaller, &pv); +#else + // Depends on return address being directly below first argument + pvCaller = *((void **)&dwMem-1); +#endif + + thkDebugOut((DEB_MEMORY, "Stack: %p frees 0x%08lX:%3d, avail %d\n", + pvCaller, dwMem, cb, _cbAvailable)); +#endif + +#if DBG == 1 + if (_dwCurrent-cb != dwMem) + { + thkDebugOut((DEB_ERROR, "Free of %d:%d is not TOS (0x%08lX)\n", + dwMem, cb, _dwCurrent)); + + thkAssert(_dwCurrent-cb == dwMem); + } +#endif + + _dwCurrent -= cb; + _cbAvailable += cb; + +#if DBG == 1 + void *pvMem; + + // Fill memory to show reuse problems + pvMem = _pmm->ResolvePtr(dwMem, cb); + memset(pvMem, 0xDD, cb); + _pmm->ReleasePtr(dwMem); +#endif + + if (_dwCurrent == BLOCK_START(_dwBlocks)) + { + SStackBlock UNALIGNED *psb; + DWORD dwBlock; + + // If we've just freed up an entire block and it's not the + // only block for the stack, free the block itself and + // restore stack state from the next block + // We keep the first block around forever to avoid memory + // thrashing + + psb = (SStackBlock UNALIGNED *) + _pmm->ResolvePtr(_dwBlocks, sizeof(SStackBlock)); + dwBlock = psb->dwNextBlock; + _pmm->ReleasePtr(_dwBlocks); + + if (dwBlock != 0) + { + _pmm->FreeMemory(_dwBlocks); + + _dwBlocks = dwBlock; + psb = (SStackBlock UNALIGNED *) + _pmm->ResolvePtr(_dwBlocks, sizeof(SStackBlock)); + _dwCurrent = psb->dwStackTop; + _cbAvailable = _cbBlock-(_dwCurrent-_dwBlocks); + _pmm->ReleasePtr(_dwBlocks); + } + } +} + +//+--------------------------------------------------------------------------- +// +// Member: CStackAllocator::Reset, public +// +// Synopsis: Releases all memory in the stack +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CStackAllocator::Reset(void) +{ + DWORD dwBlock; + SStackBlock UNALIGNED *psb; + + while (_dwBlocks != 0) + { + psb = (SStackBlock UNALIGNED *) + _pmm->ResolvePtr(_dwBlocks, sizeof(SStackBlock)); + dwBlock = psb->dwNextBlock; + _pmm->ReleasePtr(_dwBlocks); + + _pmm->FreeMemory(_dwBlocks); + + _dwBlocks = dwBlock; + } + + _dwCurrent = 0; + _cbAvailable = 0; +} + +//+--------------------------------------------------------------------------- +// +// Function: CStackAllocator::RecordState, public debug +// +// Synopsis: Records the current state of the stack +// +// Arguments: [psr] - Storage space for information +// +// Modifies: [psr] +// +// History: 28-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +void CStackAllocator::RecordState(SStackRecord *psr) +{ + psr->dwStackPointer = _dwCurrent; + psr->dwThreadId = GetCurrentThreadId(); +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: CStackAllocator::CheckState, public debug +// +// Synopsis: Checks recorded information about the stack against its +// current state +// +// Arguments: [psr] - Recorded information +// +// History: 28-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +void CStackAllocator::CheckState(SStackRecord *psr) +{ + thkAssert(psr->dwThreadId == GetCurrentThreadId()); + + if ((psr->dwStackPointer != 0 && psr->dwStackPointer != _dwCurrent) || + (psr->dwStackPointer == 0 && + _dwCurrent != 0 && _dwCurrent != BLOCK_START(_dwBlocks))) + { + thkDebugOut((DEB_ERROR, "Stack alloc change: 0x%08lX to 0x%08lX\n", + psr->dwStackPointer, _dwCurrent)); + + if (_dwCurrent > BLOCK_START(_dwBlocks)) + { + SStackMemTrace UNALIGNED *psmt; + + psmt = (SStackMemTrace UNALIGNED *) + _pmm->ResolvePtr(_dwCurrent-sizeof(SStackMemTrace), + sizeof(SStackMemTrace)); + thkDebugOut((DEB_ERROR, "Top alloc: %d bytes by %p\n", + psmt->cbSize, psmt->pvCaller)); + _pmm->ReleasePtr(_dwCurrent-sizeof(SStackMemTrace)); + } + + thkAssert(!((psr->dwStackPointer != 0 && + psr->dwStackPointer != _dwCurrent) || + (psr->dwStackPointer == 0 && + _dwCurrent != 0 || + _dwCurrent != BLOCK_START(_dwBlocks)))); + } +} +#endif diff --git a/private/ole32/olethunk/olethk32/stalloc.hxx b/private/ole32/olethunk/olethk32/stalloc.hxx new file mode 100644 index 000000000..7e4a35afc --- /dev/null +++ b/private/ole32/olethunk/olethk32/stalloc.hxx @@ -0,0 +1,113 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: stalloc.hxx +// +// Contents: CStackAllocator +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#ifndef __STALLOC_HXX__ +#define __STALLOC_HXX__ + +//+--------------------------------------------------------------------------- +// +// Struct: SStackMemTrace (smt) +// +// Purpose: Stack memory size/leak checking information +// +// History: 28-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +struct SStackMemTrace +{ + void *pvCaller; + UINT cbSize; +}; +#endif + +//+--------------------------------------------------------------------------- +// +// Class: SStackRecord (sr) +// +// Purpose: Capture stack allocation state +// +// History: 28-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +struct SStackRecord +{ + DWORD dwStackPointer; + DWORD dwThreadId; +}; +#endif + +//+--------------------------------------------------------------------------- +// +// Class: CStackAllocator (sa) +// +// Purpose: Abstract definition of a stack allocator with +// replaceable underlying memory allocator +// +// History: 29-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +class CStackAllocator +{ +public: + CStackAllocator(CMemoryModel *pmm, + DWORD cbBlock, + DWORD cbAlignment); + ~CStackAllocator(void); + + DWORD Alloc(DWORD cb); + void Free(DWORD dwMem, DWORD cb); + +#if DBG == 1 + void RecordState(SStackRecord *psr); + void CheckState(SStackRecord *psr); +#endif + + void Reset(void); + + CStackAllocator *GetNextAllocator(void) + { + return _psaNext; + } + void SetNextAllocator(CStackAllocator *psa) + { + _psaNext = psa; + } + + BOOL GetActive(void) + { + return _fActive; + } + void SetActive(BOOL fActive) + { + _fActive = fActive; + } + +private: + DWORD _cbBlock; + DWORD _cbAlignment; + CMemoryModel *_pmm; + + DWORD _dwBlocks; + DWORD _dwCurrent; + DWORD _cbAvailable; + + CStackAllocator *_psaNext; + BOOL _fActive; +}; + +#endif // #ifndef __STALLOC_HXX__ diff --git a/private/ole32/olethunk/olethk32/struct16.hxx b/private/ole32/olethunk/olethk32/struct16.hxx new file mode 100644 index 000000000..5c2674061 --- /dev/null +++ b/private/ole32/olethunk/olethk32/struct16.hxx @@ -0,0 +1,91 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: struct16.hxx +// +// Contents: 16-bit structures for use in 32-bit code +// +// History: 01-Mar-94 DrewB Created +// +//---------------------------------------------------------------------------- +#ifndef __STRUCT16_HXX__ +#define __STRUCT16_HXX__ + +#pragma pack(2) + +typedef struct tagRECT16 +{ + SHORT left; + SHORT top; + SHORT right; + SHORT bottom; +} RECT16; +typedef RECT16 UNALIGNED FAR *LPRECT16; + +typedef struct tagFORMATETC16 +{ + CLIPFORMAT cfFormat; + VPVOID ptd; + DWORD dwAspect; + LONG lindex; + DWORD tymed; +} FORMATETC16; +typedef FORMATETC16 UNALIGNED FAR* LPFORMATETC16; + +typedef struct tagOIFI16 +{ + WORD cb; + WORD fMDIApp; + HAND16 hwndFrame; + HAND16 haccel; + SHORT cAccelEntries; +} OIFI16; +typedef OIFI16 UNALIGNED FAR* LPOIFI16; + +typedef struct tagSTATDATA16 +{ // field used by: + FORMATETC16 formatetc; // EnumAdvise, EnumData (cache), + // EnumFormats + DWORD advf; // EnumAdvise, EnumData (cache) + VPVOID pAdvSink; // EnumAdvise + DWORD dwConnection; // EnumAdvise +} STATDATA16; +typedef STATDATA16 UNALIGNED FAR * LPSTATDATA16; + +typedef struct tagMSG16 +{ + HWND16 hwnd; + WORD message; + WORD wParam; + LONG lParam; + DWORD time; + ULONG pt; +} MSG16; +typedef MSG16 UNALIGNED FAR *LPMSG16; + +typedef struct tagSIZE16 +{ + SHORT cx; + SHORT cy; +} SIZE16; + +typedef struct tagMETAFILEPICT16 +{ + SHORT mm; + SHORT xExt; + SHORT yExt; + HMETAFILE16 hMF; +} METAFILEPICT16; + +typedef struct tagINTERFACEINFO16 +{ + VPVOID pUnk; + IID iid; + WORD wMethod; +} INTERFACEINFO16; + +#pragma pack() + +#endif // #ifndef __STRUCT16_HXX__ diff --git a/private/ole32/olethunk/olethk32/tc1632.cxx b/private/ole32/olethunk/olethk32/tc1632.cxx new file mode 100644 index 000000000..a7a66b70b --- /dev/null +++ b/private/ole32/olethunk/olethk32/tc1632.cxx @@ -0,0 +1,323 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: tc1632.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +#include <headers.cxx> +#pragma hdrstop + +DWORD ThunkCall1632(THUNKINFO *pti) +{ + DWORD dwReturn; + thkAssert(pti->pvfn != NULL); + thkAssert(*pti->pThop == THOP_END); + pti->pThop++; + thkAssert(*pti->pThop == THOP_ROUTINEINDEX); + pti->pThop++; + if (FAILED(pti->scResult)) + { + return (DWORD)pti->scResult; + } + pti->pThkMgr->SetThkState(THKSTATE_NOCALL); + switch(*pti->pThop) + { + case 0: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8) + ); + break; + case 1: + dwReturn = (*(DWORD (__stdcall *)( + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0) + ); + break; + case 2: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8), + *(DWORD *)(pti->s32.pbStart+12) + ); + break; + case 3: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4) + ); + break; + case 4: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8), + *(DWORD *)(pti->s32.pbStart+12), + *(DWORD *)(pti->s32.pbStart+16), + *(DWORD *)(pti->s32.pbStart+20), + *(DWORD *)(pti->s32.pbStart+24) + ); + break; + case 5: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + DWORD, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8), + *(DWORD *)(pti->s32.pbStart+12), + *(DWORD *)(pti->s32.pbStart+16) + ); + break; + case 6: + dwReturn = (*(DWORD (__stdcall *)())pti->pvfn)( + ); + break; + case 7: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8), + *(DWORD *)(pti->s32.pbStart+12), + *(DWORD *)(pti->s32.pbStart+16), + *(DWORD *)(pti->s32.pbStart+20) + ); + break; + case 8: + dwReturn = (*(DWORD (__stdcall *)( + WORD, + WORD, + DWORD))pti->pvfn)( + *(WORD *)(pti->s32.pbStart+0), + *(WORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8) + ); + break; + case 9: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + ULARGE_INTEGER, + DWORD, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(ULARGE_INTEGER UNALIGNED *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+12), + *(DWORD *)(pti->s32.pbStart+16), + *(DWORD *)(pti->s32.pbStart+20) + ); + break; + case 10: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + ULARGE_INTEGER))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(ULARGE_INTEGER UNALIGNED *)(pti->s32.pbStart+4) + ); + break; + case 11: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + ULARGE_INTEGER, + ULARGE_INTEGER, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(ULARGE_INTEGER UNALIGNED *)(pti->s32.pbStart+4), + *(ULARGE_INTEGER UNALIGNED *)(pti->s32.pbStart+12), + *(DWORD *)(pti->s32.pbStart+20) + ); + break; + case 12: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + ULARGE_INTEGER, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(ULARGE_INTEGER UNALIGNED *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+12), + *(DWORD *)(pti->s32.pbStart+16) + ); + break; + case 13: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + ULARGE_INTEGER, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(ULARGE_INTEGER UNALIGNED *)(pti->s32.pbStart+8), + *(DWORD *)(pti->s32.pbStart+16), + *(DWORD *)(pti->s32.pbStart+20) + ); + break; + case 14: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8), + *(DWORD *)(pti->s32.pbStart+12), + *(DWORD *)(pti->s32.pbStart+16), + *(DWORD *)(pti->s32.pbStart+20), + *(DWORD *)(pti->s32.pbStart+24), + *(DWORD *)(pti->s32.pbStart+28), + *(DWORD *)(pti->s32.pbStart+32), + *(DWORD *)(pti->s32.pbStart+36), + *(DWORD *)(pti->s32.pbStart+40) + ); + break; + case 15: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + DWORD, + SIZEL, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8), + *(SIZEL *)(pti->s32.pbStart+12), + *(DWORD *)(pti->s32.pbStart+20) + ); + break; + case 16: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + SIZEL, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(SIZEL *)(pti->s32.pbStart+8), + *(DWORD *)(pti->s32.pbStart+16) + ); + break; + case 17: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + WORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(WORD *)(pti->s32.pbStart+8) + ); + break; + case 18: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + SIZEL))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(SIZEL *)(pti->s32.pbStart+4) + ); + break; + case 19: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + WORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(WORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8) + ); + break; + case 20: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(DWORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8), + *(DWORD *)(pti->s32.pbStart+12), + *(DWORD *)(pti->s32.pbStart+16), + *(DWORD *)(pti->s32.pbStart+20), + *(DWORD *)(pti->s32.pbStart+24), + *(DWORD *)(pti->s32.pbStart+28) + ); + break; + case 21: + dwReturn = (*(DWORD (__stdcall *)( + DWORD, + WORD, + DWORD, + DWORD, + DWORD, + DWORD, + DWORD))pti->pvfn)( + *(DWORD *)(pti->s32.pbStart+0), + *(WORD *)(pti->s32.pbStart+4), + *(DWORD *)(pti->s32.pbStart+8), + *(DWORD *)(pti->s32.pbStart+12), + *(DWORD *)(pti->s32.pbStart+16), + *(DWORD *)(pti->s32.pbStart+20), + *(DWORD *)(pti->s32.pbStart+24) + ); + break; + } + +#if DBG == 1 + if ( !pti->fResultThunked && FAILED(dwReturn) ) + { + thkDebugOut((DEB_FAILURES, + "ThunkCall1632 pvfn = %08lX Probably failed hr = %08lX\n", + pti->pvfn, dwReturn)); + } + +#endif + + pti->pThkMgr->SetThkState(THKSTATE_INVOKETHKOUT32); + return dwReturn; +} diff --git a/private/ole32/olethunk/olethk32/the.hxx b/private/ole32/olethunk/olethk32/the.hxx new file mode 100644 index 000000000..69d320238 --- /dev/null +++ b/private/ole32/olethunk/olethk32/the.hxx @@ -0,0 +1,21 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: the.hxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +#define THE_IEnumString 0 +#define THE_IEnumUnknown 1 +#define THE_IEnumSTATSTG 2 +#define THE_IEnumFORMATETC 3 +#define THE_IEnumSTATDATA 4 +#define THE_IEnumMoniker 5 +#define THE_IEnumOLEVERB 6 diff --git a/private/ole32/olethunk/olethk32/thi.hxx b/private/ole32/olethunk/olethk32/thi.hxx new file mode 100644 index 000000000..5f754af85 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thi.hxx @@ -0,0 +1,73 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thi.hxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +#define THI_IUnknown 0 +#define THI_IClassFactory 1 +#define THI_IMalloc THI_COUNT +#define THI_IMarshal 2 +#define THI_IStdMarshalInfo 3 +#define THI_IMessageFilter 4 +#define THI_IExternalConnection 5 +#define THI_IEnumString 6 +#define THI_IEnumUnknown 7 +#define THI_IEnumSTATSTG 8 +#define THI_ILockBytes 9 +#define THI_IStream 10 +#define THI_IStorage 11 +#define THI_IRootStorage 12 +#define THI_IEnumFORMATETC 13 +#define THI_IEnumSTATDATA 14 +#define THI_IDataObject 15 +#define THI_IViewObject 16 +#define THI_IViewObject2 17 +#define THI_IAdviseSink 18 +#define THI_IAdviseSink2 19 +#define THI_IDataAdviseHolder 20 +#define THI_IOleCache 21 +#define THI_IOleCache2 22 +#define THI_IOleCacheControl 23 +#define THI_IDropTarget 24 +#define THI_IDropSource 25 +#define THI_IPersist 26 +#define THI_IPersistStorage 27 +#define THI_IPersistStream 28 +#define THI_IPersistFile 29 +#define THI_IBindCtx 30 +#define THI_IMoniker 31 +#define THI_IRunningObjectTable 32 +#define THI_IEnumMoniker 33 +#define THI_IEnumOLEVERB 34 +#define THI_IOleObject 35 +#define THI_IOleClientSite 36 +#define THI_IRunnableObject 37 +#define THI_IParseDisplayName 38 +#define THI_IOleContainer 39 +#define THI_IOleItemContainer 40 +#define THI_IOleAdviseHolder 41 +#define THI_IOleLink 42 +#define THI_IOleWindow 43 +#define THI_IOleInPlaceObject 44 +#define THI_IOleInPlaceActiveObject 45 +#define THI_IOleInPlaceUIWindow 46 +#define THI_IOleInPlaceFrame 47 +#define THI_IOleInPlaceSite 48 +#define THI_IRpcChannelBuffer 49 +#define THI_IRpcProxyBuffer 50 +#define THI_IRpcStubBuffer 51 +#define THI_IPSFactoryBuffer 52 +#define THI_IRpcChannel 53 +#define THI_IRpcProxy 54 +#define THI_IRpcStub 55 +#define THI_IPSFactory 56 +#define THI_COUNT 57 diff --git a/private/ole32/olethunk/olethk32/thkmgr.cxx b/private/ole32/olethunk/olethk32/thkmgr.cxx new file mode 100644 index 000000000..983bdbecb --- /dev/null +++ b/private/ole32/olethunk/olethk32/thkmgr.cxx @@ -0,0 +1,536 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thkmgr.cxx +// +// Contents: Thunk manager initialization +// IUnknown transition functions +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +//+--------------------------------------------------------------------------- +// +// Function: ThkMgrInitialize +// +// Synopsis: Creates a new thunkmanager and set it for given thread +// +// Arguments: [dw1] +// [dw2] +// [dw3] +// +// Returns: HRESULT +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +// Notes: Called from CoInitialize +// +//---------------------------------------------------------------------------- +STDAPI ThkMgrInitialize(DWORD dw1, DWORD dw2, DWORD dw3) +{ + CThkMgr *pcthkmgr = NULL; + + thkDebugOut((DEB_THUNKMGR, "In ThkMgrInitialize()\n")); + + // + // If we are already initialized, do nothing. + // + if (TlsGetValue(dwTlsThkIndex) != NULL) + { + thkDebugOut((DEB_THUNKMGR, "OUT ThkMgrInitialize() Already Init\n")); + return(NOERROR); + } + + // + // initialize the Tls storage + // + if ( NOERROR != TlsThkInitialize()) + { + thkDebugOut((DEB_ERROR, "TlsThkInitialize failed")); + + return E_OUTOFMEMORY; + } + + thkAssert(TlsThkGetThkMgr() == NULL); + + pcthkmgr = CThkMgr::Create(); + TlsThkSetThkMgr(pcthkmgr); + + thkDebugOut((DEB_THUNKMGR, "Out ThkMgrInitialize() => %p\n", + pcthkmgr)); + + return (pcthkmgr == NULL) ? E_OUTOFMEMORY : NOERROR; +} + +//+--------------------------------------------------------------------------- +// +// Function: ThkMgrUninitialize +// +// Synopsis: deletes the thunkmanager and removes it from thread data +// tls data are removed as well +// +// Arguments: [dw1] +// [dw2] +// [dw3] +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +// Notes: Called during CoUninitialize +// +//---------------------------------------------------------------------------- +STDAPI_(void) ThkMgrUninitialize(DWORD dw1, DWORD dw2, DWORD dw3) +{ + thkDebugOut((DEB_THUNKMGR, "In ThkMgrUninitialize()\n")); + + thkAssert(TlsGetValue(dwTlsThkIndex) != NULL); + + CThkMgr *pcthkmgr = (CThkMgr*)TlsThkGetThkMgr(); + if (pcthkmgr != NULL) + { + // Note: the thunkmanger gets removed from tlsthk + delete pcthkmgr; + } + + // If we weren't called from 16-bit code then it's not safe to reset + // the 16-bit stack allocator here because we may be doing this + // in thread cleanup and it may not be safe to call back into + // 16-bit code + + TlsThkGetStack32()->Reset(); + + // uninitialize the tls data for this apartment + TlsThkUninitialize(); + + thkDebugOut((DEB_THUNKMGR, "Out ThkMgrUninitialize()\n")); +} + +//+--------------------------------------------------------------------------- +// +// Function: IUnknownObj32 +// +// Synopsis: Entry point from 16bit for IUnknown methods +// +// Arguments: [vpvThis16] -- Proxy object +// [wMethod] -- IUnknown method +// [vpvData] -- Call data +// +// Returns: Call result, pdata contains out data for particular call +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +STDAPI_(DWORD) IUnknownObj32(VPVOID vpvThis16, DWORD wMethod, VPVOID vpvData) +{ + DWORD dwRet; + LONG vpvInterface; + IID iid; + + if (TlsThkGetData() == NULL) + { + thkDebugOut((DEB_WARN, "WARNING: IUnknownObj32 call refused\n")); + + if (wMethod == SMI_QUERYINTERFACE) + { + return (DWORD)E_FAIL; + } + else + { + return 0; + } + } + + // Note: at this point we should always get a thunkmanager + CThkMgr *pcthkmgr = (CThkMgr*)TlsThkGetThkMgr(); + thkAssert(pcthkmgr != NULL && "ThunkManager was not initialized"); + + thkAssert(vpvThis16 != 0 && "IUnknownObj32: invalid pointer." ); + thkAssert(wMethod >= 0 && wMethod < SMI_COUNT); + + switch (wMethod) + { + case SMI_QUERYINTERFACE: + thkAssert(vpvData != NULL && + "IUnknownObj32.QueryInterface without IID"); + + // Copy the 16-bit IID into 32-bit memory for the real call + iid = *FIXVDMPTR(vpvData, IID); + RELVDMPTR(vpvData); + + thkDebugOut((DEB_UNKNOWN, + "%sIn QueryInterface1632(%p, %s)\n", + NestingLevelString(), vpvThis16, + IidOrInterfaceString(&iid))); + + dwRet = pcthkmgr->QueryInterfaceProxy1632(vpvThis16, iid, + (void **)&vpvInterface); + + // Translate the 32-bit HRESULT to a 16-bit HRESULT + dwRet = (DWORD)TransformHRESULT_3216((HRESULT)dwRet); + + // Pass the return interface pointer back through the IID + // memory. We re-resolve the data pointer since nested + // calls may have occurred + (FIXVDMPTR(vpvData, IID))->Data1 = vpvInterface; + RELVDMPTR(vpvData); + + thkDebugOut((DEB_UNKNOWN, + "%sOut QueryInterface1632(%p) => %p, 0x%08lX\n", + NestingLevelString(), vpvThis16, vpvInterface, dwRet)); + break; + + case SMI_ADDREF: + thkDebugOut((DEB_UNKNOWN, "%sIn AddRef1632(%p)\n", + NestingLevelString(), vpvThis16)); + + dwRet = pcthkmgr->AddRefProxy1632(vpvThis16); + + thkDebugOut((DEB_UNKNOWN, "%sOut AddRef1632(%p) => %d\n", + NestingLevelString(), vpvThis16, dwRet)); + break; + + case SMI_RELEASE: + thkDebugOut((DEB_UNKNOWN, "%sIn Release1632(%p)\n", + NestingLevelString(), vpvThis16)); + + dwRet = pcthkmgr->ReleaseProxy1632(vpvThis16); + + thkDebugOut((DEB_UNKNOWN, "%sOut Release1632(%p) => %d\n", + NestingLevelString(), vpvThis16, dwRet)); + break; + } + + return dwRet; +} + +//+--------------------------------------------------------------------------- +// +// Function: QueryInterfaceProxy3216 +// +// Synopsis: call QueryInterface on a 32 bit proxy +// +// Arguments: [pto] -- This pointer (a 32->16 proxy) +// [refiid] -- Interface queried for +// [ppv] -- Interface return +// +// Returns: HRESULT +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +SCODE QueryInterfaceProxy3216(THUNK3216OBJ *pto, REFIID refiid, LPVOID *ppv) +{ + HRESULT hrRet; + + thkDebugOut((DEB_UNKNOWN, "%sIn QueryInterface3216(%p, %s)\n", + NestingLevelString(), pto, + IidOrInterfaceString(&refiid))); + DebugIncrementNestingLevel(); + + if (TlsThkGetData() == NULL) + { + thkDebugOut((DEB_WARN, "WARNING: QIProxy3216 call refused\n")); + + return E_FAIL; + } + + CThkMgr *pcthkmgr = TlsThkGetThkMgr(); + thkAssert(pcthkmgr != NULL && "ThunkManager was not initialized"); + + if ( pto->grfFlags & PROXYFLAG_CLEANEDUP ) + { + thkDebugOut((DEB_WARN, + "QueryInterfaceProxy3216: Attempt to QI " + "on cleaned-up proxy %08lX for 16-bit object %08lX %s\n", + pto, pto->vpvThis16, + IidIdxString(IID_IIDIDX(&refiid)) )); + *ppv = NULL; + return E_FAIL; + } + + hrRet = pcthkmgr->QueryInterfaceProxy3216(pto, refiid, ppv); + + // + // If the QI for IUnknown failed, then return the current this + // pointer as the IUnknown. Watermark 1.02 appears to not support + // IUnknown in its IOleInPlaceActiveObject interface, which causes + // CoMarshalInterface to fail. The reason it used to work is the + // original 16-bit DLL's would just use the provided pointer as + // the punk if IUnknown wasn't supported. The following lines of + // code emulate that behaviour. + // + if ((hrRet == E_NOINTERFACE) && IsEqualIID(refiid,IID_IUnknown)) + { + thkDebugOut((DEB_UNKNOWN, + "%s Object %p didn't support QI(IID_IUnknown): Faking it\n", + NestingLevelString(), pto)); + ((IUnknown *)pto)->AddRef(); + *ppv = pto; + hrRet = S_OK; + } + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_UNKNOWN, + "%sOut QueryInterface3216(%p) => %p, ret:0x%08lX\n", + NestingLevelString(), pto, *ppv, hrRet)); + return hrRet; +} + +//+--------------------------------------------------------------------------- +// +// Function: AddRefProxy3216 +// +// Synopsis: call addref on an 16 bit object +// +// Arguments: [pto] -- This pointer (a 32->16 proxy) +// +// Returns: New refcount +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +DWORD AddRefProxy3216(THUNK3216OBJ *pto) +{ + DWORD dwRet; + + thkDebugOut((DEB_UNKNOWN, "%sIn AddRef3216(%p)\n", + NestingLevelString(), pto)); + DebugIncrementNestingLevel(); + + if (TlsThkGetData() == NULL) + { + thkDebugOut((DEB_WARN, "WARNING: AddRefProxy3216 call refused\n")); + + return 0; + } + + CThkMgr *pcthkmgr = TlsThkGetThkMgr(); + thkAssert(pcthkmgr != NULL && "ThunkManager was not initialized"); + + if ( pto->grfFlags & PROXYFLAG_CLEANEDUP ) + { + thkDebugOut((DEB_WARN, + "AddRefProxy3216: Attempt to AddRef " + "on cleaned-up proxy %08lX for 16-bit object %08lX\n", + pto, pto->vpvThis16)); + return 0; + } + + dwRet = pcthkmgr->AddRefProxy3216(pto); + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_UNKNOWN, "%sOut AddRef3216(%p) => %ld\n", + NestingLevelString(), pto, dwRet)); + + return dwRet; +} + +//+--------------------------------------------------------------------------- +// +// Function: ReleaseProxy3216 +// +// Synopsis: Release implementation for 32->16 proxies +// +// Arguments: [pto] -- This pointer (a 32->16 proxy) +// +// Returns: New refcount +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +DWORD ReleaseProxy3216(THUNK3216OBJ *pto) +{ + DWORD dwRet; + + thkDebugOut((DEB_UNKNOWN, "%sIn Release3216(%p)\n", + NestingLevelString(), pto)); + DebugIncrementNestingLevel(); + + if (TlsThkGetData() == NULL) + { + thkDebugOut((DEB_WARN, "WARNING: ReleaseProxy3216 call refused\n")); + + return 0; + } + + CThkMgr *pcthkmgr = TlsThkGetThkMgr(); + thkAssert(pcthkmgr != NULL && "ThunkManager was not initialized"); + + if ( pto->grfFlags & PROXYFLAG_CLEANEDUP ) + { + thkDebugOut((DEB_WARN, + "ReleaseProxy3216: Attempt to Release " + "on cleaned-up proxy %08lX for 16-bit object %08lX\n", + pto, pto->vpvThis16)); + return 0; + } + + dwRet = pcthkmgr->ReleaseProxy3216(pto); + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_UNKNOWN, "%sOut Release3216(%p) => %ld\n", + NestingLevelString(), pto, dwRet)); + + return dwRet; +} + +//+--------------------------------------------------------------------------- +// +// Function: QueryInterfaceOnObj16 +// +// Synopsis: call QueryInterface on an 16 bit object +// +// Arguments: [vpvThis16] -- 16-bit this pointer +// [refiid] -- IID +// [ppv] -- Interface return +// +// Returns: HRESULT +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- + +struct QIARGS +{ + IID iid; + void *pvObject; +}; + +HRESULT QueryInterfaceOnObj16(VPVOID vpvThis16, REFIID refiid, LPVOID *ppv) +{ + HRESULT hrRet; + VPVOID vpvArgs; + QIARGS UNALIGNED *pqa; + BYTE bArgs32[WCB16_MAX_CBARGS]; + + thkDebugOut((DEB_THUNKMGR, "%sIn QueryInterfaceOnObj16(%p, %s)\n", + NestingLevelString(), vpvThis16, + IidOrInterfaceString(&refiid))); + DebugIncrementNestingLevel(); + + thkAssert(WCB16_MAX_CBARGS >= 3*sizeof(DWORD)); + thkAssert(vpvThis16 != 0 && "QueryInterfaceOnObj16: invalid pointer."); + + // Allocate space for the sixteen bit arguments memory + vpvArgs = STACKALLOC16(sizeof(QIARGS)); + if (vpvArgs == 0) + { + return E_OUTOFMEMORY; + } + + // Fill in the in-param memory + pqa = FIXVDMPTR(vpvArgs, QIARGS); + pqa->iid = refiid; + + // Set up the 16-bit stack in pascal order + *(VPVOID *)(bArgs32+0*sizeof(VPVOID)) = vpvArgs+ + FIELD_OFFSET(QIARGS, pvObject); + *(VPVOID *)(bArgs32+1*sizeof(VPVOID)) = vpvArgs; + *(VPVOID *)(bArgs32+2*sizeof(VPVOID)) = vpvThis16; + + RELVDMPTR(vpvArgs); + + // Call to 16-bit stub + if (!CallbackTo16Ex(gdata16Data.fnQueryInterface16, WCB16_PASCAL, + 3*sizeof(DWORD), bArgs32, (DWORD *)&hrRet)) + { + hrRet = E_UNEXPECTED; + } + + // Transform the 16-bit HRESULT to a 32-bit HRESULT + hrRet = TransformHRESULT_1632(hrRet); + + // Copy back out-param memory + pqa = FIXVDMPTR(vpvArgs, QIARGS); + *ppv = pqa->pvObject; + RELVDMPTR(vpvArgs); + + STACKFREE16(vpvArgs, sizeof(QIARGS)); + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, + "%sOut QueryInterfaceOnObj16(%p) => %p, ret:0x%08lX\n", + NestingLevelString(), vpvThis16, *ppv, hrRet)); + + return hrRet; +} + +//+--------------------------------------------------------------------------- +// +// Function: AddRefOnObj16 +// +// Synopsis: calls addref on an 16 bit object +// +// Arguments: [vpvThis16] -- 16-bit this pointer +// +// Returns: New ref count +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +#if DBG == 1 +DWORD AddRefOnObj16(VPVOID vpvThis16) +{ + DWORD dwRet; + + thkDebugOut((DEB_THUNKMGR, "%sIn AddRefOnObj16(%p)\n", + NestingLevelString(), vpvThis16)); + DebugIncrementNestingLevel(); + + dwRet = CallbackTo16(gdata16Data.fnAddRef16, vpvThis16); + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, "%sOut AddRefOnObj16(%p) => %ld\n", + NestingLevelString(), vpvThis16, dwRet)); + + return dwRet; +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: ReleaseOnObj16 +// +// Synopsis: Release a 16-bit object +// +// Arguments: [vpvThis16] -- 16-bit this pointer +// +// Returns: New ref count +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +#if DBG == 1 +DWORD ReleaseOnObj16(VPVOID vpvThis16) +{ + DWORD dwRet; + + thkDebugOut((DEB_THUNKMGR, "%sIn ReleaseOnObj16(%p)\n", + NestingLevelString(), vpvThis16)); + DebugIncrementNestingLevel(); + + dwRet = CallbackTo16(gdata16Data.fnRelease16, vpvThis16); + + DebugDecrementNestingLevel(); + thkDebugOut((DEB_THUNKMGR, "%sOut ReleaseOnObj16(%p) => %ld\n", + NestingLevelString(), vpvThis16, dwRet)); + + return dwRet; +} +#endif + +#if DBG == 1 +void DebugDump() +{ + CThkMgr *pcthkmgr = (CThkMgr*)TlsThkGetThkMgr(); + thkAssert(pcthkmgr != NULL && "ThunkManager was not initialized"); + pcthkmgr->DebugDump3216(); + pcthkmgr->DebugDump1632(); +} +#endif + diff --git a/private/ole32/olethunk/olethk32/thkmgr.hxx b/private/ole32/olethunk/olethk32/thkmgr.hxx new file mode 100644 index 000000000..28ed5cbb4 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thkmgr.hxx @@ -0,0 +1,40 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thkmgr.hxx +// +// Contents: 16->32 and 32->16 thunk manager definitions +// +// History: 23-Mar-94 JohannP Created +// 22-May-94 BobDay Split out 16-bit definitions +// into obj16.hxx +// +//---------------------------------------------------------------------------- + +#ifndef __THKMGR_HXX__ +#define __THKMGR_HXX__ + +STDAPI ThkMgrInitialize(DWORD dw1, DWORD dw2, DWORD dw3); +STDAPI_(void) ThkMgrUninitialize(DWORD dw1, DWORD dw2, DWORD dw3); + +// +// 32->16 prototypes +// + +SCODE QueryInterfaceProxy3216(THUNK3216OBJ *pto, REFIID refiid, LPVOID *ppv); +DWORD AddRefProxy3216(THUNK3216OBJ *pto); +DWORD ReleaseProxy3216(THUNK3216OBJ *pto); + +HRESULT QueryInterfaceOnObj16(VPVOID vpvThis16, REFIID refiid, LPVOID *ppv); + +#if DBG == 1 +DWORD AddRefOnObj16(VPVOID vpvThis16); +DWORD ReleaseOnObj16(VPVOID vpvThis16); +#else +#define AddRefOnObj16(this) CallbackTo16(gdata16Data.fnAddRef16, this) +#define ReleaseOnObj16(this) CallbackTo16(gdata16Data.fnRelease16, this) +#endif + +#endif // #ifndef __THKMGR_HXX__ diff --git a/private/ole32/olethunk/olethk32/thop.hxx b/private/ole32/olethunk/olethk32/thop.hxx new file mode 100644 index 000000000..159eabfa5 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thop.hxx @@ -0,0 +1,241 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thop.hxx +// +// Contents: Defines the available thops +// +// History: 22-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#ifndef __THOP_HXX__ +#define __THOP_HXX__ + +// +// THOP is a single instruction to the interpreter that encodes, +// decodes parameters sent via LRPC. A string of THOPs describes how to +// marshal, unmarshal function's paramaters. +// +// + +typedef enum +{ + THOP_END, + // Basic types size of type (win3.1) + THOP_SHORTLONG, // Signed ints 2b + THOP_WORDDWORD, // Unsigned int 2b + THOP_COPY, // Direct copies + THOP_LPSTR, // LPSTR -- (zero terminated) + THOP_LPLPSTR, // LPLPSTR -- (zero terminated) + THOP_BUFFER, // void FAR* -- (size in next long) + + // Windows types + THOP_HUSER, // HWND, HMENU 2b + THOP_HGDI, // HDC, HICON 2b + THOP_SIZE, // SIZE 4b + THOP_RECT, // RECT 8b + THOP_MSG, // MSG 18b + + // Ole types + THOP_HRESULT, // HRESULT 4b + THOP_STATSTG, // STATSTG > 38b + size of member lpstr + THOP_DVTARGETDEVICE, // DVTARGETDEVICE > 16b + THOP_STGMEDIUM, // STGMEDIUM > 12b + size of member lpstr + THOP_FORMATETC, // FORMATETC > 18b + size of member tdev + THOP_HACCEL, // HACCEL 2b + THOP_OIFI, // OLEINPLACEFRAMEINFO 10b + THOP_BINDOPTS, // BIND_OPTS > 12b + THOP_LOGPALETTE, // LOGPALETTE > 8b + THOP_SNB, // SNBs in storage Varies + THOP_CRGIID, // ciid, rgiid pair from storage + THOP_OLESTREAM, // OLESTREAM + THOP_HTASK, // HTASK + THOP_INTERFACEINFO, // INTERFACEINFO + + THOP_IFACE, // Known interface type + THOP_IFACEOWNER, // For IFACE cases with weak references + THOP_IFACENOADDREF, // For IFACE cases with no references by user (IOleCacheControl) + THOP_IFACECLEAN, // For IRpcStubBuffer::DebugServerRelease + THOP_IFACEGEN, // for QueryInterface, etc (refiid, **ppUnk) + THOP_IFACEGENOWNER, // For IFACEGEN cases with weak references + + THOP_ROUTINEINDEX, // Thop for indicating the call type index + THOP_RETURNTYPE, // Thop for indicating return type of a routine if + // not HRESULT + THOP_NULL, // NULL ptr, for checking of reserved fields + THOP_ERROR, // Invalid thop, for debugging + THOP_ENUM, // Enumerator thop start + THOP_CALLBACK, // Callback function and argument + THOP_RPCOLEMESSAGE, // RPCOLEMESSAGE + THOP_ALIAS32, // 16-bit alias for 32-bit quantity + THOP_CLSCONTEXT, // Flags DWORD with special handling + THOP_FILENAME, // String which is a filename, needs long/short cvt + THOP_SIZEDSTRING, // String which cannot exceed a certain length + + THOP_LASTOP, // Marker for last op + + THOP_OPMASK = 0x3f, // Mask for basic operation code + + // Modifiers + THOP_IOMASK = 0xc0, + THOP_IN = 0x40, // FAR Pointer to in parameter + THOP_OUT = 0x80, // FAR Pointer to out parameter + THOP_INOUT = 0xc0 // FAR Pointer to in, out parameter +} THOP_TYPE; + +typedef unsigned char THOP; + +#define ALIAS_CREATE 0 +#define ALIAS_RESOLVE 1 +#define ALIAS_REMOVE 2 + +#define MAX_PARAMS 16 + +typedef DWORD (__stdcall * VTBLFN)(DWORD dw); + +typedef struct tagSTACK16INFO +{ + BYTE UNALIGNED *pbStart; + BYTE UNALIGNED *pbCurrent; + int iDir; +} STACK16INFO; + +typedef struct tagSTACK32INFO +{ + BYTE *pbStart; + BYTE *pbCurrent; +} STACK32INFO; + +typedef struct tagTHUNKINFO +{ + STACK16INFO s16; + STACK32INFO s32; + THOP CONST *pThop; + VTBLFN pvfn; + SCODE scResult; + BOOL fResultThunked; + DWORD dwCallerProxy; + CThkMgr *pThkMgr; + IIDIDX iidx; + DWORD dwMethod; + IUnknown *this32; +} THUNKINFO; + +// These are declared extern "C" because there was a bug in the +// PPC compiler (aug '95) where the const related decorations on +// the global data symbols was not done consistantly. By using +// extern "C" the bug is simply avoided. +// The problem was only with aThopFunctions*[] but I added +// aThopEnumFunctions*[] for a consistent look and usage. A related +// bug is fixed with apthopsApiThops[]. + +extern "C" DWORD (* CONST aThopFunctions1632[])(THUNKINFO *); +extern "C" DWORD (* CONST aThopFunctions3216[])(THUNKINFO *); +extern "C" DWORD (* CONST aThopEnumFunctions1632[])(THUNKINFO *); +extern "C" DWORD (* CONST aThopEnumFunctions3216[])(THUNKINFO *); + +#define SKIP_STACK16(s16, cb) \ + (s16)->pbCurrent = (s16)->iDir < 0 ? \ + (s16)->pbCurrent-(cb) : \ + (s16)->pbCurrent+(cb) + +#define PTR_STACK16(s16, cb) \ + ((s16)->pbCurrent-((s16)->iDir < 0 ? (cb) : 0)) + +#define GET_STACK16(pti, val, typ) \ + if ((pti)->s16.iDir < 0) \ + { \ + (pti)->s16.pbCurrent -= sizeof(typ); \ + (val) = *(typ UNALIGNED *)(pti)->s16.pbCurrent; \ + } \ + else \ + { \ + (val) = *(typ UNALIGNED *)(pti)->s16.pbCurrent; \ + (pti)->s16.pbCurrent += sizeof(typ); \ + } + +#define TO_STACK16(pti, val, typ) \ + if ((pti)->s16.iDir < 0) \ + { \ + (pti)->s16.pbCurrent -= sizeof(typ); \ + *(typ UNALIGNED *)(pti)->s16.pbCurrent = (val); \ + } \ + else \ + { \ + *(typ UNALIGNED *)(pti)->s16.pbCurrent = (val); \ + (pti)->s16.pbCurrent += sizeof(typ); \ + } + +#define PEEK_STACK16(pti, val, typ) \ + (val) = *(typ UNALIGNED *)(pti)->s16.pbCurrent + +#define INDEX_STACK16(pti, val, typ, idx, predec) \ + (val) = *(typ UNALIGNED *)((pti)->s16.iDir < 0 ? \ + ((pti)->s16.pbCurrent+(idx)-(predec)) : \ + ((pti)->s16.pbCurrent-(idx))) + +#define SKIP_STACK32(s32, cb) \ + (s32)->pbCurrent += (cb) + +#define PTR_STACK32(s32) \ + (s32)->pbCurrent + +#define GET_STACK32(pti, val, typ) \ + (val) = *(typ *)(pti)->s32.pbCurrent; \ + SKIP_STACK32(&(pti)->s32, sizeof(typ)) + +#define TO_STACK32(pti, val, typ) \ + *(typ *)(pti)->s32.pbCurrent = (val);\ + SKIP_STACK32(&(pti)->s32, sizeof(typ)) + +#define PEEK_STACK32(pti, val, typ) \ + (val) = *(typ *)(pti)->s32.pbCurrent + +#define INDEX_STACK32(pti, val, typ, idx) \ + (val) = *(typ *)((pti)->s32.pbCurrent-(idx)) + +#if DBG == 0 + +// In debug builds this goes through a function that can emit +// debug info about thops being executed +#define EXECUTE_THOP1632(pti) \ + (*aThopFunctions1632[*((pti)->pThop) & THOP_OPMASK])(pti) +#define EXECUTE_THOP3216(pti) \ + (*aThopFunctions3216[*((pti)->pThop) & THOP_OPMASK])(pti) +#define EXECUTE_ENUMTHOP1632(pti) \ + (*aThopEnumFunctions1632[*(pti)->pThop])(pti) +#define EXECUTE_ENUMTHOP3216(pti) \ + (*aThopEnumFunctions3216[*(pti)->pThop])(pti) + +#else + +DWORD EXECUTE_THOP1632(THUNKINFO *pti); +DWORD EXECUTE_THOP3216(THUNKINFO *pti); +DWORD EXECUTE_ENUMTHOP1632(THUNKINFO *pti); +DWORD EXECUTE_ENUMTHOP3216(THUNKINFO *pti); + +#endif + +#define IS_THOP_IN(pti) ((*((pti)->pThop) & THOP_IN) == THOP_IN) +#define IS_THOP_OUT(pti) ((*((pti)->pThop) & THOP_OUT) == THOP_OUT) + +// Max size of preallocated strings +#define CBSTRINGPREALLOC 512 +#define CWCSTRINGPREALLOC (CBSTRINGPREALLOC/sizeof(WCHAR)) + +// BUGBUG - Max size? +#define CCHMAXSTRING 0x1000 + +// Max size of preallocated palettes +#define NPALETTEPREALLOC 256 + +// Size of a LOGPALETTE structure with N entries +#define CBPALETTE(n) (sizeof(LOGPALETTE)+((n)-1)*sizeof(PALETTEENTRY)) + +// Hide the exact field in the RPCOLEMESSAGE we use to store thunking data +#define ROM_THUNK_FIELD(rom) ((rom)->reserved1) + +#endif // #ifndef __THOP_HXX__ diff --git a/private/ole32/olethunk/olethk32/thop16.cxx b/private/ole32/olethunk/olethk32/thop16.cxx new file mode 100644 index 000000000..32d0ec207 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thop16.cxx @@ -0,0 +1,4114 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thop16.cxx +// +// Contents: Thop implementations for 16->32 +// +// History: 22-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +#include <ole2.h> +#include <valid.h> +#include <string.h> + +#include "struct16.hxx" + +//+--------------------------------------------------------------------------- +// +// Function: EXECUTE_THOP1632, public +// +// Synopsis: Debugging version of thop dispatch routine +// +// Arguments: [pti] - Thunking info +// +// Returns: Appropriate status +// +// History: 24-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +DWORD EXECUTE_THOP1632(THUNKINFO *pti) +{ + thkDebugOut((DEB_THOPS, "ExThop1632: %s (0x%02X), s16 %p, s32 %p\n", + ThopName(*pti->pThop), *pti->pThop, pti->s16.pbCurrent, + pti->s32.pbCurrent)); + thkAssert((*pti->pThop & THOP_OPMASK) < THOP_LASTOP); + return (*aThopFunctions1632[*((pti)->pThop) & THOP_OPMASK])(pti); +} +#endif + +#if DBG == 1 +DWORD EXECUTE_ENUMTHOP1632(THUNKINFO *pti) +{ + thkDebugOut((DEB_THOPS, "ExEnumThop1632: %s (0x%02X), s16 %p, s32 %p\n", + EnumThopName(*pti->pThop), *pti->pThop, pti->s16.pbCurrent, + pti->s32.pbCurrent)); + return (*aThopEnumFunctions1632[*(pti)->pThop])(pti); +} +#endif + +// Generated by the tool, in tc1632.cxx +DWORD ThunkCall1632( THUNKINFO * ); + +//+--------------------------------------------------------------------------- +// +// Function: FixedThopHandler, public +// +// Synopsis: Generic function which handles the high-level details +// of thop execution for thops that operate on known-size +// data +// +// Arguments: [pti] - Thunking state information +// [thop] - Thop being executed +// [cb16] - 16-bit size +// [pfn1632] - 16->32 conversion routine +// [cb32] - 32-bit size +// [pfn3216] - 32->16 conversion routine +// +// Returns: Appropriate status code +// +// History: 05-Apr-94 DrewB Created +// +// Notes: Automatically increments pThop +// +//---------------------------------------------------------------------------- + +DWORD FixedThopHandler1632(THUNKINFO *pti, + THOP thop, + UINT cb16, + FIXEDHANDLERROUTINE pfn1632, + UINT cb32, + FIXEDHANDLERROUTINE pfn3216) +{ + DWORD dwResult; + VPVOID vp16; + BYTE *pb16; + BYTE *pb32; + + if ((thop & (THOP_IN | THOP_OUT)) != 0) + { + pb32 = NULL; + + GET_STACK16(pti, vp16, VPVOID); + if ( vp16 != 0 ) + { + pb16 = (BYTE *)ValidatePtr16(pti, vp16, cb16, thop); + if (pb16 != NULL) + { + pb32 = (BYTE *)STACKALLOC32(cb32); + if (pb32 == NULL) + { + pti->scResult = E_OUTOFMEMORY; + } + else if ((thop & THOP_IN) != 0) + { + (pfn1632)(pb16, pb32, cb16, cb32); + } + + WOWRELVDMPTR(vp16); + } + } + + TO_STACK32(pti, pb32, BYTE *); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if ((thop & THOP_OUT) != 0 && vp16 != 0) + { + pb16 = (BYTE *)WOWFIXVDMPTR(vp16, cb16); + + if (SUCCEEDED(dwResult)) + { + (pfn3216)(pb32, pb16, cb32, cb16); + } + else if ((thop & THOP_IN) == 0) + { + // Zero out-only parameters on failure + memset(pb16, 0, cb16); + } + + WOWRELVDMPTR(vp16); + } + + if (pb32 != NULL) + { + STACKFREE32(pb32, cb32); + } + } + else + { + (pfn1632)(PTR_STACK16(&pti->s16, cb16), PTR_STACK32(&pti->s32), + cb16, cb32); + SKIP_STACK16(&pti->s16, cb16); + SKIP_STACK32(&pti->s32, cb32); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + } + + return dwResult; +} + +//----------------------------------------------------------------------------- +// +// Handler-based thunks +// +// These thunks use the fixed-size generic thop handler to do their work +// +//----------------------------------------------------------------------------- + +// Handle straight copy +DWORD Thop_Copy_1632(THUNKINFO *pti) +{ + THOP thopSize; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_COPY); + + thopSize = *++pti->pThop; + return FixedThopHandler1632(pti, + *(pti->pThop-1), + thopSize, FhCopyMemory, + thopSize, FhCopyMemory); +} + +DWORD Thop_ShortToLong_1632(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SHORTLONG); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(SHORT), FhShortToLong, + sizeof(LONG), FhLongToShort); +} + +DWORD Thop_WordToDword_1632(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_WORDDWORD); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(WORD), FhWordToDword, + sizeof(DWORD), FhDwordToWord); +} + +DWORD Thop_GdiHandle_1632(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HGDI); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(HAND16), FhGdiHandle1632, + sizeof(HANDLE), FhGdiHandle3216); +} + +DWORD Thop_UserHandle_1632(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HUSER); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(HAND16), FhUserHandle1632, + sizeof(HANDLE), FhUserHandle3216); +} + +DWORD Thop_HACCEL_1632(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HACCEL); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(HAND16), FhHaccel1632, + sizeof(HANDLE), FhHaccel3216); +} + +DWORD Thop_HTASK_1632(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HTASK); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(HAND16), FhHtask1632, + sizeof(HANDLE), FhHtask3216); +} + +DWORD Thop_HRESULT_1632( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HRESULT); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(HRESULT), FhHresult1632, + sizeof(HRESULT), FhHresult3216); +} + +DWORD Thop_NULL_1632(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_NULL); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(void *), FhNull, + sizeof(void *), FhNull); +} + +DWORD Thop_RECT_1632( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_RECT); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(RECT16), FhRect1632, + sizeof(RECT), FhRect3216); +} + +DWORD Thop_BINDOPTS_1632( THUNKINFO *pti ) +{ + VPVOID vpbo16; + BIND_OPTS UNALIGNED *pbo; + UINT cb; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_BINDOPTS); + + PEEK_STACK16(pti, vpbo16, VPVOID); + pbo = (BIND_OPTS UNALIGNED *)GetReadPtr16(pti, vpbo16, sizeof(BIND_OPTS)); + if (pbo != NULL) + { + cb = pbo->cbStruct; + WOWRELVDMPTR(vpbo16); + } + else + { + // Doesn't really matter, since pti->scResult was set to error + // by GetReadPtr16 + cb = sizeof(BIND_OPTS); + } + + return FixedThopHandler1632(pti, + *pti->pThop, + cb, FhCopyMemory, + cb, FhCopyMemory); +} + +DWORD Thop_SIZE_1632( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SIZE); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(SIZE16), FhSize1632, + sizeof(SIZE), FhSize3216); +} + +DWORD Thop_MSG_1632( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_MSG); + + return FixedThopHandler1632(pti, + *pti->pThop, + sizeof(MSG16), FhMsg1632, + sizeof(MSG), FhMsg3216); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_ERROR_1632, public +// +// Synopsis: Any Thop type which should just fail with an error +// should go be directed here. +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_ERROR_1632 ( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_ERROR); + + thkAssert( FALSE && "Hey we hit an ERROR Thop in 16->32" ); + + return (DWORD)E_UNEXPECTED; +} + +//+--------------------------------------------------------------------------- +// +// Function: ThunkInString1632, public +// +// Synopsis: Converts an in-parameter string +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 24-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD ThunkInString1632(THUNKINFO *pti) +{ + DWORD dwResult; + VPSTR vpstr; + LPOLESTR lpstrDest; + OLECHAR *ptcStackText; + + dwResult = (DWORD)S_OK; + ptcStackText = NULL; + + GET_STACK16(pti, vpstr, VPSTR); + + if (vpstr == 0) + { + lpstrDest = NULL; + } + else + { + ptcStackText = (OLECHAR *)STACKALLOC32(CWCSTRINGPREALLOC* + sizeof(OLECHAR)); + if (ptcStackText == NULL) + { + pti->scResult = E_OUTOFMEMORY; + } + else + { + lpstrDest = Convert_VPSTR_to_LPOLESTR( pti, vpstr, ptcStackText, + CWCSTRINGPREALLOC ); + } + } + + thkDebugOut((DEB_ARGS, "In1632 LPSTR: %p -> %p '%ws'\n", + vpstr, lpstrDest, lpstrDest)); + + TO_STACK32(pti, lpstrDest, LPOLESTR ); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if (lpstrDest != NULL) + { + Convert_VPSTR_to_LPOLESTR_free( ptcStackText, lpstrDest ); + } + + if (ptcStackText != NULL) + { + STACKFREE32(ptcStackText, CWCSTRINGPREALLOC*sizeof(OLECHAR)); + } + + return( dwResult ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_LPSTR_1632, public +// +// Synopsis: Converts 16-bit LPSTR to 32-bit LPSTR pointer +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_LPSTR_1632( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_LPSTR); + // + // We have only input LPSTRs + // + thkAssert( (*pti->pThop & THOP_IOMASK) == THOP_IN && + "LPSTR must be input only!" ); + + return ThunkInString1632(pti); +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertTaskString3216, public +// +// Synopsis: Converts a task-memory string +// +// Arguments: [pti] - Thunk info +// [pos32] - String +// [vpstrPreAlloc] - Preallocated string or NULL +// [cchPreAlloc] - Preallocated size or zero +// [pvpstr16] - String +// +// Returns: Appropriate status code +// +// Modifies: [pti] +// [pvpstr16] +// +// History: 14-May-94 DrewB Created +// +// Notes: Frees preallocation if successful and: +// Name is too large or +// Name is NULL +// +// Always frees source string if non-zero and valid +// +//---------------------------------------------------------------------------- + +SCODE ConvertTaskString3216(THUNKINFO *pti, + LPOLESTR pos32, + VPSTR vpstrPreAlloc, + UINT cchPreAlloc, + VPSTR UNALIGNED *pvpstr16) +{ + VPVOID vpstr16; + UINT cch; + SCODE sc; + + sc = S_OK; + + if (pos32 == NULL) + { + vpstr16 = 0; + } + else + { + if (IsBadStringPtrW(pos32, CCHMAXSTRING)) + { + sc = E_INVALIDARG; + } + else + { + cch = lstrlenW(pos32)+1; + + if (cch > cchPreAlloc) + { + // Our prealloc buffer is too small, so try and get a + // new one + + // Allow for each Unicode character to take two + // bytes in case of multibyte expansion + vpstr16 = (VPSTR)TaskMalloc16( cch*2 ); + if (vpstr16 == 0) + { + sc = E_OUTOFMEMORY; + } + } + else + { + vpstr16 = vpstrPreAlloc; + } + + if (SUCCEEDED(sc)) + { + sc = Convert_LPOLESTR_to_VPSTR(pos32, vpstr16, cch, cch*2); + if (FAILED(sc) && vpstr16 != vpstrPreAlloc) + { + TaskFree16(vpstr16); + } + } + + TaskFree32(pos32); + } + } + + if (SUCCEEDED(sc)) + { + // If there was a preallocated string we didn't use, + // free it + if (vpstrPreAlloc != 0 && vpstrPreAlloc != vpstr16) + { + TaskFree16(vpstrPreAlloc); + } + + *pvpstr16 = vpstr16; + } + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: ThunkOutString1632, public +// +// Synopsis: Converts an out param string or filename +// +// Arguments: [pti] - Thunk state information +// [fFile] - Filename or plain string +// +// Returns: Appropriate status code +// +// History: 24-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD ThunkOutString1632(THUNKINFO *pti, + BOOL fFile) +{ + DWORD dwResult; + VPVOID vpvpstr16; + VPSTR vpstr16; + VPSTR UNALIGNED *lpvpstr16; + LPOLESTR *lplpstr32; + LPOLESTR lpstr; + + GET_STACK16(pti, vpvpstr16, VPSTR); + + lplpstr32 = NULL; + if ( vpvpstr16 != 0 ) + { + lpvpstr16 = (VPSTR UNALIGNED *)GetWritePtr16(pti, vpvpstr16, + sizeof(VPSTR)); + if ( lpvpstr16 != NULL ) + { + WOWRELVDMPTR(vpvpstr16); + + lplpstr32 = &lpstr; + + vpstr16 = (VPSTR)TaskMalloc16(CBSTRINGPREALLOC); + if (vpstr16 == 0) + { + pti->scResult = E_OUTOFMEMORY; + } + } + } + + TO_STACK32(pti, lplpstr32, LPOLESTR FAR *); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if ( lplpstr32 != NULL ) + { + if ( SUCCEEDED(dwResult) ) + { + SCODE sc; + + if (fFile) + { + UINT cch; + + // The string pointed to by lpstr is ours so we + // can do the long->short conversion in place + // without worrying about trashing the memory + // The short path name should always be able + // to fit in the long path name's buffer since + // the file names that we are thunking are always + // absolute paths + + cch = lstrlenW(lpstr)+1; + + // Ignore failures; if we can't convert the name + // then we simply pass on what we were given + GetShortPathName(lpstr, lpstr, cch); + } + + sc = ConvertTaskString3216(pti, lpstr, vpstr16, + CWCSTRINGPREALLOC, &vpstr16); + if (FAILED(sc)) + { + dwResult = sc; + } + } + + if (FAILED(dwResult)) + { + TaskFree16(vpstr16); + vpstr16 = 0; + } + + lpvpstr16 = FIXVDMPTR( vpvpstr16, VPSTR ); + *lpvpstr16 = vpstr16; + +#if DBG==1 + thkDebugOut((DEB_ARGS, "Out1632 LPLPSTR: %p -> %p '%s'\n", + lpstr, vpstr16, + vpstr16 != 0 ? WOWFIXVDMPTR(vpstr16, 0) : "<null>")); + if (vpstr16 != 0) + { + WOWRELVDMPTR(vpstr16); + } +#endif + + RELVDMPTR( vpvpstr16 ); + } + else + { + thkDebugOut((DEB_ARGS, "Out1632 LPLPSTR NULL\n")); + } + + return( dwResult ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_LPLPSTR_1632, public +// +// Synopsis: Converts 32-bit LPSTR to 16-bit LPSTR pointer +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 25-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_LPLPSTR_1632( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_LPLPSTR); + // + // We don't have anything but unmodified LPLPSTRs + // + thkAssert( (*pti->pThop & THOP_IOMASK) == 0 && + "LPLPSTR must be unmodified only!" ); + + return ThunkOutString1632(pti, FALSE); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_BUFFER_1632, public +// +// Synopsis: Converts 16-bit block of memory to 32-bit block of memory +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 25-Feb-94 BobDay Created +// 14-Mar-95 KentCe Buffer copy not required for Win95. +// +// Notes: WARNING! WARNING! WARNING! For an out parameter this expects +// three parameters on the stack in the following format and order: +// VOID * pointer to buffer +// DWORD count of bytes in buffer +// DWORD * count of bytes returned in the buffer +// +//---------------------------------------------------------------------------- + +#define WATCH_VALUE 0xfef1f0 + +DWORD Thop_BUFFER_1632( THUNKINFO *pti ) +{ + DWORD dwResult; + BOOL fThopInput; + BOOL fThopOutput; + VPVOID vp16; + LPVOID lp16; + LPVOID lp32; + DWORD dwCount; + VPVOID vp16CountOut; + DWORD dwCountOut32 = 0; + DWORD * pdwCountOut32 = &dwCountOut32; +#if DBG == 1 + DWORD dwWatch; +#endif + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_BUFFER); + + fThopInput = IS_THOP_IN(pti); + fThopOutput = IS_THOP_OUT(pti); + + // + // We only have in and out BUFFER thops + // + thkAssert((fThopInput || fThopOutput) + && (fThopInput != fThopOutput) + && "BUFFER must be in or out only!" ); + + GET_STACK16(pti, vp16, VPVOID); + GET_STACK16(pti, dwCount, DWORD); + + if (fThopOutput) + { + // Get the pointer to the returned value off the stack + GET_STACK16(pti, vp16CountOut, VPVOID); + } + + lp32 = NULL; + + if (vp16 == 0) + { + // lp32 is already NULL + } + else if (dwCount == 0) + { + // If the count is zero then we can pass any valid 32-bit + // pointer + +#if DBG == 1 + // In debug, make sure that no data is written back to the + // memory we pass on + dwWatch = WATCH_VALUE; + lp32 = &dwWatch; +#else + lp32 = &dwResult; +#endif + } + else + { + // + // Under Win95 we can lock down 16-bit memory so a duplicate + // buffer is not required. + // +#if defined(_CHICAGO_) + lp32 = WOWFIXVDMPTR(vp16, dwCount); +#else + lp16 = ValidatePtr16(pti, vp16, dwCount, *pti->pThop); + + if ( lp16 != NULL ) + { + lp32 = (LPVOID)CoTaskMemAlloc( dwCount ); + if ( lp32 == NULL ) + { + pti->scResult = E_OUTOFMEMORY; + } + else + { + if ( fThopInput ) + { + memcpy( lp32, lp16, dwCount ); + } + } + + WOWRELVDMPTR(vp16); + } +#endif + } + + thkDebugOut((DEB_ARGS, "1632 BUFFER: %p -> %p, %u\n", + vp16, lp32, dwCount)); + + TO_STACK32(pti, lp32, LPVOID ); + TO_STACK32(pti, dwCount, DWORD ); + + if (fThopOutput) + { + TO_STACK32(pti, pdwCountOut32, LPVOID ); + } + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if (fThopOutput) + { + // If the pointer in sixteen bit land is non-null then return the + // count of bytes written to the buffer. + DWORD UNALIGNED *lpdw16 = (DWORD UNALIGNED *) + ValidatePtr16(pti, vp16CountOut, sizeof(DWORD), *pti->pThop); + + if (lpdw16 != NULL) + { + *lpdw16 = dwCountOut32; + WOWRELVDMPTR(vp16CountOut); + } + +#if !defined(_CHICAGO_) + // + // Under Win95 we can lock down 16-bit memory so a duplicate + // buffer is not required. + // + if ( SUCCEEDED(dwResult) ) + { + if (dwCountOut32 > 0 && vp16 != 0) + { + lp16 = (LPVOID)WOWFIXVDMPTR( vp16, dwCountOut32 ); + + memcpy( lp16, lp32, dwCountOut32 ); + + WOWRELVDMPTR(vp16); + } + } +#endif // _CHICAGO_ + } + +#if DBG == 1 + if (lp32 != NULL && dwCount == 0) + { + thkAssert(dwWatch == WATCH_VALUE); + } +#endif + + // + // Under Win95 we can lock down 16-bit memory so a duplicate + // buffer is not required. + // +#if !defined(_CHICAGO_) + // + // Now free the buffer + // + if ( lp32 != NULL && dwCount > 0 ) + { + CoTaskMemFree( lp32 ); + } +#endif + + return( dwResult ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_SNB_1632, public +// +// Synopsis: Converts 16-bit SNB to 32-bit SNB pointer +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_SNB_1632( THUNKINFO *pti ) +{ + DWORD dwResult; + BOOL fThopInput; + BOOL fThopOutput; + VPVOID snb16; + VPSTR *lpvpstr; + VPSTR UNALIGNED *lpvpstrTemp; + VPSTR vpstr; + SNB snb32; + UINT cStr; + UINT cStrTemp; + LPOLESTR *lplpstr; + UINT cbStrings; + OLECHAR *pocStr; + LPSTR lpstr16; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SNB); + + fThopInput = IS_THOP_IN(pti); + fThopOutput = IS_THOP_OUT(pti); + + // + // We don't have anything but unmodified SNBs + // + thkAssert( !fThopInput && !fThopOutput && "SNB must be unmodified only!" ); + + GET_STACK16(pti, snb16, VPVOID); + + snb32 = NULL; + if ( snb16 != 0 ) + { + // + // Count the strings in the 16-bit snb + // + lpvpstr = (VPSTR FAR *)GetReadPtr16( pti, snb16, sizeof(VPSTR) ); + if ( lpvpstr != 0 ) + { + lpvpstrTemp = lpvpstr; + cStr = 0; + cbStrings = 0; + do + { + cStr++; + vpstr = *lpvpstrTemp++; + + if ( vpstr == 0 ) + { + break; + } + + lpstr16 = GetStringPtr16(pti, vpstr, CCHMAXSTRING, + &cStrTemp); + if ( lpstr16 == 0 ) + { + WOWRELVDMPTR(snb16); + lpvpstr = NULL; + break; // Leave with snb32 still NULL + } + + WOWRELVDMPTR(vpstr); + + cbStrings += cStrTemp; + } + while ( TRUE ); + } + + if ( lpvpstr != NULL ) + { + thkDebugOut((DEB_ARGS, "In1632 SNB: %d strings\n", cStr)); + + // + // Allocate space for the 32-bit snb + // + snb32 = (LPOLESTR FAR *)CoTaskMemAlloc( cStr*sizeof(LPOLESTR) + + cbStrings*sizeof(WCHAR)); + if (snb32 == NULL) + { + pti->scResult = E_OUTOFMEMORY; + } + else + { + pocStr = (OLECHAR *)((BYTE *)snb32+cStr*sizeof(LPOLESTR)); + + // + // Now convert the strings + // + lpvpstrTemp = lpvpstr; + lplpstr = snb32; + cStrTemp = cStr - 1; + + while ( cStrTemp > 0 ) + { + --cStrTemp; + + vpstr = *lpvpstrTemp++; + + thkAssert( vpstr != 0 && + "Loop is processing end of snb\n" ); + + // Guaranteed to use pocStr as storage since cbStrings is + // large enough to contain all the strings + *lplpstr = Convert_VPSTR_to_LPOLESTR( pti, vpstr, + pocStr, cbStrings ); + + if (*lplpstr == NULL) + { + CoTaskMemFree(snb32); + snb32 = NULL; + break; + } + +#if DBG == 1 + thkDebugOut((DEB_ARGS, "In1632 SNB: %p '%s' -> " + "%p '%ws'\n", + vpstr, WOWFIXVDMPTR(vpstr, 0), + *lplpstr, *lplpstr)); + WOWRELVDMPTR(vpstr); +#endif + + pocStr += lstrlenW(pocStr)+1; + lplpstr++; + } + + // Terminate SNB + *lplpstr = NULL; + + thkAssert(*lpvpstrTemp == 0); + + WOWRELVDMPTR(snb16); + } + } + } + + thkDebugOut((DEB_ARGS, "In1632 SNB: %p -> %p\n", snb16, snb32)); + + TO_STACK32(pti, snb32, SNB ); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + // + // Free SNB memory if necessary + // + if ( snb32 != 0 ) + { + CoTaskMemFree(snb32); + } + + return( dwResult ); +} + +//+--------------------------------------------------------------------------- +// +// Function: ThunkInterface1632, private +// +// Synopsis: Handles interface thunking for THOP_IFACE and +// THOP_IFACEGEN +// +// Arguments: [pti] - Thunking state information +// [iidx] - Interface index or IID +// [thop] - Thop being executed +// [punkOuter] - Controlling IUnknown or NULL +// +// Returns: Appropriate status code +// +// History: 01-Mar-94 DrewB Created +// +// Notes: Assumes caller has already adjusted pti->pThop +// +//---------------------------------------------------------------------------- + +DWORD ThunkInterface1632(THUNKINFO *pti, + IIDIDX iidx, + THOP thop, + IUnknown *punkOuter) +{ + VPVOID vpv; + DWORD dwResult; + IUnknown *punkThis32In; + IUnknown *punkThis32Out; + VPVOID vpvThis16; + VPVOID vpvIn; + VPVOID UNALIGNED *pvpvOut; + VPVOID vpPreAlloc = NULL; + THUNK1632OBJ UNALIGNED *pto; + + punkThis32In = NULL; + + // Retrieve in or out interface pointer + GET_STACK16(pti, vpv, VPVOID); + + // Out takes precedence over in for determining indirection depth + + if ((thop & THOP_OUT) != 0 && vpv != 0) + { + pvpvOut = (VPVOID UNALIGNED *)GetWritePtr16(pti, vpv, sizeof(VPVOID)); + if (pvpvOut != NULL) + { + vpvIn = *pvpvOut; + WOWRELVDMPTR(vpv); + } + else + { + thkDebugOut((DEB_WARN, "WARNING: ThunkInterface1632 - bad " + "pointer %p\n", vpv)); + } + } + else + { + vpvIn = vpv; + } + + if ((thop & THOP_IN) != 0 && SUCCEEDED(pti->scResult)) + { + if (vpvIn == 0) + { + punkThis32In = NULL; + } + else + { + if ( !IsValidInterface16(pti, vpvIn) ) + { + thkDebugOut((DEB_WARN, "WARNING: ThunkInterface1632 - invalid " + "interface %p\n", vpvIn)); + } + else + { + thkAssert(IIDIDX_IS_IID(iidx) || + (IIDIDX_INDEX(iidx) >= 0 && + IIDIDX_INDEX(iidx) < THI_COUNT)); + + punkThis32In = pti->pThkMgr->FindProxy3216(NULL, vpvIn, iidx, + NULL); + + if (punkThis32In == NULL) + { + pti->scResult = E_OUTOFMEMORY; + thkDebugOut((DEB_WARN, "WARNING: ThunkInterface1632 - " + "Can't create proxy for %p\n", vpvIn)); + } + } + } + + thkDebugOut((DEB_ARGS, "In1632 %s %p -> %p\n", + IidIdxString(iidx), vpvIn, punkThis32In)); + } + + if ((thop & THOP_OUT) != 0 && vpv != 0 && SUCCEEDED(pti->scResult)) + { + thkAssert(IIDIDX_IS_IID(iidx) || + (IIDIDX_INDEX(iidx) >= 0 && + IIDIDX_INDEX(iidx) < THI_COUNT)); + + // Preallocate a proxy for the out parameter + if ((vpPreAlloc = pti->pThkMgr->CanGetNewProxy1632(iidx))== NULL) + { + pti->scResult = E_OUTOFMEMORY; + thkDebugOut((DEB_WARN, "WARNING: ThunkInterface1632 - " + "Cannot preallocate %s proxy\n", IidIdxString(iidx))); + } + + punkThis32Out = punkThis32In; + TO_STACK32(pti, &punkThis32Out, IUnknown **); + + // Set the temporary proxy's this pointer to point to the place + // to fetch the real this pointer from + pto = FIXVDMPTR(vpPreAlloc, THUNK1632OBJ); + pto->punkThis32 = (IUnknown *)&punkThis32Out; + RELVDMPTR(vpPreAlloc); + + // Set the out pointer to the temporary proxy so that there's + // an object available to all back through even before the + // current call has completed + // Certain apps (Corel Draw 5.0 is one) point out pointers to + // objects which are used inside of calls which fill out the + // out pointer and they require that the out pointer be filled + // in to operate correctly + // This will get NULLed out in failure cases + *FIXVDMPTR(vpv, VPVOID) = vpPreAlloc; + RELVDMPTR(vpv); + } + else + { + TO_STACK32(pti, punkThis32In, IUnknown *); + } + + // Assume that our caller has already adjusted pThop + dwResult = EXECUTE_THOP1632(pti); + + if ( ((thop & THOP_OPMASK) == THOP_IFACENOADDREF) + && (punkThis32In != NULL) + && ((thop & THOP_IN) != 0) + && (vpv != 0) + && (SUCCEEDED((SCODE)dwResult)) + && (punkOuter != NULL) + ) + { + // NOTE: the 3216 bit pointer did not get addref'd by the users + // but should remain until the outer object goes away + // Steps: + // - Local addref the 3216 proxy + // - aggregate it with punkOuter + + THUNK3216OBJ *pto = pti->pThkMgr->LookupProxy3216(vpvIn); + + if (pto) + pto->cRefLocal++; + vpvThis16 = + pti->pThkMgr->FindAggregate1632(NULL, punkOuter, + punkThis32In, iidx); + } + else if (punkThis32In != NULL) + { + // The rules for [in,out] require that we NOT release here. + // Passing an Interface [in,out] has already given the reference away. + if( (thop & THOP_INOUT) != THOP_INOUT ) + { + // Note that if the routine called keeps the proxy around + // it should AddRef it so this won't really remove the object + pti->pThkMgr->FreeProxy3216(vpvIn); + } + } + + if ((thop & THOP_OUT) != 0 && vpv != 0) + { + vpvThis16 = 0; + + if (SUCCEEDED((SCODE)dwResult) && punkThis32Out != NULL) + { + // Get a 16-bit proxy object for the 32-bit object + + if (punkOuter != NULL) + { + vpvThis16 = + pti->pThkMgr->FindAggregate1632(vpPreAlloc, punkOuter, + punkThis32Out, iidx); + } + else + { + vpvThis16 = pti->pThkMgr->FindProxy1632(vpPreAlloc, + punkThis32Out, iidx, + NULL); + } + } + else if (vpPreAlloc != NULL) + { + // Return our preallocated proxy because we don't need it + pti->pThkMgr->FreeNewProxy1632(vpPreAlloc, iidx); + } + + // Set the out param + // Get the VDM pointer again since we may have done nested + // transitions since we last got it + pvpvOut = FIXVDMPTR(vpv, VPVOID); + *pvpvOut = vpvThis16; + RELVDMPTR(vpv); + + thkDebugOut((DEB_ARGS, "Out1632 %s %p -> %p\n", + IidIdxString(iidx), punkThis32Out, vpvThis16)); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_IFACEGEN_1632, public +// +// Synopsis: Thunks interfaces out through ppvs from 16->32 +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_IFACEGEN_1632(THUNKINFO *pti) +{ + IIDIDX iidx; + THOP thop, thopOp, thopWeakOffset; + VPVOID vpvIid; + IUnknown *punkOuter; + IID UNALIGNED const *piid; + + thop = *pti->pThop++; + thopOp = thop & THOP_OPMASK; + + thkAssert(thopOp == THOP_IFACEGEN || + thopOp == THOP_IFACEGENOWNER); + + // The current thop byte indicates how many bytes to look + // back in the stack to find the IID which identifies the + // interface being returned + INDEX_STACK16(pti, vpvIid, VPVOID, *pti->pThop, sizeof(VPVOID)); + pti->pThop++; + + piid = (IID const *)GetReadPtr16(pti, vpvIid, sizeof(IID const)); + if (piid == NULL) + { + pti->scResult = E_INVALIDARG; + } + else + { +#if DBG == 1 + if (!IsValidIid(*piid)) + { + pti->scResult = E_INVALIDARG; + } + else +#endif + { + iidx = IidToIidIdx(*piid); + } + + WOWRELVDMPTR(vpvIid); + } + + punkOuter = NULL; + if (thopOp == THOP_IFACEGENOWNER) + { + // For cases where the controlling unknown is known, + // index back on the stack and find the 32-bit unknown + // pointer to use + thopWeakOffset = *pti->pThop++; + INDEX_STACK32(pti, punkOuter, IUnknown *, thopWeakOffset); + } + + return ThunkInterface1632(pti, iidx, thop, punkOuter); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_OIFI_1632, public +// +// Synopsis: Convert OLEINPLACEFRAMEINFO +// +// Arguments: [pti] - Thunking state information +// +// Returns: Appropriate status code +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_OIFI_1632( THUNKINFO *pti ) +{ + DWORD dwResult; + VPVOID vpoifi16; + OIFI16 UNALIGNED *poifi16; + OLEINPLACEFRAMEINFO oifi32; + OLEINPLACEFRAMEINFO *poifi32; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_OIFI); + thkAssert((*pti->pThop & THOP_IOMASK) == THOP_OUT); + + // OIFIs are out-only parameters for their contents + // However, cb is in/out, so we need to copy cb on the way in + // Furthermore, cb may not be set to a valid value, in which + // case the documentation mentions that it should be assumed + // that this is an OLE 2.0 OIFI + // This thop simply ignores cb on the way in and always sets + // it to the OLE 2.0 size + // Since we're out-only, this always works since the number of + // fields we thunk is the size of the structure that we give out + // If OLEINPLACEFRAMEINFO is extended, this thop will break + + // Assert that OLEINPLACEFRAMEINFO is what we expect it to be + thkAssert(sizeof(OLEINPLACEFRAMEINFO) == 20); + + GET_STACK16(pti, vpoifi16, VPVOID); + + poifi32 = NULL; + if (vpoifi16 != 0) + { + poifi16 = (OIFI16 UNALIGNED *) GetWritePtr16(pti, vpoifi16, sizeof(OIFI16)); + if (NULL != poifi16) + { + poifi32 = &oifi32; + + // OIFI's may be an out only parameters but if the "cb" field is + // "in" RPC doesn't slice up structs, so the whole thing is "in" + // as well. We are Thoping here but if we want this to match + // the RPC sematics then we need to copy all the fields. + + poifi32 = &oifi32; + poifi32->cb = sizeof(OLEINPLACEFRAMEINFO); + poifi32->fMDIApp = (BOOL)poifi16->fMDIApp; + poifi32->hwndFrame = HWND_32(poifi16->hwndFrame); + poifi32->cAccelEntries = (UINT)poifi16->cAccelEntries; + + if (poifi16->haccel == NULL) + { + poifi32->haccel = NULL; + } + else + { + // WOW will clean up any dangling accelerator tables when + // tasks die + poifi32->haccel = HACCEL_32(poifi16->haccel); + if (poifi32->haccel == NULL) + { + dwResult = (DWORD)E_UNEXPECTED; + } + } + + WOWRELVDMPTR(vpoifi16); + } + } + + TO_STACK32(pti, poifi32, OLEINPLACEFRAMEINFO *); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if (poifi32 != NULL) + { + poifi16 = FIXVDMPTR(vpoifi16, OIFI16); + + if (SUCCEEDED(dwResult)) + { + poifi16->cb = sizeof(OIFI16); + poifi16->fMDIApp = (WORD)poifi32->fMDIApp; + poifi16->hwndFrame = HWND_16(poifi32->hwndFrame); + poifi16->cAccelEntries = + ClampULongToUShort(poifi32->cAccelEntries); + + if (poifi32->haccel == NULL) + { + poifi16->haccel = NULL; + } + else + { + // WOW will clean up any dangling accelerator tables when + // tasks die + poifi16->haccel = HACCEL_16(poifi32->haccel); + if (poifi16->haccel == NULL) + { + dwResult = (DWORD)E_UNEXPECTED; + } + } + +#if DBG == 1 + if (SUCCEEDED(dwResult)) + { + thkDebugOut((DEB_ARGS, "Out1632 OIFI: " + "%p {%d, %d, 0x%p, 0x%p, %d} -> " + "%p {%d, %d, 0x%04X, 0x%04X, %d}\n", + poifi32, poifi32->cb, poifi32->fMDIApp, + poifi32->hwndFrame, poifi32->haccel, + poifi32->cAccelEntries, + vpoifi16, poifi16->cb, (BOOL)poifi16->fMDIApp, + (DWORD)poifi16->hwndFrame, (DWORD)poifi16->haccel, + poifi16->cAccelEntries)); + } +#endif + } + + if (FAILED(dwResult)) + { + memset(poifi16, 0, sizeof(OIFI16)); + } + + RELVDMPTR(vpoifi16); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_STGMEDIUM_1632, public +// +// Synopsis: Converts 32-bit STGMEDIUM to 16-bit STGMEDIUM returned +// structure +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_STGMEDIUM_1632( THUNKINFO *pti ) +{ + DWORD dwResult; + BOOL fThopInput; + BOOL fThopOutput; + VPVOID vpstgmedium16; + STGMEDIUM UNALIGNED *lpstgmedium16; + STGMEDIUM *lpstgmedium32; + STGMEDIUM stgmedium32; + DWORD dwSize; + SCODE sc; + BOOL fReleaseParam; + SHORT fTransferOwnership; + FORMATETC *pfe; + THOP thopFeOffset; + BOOL fReversedTYMED_NULL = FALSE; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_STGMEDIUM); + + fThopInput = IS_THOP_IN(pti); + fThopOutput = IS_THOP_OUT(pti); + + // + // We currently don't have any unmodified or inout thops for STGMEDIUMs + // + thkAssert( (fThopInput || fThopOutput) && + (fThopInput != fThopOutput) && + "STGMEDIUM must be input or output only" ); + + // +2 thop byte indicates whether there's a FORMATETC to look at + // or not + // We need to reference this now before the stack is modified + // by argument recovery + thopFeOffset = *(pti->pThop+2); + if (thopFeOffset > 0) + { + INDEX_STACK32(pti, pfe, FORMATETC *, thopFeOffset); + } + else + { + pfe = NULL; + } + + GET_STACK16(pti, vpstgmedium16, VPVOID); + + // Next thop byte indicates whether there's an ownership transfer + // argument or not + pti->pThop++; + fReleaseParam = (BOOL)*pti->pThop++; + + if (fReleaseParam) + { + GET_STACK16(pti, fTransferOwnership, SHORT); + } + else + { + fTransferOwnership = FALSE; + } + + // Skip FORMATETC offset thop + pti->pThop++; + + lpstgmedium32 = NULL; + + if ( vpstgmedium16 != 0 ) + { + if ( fThopInput ) + { + // This code supports GetDataHere() passing TYMED_NULL. It then + // behaves like GetData(). This is not per the OLE spec. + // According to every OLE spec TYMED_NULL is an invalid type in + // GetDataHere(). But AlexGo says that 16bit inproc servers + // did support this, especially the Default Handler / Clipboard. + + lpstgmedium16 = (STGMEDIUM FAR *)GetReadPtr16(pti, vpstgmedium16, + sizeof(STGMEDIUM)); + + if (lpstgmedium16->tymed == TYMED_NULL && + !fTransferOwnership) + { + WOWRELVDMPTR(vpstgmedium16); + + memset(&stgmedium32, 0, sizeof(stgmedium32)); + thkAssert( TYMED_NULL == 0 ); // Don't need to set tymed to 0 + + fThopInput = FALSE; + fThopOutput = TRUE; + fReversedTYMED_NULL = TRUE; + } + else + { + WOWRELVDMPTR(vpstgmedium16); + + sc = ConvertStgMed1632(pti, vpstgmedium16, &stgmedium32, + pfe, fTransferOwnership, &dwSize); + if (SUCCEEDED(sc)) + { + lpstgmedium32 = &stgmedium32; + } + } + } + + if ( fThopOutput ) + { + thkAssert( fThopOutput ); + + lpstgmedium16 = (STGMEDIUM FAR *)GetWritePtr16(pti, vpstgmedium16, + sizeof(STGMEDIUM)); + if ( lpstgmedium16 != NULL ) + { + lpstgmedium32 = &stgmedium32; + WOWRELVDMPTR(vpstgmedium16); + } + + // BUGBUG - 32->16 sets tymed to TYMED_NULL before passing + // on the STGMEDIUM because some apps incorrectly check for this + // I'm assuming this isn't necessary for 16->32 because 32-bit + // apps can't rely on tymed being NULL since nothing in the 32-bit + // code sets it that way for out parameters + // DrewB 5/30 + } + } + + TO_STACK32(pti, lpstgmedium32, STGMEDIUM FAR *); + + if (fReleaseParam) + { + TO_STACK32(pti, (BOOL)fTransferOwnership, BOOL); + } + + dwResult = EXECUTE_THOP1632(pti); + + if ( lpstgmedium32 != NULL) + { + if ( fThopInput ) + { + if (!fTransferOwnership || FAILED(dwResult)) + { + sc = CleanStgMed32(pti, lpstgmedium32, vpstgmedium16, + dwSize, TRUE, pfe); + if (FAILED(sc)) + { + dwResult = (DWORD)sc; + } + } + else if (SUCCEEDED(dwResult)) + { + lpstgmedium16 = FIXVDMPTR(vpstgmedium16, STGMEDIUM); + if (lpstgmedium16->pUnkForRelease == NULL) + { + RELVDMPTR(vpstgmedium16); + sc = CleanStgMed16(pti, vpstgmedium16, lpstgmedium32, + 0, FALSE, pfe); + thkAssert(SUCCEEDED(sc)); + } + else + { + RELVDMPTR(vpstgmedium16); + } + } + } + else + { + thkAssert( fThopOutput ); + + if (SUCCEEDED(dwResult)) + { + sc = ConvertStgMed3216(pti, lpstgmedium32, vpstgmedium16, + pfe, FALSE, &dwSize); + if (FAILED(sc)) + { + dwResult = (DWORD)sc; + ReleaseStgMedium(lpstgmedium32); + } + else if (lpstgmedium32->pUnkForRelease == NULL) + { + sc = CleanStgMed32(pti, lpstgmedium32, vpstgmedium16, + dwSize, FALSE, pfe); + thkAssert(SUCCEEDED(sc)); + } + } + + // Clear the [out] parameters if the call failed. + // Unless it had previously been an [in] parameter. + // We don't want to erase the caller's [in] argument. + + if (FAILED(dwResult) && !fReversedTYMED_NULL) + { + lpstgmedium16 = FIXVDMPTR(vpstgmedium16, STGMEDIUM); + memset(lpstgmedium16, 0, sizeof(STGMEDIUM)); + RELVDMPTR(vpstgmedium16); + } + } + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertStatStg3216, public +// +// Synopsis: Converts a STATSTG +// +// Arguments: [pti] - Thunk info +// [pss32] - STATSTG +// [vpss16] - STATSTG +// [vpstrPreAlloc] - Preallocated string memory or NULL +// [cchPreAlloc] - Amount preallocated +// +// Returns: Appropriate status code +// +// Modifies: [vpss16] +// +// History: 14-May-94 DrewB Created +// +// Notes: Assumes input STATSTG memory is valid +// Assumes task memory for the string +// +//---------------------------------------------------------------------------- + +SCODE ConvertStatStg3216(THUNKINFO *pti, + STATSTG *pss32, + VPVOID vpss16, + VPSTR vpstrPreAlloc, + UINT cchPreAlloc) +{ + STATSTG UNALIGNED *pss16; + SCODE sc; + VPSTR vpstr16; + + sc = ConvertTaskString3216(pti, pss32->pwcsName, + vpstrPreAlloc, cchPreAlloc, + &vpstr16); + if (SUCCEEDED(sc)) + { + pss16 = FIXVDMPTR(vpss16, STATSTG); + memcpy(pss16, pss32, sizeof(STATSTG)); + pss16->pwcsName = (LPOLESTR)vpstr16; + RELVDMPTR(vpss16); + } + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_STATSTG_1632, public +// +// Synopsis: Converts 32-bit STATSTG to 16-bit STATSTG returned structure +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_STATSTG_1632( THUNKINFO *pti ) +{ + DWORD dwResult; + VPVOID vpstatstg16; + STATSTG UNALIGNED *lpstatstg16; + VPSTR vpstr; + STATSTG statstg32; + STATSTG *lpstatstg32; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_STATSTG); + + // + // We currently don't have any input thops for STATSTGs + // + thkAssert( (*pti->pThop & THOP_IOMASK) == THOP_OUT && + "STATSTG must be output only" ); + + GET_STACK16(pti, vpstatstg16, VPVOID); + + lpstatstg32 = NULL; + + lpstatstg16 = (STATSTG FAR *)GetWritePtr16( pti, vpstatstg16, + sizeof(STATSTG) ); + if ( lpstatstg16 != NULL ) + { + statstg32.pwcsName = NULL; + lpstatstg32 = &statstg32; + + vpstr = (VPSTR)TaskMalloc16(CBSTRINGPREALLOC); + if (vpstr == 0) + { + pti->scResult = E_OUTOFMEMORY; + } + + WOWRELVDMPTR(vpstatstg16); + } + + TO_STACK32(pti, lpstatstg32, STATSTG FAR *); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if ( lpstatstg32 != NULL ) + { + if ( SUCCEEDED(dwResult) ) + { + SCODE sc; + + sc = ConvertStatStg3216(pti, &statstg32, vpstatstg16, + vpstr, CWCSTRINGPREALLOC); + if (FAILED(sc)) + { + dwResult = sc; + } + } + + if (FAILED(dwResult)) + { + TaskFree16(vpstr); + + lpstatstg16 = FIXVDMPTR(vpstatstg16, STATSTG); + memset(lpstatstg16, 0, sizeof(STATSTG)); + RELVDMPTR(vpstatstg16); + } + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_DVTARGETDEVICE_1632, public +// +// Synopsis: Converts 16-bit DVTARGETDEVICE to 32-bit DVTARGETDEVICE +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_DVTARGETDEVICE_1632( THUNKINFO *pti ) +{ + DWORD dwResult; + UINT uiSize; + DVTARGETDEVICE *lpdv32; + VPVOID vpdv16; + SCODE sc; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_DVTARGETDEVICE); + + // + // We currently don't have any output thops for DVTARGETDEVICEs + // + thkAssert( (*pti->pThop & THOP_IOMASK) == THOP_IN && + "DVTARGETDEVICE must be input only" ); + + // + // Processing for a DVTARGETDEVICE FAR * as input + // + GET_STACK16(pti, vpdv16, VPVOID); + + lpdv32 = NULL; + + if ( vpdv16 != 0 ) + { + sc = ConvertDvtd1632(pti, vpdv16, ArStack32, FrStack32, &lpdv32, + &uiSize); + if (FAILED(sc)) + { + pti->scResult = sc; + } + } + + TO_STACK32(pti, lpdv32, DVTARGETDEVICE FAR *); + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if (lpdv32 != NULL) + { + FrStack32(lpdv32, uiSize); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_FORMATETC_1632, public +// +// Synopsis: Converts 16-bit FORMATETC to 32-bit FORMATETC and back +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 24-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_FORMATETC_1632( THUNKINFO *pti ) +{ + DWORD dwResult; + BOOL fThopInput; + BOOL fThopOutput; + VPVOID vpformatetc16; + FORMATETC16 UNALIGNED *lpformatetc16; + LPFORMATETC lpformatetc32; + FORMATETC formatetc32; + DVTARGETDEVICE *lpdv32; + SCODE sc; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_FORMATETC); + + fThopInput = IS_THOP_IN(pti); + fThopOutput = IS_THOP_OUT(pti); + + // + // We have only input and output thops, not both, or neither + // + thkAssert( (fThopInput || fThopOutput) && + (fThopInput != fThopOutput) && + "formatetc must be input or output only" ); + + lpdv32 = NULL; + + GET_STACK16(pti, vpformatetc16, VPVOID); + + if ( vpformatetc16 == 0 ) + { + lpformatetc32 = NULL; + } + else + { + lpformatetc32 = &formatetc32; + + if ( fThopInput ) + { + sc = ConvertFetc1632(pti, vpformatetc16, lpformatetc32, FALSE); + if (FAILED(sc)) + { + pti->scResult = sc; + } + } + else + { + thkAssert( fThopOutput ); + // + // The below memset is needed at least for the DATA_S_SAMEFORMATETC + // case. This allows it to be cleaned up because all its pointers + // will be null. + // + memset( &formatetc32, 0, sizeof(formatetc32) ); + lpformatetc16 = (LPFORMATETC16)GetWritePtr16(pti, vpformatetc16, + sizeof(FORMATETC16)); + WOWRELVDMPTR(vpformatetc16); + } + } + + TO_STACK32(pti, lpformatetc32, LPFORMATETC); + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if ( fThopInput ) + { + if (lpformatetc32 != NULL && lpformatetc32->ptd != NULL) + { + TaskFree32(lpformatetc32->ptd); + } + } + + if ( fThopOutput && vpformatetc16 != NULL) + { + if (SUCCEEDED(dwResult)) + { + sc = ConvertFetc3216(pti, lpformatetc32, vpformatetc16, TRUE); + if (FAILED(sc)) + { + dwResult = sc; + } + } + + if (FAILED(dwResult)) + { + lpformatetc16 = FIXVDMPTR(vpformatetc16, FORMATETC16); + memset(lpformatetc16, 0, sizeof(FORMATETC16)); + RELVDMPTR(vpformatetc16); + } + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_LOGPALETTE_1632, public +// +// Synopsis: Converts 16-bit LOGPALLETE to 32-bit LOGPALETTE +// and converts 32-bit LOGPALETTE returned to 16-bit structure +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_LOGPALETTE_1632 ( THUNKINFO *pti ) +{ + DWORD dwResult; + UINT uiSize; + LPLOGPALETTE lplogpal32; + VPVOID vplogpal16; + LOGPALETTE UNALIGNED *lplogpal16; + VPVOID vp16; + LPVOID UNALIGNED *lp16; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_LOGPALETTE); + + // + // It must be either an input or output LOGPALETTE + // + thkAssert( ((*pti->pThop & THOP_IOMASK) == THOP_IN || + (*pti->pThop & THOP_IOMASK) == THOP_OUT) && + "Hey, LOGPALETTE can't be input and output!" ); + + lplogpal32 = NULL; + + if ( (*pti->pThop & THOP_IN) != 0 ) + { + // + // Processing for a LPLOGPALETTE as input + // + GET_STACK16(pti, vplogpal16, VPVOID); + + if ( vplogpal16 != 0 ) + { + // Copy over the input LOGPALETTE structure + lplogpal16 = (LPLOGPALETTE)GetReadPtr16( pti, vplogpal16, + sizeof(LOGPALETTE) ); + + if ( lplogpal16 != NULL ) + { + uiSize = CBPALETTE(lplogpal16->palNumEntries); + + WOWRELVDMPTR(vplogpal16); + + lplogpal16 = (LPLOGPALETTE)GetReadPtr16(pti, vplogpal16, + uiSize); + if ( lplogpal16 != NULL ) + { + lplogpal32 = (LPLOGPALETTE)CoTaskMemAlloc(uiSize); + if ( lplogpal32 == NULL ) + { + pti->scResult = E_OUTOFMEMORY; + } + else + { + memcpy( lplogpal32, lplogpal16, uiSize ); + } + + WOWRELVDMPTR(vplogpal16); + } + } + } + + TO_STACK32(pti, lplogpal32, LPLOGPALETTE); + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if ( lplogpal32 ) + { + CoTaskMemFree( lplogpal32 ); + } + } + else + { + // + // Processing for LPLPLOGPALETTE as output + // + + thkAssert((*pti->pThop & THOP_OUT) != 0); + + GET_STACK16(pti, vp16, VPVOID); + + vplogpal16 = (VPVOID)TaskMalloc16(CBPALETTE(NPALETTEPREALLOC)); + if (vplogpal16 == 0) + { + pti->scResult = E_OUTOFMEMORY; + } + + TO_STACK32(pti, &lplogpal32, LPLOGPALETTE *); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if ( SUCCEEDED(dwResult) && lplogpal32 != NULL ) + { + // + // Copy the returned LOGPALETTE into 16-bit memory + // + uiSize = CBPALETTE(lplogpal32->palNumEntries); + if (uiSize > CBPALETTE(NPALETTEPREALLOC)) + { + TaskFree16(vplogpal16); + vplogpal16 = (VPVOID)TaskMalloc16(uiSize); + if ( vplogpal16 == 0 ) + { + dwResult = (DWORD)E_OUTOFMEMORY; + } + } + + if (vplogpal16 != 0) + { + lplogpal16 = (LPLOGPALETTE)WOWFIXVDMPTR(vplogpal16, uiSize); + if ( lplogpal16 == NULL ) + { + dwResult = (DWORD)E_UNEXPECTED; + vplogpal16 = 0; + } + else + { + memcpy( lplogpal16, lplogpal32, uiSize ); + + WOWRELVDMPTR(vplogpal16); + } + } + + TaskFree32( lplogpal32 ); + } + else + { + TaskFree16(vplogpal16); + vplogpal16 = 0; + } + + // + // Update the value pointed to by the parameter on the 16-bit stack + // + lp16 = FIXVDMPTR(vp16, LPVOID); + if ( lp16 == NULL ) + { + dwResult = (DWORD)E_UNEXPECTED; + } + else + { + *lp16 = (LPVOID)vplogpal16; + RELVDMPTR(vp16); + } + } + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_CRGIID_1632, public +// +// Synopsis: Converts 16-bit CRGIID to 32-bit CRGIID structure +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_CRGIID_1632( THUNKINFO *pti ) +{ + DWORD dwResult; + DWORD dwCount; + VPVOID vpiid16; + IID UNALIGNED *lpiid16; + IID *lpiid32; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_CRGIID); + + // + // We currently don't have any output thops for CRGIIDs + // + thkAssert( (*pti->pThop & THOP_IOMASK) == 0 && + "CRGIID must be unmodified only" ); + + GET_STACK16(pti, dwCount, DWORD); + GET_STACK16(pti, vpiid16, VPVOID); + + lpiid32 = NULL; + + if ( vpiid16 != 0 ) + { + lpiid16 = (IID UNALIGNED *)GetReadPtr16( pti, vpiid16, + dwCount*sizeof(IID) ); + if ( lpiid16 != NULL ) + { + lpiid32 = (IID FAR *)CoTaskMemAlloc( dwCount * sizeof(IID) ); + if ( lpiid32 == NULL ) + { + pti->scResult = E_OUTOFMEMORY; + } + else + { + memcpy( lpiid32, lpiid16, dwCount*sizeof(IID) ); + } + + WOWRELVDMPTR(vpiid16); + } + } + + TO_STACK32(pti, dwCount, DWORD); + TO_STACK32(pti, lpiid32, IID FAR *); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if ( lpiid32 != NULL ) + { + CoTaskMemFree( lpiid32 ); + } + return( dwResult ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_INTERFACEINFO_1632, public +// +// Synopsis: Converts an INTERFACEINFO +// +// Arguments: [pti] - Thunking state information +// +// Returns: Appropriate status code +// +// History: 19-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_INTERFACEINFO_1632(THUNKINFO *pti) +{ + INTERFACEINFO *pii32; + INTERFACEINFO ii32; + INTERFACEINFO16 UNALIGNED *pii16; + VPVOID vpii16; + DWORD dwResult; + IUnknown *punk32; + VPVOID vpvUnk16; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_INTERFACEINFO); + thkAssert((*pti->pThop & THOP_INOUT) == THOP_IN); + + pii32 = NULL; + punk32 = NULL; + + GET_STACK16(pti, vpii16, VPVOID); + if (vpii16 != 0) + { + pii16 = (INTERFACEINFO16 UNALIGNED *) + GetReadPtr16(pti, vpii16, sizeof(INTERFACEINFO16)); + if (pii16 != NULL) + { + if (pii16->pUnk != NULL) + { + vpvUnk16 = pii16->pUnk; + + WOWRELVDMPTR(vpii16); + + punk32 = + pti->pThkMgr->FindProxy3216(NULL, vpvUnk16, + INDEX_IIDIDX(THI_IUnknown), + NULL); + if (punk32 == NULL) + { + pti->scResult = E_OUTOFMEMORY; + } + + pii16 = FIXVDMPTR(vpii16, INTERFACEINFO16); + } + + pii32 = &ii32; + pii32->pUnk = punk32; + pii32->iid = pii16->iid; + pii32->wMethod = pii16->wMethod; + + WOWRELVDMPTR(vpii16); + + thkDebugOut((DEB_ARGS, + "In1632 INTERFACEINFO: %p -> %p {%p (%p), %s, %u}\n", + vpii16, pii32, pii32->pUnk, pii16->pUnk, + IidOrInterfaceString(&pii32->iid), pii32->wMethod)); + } + } + + TO_STACK32(pti, pii32, INTERFACEINFO *); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if (punk32 != NULL) + { + pii16 = FIXVDMPTR(vpii16, INTERFACEINFO16); + vpvUnk16 = pii16->pUnk; + RELVDMPTR(vpii16); + pti->pThkMgr->FreeProxy3216(vpvUnk16); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_RETURNTYPE_1632, public +// +// Synopsis: Thunks the return value of a call +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 24-Feb-94 DrewB Created +// +// Notes: This thunk assumes that the return value will always fit +// in 32 bits and that the thops for it are only one thop +// long. This fits the existing APIs and methods +// +//---------------------------------------------------------------------------- + +DWORD Thop_RETURNTYPE_1632(THUNKINFO *pti) +{ + THOP thops[2]; + DWORD dwResult; + ALIAS alias; + VPVOID vpPreAlloc = NULL; + IIDIDX iidx; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_RETURNTYPE); + thkAssert((*pti->pThop & THOP_IOMASK) == 0); + + pti->fResultThunked = TRUE; + + pti->pThop++; + + // Remember return type thop + thops[0] = *pti->pThop++; + if ((thops[0] & THOP_OPMASK) == THOP_COPY || + (thops[0] & THOP_OPMASK) == THOP_IFACE || + (thops[0] & THOP_OPMASK) == THOP_ALIAS32) + { + thops[1] = *pti->pThop++; + } + + // Preallocate any necessary resources + switch(thops[0]) + { + case THOP_IFACE | THOP_IN: + iidx = INDEX_IIDIDX(thops[1]); + if ((vpPreAlloc = + pti->pThkMgr->CanGetNewProxy1632(iidx)) == NULL) + { + pti->scResult = E_OUTOFMEMORY; + } + break; + + case THOP_ALIAS32: + thkAssert(thops[1] == ALIAS_CREATE); + + // The value used for preallocation doesn't really matter + // as long as it's unique and not INVALID_VALUE + // In our case we know that we won't have to deal with nested + // preallocations so uniqueness is not as much of an issue + // By using INVALID_HANDLE_VALUE, we can be sure that there + // won't already be an entry with that value already in the + // alias table since we're aliasing handles + alias = gAliases32.AddValue((DWORD)INVALID_HANDLE_VALUE); + if (alias == INVALID_ALIAS) + { + pti->scResult = E_OUTOFMEMORY; + } + break; + } + + dwResult = EXECUTE_THOP1632(pti); + + // Now that we have the return value thunk it from 32->16 + // We must use pti->scResult to check for failure rather than + // dwResult because dwResult may not be an SCODE + + switch(thops[0]) + { + case THOP_COPY: + // Only handle DWORD copies + thkAssert(thops[1] == sizeof(DWORD)); + break; + + case THOP_SHORTLONG: + // For boolean results, not necessary to clamp + dwResult = (DWORD)(SHORT)*(LONG *)&dwResult; + break; + + case THOP_IFACE | THOP_IN: + if (dwResult != 0) + { + if (FAILED(pti->scResult)) + { + dwResult = 0; + } + else + { + dwResult = + (DWORD)pti->pThkMgr->FindProxy1632(vpPreAlloc, + (IUnknown *)dwResult, + iidx, NULL); + thkAssert(dwResult != 0); + + thkDebugOut((DEB_ARGS, "Ret1632 %s %p\n", + inInterfaceNames[thops[1]].pszInterface, + dwResult)); + } + } + else + { + pti->pThkMgr->FreeNewProxy1632(vpPreAlloc, iidx); + } + break; + + case THOP_ALIAS32: + if (dwResult != 0) + { + if (FAILED(pti->scResult)) + { + dwResult = 0; + } + else + { + gAliases32.SetValue(alias, dwResult); + + thkDebugOut((DEB_ARGS, "Ret1632 ALIAS32: 0x%08lX -> 0x%04lX\n", + dwResult, alias)); + + dwResult = (DWORD)alias; + } + } + break; + + default: + thkAssert(!"Unhandled 1632 return type"); + break; + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_IFACE_1632, public +// +// Synopsis: Thunks a known interface pointer +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 24-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_IFACE_1632(THUNKINFO *pti) +{ + IIDIDX iidx; + THOP thop, thopOp, thopWeakOffset; + IUnknown *punkOuter; + + thop = *pti->pThop++; + thopOp = thop & THOP_OPMASK; + + thkAssert( thopOp == THOP_IFACE + || thopOp == THOP_IFACEOWNER + || thopOp == THOP_IFACENOADDREF); + + iidx = INDEX_IIDIDX(*pti->pThop++); + + // There's a bit of a special case here in that IMalloc is + // not thunked so it doesn't have a real index but it's used + // in thop strings so it has a fake index to function as a placeholder + // The fake index is THI_COUNT so allow that in the assert + thkAssert(IIDIDX_INDEX(iidx) >= 0 && IIDIDX_INDEX(iidx) <= THI_COUNT); + + punkOuter = NULL; + if ( thopOp == THOP_IFACEOWNER + || thopOp == THOP_IFACENOADDREF) + { + thopWeakOffset = *pti->pThop++; + INDEX_STACK32(pti, punkOuter, IUnknown *, thopWeakOffset); + } + + return ThunkInterface1632(pti, iidx, thop, punkOuter); +} + +typedef struct tagOLESTREAMOBJECT +{ + OLESTREAM os; + VPVOID vpolestream16; +} OLESTREAMOBJECT, FAR * LPOLESTREAMOBJECT; + +#define OLESTREAM_GET 0 +#define OLESTREAM_PUT 1 + + +//+--------------------------------------------------------------------------- +// +// Function: OLESTREAM_Callback, private +// +// Synopsis: Handles callbacks into 16-bit world for OLESTREAM methods +// +// Arguments: [dwMethod] - Index of method to invoke +// [lposo] - Pointer to 32 LPOLESTREAM +// [lpv] - Pointer to 32 bit buffer +// [dwCount] - Size of 32 bit buffer +// +// +// Returns: Appropriate status code +// +// History: 11-Mar-94 BobDay Created +// 29-May-94 TerryRu Converted to call WOWCallBackEx directly. +// +//---------------------------------------------------------------------------- + +DWORD OLESTREAM_Callback( DWORD dwMethod, + LPOLESTREAM lpos, + LPVOID lpv, + DWORD dwCount ) +{ + const DWORD cbStack = sizeof( DWORD ) + + sizeof( VPVOID ) + sizeof( VPVOID ); + + BYTE b32Args[cbStack]; + DWORD dwResult; + + VPVOID vpvVtbl16; + VTBLFN vpfn16; + + VPVOID vpolestream16; + LPOLESTREAMOBJECT lposo; + + VPVOID vp16; + LPVOID lp16; + + + lposo = (LPOLESTREAMOBJECT)lpos; + vpolestream16 = lposo->vpolestream16; + + // Get pointer to 16 bit this pointer + + vpvVtbl16 = (VPVOID)*FIXVDMPTR( vpolestream16, VPVOID ); + RELVDMPTR(vpolestream16); + vpfn16 = (VTBLFN)*FIXVDMPTR( vpvVtbl16+dwMethod*sizeof(VPVOID), + VPVOID ); + RELVDMPTR(vpvVtbl16+dwMethod*sizeof(VPVOID)); + + // + // now thop the IN 32 bit-block of memory to 16 bit block + // + + vp16 = WgtAllocLock( GMEM_MOVEABLE, dwCount, NULL ); + if ( vp16 == NULL ) + { + return (DWORD) E_OUTOFMEMORY; + } + + if ( dwMethod == OLESTREAM_PUT ) + { + lp16 = WOWFIXVDMPTR( vp16, dwCount ); + memcpy( lp16, lpv, dwCount ); + WOWRELVDMPTR(vp16); + } + + // setup 32 bit arguements. + *(DWORD *)(b32Args) = dwCount; + *(VPVOID *)(b32Args+4) = vp16; + *(VPVOID *)(b32Args+8) = vpolestream16; + + if ( !CallbackTo16Ex( (DWORD)vpfn16, WCB16_PASCAL, cbStack, b32Args, + &dwResult) ) + { + dwResult = (DWORD)E_UNEXPECTED; + } + + if ( dwMethod == OLESTREAM_GET ) + { + + lp16 = WOWFIXVDMPTR( vp16, dwCount ); + memcpy( (LPVOID) lpv, lp16, dwCount ); + WOWRELVDMPTR(vp16); + + } + + WgtUnlockFree(vp16); + + thkDebugOut((DEB_INVOKES, "OLESTREAM_Callback returns 0x%08lX\n", + dwResult)); + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: OLESTREAM_Get_Proxy, private +// +// Synopsis: Handles callbacks into 16-bit world for OLESTREAM::Get +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 11-Mar-94 BobDay Created +// 29-May-94 TerryRu Now calls OLESTREAM::Get using Pascal +// calling conventions. +// +//---------------------------------------------------------------------------- + +DWORD OLESTREAM_Get_Proxy( + LPOLESTREAM lpos, + void FAR * lpv, + DWORD dwCount +) +{ + return OLESTREAM_Callback( OLESTREAM_GET, lpos, lpv, dwCount ); +} + +//+--------------------------------------------------------------------------- +// +// Function: OLESTREAM_Put_Proxy, private +// +// Synopsis: Handles callbacks into 16-bit world for OLESTREAM::Put +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 11-Mar-94 BobDay Created +// 29-May-94 TerryRu Now call OLESTREAM::Put using pascal +// calling conventions. +// +//---------------------------------------------------------------------------- + +DWORD OLESTREAM_Put_Proxy( + LPOLESTREAM lpos, + const void FAR* lpv, + DWORD dwCount +) +{ + return OLESTREAM_Callback( OLESTREAM_PUT, lpos,(LPVOID) lpv, dwCount ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_OLESTREAM_1632, public +// +// Synopsis: Thunks an OLESTREAM parameter from 16-bit to 32-bit +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 14-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +_OLESTREAMVTBL osVtbl = +{ + OLESTREAM_Get_Proxy, + OLESTREAM_Put_Proxy +}; + +DWORD Thop_OLESTREAM_1632(THUNKINFO *pti) +{ + OLESTREAMOBJECT osObject; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_OLESTREAM); + + // + // Ignore the THOP_INPUT/THOP_OUTPUT, it is always just an interface + // + + osObject.os.lpstbl = &osVtbl; + GET_STACK16(pti, osObject.vpolestream16, VPVOID); + + TO_STACK32(pti, &osObject, LPOLESTREAMOBJECT ); + + pti->pThop++; + return EXECUTE_THOP1632(pti); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_RPCOLEMESSAGE_1632, public +// +// Synopsis: Converts 16-bit RPCOLEMESSAGE to 32-bit RPCOLEMESSAGE +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// 28-May-94 JohannP Rewritten +// 13-Aug-94 Rickhi made it work for GetBuffer when the +// buffer size grows, commented better +// +// CODEWORK: this routine is inefficient. since it cant tell why it was +// called (GetBuffer/SendReceive/Invoke/FreeBuffer) it always +// copies the data, when it only really needs to in Invoke and +// in SendReceive. +// +// Context: This routine will "Thop" a client side RPCOLEMESSGE (aka "rom") +// three times. The first time for the "getbuffer" call, the second +// time for the "SendRecieve", and the third time for the "freebuffer". +// This make it confusing, some calls allocate a buffer but don't +// free it. Other calls free a buffer they didn't allocate. A good +// way to see what is happening is to step through several calls to +// this routine with a debugger and note the pointer values. +// +//---------------------------------------------------------------------------- +DWORD Thop_RPCOLEMESSAGE_1632( THUNKINFO *pti ) +{ + DWORD dwResult; + PRPCOLEMESSAGE prom32; + VPVOID vprom16; + RPCOLEMESSAGE UNALIGNED *prom16; + LPVOID lp16; + RPCOLEMESSAGE rom32; + BOOL fAllocNew = FALSE; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_RPCOLEMESSAGE); + + // + // We currently have only INOUT RPCOLEMESSAGE + // + thkAssert( (*pti->pThop & THOP_IOMASK) == (THOP_IN | THOP_OUT) && + "RPCOLEMESSAGE must be input/output only" ); + + // + // Processing for a RPCOLEMESSAGE FAR * as input/output + // + GET_STACK16(pti, vprom16, VPVOID); + + prom32 = NULL; + if ( vprom16 != 0 ) + { + // Copy over the input RPCOLEMESSAGE structure + prom16 = (RPCOLEMESSAGE UNALIGNED *) + GetReadWritePtr16( pti, vprom16, sizeof(RPCOLEMESSAGE) ); + if ( prom16 != NULL ) + { + // Note: ROM_THUNK_FIELD(prom) holds the pointer to the 32 bit rom + // in case the buffer is not NULL + + // Note: this assert is not valid when a fault happens on the + // server side. In that case, the return buffer is NULLed + // by the 16bit stub but the THUNK_FIELD is non-null. + + //thkAssert((prom16->Buffer == NULL && + // ROM_THUNK_FIELD(prom16) == NULL) || + // (prom16->Buffer != NULL && + // ROM_THUNK_FIELD(prom16) != NULL)); + + if (prom16->Buffer != NULL) + { + prom32 = (RPCOLEMESSAGE *)ROM_THUNK_FIELD(prom16); + + if ( prom32->Buffer != NULL ) + { + // we use the min size of the two buffers because when + // the stub (server side) calls GetBuffer he is supplying + // the old pBuffer with the new (and potentially larger) + // cbBuffer + + DWORD cbSizeMin = (prom16->cbBuffer <= prom32->cbBuffer) ? + prom16->cbBuffer : prom32->cbBuffer; + + lp16 = (LPVOID)GetReadPtr16(pti, + (VPVOID)prom16->Buffer, + cbSizeMin); + if (lp16 == NULL) + { + prom32 = NULL; + } + else + { + memcpy( prom32->Buffer, lp16, prom32->cbBuffer ); + WOWRELVDMPTR((VPVOID)prom16->Buffer); + } + } + + // the stub might be asking for a larger buffer for output + // parameters than it was given for input parameters. We have + // to figure that out here by comparing the 16bit size with + // the 32bit size. + + fAllocNew = (prom32->cbBuffer < prom16->cbBuffer); + prom32->cbBuffer = prom16->cbBuffer; + } + else + { + rom32 = *prom16; + prom32 = &rom32; + } + + WOWRELVDMPTR(vprom16); + } + } + + TO_STACK32(pti, prom32, PRPCOLEMESSAGE); + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + + if ( prom32 != NULL ) + { + prom16 = (RPCOLEMESSAGE UNALIGNED *) + GetReadWritePtr16( pti, vprom16, sizeof(RPCOLEMESSAGE) ); + if ( prom16 == NULL ) + { + dwResult = (DWORD)E_UNEXPECTED; + } + else + { + if (SUCCEEDED(dwResult)) + { + if (prom32->Buffer == NULL) + { + // RELEASE THE BUFFER AND ROM: + // Free the 16 bit buffer, copy the 32 bit rom into + // the 16 bit rom and free the 32bit rom, if it was + // allocated + // + if (prom16->Buffer != 0) + { + TaskFree16((VPVOID)prom16->Buffer); + } + + *prom16 = *prom32; + + if (prom32 != &rom32) + { + TaskFree32(prom32); + prom32 = NULL; + } + ROM_THUNK_FIELD(prom16) = NULL; + } + else + { + // ALLOCATE AND/OR COPYBACK THE BUFFER AND ROM: + RPCOLEMESSAGE *pr32; + LPVOID pBuffer; + + // Create a message to save the 32-bit message in + // Use the existing one in the thunk field if we can + if (ROM_THUNK_FIELD(prom16) == NULL) + { + pr32 = (RPCOLEMESSAGE *) + TaskMalloc32(sizeof(RPCOLEMESSAGE)); + } + else + { + pr32 = (RPCOLEMESSAGE *)ROM_THUNK_FIELD(prom16); + } + *pr32 = *prom32; + + // + // Allocate an output buffer and copy the buffer back + // + if ( (prom16->Buffer == NULL) + || (prom16->cbBuffer < prom32->cbBuffer) + || fAllocNew) + { + if (prom16->Buffer != NULL) + { + TaskFree16((VPVOID) prom16->Buffer); + } + + pBuffer = (LPVOID)TaskMalloc16(prom32->cbBuffer ); + } + else + { + pBuffer = prom16->Buffer; + } + + *prom16 = *prom32; + prom16->Buffer = pBuffer; + ROM_THUNK_FIELD(prom16) = pr32; + + if (prom16->Buffer == NULL) + { + dwResult = (DWORD)E_OUTOFMEMORY; + } + else + { + lp16 = (LPVOID)GetReadPtr16(pti, + (VPVOID)prom16->Buffer, + prom16->cbBuffer); + if ( lp16 == NULL ) + { + dwResult = (DWORD)E_UNEXPECTED; + } + else + { + memcpy( lp16, prom32->Buffer, + prom32->cbBuffer ); + WOWRELVDMPTR((VPVOID)prom16->Buffer); + } + } + } + } + + WOWRELVDMPTR(vprom16); + } + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_ALIAS32_1632, public +// +// Synopsis: Handles 16-bit aliases to 32-bit quantities +// +// Arguments: [pti] - Thunking state information +// +// Returns: Appropriate status code +// +// History: 27-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_ALIAS32_1632(THUNKINFO *pti) +{ + ALIAS alias; + DWORD dwValue; + THOP thopAction; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_ALIAS32); + thkAssert((*pti->pThop & THOP_IOMASK) == 0); + + pti->pThop++; + + GET_STACK16(pti, alias, ALIAS); + + // Second byte indicates how the alias should be handled + thopAction = *pti->pThop++; + + if (alias != 0) + { + switch(thopAction) + { + case ALIAS_RESOLVE: + dwValue = gAliases32.AliasValue(alias); + break; + + case ALIAS_REMOVE: + dwValue = gAliases32.AliasValue(alias); + gAliases32.RemoveAlias(alias); + break; + + default: + thkAssert(!"Default hit in Thop_ALIAS32_1632"); + break; + } + } + else + { + dwValue = 0; + } + + thkDebugOut((DEB_ARGS, "In1632 ALIAS32: 0x%04X -> 0x%08lX\n", + alias, dwValue)); + + TO_STACK32(pti, dwValue, DWORD); + + return EXECUTE_THOP1632(pti); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_ENUM_1632, public +// +// Synopsis: Thunks Enum::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is the start of a 2-byte thop. The next thop +// byte references a function in the enumerator table, rather +// than the standard thop table. +// +//---------------------------------------------------------------------------- + +DWORD Thop_ENUM_1632(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_ENUM); + thkAssert((*pti->pThop & THOP_IOMASK) == 0); + + // + // Get then next thop byte and execute it as a Enum thop + // + pti->pThop++; + return EXECUTE_ENUMTHOP1632(pti); +} + +//+--------------------------------------------------------------------------- +// +// Function: CallbackProcessing_1632, public +// +// Synopsis: Thunks IOleObject::Draw pfnContinue & DWORD parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 3-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- +typedef struct tagCallbackControl +{ + DWORD dwContinue; + VPVOID vpfn16; +} CALLBACKCONTROL; + +BOOL CallbackProcessing_1632( DWORD dwContinue ) +{ + DWORD dwResult; + CALLBACKCONTROL *lpcbc; + + lpcbc = (CALLBACKCONTROL *)dwContinue; + + // The callback function must be FAR PASCAL + // It's declared CALLBACK in the methods so this is ensured + dwResult = CallbackTo16( lpcbc->vpfn16, lpcbc->dwContinue ); + + return (BOOL)((WORD)dwResult); // Ignore HIWORD +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_CALLBACK_1632, public +// +// Synopsis: Thunks IOleObject::Draw pfnContinue & DWORD parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 3-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_CALLBACK_1632(THUNKINFO *pti) +{ + VPVOID vpfn16; + DWORD dwContinue; + CALLBACKCONTROL cbc; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_CALLBACK); + thkAssert((*pti->pThop & THOP_IOMASK) == 0); + + GET_STACK16(pti, vpfn16, VPVOID); + GET_STACK16(pti, dwContinue, DWORD); + + if ( vpfn16 == 0 ) + { + TO_STACK32(pti, NULL, LPVOID); + TO_STACK32(pti, dwContinue, DWORD); + } + else + { + cbc.vpfn16 = vpfn16; + cbc.dwContinue = dwContinue; + + TO_STACK32(pti, CallbackProcessing_1632, LPVOID); + TO_STACK32(pti, (DWORD)&cbc, DWORD); + } + + pti->pThop++; + return EXECUTE_THOP1632(pti); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_CLSCONTEXT_1632, public +// +// Synopsis: Converts a class context flags DWORD +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 29-Jun-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_CLSCONTEXT_1632(THUNKINFO *pti) +{ + DWORD dwClsContext; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_CLSCONTEXT); + thkAssert((*pti->pThop & THOP_IOMASK) == 0); + + GET_STACK16(pti, dwClsContext, DWORD); + + // When passing a 16-bit class context on to 32-bits, + // add on a flag to indicate that this is a 16-bit request + // in the inproc server case + + if (dwClsContext & CLSCTX_INPROC_SERVER) + { + dwClsContext |= CLSCTX_INPROC_SERVER16; + } + + TO_STACK32(pti, dwClsContext, DWORD); + + pti->pThop++; + return EXECUTE_THOP1632(pti); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_FILENAME_1632, public +// +// Synopsis: Converts a filename string +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 24-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_FILENAME_1632(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_FILENAME); + + // Can be in or out only + thkAssert((*pti->pThop & THOP_IOMASK) == THOP_IN || + (*pti->pThop & THOP_IOMASK) == THOP_OUT); + + if ((*pti->pThop & THOP_IN) != 0) + { + // No special processing is necessary for filenames going + // from 16->32 since it isn't possible for 16-bit code to + // generate a filename which can't be handled in 32-bits + + return ThunkInString1632(pti); + } + else + { + thkAssert((*pti->pThop & THOP_OUT) != 0); + + // Convert filenames going from 32->16 to short filenames + // to avoid any possible problems with non-8.3 names. + + return ThunkOutString1632(pti, TRUE); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_SIZEDSTRING_1632, public +// +// Synopsis: Converts strings which cannot exceed a given length +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 02-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_SIZEDSTRING_1632(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SIZEDSTRING); + thkAssert((*pti->pThop & THOP_IOMASK) == THOP_IN); + + // For 16->32, there are no limits on string length so + // thunk the string normally + + // Advance once to account for the length byte + // ThunkInString will advance again + + pti->pThop++; + return ThunkInString1632(pti); +} + +#define THOP_FN(x) Thop_ ## x ## _1632 + +DWORD (*CONST aThopFunctions1632[])(THUNKINFO *) = +{ + + // x = Implemented + // ? = Mysteriously not needed + // = Left to do + // + // ^ + // | + // +===+ + // | + // v + // + ThunkCall1632, // x Terminating THOP + Thop_ShortToLong_1632, // x SHORTLONG + Thop_WordToDword_1632, // x WORDDWORD + Thop_Copy_1632, // x COPY + THOP_FN(LPSTR), // x LPSTR + THOP_FN(LPLPSTR), // x LPLPSTR + THOP_FN(BUFFER), // x BUFFER + Thop_UserHandle_1632, // x HUSER + Thop_GdiHandle_1632, // x HGDI + THOP_FN(SIZE), // x SIZE + THOP_FN(RECT), // x RECT + THOP_FN(MSG), // x MSG + THOP_FN(HRESULT), // x HRESULT + THOP_FN(STATSTG), // x STATSTG + THOP_FN(DVTARGETDEVICE), // x DVTARGETDEVICE + THOP_FN(STGMEDIUM), // x STGMEDIUM + THOP_FN(FORMATETC), // x FORMATETC + THOP_FN(HACCEL), // x HACCEL + THOP_FN(OIFI), // x OLEINPLACEFRAMEINFO + THOP_FN(BINDOPTS), // x BIND_OPTS + THOP_FN(LOGPALETTE), // x LOGPALETTE + THOP_FN(SNB), // x SNB + THOP_FN(CRGIID), // x CRGIID + THOP_FN(OLESTREAM), // x OLESTREAM + THOP_FN(HTASK), // x HTASK + THOP_FN(INTERFACEINFO), // x INTERFACEINFO + THOP_FN(IFACE), // x IFACE + THOP_FN(IFACE), // x IFACEOWNER + THOP_FN(IFACE), // x IFACENOADDREF + Thop_ERROR_1632, // x IFACECLEAN + THOP_FN(IFACEGEN), // x IFACEGEN + THOP_FN(IFACEGEN), // x IFACEGENOWNER + Thop_ERROR_1632, // x ROUTINE_INDEX + THOP_FN(RETURNTYPE), // x RETURN_TYPE + THOP_FN(NULL), // x NULL + Thop_ERROR_1632, // x ERROR + THOP_FN(ENUM), // x ENUM + THOP_FN(CALLBACK), // x CALLBACK + THOP_FN(RPCOLEMESSAGE), // x RPCOLEMESSAGE + THOP_FN(ALIAS32), // x ALIAS32 + THOP_FN(CLSCONTEXT), // x CLSCONTEXT + THOP_FN(FILENAME), // x FILENAME + THOP_FN(SIZEDSTRING), // x SIZEDSTRING +}; + +//+--------------------------------------------------------------------------- +// +// Function: General_Enum_1632, private +// +// Synopsis: Thunking for standard OLE enumerator interface ::Next member +// function. +// +// Arguments: [pti] - Thunk state information +// [uiSize32] - 32-bit information size +// [uiSize16] - 16-bit information size +// [pfnCallback] - Data thunking callback +// [pfnCleanup] - Thunking cleanup +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This handler is called from many IXXXEnum::Next handlers thop +// thunks to do the standard sorts of "buffer of structures" +// processing. +// +//---------------------------------------------------------------------------- +#define MAX_ALLOCA_STRUCT 10 + +DWORD General_Enum_1632( + THUNKINFO *pti, + UINT uiSize32, + UINT uiSize16, + SCODE (*pfnCallback)( THUNKINFO *, LPVOID, VPVOID), + void (*pfnCleanup)( THUNKINFO *, LPVOID, VPVOID) ) +{ + DWORD dwResult; + ULONG ulCount; + VPVOID vpstruct16; + VPVOID vpfetched16; + LPVOID lpstruct32; + LPVOID lpstruct32Iterate; + VPVOID vpstruct16Iterate; + ULONG ulFetched32; + ULONG *lpfetched32; + ULONG UNALIGNED *lpfetched16; + ULONG ulIterate; + LPVOID lp16; + BOOL fError; + SCODE sc; + + dwResult = (DWORD)S_OK; + + GET_STACK16(pti, ulCount, ULONG ); + GET_STACK16(pti, vpstruct16, VPVOID ); + GET_STACK16(pti, vpfetched16, VPVOID ); + + // + // THIS ROUTINE CAN DEAL WITH dwResult RATHER THAN pti->scResult BECAUSE + // WE KNOW THIS IS THE ONLY THOP FOR THIS FUNCTION! NO OTHER CLEANUP + // WILL HAVE TO BE DONE! + // + ulFetched32 = 0; + lpfetched32 = &ulFetched32; + lp16 = NULL; + lpstruct32 = NULL; + + if ( vpstruct16 != 0 ) + { + if ( ulCount == 0 ) + { + dwResult = (DWORD)E_INVALIDARG; + } + else + { + // + // Verify we have write access to the 16-bit memory. + // + lp16 = GetWritePtr16(pti, vpstruct16, uiSize16*ulCount); + if ( lp16 == NULL ) + { + dwResult = (DWORD)E_INVALIDARG; + } + else + { + if ( ulCount > MAX_ALLOCA_STRUCT ) + { + lpstruct32 = (LPVOID)CoTaskMemAlloc( ulCount * uiSize32 ); + if (lpstruct32 == NULL) + { + dwResult = (DWORD)E_OUTOFMEMORY; + } + } + else + { + lpstruct32 = (LPVOID)STACKALLOC32( ulCount * uiSize32 ); + if (lpstruct32 == NULL) + { + dwResult = (DWORD)E_OUTOFMEMORY; + } + } + + WOWRELVDMPTR(vpstruct16); + } + } + } + + if (SUCCEEDED(dwResult)) + { + TO_STACK32(pti, ulCount, ULONG); + TO_STACK32(pti, lpstruct32, LPVOID); + TO_STACK32(pti, lpfetched32, ULONG FAR *); + + pti->pThop++; + dwResult = EXECUTE_THOP1632(pti); + } + + if ( SUCCEEDED(dwResult) ) + { + if ( vpstruct16 != 0 ) + { + // Some apps (MsWorks3 is one) return S_FALSE and do not return + // the number of elements retrieved. The only thing we can + // do is ignore the enumeration since we don't know how many + // were actually set. Of course, we can't ignore all enumerations + // when the return is S_FALSE so we only handle the case + // where S_FALSE was returned on a enumeration of one element, + // in which we can be sure there isn't any valid data + if (dwResult == (DWORD)S_FALSE && ulCount == 1) + { + ulFetched32 = 0; + } + + // + // Iterate through all of the structures, converting them + // into 16-bit + // + fError = FALSE; + ulIterate = 0; + vpstruct16Iterate = vpstruct16; + lpstruct32Iterate = lpstruct32; + + while ( ulIterate < ulFetched32 ) + { + // + // Callback to the callback function to do any specific + // processing + // + sc = (*pfnCallback)( pti, lpstruct32Iterate, + vpstruct16Iterate ); + + if ( FAILED(sc) ) + { + fError = TRUE; + dwResult = sc; + } + + vpstruct16Iterate = (VPVOID)((DWORD)vpstruct16Iterate + + uiSize16); + lpstruct32Iterate = (LPVOID)((DWORD)lpstruct32Iterate + + uiSize32); + + ulIterate++; + } + + if ( fError ) + { + // + // Cleanup all these guys + // + ulIterate = 0; + vpstruct16Iterate = vpstruct16; + lpstruct32Iterate = lpstruct32; + + while ( ulIterate <= ulFetched32 ) + { + (*pfnCleanup)( pti, lpstruct32Iterate, vpstruct16Iterate ); + vpstruct16Iterate = (VPVOID)((DWORD)vpstruct16Iterate + + uiSize16); + lpstruct32Iterate = (LPVOID)((DWORD)lpstruct32Iterate + + uiSize32); + + ulIterate++; + } + } + } + } + + if (FAILED(dwResult) && lp16 != NULL) + { + memset(lp16, 0, ulCount*uiSize16); + } + + // + // Free up any space we've allocated + // + if (lpstruct32 != NULL) + { + if ( ulCount > MAX_ALLOCA_STRUCT ) + { + CoTaskMemFree( lpstruct32 ); + } + else + { + STACKFREE32(lpstruct32, ulCount*uiSize32); + } + } + + if ( vpfetched16 != 0 ) + { + lpfetched16 = FIXVDMPTR( vpfetched16, ULONG); + *lpfetched16 = ulFetched32; + RELVDMPTR(vpfetched16); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_STRING_1632, public +// +// Synopsis: Prepares the LPOLESTR for the copy back into 16-bit address +// space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_STRING_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + VPSTR vpstr; + VPSTR UNALIGNED *pvpstr16; + SCODE sc; + + vpstr = 0; + sc = ConvertTaskString3216(pti, *(LPOLESTR *)lp32, NULL, 0, + &vpstr); + + pvpstr16 = FIXVDMPTR(vp16, VPSTR); + *pvpstr16 = vpstr; + RELVDMPTR(vp16); + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_STRING_1632, public +// +// Synopsis: Cleans up the any STRINGs returned (either to 16-bit or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_STRING_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + VPSTR UNALIGNED *lpvpstr16; + VPSTR vpstr16; + + lpvpstr16 = FIXVDMPTR( vp16, VPSTR ); + vpstr16 = *lpvpstr16; + RELVDMPTR(vp16); + + if ( vpstr16 != 0 ) + { + TaskFree16( vpstr16 ); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_STRING_1632, public +// +// Synopsis: Thunks IEnumSTRING::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_STRING_1632(THUNKINFO *pti) +{ + return General_Enum_1632(pti, + sizeof(LPOLESTR), + sizeof(VPSTR), + Callback_STRING_1632, + Cleanup_STRING_1632 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_UNKNOWN_1632, public +// +// Synopsis: Prepares the UNKNOWN structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_UNKNOWN_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + VPVOID vpunknown16; + SCODE sc = S_OK; + + vpunknown16 = + pti->pThkMgr->FindProxy1632(NULL, *(LPUNKNOWN *)lp32, + INDEX_IIDIDX(THI_IUnknown), NULL); + if (vpunknown16 == 0) + { + sc = E_OUTOFMEMORY; + } + + *FIXVDMPTR( vp16, VPVOID ) = vpunknown16; + RELVDMPTR(vp16); + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_UNKNOWN_1632, public +// +// Synopsis: Cleans up the any UNKNOWNs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_UNKNOWN_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + LPUNKNOWN lpunknown32; + VPVOID vpunknown16; + + vpunknown16 = *FIXVDMPTR( vp16, VPVOID ); + RELVDMPTR(vp16); + lpunknown32 = *(LPUNKNOWN *)lp32; + + // BUGBUG - What is the proper cleanup for IEnum<Interface>? + // Should the objects be released or only the proxies we + // created? + if (vpunknown16 != 0) + { + pti->pThkMgr->FreeProxy1632( lpunknown32 ); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_UNKNOWN_1632, public +// +// Synopsis: Thunks IEnumUNKNOWN::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_UNKNOWN_1632(THUNKINFO *pti) +{ + return General_Enum_1632(pti, + sizeof(LPUNKNOWN), + sizeof(LPUNKNOWN), + Callback_UNKNOWN_1632, + Cleanup_UNKNOWN_1632 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_STATSTG_1632, public +// +// Synopsis: Prepares the STATSTG structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_STATSTG_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + (FIXVDMPTR(vp16, STATSTG))->pwcsName = NULL; + RELVDMPTR(vp16); + return ConvertStatStg3216(pti, (STATSTG *)lp32, vp16, + NULL, 0); +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_STATSTG_1632, public +// +// Synopsis: Cleans up the any STATSTGs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_STATSTG_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + STATSTG UNALIGNED *lpstatstg16; + VPVOID vpstr; + + lpstatstg16 = FIXVDMPTR( vp16, STATSTG ); + vpstr = (VPVOID)lpstatstg16->pwcsName; + RELVDMPTR(vp16); + + if ( vpstr != 0) + { + TaskFree16( vpstr ); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_STATSTG_1632, public +// +// Synopsis: Thunks IEnumSTATSTG::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_STATSTG_1632(THUNKINFO *pti) +{ + return General_Enum_1632(pti, + sizeof(STATSTG), + sizeof(STATSTG), + Callback_STATSTG_1632, + Cleanup_STATSTG_1632 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_FORMATETC_1632, public +// +// Synopsis: Prepares the FORMATETC structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_FORMATETC_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + (FIXVDMPTR(vp16, FORMATETC16))->ptd = NULL; + RELVDMPTR(vp16); + return ConvertFetc3216(pti, (FORMATETC *)lp32, vp16, TRUE); +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_FORMATETC_1632, public +// +// Synopsis: Cleans up the any FORMATETCs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_FORMATETC_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + FORMATETC16 UNALIGNED *lpformatetc16; + VPVOID vptd; + + lpformatetc16 = FIXVDMPTR( vp16, FORMATETC16 ); + vptd = lpformatetc16->ptd; + RELVDMPTR(vp16); + + if (vptd != 0) + { + TaskFree16(vptd); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_FORMATETC_1632, public +// +// Synopsis: Thunks IEnumFORMATETC::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_FORMATETC_1632(THUNKINFO *pti) +{ + return General_Enum_1632(pti, + sizeof(FORMATETC), + sizeof(FORMATETC16), + Callback_FORMATETC_1632, + Cleanup_FORMATETC_1632 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_STATDATA_1632, public +// +// Synopsis: Prepares the STATDATA structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- +SCODE Callback_STATDATA_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + SCODE sc; + LPSTATDATA lpstatdata32; + STATDATA16 UNALIGNED *lpstatdata16; + VPVOID vpadv16; + + sc = S_OK; + + lpstatdata32 = (LPSTATDATA)lp32; + + if (lpstatdata32->pAdvSink != NULL) + { + // We don't know whether it's an AdviseSink or + // an AdviseSink2, so pass AdviseSink2 since it's + // a superset of AdviseSink and will work for both + + vpadv16 = pti->pThkMgr->FindProxy1632(NULL, lpstatdata32->pAdvSink, + INDEX_IIDIDX(THI_IAdviseSink2), + NULL); + if (vpadv16 == 0) + { + sc = E_OUTOFMEMORY; + } + } + else + { + vpadv16 = 0; + } + + lpstatdata16 = FIXVDMPTR( vp16, STATDATA16 ); + lpstatdata16->formatetc.ptd = NULL; + if (SUCCEEDED(sc)) + { + // If this fails the AdviseSink proxy will be cleaned up in + // the cleanup function later + + sc = ConvertFetc3216(pti, + &lpstatdata32->formatetc, + vp16+FIELD_OFFSET(STATDATA16, formatetc), TRUE); + } + + if (SUCCEEDED(sc)) + { + lpstatdata16->advf = lpstatdata32->advf; + lpstatdata16->pAdvSink = vpadv16; + lpstatdata16->dwConnection = lpstatdata32->dwConnection; + } + + RELVDMPTR(vp16); + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_STATDATA_1632, public +// +// Synopsis: Cleans up the any STATDATAs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_STATDATA_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + STATDATA *lpstatdata32; + STATDATA16 UNALIGNED *lpstatdata16; + LPADVISESINK lpadv32; + VPVOID vptd; + + lpstatdata32 = (STATDATA FAR *)lp32; + lpadv32 = lpstatdata32->pAdvSink; + + lpstatdata16 = FIXVDMPTR( vp16, STATDATA16 ); + vptd = lpstatdata16->formatetc.ptd; + RELVDMPTR(vp16); + + if ( lpstatdata16->pAdvSink != NULL ) + { + // BUGBUG - What is the proper cleanup for interfaces? + // Should the objects be released or only the proxies we + // created? + pti->pThkMgr->FreeProxy1632(lpstatdata32->pAdvSink); + } + + if (vptd != 0) + { + TaskFree16(vptd); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_STATDATA_1632, public +// +// Synopsis: Thunks IEnumSTATDATA::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_STATDATA_1632(THUNKINFO *pti) +{ + return General_Enum_1632(pti, + sizeof(STATDATA), + sizeof(STATDATA16), + Callback_STATDATA_1632, + Cleanup_STATDATA_1632 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_MONIKER_1632, public +// +// Synopsis: Prepares the MONIKER structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_MONIKER_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + VPVOID vpmoniker16; + SCODE sc = S_OK; + + vpmoniker16 = pti->pThkMgr->FindProxy1632(NULL, *(LPMONIKER *)lp32, + INDEX_IIDIDX(THI_IMoniker), + NULL); + if (vpmoniker16 == 0) + { + sc = E_OUTOFMEMORY; + } + + *FIXVDMPTR(vp16, VPVOID) = vpmoniker16; + RELVDMPTR(vp16); + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_MONIKER_1632, public +// +// Synopsis: Cleans up the any MONIKERs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_MONIKER_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + LPMONIKER lpmoniker32; + VPVOID vpmoniker16; + + vpmoniker16 = *FIXVDMPTR( vp16, VPVOID ); + RELVDMPTR(vp16); + lpmoniker32 = *(LPMONIKER *)lp32; + + // BUGBUG - What is the proper cleanup for IEnum<Interface>? + // Should the objects be released or only the proxies we + // created? + if (vpmoniker16 != NULL) + { + pti->pThkMgr->FreeProxy1632( lpmoniker32 ); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_MONIKER_1632, public +// +// Synopsis: Thunks IEnumMONIKER::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_MONIKER_1632(THUNKINFO *pti) +{ + return General_Enum_1632(pti, + sizeof(LPMONIKER), + sizeof(LPMONIKER), + Callback_MONIKER_1632, + Cleanup_MONIKER_1632 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_OLEVERB_1632, public +// +// Synopsis: Prepares the OLEVERB structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_OLEVERB_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + SCODE sc; + OLEVERB *lpoleverb32; + OLEVERB UNALIGNED *lpoleverb16; + VPSTR vpstr; + + lpoleverb32 = (LPOLEVERB)lp32; + vpstr = 0; + sc = ConvertTaskString3216(pti, lpoleverb32->lpszVerbName, NULL, 0, + &vpstr); + lpoleverb16 = FIXVDMPTR(vp16, OLEVERB); + lpoleverb16->lpszVerbName = (LPOLESTR)vpstr; + if (SUCCEEDED(sc)) + { + lpoleverb16->lVerb = lpoleverb32->lVerb; + lpoleverb16->fuFlags = lpoleverb32->fuFlags; + lpoleverb16->grfAttribs = lpoleverb32->grfAttribs; + } + RELVDMPTR(vp16); + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_OLEVERB_1632, public +// +// Synopsis: Cleans up the any OLEVERBs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit returned structure +// [lp16] - Pointer to 16-bit output structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_OLEVERB_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + OLEVERB UNALIGNED *lpoleverb16; + VPVOID vpstr; + + lpoleverb16 = FIXVDMPTR( vp16, OLEVERB ); + vpstr = (VPVOID)lpoleverb16->lpszVerbName; + RELVDMPTR(vp16); + + if ( vpstr != 0 ) + { + TaskFree16( vpstr ); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_OLEVERB_1632, public +// +// Synopsis: Thunks IEnumOLEVERB::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_OLEVERB_1632(THUNKINFO *pti) +{ + return General_Enum_1632(pti, + sizeof(OLEVERB), + sizeof(OLEVERB), + Callback_OLEVERB_1632, + Cleanup_OLEVERB_1632 ); +} + +#define THOP_EFN(x) Thop_Enum_ ## x ## _1632 + +DWORD (*CONST aThopEnumFunctions1632[])(THUNKINFO *) = +{ + THOP_EFN(STRING), // STRING + THOP_EFN(UNKNOWN), // UNKNOWN + THOP_EFN(STATSTG), // STATSTG + THOP_EFN(FORMATETC), // FORMATETC + THOP_EFN(STATDATA), // STATDATA + THOP_EFN(MONIKER), // MONIKER + THOP_EFN(OLEVERB), // OLEVERB +}; + + diff --git a/private/ole32/olethunk/olethk32/thop32.cxx b/private/ole32/olethunk/olethk32/thop32.cxx new file mode 100644 index 000000000..869dd75f3 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thop32.cxx @@ -0,0 +1,3959 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thop32.cxx +// +// Contents: Thop implementations for 32->16 +// +// History: 22-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +#include <ole2.h> +#include <string.h> +#include <valid.h> +#include "olethk32.hxx" +#include "struct16.hxx" + +//+--------------------------------------------------------------------------- +// +// Function: EXECUTE_THOP3216, public +// +// Synopsis: Debugging version of thop dispatch routine +// +// Arguments: [pti] - Thunking info +// +// Returns: Appropriate status +// +// History: 24-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +DWORD EXECUTE_THOP3216(THUNKINFO *pti) +{ + thkDebugOut((DEB_THOPS, "ExThop3216: %s (0x%02X), s16 %p, s32 %p\n", + ThopName(*pti->pThop), *pti->pThop, pti->s16.pbCurrent, + pti->s32.pbCurrent)); + thkAssert((*pti->pThop & THOP_OPMASK) < THOP_LASTOP); + return (*aThopFunctions3216[*((pti)->pThop) & THOP_OPMASK])(pti); +} +#endif + +#if DBG == 1 +DWORD EXECUTE_ENUMTHOP3216(THUNKINFO *pti) +{ + thkDebugOut((DEB_THOPS, "ExEnumThop3216: %s (0x%02X), s16 %p, s32 %p\n", + EnumThopName(*pti->pThop), *pti->pThop, pti->s16.pbCurrent, + pti->s32.pbCurrent)); + return (*aThopEnumFunctions3216[*(pti)->pThop])(pti); +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: FixedThopHandler, public +// +// Synopsis: Generic function which handles the high-level details +// of thop execution for thops that operate on known-size +// data +// +// Arguments: [pti] - Thunking state information +// [thop] - Thop being executed +// [cb16] - 16-bit size +// [pfn1632] - 16->32 conversion routine +// [cb32] - 32-bit size +// [pfn3216] - 32->16 conversion routine +// +// Returns: Appropriate status code +// +// History: 05-Apr-94 DrewB Created +// +// Notes: Automatically increments pThop +// +//---------------------------------------------------------------------------- + +DWORD FixedThopHandler3216(THUNKINFO *pti, + THOP thop, + UINT cb16, + FIXEDHANDLERROUTINE pfn1632, + UINT cb32, + FIXEDHANDLERROUTINE pfn3216) +{ + DWORD dwResult; + VPVOID vp16; + BYTE *pb16; + BYTE *pb32; + + if ((thop & (THOP_IN | THOP_OUT)) != 0) + { + vp16 = 0; + + GET_STACK32(pti, pb32, BYTE *); + if ( pb32 != 0 ) + { + if ((thop & THOP_IN) != 0) + { + if (IsBadReadPtr(pb32, cb32)) + { + return (DWORD)E_INVALIDARG; + } + } + if ((thop & THOP_OUT) != 0) + { + if (IsBadWritePtr(pb32, cb32)) + { + return (DWORD)E_INVALIDARG; + } + } + + vp16 = STACKALLOC16(cb16); + if (vp16 == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + else if ((thop & THOP_IN) != 0) + { + pb16 = (BYTE *)WOWFIXVDMPTR(vp16, cb16); + (pfn3216)(pb32, pb16, cb32, cb16); + WOWRELVDMPTR(vp16); + } + } + + TO_STACK16(pti, vp16, VPVOID); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if ((thop & THOP_OUT) != 0 && pb32 != NULL) + { + if (SUCCEEDED(dwResult)) + { + pb16 = (BYTE *)WOWFIXVDMPTR(vp16, cb16); + (pfn1632)(pb16, pb32, cb16, cb32); + WOWRELVDMPTR(vp16); + } + else if ((thop & THOP_IN) == 0) + { + // Zero out-only parameters on failure + memset(pb32, 0, cb32); + } + } + + if (vp16 != 0) + { + STACKFREE16(vp16, cb16); + } + } + else + { + (pfn3216)(PTR_STACK32(&pti->s32), PTR_STACK16(&pti->s16, cb16), + cb32, cb16); + + SKIP_STACK16(&pti->s16, cb16); + SKIP_STACK32(&pti->s32, cb32); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + } + + return dwResult; +} + +//----------------------------------------------------------------------------- +// +// Handler-based thunks +// +// These thunks use the fixed-size generic thop handler to do their work +// +//----------------------------------------------------------------------------- + +// Handle straight copy +DWORD Thop_Copy_3216(THUNKINFO *pti) +{ + THOP thopSize; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_COPY); + + thopSize = *++pti->pThop; + return FixedThopHandler3216(pti, + *(pti->pThop-1), + thopSize, FhCopyMemory, + thopSize, FhCopyMemory); +} + +DWORD Thop_ShortToLong_3216(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SHORTLONG); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(SHORT), FhShortToLong, + sizeof(LONG), FhLongToShort); +} + +DWORD Thop_WordToDword_3216(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_WORDDWORD); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(WORD), FhWordToDword, + sizeof(DWORD), FhDwordToWord); +} + +DWORD Thop_GdiHandle_3216(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HGDI); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(HAND16), FhGdiHandle1632, + sizeof(HANDLE), FhGdiHandle3216); +} + +DWORD Thop_UserHandle_3216(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HUSER); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(HAND16), FhUserHandle1632, + sizeof(HANDLE), FhUserHandle3216); +} + +DWORD Thop_HACCEL_3216(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HACCEL); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(HAND16), FhHaccel1632, + sizeof(HANDLE), FhHaccel3216); +} + +DWORD Thop_HTASK_3216(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HTASK); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(HAND16), FhHtask1632, + sizeof(HANDLE), FhHtask3216); +} + +DWORD Thop_HRESULT_3216( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HRESULT); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(HRESULT), FhHresult1632, + sizeof(HRESULT), FhHresult3216); +} + +DWORD Thop_NULL_3216(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_NULL); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(void *), FhNull, + sizeof(void *), FhNull); +} + +DWORD Thop_RECT_3216( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_RECT); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(RECT16), FhRect1632, + sizeof(RECT), FhRect3216); +} + +DWORD Thop_BINDOPTS_3216( THUNKINFO *pti ) +{ + LPBIND_OPTS pbo; + UINT cb; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_BINDOPTS); + + PEEK_STACK32(pti, pbo, LPBIND_OPTS); + if (!IsBadReadPtr(pbo, sizeof(LPBIND_OPTS))) + { + cb = pbo->cbStruct; + } + else + { + return (DWORD)E_INVALIDARG; + } + + return FixedThopHandler3216(pti, + *pti->pThop, + cb, FhCopyMemory, + cb, FhCopyMemory); +} + +DWORD Thop_SIZE_3216( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SIZE); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(SIZE16), FhSize1632, + sizeof(SIZE), FhSize3216); +} + +DWORD Thop_MSG_3216( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_MSG); + + return FixedThopHandler3216(pti, + *pti->pThop, + sizeof(MSG16), FhMsg1632, + sizeof(MSG), FhMsg3216); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_ERROR_3216, public +// +// Synopsis: Any Thop type which should just fail with an error +// should go be directed here. +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_ERROR_3216 ( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_ERROR); + + thkAssert( FALSE && "Hey we hit an ERROR Thop in 32->16" ); + + return (DWORD)E_UNEXPECTED; +} + +//+--------------------------------------------------------------------------- +// +// Function: ThunkInString3216, public +// +// Synopsis: Converts an in param string or filename +// +// Arguments: [pti] - Thunk state information +// [fFile] - Filename or plain string +// [cchMax] - Maximum length allowed or zero +// +// Returns: Appropriate status code +// +// History: 24-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD ThunkInString3216(THUNKINFO *pti, + BOOL fFile, + UINT cchMax) +{ + DWORD dwResult; + LPOLESTR lpstr32; + VPSTR vpstr16; + UINT uiSize; + LPOLESTR lpstrConv; + LPOLESTR lpstrShort; + + dwResult = (DWORD)S_OK; + + lpstrShort = NULL; + + GET_STACK32(pti, lpstr32, LPOLESTR); + lpstrConv = lpstr32; + + vpstr16 = 0; + if (lpstr32 != NULL) + { + if (IsBadStringPtrW(lpstr32, CCHMAXSTRING)) + { + return (DWORD)E_INVALIDARG; + } + + if (fFile) + { + DWORD cchNeeded, cchShort; + + // Special case zero-length paths since the length returns from + // GetShortPathName become ambiguous when zero characters are + // processed + cchNeeded = lstrlenW(lpstr32); + if (cchNeeded > 0) + { + cchNeeded = GetShortPathName(lpstr32, NULL, 0); + } + + // If we can't convert, simply pass through the name we're given + if (cchNeeded > 0) + { + lpstrShort = (LPOLESTR)CoTaskMemAlloc(cchNeeded*sizeof(WCHAR)); + if (lpstrShort == NULL) + { + return (DWORD)E_OUTOFMEMORY; + } + + cchShort = GetShortPathName(lpstr32, lpstrShort, + cchNeeded); + if (cchShort == 0 || cchShort > cchNeeded) + { + dwResult = (DWORD)E_UNEXPECTED; + } + else + { + lpstrConv = lpstrShort; + } + } + } + + if (SUCCEEDED(dwResult)) + { + uiSize = lstrlenW( lpstrConv ) + 1; + + vpstr16 = STACKALLOC16(uiSize*2); + if (vpstr16 == 0) + { + dwResult = (DWORD)E_OUTOFMEMORY; + } + else + { + char *psz; + + dwResult = Convert_LPOLESTR_to_VPSTR(lpstrConv, vpstr16, + uiSize, uiSize*2); + + // If a maximum length was given, truncate the converted + // string if necessary + if (SUCCEEDED(dwResult) && cchMax > 0 && cchMax < uiSize) + { + psz = (char *)WOWFIXVDMPTR(vpstr16, 0); + psz[cchMax] = 0; + WOWRELVDMPTR(vpstr16); + } + } + } + } + + if (SUCCEEDED(dwResult)) + { +#if DBG == 1 + thkDebugOut((DEB_ARGS, "In3216 LPSTR %p -> %p '%s'\n", + lpstr32, vpstr16, + vpstr16 != 0 ? WOWFIXVDMPTR(vpstr16, 0) : "<null>")); + if (vpstr16 != 0) + { + WOWRELVDMPTR(vpstr16); + } +#endif + + TO_STACK16(pti, vpstr16, VPSTR); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + } + + if (vpstr16 != 0) + { + STACKFREE16(vpstr16, uiSize*2); + } + + if (lpstrShort != NULL) + { + CoTaskMemFree(lpstrShort); + } + + return( dwResult ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_LPSTR_3216, public +// +// Synopsis: Converts 32-bit LPOLESTR to 16-bit LPSTR pointer +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_LPSTR_3216( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_LPSTR); + // + // We have only input LPSTRs + // + thkAssert( (*pti->pThop & THOP_IOMASK) == THOP_IN && + "LPSTR must be input only!" ); + + return ThunkInString3216(pti, FALSE, 0); +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertTaskString1632, public +// +// Synopsis: Converts a task-memory string +// +// Arguments: [pti] - Thunk info +// [vpstr16] - String +// [posPreAlloc] - Preallocated string or NULL +// [cchPreAlloc] - Preallocated size or zero +// [ppos32] - String +// +// Returns: Appropriate status code +// +// Modifies: [pti] +// [ppos32] +// +// History: 14-May-94 DrewB Created +// +// Notes: Frees preallocation if successful and: +// Name is too large or +// Name is NULL +// +// Always frees source string if non-zero +// +//---------------------------------------------------------------------------- + +SCODE ConvertTaskString1632(THUNKINFO *pti, + VPSTR vpstr16, + LPOLESTR posPreAlloc, + UINT cchPreAlloc, + LPOLESTR *ppos32) +{ + LPOLESTR pos32; + + if (vpstr16 == 0) + { + pos32 = NULL; + } + else + { + pos32 = Convert_VPSTR_to_LPOLESTR(pti, vpstr16, posPreAlloc, + cchPreAlloc); + + TaskFree16(vpstr16); + + if (pos32 == NULL) + { + return pti->scResult; + } + } + + // If there was a preallocated string we didn't use, + // free it + if (posPreAlloc != NULL && posPreAlloc != pos32) + { + TaskFree32(posPreAlloc); + } + + *ppos32 = pos32; + + return S_OK; +} + +//+--------------------------------------------------------------------------- +// +// Function: ThunkOutString3216, public +// +// Synopsis: Converts an out param string +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 24-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD ThunkOutString3216(THUNKINFO *pti) +{ + DWORD dwResult; + LPOLESTR *lplpstr32; + VPVOID vpvpstr16; + VPSTR UNALIGNED *lpvpstr16; + LPOLESTR lpstr32; + + GET_STACK32(pti, lplpstr32, LPOLESTR FAR *); + + if ( lplpstr32 == NULL ) + { + vpvpstr16 = 0; + } + else + { + if (IsBadWritePtr(lplpstr32, sizeof(LPOLESTR))) + { + return (DWORD)E_INVALIDARG; + } + + vpvpstr16 = STACKALLOC16(sizeof(VPSTR)); + if (vpvpstr16 == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + + lpvpstr16 = FIXVDMPTR(vpvpstr16, VPSTR); + *lpvpstr16 = 0; + RELVDMPTR(vpvpstr16); + + lpstr32 = (LPOLESTR)TaskMalloc32(CBSTRINGPREALLOC); + if (lpstr32 == NULL) + { + STACKFREE16(vpvpstr16, sizeof(VPSTR)); + return (DWORD)E_OUTOFMEMORY; + } + } + + TO_STACK16(pti, vpvpstr16, VPVOID); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if (lplpstr32 != NULL) + { + if (SUCCEEDED(dwResult)) + { + lpvpstr16 = FIXVDMPTR(vpvpstr16, VPSTR); + if (lpvpstr16 == NULL) + { + dwResult = (DWORD)E_INVALIDARG; + } + else + { + SCODE sc; + + sc = ConvertTaskString1632(pti, *lpvpstr16, lpstr32, + CWCSTRINGPREALLOC, &lpstr32); + if (FAILED(sc)) + { + dwResult = sc; + } + + RELVDMPTR(vpvpstr16); + } + } + + if (FAILED(dwResult)) + { + TaskFree32(lpstr32); + + *lplpstr32 = NULL; + } + else + { + *lplpstr32 = lpstr32; + } + + thkDebugOut((DEB_ARGS, "Out3216 LPLPSTR: %p -> %p, '%ws'\n", + *lpvpstr16, lpstr32, lpstr32)); + } + else + { + thkDebugOut((DEB_ARGS, "Out3216 LPLPSTR NULL\n")); + } + + if (vpvpstr16 != 0) + { + STACKFREE16(vpvpstr16, sizeof(VPSTR)); + } + + return( dwResult ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_LPLPSTR_3216, public +// +// Synopsis: Converts 16-bit LPSTR to 32-bit LPSTR pointer +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 26-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_LPLPSTR_3216( THUNKINFO *pti ) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_LPLPSTR); + // + // We don't have anything but unmodified LPLPSTRs + // + thkAssert( (*pti->pThop & THOP_IOMASK) == 0 && + "LPLPSTR must be unmodified only!" ); + + return ThunkOutString3216(pti); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_BUFFER_3216, public +// +// Synopsis: Converts 32-bit block of memory to 16-bit block of memory +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 25-Feb-94 BobDay Created +// +// Notes: WARNING! WARNING! WARNING! For an out parameter this expects +// three parameters on the stack in the following format and order: +// VOID * pointer to buffer +// DWORD count of bytes in buffer +// DWORD * count of bytes returned in the buffer +// +//---------------------------------------------------------------------------- + +#define WATCH_VALUE 0xfef1f0 + +DWORD Thop_BUFFER_3216( THUNKINFO *pti ) +{ + DWORD dwResult; + BOOL fThopInput; + BOOL fThopOutput; + LPVOID lp32; + VPVOID vp16; + LPVOID lp16; + DWORD dwCount; + VPVOID vp16CountOut; + LPVOID pvCountOut32; + DWORD * pdwCountOut32; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_BUFFER); + + fThopInput = IS_THOP_IN(pti); + fThopOutput = IS_THOP_OUT(pti); + + // + // Buffers can only be in or out + // + thkAssert( (fThopInput || fThopOutput) && + (fThopInput != fThopOutput) && + "BUFFER must be in or out only!" ); + + GET_STACK32(pti, lp32, LPVOID); + GET_STACK32(pti, dwCount, DWORD); + + if (fThopOutput) + { + GET_STACK32(pti, pvCountOut32, LPVOID); + pdwCountOut32 = (DWORD *) pvCountOut32; + } + + if ( lp32 == NULL ) + { + vp16 = 0; + } + else if (dwCount == 0) + { + // If the count is zero then we can pass any valid 16-bit + // pointer + +#if DBG == 1 + // In debug, make sure that no data is written back to the + // memory we pass on + vp16 = STACKALLOC16(sizeof(DWORD)); + + if ( vp16 == 0 ) + { + return (DWORD)E_OUTOFMEMORY; + } + + *FIXVDMPTR(vp16, DWORD) = WATCH_VALUE; + RELVDMPTR(vp16); +#else + vp16 = gdata16Data.atfnProxy1632Vtbl; +#endif + } + else + { + if ((fThopInput && IsBadReadPtr(lp32, dwCount)) || + (fThopOutput && IsBadWritePtr(lp32, dwCount))) + { + return (DWORD)E_INVALIDARG; + } + + vp16 = (VPVOID)WgtAllocLock( GMEM_MOVEABLE, dwCount, NULL ); + if ( vp16 == 0 ) + { + return (DWORD)E_OUTOFMEMORY; + } + + if ( fThopInput ) + { + lp16 = (LPVOID)WOWFIXVDMPTR(vp16, dwCount); + memcpy( lp16, lp32, dwCount ); + WOWRELVDMPTR(vp16); + } + } + + if (fThopOutput) + { + // We always allocate storage so we can guarantee that we + // only copy the correct number of bytes. + vp16CountOut = STACKALLOC16(sizeof(DWORD)); + + if (vp16CountOut == 0) + { + return (DWORD) E_OUTOFMEMORY; + } + } + + thkDebugOut((DEB_ARGS, "3216 BUFFER: %p -> %p, %u\n", + lp32, vp16, dwCount)); + + TO_STACK16(pti, vp16, VPVOID ); + TO_STACK16(pti, dwCount, DWORD ); + + if (fThopOutput) + { + TO_STACK16(pti, vp16CountOut, VPVOID ); + } + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if ( SUCCEEDED(dwResult) && fThopOutput ) + { + // Count of bytes to copy into the output buffer + DWORD dwCountOut; + + // Get the output data count + DWORD UNALIGNED *pdw16 = (DWORD UNALIGNED *) + WOWFIXVDMPTR(vp16CountOut, sizeof(DWORD)); + + // Save count to return to 32 bit caller. + dwCountOut = *pdw16; + if (pdwCountOut32) + { + // Note: this parameter can be a NULL pointer + *pdwCountOut32 = dwCountOut; + } + + WOWRELVDMPTR(vp16CountOut); + + // Copy data into output buffer if necessary. + if (dwCountOut > 0) + { + lp16 = (LPVOID) WOWFIXVDMPTR( vp16, dwCountOut ); + memcpy( lp32, lp16, dwCountOut ); + WOWRELVDMPTR(vp16); + } + } + +#if DBG == 1 + if (vp16 != 0 && dwCount == 0) + { + thkAssert(*FIXVDMPTR(vp16, DWORD) == WATCH_VALUE && + (RELVDMPTR(vp16), TRUE)); + STACKFREE16(vp16, sizeof(DWORD)); + } +#endif + + // + // Now free the buffers + // + if ( vp16 != 0 && dwCount > 0 ) + { + WgtUnlockFree( vp16 ); + } + + if (fThopOutput && (vp16CountOut != 0)) + { + STACKFREE16(vp16CountOut, sizeof(DWORD)); + } + + return( dwResult ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_SNB_3216, public +// +// Synopsis: Converts 32-bit SNB to 16-bit SNB pointer +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_SNB_3216( THUNKINFO *pti ) +{ + DWORD dwResult; + BOOL fThopInput; + BOOL fThopOutput; + + SNB snbSrc32; // Ptr to 32 bit Source SNB. + LPOLESTR FAR *lplpsTabSrc32; // Ptr into 32 bit Source ptr table. + LPOLESTR lpstr32; // Ptr into a Source Unicode data block. + + VPVOID snbDest16s; // Seg:Ptr to 16 bit Destination SNB. + VPSTR UNALIGNED FAR *lpvpsTabDest16f; // Flat Ptr into 16 bit Dest ptr table. + char UNALIGNED *lpstrDest16f; // Flat Ptr into 16 bit Dest data block. + VPVOID lpstrDest16s; // Seg:Ptr into 16 bit Dest data block. + + UINT cPointers; // Count of number of string pointers. + UINT cbStrings; // Count of number of bytes in data table. + UINT cLength; + UINT cChars; + UINT cbAlloc; + UINT i; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SNB); + + fThopInput = IS_THOP_IN(pti); + fThopOutput = IS_THOP_OUT(pti); + + // + // We don't have anything but unmodified SNBs + // + thkAssert( !fThopInput && !fThopOutput && "SNB must be unmodified only!" ); + + GET_STACK32(pti, snbSrc32, LPOLESTR FAR *); + + if ( snbSrc32 == NULL ) + { + snbDest16s = 0; + } + else + { + // + // Count the strings in the 32-bit snb + // + lplpsTabSrc32 = snbSrc32; + + cPointers = 0; + cbStrings = 0; + do + { + cPointers++; + if (IsBadReadPtr(lplpsTabSrc32, sizeof(LPOLESTR))) + { + return (DWORD)E_INVALIDARG; + } + + lpstr32 = *lplpsTabSrc32++; + + if ( lpstr32 == NULL ) + { + break; + } + + if (IsBadStringPtrW(lpstr32, CCHMAXSTRING)) + { + return (DWORD)E_INVALIDARG; + } + + cbStrings += lstrlenW(lpstr32)+1; + } + while ( TRUE ); + + // + // Allocate a table for the 16-bit snb + // cPointers is a count of pointers plus the NULL pointer at the end. + // + cbAlloc = cPointers*sizeof(VPSTR)+cbStrings; + snbDest16s = (VPVOID)STACKALLOC16(cbAlloc); + if (snbDest16s == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + + // + // Set up the pointers to the destination table and string block. + // This gets a flat pointer to the pointer table, a both flat and + // segmented pointers to the data block. + // + lpvpsTabDest16f = (VPSTR UNALIGNED FAR *)WOWFIXVDMPTR( snbDest16s, cbAlloc ); + lpstrDest16f = (char UNALIGNED *) + ((BYTE UNALIGNED *)lpvpsTabDest16f+cPointers*sizeof(VPSTR)); + lpstrDest16s = (VPVOID)((DWORD)snbDest16s+cPointers*sizeof(VPSTR)); + + // + // Now convert the strings + // + cPointers -= 1; + lplpsTabSrc32 = snbSrc32; + for(i=0; i<cPointers; i++) + { + lpstr32 = *lplpsTabSrc32++; + + thkAssert( lpstr32 != NULL && "Loop is processing end of snb\n" ); + + cLength = lstrlenW( lpstr32 ) + 1; + + cChars = WideCharToMultiByte( AreFileApisANSI() ? CP_ACP : CP_OEMCP, + 0, lpstr32, cLength, + lpstrDest16f, cbStrings, NULL, NULL ); + + if ( cChars == 0 && cLength != 0 ) + { + WOWRELVDMPTR(snbDest16s); + STACKFREE16(snbDest16s, cbAlloc); + return (DWORD)E_UNEXPECTED; + } + + // + // Assign the Segmented pointer into the pointer table. + // + *lpvpsTabDest16f++ = lpstrDest16s; + + // + // Advance both the flat and segmented data pointers. + // + lpstrDest16f += cChars; + lpstrDest16s = (VPVOID)((DWORD)lpstrDest16s + cChars); + + // + // As we advance the Dest pointer the size of the remaining + // space in the buffer decreases. + // + cbStrings -= cChars; + } + + // Terminate SNB + *lpvpsTabDest16f = NULL; + + thkAssert( *lplpsTabSrc32 == NULL && + "Loop is out of sync with count\n" ); + + WOWRELVDMPTR(snbDest16s); + } + + thkDebugOut((DEB_ARGS, "In3216 SNB: %p -> %p\n", snbSrc32, snbDest16s)); + + TO_STACK16(pti, snbDest16s, VPVOID ); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + // + // Free SNB data if necessary + // + if ( snbDest16s != 0 ) + { + STACKFREE16( snbDest16s, cbAlloc ); + } + + return( dwResult ); +} + +//+--------------------------------------------------------------------------- +// +// Function: ThunkInterface3216, private +// +// Synopsis: Handles 32->16 interface thunking for THOP_IFACE and +// THOP_IFACEGEN +// +// Arguments: [pti] - Thunking state information +// [iidx] - Interface IID or index +// [thop] - Thop being executed +// [vpvOuter] - Controlling unknown or NULL +// +// Returns: Appropriate status code +// +// History: 01-Mar-94 DrewB Created +// +// Notes: Assumes pti->pThop is adjusted by caller +// +//---------------------------------------------------------------------------- + +DWORD ThunkInterface3216(THUNKINFO *pti, + IIDIDX iidx, + THOP thop, + VPVOID vpvOuter) +{ + DWORD dwResult; + void *pv; + VPVOID vpvOutParam; + VPVOID vpvThis16In, vpvThis16Out; + IUnknown *punkThis32; + IUnknown *punkIn; + THUNK3216OBJ *ptoPreAlloc = NULL; + + dwResult = (DWORD)S_OK; + + vpvOutParam = 0; + vpvThis16In = 0; + + // Retrieve in or out interface pointer + GET_STACK32(pti, pv, void *); + + // Out takes precedence over in for determining indirection depth + + if ((thop & THOP_OUT) != 0 && pv != NULL) + { + if (IsBadReadPtr(pv, sizeof(void *)) || + IsBadWritePtr(pv, sizeof(void *))) + { + thkDebugOut((DEB_WARN, "WARNING: failing - bad pointer %p\n", pv)); + return (DWORD)E_INVALIDARG; + } + else + { + punkIn = *(IUnknown **)pv; + } + } + else + { + punkIn = (IUnknown *)pv; + } + + if ((thop & THOP_IN) != 0) + { + if (punkIn == NULL) + { + vpvThis16In = 0; + } + else + { + if (!IsValidInterface(punkIn)) + { + dwResult = (DWORD)E_INVALIDARG; + thkDebugOut((DEB_WARN, "WARNING: failing - " + "invalid interface %p\n", punkIn)); + } + else + { + thkAssert(IIDIDX_IS_IID(iidx) || + (IIDIDX_INDEX(iidx) >= 0 && + IIDIDX_INDEX(iidx) < THI_COUNT)); + + // If the Interface is [In,Out] then we need to build a + // proxy with a "real" reference, rather than the + // "local" ref that is normally built for interfaces + // going [in]). Normaly only [out] parameters + // (which are build when the call is returning) have + // "real" references. + // To build a proxy with a "real" reference we trick + // "FindProxy1632" into believing it is building an + // [out] parameter. + THKSTATE thkstateSaved = pti->pThkMgr->GetThkState(); + + if ((thop & THOP_INOUT) == THOP_INOUT) + { + pti->pThkMgr->SetThkState(THKSTATE_INVOKETHKOUT16); + } + + vpvThis16In = pti->pThkMgr->FindProxy1632(NULL, punkIn, iidx, + NULL); + pti->pThkMgr->SetThkState(thkstateSaved); + + if (vpvThis16In == 0) + { + dwResult = (DWORD)E_OUTOFMEMORY; + thkDebugOut((DEB_WARN, "WARNING: failing - " + "Can't create proxy for %p\n", punkIn)); + } + } + } + + thkDebugOut((DEB_ARGS, "In3216 %s %p -> %p\n", + IidIdxString(iidx), punkIn, vpvThis16In)); + } + + if ((thop & THOP_OUT) != 0 && SUCCEEDED(dwResult) && pv != NULL) + { + thkAssert(IIDIDX_IS_IID(iidx) || + (IIDIDX_INDEX(iidx) >= 0 && + IIDIDX_INDEX(iidx) < THI_COUNT)); + + // Preallocate a proxy for the out parameter + if ((ptoPreAlloc = pti->pThkMgr->CanGetNewProxy3216(iidx)) == NULL) + { + dwResult = (DWORD)E_OUTOFMEMORY; + thkDebugOut((DEB_WARN, "WARNING: failing - " + "Cannot allocate proxy\n")); + } + else + { + vpvOutParam = STACKALLOC16(sizeof(VPVOID)); + if (vpvOutParam == 0) + { + dwResult = (DWORD)E_OUTOFMEMORY; + } + else + { + *FIXVDMPTR(vpvOutParam, VPVOID) = vpvThis16In; + RELVDMPTR(vpvOutParam); + TO_STACK16(pti, vpvOutParam, VPVOID); + } + } + } + else + { + TO_STACK16(pti, vpvThis16In, VPVOID); + } + + if (SUCCEEDED((SCODE)dwResult)) + { + // Assumes pThop is already adjusted + dwResult = EXECUTE_THOP3216(pti); + } + + if (vpvThis16In != 0) + { + // Note that if the routine called keeps the proxy around + // it should AddRef it so this won't really remove the object + pti->pThkMgr->FreeProxy1632(punkIn); + + if ((thop & THOP_OPMASK) == THOP_IFACECLEAN) + { + // IRpcStubBuffer::DebugServerQueryInterface returns an + // interface non-addref'ed + // IRpcStubBuffer::DebugServerRelease cleans up a returned + // pointer from QI, so for it we have to clean up the proxy + // from QI + + // We're assuming that punkIn is actually a proxy + pti->pThkMgr->ReleaseUnreferencedProxy3216((THUNK3216OBJ *)punkIn); + } + } + + if ((thop & THOP_OUT) != 0 && pv != NULL) + { + punkThis32 = NULL; + + if (SUCCEEDED((SCODE)dwResult)) + { + vpvThis16Out = *FIXVDMPTR(vpvOutParam, VPVOID); + RELVDMPTR(vpvOutParam); + + // BUGBUG - No easy way to check interface validity + // Requires a 16-bit transition + + if (vpvThis16Out != 0) + { + // Get a 32-bit proxy object for the 16-bit object + if (vpvOuter != 0) + { + punkThis32 = + pti->pThkMgr->FindAggregate3216(ptoPreAlloc, vpvOuter, + vpvThis16Out, iidx); + } + else + { + punkThis32 = + pti->pThkMgr->FindProxy3216(ptoPreAlloc, + vpvThis16Out, iidx, + NULL); + } + if (punkThis32 == NULL) + { + dwResult = (DWORD)E_UNEXPECTED; + } + } + } + else if (ptoPreAlloc != NULL) + { + // Return our preallocated proxy because we don't need it + pti->pThkMgr->FreeNewProxy3216(ptoPreAlloc, iidx); + } + + // Set the out param + *(void **)pv = (void *)punkThis32; + + thkDebugOut((DEB_ARGS, "Out3216 %s %p -> %p\n", + IidIdxString(iidx), vpvThis16Out, punkThis32)); + } + + if (vpvOutParam != 0) + { + STACKFREE16(vpvOutParam, sizeof(VPVOID)); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_IFACEGEN_3216, public +// +// Synopsis: Thunks riid,ppv pairs from 16->32 +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_IFACEGEN_3216(THUNKINFO *pti) +{ + IIDIDX iidx; + THOP thop, thopOp, thopWeakOffset; + VPVOID vpvOuter; + IID const *piid; + + thop = *pti->pThop++; + thopOp = thop & THOP_OPMASK; + + thkAssert(thopOp == THOP_IFACEGEN || + thopOp == THOP_IFACEGENOWNER); + + // The current thop byte indicates how many bytes to look + // back in the stack to find the IID which identifies the + // interface being returned + INDEX_STACK32(pti, piid, IID const *, *pti->pThop); + +#if DBG == 1 + if (!IsValidIid(*piid)) + { + return (DWORD)E_INVALIDARG; + } +#endif + + pti->pThop++; + + iidx = IidToIidIdx(*piid); + vpvOuter = 0; + if (thopOp == THOP_IFACEGENOWNER) + { + thopWeakOffset = *pti->pThop++; + INDEX_STACK16(pti, vpvOuter, VPVOID, thopWeakOffset, sizeof(DWORD)); + } + + return ThunkInterface3216(pti, iidx, thop, vpvOuter); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_OIFI_3216, public +// +// Synopsis: Convert OLEINPLACEFRAMEINFO +// +// Arguments: [pti] - Thunking state information +// +// Returns: Appropriate status code +// +// History: 26-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_OIFI_3216( THUNKINFO *pti ) +{ + DWORD dwResult; + VPVOID vpoifi16; + OIFI16 UNALIGNED *poifi16; + OLEINPLACEFRAMEINFO *poifi32; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_OIFI); + thkAssert((*pti->pThop & THOP_IOMASK) == THOP_OUT); + + // OIFIs are out-only parameters for their contents + // However, cb is in/out, so we need to copy cb on the way in + // Furthermore, cb may not be set to a valid value, in which + // case the documentation mentions that it should be assumed + // that this is an OLE 2.0 OIFI + // This thop simply ignores cb on the way in and always sets + // it to the OLE 2.0 size + // Since we're out-only, this always works since the number of + // fields we thunk is the size of the structure that we give out + // If OLEINPLACEFRAMEINFO is extended, this thop will break + + // Assert that OLEINPLACEFRAMEINFO is what we expect it to be + thkAssert(sizeof(OLEINPLACEFRAMEINFO) == 20); + + GET_STACK32(pti, poifi32, OLEINPLACEFRAMEINFO *); + + vpoifi16 = 0; + if (poifi32 != NULL) + { + if (IsBadWritePtr(poifi32, sizeof(OLEINPLACEFRAMEINFO))) + { + return (DWORD)E_INVALIDARG; + } + + vpoifi16 = STACKALLOC16(sizeof(OIFI16)); + if (vpoifi16 == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + + // OIFI's may be an out only parameters but if the "cb" field is + // "in" RPC doesn't slice up structs, so the whole thing is "in" + // as well. We are Thoping here but if we want this to match + // the RPC sematics then we need to copy all the fields. + + poifi16 = FIXVDMPTR(vpoifi16, OIFI16); + + poifi16->cb = sizeof(OIFI16); + poifi16->fMDIApp = (WORD)poifi32->fMDIApp; + poifi16->hwndFrame = HWND_16(poifi32->hwndFrame); + poifi16->cAccelEntries = + ClampULongToUShort(poifi32->cAccelEntries); + + if (poifi32->haccel == NULL) + { + poifi16->haccel = NULL; + } + else + { + // WOW will clean up any dangling accelerator tables when + // tasks die + poifi16->haccel = HACCEL_16(poifi32->haccel); + if (poifi16->haccel == NULL) + { + dwResult = (DWORD)E_UNEXPECTED; + } + } + + RELVDMPTR(vpoifi16); + } + + TO_STACK16(pti, vpoifi16, VPVOID); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if (vpoifi16 != NULL) + { + poifi16 = FIXVDMPTR(vpoifi16, OIFI16); + + if (SUCCEEDED(dwResult)) + { + poifi32->cb = sizeof(OLEINPLACEFRAMEINFO); + poifi32->fMDIApp = (BOOL)poifi16->fMDIApp; + poifi32->hwndFrame = HWND_32(poifi16->hwndFrame); + poifi32->cAccelEntries = (UINT)poifi16->cAccelEntries; + + if (poifi16->haccel == NULL) + { + poifi32->haccel = NULL; + } + else + { + // WOW will clean up any dangling accelerator tables when + // tasks die + + // Check that the haccel is valid. We don't need to lock + // the pointer. We just want some means of validating it. + // HACCEL_32 faults in krnl386 if the handle is bad. + + if(NULL != WOWGlobalLock16(poifi16->haccel)) + { + poifi32->haccel = HACCEL_32(poifi16->haccel); + WOWGlobalUnlock16(poifi16->haccel); + } + else + { + poifi32->haccel = NULL; + } + + if (poifi32->haccel == NULL) + { + dwResult = (DWORD)E_UNEXPECTED; + } + } + +#if DBG == 1 + if (SUCCEEDED(dwResult)) + { + thkDebugOut((DEB_ARGS, "Out3216 OIFI: " + "%p {%d, %d, 0x%04X, 0x%04X, %d} -> " + "%p {%d, %d, 0x%p, 0x%p, %d}\n", + vpoifi16, poifi16->cb, (BOOL)poifi16->fMDIApp, + (DWORD)poifi16->hwndFrame, (DWORD)poifi16->haccel, + poifi16->cAccelEntries, + poifi32, poifi32->cb, poifi32->fMDIApp, + poifi32->hwndFrame, poifi32->haccel, + poifi32->cAccelEntries)); + } +#endif + } + + RELVDMPTR(vpoifi16); + + if (FAILED(dwResult)) + { + memset(poifi32, 0, sizeof(OLEINPLACEFRAMEINFO)); + } + + STACKFREE16(vpoifi16, sizeof(OIFI16)); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_STGMEDIUM_3216, public +// +// Synopsis: Converts 32-bit STGMEDIUM to 16-bit STGMEDIUM returned +// structure +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_STGMEDIUM_3216(THUNKINFO *pti) +{ + DWORD dwResult; + BOOL fThopInput; + BOOL fThopOutput; + VPVOID vpstgmedium16; + STGMEDIUM *lpstgmedium32; + DWORD dwSize; + SCODE sc; + BOOL fReleaseParam; + BOOL fTransferOwnership; + FORMATETC *pfe; + THOP thopFeOffset; + DWORD vpIStream = 0; + STGMEDIUM UNALIGNED *psm16; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_STGMEDIUM); + + fThopInput = IS_THOP_IN(pti); + fThopOutput = IS_THOP_OUT(pti); + + // + // We currently don't have any unmodified or inout thops for STGMEDIUMs + // + thkAssert( (fThopInput || fThopOutput) && + (fThopInput != fThopOutput) && + "STGMEDIUM must be input or output only" ); + + // +2 thop byte indicates whether there's a FORMATETC to look at + // or not + // We need to reference this now before the stack is modified + // by argument recovery + thopFeOffset = *(pti->pThop+2); + if (thopFeOffset > 0) + { + INDEX_STACK32(pti, pfe, FORMATETC *, thopFeOffset); + } + else + { + pfe = NULL; + } + + GET_STACK32(pti, lpstgmedium32, STGMEDIUM FAR *); + + // Next thop byte indicates whether there's an ownership transfer + // argument or not + pti->pThop++; + fReleaseParam = (BOOL)*pti->pThop++; + + if (fReleaseParam) + { + GET_STACK32(pti, fTransferOwnership, BOOL); + } + else + { + fTransferOwnership = FALSE; + } + + // Skip FORMATETC offset thop + pti->pThop++; + + vpstgmedium16 = 0; + + if ( lpstgmedium32 != NULL ) + { + if ((fThopInput && IsBadReadPtr(lpstgmedium32, sizeof(STGMEDIUM))) || + (fThopOutput && IsBadWritePtr(lpstgmedium32, sizeof(STGMEDIUM)))) + { + return (DWORD)E_INVALIDARG; + } + + vpstgmedium16 = STACKALLOC16(sizeof(STGMEDIUM)); + if (vpstgmedium16 == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + + if ( fThopInput ) + { + sc = ConvertStgMed3216(pti, lpstgmedium32, vpstgmedium16, + pfe, fTransferOwnership, &dwSize); + if (SUCCEEDED(sc)) + { + // Apparently if you pass TYMED_NULL into GetDataHere + // it's supposed to work like GetData, so switch input-only + // TYMED_NULLs to output + if (lpstgmedium32->tymed == TYMED_NULL && + !fTransferOwnership) + { + fThopInput = FALSE; + fThopOutput = TRUE; + } + else if (lpstgmedium32->tymed == TYMED_ISTREAM) + { + // + // Excel has a bug in its Clipboard data object that when + // GetDataHere is done providing a IStream interface, it + // will create its own stream and pounce on the pointer + // being passed in. So, if the thing is input, and the + // TYMED is ISTREAM we need to stash away the original + // 16-bit stream pointer for use later. + // + psm16 = FIXVDMPTR(vpstgmedium16, STGMEDIUM); + vpIStream = (DWORD)psm16->pstm; + RELVDMPTR(vpstgmedium16); + } + } + else + { + STACKFREE16(vpstgmedium16, sizeof(STGMEDIUM)); + return (DWORD)sc; + } + + } + else + { + if( !((TlsThkGetAppCompatFlags() & OACF_CORELTRASHMEM) && + lpstgmedium32->tymed == 0x66666666 )) + { + + // Even though this is an out parameter, some apps + // (Graph 5 is one) check its values and depend on it + // being zeroed out + + // However, if we are in CorelDraw *and* we're being + // called by wGetMonikerAndClassFromObject (tymed set to + // all 6's), then we do not want to set the tymed to zero. + // Corel5 relies on the memory being trashed in order to + // prevent paste-link-to-yourself. + + memset(FIXVDMPTR(vpstgmedium16, STGMEDIUM), 0, + sizeof(STGMEDIUM)); + RELVDMPTR(vpstgmedium16); + } + + } + } + + TO_STACK16(pti, vpstgmedium16, VPVOID); + + if (fReleaseParam) + { + TO_STACK16(pti, (SHORT)fTransferOwnership, SHORT); + } + + dwResult = EXECUTE_THOP3216(pti); + + if (lpstgmedium32 != NULL) + { + if (fThopInput) + { + + if (SUCCEEDED(dwResult) && + (lpstgmedium32->tymed == TYMED_ISTREAM) && + (vpIStream != 0)) + { + // + // To continue our Excel Clipboard GetDataHere hack, if the + // TYMED was ISTREAM, and the medium was input (as it is now) + // then we need to detect the case where the IStream pointer + // changed. If it did change, then we have a special function + // in the 16-bit world that will copy the contents of the + // 'new' stream into 'our' stream, and release the 'new' + // stream. This should make the clipboard work properly. + // + psm16 = FIXVDMPTR(vpstgmedium16, STGMEDIUM); + if( (psm16->tymed == TYMED_ISTREAM) && + (vpIStream != (DWORD)psm16->pstm)) + { + BYTE b32Args[WCB16_MAX_CBARGS]; + *(DWORD *)&b32Args[0] = vpIStream; + *(DWORD *)&b32Args[sizeof(DWORD)] = (DWORD)psm16->pstm; + + RELVDMPTR(vpstgmedium16); + + if( !CallbackTo16Ex( + (DWORD)gdata16Data.fnStgMediumStreamHandler16, + WCB16_PASCAL, + 2*sizeof(DWORD), + b32Args, + &dwResult) ) + { + dwResult = (DWORD)E_UNEXPECTED; + } + + } + else + { + // + // Two possibilites + // The stream pointers are the same. Good news + // The tymed was changed. Bad news. There isn't anything + // we can safely do with the different tymed, so ignore + // the whole thing. + // + + RELVDMPTR(vpstgmedium16); + } + } + + + if (!fTransferOwnership || FAILED(dwResult)) + { + sc = CleanStgMed16(pti, vpstgmedium16, lpstgmedium32, + dwSize, TRUE, pfe); + if (FAILED(sc)) + { + dwResult = (DWORD)sc; + } + } + else if (SUCCEEDED(dwResult)) + { + + if (lpstgmedium32->pUnkForRelease == NULL) + { + sc = CleanStgMed32(pti, lpstgmedium32, vpstgmedium16, + 0, FALSE, pfe); + thkAssert(SUCCEEDED(sc)); + } + } + } + else + { + thkAssert(fThopOutput); + + if (SUCCEEDED(dwResult)) + { + sc = ConvertStgMed1632(pti, vpstgmedium16, lpstgmedium32, + pfe, FALSE, &dwSize); + if (FAILED(sc)) + { + dwResult = (DWORD)sc; + CallbackTo16(gdata16Data.fnReleaseStgMedium16, + vpstgmedium16); + } + else if (lpstgmedium32->pUnkForRelease == NULL) + { + sc = CleanStgMed16(pti, vpstgmedium16, lpstgmedium32, + dwSize, FALSE, pfe); + thkAssert(SUCCEEDED(sc)); + } + } + + if (FAILED(dwResult)) + { + memset(lpstgmedium32, 0, sizeof(STGMEDIUM)); + } + } + } + + if (vpstgmedium16 != 0) + { + STACKFREE16(vpstgmedium16, sizeof(STGMEDIUM)); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertStatStg1632, public +// +// Synopsis: Converts a STATSTG +// +// Arguments: [pti] - Thunk info +// [vpss16] - STATSTG +// [pss32] - STATSTG +// [posPreAlloc] - Preallocated string memory or NULL +// [cchPreAlloc] - Amount preallocated +// +// Returns: Appropriate status code +// +// Modifies: [pss32] +// +// History: 14-May-94 DrewB Created +// +// Notes: Assumes input STATSTG memory is valid +// Assumes task memory for the string +// +//---------------------------------------------------------------------------- + +SCODE ConvertStatStg1632(THUNKINFO *pti, + VPVOID vpss16, + STATSTG *pss32, + LPOLESTR posPreAlloc, + UINT cchPreAlloc) +{ + STATSTG UNALIGNED *pss16; + SCODE sc; + LPOLESTR pos32; + VPSTR vpstr; + + pss16 = FIXVDMPTR(vpss16, STATSTG); + vpstr = (VPSTR)pss16->pwcsName; + RELVDMPTR(vpss16); + + sc = ConvertTaskString1632(pti, vpstr, + posPreAlloc, cchPreAlloc, + &pos32); + + if (SUCCEEDED(sc)) + { + pss16 = FIXVDMPTR(vpss16, STATSTG); + memcpy(pss32, pss16, sizeof(STATSTG)); + pss32->pwcsName = pos32; + RELVDMPTR(vpss16); + } + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_STATSTG_3216, public +// +// Synopsis: Converts 32-bit STATSTG to 16-bit STATSTG returned structure +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_STATSTG_3216( THUNKINFO *pti ) +{ + DWORD dwResult; + STATSTG *lpstatstg32; + VPVOID vpstatstg16; + LPOLESTR lpstr32; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_STATSTG); + + // + // We currently don't have any input thops for STATSTGs + // + thkAssert( (*pti->pThop & THOP_IOMASK) == THOP_OUT && + "STATSTG must be output only" ); + + GET_STACK32(pti, lpstatstg32, STATSTG FAR *); + + if (IsBadWritePtr(lpstatstg32, sizeof(STATSTG))) + { + return (DWORD)E_INVALIDARG; + } + + vpstatstg16 = STACKALLOC16(sizeof(STATSTG)); + if (vpstatstg16 == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + + lpstr32 = (LPOLESTR)TaskMalloc32(CBSTRINGPREALLOC); + if (lpstr32 == NULL) + { + STACKFREE16(vpstatstg16, sizeof(STATSTG)); + return (DWORD)E_OUTOFMEMORY; + } + + TO_STACK16(pti, vpstatstg16, VPVOID); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if (SUCCEEDED(dwResult)) + { + SCODE sc; + + sc = ConvertStatStg1632(pti, vpstatstg16, lpstatstg32, + lpstr32, CWCSTRINGPREALLOC); + if (FAILED(sc)) + { + dwResult = sc; + } + } + + if (FAILED(dwResult)) + { + TaskFree32(lpstr32); + + memset(lpstatstg32, 0, sizeof(STATSTG)); + } + + STACKFREE16(vpstatstg16, sizeof(STATSTG)); + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_DVTARGETDEVICE_3216, public +// +// Synopsis: Converts 16-bit DVTARGETDEVICE to 32-bit DVTARGETDEVICE +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_DVTARGETDEVICE_3216( THUNKINFO *pti ) +{ + DWORD dwResult; + UINT uiSize; + DVTARGETDEVICE FAR *lpdv32; + VPVOID vpdv16; + SCODE sc; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_DVTARGETDEVICE); + + // + // We currently don't have any output thops for DVTARGETDEVICEs + // + thkAssert( (*pti->pThop & THOP_IOMASK) == THOP_IN && + "DVTARGETDEVICE must be input only" ); + + // + // Processing for a DVTARGETDEVICE FAR * as input + // + GET_STACK32(pti, lpdv32, DVTARGETDEVICE FAR *); + + vpdv16 = 0; + + if ( lpdv32 != NULL ) + { + sc = ConvertDvtd3216(pti, lpdv32, ArStack16, FrStack16, &vpdv16, + &uiSize); + if (FAILED(sc)) + { + return (DWORD)sc; + } + } + + TO_STACK16(pti, vpdv16, VPVOID); + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if ( lpdv32 != NULL ) + { + FrStack16((void *)vpdv16, uiSize); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_FORMATETC_3216, public +// +// Synopsis: Converts 16-bit FORMATETC to 32-bit FORMATETC and back +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 24-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_FORMATETC_3216( THUNKINFO *pti ) +{ + DWORD dwResult; + BOOL fThopInput; + BOOL fThopOutput; + VPVOID vpformatetc16; + FORMATETC16 UNALIGNED *lpformatetc16; + LPFORMATETC lpformatetc32; + VPVOID vpdv16; + SCODE sc; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_FORMATETC); + + fThopInput = IS_THOP_IN(pti); + fThopOutput = IS_THOP_OUT(pti); + + vpdv16 = 0; + + // + // We have only input or output thops + // + thkAssert( (fThopInput || fThopOutput) && + (fThopInput != fThopOutput) && + "formatetc must be input or output only" ); + + GET_STACK32(pti, lpformatetc32, LPFORMATETC); + + if ( lpformatetc32 == NULL ) + { + vpformatetc16 = 0; + } + else + { + if ((fThopInput && IsBadReadPtr(lpformatetc32, sizeof(LPFORMATETC))) || + (fThopOutput && IsBadWritePtr(lpformatetc32, sizeof(LPFORMATETC)))) + { + return (DWORD)E_INVALIDARG; + } + + vpformatetc16 = STACKALLOC16(sizeof(FORMATETC16)); + if (vpformatetc16 == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + + if ( fThopInput ) + { + sc = ConvertFetc3216(pti, lpformatetc32, vpformatetc16, FALSE); + if (FAILED(sc)) + { + STACKFREE16(vpformatetc16, sizeof(FORMATETC16)); + return (DWORD)sc; + } + } + else + { + thkAssert( fThopOutput ); + + // + // The below memset is needed at least for the DATA_S_SAMEFORMATETC + // case. This allows it to be cleaned up because all its pointers + // will be null. + // + lpformatetc16 = FIXVDMPTR(vpformatetc16, FORMATETC16); + memset(lpformatetc16, 0, sizeof(FORMATETC16) ); + RELVDMPTR(vpformatetc16); + } + } + + TO_STACK16(pti, vpformatetc16, VPVOID); + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if (fThopInput && vpformatetc16 != 0) + { + VPVOID vptd; + + lpformatetc16 = FIXVDMPTR(vpformatetc16, FORMATETC16); + vptd = (VPVOID)lpformatetc16->ptd; + RELVDMPTR(vpformatetc16); + + if (vptd != 0) + { + TaskFree16(vptd); + } + } + + if ( fThopOutput && lpformatetc32 != NULL) + { + if (SUCCEEDED(dwResult)) + { + sc = ConvertFetc1632(pti, vpformatetc16, lpformatetc32, TRUE); + if (FAILED(sc)) + { + dwResult = sc; + } + } + + if (FAILED(dwResult)) + { + memset(lpformatetc32, 0, sizeof(FORMATETC)); + } + } + + if (vpformatetc16 != 0) + { + STACKFREE16(vpformatetc16, sizeof(FORMATETC16)); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_LOGPALETTE_3216, public +// +// Synopsis: Converts 16-bit LOGPALLETE to 32-bit LOGPALETTE +// and converts 32-bit LOGPALETTE returned to 16-bit structure +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_LOGPALETTE_3216 ( THUNKINFO *pti ) +{ + DWORD dwResult; + UINT uiSize; + LPLOGPALETTE lplogpal32; + VPVOID vplogpal16; + LOGPALETTE UNALIGNED *lplogpal16; + LPLOGPALETTE *lplplogpal32; + VPVOID vpvplogpal16; + VPVOID UNALIGNED *lpvplogpal16; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_LOGPALETTE); + + // + // It must be either an input or output LOGPALETTE + // + thkAssert( ((*pti->pThop & THOP_IOMASK) == THOP_IN || + (*pti->pThop & THOP_IOMASK) == THOP_OUT) && + "Hey, LOGPALETTE can't be input and output!" ); + + if ( (*pti->pThop & THOP_IN) != 0 ) + { + // + // Processing for a LPLOGPALETTE as input + // + GET_STACK32(pti, lplogpal32, LPLOGPALETTE); + + if ( lplogpal32 == NULL ) + { + vplogpal16 = 0; + } + else + { + if (IsBadReadPtr(lplogpal32, sizeof(LOGPALETTE))) + { + return (DWORD)E_INVALIDARG; + } + + uiSize = CBPALETTE(lplogpal32->palNumEntries); + + if (IsBadReadPtr(lplogpal32, uiSize)) + { + return (DWORD)E_INVALIDARG; + } + + vplogpal16 = STACKALLOC16(uiSize); + if (vplogpal16 == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + + lplogpal16 = (LOGPALETTE UNALIGNED *) + WOWFIXVDMPTR( vplogpal16, uiSize ); + + memcpy( lplogpal16, lplogpal32, uiSize ); + + WOWRELVDMPTR(vplogpal16); + } + + TO_STACK16(pti, vplogpal16, VPVOID); + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if ( vplogpal16 != 0 ) + { + STACKFREE16(vplogpal16, uiSize); + } + } + else + { + // + // Processing for LPLPLOGPALETTE as output + // + thkAssert((*pti->pThop & THOP_OUT) != 0); + + GET_STACK32(pti, lplplogpal32, LPLOGPALETTE FAR *); + if (IsBadWritePtr(lplplogpal32, sizeof(LPLOGPALETTE))) + { + return (DWORD)E_INVALIDARG; + } + + vpvplogpal16 = (VPVOID)STACKALLOC16(sizeof(LPLOGPALETTE)); + if (vpvplogpal16 == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + + lplogpal32 = (LPLOGPALETTE)TaskMalloc32(CBPALETTE(NPALETTEPREALLOC)); + if (lplogpal32 == NULL) + { + STACKFREE16(vpvplogpal16, sizeof(LPLOGPALETTE)); + return (DWORD)E_OUTOFMEMORY; + } + + // + // We DO need to zero out the pointer on the way in. + // + *FIXVDMPTR(vpvplogpal16, LPLOGPALETTE) = 0; + RELVDMPTR(vpvplogpal16); + + TO_STACK16(pti, vpvplogpal16, VPVOID); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if (SUCCEEDED(dwResult)) + { + lpvplogpal16 = FIXVDMPTR( vpvplogpal16, VPVOID); + vplogpal16 = *lpvplogpal16; + RELVDMPTR(vpvplogpal16); + + if ( vplogpal16 == 0 ) + { + TaskFree32(lplogpal32); + lplogpal32 = NULL; + } + else + { + lplogpal16 = FIXVDMPTR( vplogpal16, LOGPALETTE ); + + // + // Copy the returned LOGPALETTE into 16-bit memory + // + uiSize = CBPALETTE(lplogpal16->palNumEntries); + if (uiSize > CBPALETTE(NPALETTEPREALLOC)) + { + TaskFree32(lplogpal32); + + lplogpal32 = (LPLOGPALETTE)TaskMalloc32(uiSize); + if ( lplogpal32 == NULL ) + { + dwResult = (DWORD)E_OUTOFMEMORY; + } + } + + if (lplogpal32 != NULL) + { + memcpy( lplogpal32, lplogpal16, uiSize ); + } + + RELVDMPTR(vplogpal16); + + TaskFree16( vplogpal16 ); + } + } + else + { + TaskFree32(lplogpal32); + lplogpal32 = NULL; + } + + // + // Update the value pointed to by the parameter on the 16-bit stack + // + *lplplogpal32 = lplogpal32; + + if (vpvplogpal16 != 0) + { + STACKFREE16(vpvplogpal16, sizeof(LPLOGPALETTE)); + } + } + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_CRGIID_3216, public +// +// Synopsis: Converts 32-bit CRGIID to 16-bit CRGIID structure +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- +DWORD Thop_CRGIID_3216( THUNKINFO *pti ) +{ + DWORD dwResult; + DWORD dwCount; + VPVOID vpiid16; + IID UNALIGNED *lpiid16; + IID *lpiid32; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_CRGIID); + + // + // We currently don't have any output thops for CRGIIDs + // + thkAssert( (*pti->pThop & THOP_IOMASK) == 0 && + "CRGIID must be unmodified only" ); + + GET_STACK32(pti, dwCount, DWORD); + GET_STACK32(pti, lpiid32, IID FAR *); + + if ( lpiid32 == NULL ) + { + vpiid16 = 0; + } + else + { + if (IsBadReadPtr(lpiid32, dwCount*sizeof(IID))) + { + return (DWORD)E_INVALIDARG; + } + + vpiid16 = STACKALLOC16( dwCount * sizeof(IID) ); + if (vpiid16 == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + + lpiid16 = (IID UNALIGNED *) + WOWFIXVDMPTR( vpiid16, dwCount*sizeof(IID) ); + + memcpy( lpiid16, lpiid32, dwCount*sizeof(IID) ); + + WOWRELVDMPTR(vpiid16); + } + + TO_STACK16(pti, dwCount, DWORD); + TO_STACK16(pti, vpiid16, VPVOID); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if ( vpiid16 != 0 ) + { + STACKFREE16( vpiid16, dwCount * sizeof(IID) ); + } + return( dwResult ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_INTERFACEINFO_3216, public +// +// Synopsis: Converts an INTERFACEINFO +// +// Arguments: [pti] - Thunking state information +// +// Returns: Appropriate status code +// +// History: 19-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_INTERFACEINFO_3216(THUNKINFO *pti) +{ + INTERFACEINFO *pii32; + INTERFACEINFO16 UNALIGNED *pii16; + VPVOID vpii16; + DWORD dwResult; + VPVOID vpunk16; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_INTERFACEINFO); + thkAssert((*pti->pThop & THOP_INOUT) == THOP_IN); + + vpunk16 = 0; + + GET_STACK32(pti, pii32, INTERFACEINFO *); + if (pii32 == NULL) + { + vpii16 = 0; + } + else + { + if (IsBadReadPtr(pii32, sizeof(INTERFACEINFO))) + { + return (DWORD)E_INVALIDARG; + } + + vpii16 = STACKALLOC16(sizeof(INTERFACEINFO16)); + if (vpii16 == 0) + { + return (DWORD)E_OUTOFMEMORY; + } + + if (pii32->pUnk != NULL) + { + vpunk16 = pti->pThkMgr->FindProxy1632(NULL, pii32->pUnk, + INDEX_IIDIDX(THI_IUnknown), + NULL); + if (vpunk16 == 0) + { + STACKFREE16(vpii16, sizeof(INTERFACEINFO16)); + return (DWORD)E_OUTOFMEMORY; + } + } + + pii16 = FIXVDMPTR(vpii16, INTERFACEINFO16); + pii16->pUnk = vpunk16; + pii16->iid = pii32->iid; + pii16->wMethod = pii32->wMethod; + + thkDebugOut((DEB_ARGS, + "In3216 INTERFACEINFO: %p -> %p {%p (%p), %s, %u}\n", + pii32, vpii16, pii16->pUnk, pii32->pUnk, + IidOrInterfaceString(&pii16->iid), pii16->wMethod)); + + RELVDMPTR(vpii16); + } + + TO_STACK16(pti, vpii16, VPVOID); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + if (vpunk16 != 0) + { + pti->pThkMgr->FreeProxy1632(pii32->pUnk); + } + + if (vpii16 != 0) + { + STACKFREE16(vpii16, sizeof(INTERFACEINFO16)); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_RETURNTYPE_3216, public +// +// Synopsis: Thunks the return value of a call +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 24-Feb-94 DrewB Created +// +// Notes: This thunk assumes that the return value will always fit +// in 32 bits and that the thops for it are only one thop +// long. This fits the existing APIs and methods +// +//---------------------------------------------------------------------------- + +DWORD Thop_RETURNTYPE_3216(THUNKINFO *pti) +{ + THOP thops[2]; + DWORD dwResult; + THUNK3216OBJ *ptoPreAlloc = NULL; + IIDIDX iidx; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_RETURNTYPE); + thkAssert((*pti->pThop & THOP_IOMASK) == 0); + + pti->fResultThunked = TRUE; + + pti->pThop++; + + // Remember return type thop + thops[0] = *pti->pThop++; + if ((thops[0] & THOP_OPMASK) == THOP_COPY || + (thops[0] & THOP_OPMASK) == THOP_IFACE || + (thops[0] & THOP_OPMASK) == THOP_ALIAS32) + { + thops[1] = *pti->pThop++; + } + + // Preallocate any necessary resources + switch(thops[0]) + { + case THOP_IFACE | THOP_IN: + iidx = INDEX_IIDIDX(thops[1]); + if ((ptoPreAlloc = pti->pThkMgr->CanGetNewProxy3216(iidx)) == NULL) + { + return (DWORD)E_OUTOFMEMORY; + } + break; + } + + dwResult = EXECUTE_THOP3216(pti); + + // Now that we have the return value thunk it from 16->32 + + switch(thops[0]) + { + case THOP_COPY: + // Only handle DWORD copies + thkAssert(thops[1] == sizeof(DWORD)); + break; + + case THOP_SHORTLONG: + // For boolean results, not necessary to clamp + dwResult = (DWORD)(LONG)*(SHORT *)&dwResult; + break; + + case THOP_IFACE | THOP_IN: + if (dwResult != 0) + { + // BUGBUG - What if another thop failed and returned an HRESULT? + // This will break + dwResult = + (DWORD)pti->pThkMgr->FindProxy3216(ptoPreAlloc, dwResult, + iidx, NULL); + thkAssert(dwResult != 0); + + thkDebugOut((DEB_ARGS, "Ret3216 %s %p\n", + inInterfaceNames[thops[1]].pszInterface, + dwResult)); + } + else + { + pti->pThkMgr->FreeNewProxy3216(ptoPreAlloc, iidx); + } + break; + + default: + thkAssert(!"Unhandled 3216 return type"); + break; + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_IFACE_3216, public +// +// Synopsis: Thunks a known interface pointer +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 24-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_IFACE_3216(THUNKINFO *pti) +{ + IIDIDX iidx; + THOP thop, thopOp, thopWeakOffset; + VPVOID vpvOuter; + + thop = *pti->pThop++; + thopOp = thop & THOP_OPMASK; + + thkAssert( thopOp == THOP_IFACE + || thopOp == THOP_IFACEOWNER + || thopOp == THOP_IFACECLEAN); + + iidx = INDEX_IIDIDX(*pti->pThop++); + // There's a bit of a special case here in that IMalloc is + // not thunked so it doesn't have a real index but it's used + // in thop strings so it has a fake index to function as a placeholder + // The fake index is THI_COUNT so allow that in the assert + thkAssert(IIDIDX_INDEX(iidx) >= 0 && IIDIDX_INDEX(iidx) <= THI_COUNT); + + vpvOuter = 0; + if (thopOp == THOP_IFACEOWNER) + { + // For cases where the controlling unknown is known, + // index back on the stack and find the 32-bit unknown + // pointer to use + thopWeakOffset = *pti->pThop++; + + INDEX_STACK16(pti, vpvOuter, VPVOID, thopWeakOffset, sizeof(DWORD)); + + } + + return ThunkInterface3216(pti, iidx, thop, vpvOuter); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_ALIAS32_3216, public +// +// Synopsis: Handles 16-bit aliases to 32-bit quantities +// +// Arguments: [pti] - Thunking state information +// +// Returns: Appropriate status code +// +// History: 27-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_ALIAS32_3216(THUNKINFO *pti) +{ + ALIAS alias; + DWORD dwValue; + THOP thopAction; + BOOL fTemporary = FALSE; + DWORD dwResult; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_ALIAS32); + thkAssert((*pti->pThop & THOP_IOMASK) == 0); + + pti->pThop++; + + GET_STACK32(pti, dwValue, DWORD); + + // Second byte indicates how the alias should be handled + thopAction = *pti->pThop++; + + if (dwValue != 0) + { + switch(thopAction) + { + case ALIAS_RESOLVE: + alias = gAliases32.ValueAlias(dwValue); + + // There may be cases where there is no existing alias + // for a value (for example, remoted SetMenu calls where + // the HOLEMENU is a temporary RPC object) + // so create a temporary one + if (alias == INVALID_ALIAS) + { + alias = gAliases32.AddValue(dwValue); + if (alias == INVALID_ALIAS) + { + return (DWORD)E_OUTOFMEMORY; + } + + fTemporary = TRUE; + } + break; + + default: + thkAssert(!"Default hit in Thop_ALIAS32_3216"); + break; + } + } + else + { + alias = 0; + } + + thkDebugOut((DEB_ARGS, "In3216 ALIAS32: 0x%08lX -> 0x%04X\n", + dwValue, alias)); + + TO_STACK16(pti, alias, ALIAS); + + dwResult = EXECUTE_THOP3216(pti); + + if (fTemporary) + { + gAliases32.RemoveAlias(alias); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_RPCOLEMESSAGE_3216, public +// +// Synopsis: Converts 32-bit RPCOLEMESSAGE to 16-bit RPCOLEMESSAGE +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 23-Feb-94 JohannP Created +// +//---------------------------------------------------------------------------- +DWORD Thop_RPCOLEMESSAGE_3216( THUNKINFO *pti ) +{ + DWORD dwResult; + PRPCOLEMESSAGE prom32; + VPVOID vprom16; + RPCOLEMESSAGE UNALIGNED *prom16; + VPVOID vpvBuffer16; + LPVOID lp16; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_RPCOLEMESSAGE); + + // + // We currently have only IN/OUT RPCOLEMESSAGE + // + thkAssert( (*pti->pThop & THOP_IOMASK) == (THOP_IN | THOP_OUT) && + "RPCOLEMESSAGE must be input/output only" ); + + vprom16 = 0; + vpvBuffer16 = 0; + + // + // Processing for a RPCOLEMESSAGE FAR * as input/output + // + GET_STACK32(pti, prom32, RPCOLEMESSAGE *); + if ( prom32 != 0 ) + { + // Copy over the input RPCOLEMESSAGE structure + + vprom16 = STACKALLOC16(sizeof(RPCOLEMESSAGE)); + if (vprom16 == NULL) + { + return (DWORD)E_OUTOFMEMORY; + } + + prom16 = FIXVDMPTR(vprom16, RPCOLEMESSAGE); + *prom16 = *prom32; + ROM_THUNK_FIELD(prom16) = (void *)prom32; + RELVDMPTR(vprom16); + + // If there's a buffer, copy it + if (prom32->cbBuffer != 0) + { + vpvBuffer16 = TaskMalloc16(prom32->cbBuffer); + if (vpvBuffer16 == NULL) + { + STACKFREE16(vprom16, sizeof(RPCOLEMESSAGE)); + return (DWORD)E_OUTOFMEMORY; + } + + prom16 = FIXVDMPTR(vprom16, RPCOLEMESSAGE); + prom16->Buffer = (LPVOID) vpvBuffer16; + lp16 = (LPVOID)WOWFIXVDMPTR(vpvBuffer16, prom32->cbBuffer); + memcpy( lp16, prom32->Buffer, prom32->cbBuffer ); + WOWRELVDMPTR(vpvBuffer16); + RELVDMPTR(vprom16); + } + } + + TO_STACK16(pti, vprom16, VPVOID); + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + + prom16 = (PRPCOLEMESSAGE)FIXVDMPTR(vprom16, RPCOLEMESSAGE); + if (prom16 == NULL) + { + dwResult = (DWORD)E_UNEXPECTED; + } + else + { + VPVOID vpvBuffer; + + vpvBuffer = (VPVOID)prom16->Buffer; + RELVDMPTR(vprom16); + + if (SUCCEEDED(dwResult)) + { + if ( prom32->Buffer != NULL ) + { + lp16 = (LPVOID)WOWFIXVDMPTR(vpvBuffer, prom16->cbBuffer); + if (lp16 == NULL) + { + dwResult = (DWORD)E_UNEXPECTED; + } + else + { + memcpy( prom32->Buffer, lp16, prom16->cbBuffer ); + + WOWRELVDMPTR(vpvBuffer); + } + } + } + + if ( vpvBuffer16 != 0 ) + { + // We'd better have a buffer at this point + thkAssert( vpvBuffer != 0); + + // Free up the buffer that we've been dealing with + TaskFree16(vpvBuffer); + } + } + + if ( vprom16 != 0 ) + { + STACKFREE16(vprom16, sizeof(RPCOLEMESSAGE)); + } + + return dwResult; +} + + +//+--------------------------------------------------------------------------- +// +// Function: Thop_ENUM_3216, public +// +// Synopsis: Thunks Enum::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is the start of a 2-byte thop. The next thop +// byte references a function in the enumerator table, rather +// than the standard thop table. +// +//---------------------------------------------------------------------------- + +DWORD Thop_ENUM_3216(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_ENUM); + thkAssert((*pti->pThop & THOP_IOMASK) == 0); + + // + // Get then next thop byte and execute it as a Enum thop + // + pti->pThop++; + return EXECUTE_ENUMTHOP3216(pti); +} + +//+--------------------------------------------------------------------------- +// +// Function: CallbackProcessing_3216, public +// +// Synopsis: Thunks IOleObject::Draw pfnContinue & DWORD parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 3-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- +typedef struct tagCallbackControl +{ + DWORD dwContinue; + LPVOID lpfn32; +} CALLBACKCONTROL; + + +STDAPI_(BOOL) CallbackProcessing_3216( DWORD dwContinue, DWORD dw1, DWORD dw2 ) +{ + BOOL fResult; + CALLBACKCONTROL *lpcbc; + BOOL (*lpfn32)(DWORD); + + lpcbc = (CALLBACKCONTROL *)dwContinue; + + lpfn32 = (BOOL (*)(DWORD))lpcbc->lpfn32; + + fResult = (*lpfn32)(lpcbc->dwContinue); + + if ( fResult ) // This maps DWORD sized BOOLs into WORD sized BOOLs + { + return TRUE; + } + else + { + return FALSE; + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_CALLBACK_3216, public +// +// Synopsis: Thunks IOleObject::Draw pfnContinue & DWORD parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 3-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_CALLBACK_3216(THUNKINFO *pti) +{ + LPVOID lpfn32; + DWORD dwContinue; + CALLBACKCONTROL cbc; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_CALLBACK); + thkAssert((*pti->pThop & THOP_IOMASK) == 0); + + GET_STACK32(pti, lpfn32, LPVOID); + GET_STACK32(pti, dwContinue, DWORD); + + if ( lpfn32 == 0 ) + { + TO_STACK16(pti, NULL, VPVOID); + TO_STACK16(pti, dwContinue, DWORD); + } + else + { + cbc.lpfn32 = lpfn32; + cbc.dwContinue = dwContinue; + + TO_STACK16(pti, gdata16Data.fnCallbackHandler, DWORD); + TO_STACK16(pti, (DWORD)&cbc, DWORD); + } + + pti->pThop++; + return EXECUTE_THOP3216(pti); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_CLSCONTEXT_3216, public +// +// Synopsis: Converts a class context flags DWORD +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 29-Jun-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_CLSCONTEXT_3216(THUNKINFO *pti) +{ + DWORD dwClsContext; + + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_CLSCONTEXT); + thkAssert((*pti->pThop & THOP_IOMASK) == 0); + + // When passing a 32-bit class context to 16-bits nothing + // nothing special needs to be done + + GET_STACK32(pti, dwClsContext, DWORD); + TO_STACK16(pti, dwClsContext, DWORD); + + pti->pThop++; + return EXECUTE_THOP3216(pti); +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_FILENAME_3216, public +// +// Synopsis: Converts a filename string +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 24-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_FILENAME_3216(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_FILENAME); + + // Can be in or out only + thkAssert((*pti->pThop & THOP_IOMASK) == THOP_IN || + (*pti->pThop & THOP_IOMASK) == THOP_OUT); + + if ((*pti->pThop & THOP_IN) != 0) + { + // Convert filenames going from 32->16 to short filenames + // to avoid any possible problems with non-8.3 names. + + return ThunkInString3216(pti, TRUE, 0); + } + else + { + thkAssert((*pti->pThop & THOP_OUT) != 0); + + // No special processing is necessary for filenames going + // from 16->32 since it isn't possible for 16-bit code to + // generate a filename which can't be handled in 32-bits + + return ThunkOutString3216(pti); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_SIZEDSTRING_3216, public +// +// Synopsis: Converts strings which cannot exceed a given length +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 02-Sep-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD Thop_SIZEDSTRING_3216(THUNKINFO *pti) +{ + thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SIZEDSTRING); + thkAssert((*pti->pThop & THOP_IOMASK) == THOP_IN); + + // Advance once to account for the length byte + // ThunkInString will advance again + pti->pThop++; + return ThunkInString3216(pti, FALSE, *pti->pThop); +} + +#define THOP_FN(x) Thop_ ## x ## _3216 + +DWORD (* CONST aThopFunctions3216[])(THUNKINFO *) = +{ + + // x = Implemented + // ? = Mysteriously not needed + // = Left to do + // + // ^ + // | + // +===+ + // | + // v + // + ThunkCall3216, // x Terminating THOP + Thop_ShortToLong_3216, // x SHORTLONG + Thop_WordToDword_3216, // x WORDDWORD + Thop_Copy_3216, // x COPY + THOP_FN(LPSTR), // x LPSTR + THOP_FN(LPLPSTR), // x LPLPSTR + THOP_FN(BUFFER), // x BUFFER + Thop_UserHandle_3216, // x HUSER + Thop_GdiHandle_3216, // x HGDI + THOP_FN(SIZE), // x SIZE + THOP_FN(RECT), // x RECT + THOP_FN(MSG), // x MSG + THOP_FN(HRESULT), // x HRESULT + THOP_FN(STATSTG), // x STATSTG + THOP_FN(DVTARGETDEVICE), // x DVTARGETDEVICE + THOP_FN(STGMEDIUM), // x STGMEDIUM + THOP_FN(FORMATETC), // x FORMATETC + THOP_FN(HACCEL), // x HACCEL + THOP_FN(OIFI), // x OLEINPLACEFRAMEINFO + THOP_FN(BINDOPTS), // x BIND_OPTS + THOP_FN(LOGPALETTE), // x LOGPALETTE + THOP_FN(SNB), // x SNB + THOP_FN(CRGIID), // x CRGIID + Thop_ERROR_3216, // x OLESTREAM (only 16-bit) + THOP_FN(HTASK), // x HTASK + THOP_FN(INTERFACEINFO), // x INTERFACEINFO + THOP_FN(IFACE), // x IFACE + THOP_FN(IFACE), // x IFACEOWNER + THOP_FN(IFACE), // x IFACENOADDREF + THOP_FN(IFACE), // x IFACECLEAN + THOP_FN(IFACEGEN), // x IFACEGEN + THOP_FN(IFACEGEN), // x IFACEGENOWNER + Thop_ERROR_3216, // x ROUTINE_INDEX + THOP_FN(RETURNTYPE), // x RETURN_TYPE + THOP_FN(NULL), // x NULL + Thop_ERROR_3216, // x ERROR + THOP_FN(ENUM), // x ENUM + THOP_FN(CALLBACK), // x CALLBACK + THOP_FN(RPCOLEMESSAGE), // x RPCOLEMESSAGE + THOP_FN(ALIAS32), // x ALIAS32 + THOP_FN(CLSCONTEXT), // x CLSCONTEXT + THOP_FN(FILENAME), // x FILENAME + THOP_FN(SIZEDSTRING), // x SIZEDSTRING +}; + +//+--------------------------------------------------------------------------- +// +// Function: General_Enum_3216, private +// +// Synopsis: Thunking for standard OLE enumerator interface ::Next member +// function. +// +// Arguments: [pti] - Thunk state information +// [uiSize32] - 32-bit information size +// [uiSize16] - 16-bit information size +// [pfnCallback] - Data thunking callback +// [pfnCleanup] - Thunking cleanup +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This handler is called from many IXXXEnum::Next handlers thop +// thunks to do the standard sorts of "buffer of structures" +// processing. +// +//---------------------------------------------------------------------------- +#define MAX_ALLOCA_STRUCT 5 // 16-bit stacks are precious + +DWORD General_Enum_3216( + THUNKINFO *pti, + UINT uiSize32, + UINT uiSize16, + SCODE (*pfnCallback)( THUNKINFO *, LPVOID, VPVOID), + void (*pfnCleanup)( THUNKINFO *, LPVOID, VPVOID) ) +{ + DWORD dwResult; + ULONG ulCount; + VPVOID vpstruct16; + VPVOID vpfetched16; + LPVOID lpstruct32; + LPVOID lpstruct32Iterate; + VPVOID vpstruct16Iterate; + ULONG *lpfetched32; + ULONG UNALIGNED *lpfetched16; + ULONG ulFetched16; + ULONG ulIterate; + BOOL fError; + SCODE sc; + LPVOID pvArg32; + + dwResult = (DWORD)S_OK; + + GET_STACK32(pti, ulCount, ULONG ); + GET_STACK32(pti, lpstruct32, LPVOID ); + GET_STACK32(pti, lpfetched32, ULONG FAR *); + + vpfetched16 = STACKALLOC16(sizeof(ULONG)); + if (vpfetched16 == 0) + { + dwResult = (DWORD)E_OUTOFMEMORY; + } + else + { + // Zero this out so that we don't have a random value sitting + // underneath + // when bad apps like 16-bit MsWorks don't return the number of items + // in the returned enumeration. + + lpfetched16 = FIXVDMPTR(vpfetched16, ULONG); + *lpfetched16 = 0; + RELVDMPTR(vpfetched16); + } + + pvArg32 = NULL; + vpstruct16 = 0; + + if ( lpstruct32 != NULL ) + { + if ( ulCount == 0 ) + { + dwResult = (DWORD)E_INVALIDARG; + } + else + { + if (IsBadWritePtr(lpstruct32, ulCount*uiSize32)) + { + dwResult = (DWORD)E_INVALIDARG; + } + else + { + pvArg32 = lpstruct32; + + if ( ulCount > MAX_ALLOCA_STRUCT ) + { + vpstruct16 = WgtAllocLock( GMEM_MOVEABLE, + ulCount * uiSize16, + NULL ); + } + else + { + vpstruct16 = STACKALLOC16( ulCount * uiSize16 ); + } + + if (vpstruct16 == 0) + { + dwResult = (DWORD)E_OUTOFMEMORY; + } + } + } + } + + if (SUCCEEDED(dwResult)) + { + TO_STACK16(pti, ulCount, ULONG); + TO_STACK16(pti, vpstruct16, VPVOID); + TO_STACK16(pti, vpfetched16, VPVOID); + + pti->pThop++; + dwResult = EXECUTE_THOP3216(pti); + } + + if ( SUCCEEDED(dwResult) ) + { + lpfetched16 = FIXVDMPTR( vpfetched16, ULONG); + ulFetched16 = *lpfetched16; + RELVDMPTR(vpfetched16); + + if ( lpstruct32 != NULL ) + { + // Some apps (MsWorks3 is one) return S_FALSE and do not return + // the number of elements retrieved. The only thing we can + // do is ignore the enumeration since we don't know how many + // were actually set. Of course, we can't ignore all enumerations + // when the return is S_FALSE so we only handle the case + // where S_FALSE was returned on a enumeration of one element, + // in which we can be sure there isn't any valid data + if (dwResult == (DWORD)S_FALSE && ulCount == 1) + { + ulFetched16 = 0; + } + + // + // Iterate through all of the structures, converting them + // into 16-bit + // + fError = FALSE; + ulIterate = 0; + vpstruct16Iterate = vpstruct16; + lpstruct32Iterate = lpstruct32; + + while ( ulIterate < ulFetched16 ) + { + // + // Callback to the callback function to do any specific + // processing + // + sc = (*pfnCallback)( pti, lpstruct32Iterate, + vpstruct16Iterate ); + + if ( FAILED(sc) ) + { + fError = TRUE; + dwResult = sc; + } + + vpstruct16Iterate = (VPVOID)((DWORD)vpstruct16Iterate + + uiSize16); + lpstruct32Iterate = (LPVOID)((DWORD)lpstruct32Iterate + + uiSize32); + + ulIterate++; + } + + if ( fError ) + { + // + // Cleanup all these guys + // + ulIterate = 0; + vpstruct16Iterate = vpstruct16; + lpstruct32Iterate = lpstruct32; + + while ( ulIterate <= ulFetched16 ) + { + (*pfnCleanup)( pti, lpstruct32Iterate, vpstruct16Iterate ); + vpstruct16Iterate = (VPVOID)((DWORD)vpstruct16Iterate + + uiSize16); + lpstruct32Iterate = (LPVOID)((DWORD)lpstruct32Iterate + + uiSize32); + + ulIterate++; + } + } + } + } + + if (FAILED(dwResult) && pvArg32 != NULL) + { + memset(pvArg32, 0, ulCount*uiSize32); + } + + if ( lpfetched32 != NULL ) + { + *lpfetched32 = ulFetched16; + } + + // + // Free up any space we've allocated + // + if (vpstruct16 != 0) + { + if ( ulCount > MAX_ALLOCA_STRUCT ) + { + WgtUnlockFree( vpstruct16 ); + } + else + { + STACKFREE16( vpstruct16, ulCount * uiSize16 ); + } + } + + if (vpfetched16 != 0) + { + STACKFREE16(vpfetched16, sizeof(ULONG)); + } + + return dwResult; +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_STRING_3216, public +// +// Synopsis: Prepares the LPOLESTR for the copy back into 16-bit address +// space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_STRING_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + VPSTR vpstr; + + *(LPOLESTR *)lp32 = NULL; + vpstr = *FIXVDMPTR(vp16, VPSTR); + RELVDMPTR(vp16); + return ConvertTaskString1632(pti, vpstr, NULL, 0, (LPOLESTR *)lp32); +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_STRING_3216, public +// +// Synopsis: Cleans up the any STRINGs returned (either to 16-bit or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_STRING_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + LPOLESTR lpstr32; + + lpstr32 = *(LPOLESTR *)lp32; + if ( lpstr32 != NULL ) + { + TaskFree32( lpstr32 ); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_STRING_3216, public +// +// Synopsis: Thunks IEnumSTRING::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_STRING_3216(THUNKINFO *pti) +{ + return General_Enum_3216(pti, + sizeof(LPOLESTR), + sizeof(VPSTR), + Callback_STRING_3216, + Cleanup_STRING_3216 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_UNKNOWN_3216, public +// +// Synopsis: Prepares the UNKNOWN structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_UNKNOWN_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + SCODE sc = S_OK; + VPVOID vpunknown16; + IUnknown *punkThis32; + + vpunknown16 = *FIXVDMPTR( vp16, VPVOID ); + RELVDMPTR(vp16); + + punkThis32 = pti->pThkMgr->FindProxy3216(NULL, vpunknown16, + INDEX_IIDIDX(THI_IUnknown), + NULL); + if (punkThis32 == NULL) + { + sc = E_OUTOFMEMORY; + } + + *(LPUNKNOWN *)lp32 = (LPUNKNOWN)punkThis32; + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_UNKNOWN_3216, public +// +// Synopsis: Cleans up the any UNKNOWNs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_UNKNOWN_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + LPUNKNOWN lpunknown32; + VPVOID vpv; + + lpunknown32 = *(LPUNKNOWN *)lp32; + + // BUGBUG - What is the proper cleanup for IEnum<Interface>? + // Should the objects be released or only the proxies we + // created? + if (lpunknown32 != NULL) + { + vpv = *FIXVDMPTR(vp16, VPVOID); + RELVDMPTR(vp16); + pti->pThkMgr->FreeProxy3216(vpv); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_UNKNOWN_3216, public +// +// Synopsis: Thunks IEnumUNKNOWN::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_UNKNOWN_3216(THUNKINFO *pti) +{ + return General_Enum_3216(pti, + sizeof(LPUNKNOWN), + sizeof(LPUNKNOWN), + Callback_UNKNOWN_3216, + Cleanup_UNKNOWN_3216 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_STATSTG_3216, public +// +// Synopsis: Prepares the STATSTG structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_STATSTG_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + ((STATSTG *)lp32)->pwcsName = NULL; + return ConvertStatStg1632(pti, vp16, (STATSTG *)lp32, + NULL, 0); +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_STATSTG_3216, public +// +// Synopsis: Cleans up the any STATSTGs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_STATSTG_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + STATSTG FAR *lpstatstg32; + + lpstatstg32 = (STATSTG FAR *)lp32; + + if ( lpstatstg32->pwcsName != NULL ) + { + TaskFree32( lpstatstg32->pwcsName ); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_STATSTG_3216, public +// +// Synopsis: Thunks IEnumSTATSTG::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_STATSTG_3216(THUNKINFO *pti) +{ + return General_Enum_3216(pti, + sizeof(STATSTG), + sizeof(STATSTG), + Callback_STATSTG_3216, + Cleanup_STATSTG_3216 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_FORMATETC_3216, public +// +// Synopsis: Prepares the FORMATETC structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_FORMATETC_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + ((FORMATETC *)lp32)->ptd = NULL; + return ConvertFetc1632(pti, vp16, (FORMATETC *)lp32, TRUE); +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_FORMATETC_3216, public +// +// Synopsis: Cleans up the any FORMATETCs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_FORMATETC_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + FORMATETC FAR *lpformatetc32; + + lpformatetc32 = (FORMATETC FAR *)lp32; + + if ( lpformatetc32->ptd != NULL ) + { + TaskFree32( lpformatetc32->ptd ); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_FORMATETC_3216, public +// +// Synopsis: Thunks IEnumFORMATETC::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_FORMATETC_3216(THUNKINFO *pti) +{ + return General_Enum_3216(pti, + sizeof(FORMATETC), + sizeof(FORMATETC16), + Callback_FORMATETC_3216, + Cleanup_FORMATETC_3216 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_STATDATA_3216, public +// +// Synopsis: Prepares the STATDATA structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- +SCODE Callback_STATDATA_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + SCODE sc; + LPSTATDATA lpstatdata32; + STATDATA16 UNALIGNED *lpstatdata16; + LPADVISESINK lpadv32; + VPVOID vpadv16; + IUnknown *punkThis32; + + sc = S_OK; + + lpstatdata32 = (LPSTATDATA)lp32; + + lpstatdata16 = FIXVDMPTR( vp16, STATDATA16 ); + vpadv16 = lpstatdata16->pAdvSink; + RELVDMPTR(vp16); + + if ( vpadv16 != 0) + { + // We don't know whether it's an AdviseSink or + // an AdviseSink2, so pass AdviseSink2 since it's + // a superset of AdviseSink and will work for both + + punkThis32 = + pti->pThkMgr->FindProxy3216(NULL, vpadv16, + INDEX_IIDIDX(THI_IAdviseSink2), + NULL); + if (punkThis32 == NULL) + { + sc = E_OUTOFMEMORY; + } + + lpadv32 = (LPADVISESINK)punkThis32; + } + else + { + lpadv32 = NULL; + } + + lpstatdata32->formatetc.ptd = NULL; + if (SUCCEEDED(sc)) + { + // If this fails the AdviseSink proxy will be cleaned up in + // the cleanup function later + + sc = ConvertFetc1632(pti, + vp16+FIELD_OFFSET(STATDATA16, formatetc), + &lpstatdata32->formatetc, TRUE); + } + + if (SUCCEEDED(sc)) + { + lpstatdata16 = FIXVDMPTR( vp16, STATDATA16 ); + lpstatdata32->advf = lpstatdata16->advf; + lpstatdata32->pAdvSink = lpadv32; + lpstatdata32->dwConnection = lpstatdata16->dwConnection; + RELVDMPTR(vp16); + } + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_STATDATA_3216, public +// +// Synopsis: Cleans up the any STATDATAs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_STATDATA_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + STATDATA FAR *lpstatdata32; + VPVOID vpvSink; + + lpstatdata32 = (STATDATA FAR *)lp32; + + if ( lpstatdata32->formatetc.ptd != NULL ) + { + TaskFree32( lpstatdata32->formatetc.ptd ); + } + + if ( lpstatdata32->pAdvSink != NULL ) + { + // BUGBUG - What is the proper cleanup for interfaces? + // Should the objects be released or only the proxies we + // created? + vpvSink = (FIXVDMPTR( vp16, STATDATA16 ))->pAdvSink; + RELVDMPTR(vp16); + + pti->pThkMgr->FreeProxy3216(vpvSink); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_STATDATA_3216, public +// +// Synopsis: Thunks IEnumSTATDATA::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_STATDATA_3216(THUNKINFO *pti) +{ + return General_Enum_3216(pti, + sizeof(STATDATA), + sizeof(STATDATA16), + Callback_STATDATA_3216, + Cleanup_STATDATA_3216 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_MONIKER_3216, public +// +// Synopsis: Prepares the MONIKER structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_MONIKER_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + VPVOID vpmoniker16; + IUnknown *punkThis32; + SCODE sc = S_OK; + + vpmoniker16 = *FIXVDMPTR( vp16, VPVOID ); + RELVDMPTR(vp16); + + punkThis32 = pti->pThkMgr->FindProxy3216(NULL, vpmoniker16, + INDEX_IIDIDX(THI_IMoniker), + NULL); + if (punkThis32 == NULL) + { + sc = E_OUTOFMEMORY; + } + + *(LPMONIKER *)lp32 = (LPMONIKER)punkThis32; + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_MONIKER_3216, public +// +// Synopsis: Cleans up the any MONIKERs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_MONIKER_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + LPMONIKER lpmoniker32; + VPVOID vpv; + + lpmoniker32 = *(LPMONIKER *)lp32; + + // BUGBUG - What is the proper cleanup for IEnum<Interface>? + // Should the objects be released or only the proxies we + // created? + if (lpmoniker32 != NULL) + { + vpv = *FIXVDMPTR(vp16, VPVOID); + RELVDMPTR(vp16); + pti->pThkMgr->FreeProxy3216(vpv); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_MONIKER_3216, public +// +// Synopsis: Thunks IEnumMONIKER::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_MONIKER_3216(THUNKINFO *pti) +{ + return General_Enum_3216(pti, + sizeof(LPMONIKER), + sizeof(LPMONIKER), + Callback_MONIKER_3216, + Cleanup_MONIKER_3216 ); +} + +//+--------------------------------------------------------------------------- +// +// Function: Callback_OLEVERB_3216, public +// +// Synopsis: Prepares the OLEVERB structure for the copy back into 16-bit +// address space. +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: SCODE indicating success/failure +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +SCODE Callback_OLEVERB_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + SCODE sc; + OLEVERB *lpoleverb32; + OLEVERB UNALIGNED *lpoleverb16; + VPSTR vpstr; + + lpoleverb32 = (LPOLEVERB)lp32; + + lpoleverb16 = FIXVDMPTR(vp16, OLEVERB); + vpstr = (VPSTR)lpoleverb16->lpszVerbName; + RELVDMPTR(vp16); + + lpoleverb32->lpszVerbName = NULL; + sc = ConvertTaskString1632(pti, vpstr, NULL, 0, + &lpoleverb32->lpszVerbName); + if (SUCCEEDED(sc)) + { + lpoleverb16 = FIXVDMPTR(vp16, OLEVERB); + lpoleverb32->lVerb = lpoleverb16->lVerb; + lpoleverb32->fuFlags = lpoleverb16->fuFlags; + lpoleverb32->grfAttribs = lpoleverb16->grfAttribs; + RELVDMPTR(vp16); + } + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: Cleanup_OLEVERB_3216, public +// +// Synopsis: Cleans up the any OLEVERBs returned (either to 16-bit +// or 32-bit) +// +// Arguments: [pti] - Thunking state information +// [lp32] - Pointer to 32-bit output structure +// [lp16] - Pointer to 16-bit returned structure +// +// Returns: nothing, should NEVER fail +// +// History: 1-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +void Cleanup_OLEVERB_3216( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 ) +{ + OLEVERB FAR *lpoleverb32; + + lpoleverb32 = (LPOLEVERB)lp32; + + if ( lpoleverb32->lpszVerbName != NULL ) + { + TaskFree32( lpoleverb32->lpszVerbName ); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: Thop_Enum_OLEVERB_3216, public +// +// Synopsis: Thunks IEnumOLEVERB::Next parameters +// +// Arguments: [pti] - Thunk state information +// +// Returns: Appropriate status code +// +// History: 1-Mar-94 BobDay Created +// +// Notes: This thunk is 2nd part of a 2-byte thop. +// +//---------------------------------------------------------------------------- + +DWORD Thop_Enum_OLEVERB_3216(THUNKINFO *pti) +{ + return General_Enum_3216(pti, + sizeof(OLEVERB), + sizeof(OLEVERB), + Callback_OLEVERB_3216, + Cleanup_OLEVERB_3216 ); +} + +#define THOP_EFN(x) Thop_Enum_ ## x ## _3216 + +DWORD (*CONST aThopEnumFunctions3216[])(THUNKINFO *) = +{ + THOP_EFN(STRING), // STRING + THOP_EFN(UNKNOWN), // UNKNOWN + THOP_EFN(STATSTG), // STATSTG + THOP_EFN(FORMATETC), // FORMATETC + THOP_EFN(STATDATA), // STATDATA + THOP_EFN(MONIKER), // MONIKER + THOP_EFN(OLEVERB), // OLEVERB +}; + + diff --git a/private/ole32/olethunk/olethk32/thopapi.hxx b/private/ole32/olethunk/olethk32/thopapi.hxx new file mode 100644 index 000000000..f4bcf22d4 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thopapi.hxx @@ -0,0 +1,37 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thopapi.hxx +// +// Contents: API thops header +// +// History: 22-Feb-94 DrewB Created +// +// Notes: This file declares generated tables found in +// thtblapi.cxx +// +//---------------------------------------------------------------------------- + +#ifndef __THOPAPI_HXX__ +#define __THOPAPI_HXX__ + +// These are declared extern "C" because there was a bug in the +// PPC compiler (aug '95) where the const related decorations on +// the global data symbols was not done consistantly. By using +// extern "C" the bug is simply avoided. + +extern "C" THOP CONST * CONST apthopsApiThops[]; +extern VTBLFN CONST apfnApiFunctions[]; + +// These two routines aren't in the public headers but are needed +// in vtblapi.cxx +STDAPI ReadOleStg + (LPSTORAGE pstg, DWORD FAR* pdwFlags, DWORD FAR* pdwOptUpdate, + DWORD FAR* pdwReserved, LPMONIKER FAR* ppmk, LPSTREAM FAR* ppstmOut); +STDAPI WriteOleStg + (LPSTORAGE pstg, IOleObject FAR* pOleObj, + DWORD dwReserved, LPSTREAM FAR* ppstmOut); + +#endif // #ifndef __THOPAPI_HXX__ diff --git a/private/ole32/olethunk/olethk32/thopiint.cxx b/private/ole32/olethunk/olethk32/thopiint.cxx new file mode 100644 index 000000000..f979594cf --- /dev/null +++ b/private/ole32/olethunk/olethk32/thopiint.cxx @@ -0,0 +1,83 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thopiint.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +#include <headers.cxx> +#pragma hdrstop + +#include "thopsint.cxx" +#include "thtblint.cxx" +#include "vtblifn.cxx" +#include "vtblint.cxx" +#include "fntomthd.cxx" + +THOPI CONST athopiInterfaceThopis[] = +{ + apthopsIUnknown, 3, tfnIUnknown, NULL +, apthopsIClassFactory, 5, tfnIClassFactory, ftmIClassFactory +, apthopsIMarshal, 9, tfnIMarshal, ftmIMarshal +, apthopsIStdMarshalInfo, 4, tfnIStdMarshalInfo, ftmIStdMarshalInfo +, apthopsIMessageFilter, 6, tfnIMessageFilter, ftmIMessageFilter +, apthopsIExternalConnection, 5, tfnIExternalConnection, ftmIExternalConnection +, apthopsIEnumString, 7, tfnIEnumString, ftmIEnumString +, apthopsIEnumUnknown, 7, tfnIEnumUnknown, ftmIEnumUnknown +, apthopsIEnumSTATSTG, 7, tfnIEnumSTATSTG, ftmIEnumSTATSTG +, apthopsILockBytes, 10, tfnILockBytes, ftmILockBytes +, apthopsIStream, 14, tfnIStream, ftmIStream +, apthopsIStorage, 18, tfnIStorage, ftmIStorage +, apthopsIRootStorage, 4, tfnIRootStorage, ftmIRootStorage +, apthopsIEnumFORMATETC, 7, tfnIEnumFORMATETC, ftmIEnumFORMATETC +, apthopsIEnumSTATDATA, 7, tfnIEnumSTATDATA, ftmIEnumSTATDATA +, apthopsIDataObject, 12, tfnIDataObject, ftmIDataObject +, apthopsIViewObject, 9, tfnIViewObject, ftmIViewObject +, apthopsIViewObject2, 10, tfnIViewObject2, ftmIViewObject2 +, apthopsIAdviseSink, 8, tfnIAdviseSink, ftmIAdviseSink +, apthopsIAdviseSink2, 9, tfnIAdviseSink2, ftmIAdviseSink2 +, apthopsIDataAdviseHolder, 7, tfnIDataAdviseHolder, ftmIDataAdviseHolder +, apthopsIOleCache, 8, tfnIOleCache, ftmIOleCache +, apthopsIOleCache2, 10, tfnIOleCache2, ftmIOleCache2 +, apthopsIOleCacheControl, 5, tfnIOleCacheControl, ftmIOleCacheControl +, apthopsIDropTarget, 7, tfnIDropTarget, ftmIDropTarget +, apthopsIDropSource, 5, tfnIDropSource, ftmIDropSource +, apthopsIPersist, 4, tfnIPersist, ftmIPersist +, apthopsIPersistStorage, 10, tfnIPersistStorage, ftmIPersistStorage +, apthopsIPersistStream, 8, tfnIPersistStream, ftmIPersistStream +, apthopsIPersistFile, 9, tfnIPersistFile, ftmIPersistFile +, apthopsIBindCtx, 13, tfnIBindCtx, ftmIBindCtx +, apthopsIMoniker, 23, tfnIMoniker, ftmIMoniker +, apthopsIRunningObjectTable, 10, tfnIRunningObjectTable, ftmIRunningObjectTable +, apthopsIEnumMoniker, 7, tfnIEnumMoniker, ftmIEnumMoniker +, apthopsIEnumOLEVERB, 7, tfnIEnumOLEVERB, ftmIEnumOLEVERB +, apthopsIOleObject, 24, tfnIOleObject, ftmIOleObject +, apthopsIOleClientSite, 9, tfnIOleClientSite, ftmIOleClientSite +, apthopsIRunnableObject, 8, tfnIRunnableObject, ftmIRunnableObject +, apthopsIParseDisplayName, 4, tfnIParseDisplayName, ftmIParseDisplayName +, apthopsIOleContainer, 6, tfnIOleContainer, ftmIOleContainer +, apthopsIOleItemContainer, 9, tfnIOleItemContainer, ftmIOleItemContainer +, apthopsIOleAdviseHolder, 9, tfnIOleAdviseHolder, ftmIOleAdviseHolder +, apthopsIOleLink, 14, tfnIOleLink, ftmIOleLink +, apthopsIOleWindow, 5, tfnIOleWindow, ftmIOleWindow +, apthopsIOleInPlaceObject, 9, tfnIOleInPlaceObject, ftmIOleInPlaceObject +, apthopsIOleInPlaceActiveObject, 10, tfnIOleInPlaceActiveObject, ftmIOleInPlaceActiveObject +, apthopsIOleInPlaceUIWindow, 9, tfnIOleInPlaceUIWindow, ftmIOleInPlaceUIWindow +, apthopsIOleInPlaceFrame, 15, tfnIOleInPlaceFrame, ftmIOleInPlaceFrame +, apthopsIOleInPlaceSite, 15, tfnIOleInPlaceSite, ftmIOleInPlaceSite +, apthopsIRpcChannelBuffer, 8, tfnIRpcChannelBuffer, ftmIRpcChannelBuffer +, apthopsIRpcProxyBuffer, 5, tfnIRpcProxyBuffer, ftmIRpcProxyBuffer +, apthopsIRpcStubBuffer, 10, tfnIRpcStubBuffer, ftmIRpcStubBuffer +, apthopsIPSFactoryBuffer, 5, tfnIPSFactoryBuffer, ftmIPSFactoryBuffer +, apthopsIRpcChannel, 7, tfnIRpcChannel, ftmIRpcChannel +, apthopsIRpcProxy, 5, tfnIRpcProxy, ftmIRpcProxy +, apthopsIRpcStub, 8, tfnIRpcStub, ftmIRpcStub +, apthopsIPSFactory, 5, tfnIPSFactory, ftmIPSFactory +}; diff --git a/private/ole32/olethunk/olethk32/thopint.hxx b/private/ole32/olethunk/olethk32/thopint.hxx new file mode 100644 index 000000000..5d5eea987 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thopint.hxx @@ -0,0 +1,39 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thopint.hxx +// +// Contents: Interface thops header file +// +// History: 22-Feb-94 DrewB Created +// +// Notes: This file declares generated tables found in +// thtblint.cxx +// +//---------------------------------------------------------------------------- + +#ifndef __THOPINT_HXX__ +#define __THOPINT_HXX__ + +typedef DWORD (*THUNK3216FN)(THUNK3216OBJ *ptoThis); + +typedef struct tagTHOPI +{ + THOP CONST * CONST * ppThops; + UINT uiSize; + THUNK3216FN CONST * pt3216fn; + BYTE CONST * pftm; +} THOPI; + +typedef struct tagIIDTOTHI +{ + IID CONST * piid; + int iThi; +} IIDTOTHI; + +extern THOPI CONST athopiInterfaceThopis[]; +extern IIDTOTHI CONST aittIidToThi[]; + +#endif // #ifndef __THOPINT_HXX__ diff --git a/private/ole32/olethunk/olethk32/thopsapi.cxx b/private/ole32/olethunk/olethk32/thopsapi.cxx new file mode 100644 index 000000000..5493fb3d9 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thopsapi.cxx @@ -0,0 +1,427 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thopsapi.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +THOP CONST thopsCoInitialize[] = +{ + THOP_IFACE | THOP_IN, THI_IMalloc, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsCoUninitialize[] = +{ + THOP_END, THOP_ROUTINEINDEX, 6 +}; +THOP CONST thopsCoGetClassObject[] = +{ + THOP_COPY | THOP_IN, 16, THOP_CLSCONTEXT, THOP_NULL | THOP_IN, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsCoRegisterClassObject[] = +{ + THOP_COPY | THOP_IN, 16, THOP_IFACE | THOP_IN, THI_IUnknown, THOP_CLSCONTEXT, THOP_COPY, 4, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsCoRevokeClassObject[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsCoMarshalInterface[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_IN, 4, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsCoUnmarshalInterface[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsCoReleaseMarshalData[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsCoDisconnectObject[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsCoLockObjectExternal[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_SHORTLONG, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsCoGetStandardMarshal[] = +{ + THOP_COPY | THOP_IN, 16, THOP_IFACE | THOP_IN, THI_IUnknown, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IMarshal, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsCoIsHandlerConnected[] = +{ + THOP_RETURNTYPE, THOP_SHORTLONG, THOP_IFACE | THOP_IN, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsCoFreeAllLibraries[] = +{ + THOP_END, THOP_ROUTINEINDEX, 6 +}; +THOP CONST thopsCoFreeUnusedLibraries[] = +{ + THOP_END, THOP_ROUTINEINDEX, 6 +}; +THOP CONST thopsCoCreateInstance[] = +{ + THOP_COPY | THOP_IN, 16, THOP_IFACE | THOP_IN, THI_IUnknown, THOP_CLSCONTEXT, THOP_COPY | THOP_IN, 16, THOP_IFACEGENOWNER | THOP_OUT, 4, 12, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsCLSIDFromString[] = +{ + THOP_LPSTR | THOP_IN, THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsCoIsOle1Class[] = +{ + THOP_RETURNTYPE, THOP_SHORTLONG, THOP_COPY | THOP_IN, 16, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsProgIDFromCLSID[] = +{ + THOP_COPY | THOP_IN, 16, THOP_LPLPSTR, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsCLSIDFromProgID[] = +{ + THOP_LPSTR | THOP_IN, THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsCoCreateGuid[] = +{ + THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsCoFileTimeToDosDateTime[] = +{ + THOP_RETURNTYPE, THOP_SHORTLONG, THOP_COPY | THOP_IN, 8, THOP_WORDDWORD | THOP_OUT, THOP_WORDDWORD | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsCoDosDateTimeToFileTime[] = +{ + THOP_RETURNTYPE, THOP_SHORTLONG, THOP_WORDDWORD, THOP_WORDDWORD, THOP_COPY | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 8 +}; +THOP CONST thopsCoFileTimeNow[] = +{ + THOP_COPY | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsCoRegisterMessageFilter[] = +{ + THOP_IFACE | THOP_IN, THI_IMessageFilter, THOP_IFACE | THOP_OUT, THI_IMessageFilter, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsCoGetTreatAsClass[] = +{ + THOP_COPY | THOP_IN, 16, THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsCoTreatAsClass[] = +{ + THOP_COPY | THOP_IN, 16, THOP_COPY | THOP_IN, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsDllGetClassObject[] = +{ + THOP_COPY | THOP_IN, 16, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsStgCreateDocfile[] = +{ + THOP_LPSTR | THOP_IN, THOP_COPY, 4, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsStgCreateDocfileOnILockBytes[] = +{ + THOP_IFACE | THOP_IN, THI_ILockBytes, THOP_COPY, 4, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsStgOpenStorage[] = +{ + THOP_LPSTR | THOP_IN, THOP_IFACE | THOP_IN, THI_IStorage, THOP_COPY, 4, THOP_SNB, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsStgOpenStorageOnILockBytes[] = +{ + THOP_IFACE | THOP_IN, THI_ILockBytes, THOP_IFACE | THOP_IN, THI_IStorage, THOP_COPY, 4, THOP_SNB, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsStgIsStorageFile[] = +{ + THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsStgIsStorageILockBytes[] = +{ + THOP_IFACE | THOP_IN, THI_ILockBytes, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsStgSetTimes[] = +{ + THOP_LPSTR | THOP_IN, THOP_COPY | THOP_IN, 8, THOP_COPY | THOP_IN, 8, THOP_COPY | THOP_IN, 8, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsCreateDataAdviseHolder[] = +{ + THOP_IFACE | THOP_OUT, THI_IDataAdviseHolder, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsCreateDataCache[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_COPY | THOP_IN, 16, THOP_COPY | THOP_IN, 16, THOP_IFACEGENOWNER | THOP_OUT, 4, 12, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsBindMoniker[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_COPY, 4, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsMkParseDisplayName[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_LPSTR | THOP_IN, THOP_COPY | THOP_OUT, 4, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsMonikerRelativePathTo[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsMonikerCommonPrefixWith[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsCreateBindCtx[] = +{ + THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IBindCtx, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsCreateGenericComposite[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsGetClassFile[] = +{ + THOP_LPSTR | THOP_IN, THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsCreateFileMoniker[] = +{ + THOP_LPSTR | THOP_IN, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsCreateItemMoniker[] = +{ + THOP_LPSTR | THOP_IN, THOP_LPSTR | THOP_IN, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsCreateAntiMoniker[] = +{ + THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsCreatePointerMoniker[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsGetRunningObjectTable[] = +{ + THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IRunningObjectTable, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsReadClassStg[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsWriteClassStg[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_COPY | THOP_IN, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsReadClassStm[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsWriteClassStm[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_COPY | THOP_IN, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsWriteFmtUserTypeStg[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_WORDDWORD, THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 19 +}; +THOP CONST thopsReadFmtUserTypeStg[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_WORDDWORD | THOP_OUT, THOP_LPLPSTR, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsOleInitialize[] = +{ + THOP_IFACE | THOP_IN, THI_IMalloc, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsOleUninitialize[] = +{ + THOP_END, THOP_ROUTINEINDEX, 6 +}; +THOP CONST thopsOleQueryLinkFromData[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsOleQueryCreateFromData[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsOleCreate[] = +{ + THOP_COPY | THOP_IN, 16, THOP_COPY | THOP_IN, 16, THOP_COPY, 4, THOP_FORMATETC | THOP_IN, THOP_IFACE | THOP_IN, THI_IOleClientSite, THOP_IFACE | THOP_IN, THI_IStorage, THOP_IFACEGEN | THOP_OUT, 20, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsOleCreateFromData[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_COPY | THOP_IN, 16, THOP_COPY, 4, THOP_FORMATETC | THOP_IN, THOP_IFACE | THOP_IN, THI_IOleClientSite, THOP_IFACE | THOP_IN, THI_IStorage, THOP_IFACEGEN | THOP_OUT, 20, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsOleCreateLinkFromData[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_COPY | THOP_IN, 16, THOP_COPY, 4, THOP_FORMATETC | THOP_IN, THOP_IFACE | THOP_IN, THI_IOleClientSite, THOP_IFACE | THOP_IN, THI_IStorage, THOP_IFACEGEN | THOP_OUT, 20, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsOleCreateStaticFromData[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_COPY | THOP_IN, 16, THOP_COPY, 4, THOP_FORMATETC | THOP_IN, THOP_IFACE | THOP_IN, THI_IOleClientSite, THOP_IFACE | THOP_IN, THI_IStorage, THOP_IFACEGEN | THOP_OUT, 20, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsOleCreateLink[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_COPY | THOP_IN, 16, THOP_COPY, 4, THOP_FORMATETC | THOP_IN, THOP_IFACE | THOP_IN, THI_IOleClientSite, THOP_IFACE | THOP_IN, THI_IStorage, THOP_IFACEGEN | THOP_OUT, 20, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsOleCreateLinkToFile[] = +{ + THOP_LPSTR | THOP_IN, THOP_COPY | THOP_IN, 16, THOP_COPY, 4, THOP_FORMATETC | THOP_IN, THOP_IFACE | THOP_IN, THI_IOleClientSite, THOP_IFACE | THOP_IN, THI_IStorage, THOP_IFACEGEN | THOP_OUT, 20, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsOleCreateFromFile[] = +{ + THOP_COPY | THOP_IN, 16, THOP_LPSTR | THOP_IN, THOP_COPY | THOP_IN, 16, THOP_COPY, 4, THOP_FORMATETC | THOP_IN, THOP_IFACE | THOP_IN, THI_IOleClientSite, THOP_IFACE | THOP_IN, THI_IStorage, THOP_IFACEGEN | THOP_OUT, 20, THOP_END, + THOP_ROUTINEINDEX, 20 +}; +THOP CONST thopsOleLoad[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_COPY | THOP_IN, 16, THOP_IFACE | THOP_IN, THI_IOleClientSite, THOP_IFACEGEN | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsOleSave[] = +{ + THOP_IFACE | THOP_IN, THI_IPersistStorage, THOP_IFACE | THOP_IN, THI_IStorage, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsOleLoadFromStream[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsOleSaveToStream[] = +{ + THOP_IFACE | THOP_IN, THI_IPersistStream, THOP_IFACE | THOP_IN, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsOleSetContainedObject[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsOleNoteObjectVisible[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsRegisterDragDrop[] = +{ + THOP_HUSER, THOP_IFACE | THOP_IN, THI_IDropTarget, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsRevokeDragDrop[] = +{ + THOP_HUSER, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsDoDragDrop[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_IFACE | THOP_IN, THI_IDropSource, THOP_COPY, 4, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsOleSetClipboard[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsOleGetClipboard[] = +{ + THOP_IFACE | THOP_OUT, THI_IDataObject, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsOleFlushClipboard[] = +{ + THOP_END, THOP_ROUTINEINDEX, 6 +}; +THOP CONST thopsOleIsCurrentClipboard[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsOleCreateMenuDescriptor[] = +{ + THOP_RETURNTYPE, THOP_ALIAS32, ALIAS_CREATE, THOP_HUSER, THOP_COPY | THOP_IN, 24, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsOleSetMenuDescriptor[] = +{ + THOP_ALIAS32, ALIAS_RESOLVE, THOP_HUSER, THOP_HUSER, THOP_IFACE | THOP_IN, THI_IOleInPlaceFrame, THOP_IFACE | THOP_IN, THI_IOleInPlaceActiveObject, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsOleDestroyMenuDescriptor[] = +{ + THOP_ALIAS32, ALIAS_REMOVE, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsOleDraw[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_COPY, 4, THOP_HGDI, THOP_RECT | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsOleRun[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsOleIsRunning[] = +{ + THOP_RETURNTYPE, THOP_SHORTLONG, THOP_IFACE | THOP_IN, THI_IOleObject, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsOleLockRunning[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_SHORTLONG, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsCreateOleAdviseHolder[] = +{ + THOP_IFACE | THOP_OUT, THI_IOleAdviseHolder, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsOleCreateDefaultHandler[] = +{ + THOP_COPY | THOP_IN, 16, THOP_IFACE | THOP_IN, THI_IUnknown, THOP_COPY | THOP_IN, 16, THOP_IFACEGENOWNER | THOP_OUT, 4, 8, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsOleCreateEmbeddingHelper[] = +{ + THOP_COPY | THOP_IN, 16, THOP_IFACE | THOP_IN, THI_IUnknown, THOP_COPY, 4, THOP_IFACE | THOP_IN, THI_IClassFactory, THOP_COPY | THOP_IN, 16, THOP_IFACEGENOWNER | THOP_OUT, 4, 16, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsOleRegGetUserType[] = +{ + THOP_COPY | THOP_IN, 16, THOP_COPY, 4, THOP_LPLPSTR, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsOleRegGetMiscStatus[] = +{ + THOP_COPY | THOP_IN, 16, THOP_COPY, 4, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsOleRegEnumFormatEtc[] = +{ + THOP_COPY | THOP_IN, 16, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IEnumFORMATETC, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsOleRegEnumVerbs[] = +{ + THOP_COPY | THOP_IN, 16, THOP_IFACE | THOP_OUT, THI_IEnumOLEVERB, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsOleConvertIStorageToOLESTREAM[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_OLESTREAM | THOP_INOUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsOleConvertOLESTREAMToIStorage[] = +{ + THOP_OLESTREAM | THOP_INOUT, THOP_IFACE | THOP_IN, THI_IStorage, THOP_DVTARGETDEVICE | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsOleConvertIStorageToOLESTREAMEx[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_WORDDWORD, THOP_COPY, 4, THOP_COPY, 4, THOP_COPY, 4, THOP_STGMEDIUM | THOP_IN, 0, 0, THOP_OLESTREAM | THOP_INOUT, THOP_END, THOP_ROUTINEINDEX, 21 +}; +THOP CONST thopsOleConvertOLESTREAMToIStorageEx[] = +{ + THOP_OLESTREAM | THOP_INOUT, THOP_IFACE | THOP_IN, THI_IStorage, THOP_WORDDWORD | THOP_OUT, THOP_COPY | THOP_OUT, 4, THOP_COPY | THOP_OUT, 4, THOP_COPY | THOP_OUT, 4, THOP_STGMEDIUM | THOP_IN, 0, 0, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsOleDoAutoConvert[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsOleGetAutoConvert[] = +{ + THOP_COPY | THOP_IN, 16, THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsOleSetAutoConvert[] = +{ + THOP_COPY | THOP_IN, 16, THOP_COPY | THOP_IN, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsGetConvertStg[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsSetConvertStg[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsReadOleStg[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_COPY | THOP_OUT, 4, THOP_COPY | THOP_OUT, 4, THOP_COPY | THOP_OUT, 4, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_IFACE | THOP_OUT, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsWriteOleStg[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_IFACE | THOP_IN, THI_IOleObject, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 2 +}; diff --git a/private/ole32/olethunk/olethk32/thopsint.cxx b/private/ole32/olethunk/olethk32/thopsint.cxx new file mode 100644 index 000000000..9b0a06cf1 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thopsint.cxx @@ -0,0 +1,1313 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thopsint.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +THOP CONST thopsIClassFactory_CreateInstance[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_COPY | THOP_IN, 16, THOP_IFACEGENOWNER | THOP_OUT, 4, 8, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIClassFactory_LockServer[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIMarshal_GetUnmarshalClass[] = +{ + THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_IN, 4, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_COPY, 4, THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsIMarshal_GetMarshalSizeMax[] = +{ + THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_IN, 4, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_COPY, 4, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsIMarshal_MarshalInterface[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_IN, 4, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsIMarshal_UnmarshalInterface[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIMarshal_ReleaseMarshalData[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIMarshal_DisconnectObject[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIStdMarshalInfo_GetClassForHandler[] = +{ + THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIMessageFilter_HandleInComingCall[] = +{ + THOP_RETURNTYPE, THOP_COPY, 4, THOP_COPY, 4, THOP_HTASK, THOP_COPY, 4, THOP_INTERFACEINFO | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIMessageFilter_RetryRejectedCall[] = +{ + THOP_RETURNTYPE, THOP_COPY, 4, THOP_HTASK, THOP_COPY, 4, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIMessageFilter_MessagePending[] = +{ + THOP_RETURNTYPE, THOP_COPY, 4, THOP_HTASK, THOP_COPY, 4, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIExternalConnection_AddConnection[] = +{ + THOP_RETURNTYPE, THOP_COPY, 4, THOP_COPY, 4, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIExternalConnection_ReleaseConnection[] = +{ + THOP_RETURNTYPE, THOP_COPY, 4, THOP_COPY, 4, THOP_COPY, 4, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIEnumString_Next[] = +{ + THOP_ENUM, THE_IEnumString, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIEnumString_Skip[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumString_Reset[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIEnumString_Clone[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumString, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumUnknown_Next[] = +{ + THOP_ENUM, THE_IEnumUnknown, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIEnumUnknown_Skip[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumUnknown_Reset[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIEnumUnknown_Clone[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumUnknown, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumSTATSTG_Next[] = +{ + THOP_ENUM, THE_IEnumSTATSTG, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIEnumSTATSTG_Skip[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumSTATSTG_Reset[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIEnumSTATSTG_Clone[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumSTATSTG, THOP_END, THOP_ROUTINEINDEX, 3 +}; + +// Note: THOP_BUFFER | THOP_OUT takes care of the size of the input buffer +// and the size of the output buffer. +THOP CONST thopsILockBytes_ReadAt[] = +{ + THOP_COPY, 8, THOP_BUFFER | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 9 +}; +THOP CONST thopsILockBytes_WriteAt[] = +{ + THOP_COPY, 8, THOP_BUFFER | THOP_IN, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 9 +}; +THOP CONST thopsILockBytes_Flush[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsILockBytes_SetSize[] = +{ + THOP_COPY, 8, THOP_END, THOP_ROUTINEINDEX, 10 +}; +THOP CONST thopsILockBytes_LockRegion[] = +{ + THOP_COPY, 8, THOP_COPY, 8, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 11 +}; +THOP CONST thopsILockBytes_UnlockRegion[] = +{ + THOP_COPY, 8, THOP_COPY, 8, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 11 +}; +THOP CONST thopsILockBytes_Stat[] = +{ + THOP_STATSTG | THOP_OUT, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; + +// Note: THOP_BUFFER | THOP_OUT takes care of the size of the input buffer +// and the size of the output buffer. +THOP CONST thopsIStream_Read[] = +{ + THOP_BUFFER | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 2 +}; + +THOP CONST thopsIStream_Write[] = +{ + THOP_BUFFER | THOP_IN, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIStream_Seek[] = +{ + THOP_COPY, 8, THOP_COPY, 4, THOP_COPY | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 12 +}; +THOP CONST thopsIStream_SetSize[] = +{ + THOP_COPY, 8, THOP_END, THOP_ROUTINEINDEX, 10 +}; +THOP CONST thopsIStream_CopyTo[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_COPY, 8, THOP_COPY | THOP_OUT, 8, THOP_COPY | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 13 +}; +THOP CONST thopsIStream_Commit[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIStream_Revert[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIStream_LockRegion[] = +{ + THOP_COPY, 8, THOP_COPY, 8, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 11 +}; +THOP CONST thopsIStream_UnlockRegion[] = +{ + THOP_COPY, 8, THOP_COPY, 8, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 11 +}; +THOP CONST thopsIStream_Stat[] = +{ + THOP_STATSTG | THOP_OUT, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIStream_Clone[] = +{ + THOP_IFACE | THOP_OUT, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIStorage_CreateStream[] = +{ + THOP_LPSTR | THOP_IN, THOP_COPY, 4, THOP_COPY, 4, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsIStorage_OpenStream[] = +{ + THOP_LPSTR | THOP_IN, THOP_NULL | THOP_IN, THOP_COPY, 4, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsIStorage_CreateStorage[] = +{ + THOP_LPSTR | THOP_IN, THOP_COPY, 4, THOP_COPY, 4, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsIStorage_OpenStorage[] = +{ + THOP_LPSTR | THOP_IN, THOP_IFACE | THOP_IN, THI_IStorage, THOP_COPY, 4, THOP_SNB, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsIStorage_CopyTo[] = +{ + THOP_CRGIID, THOP_SNB, THOP_IFACE | THOP_IN, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIStorage_MoveElementTo[] = +{ + THOP_LPSTR | THOP_IN, THOP_IFACE | THOP_IN, THI_IStorage, THOP_LPSTR | THOP_IN, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIStorage_Commit[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIStorage_Revert[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIStorage_EnumElements[] = +{ + THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IEnumSTATSTG, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIStorage_DestroyElement[] = +{ + THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIStorage_RenameElement[] = +{ + THOP_LPSTR | THOP_IN, THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIStorage_SetElementTimes[] = +{ + THOP_LPSTR | THOP_IN, THOP_COPY | THOP_IN, 8, THOP_COPY | THOP_IN, 8, THOP_COPY | THOP_IN, 8, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIStorage_SetClass[] = +{ + THOP_COPY | THOP_IN, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIStorage_SetStateBits[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIStorage_Stat[] = +{ + THOP_STATSTG | THOP_OUT, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIRootStorage_SwitchToFile[] = +{ + THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumFORMATETC_Next[] = +{ + THOP_ENUM, THE_IEnumFORMATETC, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIEnumFORMATETC_Skip[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumFORMATETC_Reset[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIEnumFORMATETC_Clone[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumFORMATETC, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumSTATDATA_Next[] = +{ + THOP_ENUM, THE_IEnumSTATDATA, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIEnumSTATDATA_Skip[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumSTATDATA_Reset[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIEnumSTATDATA_Clone[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumSTATDATA, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIDataObject_GetData[] = +{ + THOP_FORMATETC | THOP_IN, THOP_STGMEDIUM | THOP_OUT, 0, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIDataObject_GetDataHere[] = +{ + THOP_FORMATETC | THOP_IN, THOP_STGMEDIUM | THOP_IN, 0, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIDataObject_QueryGetData[] = +{ + THOP_FORMATETC | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIDataObject_GetCanonicalFormatEtc[] = +{ + THOP_FORMATETC | THOP_IN, THOP_FORMATETC | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIDataObject_SetData[] = +{ + THOP_FORMATETC | THOP_IN, THOP_STGMEDIUM | THOP_IN, 1, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIDataObject_EnumFormatEtc[] = +{ + THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IEnumFORMATETC, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIDataObject_DAdvise[] = +{ + THOP_FORMATETC | THOP_IN, THOP_COPY, 4, THOP_IFACE | THOP_IN, THI_IAdviseSink, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIDataObject_DUnadvise[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIDataObject_EnumDAdvise[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumSTATDATA, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIViewObject_Draw[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_DVTARGETDEVICE | THOP_IN, THOP_HGDI, THOP_HGDI, THOP_COPY | THOP_IN, 16, THOP_COPY | THOP_IN, 16, THOP_CALLBACK, THOP_END, THOP_ROUTINEINDEX, 14 +}; +THOP CONST thopsIViewObject_GetColorSet[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_DVTARGETDEVICE | THOP_IN, THOP_HGDI, THOP_LOGPALETTE | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsIViewObject_Freeze[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIViewObject_Unfreeze[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIViewObject_SetAdvise[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_IFACE | THOP_IN, THI_IAdviseSink, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIViewObject_GetAdvise[] = +{ + THOP_COPY | THOP_OUT, 4, THOP_COPY | THOP_OUT, 4, THOP_IFACE | THOP_OUT, THI_IAdviseSink, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIViewObject2_Draw[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_DVTARGETDEVICE | THOP_IN, THOP_HGDI, THOP_HGDI, THOP_COPY | THOP_IN, 16, THOP_COPY | THOP_IN, 16, THOP_CALLBACK, THOP_END, THOP_ROUTINEINDEX, 14 +}; +THOP CONST thopsIViewObject2_GetColorSet[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_DVTARGETDEVICE | THOP_IN, THOP_HGDI, THOP_LOGPALETTE | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsIViewObject2_Freeze[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIViewObject2_Unfreeze[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIViewObject2_SetAdvise[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_IFACE | THOP_IN, THI_IAdviseSink, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIViewObject2_GetAdvise[] = +{ + THOP_COPY | THOP_OUT, 4, THOP_COPY | THOP_OUT, 4, THOP_IFACE | THOP_OUT, THI_IAdviseSink, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIViewObject2_GetExtent[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_DVTARGETDEVICE | THOP_IN, THOP_COPY | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIAdviseSink_OnDataChange[] = +{ + THOP_FORMATETC | THOP_IN, THOP_STGMEDIUM | THOP_IN, 0, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIAdviseSink_OnViewChange[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIAdviseSink_OnRename[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIAdviseSink_OnSave[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIAdviseSink_OnClose[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIAdviseSink2_OnDataChange[] = +{ + THOP_FORMATETC | THOP_IN, THOP_STGMEDIUM | THOP_IN, 0, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIAdviseSink2_OnViewChange[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIAdviseSink2_OnRename[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIAdviseSink2_OnSave[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIAdviseSink2_OnClose[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIAdviseSink2_OnLinkSrcChange[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIDataAdviseHolder_Advise[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_FORMATETC | THOP_IN, THOP_COPY, 4, THOP_IFACE | THOP_IN, THI_IAdviseSink, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsIDataAdviseHolder_Unadvise[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIDataAdviseHolder_EnumAdvise[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumSTATDATA, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIDataAdviseHolder_SendOnDataChange[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_COPY, 4, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleCache_Cache[] = +{ + THOP_FORMATETC | THOP_IN, THOP_COPY, 4, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleCache_Uncache[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleCache_EnumCache[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumSTATDATA, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleCache_InitCache[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleCache_SetData[] = +{ + THOP_FORMATETC | THOP_IN, THOP_STGMEDIUM | THOP_IN, 1, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleCache2_Cache[] = +{ + THOP_FORMATETC | THOP_IN, THOP_COPY, 4, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleCache2_Uncache[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleCache2_EnumCache[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumSTATDATA, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleCache2_InitCache[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleCache2_SetData[] = +{ + THOP_FORMATETC | THOP_IN, THOP_STGMEDIUM | THOP_IN, 1, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleCache2_UpdateCache[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleCache2_DiscardCache[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleCacheControl_OnRun[] = +{ + THOP_IFACENOADDREF | THOP_IN, THI_IDataObject, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleCacheControl_OnStop[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIDropTarget_DragEnter[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_COPY, 4, THOP_COPY, 8, THOP_COPY | THOP_INOUT, 4, THOP_END, THOP_ROUTINEINDEX, 15 +}; +THOP CONST thopsIDropTarget_DragOver[] = +{ + THOP_COPY, 4, THOP_COPY, 8, THOP_COPY | THOP_INOUT, 4, THOP_END, THOP_ROUTINEINDEX, 16 +}; +THOP CONST thopsIDropTarget_DragLeave[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIDropTarget_Drop[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_COPY, 4, THOP_COPY, 8, THOP_COPY | THOP_INOUT, 4, THOP_END, THOP_ROUTINEINDEX, 15 +}; +THOP CONST thopsIDropSource_QueryContinueDrag[] = +{ + THOP_SHORTLONG, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIDropSource_GiveFeedback[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersist_GetClassID[] = +{ + THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersistStorage_GetClassID[] = +{ + THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersistStorage_IsDirty[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIPersistStorage_InitNew[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersistStorage_Load[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersistStorage_Save[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIPersistStorage_SaveCompleted[] = +{ + THOP_IFACE | THOP_IN, THI_IStorage, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersistStorage_HandsOffStorage[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIPersistStream_GetClassID[] = +{ + THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersistStream_IsDirty[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIPersistStream_Load[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersistStream_Save[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIPersistStream_GetSizeMax[] = +{ + THOP_COPY | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersistFile_GetClassID[] = +{ + THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersistFile_IsDirty[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIPersistFile_Load[] = +{ + THOP_FILENAME | THOP_IN, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIPersistFile_Save[] = +{ + THOP_FILENAME | THOP_IN, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIPersistFile_SaveCompleted[] = +{ + THOP_FILENAME | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPersistFile_GetCurFile[] = +{ + THOP_FILENAME | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIBindCtx_RegisterObjectBound[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIBindCtx_RevokeObjectBound[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIBindCtx_ReleaseBoundObjects[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIBindCtx_SetBindOptions[] = +{ + THOP_BINDOPTS | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIBindCtx_GetBindOptions[] = +{ + THOP_BINDOPTS | THOP_INOUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIBindCtx_GetRunningObjectTable[] = +{ + THOP_IFACE | THOP_OUT, THI_IRunningObjectTable, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIBindCtx_RegisterObjectParam[] = +{ + THOP_LPSTR | THOP_IN, THOP_IFACE | THOP_IN, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIBindCtx_GetObjectParam[] = +{ + THOP_LPSTR | THOP_IN, THOP_IFACE | THOP_OUT, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIBindCtx_EnumObjectParam[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumString, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIBindCtx_RevokeObjectParam[] = +{ + THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIMoniker_GetClassID[] = +{ + THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIMoniker_IsDirty[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIMoniker_Load[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIMoniker_Save[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIMoniker_GetSizeMax[] = +{ + THOP_COPY | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIMoniker_BindToObject[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIMoniker_BindToStorage[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIMoniker_Reduce[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_COPY, 4, THOP_IFACE | THOP_INOUT, THI_IMoniker, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIMoniker_ComposeWith[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_SHORTLONG, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIMoniker_Enum[] = +{ + THOP_SHORTLONG, THOP_IFACE | THOP_OUT, THI_IEnumMoniker, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIMoniker_IsEqual[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIMoniker_Hash[] = +{ + THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIMoniker_IsRunning[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIMoniker_GetTimeOfLastChange[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_COPY | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIMoniker_Inverse[] = +{ + THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIMoniker_CommonPrefixWith[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIMoniker_RelativePathTo[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIMoniker_GetDisplayName[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_LPLPSTR, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIMoniker_ParseDisplayName[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_LPSTR | THOP_IN, THOP_COPY | THOP_OUT, 4, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsIMoniker_IsSystemMoniker[] = +{ + THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRunningObjectTable_Register[] = +{ + THOP_COPY, 4, THOP_IFACE | THOP_IN, THI_IUnknown, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIRunningObjectTable_Revoke[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRunningObjectTable_IsRunning[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRunningObjectTable_GetObject[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_IFACE | THOP_OUT, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIRunningObjectTable_NoteChangeTime[] = +{ + THOP_COPY, 4, THOP_COPY | THOP_IN, 8, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIRunningObjectTable_GetTimeOfLastChange[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_COPY | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIRunningObjectTable_EnumRunning[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumMoniker_Next[] = +{ + THOP_ENUM, THE_IEnumMoniker, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIEnumMoniker_Skip[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumMoniker_Reset[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIEnumMoniker_Clone[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumOLEVERB_Next[] = +{ + THOP_ENUM, THE_IEnumOLEVERB, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIEnumOLEVERB_Skip[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIEnumOLEVERB_Reset[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIEnumOLEVERB_Clone[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumOLEVERB, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleObject_SetClientSite[] = +{ + THOP_IFACE | THOP_IN, THI_IOleClientSite, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleObject_GetClientSite[] = +{ + THOP_IFACE | THOP_OUT, THI_IOleClientSite, THOP_END, THOP_ROUTINEINDEX, 3 +}; +/* + The eighty character limit was arrived at by trial and error + with ClipArt Gallery. It faults at 90 characters. + */ +THOP CONST thopsIOleObject_SetHostNames[] = +{ + THOP_LPSTR | THOP_IN, THOP_SIZEDSTRING | THOP_IN, 80, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleObject_Close[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleObject_SetMoniker[] = +{ + THOP_COPY, 4, THOP_IFACE | THOP_IN, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleObject_GetMoniker[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleObject_InitFromData[] = +{ + THOP_IFACE | THOP_IN, THI_IDataObject, THOP_SHORTLONG, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleObject_GetClipboardData[] = +{ + THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IDataObject, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleObject_DoVerb[] = +{ + THOP_COPY, 4, THOP_MSG | THOP_IN, THOP_IFACE | THOP_IN, THI_IOleClientSite, THOP_COPY, 4, THOP_HUSER, THOP_RECT | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsIOleObject_EnumVerbs[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumOLEVERB, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleObject_Update[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleObject_IsUpToDate[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleObject_GetUserClassID[] = +{ + THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleObject_GetUserType[] = +{ + THOP_COPY, 4, THOP_LPLPSTR, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleObject_SetExtent[] = +{ + THOP_COPY, 4, THOP_COPY | THOP_IN, 8, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleObject_GetExtent[] = +{ + THOP_COPY, 4, THOP_COPY | THOP_OUT, 8, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleObject_Advise[] = +{ + THOP_IFACE | THOP_IN, THI_IAdviseSink, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleObject_Unadvise[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleObject_EnumAdvise[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumSTATDATA, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleObject_GetMiscStatus[] = +{ + THOP_COPY, 4, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleObject_SetColorScheme[] = +{ + THOP_LOGPALETTE | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleClientSite_SaveObject[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleClientSite_GetMoniker[] = +{ + THOP_COPY, 4, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleClientSite_GetContainer[] = +{ + THOP_IFACE | THOP_OUT, THI_IOleContainer, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleClientSite_ShowObject[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleClientSite_OnShowWindow[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleClientSite_RequestNewObjectLayout[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIRunnableObject_GetRunningClass[] = +{ + THOP_COPY | THOP_OUT, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRunnableObject_Run[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRunnableObject_IsRunning[] = +{ + THOP_RETURNTYPE, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIRunnableObject_LockRunning[] = +{ + THOP_SHORTLONG, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIRunnableObject_SetContainedObject[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIParseDisplayName_ParseDisplayName[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_LPSTR | THOP_IN, THOP_COPY | THOP_OUT, 4, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIOleContainer_ParseDisplayName[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_LPSTR | THOP_IN, THOP_COPY | THOP_OUT, 4, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIOleContainer_EnumObjects[] = +{ + THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IEnumUnknown, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleContainer_LockContainer[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleItemContainer_ParseDisplayName[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_LPSTR | THOP_IN, THOP_COPY | THOP_OUT, 4, THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIOleItemContainer_EnumObjects[] = +{ + THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IEnumUnknown, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleItemContainer_LockContainer[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleItemContainer_GetObject[] = +{ + THOP_LPSTR | THOP_IN, THOP_COPY, 4, THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsIOleItemContainer_GetObjectStorage[] = +{ + THOP_LPSTR | THOP_IN, THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_COPY | THOP_IN, 16, THOP_IFACEGEN | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIOleItemContainer_IsRunning[] = +{ + THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleAdviseHolder_Advise[] = +{ + THOP_IFACE | THOP_IN, THI_IAdviseSink, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleAdviseHolder_Unadvise[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleAdviseHolder_EnumAdvise[] = +{ + THOP_IFACE | THOP_OUT, THI_IEnumSTATDATA, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleAdviseHolder_SendOnRename[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleAdviseHolder_SendOnSave[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleAdviseHolder_SendOnClose[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleLink_SetUpdateOptions[] = +{ + THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleLink_GetUpdateOptions[] = +{ + THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleLink_SetSourceMoniker[] = +{ + THOP_IFACE | THOP_IN, THI_IMoniker, THOP_COPY | THOP_IN, 16, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleLink_GetSourceMoniker[] = +{ + THOP_IFACE | THOP_OUT, THI_IMoniker, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleLink_SetSourceDisplayName[] = +{ + THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleLink_GetSourceDisplayName[] = +{ + THOP_LPLPSTR, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleLink_BindToSource[] = +{ + THOP_COPY, 4, THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleLink_BindIfRunning[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleLink_GetBoundSource[] = +{ + THOP_IFACE | THOP_OUT, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleLink_UnbindSource[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleLink_Update[] = +{ + THOP_IFACE | THOP_IN, THI_IBindCtx, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleWindow_GetWindow[] = +{ + THOP_HUSER | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleWindow_ContextSensitiveHelp[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceObject_GetWindow[] = +{ + THOP_HUSER | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceObject_ContextSensitiveHelp[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceObject_InPlaceDeactivate[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleInPlaceObject_UIDeactivate[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleInPlaceObject_SetObjectRects[] = +{ + THOP_RECT | THOP_IN, THOP_RECT | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleInPlaceObject_ReactivateAndUndo[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleInPlaceActiveObject_GetWindow[] = +{ + THOP_HUSER | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceActiveObject_ContextSensitiveHelp[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceActiveObject_TranslateAccelerator[] = +{ + THOP_MSG | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceActiveObject_OnFrameWindowActivate[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceActiveObject_OnDocWindowActivate[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceActiveObject_ResizeBorder[] = +{ + THOP_RECT | THOP_IN, THOP_IFACE | THOP_IN, THI_IOleInPlaceFrame, THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleInPlaceActiveObject_EnableModeless[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceUIWindow_GetWindow[] = +{ + THOP_HUSER | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceUIWindow_ContextSensitiveHelp[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceUIWindow_GetBorder[] = +{ + THOP_RECT | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceUIWindow_RequestBorderSpace[] = +{ + THOP_RECT | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceUIWindow_SetBorderSpace[] = +{ + THOP_RECT | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceUIWindow_SetActiveObject[] = +{ + THOP_IFACE | THOP_IN, THI_IOleInPlaceActiveObject, THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleInPlaceFrame_GetWindow[] = +{ + THOP_HUSER | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceFrame_ContextSensitiveHelp[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceFrame_GetBorder[] = +{ + THOP_RECT | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceFrame_RequestBorderSpace[] = +{ + THOP_RECT | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceFrame_SetBorderSpace[] = +{ + THOP_RECT | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceFrame_SetActiveObject[] = +{ + THOP_IFACE | THOP_IN, THI_IOleInPlaceActiveObject, THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleInPlaceFrame_InsertMenus[] = +{ + THOP_HUSER, THOP_COPY | THOP_INOUT, 24, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIOleInPlaceFrame_SetMenu[] = +{ + THOP_HUSER, THOP_ALIAS32, ALIAS_RESOLVE, THOP_HUSER, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIOleInPlaceFrame_RemoveMenus[] = +{ + THOP_HUSER, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceFrame_SetStatusText[] = +{ + THOP_LPSTR | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceFrame_EnableModeless[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceFrame_TranslateAccelerator[] = +{ + THOP_MSG | THOP_IN, THOP_WORDDWORD, THOP_END, THOP_ROUTINEINDEX, 17 +}; +THOP CONST thopsIOleInPlaceSite_GetWindow[] = +{ + THOP_HUSER | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceSite_ContextSensitiveHelp[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceSite_CanInPlaceActivate[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleInPlaceSite_OnInPlaceActivate[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleInPlaceSite_OnUIActivate[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleInPlaceSite_GetWindowContext[] = +{ + THOP_IFACE | THOP_OUT, THI_IOleInPlaceFrame, THOP_IFACE | THOP_OUT, THI_IOleInPlaceUIWindow, THOP_RECT | THOP_OUT, THOP_RECT | THOP_OUT, THOP_OIFI | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsIOleInPlaceSite_Scroll[] = +{ + THOP_SIZE, THOP_END, THOP_ROUTINEINDEX, 18 +}; +THOP CONST thopsIOleInPlaceSite_OnUIDeactivate[] = +{ + THOP_SHORTLONG, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIOleInPlaceSite_OnInPlaceDeactivate[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleInPlaceSite_DiscardUndoState[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleInPlaceSite_DeactivateAndUndo[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIOleInPlaceSite_OnPosRectChange[] = +{ + THOP_RECT | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRpcChannelBuffer_GetBuffer[] = +{ + THOP_RPCOLEMESSAGE | THOP_INOUT, THOP_COPY | THOP_IN, 16, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIRpcChannelBuffer_SendReceive[] = +{ + THOP_RPCOLEMESSAGE | THOP_INOUT, THOP_COPY | THOP_OUT, 4, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIRpcChannelBuffer_FreeBuffer[] = +{ + THOP_RPCOLEMESSAGE | THOP_INOUT, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRpcChannelBuffer_GetDestCtx[] = +{ + THOP_COPY | THOP_OUT, 4, THOP_NULL | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIRpcChannelBuffer_IsConnected[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIRpcProxyBuffer_Connect[] = +{ + THOP_IFACE | THOP_IN, THI_IRpcChannelBuffer, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRpcProxyBuffer_Disconnect[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIRpcStubBuffer_Connect[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRpcStubBuffer_Disconnect[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIRpcStubBuffer_Invoke[] = +{ + THOP_RPCOLEMESSAGE | THOP_INOUT, THOP_IFACE | THOP_IN, THI_IRpcChannelBuffer, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIRpcStubBuffer_IsIIDSupported[] = +{ + THOP_RETURNTYPE, THOP_IFACE | THOP_IN, THI_IRpcStubBuffer, THOP_COPY | THOP_IN, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRpcStubBuffer_CountRefs[] = +{ + THOP_RETURNTYPE, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIRpcStubBuffer_DebugServerQueryInterface[] = +{ + THOP_IFACE | THOP_OUT, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRpcStubBuffer_DebugServerRelease[] = +{ + THOP_IFACECLEAN | THOP_IN, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIPSFactoryBuffer_CreateProxy[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_COPY | THOP_IN, 16, THOP_IFACEOWNER | THOP_OUT, THI_IRpcProxyBuffer, 8, THOP_IFACEGENOWNER | THOP_OUT, 8, 12, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIPSFactoryBuffer_CreateStub[] = +{ + THOP_COPY | THOP_IN, 16, THOP_IFACE | THOP_IN, THI_IUnknown, THOP_IFACEOWNER | THOP_OUT, THI_IRpcStubBuffer, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; +THOP CONST thopsIRpcChannel_GetStream[] = +{ + THOP_COPY | THOP_IN, 16, THOP_SHORTLONG, THOP_SHORTLONG, THOP_SHORTLONG, THOP_COPY, 4, THOP_IFACE | THOP_OUT, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 4 +}; +THOP CONST thopsIRpcChannel_Call[] = +{ + THOP_IFACE | THOP_IN, THI_IStream, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRpcChannel_GetDestCtx[] = +{ + THOP_COPY | THOP_OUT, 4, THOP_NULL | THOP_OUT, THOP_END, THOP_ROUTINEINDEX, 0 +}; +THOP CONST thopsIRpcChannel_IsConnected[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIRpcProxy_Connect[] = +{ + THOP_IFACE | THOP_IN, THI_IRpcChannel, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRpcProxy_Disconnect[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIRpcStub_Connect[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRpcStub_Disconnect[] = +{ + THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIRpcStub_Invoke[] = +{ + THOP_COPY | THOP_IN, 16, THOP_SHORTLONG, THOP_IFACE | THOP_IN, THI_IStream, THOP_COPY, 4, THOP_NULL | THOP_IN, THOP_END, THOP_ROUTINEINDEX, 7 +}; +THOP CONST thopsIRpcStub_IsIIDSupported[] = +{ + THOP_RETURNTYPE, THOP_SHORTLONG, THOP_COPY | THOP_IN, 16, THOP_END, THOP_ROUTINEINDEX, 3 +}; +THOP CONST thopsIRpcStub_CountRefs[] = +{ + THOP_RETURNTYPE, THOP_COPY, 4, THOP_END, THOP_ROUTINEINDEX, 1 +}; +THOP CONST thopsIPSFactory_CreateProxy[] = +{ + THOP_IFACE | THOP_IN, THI_IUnknown, THOP_COPY | THOP_IN, 16, THOP_IFACEOWNER | THOP_OUT, THI_IRpcProxy, 8, THOP_IFACEGENOWNER | THOP_OUT, 8, 12, THOP_END, THOP_ROUTINEINDEX, 5 +}; +THOP CONST thopsIPSFactory_CreateStub[] = +{ + THOP_COPY | THOP_IN, 16, THOP_IFACE | THOP_IN, THI_IUnknown, THOP_IFACEOWNER | THOP_OUT, THI_IRpcStub, 4, THOP_END, THOP_ROUTINEINDEX, 2 +}; diff --git a/private/ole32/olethunk/olethk32/thoputil.cxx b/private/ole32/olethunk/olethk32/thoputil.cxx new file mode 100644 index 000000000..da4f424b6 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thoputil.cxx @@ -0,0 +1,4547 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thoputil.cxx +// +// Contents: Utility routines for thunking +// +// History: 01-Mar-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#include "headers.cxx" +#pragma hdrstop + +#include <stdio.h> +#include <limits.h> + +#include <vdmdbg.h> +#include <valid.h> + +// +// Chicago doesn't support the NT ExpLdr API, use the new Chicago +// WOWGetDescriptor that copies the LDT info to a provided buffer. +// +#if defined(_CHICAGO_) +extern "C" WOWGetDescriptor(VPVOID, VDMLDT_ENTRY *); +#else +extern "C" DECLSPEC_IMPORT VDMLDT_ENTRY *ExpLdt; +#endif + +#include "struct16.hxx" + +#define CF_INVALID ((CLIPFORMAT)0) + +#define OBJDESC_CF(cf) \ + ((cf) == g_cfObjectDescriptor || (cf) == g_cfLinkSourceDescriptor) + +// Alias manager for THOP_ALIAS32 +CAliases gAliases32; + +//+--------------------------------------------------------------------------- +// +// Function: IidToIidIdx, public +// +// Synopsis: Looks up an interface index by IID +// If it's not found, it returns the IID pointer +// +// Arguments: [riid] - IID +// +// Returns: Index or IID +// +// History: 23-Feb-94 DrewB Created +// +//---------------------------------------------------------------------------- + +IIDIDX IidToIidIdx(REFIID riid) +{ + int idx; + + for (idx = 0; idx < THI_COUNT; idx++) + { + if (IsEqualIID(riid, *aittIidToThi[idx].piid)) + { + return INDEX_IIDIDX(aittIidToThi[idx].iThi); + } + } + + return IID_IIDIDX(&riid); +} + +//+--------------------------------------------------------------------------- +// +// Function: TaskMalloc32, public +// +// Synopsis: Task allocation for 32-bits +// +// History: 01-Mar-94 DrewB Created +// +// Notes: Temporary until CoTaskMemAlloc is hooked up +// +//---------------------------------------------------------------------------- + +#ifndef COTASK_DEFINED +LPVOID TaskMalloc32(DWORD cb) +{ + IMalloc *pm; + LPVOID pv; + + if (FAILED(GetScode(CoGetMalloc(MEMCTX_TASK, &pm)))) + { + return NULL; + } + else + { + pv = pm->Alloc(cb); + pm->Release(); + } + return pv; +} + +//+--------------------------------------------------------------------------- +// +// Function: TaskFree32, public +// +// Synopsis: Task free for 32-bits +// +// History: 01-Mar-94 DrewB Created +// +// Notes: Temporary until CoTaskMemAlloc is hooked up +// +//---------------------------------------------------------------------------- + +void TaskFree32(LPVOID pv) +{ + IMalloc *pm; + + if (FAILED(GetScode(CoGetMalloc(MEMCTX_TASK, &pm)))) + { + thkAssert(!"CoGetMalloc failed"); + } + else + { + pm->Free(pv); + pm->Release(); + } +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: TaskMalloc16, public +// +// Synopsis: Allocates 16-bit task memory +// +// Arguments: [uiSize] - Amount of memory to allocate +// +// Returns: VPVOID for memory allocated +// +// History: 01-Mar-94 DrewB Created +// +//---------------------------------------------------------------------------- + +DWORD TaskMalloc16( UINT uiSize ) +{ + return CallbackTo16(gdata16Data.fnTaskAlloc, uiSize); +} + +//+--------------------------------------------------------------------------- +// +// Function: TaskFree16, public +// +// Synopsis: Frees 16-bit task memory +// +// Arguments: [vpvoid] - VPVOID of allocated memory +// +// History: 01-Mar-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void TaskFree16( DWORD vpvoid ) +{ + CallbackTo16(gdata16Data.fnTaskFree, vpvoid); +} + +// List of 16/32 HRESULT mappings for mapping functions +struct SHrMapping +{ + HRESULT hr16; + HRESULT hr32; +}; + +// Since we're including 32-bit headers in this code we can use +// the defines for the 32-bit values but we must specify the +// 16-bit values explicitly +static SHrMapping hmMappings[] = +{ + 0x80000001, E_NOTIMPL, + 0x80000002, E_OUTOFMEMORY, + 0x80000003, E_INVALIDARG, + 0x80000004, E_NOINTERFACE, + 0x80000005, E_POINTER, + 0x80000006, E_HANDLE, + 0x80000007, E_ABORT, + 0x80000008, E_FAIL, + 0x80000009, E_ACCESSDENIED +}; +#define NMAPPINGS (sizeof(hmMappings)/sizeof(hmMappings[0])) + +#define HR16_ERROR 0x80000000 +#define HR16_MAP_FIRST 1 +#define HR16_MAP_LAST 9 + +//+--------------------------------------------------------------------------- +// +// Function: TransformHRESULT_1632, public +// +// Synopsis: Translates a 16-bit hresult into a 32-bit hresult +// +// Arguments: [hresult] - 16-bit hresult to transform +// +// History: 15-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +STDAPI_(DWORD) TransformHRESULT_1632( DWORD hresult ) +{ + ULONG ulIndex; + + // We only map error codes + if (hresult & HR16_ERROR) + { + // The 16-bit HRESULTs to be mapped are known quantities + // whose values are sequential, so we can map directly from + // the value to an array index + + ulIndex = hresult & ~HR16_ERROR; + if (ulIndex >= HR16_MAP_FIRST && ulIndex <= HR16_MAP_LAST) + { + // Known value, index array to find 32-bit HRESULT + return hmMappings[ulIndex-HR16_MAP_FIRST].hr32; + } + } + + // No mapping found, so return the original + return hresult; +} + +//+--------------------------------------------------------------------------- +// +// Function: TransformHRESULT_3216, public +// +// Synopsis: Translates a 32-bit hresult into a 16-bit hresult +// +// Arguments: [hresult] - 32-bit hresult to transform +// +// History: 15-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +STDAPI_(DWORD) TransformHRESULT_3216( DWORD hresult ) +{ + int i; + SHrMapping *phm; + + // We don't know the true values of 32-bit HRESULTs since we're + // using the defines and they may change, so we have to look up + // the hard way + + phm = hmMappings; + for (i = 0; i < NMAPPINGS; i++) + { + if (phm->hr32 == (HRESULT)hresult) + { + return phm->hr16; + } + + phm++; + } + + // No mapping found, so return the original + return hresult; +} + +//+--------------------------------------------------------------------------- +// +// Function: RecordStackState, public debug +// +// Synopsis: Records the current state of the stack +// +// Arguments: [psr] - Storage space for information +// +// Modifies: [psr] +// +// History: 28-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +void RecordStackState16(SStackRecord *psr) +{ + CStackAllocator *psa; + + psa = TlsThkGetStack16(); + psa->RecordState(psr); +} + +void RecordStackState32(SStackRecord *psr) +{ + CStackAllocator *psa; + + psa = TlsThkGetStack32(); + psa->RecordState(psr); +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: CheckStackState, public debug +// +// Synopsis: Checks recorded information about the stack against its +// current state +// +// Arguments: [psr] - Recorded information +// +// History: 28-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +void CheckStackState16(SStackRecord *psr) +{ + CStackAllocator *psa; + + psa = TlsThkGetStack16(); + psa->CheckState(psr); +} + +void CheckStackState32(SStackRecord *psr) +{ + CStackAllocator *psa; + + psa = TlsThkGetStack32(); + psa->CheckState(psr); +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: Convert_VPSTR_to_LPOLESTR +// +// Synopsis: Converts 16-bit VPSTR to 32-bit LPOLESTR pointer +// +// Arguments: [vpstr] - VPSTR +// [lpOleStr] - OLESTR +// [uiSizeInPlace] - Amount of data available in [lpOleStr] +// for in-place conversion (in characters, not bytes) +// including nul +// +// Returns: Pointer to LPOLESTR with data +// +// History: 24-Feb-94 BobDay Created +// +//---------------------------------------------------------------------------- + +LPOLESTR Convert_VPSTR_to_LPOLESTR( + THUNKINFO *pti, + VPSTR vpstr, + LPOLESTR lpOleStr, + UINT uiSizeInPlace +) +{ + LPSTR lpstr; + UINT uiSize; + LPOLESTR lpOleStrResult; + UINT cChars; + + // We shouldn't be calling here for null strings + thkAssert( vpstr != NULL ); + + lpstr = GetStringPtr16(pti, vpstr, CCHMAXSTRING, &uiSize); + if ( lpstr == NULL ) + { + // + // GetStringPtr will have filled in the pti->scResult + // + return( NULL ); + } + + // The string has to have at least one character in it + // because it must be null-terminated to be valid + thkAssert(uiSize > 0); + + lpOleStrResult = lpOleStr; + + if ( uiSize > uiSizeInPlace ) + { + lpOleStrResult = (LPOLESTR)TaskMalloc32(uiSize*sizeof(OLECHAR)); + if (lpOleStrResult == NULL) + { + pti->scResult = E_OUTOFMEMORY; + return NULL; + } + } + + cChars = MultiByteToWideChar( AreFileApisANSI() ? CP_ACP : CP_OEMCP, + 0, + lpstr, + uiSize, + lpOleStrResult, + uiSize ); + + WOWRELVDMPTR(vpstr); + + if ( cChars == 0 ) + { + if (lpOleStrResult != lpOleStr) + { + TaskFree32(lpOleStrResult); + } + + pti->scResult = E_UNEXPECTED; + return( NULL ); + } + else + { + return( lpOleStrResult ); + } +} +//+--------------------------------------------------------------------------- +// +// Function: Convert_LPOLESTR_to_VPSTR +// +// Synopsis: Converts 32-bit LPOLESTR to 16-bit VPSTR pointer +// +// Arguments: [lpOleStr] - OLESTR +// [vpstr] - VPSTR +// [uiSize32] - Length of OLESTR in characters (not bytes) +// including nul +// [uiSize16] - Byte length of buffer referred to by VPSTR +// +// Returns: Appropriate status code +// +// History: 24-Feb-94 BobDay Created +// +// Notes: Always converts in place +// +//---------------------------------------------------------------------------- + +SCODE Convert_LPOLESTR_to_VPSTR( + LPCOLESTR lpOleStr, + VPSTR vpstr, + UINT uiSize32, + UINT uiSize16 +) +{ + LPSTR lpstr; + UINT cChars; + SCODE sc; + + sc = S_OK; + + lpstr = (LPSTR)WOWFIXVDMPTR(vpstr, uiSize16); + + cChars = WideCharToMultiByte( AreFileApisANSI() ? CP_ACP : CP_OEMCP, + 0, + lpOleStr, + uiSize32, + lpstr, + uiSize16, + NULL, + NULL ); + + if ( cChars == 0 && uiSize32 != 0 ) + { + sc = E_UNEXPECTED; + } + + WOWRELVDMPTR(vpstr); + + return sc; +} +#ifdef _CHICAGO_ +//+--------------------------------------------------------------------------- +// +// Function: Convert_LPSTR_to_VPSTR +// +// Synopsis: Converts 32-bit LPSTR to 16-bit VPSTR pointer +// +// Arguments: [lpOleStr] - LPSTR +// [vpstr] - VPSTR +// [uiSize32] - Length of LPSTR in bytes including nul +// [uiSize16] - Byte length of buffer referred to by VPSTR +// +// Returns: Appropriate status code +// +// History: 10-21-95 KevinRo Created +// +// Notes: +// +//---------------------------------------------------------------------------- + +SCODE Convert_LPSTR_to_VPSTR( + LPCSTR lpOleStr, + VPSTR vpstr, + UINT uiSize32, + UINT uiSize16 +) +{ + LPSTR lpstr; + + lpstr = (LPSTR)WOWFIXVDMPTR(vpstr, uiSize16); + + memcpy(lpstr,lpOleStr,uiSize32); + + WOWRELVDMPTR(vpstr); + + return S_OK; +} +#endif // _CHICAGO_ + +// Selector bit constants +#define SEL_TI 0x0004 +#define SEL_RPL 0x0003 +#define SEL_INDEX 0xfff8 + +#define IS_LDT_SELECTOR(sel) (((sel) & SEL_TI) == SEL_TI) + +// LDT bit constants +#define LTYPE_APP 0x0010 +#define LTYPE_CODE 0x0008 +#define LTYPE_CREAD 0x0002 +#define LTYPE_DDOWN 0x0004 +#define LTYPE_DWRITE 0x0002 + +// Pointer access types, or'able +// Defined to be the same as thop in/out so that no translation +// is necessary for checks on thop memory access +#define PACC_READ THOP_IN +#define PACC_WRITE THOP_OUT +#define PACC_CODE 1 // Special for CODE PTRs + +// Information about a VDM pointer +typedef struct _VPTRDESC +{ + BYTE *pbFlat; + DWORD dwLengthLeft; +} VPTRDESC; + +// VDM memory is always zero-based on Win95 +#ifndef _CHICAGO_ +DWORD dwBaseVDMMemory = 0xFFFFFFFF; +#else +#define dwBaseVDMMemory 0 +#endif + +// Extended success returns from GetPtr16Description +#define S_GDTENTRY MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_NULL, 1) +#define S_SYSLDTENTRY MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_NULL, 2) + +//+--------------------------------------------------------------------------- +// +// Function: GetPtr16Description, public +// +// Synopsis: Validates access for a VDM pointer and returns +// information about it +// Also forces not-present segments into memory by +// touching them +// +// Arguments: [vp] - VDM pointer +// [grfAccess] - Desired access +// [dwSize] - Desired size of access, must be >= 1 +// [pvpd] - VPTRDESC out +// +// Returns: Appropriate status code +// +// Modifies: [pvpd] +// +// History: 26-Apr-94 DrewB Created +// +// Notes: Returns fixed memory +// +//---------------------------------------------------------------------------- + +SCODE GetPtr16Description(VPVOID vp, + WORD grfAccess, + DWORD dwSize, + VPTRDESC *pvpd) +{ + VDMLDT_ENTRY *vle; +#if defined(_CHICAGO_) + VDMLDT_ENTRY LdtEntry; +#endif + WORD wSel; + WORD wOff; + DWORD dwLength; + + thkAssert(vp != 0); + thkAssert(dwSize > 0); + thkAssert(grfAccess != 0); + + wSel = (WORD)(vp >> 16); + wOff = (WORD)(vp & 0xffff); + + pvpd->dwLengthLeft = 0xffff-wOff+1; // Default length remaining + + if (!IS_LDT_SELECTOR(wSel)) + { + // According to the WOW developers, the only GDT selector + // is for the BIOS data area so we should never see one + + thkDebugOut((DEB_ERROR, "GDT selector: 0x%04X\n", wSel)); + + // Handle it just in case + pvpd->pbFlat = (BYTE *)WOWFIXVDMPTR(vp, dwSize); + + return S_GDTENTRY; + } + +#if defined(_CHICAGO_) + vle = &LdtEntry; + if (!WOWGetDescriptor(vp, vle)) + { + return E_INVALIDARG; + } +#else + vle = (VDMLDT_ENTRY *)((BYTE *)(ExpLdt)+(wSel & SEL_INDEX)); +#endif + + if ((vle->HighWord.Bits.Type & LTYPE_APP) == 0) + { + // According to the WOW developers, they don't use + // system segments so we should never see one + + thkDebugOut((DEB_ERROR, "System descriptor: 0x%04X\n", wSel)); + + // Handle it just in case + pvpd->pbFlat = (BYTE *)WOWFIXVDMPTR(vp, dwSize); + + return S_SYSLDTENTRY; + } + + // Do as much up-front validation as possible + // Since the segment may not be present, we are restricted to + // only checking the access permissions + + if (vle->HighWord.Bits.Type & LTYPE_CODE) + { + // Validate access for code segments + // Code segments are never writable + + if (((grfAccess & PACC_READ) && + (vle->HighWord.Bits.Type & LTYPE_CREAD) == 0) || + (grfAccess & PACC_WRITE)) + { + return E_INVALIDARG; + } + } + else + { + // Validate access for data segments + // Data segments are always readable never executable + + if (((grfAccess & PACC_WRITE) && + (vle->HighWord.Bits.Type & LTYPE_DWRITE) == 0) || + (grfAccess & PACC_CODE)) + { + return E_INVALIDARG; + } + } + + // Bring in segment if it's not present + if (!vle->HighWord.Bits.Pres) + { + // We've validated access permissions and segments must + // always be at least one byte long so it's safe to + // touch the first byte to bring it in + + // On Win95, this will call GlobalFix on the pointer + // to ensure that it stays in memory + WOWCallback16(gdata16Data.fnTouchPointer16, vp); + +#if defined(_CHICAGO_) + // Since we only copy the descriptor, recopy it now. + WOWGetDescriptor(vp, vle); +#endif + + thkAssert(vle->HighWord.Bits.Pres); + } +#ifdef _CHICAGO_ + else + { + // Lock the LDT entry (as best as we can) by fixing it + // This prevents global blocks from being relocated during + // heap compaction + WOWGetVDMPointerFix(vp, dwSize, TRUE); + } +#endif + + + dwLength = ((DWORD)vle->LimitLow | + ((DWORD)vle->HighWord.Bits.LimitHi << 16))+1; + if (vle->HighWord.Bits.Granularity) + { + // 4K granularity + dwLength <<= 12; + } + + if ((vle->HighWord.Bits.Type & LTYPE_CODE) || + (vle->HighWord.Bits.Type & LTYPE_DDOWN) == 0) + { + // Validate length for code and normal data segments + + if (wOff+dwSize > dwLength) + { + WOWRELVDMPTR(vp); + return E_INVALIDARG; + } + + pvpd->dwLengthLeft = dwLength-wOff; + } + else + { + // Expand-down segment + + if (wOff < dwLength) + { + WOWRELVDMPTR(vp); + return E_INVALIDARG; + } + + // Check for wraparound + + if (vle->HighWord.Bits.Granularity) + { + // BUGBUG - Compiler - This should be +1, but + // the compiler generates a warning about an overflow + // in constant arithmetic + pvpd->dwLengthLeft = 0xffffffff-wOff; + } + + if (dwSize > pvpd->dwLengthLeft) + { + WOWRELVDMPTR(vp); + return E_INVALIDARG; + } + } + + // VDM memory is always zero-based on Win95 +#ifndef _CHICAGO_ + if ( dwBaseVDMMemory == 0xFFFFFFFF ) + { + dwBaseVDMMemory = (DWORD)WOWGetVDMPointer(0, 0, FALSE); + } +#endif + + // Translate the pointer even on Win95 because forcing the segment + // present may have changed its address + pvpd->pbFlat = (BYTE *)(dwBaseVDMMemory + + wOff + + ( (DWORD)vle->BaseLow | + ( (DWORD)vle->HighWord.Bytes.BaseMid << 16) | + ( (DWORD)vle->HighWord.Bytes.BaseHi << 24) ) ); + +#if DBG == 1 + if (pvpd->pbFlat != WOWGetVDMPointer(vp, dwSize, TRUE)) + { + thkDebugOut((DEB_ERROR, "GetPtr16Description: " + "%p computed, %p system\n", + pvpd->pbFlat, WOWGetVDMPointer(vp, dwSize, TRUE))); + } +#endif + + return S_OK; +} + +//+--------------------------------------------------------------------------- +// +// Function: GetReadPtr16 +// +// Synopsis: Validates a 16-bit pointer for reading and converts it into +// a flat 32 pointer. +// +// Arguments: [pti] - THUNKINFO * for updating error code +// [vp] - 16-bit pointer to validate/convert +// [dwSize] - Length to validate +// +// Returns: Appropriate status code +// +// History: 22-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +VOID * +GetReadPtr16( + THUNKINFO *pti, + VPVOID vp, + DWORD dwSize ) +{ + VPTRDESC vpd; + SCODE sc; + + sc = GetPtr16Description(vp, PACC_READ, dwSize, &vpd); + if (FAILED(sc)) + { + pti->scResult = sc; + return NULL; + } + else + { + return vpd.pbFlat; + } +} + +//+--------------------------------------------------------------------------- +// +// Function: GetWritePtr16 +// +// Synopsis: Validates a 16-bit pointer for writing and converts it into +// a flat 32 pointer. +// +// Arguments: [pti] - THUNKINFO * for updating error code +// [vp] - 16-bit pointer to validate/convert +// [dwSize] - Length to validate +// +// Returns: Appropriate status code +// +// History: 22-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +VOID * +GetWritePtr16( + THUNKINFO *pti, + VPVOID vp, + DWORD dwSize ) +{ + VPTRDESC vpd; + SCODE sc; + + sc = GetPtr16Description(vp, PACC_WRITE, dwSize, &vpd); + if (FAILED(sc)) + { + pti->scResult = sc; + return NULL; + } + else + { + return vpd.pbFlat; + } +} + +//+--------------------------------------------------------------------------- +// +// Function: GetCodePtr16 +// +// Synopsis: Validates a 16-bit pointer for execution and converts it +// into a flat 32 pointer. +// +// Arguments: [pti] - THUNKINFO * for updating error code +// [vp] - 16-bit pointer to validate/convert +// [dwSize] - Length to validate +// +// Returns: Appropriate status code +// +// History: 22-Jul-94 BobDay Created +// +//---------------------------------------------------------------------------- + +VOID * +GetCodePtr16( + THUNKINFO *pti, + VPVOID vp, + DWORD dwSize ) +{ + VPTRDESC vpd; + SCODE sc; + + sc = GetPtr16Description(vp, PACC_CODE, dwSize, &vpd); + if (FAILED(sc)) + { + pti->scResult = sc; + return NULL; + } + else + { + return vpd.pbFlat; + } +} + +//+--------------------------------------------------------------------------- +// +// Function: GetReadWritePtr16 +// +// Synopsis: Validates a 16-bit pointer for reading and writing and +// converts it into a flat 32 pointer. +// +// Arguments: [pti] - THUNKINFO * for updating error code +// [vp] - 16-bit pointer to validate/convert +// [dwSize] - Length to validate +// +// Returns: Appropriate status code +// +// History: 22-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +VOID * +GetReadWritePtr16( + THUNKINFO *pti, + VPVOID vp, + DWORD dwSize ) +{ + VPTRDESC vpd; + SCODE sc; + + sc = GetPtr16Description(vp, PACC_READ | PACC_WRITE, dwSize, &vpd); + if (FAILED(sc)) + { + pti->scResult = sc; + return NULL; + } + else + { + return vpd.pbFlat; + } +} + +//+--------------------------------------------------------------------------- +// +// Function: GetStringPtr16 +// +// Synopsis: Validates a 16-bit pointer to a string for reading and +// converts it (the pointer) into a flat 32 pointer. It also +// returns the length, since it has to compute it anyway. +// +// Arguments: [pti] - THUNKINFO * for updating error code +// [vp] - 16-bit pointer to validate/convert +// [cchMax] - Maximum legal length +// [lpSize] - Place to return length +// +// Returns: Appropriate status code +// +// History: 22-Mar-94 BobDay Created +// +//---------------------------------------------------------------------------- + +CHAR * +GetStringPtr16( + THUNKINFO *pti, + VPSTR vp, + UINT cchMax, + PUINT lpSize ) +{ + VPTRDESC vpd; + SCODE sc; + + // Check the first byte to ensure read access to the segment + sc = GetPtr16Description(vp, PACC_READ, 1, &vpd); + if (FAILED(sc)) + { + pti->scResult = sc; + return NULL; + } + else + { + UINT cchLen; + BYTE *pb; + BOOL fMbLead; + + pb = vpd.pbFlat; + + if (pb == NULL) + { + goto Exit; + } + + + // Restrict zero-termination search to cchMax characters + // or valid remaining memory + // Since we specified one in GetPtr16Description, dwLengthLeft + // is one off here + cchMax = min(cchMax, vpd.dwLengthLeft+1); + + cchLen = 0; + fMbLead = FALSE; + while (cchMax > 0) + { + cchLen++; + + if (*pb == 0 && !fMbLead) + { + break; + } + else + { + fMbLead = (BOOL)g_abLeadTable[*pb++]; + cchMax--; + } + } + + if (cchMax > 0) + { + *lpSize = cchLen; + return (LPSTR)vpd.pbFlat; + } + +Exit: + { + pti->scResult = E_INVALIDARG; + WOWRELVDMPTR(vp); + return NULL; + } + } +} + +//+--------------------------------------------------------------------------- +// +// Function: ValidatePtr16, public +// +// Synopsis: Calls an appropriate validation routine for 16-bit +// memory based on in/out status +// +// Arguments: [pti] - Thunk info, can be NULL for no validation +// [vp16] - 16-bit pointer +// [dwSize] - Size +// [thopInOut] - In/out type +// +// Returns: Pointer or NULL +// +// Modifies: [pti]->scResult for errors +// +// History: 24-Apr-94 DrewB Created +// +// Notes: 0 - No validation +// THOP_IN - Read validation +// THOP_OUT - Write validation +// THOP_INOUT - Read/write validation +// +//---------------------------------------------------------------------------- + +VOID * +ValidatePtr16(THUNKINFO *pti, + VPVOID vp16, + DWORD dwSize, + THOP thopInOut) +{ + VPTRDESC vpd; + SCODE sc; + + thopInOut &= THOP_INOUT; + if (thopInOut != 0) + { + sc = GetPtr16Description(vp16, thopInOut, dwSize, &vpd); + if (FAILED(sc)) + { + pti->scResult = sc; + return NULL; + } + else + { + return vpd.pbFlat; + } + } + else + { + return WOWFIXVDMPTR(vp16, dwSize); + } +} + +//+--------------------------------------------------------------------------- +// +// Function: IsValidInterface16, public +// +// Synopsis: Validates that a provided 16-bit interface is really valid +// (uses the same validation technique as 16-bit OLE 2.01) +// +// Arguments: [pti] - Thunk info, can be NULL for no validation +// [vp16] - 16-bit pointer +// +// Returns: BOOL - true for valid, false for invalid +// +// Modifies: [pti]->scResult for errors +// +// History: 22-Jul-92 BobDay Created +// +//---------------------------------------------------------------------------- + +BOOL IsValidInterface16( THUNKINFO *pti, VPVOID vp ) +{ + VPVOID UNALIGNED *pvpv; + VPVOID vpvtbl; + VPVOID vpfn; + LPVOID lpfn; + + // + // Make sure we can read the vtbl pointer from the object. + // + pvpv = (VPVOID FAR *)GetReadPtr16(pti, vp, sizeof(VPVOID)); + if ( pvpv == NULL ) + { + thkDebugOut((DEB_WARN, "IsValidInterface16: " + "Interface ptr invalid %p\n", vp)); + return FALSE; + } + + vpvtbl = *pvpv; // Read the vtbl ptr + + WOWRELVDMPTR(vp); + + // Make sure we can read the first entry from the vtbl (QI) + + pvpv = (VPVOID FAR *)GetReadPtr16(pti, vpvtbl, sizeof(VPVOID)); + if ( pvpv == NULL ) + { + thkDebugOut((DEB_WARN, "Vtbl ptr invalid %p:%p\n", vp, vpvtbl)); + return FALSE; + } + + vpfn = *pvpv; // Get the QI Function + + WOWRELVDMPTR(vpvtbl); + + if ( vpfn == 0 ) + { + thkDebugOut((DEB_WARN, "QI function NULL %p:%p\n", vp, vpvtbl)); + pti->scResult = E_INVALIDARG; + return FALSE; + } + + // Why it has to be 9 bytes long, I have no idea. + // This check was taken from valid.cpp in + // \src\ole2\dll\src\debug the 16-bit ole2.01 + // sources... + lpfn = (LPVOID)GetCodePtr16(pti, vpfn, 9); + + WOWRELVDMPTR(vpfn); + + if ( lpfn == NULL ) + { + thkDebugOut((DEB_WARN, "QI function ptr invalid %p:%p:%p\n", + vp,vpvtbl,vpfn)); + return FALSE; + } + + return TRUE; +} + +//+--------------------------------------------------------------------------- +// +// Function: GuidString, debug public +// +// Synopsis: Converts a guid to a string +// +// Arguments: [pguid] - GUID +// +// Returns: Pointer to string +// +// History: 08-Mar-94 DrewB Created +// +// Notes: Uses a static buffer +// +//---------------------------------------------------------------------------- + +#if DBG == 1 + +#pragma pack(1) +struct SplitGuid +{ + DWORD dw1; + WORD w1; + WORD w2; + BYTE b[8]; +}; +#pragma pack() + +char *GuidString(GUID const *pguid) +{ + static char ach[39]; + SplitGuid *psg = (SplitGuid *)pguid; + + wsprintfA(ach, "{%08lX-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X}", + psg->dw1, psg->w1, psg->w2, psg->b[0], psg->b[1], psg->b[2], + psg->b[3], psg->b[4], psg->b[5], psg->b[6], psg->b[7]); + return ach; +} + +#endif + +#if DBG == 1 + char *apszThopNames[] = +{ + "THOP_END", + "THOP_SHORTLONG", + "THOP_WORDDWORD", + "THOP_COPY", + "THOP_LPSTR", + "THOP_LPLPSTR", + "THOP_BUFFER", + "THOP_HUSER", + "THOP_HGDI", + "THOP_SIZE", + "THOP_RECT", + "THOP_MSG", + "THOP_HRESULT", + "THOP_STATSTG", + "THOP_DVTARGETDEVICE", + "THOP_STGMEDIUM", + "THOP_FORMATETC", + "THOP_HACCEL", + "THOP_OIFI", + "THOP_BINDOPTS", + "THOP_LOGPALETTE", + "THOP_SNB", + "THOP_CRGIID", + "THOP_OLESTREAM", + "THOP_HTASK", + "THOP_INTERFACEINFO", + "THOP_IFACE", + "THOP_IFACEOWNER", + "THOP_IFACENOADDREF", + "THOP_IFACECLEAN", + "THOP_IFACEGEN", + "THOP_IFACEGENOWNER", + "THOP_ROUTINEINDEX", + "THOP_RETURNTYPE", + "THOP_NULL", + "THOP_ERROR", + "THOP_ENUM", + "THOP_CALLBACK", + "THOP_RPCOLEMESSAGE", + "THOP_ALIAS32", + "THOP_CLSCONTEXT", + "THOP_FILENAME", + "THOP_SIZEDSTRING" +}; +#endif + +//+--------------------------------------------------------------------------- +// +// Function: ThopName, debug public +// +// Synopsis: Returns the string name of a thop +// +// Arguments: [thop] - Thop +// +// Returns: Pointer to string +// +// History: 11-Mar-94 DrewB Created +// +// Notes: Uses a static buffer +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +char *ThopName(THOP thop) +{ + static char achString[80]; + char *psz; + + thkAssert((thop & THOP_OPMASK) < THOP_LASTOP); + thkAssert(THOP_LASTOP == + (sizeof(apszThopNames)/sizeof(apszThopNames[0]))); + + strcpy(achString, apszThopNames[thop & THOP_OPMASK]); + + psz = achString+strlen(achString); + if (thop & THOP_IN) + { + strcpy(psz, " | THOP_IN"); + psz += strlen(psz); + } + if (thop & THOP_OUT) + { + strcpy(psz, " | THOP_OUT"); + } + + return achString; +} +#endif + +#if DBG == 1 + char *apszEnumThopNames[] = +{ + "STRING", + "UNKNOWN", + "STATSTG", + "FORMATETC", + "STATDATA", + "MONIKER", + "OLEVERB" +}; +#endif + +//+--------------------------------------------------------------------------- +// +// Function: EnumThopName, debug public +// +// Synopsis: Returns the string name of an enum thop +// +// Arguments: [thopEnum] - Thop +// +// Returns: Pointer to string +// +// History: 11-Mar-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +char *EnumThopName(THOP thopEnum) +{ + thkAssert(thopEnum < + (sizeof(apszEnumThopNames)/sizeof(apszEnumThopNames[0]))); + return apszEnumThopNames[thopEnum]; +} +#endif + +#if DBG == 1 +// Maintain current thunking invocation nesting level +int _iThunkNestingLevel = 1; +#endif + +//+--------------------------------------------------------------------------- +// +// Function: NestingSpaces, debug public +// +// Synopsis: Spaces for each nesting level +// +// History: 22-Mar-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 + +#define NESTING_SPACES 32 +#define SPACES_PER_LEVEL 2 + +static char achSpaces[NESTING_SPACES+1] = " "; + +void NestingSpaces(char *psz) +{ + int iSpaces, i; + + iSpaces = _iThunkNestingLevel*SPACES_PER_LEVEL; + + while (iSpaces > 0) + { + i = min(iSpaces, NESTING_SPACES); + memcpy(psz, achSpaces, i); + psz += i; + *psz = 0; + iSpaces -= i; + } +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: NestingLevelString, debug public +// +// Synopsis: Provides a string describing the nesting level +// +// History: 22-Mar-94 DrewB Created +// +// Notes: Uses a static buffer +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +char *NestingLevelString(void) +{ + static char ach[256]; + char *psz; + + if ((thkInfoLevel & DEB_NESTING) == 0) + { + return ""; + } + + wsprintfA(ach, "%2d:", _iThunkNestingLevel); + psz = ach+strlen(ach); + + if (sizeof(ach)/SPACES_PER_LEVEL <= _iThunkNestingLevel) + { + strcpy(psz, "..."); + } + else + { + NestingSpaces(psz); + } + return ach; +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: IidOrInterfaceString, debug public +// +// Synopsis: Returns the interface name for known interfaces or +// the IID string itself +// +// Arguments: [piid] - IID +// +// Returns: char * +// +// History: 18-Jun-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +char *IidOrInterfaceString(IID const *piid) +{ + return IidIdxString(IidToIidIdx(*piid)); +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: IidIdxString, debug public +// +// Synopsis: Returns the interface name for known interfaces or +// the IID string itself +// +// Arguments: [iidx] - IID or index +// +// Returns: char * +// +// History: 07-Jul-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +char *IidIdxString(IIDIDX iidx) +{ + if (IIDIDX_IS_IID(iidx)) + { + return GuidString(IIDIDX_IID(iidx)); + } + else if (IIDIDX_INDEX(iidx) == THI_COUNT) + { + // Special case here because of IMalloc's unusual unthunked- + // but-indexed existence + return "IMalloc"; + } + else + { + return inInterfaceNames[IIDIDX_INDEX(iidx)].pszInterface; + } +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: Handler routines, public +// +// Synopsis: Generic conversion routines for the generic thop handler +// +// Arguments: [pbFrom] - Data to convert from +// [pbTo] - Buffer to convert into +// [cbFrom] - Size of source data +// [cbTo] - Size of destination data +// +// History: 05-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +//+--------------------------------------------------------------------------- +// +// Function: FhCopyMemory, public +// +// Synopsis: Handler routine for memory copies +// +// History: 05-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void FhCopyMemory(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == cbTo); + + memcpy(pbTo, pbFrom, cbFrom); + +#if DBG == 1 + if (cbFrom == sizeof(DWORD)) + { + thkDebugOut((DEB_ARGS, "Arg DWORD: 0x%08lX\n", + *(DWORD UNALIGNED *)pbFrom)); + } + else if (cbFrom == sizeof(LARGE_INTEGER)) + { + thkDebugOut((DEB_ARGS, "Arg 8 byte: 0x%08lX:%08lX\n", + *(DWORD UNALIGNED *)(pbFrom+1*sizeof(DWORD)), + *(DWORD UNALIGNED *)(pbFrom+0*sizeof(DWORD)))); + } + else if (cbFrom == sizeof(GUID)) + { + thkDebugOut((DEB_ARGS, "Arg 16 byte: 0x%08lX:%08lX:%08lX:%08lX\n", + *(DWORD UNALIGNED *)(pbFrom+3*sizeof(DWORD)), + *(DWORD UNALIGNED *)(pbFrom+2*sizeof(DWORD)), + *(DWORD UNALIGNED *)(pbFrom+1*sizeof(DWORD)), + *(DWORD UNALIGNED *)(pbFrom+0*sizeof(DWORD)))); + } + else + { + thkDebugOut((DEB_ARGS, "Arg %d byte copy\n", cbFrom)); + } +#endif +} + +//+--------------------------------------------------------------------------- +// +// Function: FhShortToLong, FhLongToShort, public +// +// Synopsis: Signed int conversion +// +// History: 05-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void FhShortToLong(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(SHORT)); + thkAssert(cbTo == sizeof(LONG)); + + *(LONG UNALIGNED *)pbTo = (LONG)*(SHORT UNALIGNED *)pbFrom; + + thkDebugOut((DEB_ARGS, "ShToLo %d -> %d\n", + *(SHORT UNALIGNED *)pbFrom, *(LONG UNALIGNED *)pbTo)); +} + +void FhLongToShort(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(LONG)); + thkAssert(cbTo == sizeof(SHORT)); + + // Not used in situations where clamping is meaningful + *(SHORT UNALIGNED *)pbTo = (SHORT)*(LONG UNALIGNED *)pbFrom; + + thkDebugOut((DEB_ARGS, "LoToSh %d -> %d\n", + *(LONG UNALIGNED *)pbFrom, *(SHORT UNALIGNED *)pbTo)); +} + +//+--------------------------------------------------------------------------- +// +// Function: FhWordToDword, FhDwordToWord, public +// +// Synopsis: Handler routine for memory copies +// +// History: 05-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void FhWordToDword(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(WORD)); + thkAssert(cbTo == sizeof(DWORD)); + + *(DWORD UNALIGNED *)pbTo = (DWORD)*(WORD UNALIGNED *)pbFrom; + + thkDebugOut((DEB_ARGS, "WoToDw 0x%04lX -> 0x%08lX\n", + *(WORD UNALIGNED *)pbFrom, *(DWORD UNALIGNED *)pbTo)); +} + +void FhDwordToWord(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(DWORD)); + thkAssert(cbTo == sizeof(WORD)); + + // Not used in situations where clamping is meaningful + *(WORD UNALIGNED *)pbTo = (WORD)*(DWORD UNALIGNED *)pbFrom; + + thkDebugOut((DEB_ARGS, "DwToWo 0x%08lX -> 0x%04lX\n", + *(DWORD UNALIGNED *)pbFrom, *(WORD UNALIGNED *)pbTo)); +} + +//+--------------------------------------------------------------------------- +// +// Function: Handle routines, public +// +// Synopsis: Handler routine for Windows handles +// +// History: 05-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void FhGdiHandle1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(HAND16)); + thkAssert(cbTo == sizeof(HANDLE)); + + *(HBITMAP *)pbTo = HBITMAP_32(*(HBITMAP16 UNALIGNED *)pbFrom); + + thkDebugOut((DEB_ARGS, "1632 HGdi: 0x%04lX -> 0x%p\n", + *(HAND16 UNALIGNED *)pbFrom, *(HANDLE *)pbTo)); +} + +void FhGdiHandle3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(HANDLE)); + thkAssert(cbTo == sizeof(HAND16)); + + *(HAND16 UNALIGNED *)pbTo = HBITMAP_16(*(HANDLE *)pbFrom); + + thkDebugOut((DEB_ARGS, "3216 HGdi: 0x%p -> 0x%04lX\n", + *(HANDLE *)pbFrom, *(HAND16 UNALIGNED *)pbTo)); +} + +void FhUserHandle1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(HAND16)); + thkAssert(cbTo == sizeof(HANDLE)); + + // Even though the constant is WOW_TYPE_FULLHWND, it + // works for any user handle + + *(HANDLE *)pbTo = WOWHandle32(*(HAND16 UNALIGNED *)pbFrom, + WOW_TYPE_FULLHWND); + + thkDebugOut((DEB_ARGS, "1632 HUser: 0x%04lX -> 0x%p\n", + *(HAND16 UNALIGNED *)pbFrom, *(HANDLE *)pbTo)); +} + +void FhUserHandle3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(HANDLE)); + thkAssert(cbTo == sizeof(HAND16)); + + *(HAND16 UNALIGNED *)pbTo = HWND_16(*(HANDLE *)pbFrom); + + thkDebugOut((DEB_ARGS, "3216 HUser: 0x%p -> 0x%04lX\n", + *(HANDLE *)pbFrom, *(HAND16 UNALIGNED *)pbTo)); +} + +void FhHaccel1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(HAND16)); + thkAssert(cbTo == sizeof(HANDLE)); + + *(HANDLE *)pbTo = HACCEL_32(*(HAND16 UNALIGNED *)pbFrom); + + thkDebugOut((DEB_ARGS, "1632 HACCEL: 0x%04lX -> 0x%p\n", + *(HAND16 UNALIGNED *)pbFrom, *(HANDLE *)pbTo)); +} + +void FhHaccel3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(HANDLE)); + thkAssert(cbTo == sizeof(HAND16)); + + *(HAND16 UNALIGNED *)pbTo = HACCEL_16(*(HANDLE *)pbFrom); + + thkDebugOut((DEB_ARGS, "3216 HACCEL: 0x%p -> 0x%04lX\n", + *(HANDLE *)pbFrom, *(HAND16 UNALIGNED *)pbTo)); +} + +void FhHtask1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + HAND16 h16; + DWORD h32; + thkAssert(cbFrom == sizeof(HAND16)); + thkAssert(cbTo == sizeof(HANDLE)); + + h16 = *(HAND16 UNALIGNED *)pbFrom; + if ( h16 == 0 ) + { + h32 = 0; + } + else + { + h32 = HTASK_32(h16); + } + *(DWORD *)pbTo = h32; + + thkDebugOut((DEB_ARGS, "1632 HTASK: 0x%04lX -> 0x%p\n", h16, h32)); +} + +void FhHtask3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + HAND16 h16; + HANDLE h32; + + thkAssert(cbFrom == sizeof(HANDLE)); + thkAssert(cbTo == sizeof(HAND16)); + + h32 = *(HANDLE *)pbFrom; + if ( h32 == NULL ) + { + h16 = 0; + } + else + { + h16 = HTASK_16(h32); + } + *(HAND16 UNALIGNED *)pbTo = h16; + + thkDebugOut((DEB_ARGS, "3216 HTASK: 0x%p -> 0x%04lX\n",h32, h16)); +} + +//+--------------------------------------------------------------------------- +// +// Function: HRESULT routines, public +// +// Synopsis: Handler routine for HRESULTs +// +// History: 05-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void FhHresult1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(HRESULT)); + thkAssert(cbTo == sizeof(HRESULT)); + + *(HRESULT *)pbTo = TransformHRESULT_1632(*(HRESULT UNALIGNED *)pbFrom); + + thkDebugOut((DEB_ARGS, "1632 HRESULT: 0x%08lX -> 0x%08lX\n", + *(HRESULT UNALIGNED *)pbFrom, *(HRESULT *)pbTo)); +} + +void FhHresult3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(HRESULT)); + thkAssert(cbTo == sizeof(HRESULT)); + + *(HRESULT UNALIGNED *)pbTo = TransformHRESULT_3216(*(HRESULT *)pbFrom); + + thkDebugOut((DEB_ARGS, "3216 HRESULT: 0x%08lX -> 0x%08lX\n", + *(HRESULT *)pbFrom, *(HRESULT UNALIGNED *)pbTo)); +} + +//+--------------------------------------------------------------------------- +// +// Function: NULL routines, public +// +// Synopsis: Handler routine for NULL +// +// History: 05-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void FhNull(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + thkAssert(cbFrom == sizeof(void *)); + thkAssert(cbTo == sizeof(void *)); + + thkDebugOut((DEB_WARN, "FhNull: %p NULL value not NULL\n", pbFrom)); + *(void UNALIGNED **)pbTo = NULL; + + thkDebugOut((DEB_ARGS, "Arg NULL\n")); +} + +//+--------------------------------------------------------------------------- +// +// Function: Rect routines, public +// +// Synopsis: Handler routines for RECT +// +// History: 05-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void FhRect1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + RECT *pr32; + RECT16 UNALIGNED * pr16; + + thkAssert(cbFrom == sizeof(RECT16)); + thkAssert(cbTo == sizeof(RECT)); + + pr16 = (RECT16 UNALIGNED *)pbFrom; + pr32 = (RECT *)pbTo; + + pr32->left = (LONG)pr16->left; // Sign extend + pr32->top = (LONG)pr16->top; // Sign extend + pr32->right = (LONG)pr16->right; // Sign extend + pr32->bottom = (LONG)pr16->bottom; // Sign extend + + thkDebugOut((DEB_ARGS, "1632 RECT: {%d, %d, %d, %d}\n", + pr32->left, pr32->top, pr32->right, pr32->bottom)); +} + +void FhRect3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + RECT *pr32; + RECT16 UNALIGNED *pr16; + + thkAssert(cbFrom == sizeof(RECT)); + thkAssert(cbTo == sizeof(RECT16)); + + pr32 = (RECT *)pbFrom; + pr16 = (RECT16 UNALIGNED *)pbTo; + + pr16->left = ClampLongToShort(pr32->left); + pr16->top = ClampLongToShort(pr32->top); + pr16->right = ClampLongToShort(pr32->right); + pr16->bottom = ClampLongToShort(pr32->bottom); + + thkDebugOut((DEB_ARGS, "3216 RECT: {%d, %d, %d, %d}\n", + pr32->left, pr32->top, pr32->right, pr32->bottom)); +} + +//+--------------------------------------------------------------------------- +// +// Function: Size routines, public +// +// Synopsis: Handler routines for SIZE +// +// History: 05-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void FhSize1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + SIZE16 UNALIGNED *psize16; + SIZE *psize32; + + thkAssert(cbFrom == sizeof(SIZE16)); + thkAssert(cbTo == sizeof(SIZE)); + + psize16 = (SIZE16 UNALIGNED *)pbFrom; + psize32 = (SIZE *)pbTo; + + psize32->cx = (LONG)psize16->cx; + psize32->cy = (LONG)psize16->cy; + + thkDebugOut((DEB_ARGS, "1632 SIZE: {%d, %d}\n", + psize32->cx, psize32->cy)); +} + +void FhSize3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + SIZE16 UNALIGNED *psize16; + SIZE *psize32; + + thkAssert(cbFrom == sizeof(SIZE)); + thkAssert(cbTo == sizeof(SIZE16)); + + psize32 = (SIZE *)pbFrom; + psize16 = (SIZE16 UNALIGNED *)pbTo; + + psize16->cx = ClampLongToShort(psize32->cx); + psize16->cy = ClampLongToShort(psize32->cy); + + thkDebugOut((DEB_ARGS, "3216 SIZE: {%d, %d}\n", + psize32->cx, psize32->cy)); +} + +//+--------------------------------------------------------------------------- +// +// Function: Message routines, public +// +// Synopsis: Handler routines for MSG +// +// History: 05-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void FhMsg1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + MSG16 UNALIGNED *pmsg16; + MSG *pmsg32; + + thkAssert(cbFrom == sizeof(MSG16)); + thkAssert(cbTo == sizeof(MSG)); + + pmsg16 = (MSG16 UNALIGNED *)pbFrom; + pmsg32 = (MSG *)pbTo; + + pmsg32->hwnd = HWND_32(pmsg16->hwnd); + pmsg32->message = (UINT)pmsg16->message; + pmsg32->wParam = (WPARAM)pmsg16->wParam; // Should we sign extend? + pmsg32->lParam = (LPARAM)pmsg16->lParam; + pmsg32->time = pmsg16->time; + pmsg32->pt.x = (LONG)(SHORT)LOWORD(pmsg16->pt); // Sign extend + pmsg32->pt.y = (LONG)(SHORT)HIWORD(pmsg16->pt); // Sign extend + + thkDebugOut((DEB_ARGS, "1632 MSG: {0x%p, %d, 0x%08lX, 0x%08lX, " + "0x%08lX, {%d, %d}}\n", + pmsg32->hwnd, pmsg32->message, pmsg32->wParam, + pmsg32->lParam, pmsg32->time, pmsg32->pt.x, + pmsg32->pt.y)); +} + +void FhMsg3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo) +{ + MSG16 UNALIGNED *pmsg16; + MSG *pmsg32; + + thkAssert(cbFrom == sizeof(MSG)); + thkAssert(cbTo == sizeof(MSG16)); + + pmsg32 = (MSG *)pbFrom; + pmsg16 = (MSG16 UNALIGNED *)pbTo; + + pmsg16->hwnd = HWND_16(pmsg32->hwnd); + pmsg16->message = (WORD)pmsg32->message; + pmsg16->wParam = (WORD)pmsg32->wParam; // Sign truncate + pmsg16->lParam = (LONG)pmsg32->lParam; + pmsg16->time = pmsg32->time; + pmsg16->pt = MAKELONG(ClampLongToShort(pmsg32->pt.x), + ClampLongToShort(pmsg32->pt.y)); + + thkDebugOut((DEB_ARGS, "3216 MSG: {0x%p, %d, 0x%08lX, 0x%08lX, " + "0x%08lX, {%d, %d}}\n", + pmsg32->hwnd, pmsg32->message, pmsg32->wParam, + pmsg32->lParam, pmsg32->time, pmsg32->pt.x, + pmsg32->pt.y)); +} + +//+--------------------------------------------------------------------------- +// +// Function: ALLOCROUTINE, public +// +// Synopsis: A routine which allocates memory +// +// Arguments: [cb] - Amount to allocate +// +// Returns: Pointer to memory +// +// History: 19-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +//+--------------------------------------------------------------------------- +// +// Function: FREEROUTINE, public +// +// Synopsis: A routine which frees memory +// +// Arguments: [pv] - Memory to free +// [cb] - Size of memory to free +// +// History: 19-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void *ArTask16(UINT cb) +{ + return (void *)TaskMalloc16(cb); +} + +void FrTask16(void *pv, UINT cb) +{ + TaskFree16((VPVOID)pv); +} + +void *ArTask32(UINT cb) +{ + return TaskMalloc32(cb); +} + +void FrTask32(void *pv, UINT cb) +{ + TaskFree32(pv); +} + +void *ArStack16(UINT cb) +{ + return (void *)STACKALLOC16(cb); +} + +void FrStack16(void *pv, UINT cb) +{ + STACKFREE16((VPVOID)pv, cb); +} + +void *ArStack32(UINT cb) +{ + // Can't use STACKALLOC32 on NT since it may be _alloca which wouldn't + // live beyond this routine +#ifdef _CHICAGO_ + return STACKALLOC32(cb); +#else + return (void *)LocalAlloc(LMEM_FIXED, cb); +#endif +} + +void FrStack32(void *pv, UINT cb) +{ +#ifdef _CHICAGO_ + STACKFREE32(pv, cb); +#else + LocalFree(pv); +#endif +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertDvtd1632, private +// +// Synopsis: Converts a DVTARGETDEVICE from 16 to 32-bits +// +// Arguments: [pti] - Thunking state information +// [vpdvtd16] - Source +// [pfnAlloc] - ALLOCROUTINE +// [pfnFree] - FREEROUTINE +// [ppdvtd32] - Destination +// [pcbSize] - Size return +// +// Returns: Appropriate status code +// +// Modifies: [ppdvtd32] +// [pcbSize] +// +// History: 18-Apr-94 DrewB Created +// +// Notes: [pfnAlloc/Free] must deal with 32-bit memory +// +//---------------------------------------------------------------------------- + +SCODE ConvertDvtd1632(THUNKINFO *pti, + VPVOID vpdvtd16, + ALLOCROUTINE pfnAlloc, + FREEROUTINE pfnFree, + DVTARGETDEVICE **ppdvtd32, + UINT *pcbSize) +{ + DVTARGETDEVICE UNALIGNED *pdvtd16; + DVTARGETDEVICE *pdvtd32; + DVTDINFO dvtdi; + + pdvtd16 = (DVTARGETDEVICE UNALIGNED *)GetReadPtr16(pti, vpdvtd16, + sizeof(DVTARGETDEVICE)); + if (pdvtd16 == NULL) + { + return pti->scResult; + } + + pdvtd16 = (DVTARGETDEVICE UNALIGNED *)GetReadPtr16(pti, vpdvtd16, + pdvtd16->tdSize); + + WOWRELVDMPTR(vpdvtd16); + + if (pdvtd16 == NULL) + { + return pti->scResult; + } + + pti->scResult = UtGetDvtd16Info( pdvtd16, &dvtdi ); + + if ( FAILED(pti->scResult) ) + { + WOWRELVDMPTR(vpdvtd16); + return pti->scResult; + } + + pdvtd32 = (DVTARGETDEVICE *)pfnAlloc(dvtdi.cbConvertSize); + if (pdvtd32 == NULL) + { + WOWRELVDMPTR(vpdvtd16); + return E_OUTOFMEMORY; + } + + pti->scResult = UtConvertDvtd16toDvtd32( pdvtd16, &dvtdi, pdvtd32 ); + + WOWRELVDMPTR(vpdvtd16); + + if ( FAILED(pti->scResult) ) + { + pfnFree(pdvtd32, dvtdi.cbConvertSize); + return pti->scResult; + } + + *ppdvtd32 = pdvtd32; + *pcbSize = dvtdi.cbConvertSize; + + return S_OK; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertDvtd3216, private +// +// Synopsis: Converts a DVTARGETDEVICE from 32 to 16-bits +// +// Arguments: [pti] - Thunking state information +// [pdvtd32] - Source +// [pfnAlloc] - Allocator +// [pfnFree] - Freer +// [ppvdvtd16] - Destination +// [pcbSize] - Size return +// +// Returns: Appropriate status code +// +// Modifies: [ppvdvtd16] +// [pcbSize] +// +// History: 18-Apr-94 DrewB Created +// +// Notes: [pfnAlloc/Free] must deal with 16-bit memory +// +//---------------------------------------------------------------------------- + +SCODE ConvertDvtd3216(THUNKINFO *pti, + DVTARGETDEVICE *pdvtd32, + ALLOCROUTINE pfnAlloc, + FREEROUTINE pfnFree, + VPVOID *ppvdvtd16, + UINT *pcbSize) +{ + DVTARGETDEVICE UNALIGNED *pdvtd16; + VPVOID vpdvtd16; + DVTDINFO dvtdi; + + if (IsBadReadPtr(pdvtd32, sizeof(DVTARGETDEVICE)) || + IsBadReadPtr(pdvtd32, pdvtd32->tdSize)) + { + return E_INVALIDARG; + } + + pti->scResult = UtGetDvtd32Info( pdvtd32, &dvtdi ); + + if ( FAILED(pti->scResult) ) + { + return pti->scResult; + } + + vpdvtd16 = (VPVOID)pfnAlloc(dvtdi.cbConvertSize); + if (vpdvtd16 == 0) + { + return E_OUTOFMEMORY; + } + + pdvtd16 = (DVTARGETDEVICE UNALIGNED *)WOWFIXVDMPTR(vpdvtd16, + dvtdi.cbConvertSize); + + pti->scResult = UtConvertDvtd32toDvtd16( pdvtd32, &dvtdi, pdvtd16 ); + + WOWRELVDMPTR(vpdvtd16); + + if ( FAILED(pti->scResult) ) + { + pfnFree((void *)vpdvtd16, dvtdi.cbConvertSize); + return pti->scResult; + } + + *ppvdvtd16 = vpdvtd16; + *pcbSize = dvtdi.cbConvertSize; + + return S_OK; +} + +#if !defined(_CHICAGO_) + +SCODE ConvertHDrop1632(HMEM16 hg16, HGLOBAL* phg32) +{ + SCODE sc = S_OK; + + *phg32 = CopyDropFilesFrom16(hg16); + if (!*phg32) + sc = E_INVALIDARG; + + return sc; +} + + +SCODE ConvertHDrop3216(HGLOBAL hg32, HMEM16* phg16) +{ + SCODE sc = S_OK; + + *phg16 = CopyDropFilesFrom32(hg32); + if (!*phg16) + sc = E_INVALIDARG; + + return sc; +} + +#endif + + + +//+--------------------------------------------------------------------------- +// +// Function: ConvertHGlobal1632, public +// +// Synopsis: Creates a 32-bit HGLOBAL for a 16-bit HGLOBAL +// +// Arguments: [pti] - Thunk info, can be NULL for no validation +// [hg16] - 16-bit HGLOBAL +// [thopInOut] - Validation type +// [phg32] - 32-bit HGLOBAL in/out +// [pdwSize] - Size in/out +// +// Returns: Appropriate status code +// +// Modifies: [phg32] +// [pdwSize] +// +// History: 24-Apr-94 DrewB Created +// +// Notes: If [phg32] is non-NULL on entry, [pdwSize] must be set +// appropriately also +// +//---------------------------------------------------------------------------- + +SCODE ConvertHGlobal1632(THUNKINFO *pti, + HMEM16 hg16, + THOP thopInOut, + HGLOBAL *phg32, + DWORD *pdwSize) +{ + SCODE sc; + VPVOID vpdata16; + LPVOID lpdata16; + LPVOID lpdata32; + HGLOBAL hg32; + DWORD dwSize; + BOOL fOwn; + + sc = S_OK; + + vpdata16 = WOWGlobalLockSize16( hg16, &dwSize ); + if ( vpdata16 == 0 ) + { + sc = E_INVALIDARG; + } + else + { + if (*phg32 != 0 && *pdwSize == dwSize) + { + hg32 = *phg32; + fOwn = FALSE; + } + else + { + hg32 = GlobalAlloc( GMEM_MOVEABLE, dwSize ); + fOwn = TRUE; + } + + if ( hg32 == 0 ) + { + sc = E_OUTOFMEMORY; + } + else + { + lpdata32 = GlobalLock( hg32 ); + + lpdata16 = (LPVOID)ValidatePtr16(pti, vpdata16, dwSize, thopInOut); + if ( lpdata16 != NULL ) + { + memcpy( lpdata32, lpdata16, dwSize ); + WOWRELVDMPTR(vpdata16); + } + else + { + sc = pti->scResult; + } + + GlobalUnlock(hg32); + + if (FAILED(sc) && fOwn) + { + GlobalFree(hg32); + } + } + + WOWGlobalUnlock16( hg16 ); + } + + if (SUCCEEDED(sc)) + { + if (*phg32 != 0 && hg32 != *phg32) + { + GlobalFree(*phg32); + } + + *phg32 = hg32; + *pdwSize = dwSize; + + thkDebugOut((DEB_ARGS, "1632 HGLOBAL: 0x%04X -> 0x%p, %u\n", + hg16, hg32, dwSize)); + } + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertHGlobal3216, public +// +// Synopsis: Creates a 16-bit HGLOBAL for a 32-bit HGLOBAL +// +// Arguments: [pti] - Thunk info, can be NULL for no validation +// [hg32] - 32-bit HGLOBAL +// [thopInOut] - Validation type +// [phg16] - 16-bit HGLOBAL in/out +// [pdwSize] - Size in/out +// +// Returns: Appropriate status code +// +// Modifies: [phg16] +// [pdwSize] +// +// History: 24-Apr-94 DrewB Created +// +// Notes: If [phg16] is non-NULL on entry, [pdwSize] must be set +// appropriately also +// +//---------------------------------------------------------------------------- + +SCODE ConvertHGlobal3216(THUNKINFO *pti, + HGLOBAL hg32, + THOP thopInOut, + HMEM16 *phg16, + DWORD *pdwSize) +{ + SCODE sc; + VPVOID vpdata16; + LPVOID lpdata16; + LPVOID lpdata32; + HMEM16 hg16; + DWORD dwSize; + BOOL fOwn; + + sc = S_OK; + + dwSize = GlobalSize(hg32); + if (dwSize == 0) + { + sc = E_INVALIDARG; + } + else + { + lpdata32 = GlobalLock(hg32); + + if (*phg16 != 0 && *pdwSize == dwSize) + { + hg16 = *phg16; + vpdata16 = WOWGlobalLock16(hg16); + fOwn = FALSE; + } + else + { + vpdata16 = WOWGlobalAllocLock16(GMEM_MOVEABLE | GMEM_DDESHARE, + dwSize, &hg16); + fOwn = TRUE; + } + + if (vpdata16 == 0) + { + sc = E_OUTOFMEMORY; + } + else + { + lpdata16 = (LPVOID)WOWFIXVDMPTR( vpdata16, dwSize ); + if ( lpdata16 == NULL ) + { + sc = E_UNEXPECTED; + } + else + { + memcpy( lpdata16, lpdata32, dwSize ); + + WOWRELVDMPTR(vpdata16); + } + + WOWGlobalUnlock16( hg16 ); + + if (FAILED(sc) && fOwn) + { + WOWGlobalFree16(hg16); + } + } + + GlobalUnlock(hg32); + } + + if (SUCCEEDED(sc)) + { + if (*phg16 != 0 && hg16 != *phg16) + { + WOWGlobalFree16(*phg16); + } + + *phg16 = hg16; + *pdwSize = dwSize; + + thkDebugOut((DEB_ARGS, "3216 HGLOBAL: 0x%p -> 0x%04X, %u\n", + hg32, hg16, dwSize)); + } + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertMfPict1632, public +// +// Synopsis: Converts a 16-bit METAFILEPICT to 32-bit +// +// Arguments: [pti] - Thunk info +// [hg16] - 16-bit HGLOBAL containing METAFILEPICT +// [phg32] - 32-bit HGLOBAL return +// +// Returns: Appropriate status code +// +// Modifies: [phg32] +// +// History: 24-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + + SCODE ConvertMfPict1632(THUNKINFO *pti, + HMEM16 hg16, + HGLOBAL *phg32) +{ + SCODE sc; + VPVOID vpmfp16; + METAFILEPICT16 UNALIGNED *pmfp16; + METAFILEPICT *pmfp32; + HGLOBAL hg32; + DWORD dwSize; +#if DBG == 1 + BOOL fSaveToFile = FALSE; +#endif + + thkDebugOut((DEB_ITRACE, "In ConvertMfPict1632(%p, 0x%04X, %p)\n", + pti, hg16, phg32)); + + *phg32 = 0; + sc = S_OK; + + vpmfp16 = WOWGlobalLockSize16( hg16, &dwSize ); + if ( vpmfp16 == 0 || dwSize < sizeof(METAFILEPICT16)) + { + sc = E_INVALIDARG; + } + else + { + hg32 = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) ); + if ( hg32 == 0 ) + { + sc = E_OUTOFMEMORY; + } + else + { + pmfp32 = (METAFILEPICT *)GlobalLock( hg32 ); + + pmfp16 = (METAFILEPICT16 UNALIGNED *)GetReadPtr16(pti, vpmfp16, + dwSize); + if ( pmfp16 != NULL ) + { + pmfp32->mm = (LONG)pmfp16->mm; + pmfp32->xExt = (LONG)pmfp16->xExt; + pmfp32->yExt = (LONG)pmfp16->yExt; + + pmfp32->hMF = HMETAFILE_32(pmfp16->hMF); + + thkDebugOut((DEB_ARGS, "1632 METAFILEPICT: " + "{%d, %d, %d, 0x%p} -> {%d, %d, %d, 0x%4x}\n", + pmfp16->mm, pmfp16->xExt, pmfp16->yExt, pmfp16->hMF, + pmfp32->mm, pmfp32->xExt, pmfp32->yExt, pmfp32->hMF)); + + WOWRELVDMPTR(vpmfp16); + +#if DBG == 1 + if (fSaveToFile) + { + HMETAFILE hmf; + + hmf = CopyMetaFile(pmfp32->hMF, __TEXT("thkmf.wmf")); + if (hmf != NULL) + { + DeleteMetaFile(hmf); + } + } +#endif + } + else + { + sc = pti->scResult; + } + + GlobalUnlock(hg32); + + if (FAILED(sc)) + { + GlobalFree(hg32); + } + } + + WOWGlobalUnlock16( hg16 ); + } + + if (SUCCEEDED(sc)) + { + *phg32 = hg32; + } + + thkDebugOut((DEB_ITRACE, "Out ConvertMfPict1632 => 0x%08lX, 0x%p\n", + sc, *phg32)); + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertMfPict3216, public +// +// Synopsis: Converts a 32-bit METAFILEPICT to 16-bit +// +// Arguments: [pti] - Thunk info +// [hg32] - 32-bit HGLOBAL containing METAFILEPICT +// [phg16] - 16-bit HGLOBAL return +// +// Returns: Appropriate status code +// +// Modifies: [phg16] +// +// History: 24-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + + SCODE ConvertMfPict3216(THUNKINFO *pti, + HGLOBAL hg32, + HMEM16 *phg16) +{ + SCODE sc; + VPVOID vpmfp16; + METAFILEPICT16 UNALIGNED *pmfp16; + METAFILEPICT *pmfp32; + DWORD dwSize; + HMEM16 hg16; +#if DBG == 1 + BOOL fSaveToFile = FALSE; +#endif + + thkDebugOut((DEB_ITRACE, "In ConvertMfPict3216(%p, 0x%p, %p)\n", + pti, hg32, phg16)); + + *phg16 = 0; + sc = S_OK; + + dwSize = GlobalSize(hg32); + pmfp32 = (METAFILEPICT *)GlobalLock(hg32); + if (dwSize == 0 || dwSize < sizeof(METAFILEPICT) || pmfp32 == NULL) + { + sc = E_INVALIDARG; + } + else + { + vpmfp16 = WOWGlobalAllocLock16(GMEM_MOVEABLE | GMEM_DDESHARE, + sizeof(METAFILEPICT16), &hg16); + if (vpmfp16 == 0) + { + sc = E_OUTOFMEMORY; + } + else + { + pmfp16 = FIXVDMPTR(vpmfp16, METAFILEPICT16); + if ( pmfp16 != NULL ) + { + pmfp16->mm = (SHORT)pmfp32->mm; + pmfp16->xExt = ClampLongToShort(pmfp32->xExt); + pmfp16->yExt = ClampLongToShort(pmfp32->yExt); + pmfp16->hMF = HMETAFILE_16(pmfp32->hMF); + + thkDebugOut((DEB_ARGS, "3216 METAFILEPICT: " + "{%d, %d, %d, 0x%p} -> {%d, %d, %d, 0x%4x}\n", + pmfp32->mm, pmfp32->xExt, pmfp32->yExt, pmfp32->hMF, + pmfp16->mm, pmfp16->xExt, pmfp16->yExt, pmfp16->hMF)); + + RELVDMPTR(vpmfp16); + +#if DBG == 1 + if (fSaveToFile) + { + HMETAFILE hmf; + + hmf = CopyMetaFile(pmfp32->hMF, __TEXT("thkmf.wmf")); + if (hmf != NULL) + { + DeleteMetaFile(hmf); + } + } +#endif + } + else + { + sc = E_UNEXPECTED; + } + + WOWGlobalUnlock16(hg16); + + if (FAILED(sc)) + { + WOWGlobalFree16(hg16); + } + } + + GlobalUnlock(hg32); + } + + if (SUCCEEDED(sc)) + { + *phg16 = hg16; + } + + thkDebugOut((DEB_ITRACE, "Out ConvertMfPict3216 => 0x%08lX, 0x%04X\n", + sc, *phg16)); + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertObjDesc1632, public +// +// Synopsis: Converts an OBJECTDESCRIPTOR structure +// +// Arguments: [pti] - THUNKINFO +// [hg16] - HGLOBAL containing structure +// [phg32] - Output HGLOBAL +// +// Returns: Appropriate status code +// +// Modifies: [phg32] +// +// History: 04-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +SCODE ConvertObjDesc1632(THUNKINFO *pti, + HMEM16 hg16, + HGLOBAL *phg32) +{ + SCODE sc; + VPVOID vp16; + HGLOBAL hg32; + DWORD dwSize; + OBJECTDESCRIPTOR UNALIGNED *pod16; + OBJECTDESCRIPTOR *pod32; + char *pszFutn, *pszSoc; + UINT cchFutn, cchSoc; + UINT cbOffset; + + sc = S_OK; + + vp16 = WOWGlobalLock16(hg16); + if ( vp16 == 0 ) + { + return E_INVALIDARG; + } + + pszFutn = NULL; + pszSoc = NULL; + + pod16 = (OBJECTDESCRIPTOR UNALIGNED *) + GetReadPtr16(pti, vp16, sizeof(OBJECTDESCRIPTOR)); + if (pod16 == NULL) + { + sc = pti->scResult; + goto EH_Unlock; + } + + dwSize = sizeof(OBJECTDESCRIPTOR); + + if (pod16->dwFullUserTypeName > 0) + { + pszFutn = (char *)GetStringPtr16(pti, vp16+pod16->dwFullUserTypeName, + CCHMAXSTRING, &cchFutn); + if (pszFutn == NULL) + { + sc = pti->scResult; + goto EH_Unlock; + } + + dwSize += cchFutn*sizeof(WCHAR); + } + + if (pod16->dwSrcOfCopy > 0) + { + pszSoc = (char *)GetStringPtr16(pti, vp16+pod16->dwSrcOfCopy, + CCHMAXSTRING, &cchSoc); + if (pszSoc == NULL) + { + sc = pti->scResult; + goto EH_Unlock; + } + + dwSize += cchSoc*sizeof(WCHAR); + } + + hg32 = GlobalAlloc(GMEM_MOVEABLE, dwSize); + if ( hg32 == 0 ) + { + sc = E_OUTOFMEMORY; + goto EH_Unlock; + } + + pod32 = (OBJECTDESCRIPTOR *)GlobalLock(hg32); + memcpy(pod32, pod16, sizeof(OBJECTDESCRIPTOR)); + pod32->cbSize = dwSize; + + cbOffset = sizeof(OBJECTDESCRIPTOR); + + if (pod16->dwFullUserTypeName > 0) + { + if (MultiByteToWideChar(AreFileApisANSI() ? CP_ACP : CP_OEMCP, + 0, pszFutn, cchFutn, + (WCHAR *)((BYTE *)pod32+cbOffset), + cchFutn) == 0) + { + sc = E_UNEXPECTED; + goto EH_Free; + } + + pod32->dwFullUserTypeName = cbOffset; + cbOffset += cchFutn*sizeof(WCHAR); + } + + if (pod16->dwSrcOfCopy > 0) + { + if (MultiByteToWideChar(AreFileApisANSI() ? CP_ACP : CP_OEMCP, + 0, pszSoc, cchSoc, + (WCHAR *)((BYTE *)pod32+cbOffset), + cchSoc) == 0) + { + sc = E_UNEXPECTED; + goto EH_Free; + } + + pod32->dwSrcOfCopy = cbOffset; + cbOffset += cchFutn*sizeof(WCHAR); + } + +#if DBG == 1 + WCHAR *pwcsFutn, *pwcsSoc; + if (pod32->dwFullUserTypeName > 0) + { + pwcsFutn = (WCHAR *)((BYTE *)pod32+pod32->dwFullUserTypeName); + } + else + { + pwcsFutn = NULL; + } + if (pod32->dwSrcOfCopy > 0) + { + pwcsSoc = (WCHAR *)((BYTE *)pod32+pod32->dwSrcOfCopy); + } + else + { + pwcsSoc = NULL; + } + thkDebugOut((DEB_ARGS, "1632 OBJECTDESCRIPTOR: " + "{%d, ..., \"%ws\" (%s), \"%ws\" (%s)} %p -> %p\n", + pod32->cbSize, pwcsFutn, pszFutn, pwcsSoc, pszSoc, + vp16, pod32)); +#endif + + GlobalUnlock(hg32); + + *phg32 = hg32; + + EH_Unlock: + if (pszFutn != NULL) + { + WOWRELVDMPTR(vp16+pod16->dwFullUserTypeName); + } + if (pszSoc != NULL) + { + WOWRELVDMPTR(vp16+pod16->dwSrcOfCopy); + } + if (pod16 != NULL) + { + WOWRELVDMPTR(vp16); + } + + WOWGlobalUnlock16(hg16); + + return sc; + + EH_Free: + GlobalUnlock(hg32); + GlobalFree(hg32); + goto EH_Unlock; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertObjDesc3216, public +// +// Synopsis: Converts an OBJECTDESCRIPTOR structure +// +// Arguments: [pti] - THUNKINFO +// [hg32] - HGLOBAL containing structure +// [phg16] - Output HGLOBAL +// +// Returns: Appropriate status code +// +// Modifies: [phg16] +// +// History: 04-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +SCODE ConvertObjDesc3216(THUNKINFO *pti, + HGLOBAL hg32, + HMEM16 *phg16) +{ + SCODE sc; + VPVOID vp16; + HMEM16 hg16; + DWORD dwSize; + OBJECTDESCRIPTOR UNALIGNED *pod16; + OBJECTDESCRIPTOR *pod32; + WCHAR *pwcsFutn, *pwcsSoc; + UINT cchFutn, cchSoc; + UINT cbOffset; + + sc = S_OK; + + pod32 = (OBJECTDESCRIPTOR *)GlobalLock(hg32); + if ( pod32 == 0 ) + { + return E_INVALIDARG; + } + + if (IsBadReadPtr(pod32, sizeof(OBJECTDESCRIPTOR))) + { + sc = E_INVALIDARG; + goto EH_Unlock; + } + + dwSize = sizeof(OBJECTDESCRIPTOR); + + pwcsFutn = NULL; + if (pod32->dwFullUserTypeName > 0) + { + pwcsFutn = (WCHAR *)((BYTE *)pod32+pod32->dwFullUserTypeName); + if (IsBadStringPtrW(pwcsFutn, CCHMAXSTRING)) + { + sc = E_INVALIDARG; + goto EH_Unlock; + } + + cchFutn = lstrlenW(pwcsFutn)+1; + dwSize += cchFutn*2; + } + + pwcsSoc = NULL; + if (pod32->dwSrcOfCopy > 0) + { + pwcsSoc = (WCHAR *)((BYTE *)pod32+pod32->dwSrcOfCopy); + if (IsBadStringPtrW(pwcsSoc, CCHMAXSTRING)) + { + sc = E_INVALIDARG; + goto EH_Unlock; + } + + cchSoc = lstrlenW(pwcsSoc)+1; + dwSize += cchSoc*2; + } + + vp16 = WOWGlobalAllocLock16(GMEM_MOVEABLE, dwSize, &hg16); + if ( vp16 == 0 ) + { + sc = E_OUTOFMEMORY; + goto EH_Unlock; + } + + pod16 = FIXVDMPTR(vp16, OBJECTDESCRIPTOR); + memcpy(pod16, pod32, sizeof(OBJECTDESCRIPTOR)); + pod16->cbSize = dwSize; + + cbOffset = sizeof(OBJECTDESCRIPTOR); + + if (pod32->dwFullUserTypeName > 0) + { + if (WideCharToMultiByte(AreFileApisANSI() ? CP_ACP : CP_OEMCP, + 0, pwcsFutn, cchFutn, + (char *)pod16+cbOffset, 2 * cchFutn, + NULL, NULL) == 0) + { + sc = E_UNEXPECTED; + goto EH_Free; + } + + pod16->dwFullUserTypeName = cbOffset; + cbOffset += cchFutn*2; + } + + if (pod32->dwSrcOfCopy > 0) + { + if (WideCharToMultiByte(AreFileApisANSI() ? CP_ACP : CP_OEMCP, + 0, pwcsSoc, cchSoc, + (char *)pod16+cbOffset, 2 * cchSoc, + NULL, NULL) == 0) + { + sc = E_UNEXPECTED; + goto EH_Free; + } + + pod16->dwSrcOfCopy = cbOffset; + cbOffset += cchFutn*2; + } + +#if DBG == 1 + char *pszFutn, *pszSoc; + if (pod16->dwFullUserTypeName > 0) + { + pszFutn = (char *)((BYTE *)pod16+pod16->dwFullUserTypeName); + } + else + { + pszFutn = NULL; + } + if (pod16->dwSrcOfCopy > 0) + { + pszSoc = (char *)((BYTE *)pod16+pod16->dwSrcOfCopy); + } + else + { + pszSoc = NULL; + } + thkDebugOut((DEB_ARGS, "3216 OBJECTDESCRIPTOR: " + "{%d, ..., \"%s\" (%ws), \"%s\" (%ws)} %p -> %p\n", + pod16->cbSize, pszFutn, pwcsFutn, pszSoc, pwcsSoc, + pod32, vp16)); +#endif + + RELVDMPTR(vp16); + + WOWGlobalUnlock16(hg16); + + *phg16 = hg16; + + EH_Unlock: + GlobalUnlock(hg32); + + return sc; + + EH_Free: + WOWGlobalUnlockFree16(vp16); + goto EH_Unlock; +} + +//+--------------------------------------------------------------------------- +// +// Class: CSm32ReleaseHandler (srh) +// +// Purpose: Provides punkForRelease for 16->32 STGMEDIUM conversion +// +// Interface: IUnknown +// +// History: 24-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +class CSm32ReleaseHandler : public IUnknown +{ +public: + CSm32ReleaseHandler(void) + { + _punkForRelease = NULL; + } + ~CSm32ReleaseHandler(void) + { + // Clean up proxy if it hasn't already been released + if (_punkForRelease) + { + _pThkMgr->FreeProxy3216((VPVOID)_sm16.pUnkForRelease); + } + } + + void Init(CThkMgr *pThkMgr, + STGMEDIUM UNALIGNED *psm16, + STGMEDIUM *psm32, + IUnknown *punkForRelease, + CLIPFORMAT cfFormat) + { + // Unfortunately, the MIPS compiler is not smart enough + // to do the right thing if we just declare psm16 as UNALIGNED -- it + // doesn't recognize that each member of the structure is also + // unaligned when it does the structure copy. So...to make + // sure we don't generate an alignment fault, we just copy each + // member of the structure directly. + + _sm16.tymed = psm16->tymed; + _sm16.hGlobal = psm16->hGlobal; + _sm16.pUnkForRelease = psm16->pUnkForRelease; + _sm32 = *psm32; + _punkForRelease = punkForRelease; + _cReferences = 1; + _cfFormat = cfFormat; + _pThkMgr = pThkMgr; + } + + STDMETHOD(QueryInterface)(REFIID riid, void **ppv) + { + if ( IsEqualIID(riid,IID_IUnknown) ) + { + *ppv = this; + AddRef(); + return NOERROR; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + } + STDMETHOD_(ULONG, AddRef)(void) + { + return InterlockedIncrement(&_cReferences); + } + STDMETHOD_(ULONG, Release)(void); + +private: + STGMEDIUM _sm16; + STGMEDIUM _sm32; + IUnknown *_punkForRelease; + CLIPFORMAT _cfFormat; + CThkMgr *_pThkMgr; + +public: + LONG _cReferences; +}; + +//+--------------------------------------------------------------------------- +// +// Member: CSm32ReleaseHandler::Release, public +// +// Synopsis: Frees resources for the 32-bit copy and then +// passes the ReleaseStgMedium on to 16-bits +// +// Returns: Ref count +// +// History: 24-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +STDMETHODIMP_(ULONG) CSm32ReleaseHandler::Release(void) +{ + STGMEDIUM UNALIGNED *psm16; + STGMEDIUM *psm32; + LONG lRet; + SCODE sc; + DWORD dwSize; + + lRet = InterlockedDecrement(&_cReferences); + if (lRet != 0) + { + return lRet; + } + + psm16 = &_sm16; + psm32 = &_sm32; + + switch(psm32->tymed) + { + case TYMED_HGLOBAL: + // BUGBUG - Assumption that OBJECTDESCRIPTOR does not need copyback + if (!OBJDESC_CF(_cfFormat)) + { + // BUGBUG - Do we ever need to do this? + // Is it valid to rely on the contents of the HGLOBAL + // at release time? + + // BUGBUG - Is this the right time to copy back? + + Assert(NULL != psm32->hGlobal); + + WOWGlobalLockSize16((HMEM16)psm16->hGlobal, &dwSize); + WOWGlobalUnlock16((HMEM16)psm16->hGlobal); + + sc = ConvertHGlobal3216(NULL, psm32->hGlobal, 0, + (HMEM16 *)&psm16->hGlobal, &dwSize); + // BUGBUG - What happens on errors? + thkAssert(SUCCEEDED(sc)); + } + + GlobalFree(psm32->hGlobal); + psm32->hGlobal = NULL; + break; + + case TYMED_MFPICT: +// Chicago uses the same GDI handles for both 32bit and 16bit worlds. +// Don't delete the handle after a copy since Chicago doesn't actually +// copy the handle. +#if !defined(_CHICAGO_) + METAFILEPICT *pmfp32; + + pmfp32 = (METAFILEPICT *)GlobalLock(psm32->hGlobal); + DeleteMetaFile(pmfp32->hMF); + GlobalUnlock(psm32->hGlobal); +#endif + GlobalFree(psm32->hGlobal); + break; + + case TYMED_FILE: + // 32-bit handled by ReleaseStgMedium + // Clean up 16-bit ourselves +#ifdef SM_FREE_16BIT_FILENAME + // BUGBUG - 16-bit OLE did not free the filename, so we can't + // either. This may lead to memory leaks, but there's not + // really anything we can do about it + TaskFree16((VPVOID)psm16->lpszFileName); +#endif + break; + + case TYMED_ISTREAM: + case TYMED_ISTORAGE: + // Handled by ReleaseStgMedium and thunked to 16-bits if necessary + break; + + case TYMED_GDI: + case TYMED_NULL: + // Nothing to release + break; + + default: + thkAssert(!"Unknown tymed in CSm32ReleaseHandler::Release"); + break; + } + + // Call 16-bit Release through proxy + ((IUnknown *)_punkForRelease)->Release(); + _punkForRelease = NULL; + + // Clean up this + delete this; + + return 0; +} + +//+--------------------------------------------------------------------------- +// +// Member: CSm16ReleaseHandler::Init, public +// +// Synopsis: Initialize class +// +// Arguments: [psm32] - 32-bit STGMEDIUM +// [psm16] - 16-bit STGMEDIUM +// [vpvUnkForRelease] - Object for punkForRelease +// [cfFormat] - Clipboard format associated with STGMEDIUM +// +// History: 24-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +void CSm16ReleaseHandler::Init(IUnknown *pThkMgr, + STGMEDIUM *psm32, + STGMEDIUM UNALIGNED *psm16, + VPVOID vpvUnkForRelease, + CLIPFORMAT cfFormat) +{ + _avpfnVtbl = gdata16Data.avpfnSm16ReleaseHandlerVtbl; + _sm32 = *psm32; + + // Unfortunately, the MIPS compiler is not smart enough + // to do the right thing if we just (ony) declare psm16 as UNALIGNED, + // it doesn't recognize that each member of the structure is also + // unaligned when it does the structure copy. So...to make + // sure we don't generate an alignment fault, we just copy each + // member of the structure directly. + + _sm16.tymed = psm16->tymed; + _sm16.hGlobal = psm16->hGlobal; + _sm16.pUnkForRelease = psm16->pUnkForRelease; + + _vpvUnkForRelease = vpvUnkForRelease; + _cReferences = 1; + _cfFormat = cfFormat; + _pUnkThkMgr = pThkMgr; +} + +//+--------------------------------------------------------------------------- +// +// Member: CSm16ReleaseHandler::Uninit, public +// +// Synopsis: Uninitialize class +// +// History: 25-Apr-94 DrewB Created +// +// Notes: For cleanup without use only; do not call after +// the release handler has actually executed Release +// +//---------------------------------------------------------------------------- + +void CSm16ReleaseHandler::Uninit(void) +{ + ((CThkMgr *)_pUnkThkMgr)->FreeProxy1632(_sm32.pUnkForRelease); +} + +//+--------------------------------------------------------------------------- +// +// Function: CSm16ReleaseHandler_Release32, public +// +// Synopsis: Handles 32-bit portion of cleaning up STGMEDIUMs for +// punkForRelease +// +// Arguments: [psrh] - this +// [dw1] +// [dw2] +// +// Returns: punkForRelease->Release() +// +// History: 24-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +STDAPI_(DWORD) CSm16ReleaseHandler_Release32(CSm16ReleaseHandler *psrh, + DWORD dw1, + DWORD dw2) +{ + STGMEDIUM UNALIGNED *psm16; + STGMEDIUM *psm32; + DWORD dwSize; + SCODE sc; + + psm16 = &psrh->_sm16; + psm32 = &psrh->_sm32; + switch(psm32->tymed) + { + case TYMED_FILE: + // 16-bit code cleaned up the 16-bit name, + // now clean up the 32-bit name + TaskFree32(psm32->lpszFileName); + break; + + case TYMED_HGLOBAL: + // BUGBUG - Assumption that OBJECTDESCRIPTOR does not need copyback + if (!OBJDESC_CF(psrh->_cfFormat)) + { + // BUGBUG - Do we ever need to do this? + // Copy data back and free global memory + + dwSize = GlobalSize(psm32->hGlobal); + + sc = ConvertHGlobal1632(NULL, (HMEM16)psm16->hGlobal, 0, + &psm32->hGlobal, &dwSize); + // BUGBUG - What happens on errors? + thkAssert(SUCCEEDED(sc)); + } + + WOWGlobalFree16((HMEM16)psm16->hGlobal); + break; + + case TYMED_MFPICT: + // Untouched in this case + break; + + case TYMED_ISTREAM: + case TYMED_ISTORAGE: + // Handled by ReleaseStgMedium and thunked to 32-bits if necessary + break; + + case TYMED_GDI: + case TYMED_NULL: + // Nothing to release + break; + + default: + thkAssert(!"Unknown tymed in ReleaseStgMedium32"); + break; + } + + return 0; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertStgMed1632, public +// +// Synopsis: Converts a 16-bit STGMEDIUM to 32-bits +// +// Arguments: [pti] - Thunk info +// [vpsm16] - VDM pointer to 16-bit STGMEDIUM +// [psm32] - 32-bit STGMEDIUM to fill in +// [pfe] - FORMATETC paired with STGMEDIUM or NULL +// [pdwSize] - Size return +// +// Returns: Appropriate status code +// +// Modifies: [pdwSize] +// +// History: 24-Apr-94 DrewB Created +// +// Notes: [pdwSize] is only set for TYMED_HGLOBAL +// +//---------------------------------------------------------------------------- + +SCODE ConvertStgMed1632(THUNKINFO *pti, + VPVOID vpsm16, + STGMEDIUM *psm32, + FORMATETC *pfe, + BOOL fPassingOwnershipIn, + DWORD *pdwSize) +{ + SCODE sc; + STGMEDIUM UNALIGNED *psm16; + CSm32ReleaseHandler *psrh; + IUnknown *punkForRelease; + VPVOID vpvUnk; + HMEM16 hmem16; + HGDIOBJ hGDI = NULL; + THKSTATE thkstateSaved; + + psm16 = (STGMEDIUM UNALIGNED *) + GetReadPtr16(pti, vpsm16, sizeof(STGMEDIUM)); + if (psm16 == NULL) + { + return pti->scResult; + } + + sc = S_OK; + + psm32->tymed = psm16->tymed; + + vpvUnk = (VPVOID)psm16->pUnkForRelease; + WOWRELVDMPTR(vpsm16); + + if (vpvUnk != 0) + { + // If the storageMedium includes a pUnk and we are passing + // ownership via an [in] parameter. Then we need to build + // a proxy with a "real" (rather than "local") reference. + // Here we trick "FindProxy3216" into believing it + // is building an [out] parameter + thkstateSaved = pti->pThkMgr->GetThkState(); + if(fPassingOwnershipIn) + { + pti->pThkMgr->SetThkState(THKSTATE_INVOKETHKOUT32); + } + + punkForRelease = pti->pThkMgr->FindProxy3216(NULL, + vpvUnk, + INDEX_IIDIDX(THI_IUnknown), + NULL); + pti->pThkMgr->SetThkState(thkstateSaved); + + if (punkForRelease == NULL) + { + return E_OUTOFMEMORY; + } + + psrh = new CSm32ReleaseHandler; + if (psrh == NULL) + { + pti->pThkMgr->FreeProxy3216(vpvUnk); + return E_OUTOFMEMORY; + } + } + else + { + psrh = NULL; + } + psm32->pUnkForRelease = psrh; + + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + + // Word 6 insists on treating BITMAPs as HGLOBALS, which is bogus. + // If this is the case, just patch the tymed to the correct value + + if (pfe != NULL) + { + if( (pfe->cfFormat == CF_BITMAP || pfe->cfFormat == CF_PALETTE ) && + psm16->tymed == TYMED_HGLOBAL ) + { + DWORD dw = TlsThkGetAppCompatFlags(); + + // if we are in Word 6, then hack the tymed so we thunk the + // bitmaps as GDI objects + + if( (dw & OACF_USEGDI ) ) + { + DWORD dwType; + + hGDI = HBITMAP_32((HBITMAP16)psm16->hBitmap); + + // make sure HGDI is either a bitmap or palette + + dwType = GetObjectType(hGDI); + if( (pfe->cfFormat == CF_BITMAP && dwType == OBJ_BITMAP) || + (pfe->cfFormat == CF_PALETTE && dwType == OBJ_PAL) ) + { + psm16->tymed = TYMED_GDI; + } + else + { + thkDebugOut((DEB_WARN, + "WARNING! invalid bitmap or palette!\n")); + hGDI = NULL; + } + } + else + { + thkDebugOut((DEB_WARN, "WARNING! App trying to transfer a " + "bitmap or palette on an HGLOBAL\n")); + } + } + } + + switch( psm16->tymed ) + { + case TYMED_HGLOBAL: + hmem16 = (HMEM16)psm16->hGlobal; + RELVDMPTR(vpsm16); + + if (pfe && OBJDESC_CF(pfe->cfFormat)) + { + sc = ConvertObjDesc1632(pti, hmem16, &psm32->hGlobal); + } +#if !defined(_CHICAGO_) + + else if (pfe && pfe->cfFormat == CF_HDROP) + { + // fix for mapi forms + // thunk CF_HDROP passed as HGLOBAL format + sc = ConvertHDrop1632(hmem16, &psm32->hGlobal); + } + +#endif + else + { + psm32->hGlobal = 0; + sc = ConvertHGlobal1632(pti, hmem16, THOP_INOUT, + &psm32->hGlobal, pdwSize); + } + break; + + case TYMED_MFPICT: + hmem16 = (HMEM16)psm16->hGlobal; + RELVDMPTR(vpsm16); + + sc = ConvertMfPict1632(pti, hmem16, &psm32->hGlobal); + break; + + case TYMED_FILE: + psm32->lpszFileName = + Convert_VPSTR_to_LPOLESTR( pti, + (VPVOID)psm16->lpszFileName, + NULL, 0 ); + if (psm32->lpszFileName == NULL) + { + sc = pti->scResult; + } + else + { +#if DBG == 1 + thkDebugOut((DEB_ARGS, "1632 TYMED_FILE: '%ws' (%s)\n", + psm32->lpszFileName, + WOWFIXVDMPTR((VPVOID)psm16->lpszFileName, 0))); + WOWRELVDMPTR((VPVOID)psm16->lpszFileName); +#endif + } + RELVDMPTR(vpsm16); + break; + + case TYMED_ISTREAM: + vpvUnk = (VPVOID)psm16->pstm; + RELVDMPTR(vpsm16); + + psm32->pstm = + (LPSTREAM)pti->pThkMgr->FindProxy3216(NULL, vpvUnk, + INDEX_IIDIDX(THI_IStream), + NULL); + if (psm32->pstm == NULL) + { + sc = E_OUTOFMEMORY; + } + else + { + thkDebugOut((DEB_ARGS, "1632 TYMED_ISTREAM: %p -> %p\n", + vpvUnk, psm32->pstm)); + } + break; + + case TYMED_ISTORAGE: + vpvUnk = (VPVOID)psm16->pstm; + RELVDMPTR(vpsm16); + + psm32->pstg = + (LPSTORAGE)pti->pThkMgr->FindProxy3216(NULL, vpvUnk, + INDEX_IIDIDX(THI_IStorage), + NULL); + if (psm32->pstg == NULL) + { + sc = E_OUTOFMEMORY; + } + else + { + thkDebugOut((DEB_ARGS, "1632 TYMED_ISTORAGE: %p -> %p\n", + vpvUnk, psm32->pstg)); + } + break; + + case TYMED_GDI: + // if we're in Word6, then we may have already converted the bitmap + // or palette handle + if( hGDI == NULL ) + { + psm32->hBitmap = HBITMAP_32((HBITMAP16)psm16->hBitmap); + } + else + { + psm32->hBitmap = (HBITMAP)hGDI; + } + + thkDebugOut((DEB_ARGS, "1632 TYMED_GDI: 0x%04X -> 0x%p\n", + psm16->hBitmap, psm32->hBitmap)); + RELVDMPTR(vpsm16); + break; + + case TYMED_NULL: + RELVDMPTR(vpsm16); + break; + + default: + RELVDMPTR(vpsm16); + sc = E_INVALIDARG; + break; + } + + if (FAILED(sc)) + { + delete psrh; + } + else + { + if (psrh) + { + CLIPFORMAT cf; + + if (pfe) + { + cf = pfe->cfFormat; + } + else + { + cf = CF_INVALID; + } + psrh->Init(pti->pThkMgr, FIXVDMPTR(vpsm16, STGMEDIUM), psm32, + punkForRelease, cf); + RELVDMPTR(vpsm16); + } + +#if DBG == 1 + if (pfe) + { + thkDebugOut((DEB_ARGS, "1632 STGMEDIUM FORMATETC %p {%d}\n", + pfe, pfe->cfFormat)); + } + thkDebugOut((DEB_ARGS, "1632 STGMEDIUM: %p {%d, %p, ...} -> " + "%p {%d, %p, ...}\n", vpsm16, psm16->tymed, + psm16->pUnkForRelease, psm32, psm32->tymed, + psm32->pUnkForRelease)); +#endif + } + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: CleanStgMed32, public +// +// Synopsis: Cleans up a 32-bit STGMEDIUM +// +// Arguments: [pti] - Thunk info +// [psm32] - STGMEDIUM to clean +// [vpsm16] - Source STGMEDIUM if thunk +// [dwSize] - Source size if thunk +// [fIsThunk] - STGMEDIUM was generated by thunking +// [pfe] - FORMATETC or NULL +// +// Returns: Appropriate status code +// +// History: 24-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +SCODE CleanStgMed32(THUNKINFO *pti, + STGMEDIUM *psm32, + VPVOID vpsm16, + DWORD dwSize, + BOOL fIsThunk, + FORMATETC *pfe) +{ + SCODE sc; + STGMEDIUM UNALIGNED *psm16; + HMEM16 hmem16; + VPVOID vpvUnk; + BOOL bNoRefs=TRUE; + + thkDebugOut((DEB_ITRACE, "In CleanStgMed32(%p, %p, %p, %u, %d, %p)\n", + pti, psm32, vpsm16, dwSize, fIsThunk, pfe)); + + sc = S_OK; + + if (fIsThunk && (NULL!=psm32->pUnkForRelease) ) + { + CSm32ReleaseHandler* psm32rh = (CSm32ReleaseHandler*)psm32->pUnkForRelease; + + // When the StgMed is a Thunk and we have a pUnkForRelease: + // + // Only the remote end is expected to call the last Release() of + // the ReleaseHandler. We normally have the last reference here + // so just "delete" the ReleaseHandler and release everything. + // + // But... in the Async OnDataChange() if the remote call hasn't + // completed yet the system will be holding a reference so we need to + // release our reference but not free any non-reference counted objects + // below. Sm32ReleaseHandler->Release() will be called when the + // remote side call completes and Release() is called on the + // pUnkForRelease. And that will clean up. + + if(1 == psm32rh->_cReferences) + { + delete psm32rh; + bNoRefs = TRUE; + } + else + { + psm32rh->Release(); + bNoRefs = FALSE; + } + psm32->pUnkForRelease = NULL; + } + + switch( psm32->tymed ) + { + case TYMED_HGLOBAL: + if (bNoRefs) + { + if (fIsThunk && + (pfe == NULL || !OBJDESC_CF(pfe->cfFormat))) + { + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + hmem16 = (HMEM16)psm16->hGlobal; + RELVDMPTR(vpsm16); + + Assert(NULL != psm32->hGlobal); + + sc = ConvertHGlobal3216(pti, psm32->hGlobal, 0, + &hmem16, &dwSize); + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + psm16->hGlobal = (HGLOBAL)hmem16; + RELVDMPTR(vpsm16); + } + + GlobalFree( psm32->hGlobal ); + psm32->hGlobal = NULL; + } + break; + + case TYMED_MFPICT: + if (bNoRefs) + { + +// Chicago uses the same GDI handles for both 32bit and 16bit worlds. +// Don't delete the handle after a copy since Chicago doesn't actually +// copy the handle. +#if !defined(_CHICAGO_) + // Can't modify an MFPICT + + METAFILEPICT *pmfp32; + + pmfp32 = (METAFILEPICT *)GlobalLock(psm32->hGlobal); + DeleteMetaFile(pmfp32->hMF); + GlobalUnlock(psm32->hGlobal); +#endif + GlobalFree(psm32->hGlobal); + } + break; + + case TYMED_FILE: + if (bNoRefs) + { + Convert_VPSTR_to_LPOLESTR_free( NULL, psm32->lpszFileName ); + } + break; + + case TYMED_ISTREAM: + if (fIsThunk) + { + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + vpvUnk = (VPVOID)psm16->pstm; + RELVDMPTR(vpsm16); + + pti->pThkMgr->FreeProxy3216(vpvUnk); + } + break; + + case TYMED_ISTORAGE: + if (fIsThunk) + { + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + vpvUnk = (VPVOID)psm16->pstg; + RELVDMPTR(vpsm16); + + pti->pThkMgr->FreeProxy3216(vpvUnk); + } + break; + + case TYMED_GDI: + // + // No unthunking needed + // + break; + + case TYMED_NULL: + break; + + default: + // Ignore, this case is handled on input + thkAssert(!"STGMEDIUM with invalid tymed"); + break; + } + + thkDebugOut((DEB_ITRACE, "Out CleanStgMed32 => 0x%08lX\n", sc)); + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertStgMed3216, public +// +// Synopsis: Converts a 32-bit STGMEDIUM to 16-bits +// +// Arguments: [pti] - Thunk info +// [psm32] - 32-bit STGMEDIUM +// [vpsm16] - VDM pointer to 16-bit STGMEDIUM +// [pfe] - FORMATETC paired with STGMEDIUM or NULL +// [pdwSize] - Size return +// +// Returns: Appropriate status code +// +// Modifies: [pdwSize] +// +// History: 24-Apr-94 DrewB Created +// +// Notes: [pdwSize] is only set for TYMED_HGLOBAL +// +//---------------------------------------------------------------------------- + +SCODE ConvertStgMed3216(THUNKINFO *pti, + STGMEDIUM *psm32, + VPVOID vpsm16, + FORMATETC *pfe, + BOOL fPassingOwnershipIn, + DWORD *pdwSize) +{ + SCODE sc; + STGMEDIUM UNALIGNED *psm16; + VPVOID vpsrh; + VPSTR vpstr; + UINT uiSize; + VPVOID vpvUnkForRelease; + VPVOID vpvUnk; + HMEM16 hmem16; + THKSTATE thkstateSaved; + + sc = S_OK; + + if (psm32->pUnkForRelease != NULL) + { + // If the storageMedium includes a pUnk and we are passing + // ownership via an [in] parameter. Then we need to build + // a proxy with a "real" (rather than "local") reference. + // Here we trick "FindProxy1632" into believing it + // is building an [out] parameter + thkstateSaved = pti->pThkMgr->GetThkState(); + if(fPassingOwnershipIn) + pti->pThkMgr->SetThkState(THKSTATE_INVOKETHKOUT16); + + vpvUnkForRelease = pti->pThkMgr->FindProxy1632(NULL, + psm32->pUnkForRelease, + INDEX_IIDIDX(THI_IUnknown), + NULL); + pti->pThkMgr->SetThkState(thkstateSaved); + + if (vpvUnkForRelease == 0) + { + return E_OUTOFMEMORY; + } + + vpsrh = WOWGlobalAllocLock16(GMEM_MOVEABLE, + sizeof(CSm16ReleaseHandler), + NULL); + if (vpsrh == 0) + { + pti->pThkMgr->FreeProxy1632(psm32->pUnkForRelease); + return E_OUTOFMEMORY; + } + } + else + { + vpsrh = 0; + } + + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + psm16->tymed = psm32->tymed; + psm16->pUnkForRelease = (IUnknown *)vpsrh; + RELVDMPTR(vpsm16); + + switch( psm32->tymed ) + { + case TYMED_HGLOBAL: + if (pfe && OBJDESC_CF(pfe->cfFormat)) + { + sc = ConvertObjDesc3216(pti, psm32->hGlobal, &hmem16); + } +#if !defined(_CHICAGO_) + + else if (pfe && pfe->cfFormat == CF_HDROP) + { + // fix for mapi forms + sc = ConvertHDrop3216(psm32->hGlobal, &hmem16); + } + +#endif + else + { + hmem16 = 0; + sc = ConvertHGlobal3216(pti, psm32->hGlobal, THOP_INOUT, + &hmem16, pdwSize); + } + + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + psm16->hGlobal = (HGLOBAL)hmem16; + RELVDMPTR(vpsm16); + break; + + case TYMED_MFPICT: + sc = ConvertMfPict3216(pti, psm32->hGlobal, &hmem16); + + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + psm16->hGlobal = (HGLOBAL)hmem16; + RELVDMPTR(vpsm16); + break; + + case TYMED_FILE: + uiSize = lstrlenW(psm32->lpszFileName) + 1; + vpstr = TaskMalloc16( uiSize*2 ); + if ( vpstr == NULL ) + { + sc = E_OUTOFMEMORY; + } + else + { + sc = Convert_LPOLESTR_to_VPSTR( psm32->lpszFileName, + vpstr, uiSize, uiSize*2 ); + if (FAILED(sc)) + { + TaskFree16(vpstr); + } + else + { + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + psm16->lpszFileName = (LPOLESTR)vpstr; + RELVDMPTR(vpsm16); + +#if DBG == 1 + thkDebugOut((DEB_ARGS, "3216 TYMED_FILE: '%s' (%ws)\n", + WOWFIXVDMPTR(vpstr, 0), + psm32->lpszFileName)); + WOWRELVDMPTR(vpstr); +#endif + } + } + break; + + case TYMED_ISTREAM: + vpvUnk = pti->pThkMgr->FindProxy1632(NULL, psm32->pstm, + INDEX_IIDIDX(THI_IStream), + NULL); + if (vpvUnk == 0) + { + sc = E_OUTOFMEMORY; + } + else + { + thkDebugOut((DEB_ARGS, "3216 TYMED_ISTREAM: %p -> %p\n", + psm32->pstm, vpvUnk)); + + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + psm16->pstm = (IStream *)vpvUnk; + RELVDMPTR(vpsm16); + } + break; + + case TYMED_ISTORAGE: + vpvUnk = pti->pThkMgr->FindProxy1632(NULL, psm32->pstg, + INDEX_IIDIDX(THI_IStorage), + NULL); + if (vpvUnk == 0) + { + sc = E_OUTOFMEMORY; + } + else + { + thkDebugOut((DEB_ARGS, "3216 TYMED_ISTORAGE: %p -> %p\n", + psm32->pstg, vpvUnk)); + + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + psm16->pstg = (IStorage *)vpvUnk; + RELVDMPTR(vpsm16); + } + break; + + case TYMED_GDI: + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + psm16->hBitmap = (HBITMAP)HBITMAP_16(psm32->hBitmap); + thkDebugOut((DEB_ARGS, "3216 TYMED_GDI: 0x%p -> 0x%04X\n", + psm32->hBitmap, psm16->hBitmap)); + RELVDMPTR(vpsm16); + break; + + case TYMED_NULL: + break; + + default: + sc = E_INVALIDARG; + break; + } + + if (FAILED(sc)) + { + if (vpsrh != 0) + { + pti->pThkMgr->FreeProxy1632(psm32->pUnkForRelease); + WOWGlobalUnlockFree16(vpsrh); + } + } + else + { + if (vpsrh != 0) + { + CSm16ReleaseHandler UNALIGNED *psrh; + CLIPFORMAT cf; + + if (pfe) + { + cf = pfe->cfFormat; + } + else + { + cf = CF_INVALID; + } + psrh = FIXVDMPTR(vpsrh, CSm16ReleaseHandler); + psrh->Init(pti->pThkMgr, psm32, FIXVDMPTR(vpsm16, STGMEDIUM), + vpvUnkForRelease, cf); + RELVDMPTR(vpsrh); + RELVDMPTR(vpsm16); + } + +#if DBG == 1 + if (pfe) + { + thkDebugOut((DEB_ARGS, "3216 STGMEDIUM FORMATETC %p {%d}\n", + pfe, pfe->cfFormat)); + } + thkDebugOut((DEB_ARGS, "3216 STGMEDIUM: %p {%d, %p, ...} -> " + "%p {%d, %p, ...}\n", psm32, psm32->tymed, + psm32->pUnkForRelease, vpsm16, psm16->tymed, + psm16->pUnkForRelease)); +#endif + } + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: CleanStgMed16, public +// +// Synopsis: Frees up resources in a 16-bit STGMEDIUM +// +// Arguments: [pti] - Thunk info +// [vpsm16] - STGMEDIUM to clean +// [psm32] - Source STGMEDIUM if thunk +// [dwSize] - Source size for thunked HGLOBAL +// [fIsThunk] - If the STGMEDIUM is a result of thunking +// [pfe] - FORMATETC or NULL +// +// Returns: Appropriate status code +// +// History: 24-Apr-94 DrewB Created +// +//---------------------------------------------------------------------------- + +SCODE CleanStgMed16(THUNKINFO *pti, + VPVOID vpsm16, + STGMEDIUM *psm32, + DWORD dwSize, + BOOL fIsThunk, + FORMATETC *pfe) +{ + SCODE sc; + STGMEDIUM UNALIGNED *psm16; + VPVOID vpvUnk; + HMEM16 hmem16; + + thkDebugOut((DEB_ITRACE, "In CleanStgMed16(%p, %p, %p, %u, %d, %p)\n", + pti, vpsm16, psm32, dwSize, fIsThunk, pfe)); + + sc = S_OK; + + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + vpvUnk = (VPVOID)psm16->pUnkForRelease; + RELVDMPTR(vpsm16); + + if (fIsThunk && vpvUnk != 0) + { + CSm16ReleaseHandler UNALIGNED *psrh; + + psrh = FIXVDMPTR(vpvUnk, CSm16ReleaseHandler); + psrh->Uninit(); + RELVDMPTR(vpvUnk); + WOWGlobalUnlockFree16(vpvUnk); + } + + psm16 = FIXVDMPTR(vpsm16, STGMEDIUM); + switch( psm16->tymed ) + { + case TYMED_HGLOBAL: + hmem16 = (HMEM16)psm16->hGlobal; + RELVDMPTR(vpsm16); + + if (fIsThunk && + (pfe == NULL || !OBJDESC_CF(pfe->cfFormat))) + { + sc = ConvertHGlobal1632(pti, hmem16, 0, + &psm32->hGlobal, &dwSize); + } + + WOWGlobalFree16( hmem16 ); + break; + + case TYMED_MFPICT: + hmem16 = (HMEM16)psm16->hGlobal; + RELVDMPTR(vpsm16); + + // Can't modify an MFPICT + +// Chicago uses the same GDI handles for both 32bit and 16bit worlds. +// Don't delete the handle after a copy since Chicago doesn't actually +// copy the handle. +#if !defined(_CHICAGO_) + VPVOID vpvmfp16; + METAFILEPICT16 *pmfp16; + HMEM16 hmf16; + + vpvmfp16 = WOWGlobalLock16(hmem16); + pmfp16 = FIXVDMPTR(vpvmfp16, METAFILEPICT16); + hmf16 = pmfp16->hMF; + RELVDMPTR(vpvmfp16); + + // Relies on the fact that a 16-bit metafile is an HGLOBAL + WOWGlobalFree16(hmf16); + + WOWGlobalUnlockFree16(vpvmfp16); +#else + WOWGlobalFree16(hmem16); +#endif + break; + + case TYMED_FILE: + vpvUnk = (VPVOID)psm16->lpszFileName; + RELVDMPTR(vpsm16); + + TaskFree16(vpvUnk); + break; + + case TYMED_ISTREAM: + RELVDMPTR(vpsm16); + + if (fIsThunk) + { + pti->pThkMgr->FreeProxy1632(psm32->pstm); + } + break; + + case TYMED_ISTORAGE: + RELVDMPTR(vpsm16); + + if (fIsThunk) + { + pti->pThkMgr->FreeProxy1632(psm32->pstg); + } + break; + + case TYMED_GDI: + RELVDMPTR(vpsm16); + + // + // No unthunking needed + // + break; + + case TYMED_NULL: + RELVDMPTR(vpsm16); + + break; + + default: + // Ignore, this case is handled on input + thkAssert(!"CleanStgMed16 with invalid tymed"); + break; + } + + thkDebugOut((DEB_ITRACE, "Out CleanStgMed16 => 0x%08lX\n", sc)); + + return sc; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertFetc1632, public +// +// Synopsis: Converts a FORMATETC +// +// Arguments: [pti] - Thunk info +// [vpfe16] - FORMATETC +// [pfe32] - FORMATETC +// [fFree] - Free resources as converting +// +// Returns: Appropriate status code +// +// Modifies: [pfe32] +// +// History: 14-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +SCODE ConvertFetc1632(THUNKINFO *pti, + VPVOID vpfe16, + FORMATETC *pfe32, + BOOL fFree) +{ + FORMATETC16 UNALIGNED *pfe16; + VPVOID vpdv16; + DVTARGETDEVICE *pdv32; + UINT cbSize; + SCODE sc; + + pfe16 = FIXVDMPTR(vpfe16, FORMATETC16); + vpdv16 = (VPVOID)pfe16->ptd; + RELVDMPTR(vpfe16); + + if ( vpdv16 == 0 ) + { + pdv32 = NULL; + } + else + { + sc = ConvertDvtd1632(pti, vpdv16, ArTask32, FrTask32, + &pdv32, &cbSize); + + if (fFree) + { + TaskFree16(vpdv16); + } + + if (FAILED(sc)) + { + return sc; + } + } + + pfe16 = FIXVDMPTR(vpfe16, FORMATETC16); + pfe32->cfFormat = pfe16->cfFormat; + pfe32->ptd = pdv32; + pfe32->dwAspect = pfe16->dwAspect; + pfe32->lindex = pfe16->lindex; + pfe32->tymed = pfe16->tymed; + + thkDebugOut((DEB_ARGS, "1632 FORMATETC: " + "%p -> %p {%d, %p (%p), %u, %u, 0x%X}\n", + vpfe16, pfe32, + pfe32->cfFormat, + pfe32->ptd, vpdv16, + pfe32->dwAspect, + pfe32->lindex, + pfe32->tymed)); + + RELVDMPTR(vpfe16); + + return S_OK; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertFetc3216, public +// +// Synopsis: Converts a FORMATETC +// +// Arguments: [pti] - Thunk info +// [pfe32] - FORMATETC +// [vpfe16] - FORMATETC +// [fFree] - Free resources as converting +// +// Returns: Appropriate status code +// +// Modifies: [vpfe16] +// +// History: 14-May-94 DrewB Created +// +//---------------------------------------------------------------------------- + +SCODE ConvertFetc3216(THUNKINFO *pti, + FORMATETC *pfe32, + VPVOID vpfe16, + BOOL fFree) +{ + FORMATETC16 UNALIGNED *pfe16; + DVTARGETDEVICE *pdv32; + SCODE sc; + VPVOID vpdv16; + UINT cbSize; + + pdv32 = pfe32->ptd; + if (pdv32 != NULL) + { + sc = ConvertDvtd3216(pti, pdv32, ArTask16, FrTask16, + &vpdv16, &cbSize); + + if (fFree) + { + TaskFree32(pdv32); + } + + if (FAILED(sc)) + { + return sc; + } + } + else + { + vpdv16 = 0; + } + + pfe16 = FIXVDMPTR(vpfe16, FORMATETC16); + pfe16->cfFormat = pfe32->cfFormat; + pfe16->ptd = vpdv16; + pfe16->dwAspect = pfe32->dwAspect; + pfe16->lindex = pfe32->lindex; + pfe16->tymed = pfe32->tymed; + + thkDebugOut((DEB_ARGS, "3216 FORMATETC: " + "%p -> %p {%d, %p (%p), %u, %u, 0x%X}\n", + pfe32, vpfe16, + pfe16->cfFormat, + vpdv16, pdv32, + pfe16->dwAspect, + pfe16->lindex, + pfe16->tymed)); + + RELVDMPTR(vpfe16); + + return S_OK; +} + +//+--------------------------------------------------------------------------- +// +// Function: DebugValidateProxy1632, debug public +// +// Synopsis: Validates a 16->32 proxy pointer and its memory +// +// Arguments: [vpvProxy] - Proxy +// +// History: 07-Jul-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +void DebugValidateProxy1632(VPVOID vpvProxy) +{ + THUNK1632OBJ UNALIGNED *pto; + THUNKINFO ti; + + thkAssert(vpvProxy != 0 && "Invalid proxy pointer"); + + pto = (THUNK1632OBJ UNALIGNED *) + GetReadWritePtr16(&ti, vpvProxy, sizeof(THUNK1632OBJ)); + thkAssert(pto != NULL && "Invalid proxy pointer"); + + thkAssert(pto->dwSignature == PSIG1632 && "Dead or invalid proxy!"); + + thkAssert(pto->cRefLocal >= 0 && "Invalid proxy refcount"); + thkAssert(pto->cRefLocal >= pto->cRef && "Invalid proxy refcount"); + + if (!IsValidInterface(pto->punkThis32)) + { + thkDebugOut((DEB_ERROR, "1632 %p: Invalid proxied object %p\n", + vpvProxy, pto->punkThis32)); + } + + WOWRELVDMPTR(vpvProxy); +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: DebugValidateProxy3216, debug public +// +// Synopsis: Validates a 32->16 proxy pointer and its memory +// +// Arguments: [pto] - Proxy +// +// History: 07-Jul-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +void DebugValidateProxy3216(THUNK3216OBJ *pto) +{ + THUNKINFO ti; + + thkAssert(pto != 0 && "Invalid proxy pointer"); + + thkAssert(!IsBadReadPtr(pto, sizeof(THUNK3216OBJ)) && + !IsBadWritePtr(pto, sizeof(THUNK3216OBJ)) && + "Invalid proxy pointer"); + + thkAssert(pto->dwSignature == PSIG3216 && "Dead or invalid proxy!"); + + thkAssert(pto->cRefLocal >= 0 && "Invalid proxy refcount"); + thkAssert(pto->cRefLocal >= pto->cRef && "Invalid proxy refcount"); + + if (!IsValidInterface16(&ti, pto->vpvThis16)) + { + thkDebugOut((DEB_ERROR, "3216 %p: Invalid proxied object %p\n", + pto, pto->vpvThis16)); + } +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: ClampLongToShort, public +// +// Synopsis: Restricts a long value to a short value by clamping +// +// Arguments: [l] - Long +// +// Returns: Short +// +// History: 16-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +SHORT ClampLongToShort(LONG l) +{ + SHORT s; + + if (l < SHRT_MIN) + { + s = SHRT_MIN; + thkDebugOut((DEB_WARN, "ClampLongToShort: %ld -> %d\n", l, s)); + } + else if (l > SHRT_MAX) + { + s = SHRT_MAX; + thkDebugOut((DEB_WARN, "ClampLongToShort: %ld -> %d\n", l, s)); + } + else + { + s = (SHORT)l; + } + + return s; +} + +//+--------------------------------------------------------------------------- +// +// Function: ClampULongToUShort, public +// +// Synopsis: Restricts an unsigned long value to an unsigned short value +// by clamping +// +// Arguments: [ul] - Long +// +// Returns: UShort +// +// History: 16-Aug-94 DrewB Created +// +//---------------------------------------------------------------------------- + +USHORT ClampULongToUShort(ULONG ul) +{ + USHORT us; + + if (ul > USHRT_MAX) + { + us = USHRT_MAX; + thkDebugOut((DEB_WARN, "ClampULongToUShort: %ld -> %d\n", ul, us)); + } + else + { + us = (USHORT)ul; + } + + return us; +} + +//+--------------------------------------------------------------------------- +// +// Function: ConvertObjDescriptor +// +// Synopsis: Exported API called by WOW to convert ObjectDescriptors to +// the indicated format. +// +// +// Arguments: [hMem] -- Handle to the ObjectDescriptor to convert. +// [flag] -- Flag indicating which direction the convertion +// should take place. Valid values are: +// CFOLE_UNICODE_TO_ANSI. +// CFOLE_ANSI_TO_UNICODE. +// +// Returns: HGLOBAL to the converted ObjectDescriptor, +// or NULL on failure. +// +// History: 8-16-94 terryru Created +// +// Notes: +// +//---------------------------------------------------------------------------- +STDAPI_(HGLOBAL) ConvertObjDescriptor( HANDLE hMem, UINT flag ) +{ + + const UINT CFOLE_UNICODE_TO_ANSI = 0; + const UINT CFOLE_ANSI_TO_UNICODE = 1; + + THUNKINFO ti; + HGLOBAL hMem32; + HMEM16 hMem16; + + switch ( flag ) + { + case CFOLE_UNICODE_TO_ANSI: + if( FAILED( ConvertObjDesc3216( &ti, (HGLOBAL) hMem, &hMem16 ))) + { + return (HGLOBAL) NULL; + } + else + { + return (HGLOBAL) hMem16; + } + break; + + case CFOLE_ANSI_TO_UNICODE: + if( FAILED( ConvertObjDesc1632( &ti, (HMEM16) hMem, &hMem32 ))) + { + return (HGLOBAL) NULL; + } + else + { + return (HGLOBAL) hMem32; + } + break; + + default: + thkAssert(!"ConvertObjDescriptor, Invalid flag"); + break; + } + return (HGLOBAL) NULL; +} + +#if defined(_CHICAGO_) + +// +// BUGBUGCHICAGO +// +// A hack so everyone can build Chicago OLE until I write the thunking +// library later this week. +// + +#define ERR ((char*) -1) + +#if DBG==1 +int UnicodeToAnsi(LPSTR sz, LPCWSTR pwsz, LONG cb) +{ + int ret; + + ret = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, pwsz, -1, sz, cb, NULL, NULL); + + thkAssert(ret != 0 && "Lost characters in thk Unicode->Ansi conversion"); + if (ret == 0) + { + DebugBreak(); + } + + return ret; +} +#else +#define UnicodeToAnsi(sz,pwsz,cb) WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, pwsz, -1, sz, cb, NULL, NULL) +#endif + + +#if DBG==1 +int AnsiToUnicode(LPWSTR pwsz, LPCSTR sz, LONG cb) +{ + int ret; + + ret = MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, sz, -1, pwsz, cb); + + thkAssert(ret != 0 && "Lost characters in thk Ansi->Unicode conversion"); + if (ret == 0) + { + DebugBreak(); + } + + return ret; +} +#else +#define AnsiToUnicode(pwsz,sz,cb) MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, sz, -1, pwsz, cb) +#endif + + + +extern "C" +DWORD +WINAPI +GetShortPathNameX( + LPCWSTR lpszFullPath, + LPWSTR lpszShortPath, + DWORD cchBuffer + ) +{ + #ifdef DEBUG_OUTPUT + OutputDebugString("GetShortPathName\n"); + #endif + + CHAR szFullPath[MAX_PATH]; + CHAR szShortBuffer[MAX_PATH]; + DWORD ret; + + + UnicodeToAnsi(szFullPath, lpszFullPath, sizeof(szFullPath)); + + if (lpszShortPath == NULL) + { + ret = GetShortPathNameA(szFullPath, NULL, cchBuffer); + } + else + { + ret = GetShortPathNameA(szFullPath, szShortBuffer, + sizeof(szShortBuffer)); + + thkAssert(ret != cchBuffer && + "GetShortPathName - Output buffer too short"); + // + // Don't convert the buffer if the + // call to GetShortPathNameA() failed. + // + if(0 != ret) + { + // + // Only convert the actual data, not the whole buffer. + // + if (cchBuffer > ret + 1) + cchBuffer = ret + 1; + + AnsiToUnicode(lpszShortPath, szShortBuffer, cchBuffer); + } + } + + return ret; +} + +#endif // _CHICAGO_ + diff --git a/private/ole32/olethunk/olethk32/thoputil.hxx b/private/ole32/olethunk/olethk32/thoputil.hxx new file mode 100644 index 000000000..f13fe7f09 --- /dev/null +++ b/private/ole32/olethunk/olethk32/thoputil.hxx @@ -0,0 +1,216 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thoputil.hxx +// +// Contents: Thunk routine utilities +// +// History: 01-Mar-94 DrewB Created +// +//---------------------------------------------------------------------------- + +#ifndef __THOPUTIL_HXX__ +#define __THOPUTIL_HXX__ + +// Alias manager for THOP_ALIAS32 +extern CAliases gAliases32; + +IIDIDX IidToIidIdx(REFIID riid); + +#ifdef COTASK_DEFINED +#define TaskMalloc32 CoTaskMemAlloc +#define TaskFree32 CoTaskMemFree +#else +LPVOID TaskMalloc32(DWORD cb); +void TaskFree32(LPVOID pv); +#endif + +DWORD TaskMalloc16( UINT uiSize ); +void TaskFree16( DWORD vpvoid ); + +LPOLESTR Convert_VPSTR_to_LPOLESTR(THUNKINFO *pti, + VPSTR vpstr, + LPOLESTR lpOleStr, + UINT uiSizeInPlace); +// +// Simple macro to free up any string allocated in the conversion process +// +#define Convert_VPSTR_to_LPOLESTR_free( lpOleStr, lpOleStrUsed ) \ + (((lpOleStr) == (lpOleStrUsed)) ? 0 : \ + (lpOleStrUsed == NULL) ? 0 : TaskFree32(lpOleStrUsed)) + +SCODE Convert_LPOLESTR_to_VPSTR(LPCOLESTR lpOleStr, + VPSTR vpstr, + UINT uiSize32, + UINT uiSize16); + +#ifdef _CHICAGO_ +// This is only really used on Chicago +SCODE Convert_LPSTR_to_VPSTR(LPCSTR lpOleStr, + VPSTR vpstr, + UINT uiSize32, + UINT uiSize16); +#endif + +STDAPI_(DWORD) TransformHRESULT_1632( DWORD hresult ); +STDAPI_(DWORD) TransformHRESULT_3216( DWORD hresult ); + +SHORT ClampLongToShort(LONG l); +USHORT ClampULongToUShort(ULONG l); + +VOID * GetReadPtr16( THUNKINFO *pti, VPVOID vp16, DWORD dwSize ); +VOID * GetWritePtr16( THUNKINFO *pti, VPVOID vp16, DWORD dwSize ); +VOID * GetCodePtr16( THUNKINFO *pti, VPVOID vp16, DWORD dwSize ); +VOID * GetReadWritePtr16( THUNKINFO *pti, VPVOID vp16, DWORD dwSize ); +CHAR * GetStringPtr16( THUNKINFO *pti, VPVOID vp16, UINT cchMax, + PUINT lpuiSize ); +VOID * ValidatePtr16(THUNKINFO *pti, VPVOID vp16, DWORD dwSize, + THOP thopInOut); +BOOL IsValidInterface16( THUNKINFO *pti, VPVOID vp ); + +SCODE ConvertHGlobal1632(THUNKINFO *pti, + HMEM16 hg16, + THOP thopInOut, + HGLOBAL *phg32, + DWORD *pdwSize); +SCODE ConvertHGlobal3216(THUNKINFO *pti, + HGLOBAL hg32, + THOP thopInOut, + HMEM16 *phg16, + DWORD *pdwSize); +SCODE ConvertStgMed1632(THUNKINFO *pti, + VPVOID vpsm16, + STGMEDIUM *psm32, + FORMATETC *pfe, + BOOL fPassingOwnershipIn, + DWORD *pdwSize); +SCODE CleanStgMed32(THUNKINFO *pti, + STGMEDIUM *psm32, + VPVOID vpsm16, + DWORD dwSize, + BOOL fIsThunk, + FORMATETC *pfe); +SCODE ConvertStgMed3216(THUNKINFO *pti, + STGMEDIUM *psm32, + VPVOID vpsm16, + FORMATETC *pfe, + BOOL fPassingOwnershipIn, + DWORD *pdwSize); +SCODE CleanStgMed16(THUNKINFO *pti, + VPVOID vpsm16, + STGMEDIUM *psm32, + DWORD dwSize, + BOOL fIsThunk, + FORMATETC *pfe); +SCODE ConvertFetc1632(THUNKINFO *pti, + VPVOID vpfe16, + FORMATETC *pfe32, + BOOL fFree); +SCODE ConvertFetc3216(THUNKINFO *pti, + FORMATETC *pfe32, + VPVOID vpfe16, + BOOL fFree); + +#if DBG == 1 + +char *ThopName(THOP thop); +char *EnumThopName(THOP thopEnum); +char *GuidString(GUID const *pguid); +char *IidOrInterfaceString(IID const *piid); +char *IidIdxString(IIDIDX iidx); + +void DebugValidateProxy1632(VPVOID vpvProxy); +void DebugValidateProxy3216(THUNK3216OBJ *ptoProxy); + +#else + +#define DebugValidateProxy1632(p) +#define DebugValidateProxy3216(p) + +#endif + +#define StackAlloc16(cb) \ + ((VPVOID)TlsThkGetStack16()->Alloc(cb)) +#define StackFree16(vpv, cb) \ + TlsThkGetStack16()->Free((DWORD)vpv, cb) +#define StackAlloc32(cb) \ + ((LPVOID)TlsThkGetStack32()->Alloc(cb)) +#define StackFree32(pv, cb) \ + TlsThkGetStack32()->Free((DWORD)pv, cb) + +#define STACKALLOC16(x) StackAlloc16(x) +#define STACKFREE16(x,y) StackFree16(x, y) + +#ifdef _CHICAGO_ +#define STACKALLOC32(x) StackAlloc32(x) +#define STACKFREE32(x, y) StackFree32(x, y) +#else +#define STACKALLOC32(x) (DWORD)_alloca(x) +#define STACKFREE32(x, y) +#endif + +#if DBG == 1 +void RecordStackState16(SStackRecord *psr); +void CheckStackState16(SStackRecord *psr); + +void RecordStackState32(SStackRecord *psr); +void CheckStackState32(SStackRecord *psr); +#endif + +typedef void *(*ALLOCROUTINE)(UINT cb); +typedef void (*FREEROUTINE)(void *pv, UINT cb); + +void *ArTask16(UINT cb); +void FrTask16(void *pv, UINT cb); + +void *ArTask32(UINT cb); +void FrTask32(void *pv, UINT cb); + +void *ArStack16(UINT cb); +void FrStack16(void *pv, UINT cb); + +void *ArStack32(UINT cb); +void FrStack32(void *pv, UINT cb); + +SCODE ConvertDvtd1632(THUNKINFO *pti, + VPVOID vpdvtd16, + ALLOCROUTINE pfnAlloc, + FREEROUTINE pfnFree, + DVTARGETDEVICE **ppdvtd32, + UINT *pcbSize); +SCODE ConvertDvtd3216(THUNKINFO *pti, + DVTARGETDEVICE *pdvtd32, + ALLOCROUTINE pfnAlloc, + FREEROUTINE pfnFree, + VPVOID *ppvdvtd16, + UINT *pcbSize); + +typedef void (*FIXEDHANDLERROUTINE)(BYTE *pbFrom, BYTE *pbTo, + UINT cbFrom, UINT cbTo); + +void FhCopyMemory(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhShortToLong(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhLongToShort(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhWordToDword(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhDwordToWord(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhGdiHandle1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhGdiHandle3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhUserHandle1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhUserHandle3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhHaccel1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhHaccel3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhHtask1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhHtask3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhHresult1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhHresult3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhNull(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhRect1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhRect3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhSize1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhSize3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhMsg1632(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); +void FhMsg3216(BYTE *pbFrom, BYTE *pbTo, UINT cbFrom, UINT cbTo); + +#endif // #ifndef __THOPUTIL_HXX__ diff --git a/private/ole32/olethunk/olethk32/thtblapi.cxx b/private/ole32/olethunk/olethk32/thtblapi.cxx new file mode 100644 index 000000000..3bc046a0d --- /dev/null +++ b/private/ole32/olethunk/olethk32/thtblapi.cxx @@ -0,0 +1,125 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thtblapi.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +#include <headers.cxx> +#pragma hdrstop + +#include "thopsapi.cxx" + +THOP CONST * CONST apthopsApiThops[] = +{ + thopsCoInitialize +, thopsCoUninitialize +, thopsCoGetClassObject +, thopsCoRegisterClassObject +, thopsCoRevokeClassObject +, thopsCoMarshalInterface +, thopsCoUnmarshalInterface +, thopsCoReleaseMarshalData +, thopsCoDisconnectObject +, thopsCoLockObjectExternal +, thopsCoGetStandardMarshal +, thopsCoIsHandlerConnected +, thopsCoFreeAllLibraries +, thopsCoFreeUnusedLibraries +, thopsCoCreateInstance +, thopsCLSIDFromString +, thopsCoIsOle1Class +, thopsProgIDFromCLSID +, thopsCLSIDFromProgID +, thopsCoCreateGuid +, thopsCoFileTimeToDosDateTime +, thopsCoDosDateTimeToFileTime +, thopsCoFileTimeNow +, thopsCoRegisterMessageFilter +, thopsCoGetTreatAsClass +, thopsCoTreatAsClass +, thopsDllGetClassObject +, thopsStgCreateDocfile +, thopsStgCreateDocfileOnILockBytes +, thopsStgOpenStorage +, thopsStgOpenStorageOnILockBytes +, thopsStgIsStorageFile +, thopsStgIsStorageILockBytes +, thopsStgSetTimes +, thopsCreateDataAdviseHolder +, thopsCreateDataCache +, thopsBindMoniker +, thopsMkParseDisplayName +, thopsMonikerRelativePathTo +, thopsMonikerCommonPrefixWith +, thopsCreateBindCtx +, thopsCreateGenericComposite +, thopsGetClassFile +, thopsCreateFileMoniker +, thopsCreateItemMoniker +, thopsCreateAntiMoniker +, thopsCreatePointerMoniker +, thopsGetRunningObjectTable +, thopsReadClassStg +, thopsWriteClassStg +, thopsReadClassStm +, thopsWriteClassStm +, thopsWriteFmtUserTypeStg +, thopsReadFmtUserTypeStg +, thopsOleInitialize +, thopsOleUninitialize +, thopsOleQueryLinkFromData +, thopsOleQueryCreateFromData +, thopsOleCreate +, thopsOleCreateFromData +, thopsOleCreateLinkFromData +, thopsOleCreateStaticFromData +, thopsOleCreateLink +, thopsOleCreateLinkToFile +, thopsOleCreateFromFile +, thopsOleLoad +, thopsOleSave +, thopsOleLoadFromStream +, thopsOleSaveToStream +, thopsOleSetContainedObject +, thopsOleNoteObjectVisible +, thopsRegisterDragDrop +, thopsRevokeDragDrop +, thopsDoDragDrop +, thopsOleSetClipboard +, thopsOleGetClipboard +, thopsOleFlushClipboard +, thopsOleIsCurrentClipboard +, thopsOleCreateMenuDescriptor +, thopsOleSetMenuDescriptor +, thopsOleDestroyMenuDescriptor +, thopsOleDraw +, thopsOleRun +, thopsOleIsRunning +, thopsOleLockRunning +, thopsCreateOleAdviseHolder +, thopsOleCreateDefaultHandler +, thopsOleCreateEmbeddingHelper +, thopsOleRegGetUserType +, thopsOleRegGetMiscStatus +, thopsOleRegEnumFormatEtc +, thopsOleRegEnumVerbs +, thopsOleConvertIStorageToOLESTREAM +, thopsOleConvertOLESTREAMToIStorage +, thopsOleConvertIStorageToOLESTREAMEx +, thopsOleConvertOLESTREAMToIStorageEx +, thopsOleDoAutoConvert +, thopsOleGetAutoConvert +, thopsOleSetAutoConvert +, thopsGetConvertStg +, thopsSetConvertStg +, thopsReadOleStg +, thopsWriteOleStg +}; diff --git a/private/ole32/olethunk/olethk32/thtblint.cxx b/private/ole32/olethunk/olethk32/thtblint.cxx new file mode 100644 index 000000000..dcd0e89dc --- /dev/null +++ b/private/ole32/olethunk/olethk32/thtblint.cxx @@ -0,0 +1,508 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: thtblint.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +THOP CONST * CONST apthopsIUnknown[] = +{ + NULL +}; +THOP CONST * CONST apthopsIClassFactory[] = +{ + thopsIClassFactory_CreateInstance +, thopsIClassFactory_LockServer +}; +THOP CONST * CONST apthopsIMarshal[] = +{ + thopsIMarshal_GetUnmarshalClass +, thopsIMarshal_GetMarshalSizeMax +, thopsIMarshal_MarshalInterface +, thopsIMarshal_UnmarshalInterface +, thopsIMarshal_ReleaseMarshalData +, thopsIMarshal_DisconnectObject +}; +THOP CONST * CONST apthopsIStdMarshalInfo[] = +{ + thopsIStdMarshalInfo_GetClassForHandler +}; +THOP CONST * CONST apthopsIMessageFilter[] = +{ + thopsIMessageFilter_HandleInComingCall +, thopsIMessageFilter_RetryRejectedCall +, thopsIMessageFilter_MessagePending +}; +THOP CONST * CONST apthopsIExternalConnection[] = +{ + thopsIExternalConnection_AddConnection +, thopsIExternalConnection_ReleaseConnection +}; +THOP CONST * CONST apthopsIEnumString[] = +{ + thopsIEnumString_Next +, thopsIEnumString_Skip +, thopsIEnumString_Reset +, thopsIEnumString_Clone +}; +THOP CONST * CONST apthopsIEnumUnknown[] = +{ + thopsIEnumUnknown_Next +, thopsIEnumUnknown_Skip +, thopsIEnumUnknown_Reset +, thopsIEnumUnknown_Clone +}; +THOP CONST * CONST apthopsIEnumSTATSTG[] = +{ + thopsIEnumSTATSTG_Next +, thopsIEnumSTATSTG_Skip +, thopsIEnumSTATSTG_Reset +, thopsIEnumSTATSTG_Clone +}; +THOP CONST * CONST apthopsILockBytes[] = +{ + thopsILockBytes_ReadAt +, thopsILockBytes_WriteAt +, thopsILockBytes_Flush +, thopsILockBytes_SetSize +, thopsILockBytes_LockRegion +, thopsILockBytes_UnlockRegion +, thopsILockBytes_Stat +}; +THOP CONST * CONST apthopsIStream[] = +{ + thopsIStream_Read +, thopsIStream_Write +, thopsIStream_Seek +, thopsIStream_SetSize +, thopsIStream_CopyTo +, thopsIStream_Commit +, thopsIStream_Revert +, thopsIStream_LockRegion +, thopsIStream_UnlockRegion +, thopsIStream_Stat +, thopsIStream_Clone +}; +THOP CONST * CONST apthopsIStorage[] = +{ + thopsIStorage_CreateStream +, thopsIStorage_OpenStream +, thopsIStorage_CreateStorage +, thopsIStorage_OpenStorage +, thopsIStorage_CopyTo +, thopsIStorage_MoveElementTo +, thopsIStorage_Commit +, thopsIStorage_Revert +, thopsIStorage_EnumElements +, thopsIStorage_DestroyElement +, thopsIStorage_RenameElement +, thopsIStorage_SetElementTimes +, thopsIStorage_SetClass +, thopsIStorage_SetStateBits +, thopsIStorage_Stat +}; +THOP CONST * CONST apthopsIRootStorage[] = +{ + thopsIRootStorage_SwitchToFile +}; +THOP CONST * CONST apthopsIEnumFORMATETC[] = +{ + thopsIEnumFORMATETC_Next +, thopsIEnumFORMATETC_Skip +, thopsIEnumFORMATETC_Reset +, thopsIEnumFORMATETC_Clone +}; +THOP CONST * CONST apthopsIEnumSTATDATA[] = +{ + thopsIEnumSTATDATA_Next +, thopsIEnumSTATDATA_Skip +, thopsIEnumSTATDATA_Reset +, thopsIEnumSTATDATA_Clone +}; +THOP CONST * CONST apthopsIDataObject[] = +{ + thopsIDataObject_GetData +, thopsIDataObject_GetDataHere +, thopsIDataObject_QueryGetData +, thopsIDataObject_GetCanonicalFormatEtc +, thopsIDataObject_SetData +, thopsIDataObject_EnumFormatEtc +, thopsIDataObject_DAdvise +, thopsIDataObject_DUnadvise +, thopsIDataObject_EnumDAdvise +}; +THOP CONST * CONST apthopsIViewObject[] = +{ + thopsIViewObject_Draw +, thopsIViewObject_GetColorSet +, thopsIViewObject_Freeze +, thopsIViewObject_Unfreeze +, thopsIViewObject_SetAdvise +, thopsIViewObject_GetAdvise +}; +THOP CONST * CONST apthopsIViewObject2[] = +{ + thopsIViewObject2_Draw +, thopsIViewObject2_GetColorSet +, thopsIViewObject2_Freeze +, thopsIViewObject2_Unfreeze +, thopsIViewObject2_SetAdvise +, thopsIViewObject2_GetAdvise +, thopsIViewObject2_GetExtent +}; +THOP CONST * CONST apthopsIAdviseSink[] = +{ + thopsIAdviseSink_OnDataChange +, thopsIAdviseSink_OnViewChange +, thopsIAdviseSink_OnRename +, thopsIAdviseSink_OnSave +, thopsIAdviseSink_OnClose +}; +THOP CONST * CONST apthopsIAdviseSink2[] = +{ + thopsIAdviseSink2_OnDataChange +, thopsIAdviseSink2_OnViewChange +, thopsIAdviseSink2_OnRename +, thopsIAdviseSink2_OnSave +, thopsIAdviseSink2_OnClose +, thopsIAdviseSink2_OnLinkSrcChange +}; +THOP CONST * CONST apthopsIDataAdviseHolder[] = +{ + thopsIDataAdviseHolder_Advise +, thopsIDataAdviseHolder_Unadvise +, thopsIDataAdviseHolder_EnumAdvise +, thopsIDataAdviseHolder_SendOnDataChange +}; +THOP CONST * CONST apthopsIOleCache[] = +{ + thopsIOleCache_Cache +, thopsIOleCache_Uncache +, thopsIOleCache_EnumCache +, thopsIOleCache_InitCache +, thopsIOleCache_SetData +}; +THOP CONST * CONST apthopsIOleCache2[] = +{ + thopsIOleCache2_Cache +, thopsIOleCache2_Uncache +, thopsIOleCache2_EnumCache +, thopsIOleCache2_InitCache +, thopsIOleCache2_SetData +, thopsIOleCache2_UpdateCache +, thopsIOleCache2_DiscardCache +}; +THOP CONST * CONST apthopsIOleCacheControl[] = +{ + thopsIOleCacheControl_OnRun +, thopsIOleCacheControl_OnStop +}; +THOP CONST * CONST apthopsIDropTarget[] = +{ + thopsIDropTarget_DragEnter +, thopsIDropTarget_DragOver +, thopsIDropTarget_DragLeave +, thopsIDropTarget_Drop +}; +THOP CONST * CONST apthopsIDropSource[] = +{ + thopsIDropSource_QueryContinueDrag +, thopsIDropSource_GiveFeedback +}; +THOP CONST * CONST apthopsIPersist[] = +{ + thopsIPersist_GetClassID +}; +THOP CONST * CONST apthopsIPersistStorage[] = +{ + thopsIPersistStorage_GetClassID +, thopsIPersistStorage_IsDirty +, thopsIPersistStorage_InitNew +, thopsIPersistStorage_Load +, thopsIPersistStorage_Save +, thopsIPersistStorage_SaveCompleted +, thopsIPersistStorage_HandsOffStorage +}; +THOP CONST * CONST apthopsIPersistStream[] = +{ + thopsIPersistStream_GetClassID +, thopsIPersistStream_IsDirty +, thopsIPersistStream_Load +, thopsIPersistStream_Save +, thopsIPersistStream_GetSizeMax +}; +THOP CONST * CONST apthopsIPersistFile[] = +{ + thopsIPersistFile_GetClassID +, thopsIPersistFile_IsDirty +, thopsIPersistFile_Load +, thopsIPersistFile_Save +, thopsIPersistFile_SaveCompleted +, thopsIPersistFile_GetCurFile +}; +THOP CONST * CONST apthopsIBindCtx[] = +{ + thopsIBindCtx_RegisterObjectBound +, thopsIBindCtx_RevokeObjectBound +, thopsIBindCtx_ReleaseBoundObjects +, thopsIBindCtx_SetBindOptions +, thopsIBindCtx_GetBindOptions +, thopsIBindCtx_GetRunningObjectTable +, thopsIBindCtx_RegisterObjectParam +, thopsIBindCtx_GetObjectParam +, thopsIBindCtx_EnumObjectParam +, thopsIBindCtx_RevokeObjectParam +}; +THOP CONST * CONST apthopsIMoniker[] = +{ + thopsIMoniker_GetClassID +, thopsIMoniker_IsDirty +, thopsIMoniker_Load +, thopsIMoniker_Save +, thopsIMoniker_GetSizeMax +, thopsIMoniker_BindToObject +, thopsIMoniker_BindToStorage +, thopsIMoniker_Reduce +, thopsIMoniker_ComposeWith +, thopsIMoniker_Enum +, thopsIMoniker_IsEqual +, thopsIMoniker_Hash +, thopsIMoniker_IsRunning +, thopsIMoniker_GetTimeOfLastChange +, thopsIMoniker_Inverse +, thopsIMoniker_CommonPrefixWith +, thopsIMoniker_RelativePathTo +, thopsIMoniker_GetDisplayName +, thopsIMoniker_ParseDisplayName +, thopsIMoniker_IsSystemMoniker +}; +THOP CONST * CONST apthopsIRunningObjectTable[] = +{ + thopsIRunningObjectTable_Register +, thopsIRunningObjectTable_Revoke +, thopsIRunningObjectTable_IsRunning +, thopsIRunningObjectTable_GetObject +, thopsIRunningObjectTable_NoteChangeTime +, thopsIRunningObjectTable_GetTimeOfLastChange +, thopsIRunningObjectTable_EnumRunning +}; +THOP CONST * CONST apthopsIEnumMoniker[] = +{ + thopsIEnumMoniker_Next +, thopsIEnumMoniker_Skip +, thopsIEnumMoniker_Reset +, thopsIEnumMoniker_Clone +}; +THOP CONST * CONST apthopsIEnumOLEVERB[] = +{ + thopsIEnumOLEVERB_Next +, thopsIEnumOLEVERB_Skip +, thopsIEnumOLEVERB_Reset +, thopsIEnumOLEVERB_Clone +}; +THOP CONST * CONST apthopsIOleObject[] = +{ + thopsIOleObject_SetClientSite +, thopsIOleObject_GetClientSite +, thopsIOleObject_SetHostNames +, thopsIOleObject_Close +, thopsIOleObject_SetMoniker +, thopsIOleObject_GetMoniker +, thopsIOleObject_InitFromData +, thopsIOleObject_GetClipboardData +, thopsIOleObject_DoVerb +, thopsIOleObject_EnumVerbs +, thopsIOleObject_Update +, thopsIOleObject_IsUpToDate +, thopsIOleObject_GetUserClassID +, thopsIOleObject_GetUserType +, thopsIOleObject_SetExtent +, thopsIOleObject_GetExtent +, thopsIOleObject_Advise +, thopsIOleObject_Unadvise +, thopsIOleObject_EnumAdvise +, thopsIOleObject_GetMiscStatus +, thopsIOleObject_SetColorScheme +}; +THOP CONST * CONST apthopsIOleClientSite[] = +{ + thopsIOleClientSite_SaveObject +, thopsIOleClientSite_GetMoniker +, thopsIOleClientSite_GetContainer +, thopsIOleClientSite_ShowObject +, thopsIOleClientSite_OnShowWindow +, thopsIOleClientSite_RequestNewObjectLayout +}; +THOP CONST * CONST apthopsIRunnableObject[] = +{ + thopsIRunnableObject_GetRunningClass +, thopsIRunnableObject_Run +, thopsIRunnableObject_IsRunning +, thopsIRunnableObject_LockRunning +, thopsIRunnableObject_SetContainedObject +}; +THOP CONST * CONST apthopsIParseDisplayName[] = +{ + thopsIParseDisplayName_ParseDisplayName +}; +THOP CONST * CONST apthopsIOleContainer[] = +{ + thopsIOleContainer_ParseDisplayName +, thopsIOleContainer_EnumObjects +, thopsIOleContainer_LockContainer +}; +THOP CONST * CONST apthopsIOleItemContainer[] = +{ + thopsIOleItemContainer_ParseDisplayName +, thopsIOleItemContainer_EnumObjects +, thopsIOleItemContainer_LockContainer +, thopsIOleItemContainer_GetObject +, thopsIOleItemContainer_GetObjectStorage +, thopsIOleItemContainer_IsRunning +}; +THOP CONST * CONST apthopsIOleAdviseHolder[] = +{ + thopsIOleAdviseHolder_Advise +, thopsIOleAdviseHolder_Unadvise +, thopsIOleAdviseHolder_EnumAdvise +, thopsIOleAdviseHolder_SendOnRename +, thopsIOleAdviseHolder_SendOnSave +, thopsIOleAdviseHolder_SendOnClose +}; +THOP CONST * CONST apthopsIOleLink[] = +{ + thopsIOleLink_SetUpdateOptions +, thopsIOleLink_GetUpdateOptions +, thopsIOleLink_SetSourceMoniker +, thopsIOleLink_GetSourceMoniker +, thopsIOleLink_SetSourceDisplayName +, thopsIOleLink_GetSourceDisplayName +, thopsIOleLink_BindToSource +, thopsIOleLink_BindIfRunning +, thopsIOleLink_GetBoundSource +, thopsIOleLink_UnbindSource +, thopsIOleLink_Update +}; +THOP CONST * CONST apthopsIOleWindow[] = +{ + thopsIOleWindow_GetWindow +, thopsIOleWindow_ContextSensitiveHelp +}; +THOP CONST * CONST apthopsIOleInPlaceObject[] = +{ + thopsIOleInPlaceObject_GetWindow +, thopsIOleInPlaceObject_ContextSensitiveHelp +, thopsIOleInPlaceObject_InPlaceDeactivate +, thopsIOleInPlaceObject_UIDeactivate +, thopsIOleInPlaceObject_SetObjectRects +, thopsIOleInPlaceObject_ReactivateAndUndo +}; +THOP CONST * CONST apthopsIOleInPlaceActiveObject[] = +{ + thopsIOleInPlaceActiveObject_GetWindow +, thopsIOleInPlaceActiveObject_ContextSensitiveHelp +, thopsIOleInPlaceActiveObject_TranslateAccelerator +, thopsIOleInPlaceActiveObject_OnFrameWindowActivate +, thopsIOleInPlaceActiveObject_OnDocWindowActivate +, thopsIOleInPlaceActiveObject_ResizeBorder +, thopsIOleInPlaceActiveObject_EnableModeless +}; +THOP CONST * CONST apthopsIOleInPlaceUIWindow[] = +{ + thopsIOleInPlaceUIWindow_GetWindow +, thopsIOleInPlaceUIWindow_ContextSensitiveHelp +, thopsIOleInPlaceUIWindow_GetBorder +, thopsIOleInPlaceUIWindow_RequestBorderSpace +, thopsIOleInPlaceUIWindow_SetBorderSpace +, thopsIOleInPlaceUIWindow_SetActiveObject +}; +THOP CONST * CONST apthopsIOleInPlaceFrame[] = +{ + thopsIOleInPlaceFrame_GetWindow +, thopsIOleInPlaceFrame_ContextSensitiveHelp +, thopsIOleInPlaceFrame_GetBorder +, thopsIOleInPlaceFrame_RequestBorderSpace +, thopsIOleInPlaceFrame_SetBorderSpace +, thopsIOleInPlaceFrame_SetActiveObject +, thopsIOleInPlaceFrame_InsertMenus +, thopsIOleInPlaceFrame_SetMenu +, thopsIOleInPlaceFrame_RemoveMenus +, thopsIOleInPlaceFrame_SetStatusText +, thopsIOleInPlaceFrame_EnableModeless +, thopsIOleInPlaceFrame_TranslateAccelerator +}; +THOP CONST * CONST apthopsIOleInPlaceSite[] = +{ + thopsIOleInPlaceSite_GetWindow +, thopsIOleInPlaceSite_ContextSensitiveHelp +, thopsIOleInPlaceSite_CanInPlaceActivate +, thopsIOleInPlaceSite_OnInPlaceActivate +, thopsIOleInPlaceSite_OnUIActivate +, thopsIOleInPlaceSite_GetWindowContext +, thopsIOleInPlaceSite_Scroll +, thopsIOleInPlaceSite_OnUIDeactivate +, thopsIOleInPlaceSite_OnInPlaceDeactivate +, thopsIOleInPlaceSite_DiscardUndoState +, thopsIOleInPlaceSite_DeactivateAndUndo +, thopsIOleInPlaceSite_OnPosRectChange +}; +THOP CONST * CONST apthopsIRpcChannelBuffer[] = +{ + thopsIRpcChannelBuffer_GetBuffer +, thopsIRpcChannelBuffer_SendReceive +, thopsIRpcChannelBuffer_FreeBuffer +, thopsIRpcChannelBuffer_GetDestCtx +, thopsIRpcChannelBuffer_IsConnected +}; +THOP CONST * CONST apthopsIRpcProxyBuffer[] = +{ + thopsIRpcProxyBuffer_Connect +, thopsIRpcProxyBuffer_Disconnect +}; +THOP CONST * CONST apthopsIRpcStubBuffer[] = +{ + thopsIRpcStubBuffer_Connect +, thopsIRpcStubBuffer_Disconnect +, thopsIRpcStubBuffer_Invoke +, thopsIRpcStubBuffer_IsIIDSupported +, thopsIRpcStubBuffer_CountRefs +, thopsIRpcStubBuffer_DebugServerQueryInterface +, thopsIRpcStubBuffer_DebugServerRelease +}; +THOP CONST * CONST apthopsIPSFactoryBuffer[] = +{ + thopsIPSFactoryBuffer_CreateProxy +, thopsIPSFactoryBuffer_CreateStub +}; +THOP CONST * CONST apthopsIRpcChannel[] = +{ + thopsIRpcChannel_GetStream +, thopsIRpcChannel_Call +, thopsIRpcChannel_GetDestCtx +, thopsIRpcChannel_IsConnected +}; +THOP CONST * CONST apthopsIRpcProxy[] = +{ + thopsIRpcProxy_Connect +, thopsIRpcProxy_Disconnect +}; +THOP CONST * CONST apthopsIRpcStub[] = +{ + thopsIRpcStub_Connect +, thopsIRpcStub_Disconnect +, thopsIRpcStub_Invoke +, thopsIRpcStub_IsIIDSupported +, thopsIRpcStub_CountRefs +}; +THOP CONST * CONST apthopsIPSFactory[] = +{ + thopsIPSFactory_CreateProxy +, thopsIPSFactory_CreateStub +}; diff --git a/private/ole32/olethunk/olethk32/tlsthk.cxx b/private/ole32/olethunk/olethk32/tlsthk.cxx new file mode 100644 index 000000000..628710327 --- /dev/null +++ b/private/ole32/olethunk/olethk32/tlsthk.cxx @@ -0,0 +1,171 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: tlsthk.cxx +// +// Contents: Utility routines for logical thread data +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +#include "headers.cxx" +#pragma hdrstop + +#define UNINITIALIZED_INDEX (0xffffffff) + +DWORD dwTlsThkIndex = UNINITIALIZED_INDEX; + +//+--------------------------------------------------------------------------- +// +// Function: TlsThkGetData +// +// Synopsis: returns pointer to thread data +// +// Returns: pointer to threaddata +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- + +#if DBG == 1 +PThreadData TlsThkGetData(void) +{ + if (dwTlsThkIndex == UNINITIALIZED_INDEX) + { + thkDebugOut((DEB_WARN, "WARNING: TLS slot used when uninitialized\n")); + } + + PThreadData pThreaddata = (PThreadData) TlsGetValue(dwTlsThkIndex); + + return pThreaddata; +} +#endif + +//+--------------------------------------------------------------------------- +// +// Function: TlsThkAlloc +// +// Synopsis: allocates a slot for thread data +// +// Returns: BOOL +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +BOOL TlsThkAlloc(void) +{ + thkDebugOut((DEB_THUNKMGR, "In TlsThkAlloc\n")); + + // We must be uninitialized to call this routine + thkAssert(dwTlsThkIndex == UNINITIALIZED_INDEX); + + dwTlsThkIndex = TlsAlloc(); + if (dwTlsThkIndex == UNINITIALIZED_INDEX) + { + return FALSE; + } + + thkDebugOut((DEB_THUNKMGR, "Out TlsThkAlloc\n")); + return TRUE; +} + +//+--------------------------------------------------------------------------- +// +// Function: TlsThkInitialize +// +// Synopsis: allocates thread data and initialize slot +// +// Returns: Appropriate status code +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +HRESULT TlsThkInitialize(void) +{ + PThreadData pThreaddata; + + thkDebugOut((DEB_THUNKMGR, "In TlsThkInitialize\n")); + + thkAssert(dwTlsThkIndex != UNINITIALIZED_INDEX && + "Tls slot not allocated."); + + // We must be uninitialized to call this routine + thkAssert(TlsGetValue(dwTlsThkIndex) == 0); + + pThreaddata = (PThreadData) LocalAlloc(LPTR, sizeof (ThreadData)); + if(pThreaddata != NULL) + { + // Force construction since we allocated with LocalAlloc + pThreaddata->sa16.CStackAllocator:: + CStackAllocator(&mmodel16Owned, 1024, 2); + pThreaddata->sa32.CStackAllocator:: + CStackAllocator(&mmodel32, 8192, 8); + + pThreaddata->pCThkMgr = 0; + pThreaddata->dwAppCompatFlags = 0; + + TlsSetValue(dwTlsThkIndex, pThreaddata); + } + + thkDebugOut((DEB_THUNKMGR, "Out TlsThkInitialize\n")); + + return (pThreaddata != NULL) ? NOERROR : E_OUTOFMEMORY; +} + +//+--------------------------------------------------------------------------- +// +// Function: TlsThkUninitialize +// +// Synopsis: frees thread data and set it to NULL +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +void TlsThkUninitialize(void) +{ + thkDebugOut((DEB_TLSTHK, "In TlsThkUninitialize\n")); + + // Asserts if data is NULL + PThreadData pThreaddata = TlsThkGetData(); + + // BUGBUG - We should assert that the things in the ThreadData + // are freed up + + if (pThreaddata != NULL) + { + // Stack allocators are cleaned up elsewhere + // because they require special treatment + + if (pThreaddata->pDelayedRegs != NULL) + { + delete pThreaddata->pDelayedRegs; + } + LocalFree(pThreaddata); + } + + TlsSetValue(dwTlsThkIndex, NULL); + + thkDebugOut((DEB_TLSTHK, "Out TlsThkUninitialize\n")); +} + +//+--------------------------------------------------------------------------- +// +// Function: TlsThkFree +// +// Synopsis: frees slot +// +// History: 5-18-94 JohannP (Johann Posch) Created +// +//---------------------------------------------------------------------------- +void TlsThkFree(void) +{ + thkAssert(dwTlsThkIndex != UNINITIALIZED_INDEX); + + TlsFree( dwTlsThkIndex ); + + // We must set this to an invalid value so any further uses of the + // TLS slot will return NULL + dwTlsThkIndex = UNINITIALIZED_INDEX; +} diff --git a/private/ole32/olethunk/olethk32/tlsthk.hxx b/private/ole32/olethunk/olethk32/tlsthk.hxx new file mode 100644 index 000000000..c2411133d --- /dev/null +++ b/private/ole32/olethunk/olethk32/tlsthk.hxx @@ -0,0 +1,85 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: TLSTHK.hxx +// +// Contents: Thunk routine utilities for tls +// +// History: 05-May-94 JohannP Created +// +//---------------------------------------------------------------------------- + +#ifndef __TLSTHK_HXX__ +#define __TLSTHK_HXX__ + +// +// The following structures are used by CoRegisterClassObjectDelayed +// +typedef struct tagDelayedRegistration +{ + CLSID _clsid; + DWORD _dwRealKey; + LPUNKNOWN _punk; + DWORD _dwClsContext; + DWORD _flags; +} DelayRegistration; + +#define MAX_DELAYED_REGISTRATIONS 8 + +typedef struct tagDelayedRegistrationTable +{ + tagDelayedRegistrationTable() + { + memset(&_Entries,0,sizeof(_Entries)); + } + DelayRegistration _Entries[MAX_DELAYED_REGISTRATIONS]; +} DelayedRegistrationTable; + +// +// This is the per thread thunk manager state +// + +typedef struct tagThreadData +{ + tagThreadData(DWORD cbBlock16, + DWORD cbAlign16, + DWORD cbBlock32, + DWORD cbAlign32) + : sa16(&mmodel16Owned, cbBlock16, cbAlign16), + sa32(&mmodel32, cbBlock32, cbAlign32),pDelayedRegs(NULL) + { + } + + CStackAllocator sa16; + CStackAllocator sa32; + CThkMgr *pCThkMgr; + DWORD dwAppCompatFlags; + DelayedRegistrationTable *pDelayedRegs; +} ThreadData, *PThreadData; + +HRESULT TlsThkInitialize(); +void TlsThkUninitialize(); + +BOOL TlsThkAlloc(); +void TlsThkFree(); + +#if DBG == 1 +PThreadData TlsThkGetData(void); +#else +extern DWORD dwTlsThkIndex; +#define TlsThkGetData() ((PThreadData)TlsGetValue(dwTlsThkIndex)) +#endif + +#define TlsThkGetStack16() (&TlsThkGetData()->sa16) +#define TlsThkGetStack32() (&TlsThkGetData()->sa32) + +#define TlsThkGetThkMgr() (TlsThkGetData()->pCThkMgr) +#define TlsThkSetThkMgr(ptm) ((TlsThkGetData()->pCThkMgr) = (ptm)) + +#define TlsThkGetAppCompatFlags() (TlsThkGetData()->dwAppCompatFlags) +#define TlsThkSetAppCompatFlags(dw) \ + ((TlsThkGetData()->dwAppCompatFlags) = (dw)) + +#endif // #ifndef __TLSTHK_HXX__ diff --git a/private/ole32/olethunk/olethk32/vtblapi.cxx b/private/ole32/olethunk/olethk32/vtblapi.cxx new file mode 100644 index 000000000..12f7ea492 --- /dev/null +++ b/private/ole32/olethunk/olethk32/vtblapi.cxx @@ -0,0 +1,123 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: vtblapi.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +#include <headers.cxx> +#pragma hdrstop + +VTBLFN CONST apfnApiFunctions[] = +{ + (VTBLFN)CoInitializeNot +, (VTBLFN)CoUninitialize +, (VTBLFN)CoGetClassObject +, (VTBLFN)CoRegisterClassObjectNot +, (VTBLFN)CoRevokeClassObjectNot +, (VTBLFN)CoMarshalInterface +, (VTBLFN)CoUnmarshalInterface +, (VTBLFN)CoReleaseMarshalData +, (VTBLFN)CoDisconnectObject +, (VTBLFN)CoLockObjectExternal +, (VTBLFN)CoGetStandardMarshal +, (VTBLFN)CoIsHandlerConnected +, (VTBLFN)CoFreeAllLibraries +, (VTBLFN)CoFreeUnusedLibraries +, (VTBLFN)CoCreateInstance +, (VTBLFN)CLSIDFromString +, (VTBLFN)CoIsOle1Class +, (VTBLFN)ProgIDFromCLSID +, (VTBLFN)CLSIDFromProgID +, (VTBLFN)CoCreateGuid +, (VTBLFN)CoFileTimeToDosDateTime +, (VTBLFN)CoDosDateTimeToFileTime +, (VTBLFN)CoFileTimeNow +, (VTBLFN)CoRegisterMessageFilter +, (VTBLFN)CoGetTreatAsClass +, (VTBLFN)CoTreatAsClass +, (VTBLFN)DllGetClassObjectWOW +, (VTBLFN)StgCreateDocfile +, (VTBLFN)StgCreateDocfileOnILockBytes +, (VTBLFN)StgOpenStorage +, (VTBLFN)StgOpenStorageOnILockBytes +, (VTBLFN)StgIsStorageFile +, (VTBLFN)StgIsStorageILockBytes +, (VTBLFN)StgSetTimes +, (VTBLFN)CreateDataAdviseHolder +, (VTBLFN)CreateDataCache +, (VTBLFN)BindMoniker +, (VTBLFN)MkParseDisplayName +, (VTBLFN)MonikerRelativePathTo +, (VTBLFN)MonikerCommonPrefixWith +, (VTBLFN)CreateBindCtx +, (VTBLFN)CreateGenericComposite +, (VTBLFN)GetClassFile +, (VTBLFN)CreateFileMoniker +, (VTBLFN)CreateItemMoniker +, (VTBLFN)CreateAntiMoniker +, (VTBLFN)CreatePointerMoniker +, (VTBLFN)GetRunningObjectTable +, (VTBLFN)ReadClassStg +, (VTBLFN)WriteClassStg +, (VTBLFN)ReadClassStm +, (VTBLFN)WriteClassStm +, (VTBLFN)WriteFmtUserTypeStg +, (VTBLFN)ReadFmtUserTypeStg +, (VTBLFN)OleInitializeNot +, (VTBLFN)OleUninitialize +, (VTBLFN)OleQueryLinkFromData +, (VTBLFN)OleQueryCreateFromData +, (VTBLFN)OleCreate +, (VTBLFN)OleCreateFromData +, (VTBLFN)OleCreateLinkFromData +, (VTBLFN)OleCreateStaticFromData +, (VTBLFN)OleCreateLink +, (VTBLFN)OleCreateLinkToFile +, (VTBLFN)OleCreateFromFile +, (VTBLFN)OleLoad +, (VTBLFN)OleSave +, (VTBLFN)OleLoadFromStream +, (VTBLFN)OleSaveToStream +, (VTBLFN)OleSetContainedObject +, (VTBLFN)OleNoteObjectVisible +, (VTBLFN)RegisterDragDrop +, (VTBLFN)RevokeDragDrop +, (VTBLFN)DoDragDrop +, (VTBLFN)OleSetClipboard +, (VTBLFN)OleGetClipboard +, (VTBLFN)OleFlushClipboard +, (VTBLFN)OleIsCurrentClipboard +, (VTBLFN)OleCreateMenuDescriptor +, (VTBLFN)OleSetMenuDescriptor +, (VTBLFN)OleDestroyMenuDescriptor +, (VTBLFN)OleDraw +, (VTBLFN)OleRun +, (VTBLFN)OleIsRunning +, (VTBLFN)OleLockRunning +, (VTBLFN)CreateOleAdviseHolder +, (VTBLFN)OleCreateDefaultHandler +, (VTBLFN)OleCreateEmbeddingHelper +, (VTBLFN)OleRegGetUserTypeNot +, (VTBLFN)OleRegGetMiscStatus +, (VTBLFN)OleRegEnumFormatEtc +, (VTBLFN)OleRegEnumVerbs +, (VTBLFN)OleConvertIStorageToOLESTREAM +, (VTBLFN)OleConvertOLESTREAMToIStorage +, (VTBLFN)OleConvertIStorageToOLESTREAMEx +, (VTBLFN)OleConvertOLESTREAMToIStorageEx +, (VTBLFN)OleDoAutoConvert +, (VTBLFN)OleGetAutoConvert +, (VTBLFN)OleSetAutoConvert +, (VTBLFN)GetConvertStg +, (VTBLFN)SetConvertStg +, (VTBLFN)ReadOleStg +, (VTBLFN)WriteOleStg +}; diff --git a/private/ole32/olethunk/olethk32/vtblifn.cxx b/private/ole32/olethunk/olethk32/vtblifn.cxx new file mode 100644 index 000000000..b6fb85ea4 --- /dev/null +++ b/private/ole32/olethunk/olethk32/vtblifn.cxx @@ -0,0 +1,766 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: vtblifn.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +DWORD ThunkMethod3216_48( + THUNK3216OBJ *ptoThis32 + ) +{ + DWORD dwMethod; + BYTE bArgs[4]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[48]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_47( + THUNK3216OBJ *ptoThis32 + ) +{ + DWORD dwMethod; + BYTE bArgs[4]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[47]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_46( + THUNK3216OBJ *ptoThis32 + ) +{ + DWORD dwMethod; + BYTE bArgs[4]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[46]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_45( + THUNK3216OBJ *ptoThis32, + SIZEL Arg1 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(SIZEL *)(bArgs+4) = Arg1; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[45]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_44( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + WORD Arg2 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(WORD *)(bArgs+8) = Arg2; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[44]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_43( + THUNK3216OBJ *ptoThis32 + ) +{ + DWORD dwMethod; + BYTE bArgs[4]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[43]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_42( + THUNK3216OBJ *ptoThis32, + DWORD Arg1 + ) +{ + DWORD dwMethod; + BYTE bArgs[8]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[42]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_41( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[41]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_40( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[40]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_39( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[39]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_38( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[38]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_37( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3 + ) +{ + DWORD dwMethod; + BYTE bArgs[16]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[37]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_36( + THUNK3216OBJ *ptoThis32, + DWORD Arg1 + ) +{ + DWORD dwMethod; + BYTE bArgs[8]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[36]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_35( + THUNK3216OBJ *ptoThis32, + DWORD Arg1 + ) +{ + DWORD dwMethod; + BYTE bArgs[8]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[35]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_34( + THUNK3216OBJ *ptoThis32, + DWORD Arg1 + ) +{ + DWORD dwMethod; + BYTE bArgs[8]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[34]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_33( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + SIZEL Arg3, + DWORD Arg4 + ) +{ + DWORD dwMethod; + BYTE bArgs[24]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(SIZEL *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+20) = Arg4; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[33]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_32( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + SIZEL Arg2, + DWORD Arg3 + ) +{ + DWORD dwMethod; + BYTE bArgs[20]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(SIZEL *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+16) = Arg3; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[32]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_31( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + SIZEL Arg3, + DWORD Arg4 + ) +{ + DWORD dwMethod; + BYTE bArgs[24]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(SIZEL *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+20) = Arg4; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[31]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_30( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3 + ) +{ + DWORD dwMethod; + BYTE bArgs[16]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[30]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_29( + THUNK3216OBJ *ptoThis32 + ) +{ + DWORD dwMethod; + BYTE bArgs[4]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[29]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_28( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4, + DWORD Arg5, + DWORD Arg6, + DWORD Arg7, + DWORD Arg8, + DWORD Arg9, + DWORD Arg10 + ) +{ + DWORD dwMethod; + BYTE bArgs[44]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + *(DWORD *)(bArgs+20) = Arg5; + *(DWORD *)(bArgs+24) = Arg6; + *(DWORD *)(bArgs+28) = Arg7; + *(DWORD *)(bArgs+32) = Arg8; + *(DWORD *)(bArgs+36) = Arg9; + *(DWORD *)(bArgs+40) = Arg10; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[28]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_27( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[27]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_26( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[26]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_25( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[25]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_24( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4 + ) +{ + DWORD dwMethod; + BYTE bArgs[20]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[24]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_23( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4 + ) +{ + DWORD dwMethod; + BYTE bArgs[20]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[23]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_22( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4 + ) +{ + DWORD dwMethod; + BYTE bArgs[20]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[22]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_21( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4, + DWORD Arg5 + ) +{ + DWORD dwMethod; + BYTE bArgs[24]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + *(DWORD *)(bArgs+20) = Arg5; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[21]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_20( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4, + DWORD Arg5 + ) +{ + DWORD dwMethod; + BYTE bArgs[24]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + *(DWORD *)(bArgs+20) = Arg5; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[20]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_19( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4, + DWORD Arg5 + ) +{ + DWORD dwMethod; + BYTE bArgs[24]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + *(DWORD *)(bArgs+20) = Arg5; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[19]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_18( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + ULARGE_INTEGER Arg2, + DWORD Arg3, + DWORD Arg4 + ) +{ + DWORD dwMethod; + BYTE bArgs[24]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(ULARGE_INTEGER UNALIGNED *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+16) = Arg3; + *(DWORD *)(bArgs+20) = Arg4; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[18]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_17( + THUNK3216OBJ *ptoThis32, + ULARGE_INTEGER Arg1, + DWORD Arg2, + DWORD Arg3 + ) +{ + DWORD dwMethod; + BYTE bArgs[20]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(ULARGE_INTEGER UNALIGNED *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+12) = Arg2; + *(DWORD *)(bArgs+16) = Arg3; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[17]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_16( + THUNK3216OBJ *ptoThis32, + ULARGE_INTEGER Arg1, + ULARGE_INTEGER Arg2, + DWORD Arg3 + ) +{ + DWORD dwMethod; + BYTE bArgs[24]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(ULARGE_INTEGER UNALIGNED *)(bArgs+4) = Arg1; + *(ULARGE_INTEGER UNALIGNED *)(bArgs+12) = Arg2; + *(DWORD *)(bArgs+20) = Arg3; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[16]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_15( + THUNK3216OBJ *ptoThis32, + ULARGE_INTEGER Arg1, + ULARGE_INTEGER Arg2, + DWORD Arg3 + ) +{ + DWORD dwMethod; + BYTE bArgs[24]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(ULARGE_INTEGER UNALIGNED *)(bArgs+4) = Arg1; + *(ULARGE_INTEGER UNALIGNED *)(bArgs+12) = Arg2; + *(DWORD *)(bArgs+20) = Arg3; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[15]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_14( + THUNK3216OBJ *ptoThis32, + ULARGE_INTEGER Arg1 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(ULARGE_INTEGER UNALIGNED *)(bArgs+4) = Arg1; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[14]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_13( + THUNK3216OBJ *ptoThis32, + ULARGE_INTEGER Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4 + ) +{ + DWORD dwMethod; + BYTE bArgs[24]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(ULARGE_INTEGER UNALIGNED *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+12) = Arg2; + *(DWORD *)(bArgs+16) = Arg3; + *(DWORD *)(bArgs+20) = Arg4; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[13]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_12( + THUNK3216OBJ *ptoThis32, + ULARGE_INTEGER Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4 + ) +{ + DWORD dwMethod; + BYTE bArgs[24]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(ULARGE_INTEGER UNALIGNED *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+12) = Arg2; + *(DWORD *)(bArgs+16) = Arg3; + *(DWORD *)(bArgs+20) = Arg4; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[12]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_11( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3 + ) +{ + DWORD dwMethod; + BYTE bArgs[16]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[11]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_10( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4 + ) +{ + DWORD dwMethod; + BYTE bArgs[20]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[10]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_9( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4, + DWORD Arg5, + DWORD Arg6 + ) +{ + DWORD dwMethod; + BYTE bArgs[28]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + *(DWORD *)(bArgs+20) = Arg5; + *(DWORD *)(bArgs+24) = Arg6; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[9]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_8( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4, + DWORD Arg5, + DWORD Arg6 + ) +{ + DWORD dwMethod; + BYTE bArgs[28]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + *(DWORD *)(bArgs+20) = Arg5; + *(DWORD *)(bArgs+24) = Arg6; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[8]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_7( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3, + DWORD Arg4, + DWORD Arg5, + DWORD Arg6 + ) +{ + DWORD dwMethod; + BYTE bArgs[28]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + *(DWORD *)(bArgs+16) = Arg4; + *(DWORD *)(bArgs+20) = Arg5; + *(DWORD *)(bArgs+24) = Arg6; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[7]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_6( + THUNK3216OBJ *ptoThis32 + ) +{ + DWORD dwMethod; + BYTE bArgs[4]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[6]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_5( + THUNK3216OBJ *ptoThis32, + DWORD Arg1 + ) +{ + DWORD dwMethod; + BYTE bArgs[8]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[5]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_4( + THUNK3216OBJ *ptoThis32, + DWORD Arg1 + ) +{ + DWORD dwMethod; + BYTE bArgs[8]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[4]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_3( + THUNK3216OBJ *ptoThis32, + DWORD Arg1 + ) +{ + DWORD dwMethod; + BYTE bArgs[8]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[3]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_2( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2 + ) +{ + DWORD dwMethod; + BYTE bArgs[12]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[2]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_1( + THUNK3216OBJ *ptoThis32, + DWORD Arg1 + ) +{ + DWORD dwMethod; + BYTE bArgs[8]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[1]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} +DWORD ThunkMethod3216_0( + THUNK3216OBJ *ptoThis32, + DWORD Arg1, + DWORD Arg2, + DWORD Arg3 + ) +{ + DWORD dwMethod; + BYTE bArgs[16]; + *(VPVOID *)bArgs = (DWORD)ptoThis32; + *(DWORD *)(bArgs+4) = Arg1; + *(DWORD *)(bArgs+8) = Arg2; + *(DWORD *)(bArgs+12) = Arg3; + dwMethod = athopiInterfaceThopis[IIDIDX_INDEX(ptoThis32->iidx)].pftm[0]; + return InvokeOn16(IIDIDX_INDEX(ptoThis32->iidx), dwMethod, bArgs); +} diff --git a/private/ole32/olethunk/olethk32/vtblint.cxx b/private/ole32/olethunk/olethk32/vtblint.cxx new file mode 100644 index 000000000..cd1e9b62b --- /dev/null +++ b/private/ole32/olethunk/olethk32/vtblint.cxx @@ -0,0 +1,678 @@ +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992 - 1994. +// +// File: vtblint.cxx +// +// Notes: This file is automatically generated +// Do not modify by hand +// +// History: Fri May 27 10:39:02 1994 Generated +// +//---------------------------------------------------------------------------- + +THUNK3216FN CONST tfnIUnknown[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +}; +THUNK3216FN CONST tfnIClassFactory[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_0 +, (THUNK3216FN)ThunkMethod3216_1 +}; +THUNK3216FN CONST tfnIMarshal[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_7 +, (THUNK3216FN)ThunkMethod3216_8 +, (THUNK3216FN)ThunkMethod3216_9 +, (THUNK3216FN)ThunkMethod3216_0 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_4 +}; +THUNK3216FN CONST tfnIStdMarshalInfo[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_0 +}; +THUNK3216FN CONST tfnIMessageFilter[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_10 +, (THUNK3216FN)ThunkMethod3216_0 +, (THUNK3216FN)ThunkMethod3216_11 +}; +THUNK3216FN CONST tfnIExternalConnection[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_2 +, (THUNK3216FN)ThunkMethod3216_11 +}; +THUNK3216FN CONST tfnIEnumString[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_4 +}; +THUNK3216FN CONST tfnIEnumUnknown[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_4 +}; +THUNK3216FN CONST tfnIEnumSTATSTG[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_4 +}; +THUNK3216FN CONST tfnILockBytes[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_12 +, (THUNK3216FN)ThunkMethod3216_13 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_14 +, (THUNK3216FN)ThunkMethod3216_15 +, (THUNK3216FN)ThunkMethod3216_16 +, (THUNK3216FN)ThunkMethod3216_2 +}; +THUNK3216FN CONST tfnIStream[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_0 +, (THUNK3216FN)ThunkMethod3216_17 +, (THUNK3216FN)ThunkMethod3216_14 +, (THUNK3216FN)ThunkMethod3216_18 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_16 +, (THUNK3216FN)ThunkMethod3216_15 +, (THUNK3216FN)ThunkMethod3216_2 +, (THUNK3216FN)ThunkMethod3216_4 +}; +THUNK3216FN CONST tfnIStorage[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_19 +, (THUNK3216FN)ThunkMethod3216_20 +, (THUNK3216FN)ThunkMethod3216_21 +, (THUNK3216FN)ThunkMethod3216_9 +, (THUNK3216FN)ThunkMethod3216_10 +, (THUNK3216FN)ThunkMethod3216_22 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_23 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_2 +, (THUNK3216FN)ThunkMethod3216_24 +, (THUNK3216FN)ThunkMethod3216_3 +, (THUNK3216FN)ThunkMethod3216_25 +, (THUNK3216FN)ThunkMethod3216_26 +}; +THUNK3216FN CONST tfnIRootStorage[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_5 +}; +THUNK3216FN CONST tfnIEnumFORMATETC[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_4 +}; +THUNK3216FN CONST tfnIEnumSTATDATA[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_4 +}; +THUNK3216FN CONST tfnIDataObject[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_26 +, (THUNK3216FN)ThunkMethod3216_25 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_2 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_24 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_3 +}; +THUNK3216FN CONST tfnIViewObject[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_28 +, (THUNK3216FN)ThunkMethod3216_9 +, (THUNK3216FN)ThunkMethod3216_24 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_0 +}; +THUNK3216FN CONST tfnIViewObject2[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_28 +, (THUNK3216FN)ThunkMethod3216_9 +, (THUNK3216FN)ThunkMethod3216_24 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_0 +, (THUNK3216FN)ThunkMethod3216_23 +}; +THUNK3216FN CONST tfnIAdviseSink[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_26 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_29 +}; +THUNK3216FN CONST tfnIAdviseSink2[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_26 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_4 +}; +THUNK3216FN CONST tfnIDataAdviseHolder[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_21 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_11 +}; +THUNK3216FN CONST tfnIOleCache[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_3 +, (THUNK3216FN)ThunkMethod3216_0 +}; +THUNK3216FN CONST tfnIOleCache2[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_3 +, (THUNK3216FN)ThunkMethod3216_0 +, (THUNK3216FN)ThunkMethod3216_30 +, (THUNK3216FN)ThunkMethod3216_1 +}; +THUNK3216FN CONST tfnIOleCacheControl[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_29 +}; +THUNK3216FN CONST tfnIDropTarget[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_31 +, (THUNK3216FN)ThunkMethod3216_32 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_33 +}; +THUNK3216FN CONST tfnIDropSource[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_5 +}; +THUNK3216FN CONST tfnIPersist[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_5 +}; +THUNK3216FN CONST tfnIPersistStorage[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_3 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_1 +, (THUNK3216FN)ThunkMethod3216_6 +}; +THUNK3216FN CONST tfnIPersistStream[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_3 +}; +THUNK3216FN CONST tfnIPersistFile[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_26 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_3 +}; +THUNK3216FN CONST tfnIBindCtx[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_3 +, (THUNK3216FN)ThunkMethod3216_1 +, (THUNK3216FN)ThunkMethod3216_34 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_26 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_36 +}; +THUNK3216FN CONST tfnIMoniker[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_34 +, (THUNK3216FN)ThunkMethod3216_24 +, (THUNK3216FN)ThunkMethod3216_23 +, (THUNK3216FN)ThunkMethod3216_22 +, (THUNK3216FN)ThunkMethod3216_30 +, (THUNK3216FN)ThunkMethod3216_26 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_11 +, (THUNK3216FN)ThunkMethod3216_0 +, (THUNK3216FN)ThunkMethod3216_3 +, (THUNK3216FN)ThunkMethod3216_25 +, (THUNK3216FN)ThunkMethod3216_2 +, (THUNK3216FN)ThunkMethod3216_37 +, (THUNK3216FN)ThunkMethod3216_21 +, (THUNK3216FN)ThunkMethod3216_1 +}; +THUNK3216FN CONST tfnIRunningObjectTable[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_24 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_26 +, (THUNK3216FN)ThunkMethod3216_25 +, (THUNK3216FN)ThunkMethod3216_34 +}; +THUNK3216FN CONST tfnIEnumMoniker[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_37 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_35 +}; +THUNK3216FN CONST tfnIEnumOLEVERB[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_37 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_35 +}; +THUNK3216FN CONST tfnIOleObject[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_27 +, (THUNK3216FN)ThunkMethod3216_34 +, (THUNK3216FN)ThunkMethod3216_26 +, (THUNK3216FN)ThunkMethod3216_37 +, (THUNK3216FN)ThunkMethod3216_30 +, (THUNK3216FN)ThunkMethod3216_25 +, (THUNK3216FN)ThunkMethod3216_9 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_2 +, (THUNK3216FN)ThunkMethod3216_38 +, (THUNK3216FN)ThunkMethod3216_39 +, (THUNK3216FN)ThunkMethod3216_40 +, (THUNK3216FN)ThunkMethod3216_3 +, (THUNK3216FN)ThunkMethod3216_1 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_42 +}; +THUNK3216FN CONST tfnIOleClientSite[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_37 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_43 +}; +THUNK3216FN CONST tfnIRunnableObject[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_43 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_35 +}; +THUNK3216FN CONST tfnIParseDisplayName[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_24 +}; +THUNK3216FN CONST tfnIOleContainer[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_24 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_42 +}; +THUNK3216FN CONST tfnIOleItemContainer[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_24 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_21 +, (THUNK3216FN)ThunkMethod3216_23 +, (THUNK3216FN)ThunkMethod3216_36 +}; +THUNK3216FN CONST tfnIOleAdviseHolder[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_43 +, (THUNK3216FN)ThunkMethod3216_29 +}; +THUNK3216FN CONST tfnIOleLink[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_34 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_40 +, (THUNK3216FN)ThunkMethod3216_43 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_3 +}; +THUNK3216FN CONST tfnIOleWindow[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_36 +}; +THUNK3216FN CONST tfnIOleInPlaceObject[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_43 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_6 +}; +THUNK3216FN CONST tfnIOleInPlaceActiveObject[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_34 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_37 +, (THUNK3216FN)ThunkMethod3216_4 +}; +THUNK3216FN CONST tfnIOleInPlaceUIWindow[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_34 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_41 +}; +THUNK3216FN CONST tfnIOleInPlaceFrame[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_34 +, (THUNK3216FN)ThunkMethod3216_5 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_40 +, (THUNK3216FN)ThunkMethod3216_37 +, (THUNK3216FN)ThunkMethod3216_4 +, (THUNK3216FN)ThunkMethod3216_3 +, (THUNK3216FN)ThunkMethod3216_1 +, (THUNK3216FN)ThunkMethod3216_44 +}; +THUNK3216FN CONST tfnIOleInPlaceSite[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_43 +, (THUNK3216FN)ThunkMethod3216_29 +, (THUNK3216FN)ThunkMethod3216_6 +, (THUNK3216FN)ThunkMethod3216_21 +, (THUNK3216FN)ThunkMethod3216_45 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_46 +, (THUNK3216FN)ThunkMethod3216_47 +, (THUNK3216FN)ThunkMethod3216_48 +, (THUNK3216FN)ThunkMethod3216_34 +}; +THUNK3216FN CONST tfnIRpcChannelBuffer[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_40 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_39 +, (THUNK3216FN)ThunkMethod3216_48 +}; +THUNK3216FN CONST tfnIRpcProxyBuffer[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_48 +}; +THUNK3216FN CONST tfnIRpcStubBuffer[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_48 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_47 +, (THUNK3216FN)ThunkMethod3216_35 +, (THUNK3216FN)ThunkMethod3216_34 +}; +THUNK3216FN CONST tfnIPSFactoryBuffer[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_24 +, (THUNK3216FN)ThunkMethod3216_37 +}; +THUNK3216FN CONST tfnIRpcChannel[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_9 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_41 +, (THUNK3216FN)ThunkMethod3216_48 +}; +THUNK3216FN CONST tfnIRpcProxy[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_48 +}; +THUNK3216FN CONST tfnIRpcStub[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_42 +, (THUNK3216FN)ThunkMethod3216_48 +, (THUNK3216FN)ThunkMethod3216_21 +, (THUNK3216FN)ThunkMethod3216_36 +, (THUNK3216FN)ThunkMethod3216_47 +}; +THUNK3216FN CONST tfnIPSFactory[] = +{ + (THUNK3216FN)QueryInterfaceProxy3216 +, (THUNK3216FN)AddRefProxy3216 +, (THUNK3216FN)ReleaseProxy3216 +, (THUNK3216FN)ThunkMethod3216_24 +, (THUNK3216FN)ThunkMethod3216_37 +}; |