summaryrefslogtreecommitdiff
path: root/splashscreen/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'splashscreen/src/main.cpp')
-rw-r--r--splashscreen/src/main.cpp534
1 files changed, 534 insertions, 0 deletions
diff --git a/splashscreen/src/main.cpp b/splashscreen/src/main.cpp
new file mode 100644
index 0000000..90f83b4
--- /dev/null
+++ b/splashscreen/src/main.cpp
@@ -0,0 +1,534 @@
+/*
+ Splash Screen Plugin for Miranda-IM (www.miranda-im.org)
+ (c) 2004-2007 nullbie, (c) 2005-2007 Thief
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ File name : $URL: http://svn.miranda.im/mainrepo/splashscreen/trunk/src/main.cpp $
+ Revision : $Rev: 1586 $
+ Last change on : $Date: 2010-04-09 12:34:01 +0300 (Пт, 09 апр 2010) $
+ Last change by : $Author: Thief $
+
+*/
+
+#include "headers.h"
+
+HINSTANCE hInst = 0;
+PLUGINLINK *pluginLink;
+
+static HMODULE hUserDll = NULL;
+static HMODULE hAdvaimg = NULL;
+
+pfnConvertPng2dib png2dibConvertor = NULL;
+
+bool bstartup = true; // startup?
+bool bserviceinvoked = false;
+bool bmodulesloaded = false; // modules are loaded
+bool png2dibavail = true; // can we use png2dib service?
+
+char *mirandaVerString;
+char szPrefix[128];
+PVOID pVerInfo;
+
+// path to miranda's dir, config file path, splash path, sound path
+char szMirDir[MAX_PATH], szIniFile[MAX_PATH], szDllName[MAX_PATH], szSplashFile[MAX_PATH], szSoundFile [MAX_PATH], szhAdvaimgPath [MAX_PATH];
+#ifdef _DEBUG
+char szLogFile[MAX_PATH];
+#endif
+static char inBuf[80];
+
+SPLASHOPTS options;
+
+// Options handle. Declarated in options.cpp
+extern BOOL CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+extern int OptInit(WPARAM wParam, LPARAM lParam);
+extern bool ShowSplash(bool bpreview);
+extern void ReadIniConfig();
+
+HANDLE hShowSplashService, hTestService;
+// Service functions declarated in service.cpp
+extern int ShowSplashService(WPARAM wparam,LPARAM lparam);
+#ifdef _DEBUG
+extern int TestService(WPARAM wParam,LPARAM lParam);
+#endif
+
+extern BOOL (WINAPI *MyUpdateLayeredWindow)
+ (HWND hwnd, HDC hdcDST, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc,
+ COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags);
+extern HWND hwndSplash;
+
+PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+ #ifndef _DEBUG
+ "Splash Screen",
+ #else
+ "Splash Screen (Debug)",
+ #endif
+ __VERSION_DWORD,
+ "Shows a splash at Miranda startup",
+ "nullbie, Thief",
+ "thief@miranda.im",
+ "2004-2007 Victor Pavlychko, 2005-2010 Alexander Turyak ["BuildDate"]",
+ "http://addons.miranda-im.org/details.php?id=2624",
+ 0, //not transient
+ 0, //doesn't replace anything built-in
+ {0xc64cc8e0, 0xcf03, 0x474a, {0x8b, 0x11, 0x8b, 0xd4, 0x56, 0x5c, 0xcf, 0x04}} /* C64CC8E0-CF03-474A-8B11-8BD4565CC */
+};
+
+PLUGININFO oldpluginInfo={
+ sizeof(PLUGININFO),
+ pluginInfo.shortName,
+ pluginInfo.version,
+ pluginInfo.description,
+ pluginInfo.author,
+ pluginInfo.authorEmail,
+ pluginInfo.copyright,
+ pluginInfo.homepage,
+ pluginInfo.flags,
+ pluginInfo.replacesDefaultModule
+};
+
+/* 91CB1E8D-C33C-43C0-BDD8-6725B070B3E0 */
+#define MIID_SPLASHSCREEN {0x91cb1e8d, 0xc33c, 0x43c0, {0xbd, 0xd8, 0x67, 0x25, 0xb0, 0x70, 0xb3, 0xe0}}
+
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ static const MUUID interfaces[] = {MIID_SPLASHSCREEN, MIID_LAST};
+ return interfaces;
+}
+
+HANDLE hSplashThread, hModulesLoaded, hPlugDisableHook, hOptInit, hSystemOKToExit;
+LRESULT CALLBACK SplashWindowProc(HWND, UINT, WPARAM, LPARAM);
+int ModulesLoaded(WPARAM wParam,LPARAM lParam);
+int PlugDisableHook(WPARAM wParam,LPARAM lParam);
+int onSystemOKToExit(WPARAM wParam,LPARAM lParam);
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ hInst = hinstDLL;
+ return TRUE;
+}
+
+void SplashMain()
+{
+if (bstartup)
+{
+ DWORD unused;
+ DWORD verInfoSize;
+ UINT blockSize;
+
+ // Retrive path to exe of current running Miranda is located
+ GetModuleFileName(GetModuleHandle(NULL), szMirDir, sizeof(szMirDir));
+
+ verInfoSize = GetFileVersionInfoSizeA(szMirDir,&unused);
+ pVerInfo = /*mir_*/malloc(verInfoSize);
+ GetFileVersionInfoA(szMirDir,0,verInfoSize,pVerInfo);
+ VerQueryValueA(pVerInfo,"\\StringFileInfo\\000004b0\\ProductVersion",(PVOID*)&mirandaVerString,&blockSize);
+
+ // Remove 'miranda32.exe' from string
+ char *pos;
+ pos = strrchr(szMirDir, '\\');
+ if(pos != NULL) *pos = 0;
+ lstrcat(szMirDir,"\\");
+
+ // Get the name string of plugin's dll name whatever it named
+ static char* sztmpstr;
+ GetModuleFileName(hInst, szDllName, sizeof(szDllName));
+ sztmpstr = _strrev(szDllName);
+ pos = strchr(sztmpstr, '\\');
+ if(pos != NULL) *pos = 0;
+ strcpy(szDllName, _strrev(sztmpstr));
+
+ static char szPath[MAX_PATH];
+
+ lstrcat(szPath,szMirDir);
+ lstrcat(szPath,"plugins\\splash.ini");
+ lstrcat(szhAdvaimgPath,szMirDir);
+ lstrcat(szhAdvaimgPath,"plugins\\advaimg.dll");
+
+ #ifdef _DEBUG
+ lstrcat(szLogFile,szMirDir);
+ lstrcat(szLogFile,PlugName);
+ lstrcat(szLogFile,".log");
+ #endif
+
+ #ifdef _DEBUG
+ initLog();
+ logTimeStamp();
+ #endif
+
+ #ifdef _DEBUG
+ logMessage("Miranda version", mirandaVerString);
+ #endif
+
+ static char szMirandaBootIni[MAX_PATH];
+ lstrcat(szMirandaBootIni,szMirDir);
+ lstrcat(szMirandaBootIni,"mirandaboot.ini");
+ GetPrivateProfileString("Splash","Ini","",inBuf,sizeof(inBuf),szMirandaBootIni);
+ if (strlen(inBuf))
+ {
+ char szExpandedIniPath[MAX_PATH];
+ ExpandEnvironmentStringsA(inBuf, szExpandedIniPath,sizeof(szExpandedIniPath));
+ lstrcat(szIniFile,szExpandedIniPath);
+ }
+ else
+ {
+ FILE *fp;
+ fp = fopen(szPath, "r");
+ if (!fp)
+ {
+ #ifdef _DEBUG
+ logMessage("error! couldn't open", szPath);
+ #endif
+
+ lstrcat(szIniFile,szMirDir);
+ lstrcat(szIniFile,"mirandaboot.ini");
+ }
+ else
+ {
+ lstrcat(szIniFile,szPath);
+ fclose(fp);
+ }
+ }
+
+ ReadIniConfig();
+
+ #ifdef _DEBUG
+ logMessage("Dll Name", szDllName);
+ logMessage("Ini path",szIniFile);
+ logMessage("Advaimg path", szhAdvaimgPath);
+ #endif
+}
+
+if (bstartup & (options.active == 1)) {
+
+ if (options.runonce)
+ {
+ WritePrivateProfileString("Splash","Active","0",szIniFile);
+ WritePrivateProfileString("Splash","DisableAfterStartup","0",szIniFile);
+ }
+
+ if (hUserDll == NULL)
+ {
+ hUserDll = LoadLibrary("user32.dll");
+ if (hUserDll)
+ {
+ MyUpdateLayeredWindow = (BOOL (WINAPI *)(HWND, HDC, POINT *, SIZE *, HDC, POINT *, COLORREF, BLENDFUNCTION *, DWORD))GetProcAddress(hUserDll, "UpdateLayeredWindow");
+ }
+ }
+
+ if (hAdvaimg == NULL)
+ {
+ hAdvaimg = LoadLibrary(szhAdvaimgPath);
+ if (hAdvaimg == NULL)
+ {
+ png2dibavail = false;
+ bstartup = false;
+ }
+ if (hAdvaimg)
+ {
+ png2dibConvertor = (pfnConvertPng2dib) GetProcAddress(hAdvaimg, "mempng2dib");
+ if (png2dibConvertor == NULL)
+ {
+ FreeLibrary(hAdvaimg); hAdvaimg = NULL;
+ MessageBoxA(NULL,
+ "Your advaimg.dll is either obsolete or damaged. Get latest from Miranda alpha builds.",
+ "Error",
+ MB_OK | MB_ICONSTOP);
+ }
+ #ifdef _DEBUG
+ if (png2dibConvertor) logMessage("Loading advaimg","done");
+ #endif
+ }
+ }
+
+ //for 9x "alfa" testing
+ //MyUpdateLayeredWindow = 0;
+
+ GetPrivateProfileString("Splash","VersionPrefix","",inBuf,sizeof(inBuf),szIniFile);
+ strcpy(szPrefix,inBuf);
+
+ GetPrivateProfileString("Splash","Path","splash\\splash.png",inBuf,sizeof(inBuf),szIniFile);
+
+ char szExpandedSplashFile[MAX_PATH];
+ ExpandEnvironmentStringsA(inBuf, szExpandedSplashFile,sizeof(szExpandedSplashFile));
+ lstrcpy(inBuf, szExpandedSplashFile);
+
+ char *pos3 = 0;
+ pos3 = strrchr(inBuf, ':');
+ if (pos3 == NULL)
+ {
+ lstrcpy(szSplashFile, szMirDir);
+ }
+
+ lstrcat(szSplashFile, inBuf);
+
+ GetPrivateProfileString("Splash","Sound","sounds\\startup.wav",inBuf,sizeof(inBuf),szIniFile);
+
+ char szExpandedSoundFile[MAX_PATH];
+ ExpandEnvironmentStringsA(inBuf, szExpandedSoundFile,sizeof(szExpandedSoundFile));
+ lstrcpy(inBuf, szExpandedSoundFile);
+
+ char *pos2;
+ pos2 = strchr(inBuf, ':');
+ if (pos2 == NULL)
+ {
+ lstrcat(szSoundFile, szMirDir);
+ }
+
+ lstrcat(szSoundFile, inBuf);
+
+ #ifdef _DEBUG
+ logMessage("SoundFilePath",szSoundFile);
+ #endif
+
+ char szOldPath[MAX_PATH] = {0};
+
+ if(options.random) // randomly select a splash file
+ {
+ int filescount = 0;
+ char szSplashDir[MAX_PATH] = {0}, szSearch[MAX_PATH] = {0};
+ char* p = 0;
+ char files [255][50]; //TODO: make memory allocation dynamic
+
+ lstrcpy(szSplashDir, szSplashFile);
+ lstrcpy(szOldPath, szSplashFile);
+ // find the last \ and null it out, this leaves no trailing slash
+ p = strrchr(szSplashDir, '\\');
+ if (p) *p = 0;
+ // create the search filter
+ mir_snprintf(szSearch,sizeof(szSearch),"%s\\*.*", szSplashDir);
+ // FFFN will return filenames
+ HANDLE hFind = INVALID_HANDLE_VALUE;
+ WIN32_FIND_DATAA ffd;
+ hFind = FindFirstFileA(szSearch, &ffd);
+ if ( hFind != INVALID_HANDLE_VALUE )
+ {
+ do
+ {
+ if (!(ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
+ {
+ #ifdef _DEBUG
+ logMessage("Found file",ffd.cFileName);
+ #endif
+ //files = new char[strlen(ffd.cFileName)];
+ //files[filescount] = new char[strlen(ffd.cFileName)];
+ char ext[5];
+ memcpy(ext,ffd.cFileName+(strlen(ffd.cFileName)-4),5);
+
+ #ifdef _DEBUG
+ logMessage("Extention",ext);
+ #endif
+
+ if (lstrcmpi(ext,".png") & lstrcmpi(ext,".bmp"))
+ continue;
+
+ #ifdef _DEBUG
+ logMessage("File has valid ext",ext);
+ #endif
+ strcpy(files[filescount++],ffd.cFileName);
+ } //if
+ } while (FindNextFileA(hFind, &ffd));
+
+ srand((unsigned) time(NULL));
+ int r = 0;
+ if (filescount) r = (rand() % filescount) + 1;
+
+ ZeroMemory(&szSplashFile,sizeof(szSplashFile));
+ lstrcpy(szSplashFile, szSplashDir);
+ lstrcat(szSplashFile,"\\");
+ lstrcat(szSplashFile,files[r-1]);
+
+ #ifdef _DEBUG
+ logMessage("final file",szSplashFile);
+ #endif
+ FindClose(hFind);
+ } //if
+ }
+
+ // Call splash display routine
+ ShowSplash(false);
+
+ if (options.random)
+ {
+ ZeroMemory(&szSplashFile,sizeof(szSplashFile));
+ lstrcpy(szSplashFile, szOldPath);
+ }
+
+ }
+ bstartup = false;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ SplashMain();
+ return &pluginInfo;
+}
+
+extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ SplashMain();
+ return &oldpluginInfo;
+}
+
+extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ pluginLink = link;
+
+ hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
+ hSystemOKToExit = HookEvent(ME_SYSTEM_OKTOEXIT,onSystemOKToExit);
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ free(pVerInfo);
+
+ if (hSplashThread) CloseHandle(hSplashThread);
+
+ UnregisterClass(SPLASH_CLASS, hInst);
+
+ // Freeing loaded libraries
+ if (hUserDll) FreeLibrary(hUserDll);
+ if (hAdvaimg) FreeLibrary(hAdvaimg);
+
+ #ifdef _DEBUG
+ logMessage("Unload","Job done");
+ #endif
+
+ return 0;
+}
+
+int onSystemOKToExit(WPARAM wParam,LPARAM lParam)
+{
+ // Hooked events need to be unhooked
+ UnhookEvent(hModulesLoaded);
+ UnhookEvent(hSystemOKToExit);
+ UnhookEvent(hPlugDisableHook);
+ UnhookEvent(hOptInit);
+
+ DestroyServiceFunction(hShowSplashService);
+ #ifdef _DEBUG
+ DestroyServiceFunction(hTestService);
+ #endif
+
+ return 0;
+}
+
+int ModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ bmodulesloaded = true; // all modules are loaded now, let other parts know about this fact
+
+ if (hwndSplash)
+ {
+ if (PostMessage(hwndSplash, WM_LOADED, 0, 0))
+ {
+ #ifdef _DEBUG
+ logMessage("Posted WM_LOADED message","done");
+ #endif
+ }
+ }
+
+ // Options initialize hook
+ hOptInit = HookEvent(ME_OPT_INITIALISE, OptInit);
+
+ hPlugDisableHook = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, PlugDisableHook);
+
+ // Service to call splash
+ hShowSplashService = CreateServiceFunction(MS_SHOWSPLASH, ShowSplashService);
+
+ #ifdef _DEBUG
+ hTestService = CreateServiceFunction("Splash/Test",TestService);
+ CLISTMENUITEM mi;
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.flags = 0;
+ mi.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ mi.hotKey = 0;
+ mi.position = -0x7FFFFFFF;
+ mi.pszName = "Call Splash Service";
+ mi.pszService = "Splash/Test";
+
+ CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+ #endif
+
+ if (ServiceExists(MS_UPDATE_REGISTER))
+ {
+ // register with updater
+ Update update = {0};
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(pluginInfo.version, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ update.szUpdateURL = UPDATER_AUTOREGISTER;
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+ update.szBetaUpdateURL = "http://thief.miranda.im/advsplashscreen.zip";
+ update.szBetaVersionURL = "http://thief.miranda.im/updater/splash_version.txt";
+ update.szBetaChangelogURL = "http://thief.miranda.im";
+ update.pbBetaVersionPrefix = (BYTE *)"Splash Screen ";
+
+ update.cpbBetaVersionPrefix = strlen((char *)update.pbBetaVersionPrefix);
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+ }
+
+ #ifdef _DEBUG
+ logMessage("Loading modules","done");
+ #endif
+
+ return 0;
+}
+
+int PlugDisableHook(WPARAM wParam, LPARAM lParam)
+{
+ char buf [128];
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
+ if(options.inheritGS)
+ if (!lstrcmp(cws->szModule,"Skin") & !lstrcmp(cws->szSetting,"UseSound"))
+ {
+ sprintf(buf,"%d",cws->value.bVal);
+ WritePrivateProfileString("Splash","PlaySound",buf,szIniFile);
+ #ifdef _DEBUG
+ cws->value.bVal ? _DebugPopup(NULL, "Sounds enabled.", "") : _DebugPopup(NULL, "Sounds disabled.", "");
+ logMessage("Module",cws->szModule);
+ logMessage("Setting",cws->szSetting);
+ logMessage("Value",buf);
+ #endif
+ }
+ if (!lstrcmp(cws->szModule,"PluginDisable") & (!lstrcmp(cws->szSetting,szDllName)))
+ {
+ sprintf(buf,"%d",!cws->value.bVal);
+ WritePrivateProfileString("Splash","Active",buf,szIniFile);
+
+ #ifdef _DEBUG
+ cws->value.bVal ? _DebugPopup(NULL, "Disabled.", "") : _DebugPopup(NULL, "Enabled.", "");
+ logMessage("PlugDisableHook","Triggered");
+ logMessage("Module",cws->szModule);
+ logMessage("Setting",cws->szSetting);
+ logMessage("Value",buf);
+ #endif
+ }
+
+ return 0;
+}