home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 June / CHIP_CD_2004-06.iso / software / miranda_hit / files / mirinstsetup.exe / Miranda Installer 0.0.1.2 / Misc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-04-20  |  9.0 KB  |  302 lines

  1. /*
  2.     Miranda Installer - Installs nightlies and Miranda addons.
  3.     Copyright (C) 2002-2003 Goblineye Entertainment
  4.  
  5.     Authors: Saar (Tornado) and Kai (kai_b)
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20. */
  21.  
  22. #include "MirandaInstaller.h"
  23. #pragma hdrstop
  24.  
  25.  
  26. static bool Is_Using_NT(bool fOnlyNT4) // returns true if we're using an NT operating system
  27. {
  28.     OSVERSIONINFO osInfo;
  29.     osInfo.dwOSVersionInfoSize = sizeof(osInfo);
  30.  
  31.     if (!GetVersionEx(&osInfo))
  32.         return(false);
  33.  
  34.     if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) // if we're using an NT OS and the OS isn't NT3.5
  35.     {
  36.         if ((osInfo.dwMajorVersion == 3) && (fOnlyNT4)) // it's actually NT3.5
  37.             return(false);
  38.         return(true);
  39.     }
  40.     else
  41.         return(false);
  42. }
  43.  
  44.  
  45.  
  46. static bool Get_ModulePath_From_Window(HWND hWnd,char *lpszoutPath,WORD wLen)
  47. {
  48.     static bool bUsingNT4 = Is_Using_NT(true); // assuming that the OS doesn't change
  49.     bool fRetVal = true;
  50.  
  51.     if (bUsingNT4) // only using NT4 and above
  52.     {
  53.         // get the module of the window
  54.         HMODULE hModule = (HMODULE)GetWindowLongPtr(hWnd,GWLP_HINSTANCE);
  55.  
  56.         DWORD dwProcessID;
  57.         GetWindowThreadProcessId(hWnd,&dwProcessID); // get process ID
  58.  
  59.         // open it with full access
  60.         HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessID);
  61.         HINSTANCE hPSAPI = LoadLibrary("psapi.dll");
  62.  
  63.         if ((hProcess != NULL) && (hPSAPI != NULL))
  64.         {
  65.             pGMFileNameEx pGetModuleFNX = (pGMFileNameEx)GetProcAddress(hPSAPI,"GetModuleFileNameExA");
  66.             if (pGetModuleFNX != NULL) // if everything is ok
  67.             {
  68.                 fRetVal = (pGetModuleFNX(hProcess,hModule,lpszoutPath,wLen)) ? (true) : (false);
  69.             }
  70.             else
  71.             {
  72.                 fRetVal = false;
  73.             }
  74.         }
  75.         else
  76.         {
  77.             fRetVal = false;
  78.         }
  79.  
  80.         if (hPSAPI != NULL)
  81.         {
  82.             FreeLibrary(hPSAPI);
  83.         }
  84.  
  85.         if (hProcess != NULL)
  86.         {
  87.             CloseHandle(hProcess); // close handle to process
  88.         }
  89.     }
  90.     else
  91.     {
  92.         // win95/98/me way, very easy
  93.         fRetVal = GetWindowModuleFileName(hWnd,lpszoutPath,wLen) > 0;
  94.     }
  95.     return(fRetVal);
  96. }
  97.  
  98.  
  99.  
  100. BOOL CALLBACK EnumMirWndProc(HWND hWnd,LPARAM lParam)
  101. {
  102.     char szName[32];
  103.     GetClassName(hWnd,szName,32);
  104.  
  105.     // temporary fix to MultiWindow plugin bug. should be removed later.
  106.     if (lstrcmp(szName,"Miranda") == 0) // it's miranda
  107.     {
  108.         char szWndPath[MAX_PATH + 1];
  109.         if (!Get_ModulePath_From_Window(hWnd,szWndPath,MAX_PATH+1))
  110.         {
  111.             return(true);
  112.         }
  113.  
  114.         // hmm
  115.         // messy
  116.         // but easy
  117.         // if length is longer than our original, cut it
  118.         int iLen = lstrlen(g_WorkOptions.szMirandaDirectory);
  119.         if (lstrlen(szWndPath) > iLen)
  120.         {
  121.             szWndPath[iLen] = '\0'; // bah
  122.         }
  123.  
  124.         if (lstrcmpi(szWndPath,g_WorkOptions.szMirandaDirectory) == 0) // found it
  125.         {
  126.             *((HWND*)lParam) = hWnd;
  127.             return(false); // stop enumeration
  128.         }
  129.     }
  130.     return(true);
  131. }
  132.  
  133.  
  134.  
  135. // returns the handle to the first found window if the app is running
  136. // how this works: the enum proc tries to find a window in the system, which has the class "Miranda"
  137. // and resides in the same given miranda directory
  138. // we don't check the filename of the module, only the directory
  139. // that should be enough (checking the filename is no good, coz the module path given could be different then miranda32.exe)
  140. HWND Is_App_Running(void)
  141. {
  142.     HWND hWnd = NULL; // will receive the handle, if found
  143.     EnumWindows(EnumMirWndProc,(LPARAM)&hWnd); // enumerate windows (find miranda)
  144.     return(hWnd);
  145. }
  146.  
  147.  
  148.  
  149. // lpoutText is assumed to be big enough to hold this
  150. void Format_DisplaySize(char *lpoutText,DWORD dwSize) // format size into lpoutText
  151. {
  152.     if (dwSize >= 1048576) // MB
  153.     {
  154.         wsprintf(lpoutText,Translate("%dMB"),dwSize / 1048576);
  155.     }
  156.     else if (dwSize >= 1024) // KB
  157.     {
  158.         wsprintf(lpoutText,Translate("%dKB"),dwSize / 1024);
  159.     }
  160.     else // bytes
  161.     {
  162.         wsprintf(lpoutText,Translate("%d bytes"),dwSize);
  163.     }
  164. }
  165.  
  166.  
  167.  
  168. // clean up a given file list, the general file list is used A LOT, so a cleanup function is a must
  169. void Cleanup_FileList(GENERAL_FILELIST **ppFileList)
  170. {
  171.     if ((ppFileList == NULL) || (*ppFileList == NULL))
  172.     {
  173.         return;
  174.     }
  175.  
  176.     GENERAL_FILELIST *pFileList = *ppFileList;
  177.     while (pFileList != NULL)
  178.     {
  179.         GENERAL_FILELIST *pNext = pFileList->next;
  180.         delete [] pFileList->lpFilename;
  181.         delete pFileList;
  182.         pFileList = pNext;
  183.     }
  184.     *ppFileList = NULL;
  185. }
  186.  
  187.  
  188.  
  189. // pretty straight forward... converts slashes to backslashes
  190. // reverse means backslashes to slashes
  191. void Switch_Slashes(char *lpText,bool fReverse)
  192. {
  193.     while (*lpText != '\0')
  194.     {
  195.         if (fReverse) // backslash to slash
  196.         {
  197.             if (*lpText == '\\')
  198.             { *lpText = '/'; }
  199.         }
  200.         else if (*lpText == '/') // reverse it
  201.         { *lpText = '\\'; }
  202.  
  203.         lpText++; // local copy
  204.     }
  205. }
  206.  
  207.  
  208.  
  209. // simple as that
  210. void Restart_Miranda(void)
  211. {
  212.     char szPath[MAX_PATH + 1];
  213.     lstrcpy(szPath,g_WorkOptions.szMirandaDirectory);
  214.     lstrcat(szPath,"\\miranda32.exe");
  215.     ShellExecute(NULL,"open",szPath,((*g_WorkOptions.szDefaultProfile == '\0') ? (NULL) : (g_WorkOptions.szDefaultProfile)),NULL,SW_SHOW);
  216. }
  217.  
  218.  
  219.  
  220. bool RegisterApplication(const char *szTypeName, const char *szDescription)
  221. {
  222.     HKEY hKey=NULL, hKeyTypeName=NULL;
  223.     char buf[MAX_PATH+32];
  224.  
  225.     // register the type description
  226.     RegCreateKeyEx(HKEY_CLASSES_ROOT,(LPCTSTR)szTypeName,0,"",REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKeyTypeName,NULL);
  227.     RegSetValueEx(hKeyTypeName,"",0,REG_SZ,(const BYTE*)szDescription,lstrlen(szDescription)+1);
  228.     DWORD dwValue = 0x10000;
  229.     RegSetValueEx(hKeyTypeName,"EditFlags",0,REG_BINARY,(BYTE*)&dwValue,sizeof(dwValue));
  230.  
  231.     // register the program executable for this type name
  232.     RegCreateKeyEx(hKeyTypeName,"shell\\open",0,"",REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,NULL);
  233.     // set a nice context menu command string
  234.     RegSetValueEx(hKey,"",0,REG_SZ,(const BYTE*)Translate("&Install"),lstrlen(Translate("&Install"))+1);
  235.     RegCreateKeyEx(hKey,"command",0,"",REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,NULL);
  236.     GetModuleFileName(NULL,buf+1,MAX_PATH); // build the command line
  237.     *buf = '"';
  238.     lstrcat(buf,"\" \"%1\"");
  239.  
  240.     // This is the most important line here. It should only fail if something went wrong before.
  241.     if (RegSetValueEx(hKey,"",0,REG_SZ,(const BYTE*)buf,lstrlen(buf)+1)!=ERROR_SUCCESS)
  242.     {
  243.         if (hKey!=NULL)            RegCloseKey(hKey);
  244.         if (hKeyTypeName!=NULL)    RegCloseKey(hKeyTypeName);
  245.         return false;
  246.     }
  247.     RegCloseKey(hKey); // close this HKEY, we don't need it anymore.
  248.  
  249.     // The following lines may fail, we don't care much
  250.  
  251.     // set an icon for registered file types
  252.     RegCreateKeyEx(hKeyTypeName,"DefaultIcon",0,"",REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,NULL);
  253.     GetModuleFileName(NULL,buf,MAX_PATH); // build an icon path
  254.     lstrcat(buf,",1"); // ** document icon, use second icon in library
  255.     RegSetValueEx(hKey,"",0,REG_SZ,(const BYTE*)buf,lstrlen(buf)+1);
  256.     if (hKey!=NULL) RegCloseKey(hKey);
  257.  
  258.     // try to find ZIP file reg entry
  259.     RegOpenKeyEx(HKEY_CLASSES_ROOT,".zip",0,KEY_READ,&hKey);
  260.     int nSize = MAX_PATH;
  261.     if (RegQueryValueEx(hKey,"",0,NULL,(LPBYTE)buf,(LPDWORD)&nSize)==ERROR_SUCCESS)
  262.     {
  263.         RegCloseKey(hKey);
  264.         lstrcat(buf,"\\shell\\open\\command");
  265.         // open and read shell/open/command from ZIP program reg key
  266.         RegOpenKeyEx(HKEY_CLASSES_ROOT,buf,0,KEY_READ,&hKey);
  267.         nSize = MAX_PATH;
  268.         RegQueryValueEx(hKey,"",0,NULL,(LPBYTE)buf,(LPDWORD)&nSize);
  269.         if (hKey!=NULL)    RegCloseKey(hKey);
  270.  
  271.         // register 'Open as ZIP'
  272.         RegCreateKeyEx(hKeyTypeName,"shell\\openZIP",0,"",REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,NULL);
  273.         // set a nice context menu command string
  274.         RegSetValueEx(hKey,"",0,REG_SZ,(const BYTE*)Translate("Open as &ZIP"),lstrlen(Translate("Open as &ZIP"))+1);
  275.         RegCreateKeyEx(hKey,"command",0,"",REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,NULL);
  276.         RegSetValueEx(hKey,"",0,REG_SZ,(const BYTE*)buf,lstrlen(buf)+1);
  277.     }
  278.     
  279.     if (hKey!=NULL)            RegCloseKey(hKey);
  280.     if (hKeyTypeName!=NULL)    RegCloseKey(hKeyTypeName);
  281.     return true;
  282. }
  283.  
  284.  
  285.  
  286. bool RegisterExtension(const char *szExtension, const char *szTypeName)
  287. {
  288.     HKEY hKey;
  289.  
  290.     // register the type name for the extension
  291.     RegCreateKeyEx(HKEY_CLASSES_ROOT,(LPCTSTR)szExtension,0,"",REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,NULL);
  292.     if (RegSetValueEx(hKey,"",0,REG_SZ,(const BYTE*)szTypeName,lstrlen(szTypeName)+1)!=ERROR_SUCCESS) {
  293.         if (hKey!=NULL) RegCloseKey(hKey);
  294.         return false; // this is bad
  295.     }
  296.  
  297.     // we set our own content type to increase compatibility with mozilla
  298.     RegSetValueEx(hKey,"Content Type",0,REG_SZ,(const BYTE*)MI_CONTENT_TYPE,lstrlen(MI_CONTENT_TYPE)+1);
  299.  
  300.     if (hKey!=NULL) RegCloseKey(hKey);
  301.     return true;
  302. }