Subversion Repositories libraries.mycontrols

Rev

Rev 6 | Blame | Compare with Previous | Last modification | View Log

/////////////////////////////////  Includes  //////////////////////////////////
#pragma warning( disable : 4996 )
#include "stdafx.h"
#include "nteventlogsource.h"


/////////////////////////////////  Macros /////////////////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



///////////////////////// CNTEventLogSource implementation ////////////////////
CNTEventLogSource::CNTEventLogSource(LPCTSTR lpUNCServerName, LPCTSTR lpSourceName)
{
  m_hEventSource = NULL;
  m_sServerName = lpUNCServerName;
  m_sSourceName = lpSourceName;
}

CNTEventLogSource::~CNTEventLogSource()
{
  Deregister();
}

CNTEventLogSource::operator HANDLE() const
{
  return m_hEventSource;
}

BOOL CNTEventLogSource::Attach(HANDLE hEventSource)
{
  if (m_hEventSource != hEventSource)
    Deregister();

  m_hEventSource = hEventSource;
  return TRUE;
}

HANDLE CNTEventLogSource::Detach()
{
  HANDLE hReturn = m_hEventSource;
  m_hEventSource = NULL;
  return hReturn;
}

BOOL CNTEventLogSource::Register(LPCTSTR lpUNCServerName, LPCTSTR lpSourceName)
{
  Deregister();
  m_hEventSource = ::RegisterEventSource(lpUNCServerName, lpSourceName);
  if (m_hEventSource == NULL)
    TRACE(_T("Failed in call to RegisterEventSource in Register, GetLastError:%d\n"), ::GetLastError());
  else
  {

    m_sServerName = lpUNCServerName;
    m_sSourceName = lpSourceName;
  }
  return (m_hEventSource != NULL);
}

BOOL CNTEventLogSource::Report(WORD wType, WORD wCategory, DWORD dwEventID, PSID lpUserSid,
                               WORD wNumStrings, DWORD dwDataSize, LPCTSTR* lpStrings, LPVOID lpRawData)
{
  //CSingleLock sl(&m_csReport, TRUE);

  ASSERT(m_hEventSource == NULL);
  Register(m_sServerName, m_sSourceName);

  //Call the SDK version of the function
  BOOL bSuccess = ::ReportEvent(m_hEventSource, wType,  wCategory, dwEventID, lpUserSid,
                                wNumStrings, dwDataSize, lpStrings, lpRawData);
  if (!bSuccess)
    TRACE(_T("Failed in call to ReportEvent in Report, GetLastError:%d\n"), ::GetLastError());

  Deregister();  

  return bSuccess;
}

BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID)
{
  return Report(wType, 0, dwEventID, NULL, 0, 0, NULL, NULL);
}

BOOL CNTEventLogSource::Report(WORD wType, LPCTSTR lpszString)
{
  return Report(wType, CNT_MSG_FULLSTRING, lpszString);
}

BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString)
{
  ASSERT(lpszString);
  return Report(wType, 0, dwEventID, NULL, 1, 0, &lpszString, NULL);
}


BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString1, LPCTSTR lpszString2)
{
  ASSERT(lpszString1);
  ASSERT(lpszString2);
//  LPCTSTR lpStrings[2];
//  lpStrings[0] = lpszString1;
//  lpStrings[1] = lpszString2;
  return Report(wType, 0, dwEventID, NULL, 1, strlen(lpszString2), &lpszString1, (void *)lpszString2);
}

BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString1, LPCTSTR lpszString2, int len2)
{
  ASSERT(lpszString1);
  ASSERT(lpszString2);
//  LPCTSTR lpStrings[2];
//  lpStrings[0] = lpszString1;
//  lpStrings[1] = lpszString2;
  return Report(wType, 0, dwEventID, NULL, 1, len2, &lpszString1, (void *)lpszString2);
}


BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString1, LPCTSTR lpszString2, DWORD dwCode, BOOL bReportAsHex)
{
  ASSERT(lpszString1);
  ASSERT(lpszString2);
  LPCTSTR lpStrings[3];
  lpStrings[0] = lpszString1;
  lpStrings[1] = lpszString2;
  CString sError;
  if (bReportAsHex)
    sError.Format(_T("%x"), dwCode);
  else
    sError.Format(_T("%d"), dwCode);
  lpStrings[2] = sError;
  return Report(wType, 0, dwEventID, NULL, 3, 0, lpStrings, NULL);
}

BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, DWORD dwCode, BOOL bReportAsHex)
{
  CString sError;
  if (bReportAsHex)
    sError.Format(_T("%x"), dwCode);
  else
    sError.Format(_T("%d"), dwCode);
  return Report(wType, dwEventID, sError);
}

BOOL CNTEventLogSource::Report(WORD wType, DWORD dwEventID, LPCTSTR lpszString, DWORD dwCode, BOOL bReportAsHex)
{

  LPCTSTR lpStrings[2];
  CString sError;

  if (bReportAsHex)
    sError.Format(_T("%x"), dwCode);
  else
    sError.Format(_T("%d"), dwCode);

  lpStrings[0] = lpszString;
  lpStrings[1] = sError;

  return Report(wType, 0, dwEventID, NULL, 2, 0, lpStrings, NULL);
}

BOOL CNTEventLogSource::Deregister()
{
  BOOL bSuccess = TRUE;
  if (m_hEventSource != NULL)
  {
    bSuccess = ::DeregisterEventSource(m_hEventSource);
    if (!bSuccess)
      TRACE(_T("Failed in call to DeregisterEventSource in Deregister, GetLastError:%d\n"), ::GetLastError());
    m_hEventSource = NULL;
  }

  return bSuccess;
}

BOOL CNTEventLogSource::Install(LPCTSTR lpSourceName, LPCTSTR lpEventMessageFile, DWORD dwTypesSupported)
{
  //Validate our parameters
  ASSERT(lpSourceName);
  ASSERT(lpEventMessageFile);


  //Make the necessary updates to the registry
  HKEY hAppKey;
  BOOL bSuccess = FALSE;
  int error = 0;
  error = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"), 0,
                     KEY_WRITE|KEY_READ, &hAppKey);
  if (error == ERROR_SUCCESS)
  {
    DWORD dw;
    HKEY hSourceKey;
    if (RegCreateKeyEx(hAppKey, lpSourceName, 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,
                       &hSourceKey, &dw) == ERROR_SUCCESS)
    {
      //Write the Message file string
      bSuccess = (RegSetValueEx(hSourceKey, _T("EventMessageFile"), NULL, REG_SZ, (LPBYTE)lpEventMessageFile,
                                (lstrlen(lpEventMessageFile)+1)*sizeof(TCHAR)) == ERROR_SUCCESS);
      if (!bSuccess)
        TRACE(_T("Failed in call to RegSetValueEx in Install, GetLastError:%d\n"), ::GetLastError());


      //Write the Types supported dword
      bSuccess = bSuccess && (RegSetValueEx(hSourceKey, _T("TypesSupported"), NULL, REG_DWORD,
                                            (LPBYTE)&dwTypesSupported, sizeof(dwTypesSupported)) == ERROR_SUCCESS);
      if (!bSuccess)
        TRACE(_T("Failed in call to RegSetValueEx in Install, GetLastError:%d\n"), ::GetLastError());

      //Close the registry key we opened
      ::RegCloseKey(hSourceKey);

      //Update the sources registry key so that the event viewer can filter
      //on the events which we write to the event log
      CStringArray sources;
      if (GetStringArrayFromRegistry(hAppKey, _T("Sources"), sources))
      {
        //If our name is not in the array then add it
        BOOL bFoundMyself = FALSE;
        for (int i=0; i<sources.GetSize() && !bFoundMyself; i++)
          bFoundMyself = (sources.GetAt(i) == lpSourceName);
        if (!bFoundMyself)
        {
          sources.Add(lpSourceName);
          SetStringArrayIntoRegistry(hAppKey, _T("Sources"), sources);
        }
      }
    }
    else
      TRACE(_T("Failed in call to RegCreateKeyEx in Install, GetLastError:%d\n"), ::GetLastError()); //::GetLastError());

    //Close the registry key we opened
    ::RegCloseKey(hAppKey);
  }
  else
    TRACE(_T("Failed in call to RegOpenKeyEx in Install, GetLastError:%d\n"), error);

  return bSuccess;
}

BOOL CNTEventLogSource::Uninstall(LPCTSTR lpSourceName)
{
  //Validate our parameters
  ASSERT(lpSourceName);

  //Remove the settings from the registry
  CString sSubKey(_T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"));
  sSubKey += lpSourceName;
  BOOL bSuccess = (RegDeleteKey(HKEY_LOCAL_MACHINE, sSubKey) == ERROR_SUCCESS);
  if (!bSuccess)
    TRACE(_T("Failed in call to RegDeleteKey in Uninstall, GetLastError:%d\n"), ::GetLastError());

  //Remove ourself from the "Sources" registry key
  HKEY hAppKey;
  if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"), 0,
                     KEY_WRITE|KEY_READ, &hAppKey) == ERROR_SUCCESS)
  {
    CStringArray sources;
    if (GetStringArrayFromRegistry(hAppKey, _T("Sources"), sources))
    {
      //If our name is in the array then remove it
      BOOL bFoundMyself = FALSE;
      for (int i=0; i<sources.GetSize() && !bFoundMyself; i++)
      {
        bFoundMyself = (sources.GetAt(i) == lpSourceName);
        if (bFoundMyself)
          sources.RemoveAt(i);
      }
      if (bFoundMyself)
        SetStringArrayIntoRegistry(hAppKey, _T("Sources"), sources);
    }

    //Close the registry key we opened
    ::RegCloseKey(hAppKey);
  }

  return bSuccess;
}

BOOL CNTEventLogSource::GetStringArrayFromRegistry(HKEY hKey, LPCTSTR lpszEntry, CStringArray& array)
{
  ASSERT(hKey != NULL);
  ASSERT(lpszEntry != NULL);

  //Assume the worst
  BOOL bSuccess = FALSE;

  //Empty the array before we go any further
  array.RemoveAll();

  DWORD dwType, dwCount;
  LONG lResult = RegQueryValueEx(hKey, (LPTSTR)lpszEntry, NULL, &dwType, NULL, &dwCount);
  if (lResult == ERROR_SUCCESS)
  {
    ASSERT(dwType == REG_MULTI_SZ);
    LPBYTE lpBuffer = new BYTE[dwCount];
    lResult = RegQueryValueEx(hKey, (LPTSTR)lpszEntry, NULL, &dwType, lpBuffer, &dwCount);
    if (lResult == ERROR_SUCCESS)
    {
      LPTSTR lpszStrings = (LPTSTR) lpBuffer;
      while (lpszStrings[0] != 0)
      {
        array.Add((LPCTSTR) lpszStrings);
        lpszStrings += (_tcslen(lpszStrings ) + 1);
      }

      bSuccess = TRUE;
    }

    //Tidy up the heap memory we have used
    delete [] lpBuffer;
  }

  return bSuccess;
}

BOOL CNTEventLogSource::SetStringArrayIntoRegistry(HKEY hKey, LPCTSTR lpszEntry, const CStringArray& array)
{  
  int i;
  //Validate our input parameters
  ASSERT(hKey);
  ASSERT(lpszEntry != NULL);

  //Work out the size of the buffer we will need
  DWORD dwSize = 0;
  int nStrings = array.GetSize();
  for (i=0; i<nStrings; i++)
    dwSize += array.GetAt(i).GetLength() + 1; //1 extra for each NULL terminator

  //Need one second NULL for the double NULL at the end
  dwSize++;

  //Convert from BYTE size to character size
  dwSize *= sizeof(TCHAR);

  //Allocate the memory we want
  BYTE* lpBuffer = new BYTE[dwSize];
  ::ZeroMemory(lpBuffer, dwSize);

  //Now copy the strings into the buffer
  int nCurOffset = 0;
  LPTSTR lpszString = (LPTSTR) lpBuffer;
  for (i=0; i<nStrings; i++)
  {
    CString sText = array.GetAt(i);
    _tcscpy(&lpszString[nCurOffset], sText);
    nCurOffset += sText.GetLength();
    nCurOffset++;
  }
  //Don't forgot to doubly NULL terminate
  lpszString[nCurOffset] = _T('\0');

  //Finally write it into the registry
  BOOL bSuccess = (::RegSetValueEx(hKey, lpszEntry, NULL, REG_MULTI_SZ, lpBuffer, dwSize) == ERROR_SUCCESS);

  //free up the memory we used
  delete [] lpBuffer;

  return bSuccess;
}