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/oleutest/letest/outline/classfac.h | |
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/oleutest/letest/outline/classfac.h')
-rw-r--r-- | private/oleutest/letest/outline/classfac.h | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/private/oleutest/letest/outline/classfac.h b/private/oleutest/letest/outline/classfac.h new file mode 100644 index 000000000..cf3070227 --- /dev/null +++ b/private/oleutest/letest/outline/classfac.h @@ -0,0 +1,219 @@ +/************************************************************************* +** +** OLE 2 Sample Code +** +** classfac.c +** +** This file contains the implementation for IClassFactory for both the +** server and the client version of the OUTLINE app. +** +** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved +** +*************************************************************************/ + +#include "outline.h" + +OLEDBGDATA + +extern LPOUTLINEAPP g_lpApp; + + +/* OLE2NOTE: this object illustrates the manner in which to statically +** (compile-time) initialize an interface VTBL. +*/ +static IClassFactoryVtbl g_AppClassFactoryVtbl = { + AppClassFactory_QueryInterface, + AppClassFactory_AddRef, + AppClassFactory_Release, + AppClassFactory_CreateInstance, + AppClassFactory_LockServer +}; + + +/* AppClassFactory_Create +** ---------------------- +** create an instance of APPCLASSFACTORY. +** NOTE: type of pointer returned is an IClassFactory* interface ptr. +** the returned pointer can be directly passed to +** CoRegisterClassObject and released later by calling the +** Release method of the interface. +*/ +LPCLASSFACTORY WINAPI AppClassFactory_Create(void) +{ + LPAPPCLASSFACTORY lpAppClassFactory; + LPMALLOC lpMalloc; + + if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR) + return NULL; + + lpAppClassFactory = (LPAPPCLASSFACTORY)lpMalloc->lpVtbl->Alloc( + lpMalloc, (sizeof(APPCLASSFACTORY))); + lpMalloc->lpVtbl->Release(lpMalloc); + if (! lpAppClassFactory) return NULL; + + lpAppClassFactory->m_lpVtbl = &g_AppClassFactoryVtbl; + lpAppClassFactory->m_cRef = 1; +#if defined( _DEBUG ) + lpAppClassFactory->m_cSvrLock = 0; +#endif + return (LPCLASSFACTORY)lpAppClassFactory; +} + + +/************************************************************************* +** OleApp::IClassFactory interface implementation +*************************************************************************/ + +STDMETHODIMP AppClassFactory_QueryInterface( + LPCLASSFACTORY lpThis, REFIID riid, LPVOID FAR* ppvObj) +{ + LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis; + SCODE scode; + + // Two interfaces supported: IUnknown, IClassFactory + + if (IsEqualIID(riid, &IID_IClassFactory) || + IsEqualIID(riid, &IID_IUnknown)) { + lpAppClassFactory->m_cRef++; // A pointer to this object is returned + *ppvObj = lpThis; + scode = S_OK; + } + else { // unsupported interface + *ppvObj = NULL; + scode = E_NOINTERFACE; + } + + return ResultFromScode(scode); +} + + +STDMETHODIMP_(ULONG) AppClassFactory_AddRef(LPCLASSFACTORY lpThis) +{ + LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis; + return ++lpAppClassFactory->m_cRef; +} + +STDMETHODIMP_(ULONG) AppClassFactory_Release(LPCLASSFACTORY lpThis) +{ + LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis; + LPMALLOC lpMalloc; + + if (--lpAppClassFactory->m_cRef != 0) // Still used by others + return lpAppClassFactory->m_cRef; + + // Free storage + if (CoGetMalloc(MEMCTX_TASK, (LPMALLOC FAR*)&lpMalloc) != NOERROR) + return 0; + + lpMalloc->lpVtbl->Free(lpMalloc, lpAppClassFactory); + lpMalloc->lpVtbl->Release(lpMalloc); + return 0; +} + + +STDMETHODIMP AppClassFactory_CreateInstance ( + LPCLASSFACTORY lpThis, + LPUNKNOWN lpUnkOuter, + REFIID riid, + LPVOID FAR* lplpvObj +) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + LPOLEDOC lpOleDoc; + HRESULT hrErr; + + OLEDBG_BEGIN2("AppClassFactory_CreateInstance\r\n") + + /* OLE2NOTE: we must make sure to set all out parameters to NULL. */ + *lplpvObj = NULL; + + /********************************************************************* + ** OLE2NOTE: this is an SDI app; it can only create and support one + ** instance. After the instance is created, the OLE libraries + ** should not call CreateInstance again. it is a good practise + ** to specifically guard against this. + *********************************************************************/ + + if (lpOutlineApp->m_lpDoc != NULL) + return ResultFromScode(E_UNEXPECTED); + + /* OLE2NOTE: create a new document instance. by the time we return + ** from this method the document's refcnt must be 1. + */ + lpOutlineApp->m_lpDoc = OutlineApp_CreateDoc(lpOutlineApp, FALSE); + lpOleDoc = (LPOLEDOC)lpOutlineApp->m_lpDoc; + if (! lpOleDoc) { + OLEDBG_END2 + return ResultFromScode(E_OUTOFMEMORY); + } + + /* OLE2NOTE: retrieve pointer to requested interface. the ref cnt + ** of the object after OutlineApp_CreateDoc is 0. this call to + ** QueryInterface will increment the refcnt to 1. the object + ** returned from IClassFactory::CreateInstance should have a + ** refcnt of 1 and be controlled by the caller. If the caller + ** releases the document, the document should be destroyed. + */ + hrErr = OleDoc_QueryInterface(lpOleDoc, riid, lplpvObj); + + OLEDBG_END2 + return hrErr; +} + + +STDMETHODIMP AppClassFactory_LockServer ( + LPCLASSFACTORY lpThis, + BOOL fLock +) +{ + LPAPPCLASSFACTORY lpAppClassFactory = (LPAPPCLASSFACTORY)lpThis; + LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp; + HRESULT hrErr; + OLEDBG_BEGIN2("AppClassFactory_LockServer\r\n") + +#if defined( _DEBUG ) + if (fLock) { + ++lpAppClassFactory->m_cSvrLock; + OleDbgOutRefCnt3( + "AppClassFactory_LockServer: cLock++\r\n", + lpAppClassFactory, lpAppClassFactory->m_cSvrLock); + } else { + + /* OLE2NOTE: when there are no open documents and the app is not + ** under the control of the user and there are no outstanding + ** locks on the app, then revoke our ClassFactory to enable the + ** app to shut down. + */ + --lpAppClassFactory->m_cSvrLock; + OleDbgAssertSz (lpAppClassFactory->m_cSvrLock >= 0, + "AppClassFactory_LockServer(FALSE) called with cLock == 0" + ); + + if (lpAppClassFactory->m_cSvrLock == 0) { + OleDbgOutRefCnt2( + "AppClassFactory_LockServer: UNLOCKED\r\n", + lpAppClassFactory, lpAppClassFactory->m_cSvrLock); + } else { + OleDbgOutRefCnt3( + "AppClassFactory_LockServer: cLock--\r\n", + lpAppClassFactory, lpAppClassFactory->m_cSvrLock); + } + } +#endif // _DEBUG + /* OLE2NOTE: in order to hold the application alive we call + ** CoLockObjectExternal to add a strong reference to our app + ** object. this will keep the app alive when all other external + ** references release us. if the user issues File.Exit the + ** application will shut down in any case ignoring any + ** outstanding LockServer locks because CoDisconnectObject is + ** called in OleApp_CloseAllDocsAndExitCommand. this will + ** forceably break any existing strong reference counts + ** including counts that we add ourselves by calling + ** CoLockObjectExternal and guarantee that the App object gets + ** its final release (ie. cRefs goes to 0). + */ + hrErr = OleApp_Lock(lpOleApp, fLock, TRUE /* fLastUnlockReleases */); + + OLEDBG_END2 + return hrErr; +} |