/***************************************************************************
                             DllLoader.cpp
                             -------------------
    Begin                : Fri Oct 12, 2001
    Objective            : Implement an object to load a DLL from a resource
                           and load the exports
    Author               : Drew Hall
    Email                : dhall@Zero-Soft.com
 ***************************************************************************/

#include "stdafx.h"


CDllLoader::CDllLoader() : m_hLibrary(NULL), m_hResource(NULL), m_hResData(NULL), m_hTempFile(NULL)
{
   *m_szFileName = '\0';
   m_hModule = GetModuleHandle(NULL);
   //if(hModule == 0)
      // Throw an exception
}

CDllLoader::~CDllLoader()
{
   FreeLibrary(m_hLibrary);
   DeleteFile(m_szFileName);
}

bool CDllLoader::LoadDll(const TCHAR* szTempFileName, const TCHAR* szResourceGroup, int nResourceID)
{
   if(szTempFileName)
      strcpy((TCHAR*)szTempFileName, m_szFileName);
   else
      if(!CreateTempFile())
         return false;

   if(!OpenTempFile())
      return false;

   if(!LoadResource(szResourceGroup, nResourceID))
      return false;

   if(!WriteDll())
      return false;

   return LoadExports();
}

bool CDllLoader::LoadExports()
{
   StartLogging = (STARTLOGGINGFUNC)GetProcAddress(m_hLibrary, "StartLogging");
   if(StartLogging == 0)
      return false;

   StopLogging = (STOPLOGGINGFUNC)GetProcAddress(m_hLibrary, "StopLogging");
   if(StopLogging == 0)
      return false;
   
   return true;
}

bool CDllLoader::CreateTempFile()
{
   TCHAR szTempPath[MAX_PATH];

   if(!GetTempPath(MAX_PATH, szTempPath))
      return false;

   if(!GetTempFileName(szTempPath, TEXT("tmp"), 0, m_szFileName))
      return false;

   return true;
}

bool CDllLoader::OpenTempFile()
{
   m_hTempFile = CreateFile(m_szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
   
   if(m_hTempFile == INVALID_HANDLE_VALUE)
      return false;

   return true;
}


bool CDllLoader::LoadResource(const TCHAR* szResourceGroup, int nResourceID)
{
   m_hResource = FindResource(m_hModule, MAKEINTRESOURCE(nResourceID), szResourceGroup);
   if(m_hResource == 0)
      return false;

   m_Size = SizeofResource(m_hModule, m_hResource);
   m_hResData = ::LoadResource(m_hModule, m_hResource);
   if(m_hResData == 0)
      return false;

   return true;
}

bool CDllLoader::WriteDll()
{
   void *pDllData;
   DWORD dwBytes=0L;

   pDllData = LockResource(m_hResData);
   if(pDllData == 0)
      return false;

   WriteFile(m_hTempFile, pDllData, m_Size, &dwBytes, 0);
   CloseHandle(m_hTempFile);
   m_hTempFile = NULL;

   m_hLibrary = LoadLibrary(m_szFileName);
   
   if(m_hLibrary == 0)
      return false;

   return true;
}
   


