319 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			319 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /***************************************************************************
 | |
|  * MAINENTRY.CPP
 | |
|  *
 | |
|  * Main DLL Entry and Required COM Entry Points.
 | |
|  *
 | |
|  *  Copyright ©1999-2004; Microsoft Corporation. All rights reserved.
 | |
|  *  Written by Microsoft Developer Support Office Integration (PSS DSOI)
 | |
|  * 
 | |
|  *  This code is provided via KB 311765 as a sample. It is not a formal
 | |
|  *  product and has not been tested with all containers or servers. Use it
 | |
|  *  for educational purposes only. See the EULA.TXT file included in the
 | |
|  *  KB download for full terms of use and restrictions.
 | |
|  *
 | |
|  *  THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 | |
|  *  EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 | |
|  *  WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 | |
|  *
 | |
|  ***************************************************************************/
 | |
| #define INITGUID // Init the GUIDS for the control...
 | |
| #include "dsoframer.h"
 | |
| 
 | |
| HINSTANCE        v_hModule        = NULL;   // DLL module handle
 | |
| HANDLE           v_hPrivateHeap   = NULL;   // Private Memory Heap
 | |
| ULONG            v_cLocks         = 0;      // Count of server locks
 | |
| HICON            v_icoOffDocIcon  = NULL;   // Small office icon (for caption bar)
 | |
| BOOL             v_fUnicodeAPI    = FALSE;  // Flag to determine if we should us Unicode API
 | |
| BOOL             v_fWindows2KPlus = FALSE;
 | |
| CRITICAL_SECTION v_csecThreadSynch;
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////
 | |
| // DllMain -- OCX Main Entry
 | |
| //
 | |
| //
 | |
| extern "C" BOOL APIENTRY DllMain(HINSTANCE hDllHandle, DWORD dwReason, LPVOID /*lpReserved*/)
 | |
| {
 | |
| 	switch (dwReason)
 | |
| 	{
 | |
| 	case DLL_PROCESS_ATTACH:
 | |
| 		v_hModule = hDllHandle;
 | |
|         v_hPrivateHeap = HeapCreate(0, 0x1000, 0);
 | |
| 		v_icoOffDocIcon = (HICON)LoadImage(hDllHandle, MAKEINTRESOURCE(IDI_SMALLOFFDOC), IMAGE_ICON, 16, 16, 0);
 | |
| 		{
 | |
| 			DWORD dwVersion = GetVersion();
 | |
| 			v_fUnicodeAPI = ((dwVersion & 0x80000000) == 0);
 | |
| 			v_fWindows2KPlus = ((v_fUnicodeAPI) && (LOBYTE(LOWORD(dwVersion)) > 4));
 | |
| 		}
 | |
| 		InitializeCriticalSection(&v_csecThreadSynch);
 | |
| 		DisableThreadLibraryCalls(hDllHandle);
 | |
| 		break;
 | |
| 
 | |
| 	case DLL_PROCESS_DETACH:
 | |
| 		if (v_icoOffDocIcon) DeleteObject(v_icoOffDocIcon);
 | |
|         if (v_hPrivateHeap) HeapDestroy(v_hPrivateHeap);
 | |
|         DeleteCriticalSection(&v_csecThreadSynch);
 | |
| 		break;
 | |
| 	}
 | |
| 	return TRUE;
 | |
| }
 | |
| 
 | |
| #ifdef DSO_MIN_CRT_STARTUP
 | |
| extern "C" BOOL APIENTRY _DllMainCRTStartup(HINSTANCE hDllHandle, DWORD dwReason, LPVOID lpReserved)
 | |
| {return DllMain(hDllHandle, dwReason, lpReserved);}
 | |
| #endif
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////
 | |
| // Standard COM DLL Entry Points
 | |
| //
 | |
| //
 | |
| ////////////////////////////////////////////////////////////////////////
 | |
| // DllCanUnloadNow
 | |
| //
 | |
| //
 | |
| STDAPI DllCanUnloadNow()
 | |
| {
 | |
| 	return ((v_cLocks == 0) ? S_OK : S_FALSE);
 | |
| }
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////
 | |
| // DllGetClassObject
 | |
| //
 | |
| //  Returns IClassFactory instance for FramerControl. We only support
 | |
| //  this one object for creation.
 | |
| //
 | |
| STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
 | |
| {
 | |
| 	HRESULT hr;
 | |
| 	CDsoFramerClassFactory* pcf;
 | |
| 
 | |
| 	CHECK_NULL_RETURN(ppv, E_POINTER);
 | |
| 	*ppv = NULL;
 | |
| 
 | |
|  // The only component we can create is the BinderControl...
 | |
| 	if (rclsid != CLSID_FramerControl)
 | |
| 		return CLASS_E_CLASSNOTAVAILABLE;
 | |
| 
 | |
|  // Create the needed class factory...
 | |
| 	pcf = new CDsoFramerClassFactory();
 | |
| 	CHECK_NULL_RETURN(pcf, E_OUTOFMEMORY);
 | |
| 
 | |
|  // Get requested interface.
 | |
| 	if (FAILED(hr = pcf->QueryInterface(riid, ppv)))
 | |
| 	{
 | |
| 		*ppv = NULL; delete pcf;
 | |
| 	}
 | |
| 	else InterlockedIncrement((LPLONG)&v_cLocks);
 | |
| 
 | |
| 	return hr;
 | |
| }
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////
 | |
| // DllRegisterServer
 | |
| //
 | |
| //  Registration of the OCX.
 | |
| //
 | |
| STDAPI DllRegisterServer()
 | |
| {
 | |
|     HRESULT hr = S_OK;
 | |
|     HKEY    hk, hk2;
 | |
|     DWORD   dwret;
 | |
|     CHAR    szbuffer[256];
 | |
| 	LPWSTR  pwszModule;
 | |
|     ITypeInfo* pti;
 | |
|     
 | |
|  // If we can't find the path to the DLL, we can't register...
 | |
| 	if (!FGetModuleFileName(v_hModule, &pwszModule))
 | |
| 		return E_FAIL;
 | |
| 
 | |
|  // Setup the CLSID. This is the most important. If there is a critical failure,
 | |
|  // we will set HR = GetLastError and return...
 | |
|     if ((dwret = RegCreateKeyEx(HKEY_CLASSES_ROOT, 
 | |
| 		"CLSID\\"DSOFRAMERCTL_CLSIDSTR, 0, NULL, 0, KEY_WRITE, NULL, &hk, NULL)) != ERROR_SUCCESS)
 | |
| 	{
 | |
| 		DsoMemFree(pwszModule);
 | |
|         return HRESULT_FROM_WIN32(dwret);
 | |
| 	}
 | |
| 
 | |
|     lstrcpy(szbuffer, DSOFRAMERCTL_SHORTNAME);
 | |
|     RegSetValueEx(hk, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer));
 | |
| 
 | |
|  // Setup the InprocServer32 key...
 | |
|     dwret = RegCreateKeyEx(hk, "InprocServer32", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL);
 | |
|     if (dwret == ERROR_SUCCESS)
 | |
|     {
 | |
|         lstrcpy(szbuffer, "Apartment");
 | |
|         RegSetValueEx(hk2, "ThreadingModel", 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer));
 | |
|         
 | |
| 	 // We call a wrapper function for this setting since the path should be
 | |
| 	 // stored in Unicode to handle non-ANSI file path names on some systems.
 | |
| 	 // This wrapper will convert the path to ANSI if we are running on Win9x.
 | |
| 	 // The rest of the Reg calls should be OK in ANSI since they do not
 | |
| 	 // contain non-ANSI/Unicode-specific characters...
 | |
| 		if (!FSetRegKeyValue(hk2, pwszModule))
 | |
|             hr = E_ACCESSDENIED;
 | |
| 
 | |
|         RegCloseKey(hk2);
 | |
| 
 | |
|         dwret = RegCreateKeyEx(hk, "ProgID", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL);
 | |
|         if (dwret == ERROR_SUCCESS)
 | |
|         {
 | |
|             lstrcpy(szbuffer, DSOFRAMERCTL_PROGID);
 | |
|             RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer));
 | |
|             RegCloseKey(hk2);
 | |
|         }
 | |
| 
 | |
|     }
 | |
|     else hr = HRESULT_FROM_WIN32(dwret);
 | |
| 
 | |
| 	if (SUCCEEDED(hr))
 | |
| 	{
 | |
| 		dwret = RegCreateKeyEx(hk, "Control", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL);
 | |
| 		if (dwret == ERROR_SUCCESS)
 | |
| 		{
 | |
| 			RegCloseKey(hk2);
 | |
| 		}
 | |
| 		else hr = HRESULT_FROM_WIN32(dwret);
 | |
| 	}
 | |
| 
 | |
| 
 | |
|  // If we succeeded so far, andle the remaining (non-critical) reg keys...
 | |
| 	if (SUCCEEDED(hr))
 | |
| 	{
 | |
| 		dwret = RegCreateKeyEx(hk, "ToolboxBitmap32", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL);
 | |
| 		if (dwret == ERROR_SUCCESS)
 | |
| 		{
 | |
| 			LPWSTR pwszT = DsoCopyStringCat(pwszModule, L",102");
 | |
| 			if (pwszT)
 | |
| 			{
 | |
| 				FSetRegKeyValue(hk2, pwszT);
 | |
| 				DsoMemFree(pwszT);
 | |
| 			}
 | |
| 			RegCloseKey(hk2);
 | |
| 		}
 | |
| 
 | |
| 		dwret = RegCreateKeyEx(hk, "TypeLib", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL);
 | |
| 		if (dwret == ERROR_SUCCESS)
 | |
| 		{
 | |
| 			lstrcpy(szbuffer, DSOFRAMERCTL_TLIBSTR);
 | |
| 			RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer));
 | |
| 			RegCloseKey(hk2);
 | |
| 		}
 | |
| 
 | |
| 		dwret = RegCreateKeyEx(hk, "Version", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL);
 | |
| 		if (dwret == ERROR_SUCCESS)
 | |
| 		{
 | |
| 			lstrcpy(szbuffer, DSOFRAMERCTL_VERSIONSTR);
 | |
| 			RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer));
 | |
| 			RegCloseKey(hk2);
 | |
| 		}
 | |
| 
 | |
| 		dwret = RegCreateKeyEx(hk, "MiscStatus", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL);
 | |
| 		if (dwret == ERROR_SUCCESS)
 | |
| 		{
 | |
| 			lstrcpy(szbuffer, "131473");
 | |
| 			RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer));
 | |
| 			RegCloseKey(hk2);
 | |
| 		}
 | |
| 
 | |
| 		dwret = RegCreateKeyEx(hk, "DataFormats\\GetSet\\0", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL);
 | |
| 		if (dwret == ERROR_SUCCESS)
 | |
| 		{
 | |
| 			lstrcpy(szbuffer, "3,1,32,1");
 | |
| 			RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer));
 | |
| 			RegCloseKey(hk2);
 | |
| 		}
 | |
|     }
 | |
| 
 | |
|     RegCloseKey(hk);
 | |
| 	DsoMemFree(pwszModule);
 | |
| 
 | |
|  // This should catch any critical failures during setup of CLSID...
 | |
| 	RETURN_ON_FAILURE(hr);
 | |
| 
 | |
|  // Setup the ProgID (non-critical)...
 | |
|     if (RegCreateKeyEx(HKEY_CLASSES_ROOT, DSOFRAMERCTL_PROGID, 0,
 | |
|             NULL, 0, KEY_WRITE, NULL, &hk, NULL) == ERROR_SUCCESS)
 | |
|     {
 | |
|         lstrcpy(szbuffer, DSOFRAMERCTL_FULLNAME);
 | |
|         RegSetValueEx(hk, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer));
 | |
| 
 | |
|         if (RegCreateKeyEx(hk, "CLSID", 0,
 | |
|                 NULL, 0, KEY_WRITE, NULL, &hk2, NULL) == ERROR_SUCCESS)
 | |
|         {
 | |
|             lstrcpy(szbuffer, DSOFRAMERCTL_CLSIDSTR);
 | |
|             RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer));
 | |
|             RegCloseKey(hk2);
 | |
|         }
 | |
|         RegCloseKey(hk);
 | |
|     }
 | |
| 
 | |
|  // Load the type info (this should register the lib once)...
 | |
|     hr = DsoGetTypeInfoEx(LIBID_DSOFramer, 0,
 | |
| 		DSOFRAMERCTL_VERSION_MAJOR, DSOFRAMERCTL_VERSION_MINOR, v_hModule, CLSID_FramerControl, &pti);
 | |
|     if (SUCCEEDED(hr)) pti->Release();
 | |
| 
 | |
| 	return hr;
 | |
| }
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////
 | |
| // RegRecursiveDeleteKey
 | |
| //
 | |
| //  Helper function called by DllUnregisterServer for nested key removal.
 | |
| //
 | |
| static HRESULT RegRecursiveDeleteKey(HKEY hkParent, LPCSTR pszSubKey)
 | |
| {
 | |
|     HRESULT hr = S_OK;
 | |
|     HKEY hk;
 | |
|     DWORD dwret, dwsize;
 | |
| 	FILETIME time ;
 | |
|     CHAR szbuffer[512];
 | |
| 
 | |
|     dwret = RegOpenKeyEx(hkParent, pszSubKey, 0, KEY_ALL_ACCESS, &hk);
 | |
| 	if (dwret != ERROR_SUCCESS)
 | |
| 		return HRESULT_FROM_WIN32(dwret);
 | |
| 
 | |
|  // Enumerate all of the decendents of this child...
 | |
| 	dwsize = 510 ;
 | |
| 	while (RegEnumKeyEx(hk, 0, szbuffer, &dwsize, NULL, NULL, NULL, &time) == ERROR_SUCCESS)
 | |
| 	{
 | |
|       // If there are any sub-folders, delete them first (to make NT happy)...
 | |
| 		hr = RegRecursiveDeleteKey(hk, szbuffer);
 | |
| 		if (FAILED(hr)) break;
 | |
| 		dwsize = 510;
 | |
| 	}
 | |
| 
 | |
|  // Close the child...
 | |
| 	RegCloseKey(hk);
 | |
| 
 | |
| 	RETURN_ON_FAILURE(hr);
 | |
| 
 | |
|  // Delete this child.
 | |
|     dwret = RegDeleteKey(hkParent, pszSubKey);
 | |
|     if (dwret != ERROR_SUCCESS)
 | |
|         hr = HRESULT_FROM_WIN32(dwret);
 | |
| 
 | |
| 	return hr;
 | |
| }
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////
 | |
| // DllUnregisterServer
 | |
| //
 | |
| //  Removal code for the OCX.
 | |
| //
 | |
| STDAPI DllUnregisterServer()
 | |
| {
 | |
|     HRESULT hr;
 | |
|     hr = RegRecursiveDeleteKey(HKEY_CLASSES_ROOT, "CLSID\\"DSOFRAMERCTL_CLSIDSTR);
 | |
|     if (SUCCEEDED(hr))
 | |
|     {
 | |
|         RegRecursiveDeleteKey(HKEY_CLASSES_ROOT, DSOFRAMERCTL_PROGID);
 | |
|         RegRecursiveDeleteKey(HKEY_CLASSES_ROOT, "TypeLib\\"DSOFRAMERCTL_TLIBSTR);
 | |
|     }
 | |
| 
 | |
|   // This means the key does not exist (i.e., the DLL 
 | |
|   // was alreay unregistered, so return OK)...
 | |
|     if (hr == 0x80070002) hr = S_OK;
 | |
| 
 | |
| 	return hr;
 | |
| }
 | 
