home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- Copyright (c) 1996-1999 Microsoft Corporation
-
- Module Name:
-
- dllstub.cpp
-
- Abstract:
-
- generic Java/COM DLL stub.
-
- --*/
-
-
- #include <string.h>
-
- #pragma intrinsic(memcmp)
-
- #pragma warning(disable:4514) // "unreferenced inline function" warning
-
- #pragma warning(disable:4201) // "nameless struct/union" warning
- #include <windows.h>
- #pragma warning(default:4201) // "nameless struct/union" warning
-
- #include "jpcommon.h"
- #include "jpsplit.h"
- #include "util.h"
-
- #include <initguid.h>
- #include "javaax.h"
-
-
- //----------------------------------------------------------------
- // Constants
- //----------------------------------------------------------------
-
- #define BUFSIZE 512 // A one-size fits all buffer size...
-
- // # chars in guid (including null terminator.)
- #define GUIDSTR_MAX (1+ 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1)
-
- // General strings that are useful.
- const CHAR achCLSID[] = "CLSID";
- const CHAR achProgID[] = "ProgID";
- const CHAR achInprocServer32[] = "InprocServer32";
- const CHAR achControl[] = "Control";
- const CHAR achJavaClass[] = "JavaClass";
- const CHAR achCodeBase[] = "CodeBase";
- const CHAR achThreadingModel[] = "ThreadingModel";
- const CHAR achBoth[] = "Both";
- const CHAR achApartment[] = "Apartment";
- const CHAR achFree[] = "Free";
- const CHAR achNeutral[] = "Neutral";
- CHAR g_szMSJAVAPath[_MAX_PATH];
-
-
- // {BE0975F0-BBDD-11cf-97DF-00AA001F73C1}
- const GUID TYPEID_JavaClasses =
- { 0xbe0975f0, 0xbbdd, 0x11cf, { 0x97, 0xdf, 0x0, 0xaa, 0x0, 0x1f, 0x73, 0xc1 } };
-
- //----------------------------------------------------------------
- // Types
- //----------------------------------------------------------------
-
- #if defined(_WIN64)
- typedef __int64 LONG_PTR, *PLONG_PTR;
- typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
- #else
- typedef long LONG_PTR, *PLONG_PTR;
- typedef unsigned long ULONG_PTR, *PULONG_PTR;
- #endif
-
-
- class MyClassFactory : public IClassFactory
- {
- public:
- // Allocation/free
- void * operator new(size_t cb)
- { return HeapAlloc(GetProcessHeap(), 0, cb); }
- void operator delete(void * pv)
- { HeapFree(GetProcessHeap(), 0, pv); }
- __declspec(nothrow) MyClassFactory()
- {}
-
- // IUnknown methods
- virtual STDMETHODIMP QueryInterface( REFIID riid, LPVOID* ppv );
- virtual STDMETHODIMP_(ULONG) AddRef( void );
- virtual STDMETHODIMP_(ULONG) Release( void );
- // IClassFactory methods
- virtual STDMETHODIMP CreateInstance( IUnknown* pUnkOuter, REFIID riid,
- LPVOID* ppvObject );
- virtual STDMETHODIMP LockServer( BOOL fLock );
- };
-
-
- //----------------------------------------------------------------
- // Global Variables
- //----------------------------------------------------------------
-
- BOOL g_fInitialized = FALSE;
- CRITICAL_SECTION g_CriticalSection;
- HINSTANCE g_hModuleMine = NULL;
- char g_szFileName[BUFSIZE];
- BOOL g_fTypeLibError = FALSE;
- HCRIDATA g_hCRIData = NULL;
- ULONG g_dwUseCount = 0;
- ULONG g_dwLockCount = 0;
- MyClassFactory *g_pMyClassFactory;
- IJavaComModuleManager *g_pModuleManager = NULL;
-
-
- //----------------------------------------------------------------
- // We don't link with CRT for size reasons--must define this.
- //----------------------------------------------------------------
- int
- __cdecl
- _purecall()
- {
- DebugBreak();
- return 0;
- }
-
- //----------------------------------------------------------------
- // InitializeDll()
- //----------------------------------------------------------------
- HRESULT
- InitializeDll( void )
- {
- // Rarely, several threads may attempt to call this routine simultaneously
-
- HRESULT hr = NOERROR;
-
- EnterCriticalSection( &g_CriticalSection );
-
- if ( !g_fInitialized ) {
-
- g_pMyClassFactory = new MyClassFactory();
- if (!g_pMyClassFactory)
- hr = E_OUTOFMEMORY;
-
- if (SUCCEEDED(hr) && g_pModuleManager == NULL) {
- hr = CoCreateInstance(CLSID_StdJavaComModuleManager, NULL,
- CLSCTX_INPROC_SERVER, IID_IJavaComModuleManager, (LPVOID *)
- &g_pModuleManager);
- }
-
- if (SUCCEEDED(hr))
- g_fInitialized = TRUE;
- }
-
- LeaveCriticalSection( &g_CriticalSection );
- return hr;
- }
-
- //----------------------------------------------------------------
- // LoadCRIData()
- //----------------------------------------------------------------
- void
- LoadCRIData( void )
- {
- EnterCriticalSection( &g_CriticalSection );
-
- g_hCRIData = CRIOpenData( g_hModuleMine, JEX_DEFAULT_CRI_RESOURCE_ID );
-
- LeaveCriticalSection( &g_CriticalSection );
-
- }
-
- //----------------------------------------------------------------
- // GetVMPath() - get path to VM DLL.
- //----------------------------------------------------------------
- void
- GetVMPath( void )
- {
- BOOL fGotIt = FALSE;
- LONG cb = sizeof( g_szMSJAVAPath );
- LONG nResult;
-
- nResult = RegQueryValue( HKEY_CLASSES_ROOT,
- "CLSID\\{3EFB1800-C2A1-11CF-960C-0080C7C2BA87}\\InprocServer32",
- g_szMSJAVAPath, &cb );
-
- if( ERROR_SUCCESS == nResult ) {
- if( GetFileAttributes( g_szMSJAVAPath ) != 0xFFFFFFFF )
- fGotIt = TRUE;
- }
-
- if( !fGotIt )
- lstrcpy( g_szMSJAVAPath, "msjava.dll" );
- }
-
-
- //----------------------------------------------------------------
- // MyDeleteKey() - delete a key and subkeys.
- //----------------------------------------------------------------
- void
- MyDeleteKey(
- HKEY hKey,
- const char *pszName )
- {
- HKEY hKey2;
- char szSubkey[BUFSIZE];
- DWORD dwLen;
- LONG nResult;
-
- nResult = RegOpenKeyEx( hKey, pszName, 0, KEY_ALL_ACCESS, &hKey2 );
- if ( ERROR_SUCCESS != nResult )
- return;
-
- for (;;) {
- dwLen = BUFSIZE;
- nResult = RegEnumKeyEx( hKey2, 0, szSubkey, &dwLen, NULL, NULL,
- NULL, NULL );
- if ( ERROR_SUCCESS != nResult )
- break;
-
- MyDeleteKey( hKey2, szSubkey );
- }
-
- RegCloseKey( hKey2 );
-
- RegDeleteKey( hKey, pszName );
- }
-
-
- /*
- * Register the given Java class in the registry by adding the correct
- * registry keys.
- */
- BOOL
- RegisterOneClass(
- LPCSTR szJavaClass, // must be in dotted form
- LPCSTR szClsid,
- LPCSTR szProgID,
- LPCSTR szDesc,
- LPCSTR szTypeLib,
- WORD verMajor,
- WORD verMinor,
- LPCSTR szServer,
- DWORD dwFlags )
- {
- HKEY hKey = NULL;
- HKEY hKey2 = NULL;
- HKEY hKey3 = NULL;
- HKEY hKey4 = NULL;
- DWORD result;
- BOOL fRet = FALSE;
- LPCSTR pcszThreadingModelValue;
-
- // If we fail in the middle, the state of the registry entries
- // is indeterminate (as per OLE specs).
-
- // HKEY_CLASSES_ROOT\{progid} = {description}
- result = RegCreateKey(HKEY_CLASSES_ROOT, szProgID, &hKey);
- if (result != ERROR_SUCCESS) goto lExit;
- result = RegSetValue(hKey, NULL, REG_SZ, szDesc, lstrlen(szDesc)+1);
- if (result != ERROR_SUCCESS) goto lExit;
-
- // HKEY_CLASSES_ROOT\{progid}\CLSID = {clsid}
- result = RegCreateKey(hKey, achCLSID, &hKey2);
- if (result != ERROR_SUCCESS) goto lExit;
- result = RegSetValue(hKey2, NULL, REG_SZ, szClsid, GUIDSTR_MAX);
- if (result != ERROR_SUCCESS) goto lExit;
-
- RegCloseKey(hKey);
- RegCloseKey(hKey2);
- hKey = NULL;
- hKey2 = NULL;
-
- // Create HKEY_CLASSES_ROOT\CLSID
- result = RegCreateKey(HKEY_CLASSES_ROOT, achCLSID, &hKey);
- if (result != ERROR_SUCCESS) goto lExit;
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid} = {description}
- // Remove the key and all subkeys first...
- MyDeleteKey(hKey, szClsid);
- result = RegCreateKey(hKey, szClsid, &hKey2);
- if (result != ERROR_SUCCESS) goto lExit;
- result = RegSetValue(hKey2, NULL, REG_SZ, szDesc, lstrlen(szDesc)+1);
- if (result != ERROR_SUCCESS) goto lExit;
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\InprocServer32 = {server}
- result = RegCreateKey(hKey2, achInprocServer32, &hKey3);
- if (result != ERROR_SUCCESS) goto lExit;
- result = RegSetValue(hKey3, NULL, REG_SZ, szServer, lstrlen(szServer)+1);
- if (result != ERROR_SUCCESS) goto lExit;
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\InprocServer32\ThreadingModel =
- // {Both,Free,Apartment,Neutral}
- if( dwFlags & DLLREG_TM_APARTMENT ) {
- pcszThreadingModelValue = (LPCSTR)achApartment;
- } else if( dwFlags & DLLREG_TM_FREE ) {
- pcszThreadingModelValue = (LPCSTR)achFree;
- } else if( dwFlags & DLLREG_TM_BOTH ) {
- pcszThreadingModelValue = (LPCSTR)achBoth;
- } else if( dwFlags & DLLREG_TM_NEUTRAL ) {
- pcszThreadingModelValue = (LPCSTR)achNeutral;
- } else if( dwFlags & DLLREG_CONTROL ) {
- // default ThreadingModel for controls is "Apartment".
- pcszThreadingModelValue = (LPCSTR)achApartment;
- } else {
- // default ThreadingModel for non-controls is "Both".
- pcszThreadingModelValue = (LPCSTR)achBoth;
- }
-
- result = RegSetValueEx(hKey3, achThreadingModel, 0, REG_SZ,
- (BYTE*)pcszThreadingModelValue, lstrlen(pcszThreadingModelValue)+1);
- if (result != ERROR_SUCCESS) goto lExit;
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\InprocServer32\JavaClass = {classname}
- result = RegSetValueEx(hKey3, achJavaClass, 0, REG_SZ, (BYTE*)szJavaClass,
- lstrlen(szJavaClass)+1);
- if (result != ERROR_SUCCESS) goto lExit;
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\InprocServer32\CodeBase -- not used for DLL
-
- RegCloseKey(hKey3);
- hKey3 = NULL;
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\progid = {progid}
- result = RegCreateKey(hKey2, achProgID, &hKey3);
- if (result != ERROR_SUCCESS) goto lExit;
- result = RegSetValue(hKey3, NULL, REG_SZ, szProgID, lstrlen(szProgID)+1);
- if (result != ERROR_SUCCESS) goto lExit;
- RegCloseKey(hKey3);
- hKey3 = NULL;
-
- if( szTypeLib != NULL ) {
- char szVersion[10];
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\TypeLib = {typelib guid}
- result = RegCreateKey(hKey2, "TypeLib", &hKey3);
- if (result != ERROR_SUCCESS) goto lExit;
- result = RegSetValue(hKey3, NULL, REG_SZ, szTypeLib, lstrlen(szTypeLib) + 1);
- if (result != ERROR_SUCCESS) goto lExit;
- RegCloseKey( hKey3 );
- hKey3 = NULL;
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\Version = {major version}.{minor version}
- wsprintf(szVersion, "%u.%u", verMajor, verMinor);
- result = RegCreateKey(hKey2, "Version", &hKey3);
- if (result != ERROR_SUCCESS) goto lExit;
- result = RegSetValue(hKey3, NULL, REG_SZ, szVersion, lstrlen(szVersion) + 1);
- if (result != ERROR_SUCCESS) goto lExit;
- RegCloseKey( hKey3 );
- hKey3 = NULL;
- }
-
- // Register as an OLE control if specified.
- if( dwFlags & DLLREG_CONTROL ) {
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\Control
- result = RegCreateKey(hKey2, achControl, &hKey3);
- if (result != ERROR_SUCCESS) goto lExit;
-
- // just create the key, nothing else with "Control"
- RegCloseKey( hKey3 );
- hKey3 = NULL;
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\ToolboxBitmap32 = {server},1
- char szBitmapPath[MAX_PATH*2];
-
- GetVMPath();
-
- lstrcpyn( szBitmapPath, g_szMSJAVAPath, (ARRAY_ELEMENTS( szBitmapPath ) - 3) );
- lstrcat(szBitmapPath, ",1");
- result = RegCreateKey(hKey2, "ToolboxBitmap32", &hKey3);
- if (result != ERROR_SUCCESS) goto lExit;
- result = RegSetValue(hKey3, NULL, REG_SZ, szBitmapPath, lstrlen(szBitmapPath)+1);
- if (result != ERROR_SUCCESS) goto lExit;
- RegCloseKey( hKey3 );
- hKey3 = NULL;
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\MiscStatus\1 = {misc status bits}
- char szMiscStatus[16];
- wsprintf(szMiscStatus, "%d", OLEMISC_SETCLIENTSITEFIRST |
- OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_RECOMPOSEONRESIZE |
- OLEMISC_INSIDEOUT );
-
- result = RegCreateKey(hKey2, "MiscStatus\\1", &hKey3);
- if (result != ERROR_SUCCESS) goto lExit;
- result = RegSetValue(hKey3, NULL, REG_SZ, szMiscStatus, lstrlen(szMiscStatus)+1);
- if (result != ERROR_SUCCESS) goto lExit;
- RegCloseKey( hKey3 );
- hKey3 = NULL;
- }
-
- // HKEY_CLASSES_ROOT\CLSID\{clsid}\Implemented Categories\{TYPEID_JavaClasses}
- // Register as a Java Class. Equivalent of
- // rgcatid[0] = TYPEID_JavaClasses;
- // ICatRegister::RegisterClassImplCategories(clsid, 1, rgcatid);
- CHAR szCatid[GUIDSTR_MAX];
-
- GUID2StringA(TYPEID_JavaClasses, szCatid);
-
- result = RegCreateKey(hKey2, "Implemented Categories", &hKey3);
- if (result != ERROR_SUCCESS) goto lExit;
- result = RegCreateKey(hKey3, szCatid, &hKey4);
- if (result != ERROR_SUCCESS) goto lExit;
- RegCloseKey(hKey4);
- RegCloseKey(hKey3);
- hKey3 = hKey4 = NULL;
-
- fRet = TRUE;
-
- lExit:
- if (hKey) {
- RegCloseKey(hKey);
- }
- if (hKey2) {
- RegCloseKey(hKey2);
- }
- if (hKey3) {
- RegCloseKey(hKey3);
- }
- if (hKey4) {
- RegCloseKey(hKey4);
- }
-
- return fRet;
- }
-
- //----------------------------------------------------------------
- // UnregisterOneClass()
- //----------------------------------------------------------------
- BOOL
- UnregisterOneClass(
- const char *pszClsid,
- const char *pszProgid )
- {
- char szName[BUFSIZE];
-
- lstrcpy( szName, achCLSID);
- lstrcat( szName, "\\" );
- lstrcat( szName, pszClsid );
- MyDeleteKey( HKEY_CLASSES_ROOT, szName );
-
- if ( pszProgid != NULL )
- MyDeleteKey( HKEY_CLASSES_ROOT, pszProgid );
-
- return TRUE;
- }
-
- /* InvokeUserRegHandler( wszClassName )
- *
- * Attempts to locate the registration method for the given class name. The
- * registration method is a method matching the following signature, including
- * the name:
- *
- * public static void onCOMRegister( boolean bRegister );
- *
- * If the method is found, it is invoked via RNI interfaces, and the bRegister
- * flag indicates whether the component is being registered or unregistered.
- * The flag is true if registering; false if unregistering. If the method is
- * not found, the function simply returns.
- */
- HRESULT
- InvokeUserRegHandler(
- IJavaComModuleManager *pModuleManager,
- REFCLSID clsid,
- BOOL fRegister )
- {
- return pModuleManager->RunRegistrationCode(clsid, g_hModuleMine,
- CLSCTX_INPROC_SERVER, fRegister);
- }
-
-
- //----------------------------------------------------------------
- // TypeLib
- //----------------------------------------------------------------
- BOOL
- CALLBACK
- MyRegisterTypeLib(
- HINSTANCE hModule,
- LPCTSTR lpszType,
- LPTSTR lpszName,
- LONG_PTR fRegister )
- {
- UNREFERENCED_PARAMETER( hModule );
- UNREFERENCED_PARAMETER( lpszType );
-
- CHAR szName[BUFSIZE];
- WCHAR wszName[BUFSIZE];
- ITypeLib *ptlb = NULL;
- TLIBATTR *pta = NULL;
- HRESULT hr;
-
- // Add typelib ID onto end of name.
- if( IS_INTRESOURCE( lpszName ) ) {
- if( (LONG_PTR) lpszName != 1 ) {
- wsprintf(szName, "%s\\%ld", g_szFileName, (long)(LONG_PTR)lpszName);
- } else {
- lstrcpyn( szName, g_szFileName, ARRAY_ELEMENTS( szName ) );
- }
- }
-
- MultiByteToWideChar(CP_ACP, 0, szName, -1, wszName, BUFSIZE );
-
- hr = LoadTypeLib( wszName, &ptlb );
- if ( hr != S_OK ) goto Error;
-
- if ( fRegister ) {
- hr = RegisterTypeLib( ptlb, wszName, NULL );
- } else {
- hr = ptlb->GetLibAttr( &pta );
- if (hr != S_OK ) goto Error;
-
- hr = UnRegisterTypeLib( pta->guid, pta->wMajorVerNum, pta->wMinorVerNum,
- pta->lcid, pta->syskind );
- }
-
- Error:
- if ( pta != NULL )
- ptlb->ReleaseTLibAttr( pta );
-
- if ( ptlb != NULL )
- ptlb->Release();
-
- if ( hr != S_OK ) {
- g_fTypeLibError = TRUE;
-
- // NB: we keep enumerating even after reg/unreg failure.
- }
-
- return TRUE;
- }
-
-
- //----------------------------------------------------------------
- // RegistrationCallback()
- //----------------------------------------------------------------
-
- typedef struct
- {
- BOOL fRegister;
- IJavaComModuleManager *pModuleManager;
- IUnknown **ppunkClassObjects;
- HRESULT hr;
- } ExtraEnumerationData;
-
-
- // NB: this callback does not use the hr field of ExtraEnumerationData.
- BOOL
- CALLBACK
- RegistrationCallback(
- DWORD iCRIEntry, // CRI entry index
- LPCWSTR pcwszClassName,
- LPCWSTR pcwszProgID, // may be NULL
- LPCWSTR pcwszDescription, // may be NULL
- DWORD dwFlags,
- REFGUID rguidCLSID,
- REFGUID rguidTypelib, // may be GUID_NULL, meaning no type library
- WORD wVerMajor, // typelib major version
- WORD wVerMinor, // typelib minor version
- void *pvExtra )
- {
- BOOL fRetVal;
- char pszClassName[2 * MAX_PATH];
- char pszProgID[2 * MAX_PATH];
- char pszDescription[2 * MAX_PATH];
- char szCLSID[GUIDSTR_MAX];
- char szTypelibGUIDBuffer[GUIDSTR_MAX];
- char *szTypelibGUID;
- HRESULT hr;
- ExtraEnumerationData *pExtra;
-
- szTypelibGUID = NULL;
- pExtra = (ExtraEnumerationData *)pvExtra;
-
- //
- // convert strings to MBCS
- //
-
- WideCharToMultiByte(CP_ACP, 0, pcwszClassName, -1, pszClassName,
- ARRAY_ELEMENTS(pszClassName), NULL, NULL);
-
- if (pcwszProgID)
- WideCharToMultiByte(CP_ACP, 0, pcwszProgID, -1, pszProgID,
- ARRAY_ELEMENTS(pszProgID), NULL, NULL);
- else
- pszProgID[0] = '\0';
-
- if (pcwszDescription)
- WideCharToMultiByte(CP_ACP, 0, pcwszDescription, -1, pszDescription,
- ARRAY_ELEMENTS(pszDescription), NULL, NULL);
- else
- pszDescription[0] = '\0';
-
- // ensure that class name is in dotted form.
- AnsiTranslateChars(pszClassName, '/', '.');
-
- // Convert GUIDs to ANSI string version.
- GUID2StringA(rguidCLSID, szCLSID);
-
- if (rguidTypelib != GUID_NULL) {
- GUID2StringA(rguidTypelib, szTypelibGUIDBuffer);
- szTypelibGUID = szTypelibGUIDBuffer;
- }
-
- // Register/Unregister
- if (pExtra->fRegister) {
- fRetVal = RegisterOneClass(pszClassName, szCLSID, pszProgID,
- pszDescription, szTypelibGUID, wVerMajor, wVerMinor,
- g_szFileName, dwFlags);
- } else {
- // load the class object before removing the registry settings.
- hr = pExtra->pModuleManager->GetClassObject(rguidCLSID,
- g_hModuleMine, CLSCTX_INPROC_SERVER, IID_IUnknown,
- (void**)&(pExtra->ppunkClassObjects[iCRIEntry]));
- // We ignore this HR and delete the reg keys anyway...
-
- fRetVal = UnregisterOneClass(szCLSID, pszProgID);
- }
-
- return fRetVal;
- }
-
- //----------------------------------------------------------------
- // UserRegHandlerCallback()
- //----------------------------------------------------------------
-
- #pragma warning(disable:4100) // "unreferenced formal parameter" warning
-
- BOOL
- CALLBACK
- UserRegHandlerCallback(
- DWORD iCRIEntry, // CRI entry index
- LPCWSTR pcwszClassName,
- LPCWSTR pcwszProgID, // may be NULL
- LPCWSTR pcwszDescription, // may be NULL
- DWORD dwFlags,
- REFGUID rguidCLSID,
- REFGUID rguidTypelib, // may be GUID_NULL, meaning no type library
- WORD wVerMajor, // typelib major version
- WORD wVerMinor, // typelib minor version
- void *pvExtra )
- {
- ExtraEnumerationData *pExtra;
-
- pExtra = (ExtraEnumerationData *)pvExtra;
-
- // if there is a user registration handler, invoke it.
- if (dwFlags & DLLREG_USERREG) {
- pExtra->hr = InvokeUserRegHandler(pExtra->pModuleManager, rguidCLSID,
- pExtra->fRegister);
- }
-
- return( SUCCEEDED( pExtra->hr ) );
- }
-
- #pragma warning(default:4100) // "unreferenced formal parameter" warning
-
- //----------------------------------------------------------------
- // FindCLSIDCallback()
- //----------------------------------------------------------------
-
- typedef struct
- {
- GUID guidCLSID;
- BOOL fFoundCLSID;
- } FindCLSIDCallbackExtra;
-
- #pragma warning(disable:4100) // "unreferenced formal parameter" warning
-
- BOOL
- CALLBACK
- FindCLSIDCallback(
- DWORD iCRIEntry, // CRI entry index
- LPCWSTR pcwszClassName,
- LPCWSTR pcwszProgID, // may be NULL
- LPCWSTR pcwszDescription, // may be NULL
- DWORD dwFlags,
- REFGUID rguidCLSID,
- REFGUID rguidTypelib, // may be GUID_NULL, meaning no type library
- WORD wVerMajor, // typelib major version
- WORD wVerMinor, // typelib minor version
- void *pvExtra )
- {
- BOOL fRetVal;
- FindCLSIDCallbackExtra *pExtra;
-
- fRetVal = TRUE;
- pExtra = (FindCLSIDCallbackExtra *)pvExtra;
-
- // if this CRI entry has a matching CLSID, stop enumerating.
- if( pExtra->guidCLSID == rguidCLSID )
- {
- pExtra->fFoundCLSID = TRUE;
- fRetVal = FALSE;
- }
-
- return fRetVal;
- }
-
- #pragma warning(default:4100) // "unreferenced formal parameter" warning
-
- //----------------------------------------------------------------
- // MyRegisterUnregister()
- //----------------------------------------------------------------
- HRESULT
- MyRegisterUnregister(
- BOOL fRegister )
- {
- ULONG iCRIEntry;
- BOOL fRes;
- HRESULT hr;
- HRESULT hrCoInit;
- ULONG cCRIEntries;
- ExtraEnumerationData extra;
-
- if ( 0 == GetModuleFileName( g_hModuleMine, g_szFileName, BUFSIZE ) )
- return E_UNEXPECTED;
-
- LoadCRIData();
- if ( g_hCRIData == NULL )
- return E_UNEXPECTED;
-
- cCRIEntries = CRIGetEntryCount(g_hCRIData);
- extra.pModuleManager = NULL;
- extra.ppunkClassObjects = NULL;
-
- // initialize COM and create an instance of StdJavaComModuleManager. we
- // don't want to call InitializeDll() here and use the global
- // StdJavaComModuleManager. that may cause us to fault in our
- // DLL_PROCESS_DETACH code, when we try to use a bogus
- // StdJavaComModuleManager (bogus because msjava.dll may be unloaded
- // before us).
- hrCoInit = CoInitialize( NULL );
- if( FAILED( hrCoInit ) &&
- (hrCoInit != RPC_E_CHANGED_MODE) ) {
- hr = hrCoInit;
- goto Error;
- }
-
- hr = CoCreateInstance( CLSID_StdJavaComModuleManager, NULL,
- CLSCTX_INPROC_SERVER, IID_IJavaComModuleManager,
- (LPVOID *)&(extra.pModuleManager) );
- if( FAILED( hr ) ) {
- goto Error;
- }
-
- // when performing unregistration, we have a problem- we wish to call
- // the user's onCOMRegister() method after we have removed all registry
- // entries. but, we actually ask the VM to call onCOMRegister() for us,
- // and the VM uses registry values to load the correct class. to get
- // around this, we force the VM to load registry info before we remove it
- // by asking for class objects for each class we'll be unregistering.
-
- // allocate space for an array of class objects.
- if (!fRegister) {
- // we explicitly use HeapAlloc() to ensure that we don't use
- // the CRT libraries.
- extra.ppunkClassObjects = (IUnknown**) HeapAlloc(GetProcessHeap(), 0,
- sizeof(IUnknown*) * cCRIEntries);
- if (!extra.ppunkClassObjects) {
- hr = E_OUTOFMEMORY;
- goto Error;
- }
-
- for (iCRIEntry = 0; iCRIEntry < cCRIEntries; iCRIEntry++ ) {
- extra.ppunkClassObjects[iCRIEntry] = NULL;
- }
- }
-
- // enumerate over the CRI data, registering or unregistering as necessary.
- // if unregistering, this will also fill the ppunkClassObjects field of
- // the extra data.
- extra.fRegister = fRegister;
- fRes = CRIEnumEntries(g_hCRIData, RegistrationCallback, &extra);
-
- if ( !fRes ) {
- hr = E_UNEXPECTED;
- goto Error;
- }
-
- // register type libraries.
- g_fTypeLibError = FALSE;
- EnumResourceNames(g_hModuleMine, "TYPELIB", MyRegisterTypeLib,
- (LONG_PTR)fRegister);
-
- if ( g_fTypeLibError ) {
- hr = E_UNEXPECTED;
- goto Error;
- }
-
- // Invoke the user registration handler for any classes that have one.
- extra.hr = S_OK;
- fRes = CRIEnumEntries(g_hCRIData, UserRegHandlerCallback, &extra);
- hr = extra.hr;
-
- if (FAILED(hr))
- goto Error;
-
- hr = S_OK;
-
- Error:
- // clean up the class object punks.
- if (extra.ppunkClassObjects) {
- for (iCRIEntry = 0; iCRIEntry < cCRIEntries; iCRIEntry++ ) {
- if (extra.ppunkClassObjects[iCRIEntry]) {
- extra.ppunkClassObjects[iCRIEntry]->Release();
- }
- }
- HeapFree(GetProcessHeap(), 0, extra.ppunkClassObjects);
- }
-
- if( extra.pModuleManager != NULL ) {
- extra.pModuleManager->Release();
- }
-
- if( SUCCEEDED( hrCoInit ) ) {
- CoUninitialize();
- }
-
- return hr;
- }
-
- /************************** class MyClassFactory *************************/
- HRESULT
- MyClassFactory::QueryInterface(
- REFIID iid,
- LPVOID *ppv )
- {
- if( ppv == NULL )
- return E_INVALIDARG;
-
- if( iid != IID_IUnknown &&
- iid != IID_IClassFactory ) {
-
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- *ppv = this;
- AddRef();
- return S_OK;
- }
-
- ULONG
- MyClassFactory::AddRef( void )
- {
- return ++g_dwUseCount;
- }
-
- ULONG
- MyClassFactory::Release( void )
- {
- return --g_dwUseCount;
- }
-
- HRESULT
- MyClassFactory::CreateInstance(
- IUnknown *pUnkOuter,
- REFIID iid,
- LPVOID *ppv )
- {
- UNREFERENCED_PARAMETER( pUnkOuter );
- UNREFERENCED_PARAMETER( iid );
-
- if( ppv == NULL )
- return E_INVALIDARG;
-
- *ppv = NULL;
- return E_UNEXPECTED;
- }
-
- HRESULT
- MyClassFactory::LockServer(
- BOOL fLock )
- {
- if( fLock )
- g_dwLockCount++;
- else
- g_dwLockCount--;
-
- return S_OK;
- }
-
- /****************************** Public Functions *****************************/
-
- //----------------------------------------------------------------
- // DllMain() - DLL entry point
- //----------------------------------------------------------------
- BOOL
- WINAPI
- DllMain(
- HINSTANCE hModule,
- ULONG ulReasonForCall,
- LPVOID lpReserved )
- {
- UNREFERENCED_PARAMETER( lpReserved );
-
- switch ( ulReasonForCall ) {
-
- case DLL_PROCESS_ATTACH:
- g_hModuleMine = hModule;
- InitializeCriticalSection(&g_CriticalSection);
- DisableThreadLibraryCalls(hModule);
- return TRUE;
-
- case DLL_PROCESS_DETACH:
- DeleteCriticalSection( &g_CriticalSection );
- if ( g_hCRIData != NULL ) {
- CRICloseData(g_hCRIData);
- g_hCRIData = NULL;
- }
-
- if (g_pModuleManager) {
- // Notify the module manager that we're unloading.
- g_pModuleManager->OnModuleUnload(g_hModuleMine);
-
- g_pModuleManager->Release();
- g_pModuleManager = NULL;
- }
-
- return TRUE;
-
- default:
- return TRUE;
- }
- }
-
- // Don't link in CRT startup code.
- extern "C"
- BOOL
- WINAPI
- _DllMainCRTStartup(
- HINSTANCE hDllHandle,
- DWORD dwReason,
- LPVOID lpReserved )
- {
- return DllMain(hDllHandle, dwReason, lpReserved);
- }
-
-
- //----------------------------------------------------------------
- // DllCanUnloadNow()
- //----------------------------------------------------------------
- extern "C"
- HRESULT
- __stdcall
- DllCanUnloadNow( void )
- {
- HRESULT hr;
-
- if ( !g_fInitialized ) {
- hr = InitializeDll();
- if (FAILED(hr))
- return hr;
- }
-
- if ( g_dwUseCount > 0 )
- return S_FALSE;
-
- if ( g_dwLockCount > 0 )
- return S_FALSE;
-
- if (g_pModuleManager)
- return g_pModuleManager->CanUnloadNow(g_hModuleMine);
-
- return S_OK;
- }
-
- //----------------------------------------------------------------
- // DllGetClassObject()
- //----------------------------------------------------------------
- extern "C"
- HRESULT
- __stdcall
- DllGetClassObject(
- REFCLSID rclsid,
- REFIID riid,
- LPVOID *ppv )
- {
- HRESULT hr;
- FindCLSIDCallbackExtra extra;
-
- if ( !g_fInitialized ) {
- hr = InitializeDll();
- if (FAILED(hr))
- return hr;
- }
-
- hr = g_pModuleManager->GetClassObject(rclsid, g_hModuleMine,
- CLSCTX_INPROC_SERVER, riid, ppv);
-
- if ( hr != CLASS_E_CLASSNOTAVAILABLE )
- return hr;
-
- // here we have a kludge. Some administrative tools attempt to get a class
- // object before the registration code has run, just to see if the DLL
- // implements a specific class. When called before we have
- // self-registered, JAVA returns CLASS_E_CLASSNOTAVAILABLE. If the class
- // is one that we would have registered, we return a reference to our own
- // class object here.
-
- LoadCRIData();
- if ( g_hCRIData == NULL )
- return CLASS_E_CLASSNOTAVAILABLE; // we don't have any info to look at
-
- // enumerate the CRI data, looking for an entry whose CLSID matches
- // that requested. the fFoundCLSID field of the extra data will be
- // set to TRUE if a matching entry is found.
- extra.guidCLSID = rclsid;
- extra.fFoundCLSID = FALSE;
- CRIEnumEntries(g_hCRIData, FindCLSIDCallback, &extra);
-
- if ( extra.fFoundCLSID ) {
- return g_pMyClassFactory->QueryInterface( riid, ppv );
- }
-
- return CLASS_E_CLASSNOTAVAILABLE; // class is not one that we will register
- }
-
- //----------------------------------------------------------------
- // DllRegisterServer()
- //----------------------------------------------------------------
- extern "C"
- HRESULT
- __stdcall
- DllRegisterServer( void )
- {
- return MyRegisterUnregister( TRUE );
- }
-
- //----------------------------------------------------------------
- // DllUnregisterServer()
- //----------------------------------------------------------------
- extern "C"
- HRESULT
- __stdcall
- DllUnregisterServer( void )
- {
- return MyRegisterUnregister( FALSE );
- }
-