
/*****************************************************************************
* Copyright (c) 1990-98 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/


// ObjectFactory.cpp: 
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ObjectFactory.h"


static BOOL GetDllPath(CString const & strMapName, CString const & strName, CString & strDllPath)
{
   BOOL fSuccess = FALSE;

   try
   {
      CString strMapKey = DXB_REGKEY_CONFIG_DATA;
      strMapKey += TEXT("\\") + strMapName;

      HKEY hkMap = NULL;
      AffirmThrow(RegOpenKey(HKEY_LOCAL_MACHINE, strMapKey, &hkMap));
      AffirmThrow(hkMap != NULL);

      try
      {
         AffirmThrow(RegReadStrValue(hkMap, strName, strDllPath));
      }
      catch (CAffirmException ae)
      {
      }

      RegCloseKey(hkMap);

      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

static BOOL LoadDllAndNewObject(CString const & strDllPath, HINSTANCE * const phDll,
                                CConfigObject ** const ppObj, CString const & strName,
                                HKEY const hKeyRoot, CString const & strRegPath, CConfigObject const * const pParent)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(phDll != NULL);
#if defined(_DEBUG)
      if (*phDll != NULL) TRACE("LoadDllAndNewObject(): *phDll != NULL\n");
#endif
      AffirmThrow(ppObj != NULL);
#if defined(_DEBUG)
      if (*ppObj != NULL) TRACE("LoadDllAndNewObject(): *ppObj != NULL\n");
#endif

      *phDll = AfxLoadLibrary((LPCTSTR)strDllPath);
      AffirmThrow(*phDll != NULL);

      NEWOBJPROC pfnNew = (NEWOBJPROC) GetProcAddress(*phDll, NEWOBJPROCNAME);
      AffirmThrow(pfnNew != NULL);
      AffirmThrow(pfnNew(ppObj, strName, hKeyRoot, strRegPath, pParent));
      AffirmThrow(*ppObj != NULL);

      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

static void DeleteObjectAndUnloadDll(CConfigObject ** const ppObj, HINSTANCE const hDll)
{
   try
   {
      AffirmThrow(ppObj != NULL);
      AffirmThrow(*ppObj != NULL);
      AffirmThrow(hDll != NULL);

      DELETEOBJPROC pfnDelete = (DELETEOBJPROC) GetProcAddress(hDll, DELETEOBJPROCNAME);
      AffirmThrow(pfnDelete != NULL);
      pfnDelete(ppObj);

      // !! CAUTION !!
      // Don't use *ppObj after this point!

      AfxFreeLibrary(hDll);
   }
   catch (CAffirmException ae)
   {
   }

   return;
}

BOOL FW_EXPORTED_API NewConfigObject(CConfigObject ** const ppObj,
                                            int const eType,
                                            CString const & strName,
                                            HKEY const hKeyRoot,
                                            CString const & strRegPath,
                                            CConfigObject const * const pParent)
{
   BOOL fSuccess = FALSE;

   TRACE("NewConfigObject(%d, %s, %s)\n", eType, (LPCTSTR)strName, (LPCTSTR)strRegPath);

   try
   {
      AffirmThrow(ppObj != NULL);
#if defined(_DEBUG)
      if (*ppObj != NULL) TRACE("NewConfigObject(): *ppObj != NULL\n");
#endif

      CString strMapName;
      switch (eType)
      {
         case CConfigObject::ADAPTER:     strMapName = TEXT("AdapterMap");    break;
         case CConfigObject::LINE:        strMapName = TEXT("LineMap");       break;
         case CConfigObject::PROTOCOL:    strMapName = TEXT("ProtocolMap");   break;
         case CConfigObject::SERVICE:     strMapName = TEXT("ServiceMap");    break;
         case CConfigObject::PORT:        strMapName = TEXT("PortMap");       break;
		 case CConfigObject::ROUTER:	  strMapName = TEXT("RouterMap");     break;
         default: AffirmThrow(FALSE); break;
      }

      CString strDllPath;
      AffirmThrow(GetDllPath(strMapName, strName, strDllPath));

      HINSTANCE hDll = NULL;
      AffirmThrow(LoadDllAndNewObject(strDllPath, &hDll, ppObj, strName, hKeyRoot, strRegPath, pParent));
      AffirmThrow(hDll != NULL);
      AffirmThrow(*ppObj != NULL);

      (*ppObj)->SetDllHandle(hDll);

      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

void FW_EXPORTED_API DeleteConfigObject(CConfigObject ** const ppObj)
{
   try
   {
      AffirmThrow(ppObj != NULL);
      AffirmThrow(*ppObj != NULL);

      HINSTANCE hDll = (*ppObj)->GetDllHandle();
      AffirmThrow(hDll != NULL);

      DeleteObjectAndUnloadDll(ppObj, hDll);

      // !! CAUTION !!
      //    Do NOT use *ppObj anymore!
   }
   catch (CAffirmException ae)
   {
   }

   return;
}
