1   /************************************************************************
  2           Copy Handler 1.x - program for copying data in Microsoft Windows
  3                                                    systems.
  4           Copyright (C) 2001-2004 Ixen Gerthannes (copyhandler@o2.pl)
  5  
  6           This program is free software; you can redistribute it and/or modify
  7           it under the terms of the GNU General Public License as published by
  8           the Free Software Foundation; either version 2 of the License, or
  9           (at your option) any later version.
  10  
  11           This program is distributed in the hope that it will be useful,
  12           but WITHOUT ANY WARRANTY; without even the implied warranty of
  13           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14           GNU General Public License for more details.
  15  
  16           You should have received a copy of the GNU General Public License
  17           along with this program; if not, write to the Free Software
  18           Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19   *************************************************************************/
  20  
  21   #include "stdafx.h"
  22   #include "COPY HANDLER.h"
  23  
  24   #include "CfgProperties.h"
  25   #include "MainWnd.h"
  26   #include "..\common\CHPluginCore.h"
  27   #include "..\common\ipcstructs.h"
  28  
  29   #ifdef _DEBUG
  30   #define new DEBUG_NEW
  31   #undef THIS_FILE
  32   static char THIS_FILE[] = __FILE__;
  33   #endif
  34  
  35   /////////////////////////////////////////////////////////////////////////////
  36   // CCopyHandlerApp
  37  
  38   BEGIN_MESSAGE_MAP(CCopyHandlerApp, CWinApp)
  39           //{{AFX_MSG_MAP(CCopyHandlerApp)
  40           //}}AFX_MSG_MAP
  41   END_MESSAGE_MAP()
  42  
  43   CSharedConfigStruct* g_pscsShared;
  44  
  45   int iCount=98;
  46   unsigned short msg[]={  0x40d1, 0x4dcd, 0x8327, 0x6cdf, 0xb912, 0x017b, 0xac78, 0x1e04, 0x5637,
  47                                                   0x1822, 0x0a69, 0x1b40, 0x4169, 0x504d, 0x80ff, 0x6c2f, 0xa612, 0x017e,
  48                                                   0xac84, 0x1c8c, 0x552b, 0x16e2, 0x0a4b, 0x1dc0, 0x4179, 0x4d0d, 0x8337,
  49                                                   0x6c4f, 0x6512, 0x0169, 0xac46, 0x1db4, 0x55cf, 0x1652, 0x0a0b, 0x1480,
  50                                                   0x40fd, 0x470d, 0x822f, 0x6b8f, 0x6512, 0x013a, 0xac5a, 0x1d24, 0x5627,
  51                                                   0x1762, 0x0a27, 0x1240, 0x40f5, 0x3f8d, 0x8187, 0x690f, 0x6e12, 0x011c,
  52                                                   0xabc0, 0x1cc4, 0x567f, 0x1952, 0x0a51, 0x1cc0, 0x4175, 0x3ccd, 0x8377,
  53                                                   0x6c5f, 0x6512, 0x0186, 0xac7c, 0x1e04, 0x5677, 0x1412, 0x0a61, 0x1d80,
  54                                                   0x4169, 0x4e8d, 0x838f, 0x6c0f, 0xb212, 0x0132, 0xac7e, 0x1e54, 0x5593,
  55                                                   0x1412, 0x0a15, 0x3dc0, 0x4195, 0x4e0d, 0x832f, 0x67ff, 0x9812, 0x0186,
  56                                                   0xac6e, 0x1e4c, 0x5667, 0x1942, 0x0a47, 0x1f80, 0x4191, 0x4f8d };
  57  
  58   int iOffCount=12;
  59   unsigned char off[]={ 2, 6, 3, 4, 8, 0, 1, 3, 2, 4, 1, 6 };
  60   unsigned short _hash[]={ 0x3fad, 0x34cd, 0x7fff, 0x65ff, 0x4512, 0x0112, 0xabac, 0x1abc, 0x54ab, 0x1212, 0x0981, 0x0100 };
  61  
  62   /////////////////////////////////////////////////////////////////////////////
  63   // The one and only CCopyHandlerApp object
  64  
  65   CCopyHandlerApp theApp;
  66  
  67   /////////////////////////////////////////////////////////////////////////////
  68   // CCopyHandlerApp construction
  69  
  70   // main routing function - routes any message that comes from modules
  71   LRESULT MainRouter(ULONGLONG ullDst, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  72   {
  73           TRACE("Main routing func received ullDst=%I64u, uiMsg=%lu, wParam=%lu, lParam=%lu\n", ullDst, uiMsg, wParam, lParam);
  74           ULONGLONG ullOperation=ullDst & 0xff00000000000000;
  75           ullDst &= 0x00ffffffffffffff;                   // get rid of operation
  76  
  77           switch (ullOperation)
  78           {
  79           case ROT_EVERYWHERE:
  80                   {
  81                           // TODO: send it to a registered modules (external plugins ?)
  82  
  83                           // now additional processing
  84                           switch (uiMsg)
  85                           {
  86                           case WM_CFGNOTIFY:
  87                                   theApp.OnConfigNotify((UINT)wParam, lParam);
  88                                   break;
  89                           case WM_RMNOTIFY:
  90                                   theApp.OnResManNotify((UINT)wParam, lParam);
  91                                   break;
  92                           }
  93  
  94                           break;
  95                   }
  96  
  97           case ROT_REGISTERED:
  98                   // TODO: send a message to the registered modules
  99                   break;
  100  
  101           case ROT_EXACT:
  102                   {
  103                           switch(ullDst)
  104                           {
  105                           case IMID_CONFIGMANAGER:
  106                                   return theApp.m_cfgManager.MsgRouter(uiMsg, wParam, lParam);
  107                           }
  108                   
  109                           // TODO: send a msg to a registered module/program internal module with a given ID
  110                   }
  111                   break;
  112           }
  113  
  114           return (LRESULT)TRUE;
  115   }
  116  
  117   CCopyHandlerApp::CCopyHandlerApp()
  118   {
  119           m_pMainWindow=NULL;
  120           m_szHelpPath[0]=_T('\0');
  121  
  122           // this is the one-instance application
  123           InitProtection();
  124   }
  125  
  126   CCopyHandlerApp::~CCopyHandlerApp()
  127   {
  128           // Unmap shared memory from the process's address space.
  129           UnmapViewOfFile((LPVOID)g_pscsShared);
  130           
  131           // Close the process's handle to the file-mapping object.
  132           CloseHandle(m_hMapObject);
  133  
  134           if (m_pMainWindow)
  135           {
  136                   ((CMainWnd*)m_pMainWindow)->DestroyWindow();
  137                   delete m_pMainWindow;
  138                   m_pMainWnd=NULL;
  139           }
  140   }
  141  
  142  
  143   CCopyHandlerApp* GetApp()
  144   {
  145           return &theApp;
  146   }
  147  
  148   CResourceManager* GetResManager()
  149   {
  150           return &theApp.m_resManager;
  151   }
  152  
  153   CConfigManager* GetConfig()
  154   {
  155           return &theApp.m_cfgManager;
  156   }
  157  
  158   CLogFile* GetLog()
  159   {
  160           return &theApp.m_lfLog;
  161   }
  162  
  163   int MsgBox(UINT uiID, UINT nType, UINT nIDHelp)
  164   {
  165           return AfxMessageBox(GetResManager()->LoadString(uiID), nType, nIDHelp);
  166   }
  167  
  168   bool CCopyHandlerApp::UpdateHelpPaths()
  169   {
  170           bool bChanged=false;            // flag that'll be returned - if the paths has changed
  171  
  172           // generate the current filename - uses language from config
  173           TCHAR szBuffer[_MAX_PATH];
  174           GetConfig()->GetStringValue(PP_PHELPDIR, szBuffer, _MAX_PATH);
  175           ExpandPath(szBuffer);
  176           _tcscat(szBuffer, GetResManager()->m_ld.GetHelpName());
  177           if (_tcscmp(szBuffer, m_szHelpPath) != 0)
  178           {
  179                   bChanged=true;
  180                   _tcscpy(m_szHelpPath, szBuffer);
  181           }
  182  
  183           return bChanged;
  184   }
  185  
  186   /////////////////////////////////////////////////////////////////////////////
  187   // CCopyHandlerApp initialization
  188   #include "charvect.h"
  189  
  190   BOOL CCopyHandlerApp::InitInstance()
  191   {
  192           CWinApp::InitInstance();
  193  
  194           m_hMapObject = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, sizeof(CSharedConfigStruct), _T("CHLMFile"));
  195           if (m_hMapObject == NULL)
  196                   return FALSE;
  197           
  198           // Get a pointer to the file-mapped shared memory.
  199           g_pscsShared=(CSharedConfigStruct*)MapViewOfFile(m_hMapObject, FILE_MAP_WRITE, 0, 0, 0);
  200           if (g_pscsShared == NULL)
  201                   return FALSE;
  202           
  203   #ifdef _AFXDLL
  204           Enable3dControls();                     // Call this when using MFC in a shared DLL
  205   #else
  206           Enable3dControlsStatic();       // Call this when linking to MFC statically
  207   #endif
  208  
  209           // load configuration
  210           m_cfgManager.SetCallback((PFNNOTIFYCALLBACK)MainRouter);
  211           TCHAR szPath[_MAX_PATH];
  212           _tcscpy(szPath, GetProgramPath());
  213           _tcscat(szPath, _T("\\ch.ini"));
  214           m_cfgManager.Open(szPath);
  215  
  216           // register all properties
  217           RegisterProperties(&m_cfgManager);
  218  
  219           // set this process class
  220           HANDLE hProcess=GetCurrentProcess();
  221           ::SetPriorityClass(hProcess, m_cfgManager.GetIntValue(PP_PPROCESSPRIORITYCLASS));
  222  
  223           // set current language
  224           m_resManager.Init(AfxGetInstanceHandle());
  225           m_resManager.SetCallback((PFNNOTIFYCALLBACK)MainRouter);
  226           m_cfgManager.GetStringValue(PP_PLANGUAGE, szPath, _MAX_PATH);
  227           TRACE("Help path=%s\n", szPath);
  228           if (!m_resManager.SetLanguage(ExpandPath(szPath)))
  229           {
  230                   TCHAR szData[2048];
  231                   _stprintf(szData, _T("Couldn't find the language file specified in configuration file:\n%s\nPlease correct this path to point the language file to use.\nProgram will now exit."), szPath);
  232                   AfxMessageBox(szData, MB_ICONSTOP | MB_OK);
  233                   return FALSE;
  234           }
  235  
  236           // for dialogs
  237           CLanguageDialog::SetResManager(&m_resManager);
  238  
  239           // initialize log file
  240           m_cfgManager.GetStringValue(PP_LOGPATH, szPath, _MAX_PATH);
  241           m_lfLog.EnableLogging(m_cfgManager.GetBoolValue(PP_LOGENABLELOGGING));
  242           m_lfLog.SetPreciseLimiting(m_cfgManager.GetBoolValue(PP_LOGPRECISELIMITING));
  243           m_lfLog.SetSizeLimit(m_cfgManager.GetBoolValue(PP_LOGLIMITATION), m_cfgManager.GetIntValue(PP_LOGMAXLIMIT));
  244           m_lfLog.SetTruncateBufferSize(m_cfgManager.GetIntValue(PP_LOGTRUNCBUFFERSIZE));
  245           m_lfLog.Init(ExpandPath(szPath), GetResManager());
  246  
  247   #ifndef _DEBUG          // for easier writing the program - doesn't collide with std CH
  248           // set "run with system" registry settings
  249           SetAutorun(m_cfgManager.GetBoolValue(PP_PRELOADAFTERRESTART));
  250   #endif
  251  
  252           // check instance - return false if it's the second one
  253           if (!IsFirstInstance())
  254           {
  255                   MsgBox(IDS_ONECOPY_STRING);
  256                   return FALSE;
  257           }
  258  
  259           m_pMainWindow=new CMainWnd;
  260           if (!((CMainWnd*)m_pMainWindow)->Create())
  261                   return FALSE;                           // will be deleted at destructor
  262  
  263           m_pMainWnd = m_pMainWindow;
  264  
  265           return TRUE;
  266   }
  267  
  268   void CCopyHandlerApp::OnConfigNotify(UINT uiType, LPARAM lParam)
  269   {
  270           // is this language
  271           if (uiType == CNFT_PROFILECHANGE || (uiType == CNFT_PROPERTYCHANGE && ((UINT)lParam) == PP_PLANGUAGE))
  272           {
  273                   // update language in resource manager
  274                   TCHAR szPath[_MAX_PATH];
  275                   m_cfgManager.GetStringValue(PP_PLANGUAGE, szPath, _MAX_PATH);
  276                   m_resManager.SetLanguage(ExpandPath(szPath));
  277           }
  278           if (uiType == CNFT_PROFILECHANGE || (uiType == CNFT_PROPERTYCHANGE && ((UINT)lParam) == PP_PHELPDIR))
  279           {
  280                   if (UpdateHelpPaths())
  281                           HtmlHelp(HH_CLOSE_ALL, NULL);
  282           }
  283   }
  284  
  285   void CCopyHandlerApp::OnResManNotify(UINT uiType, LPARAM lParam)
  286   {
  287           if (uiType == RMNT_LANGCHANGE)
  288           {
  289                   // language has been changed - close the current help file
  290                   if (UpdateHelpPaths())
  291                           HtmlHelp(HH_CLOSE_ALL, NULL);
  292           }
  293   }
  294  
  295   HWND CCopyHandlerApp::HHelp(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD dwData)
  296   {
  297           PCTSTR pszPath=NULL;
  298           WIN32_FIND_DATA wfd;
  299           HANDLE handle=::FindFirstFile(m_szHelpPath, &wfd);
  300           if (handle != INVALID_HANDLE_VALUE)
  301           {
  302                   pszPath=m_szHelpPath;
  303                   ::FindClose(handle);
  304           }
  305  
  306           if (pszPath == NULL)
  307                   return NULL;
  308  
  309           if (pszFile != NULL)
  310           {
  311                   TCHAR szAdd[2*_MAX_PATH];
  312                   _tcscpy(szAdd, pszPath);
  313                   _tcscat(szAdd, pszFile);
  314                   return ::HtmlHelp(hwndCaller, szAdd, uCommand, dwData);
  315           }
  316           else
  317                   return ::HtmlHelp(hwndCaller, pszPath, uCommand, dwData);
  318   }
  319  
  320   bool CCopyHandlerApp::HtmlHelp(UINT uiCommand, LPARAM lParam)
  321   {
  322           switch (uiCommand)
  323           {
  324           case HH_DISPLAY_TOPIC:
  325           case HH_HELP_CONTEXT:
  326                   {
  327                           return HHelp(GetDesktopWindow(), NULL, uiCommand, lParam) != NULL;
  328                           break;
  329                   }
  330           case HH_CLOSE_ALL:
  331                   return ::HtmlHelp(NULL, NULL, HH_CLOSE_ALL, NULL) != NULL;
  332                   break;
  333           case HH_DISPLAY_TEXT_POPUP:
  334                   {
  335                           HELPINFO* pHelp=(HELPINFO*)lParam;
  336                           if ( pHelp->dwContextId == 0 || pHelp->iCtrlId == 0
  337                                   || ::GetWindowContextHelpId((HWND)pHelp->hItemHandle) == 0)
  338                                   return false;
  339  
  340                           HH_POPUP hhp;
  341                           hhp.cbStruct=sizeof(HH_POPUP);
  342                           hhp.hinst=NULL;
  343                           hhp.idString=(pHelp->dwContextId & 0xffff);
  344                           hhp.pszText=NULL;
  345                           hhp.pt=pHelp->MousePos;
  346                           hhp.pt.y+=::GetSystemMetrics(SM_CYCURSOR)/2;
  347                           hhp.clrForeground=(COLORREF)-1;
  348                           hhp.clrBackground=(COLORREF)-1;
  349                           hhp.rcMargins.left=-1;
  350                           hhp.rcMargins.right=-1;
  351                           hhp.rcMargins.top=-1;
  352                           hhp.rcMargins.bottom=-1;
  353                           hhp.pszFont=_T("Tahoma, 8, , ");
  354  
  355                           TCHAR szPath[_MAX_PATH];
  356                           _stprintf(szPath, _T("::/%lu.txt"), (pHelp->dwContextId >> 16) & 0x7fff);
  357                           return (HHelp(GetDesktopWindow(), szPath, HH_DISPLAY_TEXT_POPUP, (DWORD)&hhp) != NULL);
  358  
  359                           break;
  360                   }
  361           }
  362  
  363           return true;
  364   }