⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dllmain.cpp

📁 基于Intellution开发包的开发的OPC服务器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DllMain.cpp
//
// This source file contains the DLL Mainline code for the 
// in-process OPC server.
//
//
//	(c) COPYRIGHT 1996-1998, INTELLUTION INC.
// ALL RIGHTS RESERVED
//
//
// Modification Log:
//	Vers	Date		By		Notes
//	----	--------	---		-----
//	1.0		08/26/97	jra		Created
//	1.3		03/10/98	jra		Modified to be wizard generated and driver specific.
//	7.13	02/29/00	jra		Added call to DeleteServerSlot() at the end of
//								DLL_PROCESS_DETACH section of DllMain()
//
//

#define WIN32_LEAN_AND_MEAN

#include "OpcStdAfx.h"

#include <afxconv.h>
#include <Process.h>
#include <objbase.h>
#include <initguid.h>

#include "OPCDrv.h"
#include "OPCDrvThread.h"


/////////////////////////////////////////////////////////////////////////////
// Local definitions
//
#define INITGUID
#define GUID_SIZE			128
#define	MAX_STRING_LENGTH	256
#define	BUFFER_SIZE			100


/////////////////////////////////////////////////////////////////////////////
// Define the unique classID that represents this server
//
// *** EVERY IMPLEMENTATION MUST USE A DIFFERENT GUID ***
//
// The following GUID was generated by the I/O server wizard specifically for
// this OPC server implementation. You do not need to modify or change it.
//
// {1951702F-AD76-11d1-B81A-0060971E5E37}
DEFINE_GUID(CLSID_COPCDrvServer, 
	0x6a202687, 0xa6f9, 0x4a69, 0x8a, 0x22, 0xa6, 0xff, 0x5b, 0x10, 0x79, 0x37);


////////////////////////////////////////////////////////////////
// Globals (Note there is a copy per instance of the server)
//
long		g_lObjectCount		= 0;	// Number of servers created
long		g_lLockCount		= 0;	// Standard COM Server lock count
FILETIME	g_ftStartTime;				// OPC specific server start time
HINSTANCE	g_hServerInstance	= 0;	// DLL instance (e.g. for LoadString)
IMalloc		*pIMalloc			= 0;	// Common memory allocator
HINSTANCE	g_hDllInst;					// Instance handle of the DLL.

TCHAR			g_tszAcronym[] = { "OPCHLL" };
static TCHAR	g_tszServerDesciption[100];
static TCHAR	g_tszIndepProgID[100];
static TCHAR	g_tszDepProgID[100];
static TCHAR	g_tszRegKey[100];
static TCHAR	g_tszMallocError[100];


////////////////////////////////////////////////////////////////
// Miscellaneous utility functions used within this module.
//
BOOL	SetRegKeyStringValue(LPTSTR pszKey, LPTSTR pszSubkey, LPTSTR pszValue);
BOOL	AddRegNamedStringValue(LPTSTR pszKey, LPTSTR pszSubkey, LPTSTR pszValueName,
						 LPTSTR pszValue);
BOOL	GetRegNamedStringValue(LPTSTR pszKey, LPTSTR pszSubkey, LPTSTR pszValueName,
						 LPTSTR pszValue);
STDAPI	A_StringFromGUID2(REFGUID guid, LPSTR pszGUID, int nNumChars);
HRESULT	UcToAnsi(LPWSTR pszUc, LPSTR pszAnsi, int nNumChars);
HRESULT	GetServerClassID(CLSID *pClassID);
void	BuildStrings(void);
BOOL	ServerCanUnloadNow(void);

void	SetRegistryDefaults(void);
BOOL	GetRegistryDefaults(void);


////////////////////////////////////////////////////////////////
// The following parameters are tunable from the system registry. 
// They will be read at startup. If changed, the server will 
// need to be shutdown and restarted. It would not be worth the
// performance hit to periodically read them to see if anything
// changed.
//
DWORD	g_dwWaitPeriod					= 25;	// 25ms
DWORD	g_dwServerThreadPriority		= 7;	// Normal class/Normal priority
BOOL	g_bAutoStart					= TRUE;	// Autostart 7x drivers
WORD	g_wStringLength					= 20;	// String length default
CString	g_strDefaultSignalConditioning	= "NONE",
		g_strDefaultHiEGU				= "65535.0",
		g_strDefaultLoEGU				= "0.0",
		g_strDefaultHardwareOptions		= "NONE",
		g_strDefaultGeneratedGroupName	= "Group";


////////////////////////////////////////////////////////////////
// DllMain()
//
// Main entry point for the DLL. When the server is loaded, we
// create a worked thread used to perform background updates of
// all the active item objects.
//
////////////////////////////////////////////////////////////////
BOOL WINAPI DllMain(HINSTANCE	hinstDLL, 
					DWORD		fdwReason, 
					LPVOID		lpvReserved)
{
	// Save the instance handle
	g_hDllInst = hinstDLL;

	if (fdwReason == DLL_PROCESS_ATTACH)
	{
		// Initialize the server map stuff.
		InitServerSlot();

		// Build the strings for this acronym
		BuildStrings();

		// Save the startup info
		g_hServerInstance = hinstDLL;
		CoFileTimeNow(&g_ftStartTime);

		// Register the application with Event Viewer
		RegisterEventService();

		// Get a pointer to the OLE IMalloc memory allocator function.
		// If this call fails, then we're done, so return FALSE.
		if (FAILED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))	// 'TASK' ok for DLL use
		{
			LogEventMessage(g_tszMallocError);
			return FALSE;
		}

		// Get some default info from the registry
		GetRegistryDefaults();
	}
	else if (fdwReason == DLL_PROCESS_DETACH)
	{
		// Free the reference to IMalloc
		pIMalloc->Release();

		// Deregister the application with Event Viewer
		DeRegisterEventService();

		// Perform any shutdown cleanup
		DeleteServerSlot();
	}

	return TRUE;
}


////////////////////////////////////////////////////////////////
// DllGetClassObject()
//
// This is the standard COM function for returning our class 
// factory to the caller.
//
////////////////////////////////////////////////////////////////
STDAPI DllGetClassObject(REFCLSID	rclsid, 
						 REFIID		riid, 
						 LPVOID		*ppv)
{
	if (rclsid == CLSID_COPCDrvServer) 
	{
		CImpIClassFactory* pCImpIClassFactory = new CImpIClassFactory(rclsid);
		if (NULL == pCImpIClassFactory)
		{
			return E_OUTOFMEMORY;
		}

		HRESULT hr = pCImpIClassFactory->QueryInterface(riid, ppv);
		if (FAILED(hr))
		{
			delete pCImpIClassFactory;
		}

		return hr;
	}

	return CLASS_E_CLASSNOTAVAILABLE;
}


////////////////////////////////////////////////////////////////
// DllCanUnloadNow()
// 
// This is the standard function that is called to determine 
// whether or not this DLL is in use.
//
////////////////////////////////////////////////////////////////
STDAPI DllCanUnloadNow(void)
{
	// If we have no objects and we are not locked
	// then we can be unloaded.
	if (ServerCanUnloadNow())
	{
		return S_OK;
	}
	return S_FALSE;
}


////////////////////////////////////////////////////////////////
// Function: DllRegisterServer
//
// Summary:	The standard exported function that can be called 
//			to command this DLL server to register itself in 
//			the system registry.
//
// Args:	void.
//
// Returns:	HRESULT
//			NOERROR if everything OK, E_UNEXPECTED if error
////////////////////////////////////////////////////////////////
STDAPI DllRegisterServer(void)
{
	HRESULT		hr = NOERROR;
	TCHAR		tszGUID[GUID_SIZE+10],
				tszCLSID[GUID_SIZE+10],
				tszAppID[GUID_SIZE+10],
				tszModulePath[MAX_PATH];


	// Obtain the path to this module's executable file for later use.
	GetModuleFileName(g_hDllInst, tszModulePath, sizeof(tszModulePath)/sizeof(TCHAR));

	// Create some base key strings.
	A_StringFromGUID2(CLSID_COPCDrvServer, tszGUID, GUID_SIZE);
	
	lstrcpy(tszCLSID, TEXT("CLSID\\"));
	lstrcat(tszCLSID, tszGUID);
	
	lstrcpy(tszAppID, "AppID\\");
	lstrcat(tszAppID, tszGUID);


	// Create VersionDependantProgID keys.
	SetRegKeyStringValue(g_tszDepProgID, NULL, g_tszServerDesciption);
	SetRegKeyStringValue(g_tszDepProgID, TEXT("CLSID"), tszGUID);

	// Create VersionIndependentProgID keys.
	SetRegKeyStringValue(g_tszIndepProgID, NULL,
							g_tszServerDesciption);
	SetRegKeyStringValue(g_tszIndepProgID, TEXT("CurVer"),
							g_tszDepProgID);
	SetRegKeyStringValue(g_tszIndepProgID, TEXT("CLSID"),
							tszGUID);
	SetRegKeyStringValue(g_tszIndepProgID, TEXT("OPC"),
							NULL);
	SetRegKeyStringValue(g_tszIndepProgID, TEXT("OPC\\Vendor"),
							TEXT("Intellution, Inc."));

	// Create entries under CLSID.
	SetRegKeyStringValue(tszCLSID, NULL,
							g_tszServerDesciption);
	SetRegKeyStringValue(tszCLSID, TEXT("ProgID"),
							g_tszDepProgID);
	SetRegKeyStringValue(tszCLSID, TEXT("VersionIndependentProgID"),
							g_tszIndepProgID);
	SetRegKeyStringValue(tszCLSID, TEXT("NotInsertable"),
							NULL);
	SetRegKeyStringValue(tszCLSID, TEXT("InprocServer32"),
							tszModulePath);

	// Add values under CLSID
	AddRegNamedStringValue(tszCLSID, TEXT("InprocServer32"), 
							TEXT("ThreadingModel"), TEXT("Apartment"));
	AddRegNamedStringValue(tszCLSID, NULL, 
							TEXT("AppID"), tszGUID);

	// Create entries under AppID
	SetRegKeyStringValue(tszAppID, NULL,
							g_tszServerDesciption);

	// Create entries under AppID
	AddRegNamedStringValue(tszAppID, NULL, 
							TEXT("DllSurrogate"), TEXT(""));
	AddRegNamedStringValue(tszAppID, NULL, 
							TEXT("RunAs"), TEXT("Interactive User"));

	// Setup the user tunable parameters under HKEY_LOCAL_MACHINE
	SetRegistryDefaults();

	return hr;
}


////////////////////////////////////////////////////////////////
// DllUnregisterServer()
//
// Summary:	The standard exported function that can be called to 
//			command this DLL server to unregister itself from 
//			the system Registry.
//
// Args:	void.
//
// Returns:	HRESULT
//			NOERROR
////////////////////////////////////////////////////////////////
STDAPI DllUnregisterServer(void)
{
	HRESULT		hr = NOERROR;
	TCHAR		tszGUID[GUID_SIZE+10],
				tszCLSID[GUID_SIZE+10],
				tszAppID[GUID_SIZE+10],
				tszTemp[GUID_SIZE+10],
				tszUserEntries[GUID_SIZE+10];


	// Create some base key strings.
	A_StringFromGUID2(CLSID_COPCDrvServer, tszGUID, GUID_SIZE);
	
	lstrcpy(tszCLSID, TEXT("CLSID\\"));
	lstrcat(tszCLSID, tszGUID);

	lstrcpy(tszAppID, "AppID\\");
	lstrcat(tszAppID, tszGUID);

	lstrcpy(tszUserEntries, g_tszRegKey);

	// Delete VersionIndependentProgID keys.
	wsprintf(tszTemp, TEXT("%s\\OPC\\Vendor"), g_tszIndepProgID);
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\OPC"), g_tszIndepProgID);
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\CurVer"), g_tszIndepProgID);
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\CLSID"), g_tszIndepProgID);
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	RegDeleteKey(HKEY_CLASSES_ROOT, g_tszIndepProgID);

	// Delete VersionDependantProgID keys.
	wsprintf(tszTemp, TEXT("%s\\CLSID"), g_tszDepProgID);
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	RegDeleteKey(HKEY_CLASSES_ROOT, g_tszDepProgID);

	// Delete entries under CLSID.
	wsprintf(tszTemp, TEXT("%s\\%s"), tszCLSID, TEXT("ProgID"));
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\%s"), tszCLSID, TEXT("VersionIndependentProgID"));
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\%s"), tszCLSID, TEXT("NotInsertable"));
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\%s"), tszCLSID, TEXT("InprocServer32"));
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	RegDeleteKey(HKEY_CLASSES_ROOT, tszCLSID);

	// Delete the entries under AppID
	wsprintf(tszTemp, TEXT("%s\\%s"), tszAppID, TEXT("DllSurrogate"));
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\%s"), tszAppID, TEXT("RunAs"));
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\%s"), tszAppID, TEXT("AccessPermission"));
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\%s"), tszAppID, TEXT("LaunchPermission"));
	RegDeleteKey(HKEY_CLASSES_ROOT, tszTemp);
	RegDeleteKey(HKEY_CLASSES_ROOT, tszAppID);

	// Delete entries for the user tunable parameters
	wsprintf(tszTemp, TEXT("%s\\%s"), tszUserEntries, TEXT("ServerDefaults"));
	RegDeleteKey(HKEY_LOCAL_MACHINE, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\%s"), tszUserEntries, TEXT("GroupDefaults"));
	RegDeleteKey(HKEY_LOCAL_MACHINE, tszTemp);
	wsprintf(tszTemp, TEXT("%s\\%s"), tszUserEntries, TEXT("ItemDefaults"));
	RegDeleteKey(HKEY_LOCAL_MACHINE, tszTemp);
	RegDeleteKey(HKEY_LOCAL_MACHINE, tszUserEntries);

	return hr;
}

////////////////////////////////////////////////////////////////
// ServerCanUnloadNow()
//
// Summary:	Detemines if the DLL can be unloaded
//
// Returns:  BOOL
//           TRUE if not locks or objects; FALSE if there are locks or objects.
////////////////////////////////////////////////////////////////
BOOL	ServerCanUnloadNow(void)
{
	if (g_lObjectCount == 0 && g_lLockCount == 0)
	{
		return TRUE;
	}
	return FALSE;
}

////////////////////////////////////////////////////////////////
// SetRegKeyStringValue()
//
// Summary:	Internal utility function to set a Key, Subkey, and 
//			string value in the system Registry under 
//			HKEY_CLASSES_ROOT.
//
// Args:	LPTSTR pszKey,		-	key name
//			LPTSTR pszSubkey,	-	subkey name
//			LPTSTR pszValue		-	value to set it to
//
// Returns:  BOOL
//           TRUE if success; FALSE if not.
////////////////////////////////////////////////////////////////
BOOL SetRegKeyStringValue(LPTSTR		pszKey, 
						  LPTSTR		pszSubkey, 
						  LPTSTR		pszValue)
{
	BOOL	bOk = FALSE;
	LONG	lRetVal;
	HKEY	hKey;
	TCHAR	szKey[MAX_STRING_LENGTH];


	lstrcpy(szKey, pszKey);

	if (NULL != pszSubkey)
	{
		lstrcat(szKey, TEXT("\\"));
		lstrcat(szKey, pszSubkey);
	}

	lRetVal = RegCreateKeyEx(HKEY_CLASSES_ROOT, 
							 szKey, 
							 0, 
							 NULL, 
							 REG_OPTION_NON_VOLATILE, 
							 KEY_ALL_ACCESS, 
							 NULL, 
							 &hKey, 
							 NULL);

	if (NULL != pszValue && ERROR_SUCCESS == lRetVal)
	{
		lRetVal = RegSetValueEx(hKey, 
								NULL, 
								0, 
								REG_SZ, 
								(BYTE *)pszValue,
								(lstrlen(pszValue)+1)*sizeof(TCHAR));
		
		if (ERROR_SUCCESS == lRetVal)
		{
			bOk = TRUE;
		}

		RegCloseKey(hKey);
	}

	return bOk;
}


////////////////////////////////////////////////////////////////
// GetRegNamedStringValue()
//
// Summary:	Internal utility function to get a named data value 
//			string to an existing Key (with optional Subkey) in 
//			the system Registry under HKEY_LOCAL_MACHINE.
//
// Args:	LPTSTR	pszKey,
//			LPTSTR	pszSubkey,
//			LPTSTR	pszValueName,
//			DWORD	dwValue
//
// Returns:	BOOL
//			TRUE if success; FALSE if not.
////////////////////////////////////////////////////////////////
BOOL GetRegNamedStringValue(LPTSTR		pszKey, 
						    LPTSTR		pszSubkey, 
						    LPTSTR		pszValueName,
						    LPTSTR		pszValue)
{
	HKEY			hKey;
	TCHAR			szKey[BUFFER_SIZE];
	DWORD			dwDataSize = sizeof(szKey) * sizeof(TCHAR);
	long			lRetVal;
	unsigned long	lType;


	lstrcpy(szKey, pszKey);

	if (NULL != pszSubkey)
	{
		lstrcat(szKey, TEXT("\\"));
		lstrcat(szKey, pszSubkey);
	}

	lRetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
						   szKey,
						   0,
						   KEY_READ,
						   &hKey);
	if (ERROR_SUCCESS == lRetVal)
	{
		lRetVal = RegQueryValueEx(hKey,
								  pszValueName,
								  NULL,
								  &lType,
								  (unsigned char *)pszValue,
								  &dwDataSize);

		RegCloseKey(hKey);

		if (ERROR_SUCCESS == lRetVal)
		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -