diff options
Diffstat (limited to 'fddnotify')
-rw-r--r-- | fddnotify/AggressiveOptimize.h | 165 | ||||
-rw-r--r-- | fddnotify/EnumProc.c | 255 | ||||
-rw-r--r-- | fddnotify/EnumProc.h | 27 | ||||
-rw-r--r-- | fddnotify/PTInstaller/PT-Installer.c | 62 | ||||
-rw-r--r-- | fddnotify/PTInstaller/PortTalk_IOCTL.h | 37 | ||||
-rw-r--r-- | fddnotify/PTInstaller/pt_ioctl.c | 249 | ||||
-rw-r--r-- | fddnotify/PortTalk_IOCTL.h | 37 | ||||
-rw-r--r-- | fddnotify/constants.h | 62 | ||||
-rw-r--r-- | fddnotify/docs/fddnotify_readme.txt | 154 | ||||
-rw-r--r-- | fddnotify/docs/fddnotify_translation.txt | 168 | ||||
-rw-r--r-- | fddnotify/fdd.c | 81 | ||||
-rw-r--r-- | fddnotify/fdd.h | 21 | ||||
-rw-r--r-- | fddnotify/m_fddnotify.h | 57 | ||||
-rw-r--r-- | fddnotify/main.c | 1203 | ||||
-rw-r--r-- | fddnotify/options.c | 785 | ||||
-rw-r--r-- | fddnotify/protolist.h | 28 | ||||
-rw-r--r-- | fddnotify/resource.h | 65 | ||||
-rw-r--r-- | fddnotify/resources.rc | 238 |
18 files changed, 3694 insertions, 0 deletions
diff --git a/fddnotify/AggressiveOptimize.h b/fddnotify/AggressiveOptimize.h new file mode 100644 index 0000000..34c6074 --- /dev/null +++ b/fddnotify/AggressiveOptimize.h @@ -0,0 +1,165 @@ +//////////////////////////////
+// Version 1.40
+// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support!
+// Version 1.30
+// Nov 24th, 2000
+// Version 1.20
+// Jun 9th, 2000
+// Version 1.10
+// Jan 23rd, 2000
+// Version 1.00
+// May 20th, 1999
+// Todd C. Wilson, Fresh Ground Software
+// (todd@nopcode.com)
+// This header file will kick in settings for Visual C++ 5 and 6 that will (usually)
+// result in smaller exe's.
+// The "trick" is to tell the compiler to not pad out the function calls; this is done
+// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads
+// out each and every function call. In one single 500k dll, I managed to cut out 120k
+// by this alone!
+// The other two "tricks" are telling the Linker to merge all data-type segments together
+// in the exe file. The relocation, read-only (constants) data, and code section (.text)
+// sections can almost always be merged. Each section merged can save 4k in exe space,
+// since each section is padded out to 4k chunks. This is very noticeable with smaller
+// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of
+// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger
+// programs, this is less overall, but can save at least 4k.
+// Note that if you're using MFC static or some other 3rd party libs, you may get poor
+// results with merging the readonly (.rdata) section - the exe may grow larger.
+// To use this feature, define _MERGE_RDATA_ in your project or before this header is used.
+// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results
+// in a small exe. Under VC6, the program instead uses 4k, which is the same as the
+// section size. The reason (from what I understand) is that 4k is the chunk size of
+// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98)
+// will re-align the programs on this boundary. The problem with this is that all of
+// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious
+// exe bloat. This is very noticeable for smaller programs.
+// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the
+// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75%
+// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is*
+// a previously documented switch, but was left out of the docs for some reason in VC6 and
+// all of the current MSDN's - see KB:Q235956 for more information.
+// Microsoft does say that using the 4k alignment will "speed up process loading",
+// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe.
+// Please note, however, that this will probably not change the size of the COMPRESSED
+// file (either in a .zip file or in an install archive), since this 4k is all zeroes and
+// gets compressed away.
+// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the
+// default setting for this switch. Apparently this sets the same values as the above two
+// switches do. We do not use this in this header, since it smacks of a bug and not a feature.
+// Thanks to Michael Geary <Mike@Geary.com> for some additional tips!
+//
+// Notes about using this header in .NET
+// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no
+// honest or good reason why Microsoft decided to make this change, it just doesn't.
+// So that is why there are a lot of <1300 #if's in the header.
+// If you want to take full advantage of the VC7 linker options, you will need to do it on a
+// PER PROJECT BASIS; you can no longer use a global header file like this to make it better.
+// Items I strongly suggest putting in all your VC7 project linker options command line settings:
+// /ignore:4078 /RELEASE
+// Compiler options:
+// /GL (Whole Program Optimization)
+// If you're making an .EXE and not a .DLL, consider adding in:
+// /GA (Optimize for Windows Application)
+// Some items to consider using in your VC7 projects (not VC6):
+// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings.
+// /LTCG:NOSTATUS
+// The classic no-padding and no-bloat compiler C/C++ switch:
+// /opt:nowin98
+//
+// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files)
+// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS)
+//
+// Now, notes on using these options in VC7 vs VC6.
+// VC6 consistently, for me, produces smaller code from C++ the exact same sources,
+// with or without this header. On average, VC6 produces 5% smaller binaries compared
+// to VC7 compiling the exact same project, *without* this header. With this header, VC6
+// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and
+// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting
+// in the way of code generation. However, template support is better, so there.
+// Both VC6 and VC7 show the same end kind of end result savings - larger binary output
+// will shave about 2% off, where as smaller projects (support DLL's, cpl's,
+// activex controls, ATL libs, etc) get the best result, since the padding is usually
+// more than the actual usable code. But again, VC7 does not compile down as small as VC6.
+//
+// The argument can be made that doing this is a waste of time, since the "zero bytes"
+// will be compressed out in a zip file or install archive. Not really - it doesn't matter
+// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes
+// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to
+// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the
+// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're
+// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with
+// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all
+// worthy developers have (all six of us), so they will need any space and LOADING TIME
+// savings they will need; taking an extra 32k or more out of your end user's 64megs of
+// ram on Windows 98 is Not a Good Thing.
+//
+// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data
+// pragma will cause the output file to be un-disassembleable! (is that a word?) At least,
+// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the
+// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code!
+// Thanks to Gëzim Pani <gpani@siu.edu> for discovering this gem - for a full writeup on
+// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize
+// article.
+
+#ifndef _AGGRESSIVEOPTIMIZE_H_
+#define _AGGRESSIVEOPTIMIZE_H_
+
+#pragma warning(disable:4711)
+
+#ifdef NDEBUG
+// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers)
+#pragma optimize("gsy",on)
+
+#if (_MSC_VER<1300)
+ #pragma comment(linker,"/RELEASE")
+#endif
+
+// Note that merging the .rdata section will result in LARGER exe's if you using
+// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project.
+//#ifdef _MERGE_RDATA_
+//#pragma comment(linker,"/merge:.rdata=.data")
+//#endif // _MERGE_RDATA_
+
+//#pragma comment(linker,"/merge:.text=.data")
+//#if (_MSC_VER<1300)
+ // In VC7, this causes problems with the relocation and data tables, so best to not merge them
+// #pragma comment(linker,"/merge:.reloc=.data")
+//#endif
+
+// Merging sections with different attributes causes a linker warning, so
+// turn off the warning. From Michael Geary. Undocumented, as usual!
+#if (_MSC_VER<1300)
+ // In VC7, you will need to put this in your project settings
+ #pragma comment(linker,"/ignore:4078")
+#endif
+
+// With Visual C++ 5, you already get the 512-byte alignment, so you will only need
+// it for VC6, and maybe later.
+#if _MSC_VER >= 1000
+
+// Option #1: use /filealign
+// Totally undocumented! And if you set it lower than 512 bytes, the program crashes.
+// Either leave at 0x200 or 0x1000
+//#pragma comment(linker,"/FILEALIGN:0x200")
+
+// Option #2: use /opt:nowin98
+// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one.
+// This is our currently preferred option, since it is fully documented and unlikely
+// to break in service packs and updates.
+#if (_MSC_VER<1300)
+ // In VC7, you will need to put this in your project settings
+ #pragma comment(linker,"/opt:nowin98")
+#else
+
+// Option #3: use /align:4096
+// A side effect of using the default align value is that it turns on the above switch.
+// Does nothing under Vc7 that /opt:nowin98 doesn't already give you
+// #pragma comment(linker,"/ALIGN:512")
+#endif
+
+#endif // _MSC_VER >= 1000
+
+#endif // NDEBUG
+
+#endif // _AGGRESSIVEOPTIMIZE_H_
diff --git a/fddnotify/EnumProc.c b/fddnotify/EnumProc.c new file mode 100644 index 0000000..df08562 --- /dev/null +++ b/fddnotify/EnumProc.c @@ -0,0 +1,255 @@ +/*
+
+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.
+
+*/
+
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+#include <stdio.h>
+#include <tlhelp32.h>
+#include <vdmdbg.h>
+#include "EnumProc.h"
+
+
+BOOL findFilename(char *);
+char *filename(char *);
+BOOL WINAPI Enum16(DWORD, WORD, WORD, char *, char *, LPARAM);
+
+
+// Globals
+extern double dWinVer;
+extern BOOL bWindowsNT;
+extern PROCESS_LIST ProcessList;
+
+HINSTANCE hInstLib, hInstLib2;
+HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD, DWORD);
+BOOL (WINAPI *lpfProcess32First)(HANDLE, LPPROCESSENTRY32);
+BOOL (WINAPI *lpfProcess32Next)(HANDLE, LPPROCESSENTRY32);
+BOOL (WINAPI *lpfEnumProcesses)(DWORD *, DWORD, DWORD *);
+BOOL (WINAPI *lpfEnumProcessModules)(HANDLE, HMODULE *, DWORD, LPDWORD);
+DWORD (WINAPI *lpfGetModuleBaseName)(HANDLE, HMODULE, LPTSTR, DWORD);
+INT (WINAPI *lpfVDMEnumTaskWOWEx)(DWORD, TASKENUMPROCEX, LPARAM);
+
+
+void LoadProcsLibrary(void)
+{
+ if (bWindowsNT && dWinVer < 5) {
+
+ if (!(hInstLib = LoadLibraryA("PSAPI.DLL")))
+ return;
+
+ if (!(hInstLib2 = LoadLibraryA("VDMDBG.DLL")))
+ return;
+
+ lpfEnumProcesses = (BOOL (WINAPI *)(DWORD *, DWORD, DWORD*)) GetProcAddress(hInstLib, "EnumProcesses");
+ lpfEnumProcessModules = (BOOL (WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress(hInstLib, "EnumProcessModules");
+ lpfGetModuleBaseName = (DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD)) GetProcAddress(hInstLib, "GetModuleBaseNameA");
+
+ lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX, LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx");
+ } else {
+
+ if(!(hInstLib = LoadLibraryA("Kernel32.DLL")))
+ return;
+
+ if (bWindowsNT && !(hInstLib2 = LoadLibraryA("VDMDBG.DLL")))
+ return;
+
+ lpfCreateToolhelp32Snapshot = (HANDLE (WINAPI *)(DWORD,DWORD)) GetProcAddress(hInstLib, "CreateToolhelp32Snapshot");
+ lpfProcess32First = (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress(hInstLib, "Process32First");
+ lpfProcess32Next = (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress(hInstLib, "Process32Next");
+
+ if (bWindowsNT)
+ lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX, LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx");
+ }
+}
+
+
+void UnloadProcsLibrary(void)
+{
+ if (hInstLib)
+ FreeLibrary(hInstLib);
+ if (hInstLib2)
+ FreeLibrary(hInstLib2);
+
+ hInstLib = hInstLib = NULL;
+ lpfCreateToolhelp32Snapshot = NULL;
+ lpfProcess32First = (void *)lpfProcess32Next = (void *)lpfEnumProcesses = (void *)lpfEnumProcessModules = (void *)lpfGetModuleBaseName = (void *)lpfVDMEnumTaskWOWEx = NULL;
+}
+
+
+BOOL areThereProcessesRunning(void)
+{
+ HANDLE hSnapShot = NULL;
+ LPDWORD lpdwPIDs = NULL;
+ PROCESSENTRY32 procentry;
+ BOOL bFlag;
+ DWORD dwSize;
+ DWORD dwSize2;
+ DWORD dwIndex;
+ HMODULE hMod;
+ HANDLE hProcess;
+ char szFileName[MAX_PATH+1];
+
+
+ if (!ProcessList.count) // Process list is empty
+ return FALSE;
+
+ // If Windows NT 4.0
+ if (bWindowsNT && dWinVer < 5) {
+
+ if (!lpfEnumProcesses || !lpfEnumProcessModules || !lpfGetModuleBaseName || !lpfVDMEnumTaskWOWEx)
+ return FALSE;
+
+ //
+ // Call the PSAPI function EnumProcesses to get all of the ProcID's currently in the system.
+ //
+ // NOTE: In the documentation, the third parameter of EnumProcesses is named cbNeeded, which implies that you
+ // can call the function once to find out how much space to allocate for a buffer and again to fill the buffer.
+ // This is not the case. The cbNeeded parameter returns the number of PIDs returned, so if your buffer size is
+ // zero cbNeeded returns zero.
+ //
+ // NOTE: The "HeapAlloc" loop here ensures that we actually allocate a buffer large enough for all the
+ // PIDs in the system.
+ //
+ dwSize2 = 256 * sizeof(DWORD);
+ do {
+ if (lpdwPIDs) {
+ HeapFree(GetProcessHeap(), 0, lpdwPIDs);
+ dwSize2 *= 2;
+ }
+ if (!(lpdwPIDs = (LPDWORD)HeapAlloc(GetProcessHeap(), 0, dwSize2)))
+ return FALSE;
+ if (!lpfEnumProcesses(lpdwPIDs, dwSize2, &dwSize)) {
+ HeapFree(GetProcessHeap(), 0, lpdwPIDs);
+ return FALSE;
+ }
+ } while (dwSize == dwSize2);
+
+ // How many ProcID's did we get?
+ dwSize /= sizeof(DWORD);
+
+ // Loop through each ProcID.
+ for (dwIndex = 0; dwIndex < dwSize; dwIndex++) {
+ char *szFileNameAux;
+ szFileName[0] = '\0';
+
+ // Open the process (if we can... security does not permit every process in the system to be opened).
+ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, lpdwPIDs[dwIndex]);
+ if (hProcess) {
+ // Here we call EnumProcessModules to get only the first module in the process. This will be the
+ // EXE module for which we will retrieve the name.
+ if (lpfEnumProcessModules(hProcess, &hMod, sizeof(hMod), &dwSize2)) {
+ // Get the module name
+ if (!lpfGetModuleBaseName(hProcess, hMod, szFileName, sizeof(szFileName)))
+ szFileName[0] = '\0';
+ }
+ CloseHandle(hProcess);
+ }
+ szFileNameAux = filename(szFileName);
+
+ // Search szFileName in user-defined list
+ if (findFilename(szFileNameAux)) {
+ HeapFree(GetProcessHeap(), 0, lpdwPIDs);
+ return TRUE;
+ }
+
+ // Did we just bump into an NTVDM?
+ if (!_stricmp(szFileNameAux, "NTVDM.EXE")) {
+ BOOL bFound = FALSE;
+
+ // Enum the 16-bit stuff.
+ lpfVDMEnumTaskWOWEx(lpdwPIDs[dwIndex], (TASKENUMPROCEX) Enum16, (LPARAM)&bFound);
+
+ // Did we find any user-defined process?
+ if (bFound) {
+ HeapFree(GetProcessHeap(), 0, lpdwPIDs);
+ return TRUE;
+ }
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, lpdwPIDs);
+
+ // If any OS other than Windows NT 4.0.
+ } else {
+
+ if (!lpfProcess32Next || !lpfProcess32First || !lpfCreateToolhelp32Snapshot)
+ return FALSE;
+
+ // Get a handle to a Toolhelp snapshot of all processes.
+ if ((hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ // While there are processes, keep looping.
+ for (procentry.dwSize=sizeof(PROCESSENTRY32), bFlag=lpfProcess32First(hSnapShot, &procentry); bFlag; procentry.dwSize=sizeof(PROCESSENTRY32), bFlag=lpfProcess32Next(hSnapShot, &procentry)) {
+ char *szFileNameAux = filename(procentry.szExeFile);
+
+ // Search szFileName in user-defined list
+ if (findFilename(szFileNameAux))
+ return TRUE;
+
+ // Did we just bump into an NTVDM?
+ if (lpfVDMEnumTaskWOWEx && !_stricmp(szFileNameAux, "NTVDM.EXE")) {
+ BOOL bFound = FALSE;
+
+ // Enum the 16-bit stuff.
+ lpfVDMEnumTaskWOWEx(procentry.th32ProcessID, (TASKENUMPROCEX)Enum16, (LPARAM)&bFound);
+
+ // Did we find any user-defined process?
+ if (bFound)
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+BOOL WINAPI Enum16(DWORD dwThreadId, WORD hMod16, WORD hTask16, char *szModName, char *szFileName, LPARAM lpUserDefined)
+{
+ BOOL bRet;
+ BOOL *pbFound = (BOOL *)lpUserDefined;
+
+ if ((bRet = findFilename(filename(szFileName))))
+ *pbFound = TRUE;
+
+ return bRet;
+}
+
+
+BOOL findFilename(char *fileName)
+{
+ unsigned int i;
+
+ for (i=0; i < ProcessList.count; i++)
+ if (ProcessList.szFileName[i] && !_stricmp(ProcessList.szFileName[i], fileName))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+char *filename(char *fullFileName)
+{
+ char *str;
+
+ str = strrchr(fullFileName, '\\');
+ if (!str)
+ return fullFileName;
+
+ return ++str;
+}
\ No newline at end of file diff --git a/fddnotify/EnumProc.h b/fddnotify/EnumProc.h new file mode 100644 index 0000000..f7e6a42 --- /dev/null +++ b/fddnotify/EnumProc.h @@ -0,0 +1,27 @@ +/*
+
+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.
+
+*/
+
+typedef struct {
+ unsigned int count;
+ char **szFileName;
+} PROCESS_LIST;
+
+
+void LoadProcsLibrary(void);
+void UnloadProcsLibrary(void);
+BOOL areThereProcessesRunning(void);
diff --git a/fddnotify/PTInstaller/PT-Installer.c b/fddnotify/PTInstaller/PT-Installer.c new file mode 100644 index 0000000..4010331 --- /dev/null +++ b/fddnotify/PTInstaller/PT-Installer.c @@ -0,0 +1,62 @@ +#include <windows.h>
+#include <stdio.h>
+#include "pt_ioctl.c"
+
+HANDLE hPortTalk;
+
+BOOL isWindowsNT(void)
+{
+ OSVERSIONINFOEX osvi;
+ BOOL bOsVersionInfoEx;
+
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi))) {
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ if(!GetVersionEx((OSVERSIONINFO *)&osvi))
+ osvi.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
+ }
+ return osvi.dwPlatformId==VER_PLATFORM_WIN32_NT;
+}
+
+void AddKeysToRegistry(void)
+{
+ HKEY hk;
+ DWORD dwData;
+ LPTSTR pszData = "PortTalk";
+
+
+ if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PortTalk", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hk, NULL))
+ return;
+
+ dwData = 1;
+ RegSetValueEx(hk, "Type", 0, REG_DWORD, (LPBYTE)&dwData, sizeof(DWORD));
+
+ dwData = 1;
+ RegSetValueEx(hk, "ErrorControl", 0, REG_DWORD, (LPBYTE)&dwData, sizeof(DWORD));
+
+ dwData = 2;
+ RegSetValueEx(hk, "Start", 0, REG_DWORD, (LPBYTE)&dwData, sizeof(DWORD));
+
+ RegSetValueEx(hk, "DisplayName", 0, REG_EXPAND_SZ, (LPBYTE)pszData, (DWORD)lstrlen(pszData)+1);
+
+ RegCloseKey(hk);
+}
+
+int main(void)
+{
+ if (!isWindowsNT()) {
+ printf("PortTalk cannot be installed on non-NT systems (as a matter of fact you won't need it) :)\n");
+ return 0;
+ }
+
+ if (OpenPortTalk())
+ return 1;
+
+ ClosePortTalk();
+
+ AddKeysToRegistry();
+
+ printf("PortTalk succesful installation\n");
+ return 0;
+}
diff --git a/fddnotify/PTInstaller/PortTalk_IOCTL.h b/fddnotify/PTInstaller/PortTalk_IOCTL.h new file mode 100644 index 0000000..1fe562f --- /dev/null +++ b/fddnotify/PTInstaller/PortTalk_IOCTL.h @@ -0,0 +1,37 @@ +/******************************************************************************/
+/* */
+/* PortTalk Driver for Windows NT/2000/XP */
+/* Version 2.0, 12th January 2002 */
+/* http://www.beyondlogic.org */
+/* */
+/* Copyright © 2002 Craig Peacock. Craig.Peacock@beyondlogic.org */
+/* Any publication or distribution of this code in source form is prohibited */
+/* without prior written permission of the copyright holder. This source code */
+/* is provided "as is", without any guarantee made as to its suitability or */
+/* fitness for any particular use. Permission is herby granted to modify or */
+/* enhance this sample code to produce a derivative program which may only be */
+/* distributed in compiled object form only. */
+/******************************************************************************/
+
+#define PORTTALK_TYPE 40000 /* 32768-65535 are reserved for customers */
+
+// The IOCTL function codes from 0x800 to 0xFFF are for customer use.
+
+#define IOCTL_IOPM_RESTRICT_ALL_ACCESS \
+ CTL_CODE(PORTTALK_TYPE, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_IOPM_ALLOW_EXCUSIVE_ACCESS \
+ CTL_CODE(PORTTALK_TYPE, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_SET_IOPM \
+ CTL_CODE(PORTTALK_TYPE, 0x902, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_ENABLE_IOPM_ON_PROCESSID \
+ CTL_CODE(PORTTALK_TYPE, 0x903, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_READ_PORT_UCHAR \
+ CTL_CODE(PORTTALK_TYPE, 0x904, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_WRITE_PORT_UCHAR \
+ CTL_CODE(PORTTALK_TYPE, 0x905, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
diff --git a/fddnotify/PTInstaller/pt_ioctl.c b/fddnotify/PTInstaller/pt_ioctl.c new file mode 100644 index 0000000..18b9213 --- /dev/null +++ b/fddnotify/PTInstaller/pt_ioctl.c @@ -0,0 +1,249 @@ +/******************************************************************************/
+/* */
+/* IoExample for PortTalk V2.1 */
+/* Version 2.1, 12th January 2002 */
+/* http://www.beyondlogic.org */
+/* */
+/* Copyright © 2002 Craig Peacock. Craig.Peacock@beyondlogic.org */
+/* Any publication or distribution of this code in source form is prohibited */
+/* without prior written permission of the copyright holder. This source code */
+/* is provided "as is", without any guarantee made as to its suitability or */
+/* fitness for any particular use. Permission is herby granted to modify or */
+/* enhance this sample code to produce a derivative program which may only be */
+/* distributed in compiled object form only. */
+/******************************************************************************/
+
+#include <winioctl.h>
+#include "porttalk_IOCTL.h"
+
+unsigned char OpenPortTalk(void);
+void ClosePortTalk(void);
+
+void outportb(unsigned short PortAddress, unsigned char byte);
+unsigned char inportb(unsigned short PortAddress);
+
+void InstallPortTalkDriver(void);
+unsigned char StartPortTalkDriver(void);
+
+#define inp(PortAddress) inportb(PortAddress)
+#define outp(PortAddress, Value) outportb(PortAddress, Value)
+
+HANDLE PortTalk_Handle; /* Handle for PortTalk Driver */
+
+void outportb(unsigned short PortAddress, unsigned char byte)
+{
+ unsigned int error;
+ DWORD BytesReturned;
+ unsigned char Buffer[3];
+ unsigned short * pBuffer;
+ pBuffer = (unsigned short *)&Buffer[0];
+ *pBuffer = PortAddress;
+ Buffer[2] = byte;
+
+ error = DeviceIoControl(PortTalk_Handle,
+ IOCTL_WRITE_PORT_UCHAR,
+ &Buffer,
+ 3,
+ NULL,
+ 0,
+ &BytesReturned,
+ NULL);
+
+ if (!error) printf("Error occured during outportb while talking to PortTalk driver %d\n",GetLastError());
+}
+
+unsigned char inportb(unsigned short PortAddress)
+{
+ unsigned int error;
+ DWORD BytesReturned;
+ unsigned char Buffer[3];
+ unsigned short * pBuffer;
+ pBuffer = (unsigned short *)&Buffer;
+ *pBuffer = PortAddress;
+
+ error = DeviceIoControl(PortTalk_Handle,
+ IOCTL_READ_PORT_UCHAR,
+ &Buffer,
+ 2,
+ &Buffer,
+ 1,
+ &BytesReturned,
+ NULL);
+
+ if (!error) printf("Error occured during inportb while talking to PortTalk driver %d\n",GetLastError());
+ return(Buffer[0]);
+}
+
+unsigned char OpenPortTalk(void)
+{
+ /* Open PortTalk Driver. If we cannot open it, try installing and starting it */
+ PortTalk_Handle = CreateFile("\\\\.\\PortTalk",
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(PortTalk_Handle == INVALID_HANDLE_VALUE) {
+ /* Start or Install PortTalk Driver */
+ StartPortTalkDriver();
+ /* Then try to open once more, before failing */
+ PortTalk_Handle = CreateFile("\\\\.\\PortTalk",
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(PortTalk_Handle == INVALID_HANDLE_VALUE) {
+ printf("PortTalk: Couldn't access PortTalk Driver, Please ensure driver is loaded.\n\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void ClosePortTalk(void)
+{
+ CloseHandle(PortTalk_Handle);
+}
+
+unsigned char StartPortTalkDriver(void)
+{
+ SC_HANDLE SchSCManager;
+ SC_HANDLE schService;
+ BOOL ret;
+ DWORD err;
+
+ /* Open Handle to Service Control Manager */
+ SchSCManager = OpenSCManager (NULL, /* machine (NULL == local) */
+ NULL, /* database (NULL == default) */
+ SC_MANAGER_ALL_ACCESS); /* access required */
+
+ if (SchSCManager == NULL)
+ if (GetLastError() == ERROR_ACCESS_DENIED) {
+ /* We do not have enough rights to open the SCM, therefore we must */
+ /* be a poor user with only user rights. */
+ printf("PortTalk: You do not have rights to access the Service Control Manager and\n");
+ printf("PortTalk: the PortTalk driver is not installed or started. Please ask \n");
+ printf("PortTalk: your administrator to install the driver on your behalf.\n");
+ return(0);
+ }
+
+ do {
+ /* Open a Handle to the PortTalk Service Database */
+ schService = OpenService(SchSCManager, /* handle to service control manager database */
+ "PortTalk", /* pointer to name of service to start */
+ SERVICE_ALL_ACCESS); /* type of access to service */
+
+ if (schService == NULL)
+ switch (GetLastError()){
+ case ERROR_ACCESS_DENIED:
+ printf("PortTalk: You do not have rights to the PortTalk service database\n");
+ return(0);
+ case ERROR_INVALID_NAME:
+ printf("PortTalk: The specified service name is invalid.\n");
+ return(0);
+ case ERROR_SERVICE_DOES_NOT_EXIST:
+ printf("PortTalk: The PortTalk driver does not exist. Installing driver.\n");
+ printf("PortTalk: This can take up to 30 seconds on some machines . .\n");
+ InstallPortTalkDriver();
+ break;
+ }
+ } while (schService == NULL);
+
+ /* Start the PortTalk Driver. Errors will occur here if PortTalk.SYS file doesn't exist */
+
+ ret = StartService (schService, /* service identifier */
+ 0, /* number of arguments */
+ NULL); /* pointer to arguments */
+
+ if (ret) printf("PortTalk: The PortTalk driver has been successfully started.\n");
+ else {
+ err = GetLastError();
+ if (err == ERROR_SERVICE_ALREADY_RUNNING)
+ printf("PortTalk: The PortTalk driver is already running.\n");
+ else {
+ printf("PortTalk: Unknown error while starting PortTalk driver service.\n");
+ printf("PortTalk: Does PortTalk.SYS exist in your \\System32\\Drivers Directory?\n");
+ return(0);
+ }
+ }
+
+ /* Close handle to Service Control Manager */
+ CloseServiceHandle (schService);
+ return(TRUE);
+}
+
+void InstallPortTalkDriver(void)
+{
+ SC_HANDLE SchSCManager;
+ SC_HANDLE schService;
+ DWORD err;
+ CHAR DriverFileName[80];
+
+ /* Get Current Directory. Assumes PortTalk.SYS driver is in this directory. */
+ /* Doesn't detect if file exists, nor if file is on removable media - if this */
+ /* is the case then when windows next boots, the driver will fail to load and */
+ /* a error entry is made in the event viewer to reflect this */
+
+ /* Get System Directory. This should be something like c:\windows\system32 or */
+ /* c:\winnt\system32 with a Maximum Character lenght of 20. As we have a */
+ /* buffer of 80 bytes and a string of 24 bytes to append, we can go for a max */
+ /* of 55 bytes */
+
+ if (!GetSystemDirectory(DriverFileName, 55))
+ {
+ printf("PortTalk: Failed to get System Directory. Is System Directory Path > 55 Characters?\n");
+ printf("PortTalk: Please manually copy driver to your system32/driver directory.\n");
+ }
+
+ /* Append our Driver Name */
+ lstrcat(DriverFileName,"\\Drivers\\PortTalk.sys");
+ printf("PortTalk: Copying driver to %s\n",DriverFileName);
+
+ /* Copy Driver to System32/drivers directory. This fails if the file doesn't exist. */
+
+ if (!CopyFile("PortTalk.sys", DriverFileName, FALSE))
+ {
+ printf("PortTalk: Failed to copy driver to %s\n",DriverFileName);
+ printf("PortTalk: Please manually copy driver to your system32/driver directory.\n");
+ }
+
+ /* Open Handle to Service Control Manager */
+ SchSCManager = OpenSCManager (NULL, /* machine (NULL == local) */
+ NULL, /* database (NULL == default) */
+ SC_MANAGER_ALL_ACCESS); /* access required */
+
+ /* Create Service/Driver - This adds the appropriate registry keys in */
+ /* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services - It doesn't */
+ /* care if the driver exists, or if the path is correct. */
+
+ schService = CreateService (SchSCManager, /* SCManager database */
+ "PortTalk", /* name of service */
+ "PortTalk", /* name to display */
+ SERVICE_ALL_ACCESS, /* desired access */
+ SERVICE_KERNEL_DRIVER, /* service type */
+ SERVICE_DEMAND_START, /* start type */
+ SERVICE_ERROR_NORMAL, /* error control type */
+ "System32\\Drivers\\PortTalk.sys", /* service's binary */
+ NULL, /* no load ordering group */
+ NULL, /* no tag identifier */
+ NULL, /* no dependencies */
+ NULL, /* LocalSystem account */
+ NULL /* no password */
+ );
+
+ if (schService == NULL) {
+ err = GetLastError();
+ if (err == ERROR_SERVICE_EXISTS)
+ printf("PortTalk: Driver already exists. No action taken.\n");
+ else printf("PortTalk: Unknown error while creating Service.\n");
+ }
+ else printf("PortTalk: Driver successfully installed.\n");
+
+ /* Close Handle to Service Control Manager */
+ CloseServiceHandle (schService);
+}
\ No newline at end of file diff --git a/fddnotify/PortTalk_IOCTL.h b/fddnotify/PortTalk_IOCTL.h new file mode 100644 index 0000000..1fe562f --- /dev/null +++ b/fddnotify/PortTalk_IOCTL.h @@ -0,0 +1,37 @@ +/******************************************************************************/
+/* */
+/* PortTalk Driver for Windows NT/2000/XP */
+/* Version 2.0, 12th January 2002 */
+/* http://www.beyondlogic.org */
+/* */
+/* Copyright © 2002 Craig Peacock. Craig.Peacock@beyondlogic.org */
+/* Any publication or distribution of this code in source form is prohibited */
+/* without prior written permission of the copyright holder. This source code */
+/* is provided "as is", without any guarantee made as to its suitability or */
+/* fitness for any particular use. Permission is herby granted to modify or */
+/* enhance this sample code to produce a derivative program which may only be */
+/* distributed in compiled object form only. */
+/******************************************************************************/
+
+#define PORTTALK_TYPE 40000 /* 32768-65535 are reserved for customers */
+
+// The IOCTL function codes from 0x800 to 0xFFF are for customer use.
+
+#define IOCTL_IOPM_RESTRICT_ALL_ACCESS \
+ CTL_CODE(PORTTALK_TYPE, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_IOPM_ALLOW_EXCUSIVE_ACCESS \
+ CTL_CODE(PORTTALK_TYPE, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_SET_IOPM \
+ CTL_CODE(PORTTALK_TYPE, 0x902, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_ENABLE_IOPM_ON_PROCESSID \
+ CTL_CODE(PORTTALK_TYPE, 0x903, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_READ_PORT_UCHAR \
+ CTL_CODE(PORTTALK_TYPE, 0x904, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_WRITE_PORT_UCHAR \
+ CTL_CODE(PORTTALK_TYPE, 0x905, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
diff --git a/fddnotify/constants.h b/fddnotify/constants.h new file mode 100644 index 0000000..e36608c --- /dev/null +++ b/fddnotify/constants.h @@ -0,0 +1,62 @@ +/*
+
+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.
+
+*/
+
+// Settings values
+#define FDDMODULE "fddnotify"
+#define ACTIVE_MIRANDA 0
+#define ACTIVE_WINDOWS 1
+// Until settings map
+#define UNTIL_NBLINKS 1
+#define UNTIL_REATTENDED 2
+#define UNTIL_EVENTSOPEN 4
+#define UNTIL_CONDITIONS 8
+
+// Status map
+#define MAP_ONLINE 1
+#define MAP_AWAY 2
+#define MAP_NA 4
+#define MAP_OCCUPIED 8
+#define MAP_DND 16
+#define MAP_FREECHAT 32
+#define MAP_INVISIBLE 64
+#define MAP_ONTHEPHONE 128
+#define MAP_OUTTOLUNCH 256
+#define MAP_OFFLINE 512
+
+// Default settings
+#define DEF_SETTING_ONMSG 1 // 1: Yes, 0: No
+#define DEF_SETTING_ONURL 1 // 1: Yes, 0: No
+#define DEF_SETTING_ONFILE 1 // 1: Yes, 0: No
+#define DEF_SETTING_OTHER 1 // 1: Yes, 0: No
+#define DEF_SETTING_FSCREEN 1 // 1: Yes, 0: No
+#define DEF_SETTING_SSAVER 1 // 1: Yes, 0: No
+#define DEF_SETTING_LOCKED 1 // 1: Yes, 0: No
+#define DEF_SETTING_PROCS 0 // 1: Yes, 0: No
+#define DEF_SETTING_ACTIVE 1 // 1: Yes, 0: No
+#define DEF_SETTING_IFMSGOPEN 1 // 1: Yes, 0: No
+#define DEF_SETTING_IFMSGNOTTOP 0 // 1: Yes, 0: No
+#define DEF_SETTING_IFMSGOLDER 0 // 1: Yes, 0: No
+#define DEF_SETTING_SECSOLDER 10 // Seconds
+#define DEF_SETTING_FLASHUNTIL 2 // 1 = After x blinks, 2 = Until Miranda/Windows become active, 4 = Events are opened, 8 = Until end of 'notify when' conditions
+#define DEF_SETTING_NBLINKS 4 // Seconds
+#define DEF_SETTING_MIRORWIN 0 // 0-1, 0 = Miranda becomes active, 1 = Windows becomes active
+#define DEF_SETTING_STATUS 1023 // 1023 = All
+#define DEF_SETTING_CHECKTIME 0 // Minutes, 0 = don't check
+#define DEF_SETTING_STARTDELAY 2 // Seconds
+#define DEF_SETTING_FLASHSPEED 1 // 0-5, 0 = really slow, 5 = really fast
+#define DEF_SETTING_PROTOCOL 1 // 1: Yes, 0: No
diff --git a/fddnotify/docs/fddnotify_readme.txt b/fddnotify/docs/fddnotify_readme.txt new file mode 100644 index 0000000..13e9d55 --- /dev/null +++ b/fddnotify/docs/fddnotify_readme.txt @@ -0,0 +1,154 @@ + -================================-
+ FDD Notify plugin for Miranda-IM
+ -================================-
+
+
+Copyright (C) 2005 TioDuke (tioduke@yahoo.ca)
+
+
+Description
+-----------
+This plugin for Miranda-IM notifies user of specified events (as incoming messages, incoming files, incoming URLs or other events). This plugin is based on keyboardnotify by Martin Öberg/Std/TioDuke (me).
+
+It has many options allowing:
+ a) To select on which events to react
+ b) Under which conditions (eg: fullscreen mode, ScreenSaver running, workstation locked)
+ c) To act only if the protocol receiving the event is under specified status
+ d) For message events you can choose to be notified if the message window is open or not
+ e) A notification feature allowing to be notified of pending events (unopened events) after specified period of time
+ f) To select method for stopping the blinking (after x secs, if Miranda is re-attended, if Windows is re-attended, if all notified events are opened or when the notify conditions end)
+ g) To select initial delay and speed and a preview button
+
+It was designed to be flexible and performing different tasks.
+It also provides a service to allow third party plugins use its notifier capabilities.
+
+
+Installation
+------------
+First you have to copy fddnotify.dll into plugins folder. Now, if you are running on a non-NT system (as Windows 98/ME) you are done. If not you will need a driver to use the plugin (if the driver is not installed when running Miranda with this plugin you will receive a message box at startup warning you about it and the plugin will simply do nothing -neither bad nor good-, not even show its option page). To continue with installation you will need two files I have packed inside the zip: porttalk.sys, the driver, and PTInstaller, a console application that will install the driver for you and make it available on system startup (by writing a few settings in Windows' Registry). The plugin won't try to install it: you need the installer (or any other mean) to do that. Take into consideration that you will need administrator rights to install the driver. Now, both the Win98 or the WinNT user will have to restart Miranda and configure the Options the way yhey want. That's it, that's all.
+
+
+Options
+-------
+Options page Options->Plugins->Floppy Flash. Tabbed: Protocols, Rules (when) and Flashing (how).
+
+Here there are some explanations on features on the Options' Page.
+
+Protocols tab:
+Protocols to check: check/uncheck the protocols you want this plugin to work with.
+
+Rules tab:
+Events to react on:
+ - Incoming messages: check this if you want to be notified on incoming message events
+ - Incoming files: check this if you want to be notified on incoming file events
+ - Incoming URLs: check this if you want to be notified on incoming URL events
+ - Everything else: check this if you want to be notified on incoming events that are not messages, files or URLs (like authorization requests or you-were-added events).
+Message event only:
+ - Blink if message window is open: check it if you want to be notified of incoming messages even if that contact's message window is open, if you uncheck it you will only be notified of incoming messages if the window is closed
+ - ... and not in foreground: check this option if you want to be notified if the message window is open and that window is not focused
+ - Only if last is xx seconds old: if you check this option the plugin will not notify you of new messages until xx seconds have passed after the last message for that contact was sent/received
+Notify when:
+ - Full screen mode: check this if you want to be notified when you are on full screen mode (screen saver excluded form the full screen classification, although it is a special type of full screen application)
+ - Screen saver is running: check this if you want to be notified while screen saver is running
+ - Workstation is locked (2000/XP): check this if you want to be notified when your workstation is locked (only for Windows NT systems)
+ - All other situations: check this if you want to be notified when neither you are in full screen mode, nor the screen saver is running and nor the workstation is locked.
+ Note on 'notify when': to be notified on ANY condition (always) you will have to check them all.
+Notify if status is:
+ - Online, Away, NA, etc: check each status for which you want notification to be turn on. Checking all means on all statuses.
+ Note on 'notify if status is ...': The plugin will check these options against the event's protocol status, this means that if you choose to be notified only when you are online and at a certain moment you are online in one protocol but away in another, then you will be notified on events for the first one only.
+Flash until:
+ - nn seconds: if this option is selected leds will flash for the amount of seconds you have specified
+ - Miranda/Windows is re-attended: if this option is selected flashing will stop when either the mouse or a key is pressed on any of Miranda/Windows's windows
+ - Events are opened: if this option is selected flashing will stop when there will be no more pending events (for the selected protocols, of course)
+ - End of 'notify when' conditions: if this option is selected the flashing will stop when all situations checked under 'notify when' (and also the status conditions) ceased to be true.
+ Note on 'End of notify when conditions': this means that if you select ALL the 'notify when' situations and all the statuses (e.g. always) flashing will not stop (you may still stop it manually by pressing the Pause key).
+ This option is particluarly usuful if you want to be notified only when you are in full screen mode (for example) and you want the flashing to stop when you change to non full screen mode. The same applies to all the other situations.
+Pending Events:
+ - Remind me every xx minutes: this option will make the plugin check for unopen events every xx minutes and start notifying if any is found and the 'notify when' and the status conditions are met. If you don't want this option, just specify 0 minutes and it will be disabled.
+ This option is usuful if you, for example, select to be notified on workstation locked and then to stop the flashing using 'end of notify conditions'. If you do not open the event that generated the flashing (e.g. leaving the event pending) then when you lock your computer back the flashing will begin again.
+ Note that if on your messaging plugin you have enabled the option to pop up the message window, then the reminder won't alert you of messages (as they will be promptly opened) but it will still work for files/URLs/others.
+
+Flashing tab:
+Wait before starting flashing:
+ - nn seconds: specify the amount of time for the plugin to wait before starting flashing (0 means do not wait).
+Speed: You may select between 5 different speeds that go from really slow to really fast.
+Preview button: This button will allow you to test your flashing settings. Since v.0.0.1.0 it is an on/off button (thank you tweety for the definition), which means that it will flash when it is on and stop when it is off.
+
+
+Warning
+-------
+Playing with the floppy motor (to turn the led on the plugin turns on and off the motor, led is connected to that function in floppy's architecture) is not a funny thing, so be aware that if you abuse hardware damage could arrive. That's why I recommend you to use a low speed, set maximum time option to stop blinking and use a high delay time (so that, the floppy will blink only on necessary situations).
+Having said that, the only remaining thing to tell is: enjoy!
+
+
+Thanks
+------
+- Pete for the numerous patches he sent, actively helping to improve the code and functionality
+- UnregistereD for great help in solving problem with Windows activity detection
+- Slacktarn, Sir_qwerty and Tweety for giving great help with ideas (most of the new features included in this plugin were suggested by them) and testing
+- The authors of AAA, PopUp+, KeyScrollNotify, original KeyboardNotify, Neweventnotify, IEView, NGEventNotify for part of their code used in this plugin.
+- Miranda IM developers for this amazing program
+- all other people from Miranda community
+
+History
+-------
+0.0.2.2:
+ [!] Fixed problem while trying to detect if message window is in foreground
+ [*] Improved ListView control handling
+ [*] Changed the default values (for the sake of new users)
+ [*] More code optimization.
+0.0.2.1:
+ [+] Support for Update plugin.
+0.0.2.0:
+ [+] New 'notify when' option: while defined programs are running (just like gamerstatus)
+ [+] Extended the API to add two new services to disable and re-enable keyboards notifications (for use by bosskey plugin)
+ [!] Minor source fixes.
+0.0.1.2:
+ [!] Fixed some compatibility issues with nconvers++ (thank you donatas for your help).
+0.0.1.1:
+ [!] Fixed problem with Windows' activity detection under Win9X when using other plugins that do the same.
+ [!] Fixed crash caused by incoming authorisation requests when metacontacts was enabled.
+0.0.1.0:
+ [+] Applied pete's patches (thank you very much for your great work)
+ - Use of GetLastInputInfo when possible for detecting Windows' activity
+ - Made Windows' mouse hooks also aware of mouse clicking
+ - Made Miranda re-attended option react on windows restoring and ignoring mouse hovering an unfocused window
+ - New option for message events to avoid blinking if message window is focused
+ - Made the plugin handle metacontact's special issues
+ [!] Use of the new message API for windows detection when possible
+ [+] New message event option to check last message timestamp (requested by D46MD)
+ [+] Possibility of choosing more than one flash until option at the same time
+ [+] Possibility of selecting/unselecting protocols (requested by tweety, usuful to avoid flashing on some protocols as rss)
+ [!] Changed behaviour of Preview button to make it independent of the rules' options.
+ [!] Fixed Metacontacts recognition in checking and counting of pending events (thank you NirG for finding the problem)
+ [!] Fixed problems with multiple instances of the plugin running (thank you tweety for reporting and testing).
+ [+] New plugin API (thank you CriS for your ideas and great help)
+ [!] Added Offline status to status check list (thank you Slaktarn for finding it).
+ [!] Fixed problem with first message in Metacontacts recognition while checking for pending events (thank you again NirG)
+0.0.0.3:
+ [!] scriver's message window detection (thanks D46MD for your great help)
+ [!] corrected 'flash until' checking accordingly to pete's patch (thank you)
+0.0.0.2:
+ [!] fixed nconvers++'s message window detection and checked window detection for srmm, scriver, sramm and srmm_mod
+ [!] checking of 'notify when' and statuses added for API events
+0.0.0.1:
+ First version (using keyboardnotify 1.5.1.0 as a model)
+
+
+License
+-------
+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.
+
+=====================================================================
diff --git a/fddnotify/docs/fddnotify_translation.txt b/fddnotify/docs/fddnotify_translation.txt new file mode 100644 index 0000000..732dc9e --- /dev/null +++ b/fddnotify/docs/fddnotify_translation.txt @@ -0,0 +1,168 @@ +
+; This file contains the list of translatable strings in the
+; Miranda FDDNotify plugin.
+; Author TioDuke
+
+; Last updated: June, 2005
+; FDDNotify 0.0.1.0
+
+
+[Plugins]
+trans!
+
+[Floppy Flash]
+trans!
+
+[Protocols]
+trans!
+
+[Protocols to check]
+trans!
+
+[Rules]
+trans!
+
+[Events to react on]
+trans!
+
+[Incoming messages]
+trans!
+
+[Incoming files]
+trans!
+
+[Incoming URLs]
+trans!
+
+[Everything else]
+trans!
+
+[Message-Event only]
+trans!
+
+[Blink if message window is open]
+trans!
+
+[ ... and not in foreground]
+trans!
+
+[Only if last is]
+trans!
+
+[sec. old]
+trans!
+
+[Flash until]
+trans!
+
+[seconds]
+trans!
+
+[is re-attended]
+trans!
+
+[Events are opened]
+trans!
+
+[End of 'notify when' conditions]
+trans!
+
+[Notify when]
+trans!
+
+[Full Screen mode]
+trans!
+
+[Screen Saver is running]
+trans!
+
+[Workstation is Locked (2000/XP)]
+trans!
+
+[Defined programs are running]
+trans!
+
+[All other situations]
+trans!
+
+[Only notify if status is]
+trans!
+
+[Online]
+trans!
+
+[Away]
+trans!
+
+[NA]
+trans!
+
+[Occupied]
+trans!
+
+[DND]
+trans!
+
+[Free for chat]
+trans!
+
+[Invisible]
+trans!
+
+[On the phone]
+trans!
+
+[Out to lunch]
+trans!
+
+[Offline]
+trans!
+
+[Pending Events]
+trans!
+
+[Remind me every]
+trans!
+
+[minutes]
+trans!
+
+[Flashing]
+trans!
+
+[Wait before starting flashing]
+trans!
+
+[seconds]
+trans!
+
+[Flash speed]
+trans!
+
+[Fast]
+trans!
+
+[Slow]
+trans!
+
+[&Preview]
+trans!
+
+[Set program list]
+trans!
+
+[Program]
+trans!
+
+[Cancel]
+trans!
+
+[OK]
+trans!
+
+[Error]
+trans!
+
+[Could not open PortTalk device. Check installation of the driver.]
+trans!
+
diff --git a/fddnotify/fdd.c b/fddnotify/fdd.c new file mode 100644 index 0000000..3d91b38 --- /dev/null +++ b/fddnotify/fdd.c @@ -0,0 +1,81 @@ +/*
+
+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.
+
+*/
+
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+#include <winioctl.h>
+#include "porttalk_IOCTL.h"
+
+
+// Globals
+extern BOOL bWindowsNT;
+HANDLE hFddDev=INVALID_HANDLE_VALUE;
+
+
+void outportb(UINT portid, BYTE value)
+{
+ __asm mov edx,portid
+ __asm mov al,value
+ __asm out dx,al
+}
+
+BOOL OpenFddDevice(void)
+{
+ if (!bWindowsNT)
+ return TRUE;
+
+ if((hFddDev = CreateFile("\\\\.\\PortTalk", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL ToggleFddLight(BYTE drive, BYTE status)
+{
+ DWORD BytesReturned;
+ unsigned char Buffer[3];
+ unsigned short *pBuffer;
+ BYTE value = status<<(drive|4)|drive|12;
+
+ if (!bWindowsNT) {
+ outportb(0x3F2, value);
+ return TRUE;
+ }
+
+ if (hFddDev == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ pBuffer = (unsigned short *)&Buffer[0];
+ *pBuffer = 0x3F2;
+ Buffer[2] = (unsigned char)value;
+
+ if (!DeviceIoControl(hFddDev, IOCTL_WRITE_PORT_UCHAR, &Buffer, 3, NULL, 0, &BytesReturned, NULL))
+ return FALSE;
+
+ return TRUE;
+}
+
+void CloseFddDevice(void)
+{
+ if (!bWindowsNT)
+ return;
+
+ if (hFddDev != INVALID_HANDLE_VALUE)
+ CloseHandle(hFddDev);
+}
diff --git a/fddnotify/fdd.h b/fddnotify/fdd.h new file mode 100644 index 0000000..7af9c8d --- /dev/null +++ b/fddnotify/fdd.h @@ -0,0 +1,21 @@ +/*
+
+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.
+
+*/
+
+BOOL OpenFddDevice(void);
+BOOL ToggleFddLight(BYTE, BYTE);
+void CloseFddDevice(void);
diff --git a/fddnotify/m_fddnotify.h b/fddnotify/m_fddnotify.h new file mode 100644 index 0000000..a2b30f4 --- /dev/null +++ b/fddnotify/m_fddnotify.h @@ -0,0 +1,57 @@ +/*
+
+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.
+
+*/
+
+#ifndef _FDDNOTIFY_
+#define _FDDNOTIFY_
+
+//Enables all notifications (for use by BossKey)
+//wParam=0
+//lParam=0
+//returns 0
+#define MS_FDDNOTIFY_ENABLE "FddNotify/NotifyEnable"
+
+
+//Disables all notifications (for use by BossKey)
+//wParam=0
+//lParam=0
+//returns 0
+#define MS_FDDNOTIFY_DISABLE "FddNotify/NotifyDisable"
+
+
+//Makes the flashing begin
+//wParam=(unsigned int)eventCount
+//lParam=0
+//returns 0
+#define MS_FDDNOTIFY_STARTBLINK "FddNotify/StartBlinking"
+
+
+//Receives the number of events that were opened (usuful for the 'until events opened' setting)
+//wParam=(unsigned int)eventCount
+//lParam=0
+//returns 0
+#define MS_FDDNOTIFY_EVENTSOPENED "FddNotify/EventsWereOpened"
+
+
+//Informs if the flashing is active
+//wParam=0
+//lParam=0
+//returns 0 if the flashing is inactive or 1 if it is active
+#define MS_FDDNOTIFY_FLASHINGACTIVE "FddNotify/IsFlashingActive"
+
+
+#endif
\ No newline at end of file diff --git a/fddnotify/main.c b/fddnotify/main.c new file mode 100644 index 0000000..6594492 --- /dev/null +++ b/fddnotify/main.c @@ -0,0 +1,1203 @@ +
+/*
+ FDDNotify plugin v0.0.2 for Miranda IM
+ ______________________________________
+
+ Copyright (C) 2005 TioDuke (tioduke@yahoo.ca)
+
+
+ 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.
+
+
+ Description
+ -----------
+ This plugin for Miranda-IM notifies user of specified events (as incoming messages,
+ incoming files, incoming URLs or other events). This plugin is based on KeyboardNotify
+ by me.
+ It has many options allowing:
+ a) To select on which events to react
+ b) Under which conditions (eg: fullscreen mode, ScreenSaver running, workstation locked)
+ c) To act only if the protocol receiving the event is under specified status
+ d) For message events you can choose to be notified if the message window is open or not
+ e) A notification feature allowing to be notified of pending events (unopened events)
+ after specified period of time
+ f) To select method for stopping the blinking (after x secs, if Miranda is re-attended,
+ if Windows is re-attended, if all notified events are opened or when the notify conditions
+ end)
+ It was designed to be flexible and performing several different tasks.
+ It also provides a service to allow third party plugins use its notifier abilities.
+
+ Options
+ -------
+ Options page Options->Plugins->Floppy Flash. Tabbed: Protocols, Rules (when) and Flashing (how).
+
+ Thanks
+ ------
+ - Pete for the numerous patches he sent, actively helping to improve the code and
+ functionality
+ - UnregistereD for great help in solving problem with Windows activity detection
+ - Slacktarn, Sir_qwerty and Tweety for giving great help with ideas (most of the new
+ features included in this plugin were suggested by them) and testing
+ - The authors of AAA, PopUp+, KeyScrollNotify, original KeyboardNotify, Neweventnotify,
+ IEView, NGEventNotify for part of their code used in this plugin.
+ - Miranda IM developers for this amazing program
+ - all other people from Miranda community
+
+ History
+ -------
+ 0.0.2.2:
+ [!] Fixed problem while trying to detect if message window is in foreground
+ [*] Improved ListView control handling
+ [*] Changed the default values (for the sake of new users)
+ [*] More code optimization.
+ 0.0.2.1:
+ [+] Support for Updater plugin.
+ 0.0.2.0:
+ [+] New 'notify when' option: while defined programs are running (just like gamerstatus)
+ [+] Extended the API to add two new services to disable and re-enable keyboards notifications (for use by bosskey plugin).
+ 0.0.1.2:
+ [!] Fixed some compatibility issues with nconvers++ (thank you donatas for your help).
+ 0.0.1.1:
+ [!] Fixed problem with Windows' activity detection under Win9x when using other plugins that do the same
+ [!] Fixed crash caused by incoming authorisation requests when metacontacts was enabled.
+ 0.0.1.0:
+ [+] Applied pete's patches (thank you very much for your great work)
+ - Use of GetLastInputInfo when possible for detecting Windows' activity
+ - Made Windows' mouse hooks also aware of mouse clicking
+ - Made Miranda re-attended option react on windows restoring and ignoring mouse hovering an unfocused window
+ - New option for message events to avoid blinking if message window is focused
+ - Made the plugin handle metacontact's special issues
+ [!] Use of the new message API for windows detection when possible
+ [+] New message event option to check last message timestamp (requested by D46MD)
+ [+] Possibility of choosing more than one flash until option at the same time
+ [+] Possibility of selecting/unselecting protocols (requested by tweety, usuful to avoid flashing on some protocols as rss)
+ [!] Changed behaviour of Preview button to make it independent of the rules' options.
+ [!] Fixed Metacontacts recognition in checking and counting of pending events (thank you NirG for finding the problem)
+ [!] Fixed problems with multiple instances of the plugin running (thank you tweety for reporting and testing).
+ [+] New plugin API (thank you CriS for your ideas and great help)
+ [!] Added Offline status to status check list (thank you Slaktarn for finding it).
+ [!] Fixed problem with first message in Metacontacts recognition while checking for pending events (thank you again NirG)
+ 0.0.0.3:
+ [!] scriver's message window detection (thanks D46MD for your great help)
+ [!] corrected 'flash until' checking accordingly to pete's patch (thank you for this)
+ 0.0.0.2:
+ [!] nconvers++'s message window detection
+ [!] checked window detection for srmm, scriver, sramm and srmm_mod
+ 0.0.0.1:
+ Original version
+
+*/
+
+#define WIN32_LEAN_AND_MEAN
+#define _WIN32_WINNT 0x0500
+
+#include "AggressiveOptimize.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+#include "fdd.h"
+#include "constants.h"
+#include "protolist.h"
+#include "EnumProc.h"
+#include "m_fddnotify.h"
+#include "../headers_c/newpluginapi.h"
+#include "../headers_c/m_database.h"
+#include "../headers_c/m_options.h"
+#include "../headers_c/m_clist.h"
+#include "../headers_c/m_skin.h"
+#include "../headers_c/m_system.h"
+#include "../headers_c/m_langpack.h"
+#include "../headers_c/m_protocols.h"
+#include "../headers_c/m_protosvc.h"
+#include "../headers_c/m_contacts.h"
+#include "../headers_c/m_message.h"
+#include "../headers_c/m_metacontacts.h"
+#include "../headers_c/m_utils.h"
+#include "../headers_c/m_updater.h"
+#pragma comment(lib, "advapi32.lib")
+
+#define NCONVERS_BLINKID ((HANDLE)123456) //nconvers' random identifier used to flash an icon for "incoming message" on contact list
+
+#ifndef SPI_GETSCREENSAVERRUNNING
+#define SPI_GETSCREENSAVERRUNNING 114
+#endif
+
+#ifndef WM_XBUTTONDBLCLK
+#define WM_XBUTTONDBLCLK 0x020D
+#endif
+#ifndef WM_NCXBUTTONDBLCLK
+#define WM_NCXBUTTONDBLCLK 0x00AD
+#endif
+
+
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+
+
+DWORD IDThread = 0;
+HANDLE hThread = NULL;
+HANDLE hFlashEvent;
+HANDLE hExitEvent;
+
+HANDLE hModulesLoaded = NULL;
+HANDLE hMsgEventHook = NULL;
+HANDLE hOptionsInitialize = NULL;
+HANDLE hEnableService = NULL;
+HANDLE hDisableService = NULL;
+HANDLE hStartBlinkService = NULL;
+HANDLE hEventsOpenedService = NULL;
+HANDLE hFlashingEventService = NULL;
+
+HHOOK hMirandaMouseHook = NULL;
+HHOOK hMirandaKeyBoardHook = NULL;
+HHOOK hMirandaWndProcHook = NULL;
+UINT hReminderTimer = 0;
+
+#pragma data_seg("Shared")
+HHOOK hMouseHook = NULL;
+HHOOK hKeyBoardHook = NULL;
+DWORD dwLastInput = 0;
+POINT lastGlobalMousePos = {0, 0};
+#pragma data_seg()
+#pragma comment(linker, "/section:Shared,rws")
+
+static BOOL (WINAPI * MyGetLastInputInfo)(PLASTINPUTINFO);
+
+
+BYTE bFlashOnMsg;
+BYTE bFlashOnURL;
+BYTE bFlashOnFile;
+BYTE bFlashOnOther;
+BYTE bFullScreenMode;
+BYTE bScreenSaverRunning;
+BYTE bWorkstationLocked;
+BYTE bProcessesAreRunning;
+BYTE bWorkstationActive;
+BYTE bFlashIfMsgOpen;
+BYTE bFlashIfMsgOlder;
+WORD wSecondsOlder;
+BYTE bFlashUntil;
+WORD wBlinksNumber;
+BYTE bMirandaOrWindows;
+WORD wStatusMap;
+WORD wReminderCheck;
+WORD wStartDelay;
+WORD wBlinksNumber;
+BYTE bFlashSpeed;
+BYTE bFlashIfMsgWinNotTop;
+
+PROTOCOL_LIST ProtoList = {0, NULL};
+PROCESS_LIST ProcessList = {0, NULL};
+
+double dWinVer;
+BOOL bWindowsNT;
+
+int nWaitDelay;
+unsigned int nExternCount = 0;
+BOOL bFlashingEnabled = TRUE;
+BOOL bReminderDisabled = FALSE;
+
+char *szMetaProto = NULL;
+BYTE bMetaProtoEnabled = 0;
+
+
+PLUGININFO pluginInfo={
+ sizeof(PLUGININFO),
+ "FDD Notify",
+ PLUGIN_MAKE_VERSION(0,0,2,2),
+ "Flashes your floppy LED when an event has arrived",
+ "TioDuke",
+ "tioduke@yahoo.ca",
+ "© 2005 TioDuke",
+ "http://www.miranda-im.org/download/",
+ 0, //not transient
+ 0 //doesn't replace anything built-in
+};
+
+
+int InitializeOptions(WPARAM,LPARAM);
+void LoadSettings(void);
+int HookWindowsHooks(void);
+int UnhookWindowsHooks(void);
+static LRESULT CALLBACK MouseHookFunction(int, WPARAM, LPARAM);
+static LRESULT CALLBACK KeyBoardHookFunction(int, WPARAM, LPARAM);
+static LRESULT CALLBACK MirandaMouseHookFunction(int, WPARAM, LPARAM);
+static LRESULT CALLBACK MirandaKeyBoardHookFunction(int, WPARAM, LPARAM);
+static LRESULT CALLBACK MirandaWndProcHookFunction(int, WPARAM, LPARAM);
+BOOL CheckMsgWnd(HANDLE, BOOL *);
+char *NumberToDBSetting(const char *, int);
+
+
+// Restores the three LEDs to the state
+// that was previously saved with SaveLEDState()
+// If no state is currently saved, this function
+// will do nothing.
+static void RestoreLEDState()
+{
+ ToggleFddLight(0, 0);
+}
+
+
+BOOL isMetaContactsSubContact(HANDLE hMetaContact, HANDLE hContact)
+{
+ char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hMetaContact, 0);
+ if (szProto && !strcmp(szMetaProto, szProto)) { // Safety check
+ int i = DBGetContactSettingDword(hContact, szMetaProto, "ContactNumber", -1);
+ if (i >= 0 && hContact == (HANDLE)CallService(MS_MC_GETSUBCONTACT, (WPARAM)hMetaContact, i))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+BOOL checkOpenWindow(HANDLE hContact)
+{
+ BOOL found, focus;
+
+ if (bFlashIfMsgOpen && !bFlashIfMsgWinNotTop)
+ return TRUE;
+
+ found = CheckMsgWnd(hContact, &focus);
+ if (!found && szMetaProto && bMetaProtoEnabled) {
+ HANDLE hMetaContact = (HANDLE)DBGetContactSettingDword(hContact, szMetaProto, "Handle", 0);
+ if (hMetaContact && isMetaContactsSubContact(hMetaContact, hContact))
+ found = CheckMsgWnd(hMetaContact, &focus);
+ }
+ if (!found)
+ return TRUE;
+
+ if (bFlashIfMsgOpen && !focus)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+BOOL IsSaverOnNT4()
+{
+ HDESK hd = OpenDesktop("screen-saver", 0, FALSE, MAXIMUM_ALLOWED);
+
+ if(hd == NULL)
+ return GetLastError()==ERROR_ACCESS_DENIED;
+
+ CloseDesktop(hd);
+ return TRUE;
+}
+
+
+BOOL isScreenSaverRunning()
+{
+ BOOL screenSaverIsRunning=FALSE;
+
+ if (bWindowsNT && dWinVer < 5) return IsSaverOnNT4();
+
+ SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &screenSaverIsRunning, FALSE);
+ return screenSaverIsRunning;
+}
+
+
+/* this function is from the original idle module */
+BOOL isWorkstationLocked()
+{
+ HDESK hd;
+ char buf[MAX_PATH];
+
+ if (!bWindowsNT) return FALSE;
+
+ hd = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED); /* if it fails then the workstation is prolly locked anyway */
+ if (hd == NULL) return TRUE;
+ GetUserObjectInformation(hd, UOI_NAME, buf, sizeof(buf), NULL); /* if we got it (hmm,) get a name */
+ CloseDesktop(hd);
+ return strcmp(buf, "Winlogon")==0;
+}
+
+
+BOOL isFullScreen()
+{
+ int w = GetSystemMetrics(SM_CXSCREEN);
+ int h = GetSystemMetrics(SM_CYSCREEN);
+
+ HWND hWnd = 0;
+ while (hWnd = FindWindowEx(NULL, hWnd, NULL, NULL)) {
+ RECT WindowRect;
+
+ if (!(GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST))
+ continue;
+
+ GetWindowRect(hWnd, &WindowRect);
+ if ((w != (WindowRect.right - WindowRect.left)) || (h != (WindowRect.bottom - WindowRect.top)))
+ continue;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+BOOL checkNotifyOptions()
+{
+ BOOL fullScreenMode, screenSaverIsRunning, workstationIsLocked, processesRunning;
+
+ screenSaverIsRunning = isScreenSaverRunning();
+ if (screenSaverIsRunning && bScreenSaverRunning)
+ return TRUE;
+
+ workstationIsLocked = isWorkstationLocked();
+ if (workstationIsLocked && bWorkstationLocked)
+ return TRUE;
+
+ fullScreenMode = isFullScreen() && !screenSaverIsRunning;
+ if (fullScreenMode && bFullScreenMode)
+ return TRUE;
+
+ processesRunning = areThereProcessesRunning();
+ if (processesRunning && bProcessesAreRunning)
+ return TRUE;
+
+ return (!fullScreenMode && !screenSaverIsRunning && !workstationIsLocked && !processesRunning && bWorkstationActive);
+}
+
+
+BOOL isStatusEnabled(int status)
+{
+ switch (status) {
+ case ID_STATUS_OFFLINE: return wStatusMap & MAP_OFFLINE;
+ case ID_STATUS_ONLINE: return wStatusMap & MAP_ONLINE;
+ case ID_STATUS_AWAY: return wStatusMap & MAP_AWAY;
+ case ID_STATUS_NA: return wStatusMap & MAP_NA;
+ case ID_STATUS_OCCUPIED: return wStatusMap & MAP_OCCUPIED;
+ case ID_STATUS_DND: return wStatusMap & MAP_DND;
+ case ID_STATUS_FREECHAT: return wStatusMap & MAP_FREECHAT;
+ case ID_STATUS_INVISIBLE: return wStatusMap & MAP_INVISIBLE;
+ case ID_STATUS_ONTHEPHONE: return wStatusMap & MAP_ONTHEPHONE;
+ case ID_STATUS_OUTTOLUNCH: return wStatusMap & MAP_OUTTOLUNCH;
+ default: return FALSE;
+ }
+}
+
+
+BOOL checkGlobalStatus()
+{
+ return isStatusEnabled(CallService(MS_CLIST_GETSTATUSMODE, 0, 0));
+}
+
+
+DBEVENTINFO createMsgEventInfo(HANDLE hContact)
+{
+ DBEVENTINFO einfo = {0};
+
+ einfo.cbSize = sizeof(einfo);
+ einfo.eventType = EVENTTYPE_MESSAGE;
+ einfo.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+
+ return einfo;
+}
+
+
+DBEVENTINFO readEventInfo(HANDLE hDbEvent, HANDLE hContact)
+{
+ DBEVENTINFO einfo = {0};
+
+ if (hDbEvent == NCONVERS_BLINKID) // we need to handle nconvers' blink event
+ return createMsgEventInfo(hContact);
+
+ einfo.cbSize = sizeof(einfo);
+ einfo.cbBlob = 0;
+ einfo.pBlob = NULL;
+ CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&einfo);
+
+ return einfo;
+}
+
+
+BOOL checkProtocol(char *szProto)
+{
+ int i;
+
+ if (!szProto)
+ return FALSE;
+
+ for(i=0; i < ProtoList.protoCount; i++)
+ if (ProtoList.protoInfo[i].szProto && !strcmp(ProtoList.protoInfo[i].szProto, szProto))
+ return ProtoList.protoInfo[i].enabled;
+
+ return FALSE;
+}
+
+
+BOOL metaCheckProtocol(char *szProto, HANDLE hContact)
+{
+ HANDLE hSubContact;
+
+ if (szMetaProto && bMetaProtoEnabled && szProto && !strcmp(szMetaProto, szProto))
+ if (hSubContact = (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM)hContact, 0))
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hSubContact, 0);
+
+ return checkProtocol(szProto);
+}
+
+
+BOOL checkUnopenEvents()
+{
+ int nIndex;
+ CLISTEVENT *pCLEvent;
+
+ if (nExternCount && bFlashOnOther)
+ return TRUE;
+
+ for (nIndex = 0; pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex); nIndex++) {
+ DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact);
+
+ if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg) ||
+ (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) ||
+ (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) ||
+ (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther))
+
+ if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void FlashThreadFunction()
+{
+ BOOL bEvent = FALSE;
+ DWORD dwEventStarted, dwFlashStarted;
+ BYTE data=0;
+
+ while (TRUE) {
+ GetAsyncKeyState(VK_PAUSE); // empty Pause's keystroke buffer
+
+ // Start flashing
+ while(bEvent && bFlashingEnabled)
+ {
+ // Let's give the user the opportunity of finishing flashing manually :)
+ if (GetAsyncKeyState(VK_PAUSE) & 1)
+ break;
+
+ if ((bFlashUntil & UNTIL_NBLINKS) && GetTickCount() > (dwFlashStarted + wBlinksNumber * 1000))
+ break;
+ if (bFlashUntil & UNTIL_REATTENDED) {
+ if (bMirandaOrWindows == ACTIVE_WINDOWS && MyGetLastInputInfo) {
+ LASTINPUTINFO lii;
+ ZeroMemory(&lii, sizeof(lii));
+ lii.cbSize = sizeof(lii);
+ MyGetLastInputInfo(&lii);
+ dwLastInput = lii.dwTime;
+ }
+ if (dwLastInput > dwEventStarted)
+ break;
+ }
+ if ((bFlashUntil & UNTIL_EVENTSOPEN) && !checkUnopenEvents())
+ break;
+ if ((bFlashUntil & UNTIL_CONDITIONS) && (!checkNotifyOptions() || !checkGlobalStatus()))
+ break;
+
+ data = !data;
+ ToggleFddLight(0, data);
+
+ // Wait for exit event
+ if (WaitForSingleObject(hExitEvent, nWaitDelay) == WAIT_OBJECT_0)
+ return;
+ }
+ RestoreLEDState();
+
+ bReminderDisabled = FALSE;
+ // Wait for new event
+ {
+ DWORD dwEvent;
+ HANDLE Objects[2];
+ Objects[0] = hFlashEvent;
+ Objects[1] = hExitEvent;
+ dwEvent = WaitForMultipleObjects(2, Objects, FALSE, INFINITE);
+ if ((dwEvent - WAIT_OBJECT_0) == 1)
+ return;
+ }
+
+ bEvent = TRUE;
+ bReminderDisabled = TRUE;
+ dwEventStarted = GetTickCount();
+ // Wait StartDelay seconds
+ if (wStartDelay > 0)
+ Sleep(wStartDelay * 1000);
+ dwFlashStarted = GetTickCount();
+
+ }
+
+}
+
+
+BOOL checkMsgTimestamp(HANDLE hEventCurrent, DWORD timestampCurrent)
+{
+ HANDLE hEvent;
+
+ if (!bFlashIfMsgOlder)
+ return TRUE;
+
+ for (hEvent=(HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hEventCurrent, 0); hEvent; hEvent=(HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hEvent, 0)) {
+ DBEVENTINFO einfo = {0};
+
+ einfo.cbSize = sizeof(einfo);
+ einfo.cbBlob = 0;
+ einfo.pBlob = NULL;
+ CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&einfo);
+ if ((einfo.timestamp + wSecondsOlder) <= timestampCurrent)
+ return TRUE;
+ if (einfo.eventType == EVENTTYPE_MESSAGE)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+BOOL contactCheckProtocol(char *szProto, HANDLE hContact)
+{
+ if (szMetaProto && bMetaProtoEnabled && hContact) {
+ HANDLE hMetaContact = (HANDLE)DBGetContactSettingDword(hContact, szMetaProto, "Handle", 0);
+ if (hMetaContact && isMetaContactsSubContact(hMetaContact, hContact))
+ return FALSE;
+ }
+
+ return metaCheckProtocol(szProto, hContact);
+}
+
+
+BOOL checkStatus(char *szProto)
+{
+ if(!szProto)
+ return checkGlobalStatus();
+
+ return isStatusEnabled(CallProtoService(szProto, PS_GETSTATUS, 0, 0));
+}
+
+
+static int PluginMessageEventHook(WPARAM wParam, LPARAM lParam)
+{
+ DBEVENTINFO einfo = {0};
+ HANDLE hContact = (HANDLE)wParam;
+ HANDLE hEvent = (HANDLE)lParam;
+
+ //get DBEVENTINFO without pBlob
+ einfo.cbSize = sizeof(einfo);
+ einfo.cbBlob = 0;
+ einfo.pBlob = NULL;
+ CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&einfo);
+
+ if (!(einfo.flags & DBEF_SENT))
+ if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg && checkOpenWindow(hContact) && checkMsgTimestamp(hEvent, einfo.timestamp)) ||
+ (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) ||
+ (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) ||
+ (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) {
+
+ if (contactCheckProtocol(einfo.szModule, hContact) && checkNotifyOptions() && checkStatus(einfo.szModule))
+
+ SetEvent(hFlashEvent);
+ }
+
+ return 0;
+}
+
+
+// **
+// ** Checks for pending events. If it finds any, it pings the FlashThread to keep the LED flashing.
+// **
+
+static VOID CALLBACK ReminderTimer(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime) {
+ int nIndex;
+ CLISTEVENT *pCLEvent;
+
+ for (nIndex = 0; !bReminderDisabled && (pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex)); nIndex++) {
+ DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact);
+
+ if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg) ||
+ (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) ||
+ (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) ||
+ (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther))
+
+ if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact) && checkNotifyOptions() && checkStatus(einfo.szModule)) {
+
+ SetEvent(hFlashEvent);
+ return;
+ }
+ }
+
+}
+
+
+// Support for third-party plugins and mBot's scripts
+static int EnableService(WPARAM wParam, LPARAM lParam)
+{
+ bFlashingEnabled = TRUE;
+
+ return 0;
+}
+
+
+static int DisableService(WPARAM wParam, LPARAM lParam)
+{
+ bFlashingEnabled = FALSE;
+
+ return 0;
+}
+
+
+static int StartBlinkService(WPARAM wParam, LPARAM lParam)
+{
+ nExternCount += (unsigned int)wParam;
+ if (bFlashOnOther && checkNotifyOptions() && checkGlobalStatus())
+ SetEvent(hFlashEvent);
+
+ return 0;
+}
+
+
+static int EventsWereOpenedService(WPARAM wParam, LPARAM lParam)
+{
+ if ((unsigned int)wParam > nExternCount)
+ nExternCount = 0;
+ else
+ nExternCount -= (unsigned int)wParam;
+
+ return 0;
+}
+
+
+static int IsFlashingActiveService(WPARAM wParam, LPARAM lParam)
+{
+ return bReminderDisabled;
+}
+
+
+void createProcessList(void)
+{
+ DBVARIANT dbv;
+ unsigned int i, count;
+
+ count = (unsigned int)DBGetContactSettingWord(NULL, FDDMODULE, "processcount", 0);
+
+ ProcessList.count = 0;
+ ProcessList.szFileName = (char **)malloc(count * sizeof(char *));
+ if (ProcessList.szFileName) {
+ for(i=0; i < count; i++)
+ if (DBGetContactSetting(NULL, FDDMODULE, NumberToDBSetting("process", i), &dbv))
+ ProcessList.szFileName[i] = NULL;
+ else {
+ ProcessList.szFileName[i] = (char *)malloc(strlen(dbv.pszVal) + 1);
+ if (ProcessList.szFileName[i])
+ strcpy(ProcessList.szFileName[i], dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ ProcessList.count = count;
+ }
+
+}
+
+
+void destroyProcessList(void)
+{
+ unsigned int i, count;
+
+ count = ProcessList.count;
+
+ ProcessList.count = 0;
+ for(i=0; i < count; i++)
+ if (ProcessList.szFileName[i])
+ free(ProcessList.szFileName[i]);
+
+ if (ProcessList.szFileName)
+ free(ProcessList.szFileName);
+ ProcessList.szFileName = NULL;
+}
+
+
+void LoadSettings(void)
+{
+ int i;
+
+ bFlashOnMsg = DBGetContactSettingByte(NULL, FDDMODULE, "onmsg", DEF_SETTING_ONMSG);
+ bFlashOnURL = DBGetContactSettingByte(NULL, FDDMODULE, "onurl", DEF_SETTING_ONURL);
+ bFlashOnFile = DBGetContactSettingByte(NULL, FDDMODULE, "onfile", DEF_SETTING_ONFILE);
+ bFlashOnOther = DBGetContactSettingByte(NULL, FDDMODULE, "onother", DEF_SETTING_OTHER);
+ bFullScreenMode = DBGetContactSettingByte(NULL, FDDMODULE, "fscreenmode", DEF_SETTING_FSCREEN);
+ bScreenSaverRunning = DBGetContactSettingByte(NULL, FDDMODULE, "ssaverrunning", DEF_SETTING_SSAVER);
+ bWorkstationLocked = (bWindowsNT ? DBGetContactSettingByte(NULL, FDDMODULE, "wstationlocked", DEF_SETTING_LOCKED):0);
+ bProcessesAreRunning = DBGetContactSettingByte(NULL, FDDMODULE, "procsrunning", DEF_SETTING_PROCS);
+ bWorkstationActive = DBGetContactSettingByte(NULL, FDDMODULE, "wstationactive", DEF_SETTING_ACTIVE);
+ bFlashIfMsgOpen = DBGetContactSettingByte(NULL, FDDMODULE, "ifmsgopen", DEF_SETTING_IFMSGOPEN);
+ bFlashIfMsgWinNotTop = DBGetContactSettingByte(NULL, FDDMODULE, "ifmsgnottop", DEF_SETTING_IFMSGNOTTOP);
+ bFlashIfMsgOlder = DBGetContactSettingByte(NULL, FDDMODULE, "ifmsgolder", DEF_SETTING_IFMSGOLDER);
+ wSecondsOlder = DBGetContactSettingWord(NULL, FDDMODULE, "secsolder", DEF_SETTING_SECSOLDER);
+ bFlashUntil = DBGetContactSettingByte(NULL, FDDMODULE, "funtil", DEF_SETTING_FLASHUNTIL);
+ wBlinksNumber = DBGetContactSettingWord(NULL, FDDMODULE, "nblinks", DEF_SETTING_NBLINKS);
+ bMirandaOrWindows = DBGetContactSettingByte(NULL, FDDMODULE, "mirorwin", DEF_SETTING_MIRORWIN);
+ wStatusMap = DBGetContactSettingWord(NULL, FDDMODULE, "status", DEF_SETTING_STATUS);
+ wReminderCheck = DBGetContactSettingWord(NULL, FDDMODULE, "remcheck", DEF_SETTING_CHECKTIME);
+ wStartDelay = DBGetContactSettingWord(NULL, FDDMODULE, "sdelay", DEF_SETTING_STARTDELAY);
+ bFlashSpeed = DBGetContactSettingByte(NULL, FDDMODULE, "speed", DEF_SETTING_FLASHSPEED);
+ switch (bFlashSpeed) {
+ case 0: nWaitDelay = 1500; break;
+ case 1: nWaitDelay = 1000; break;
+ case 2: nWaitDelay = 0750; break;
+ case 3: nWaitDelay = 0500; break;
+ case 4: nWaitDelay = 0250; break;
+ default: nWaitDelay = 0150; break;
+ }
+ for(i=0; i < ProtoList.protoCount; i++)
+ if (ProtoList.protoInfo[i].visible)
+ ProtoList.protoInfo[i].enabled = DBGetContactSettingByte(NULL, FDDMODULE, ProtoList.protoInfo[i].szProto, DEF_SETTING_PROTOCOL);
+
+ if (szMetaProto)
+ bMetaProtoEnabled = DBGetContactSettingByte(NULL, szMetaProto, "Enabled", 1);
+
+ destroyProcessList();
+ createProcessList();
+ UnhookWindowsHooks();
+ HookWindowsHooks();
+}
+
+
+void GetWindowsVersion(void)
+{
+ OSVERSIONINFOEX osvi;
+ BOOL bOsVersionInfoEx;
+
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi))) {
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ if(!GetVersionEx((OSVERSIONINFO *)&osvi))
+ osvi.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
+ }
+ bWindowsNT = osvi.dwPlatformId==VER_PLATFORM_WIN32_NT;
+ dWinVer = osvi.dwMajorVersion + osvi.dwMinorVersion / 10.0;
+}
+
+
+void createProtocolList(void)
+{
+ int i;
+ PROTOCOLDESCRIPTOR **proto;
+
+ if (ServiceExists(MS_MC_GETPROTOCOLNAME))
+ szMetaProto = (char *)CallService(MS_MC_GETPROTOCOLNAME, 0, 0);
+
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoList.protoCount, (LPARAM)&proto);
+ ProtoList.protoInfo = (PROTOCOL_INFO *)malloc(ProtoList.protoCount * sizeof(PROTOCOL_INFO));
+ if (!ProtoList.protoInfo)
+ ProtoList.protoCount = 0;
+ else
+ for(i=0; i < ProtoList.protoCount; i++) {
+ ProtoList.protoInfo[i].szProto = (char *)malloc(strlen(proto[i]->szName) + 1);
+ if (!ProtoList.protoInfo[i].szProto) {
+ ProtoList.protoInfo[i].enabled = FALSE;
+ ProtoList.protoInfo[i].visible = FALSE;
+ } else {
+ strcpy(ProtoList.protoInfo[i].szProto, proto[i]->szName);
+ ProtoList.protoInfo[i].enabled = FALSE;
+ if (proto[i]->type != PROTOTYPE_PROTOCOL)
+ ProtoList.protoInfo[i].visible = FALSE;
+ else
+ if (szMetaProto && !strcmp(proto[i]->szName, szMetaProto))
+ ProtoList.protoInfo[i].visible = FALSE;
+ else
+ ProtoList.protoInfo[i].visible = TRUE;
+ }
+ }
+
+}
+
+
+char *getAbsoluteProfileName(char *absoluteProfileName, size_t maxLen)
+{
+ char profilePath[MAX_PATH+1], profileName[MAX_PATH+1];
+
+ profilePath[0] = profileName[0] = '\0';
+ CallService(MS_DB_GETPROFILEPATH, MAX_PATH, (LPARAM)profilePath);
+ CallService(MS_DB_GETPROFILENAME, MAX_PATH, (LPARAM)profileName);
+ mir_snprintf(absoluteProfileName, maxLen, "%s\\%s", profilePath, profileName);
+
+ return absoluteProfileName;
+}
+
+
+// We use the profile name to create the first part of each event name
+// We do so to avoid problems between different instances of the plugin concurrently running
+void createEventPrefix(char *prefixName, size_t maxLen)
+{
+ size_t len;
+ char profileName[MAX_PATH+1], *str;
+
+ getAbsoluteProfileName(profileName, MAX_PATH);
+
+ while (str = strchr(profileName, '\\'))
+ *str = '/';
+ if ((len = strlen(profileName)) <= maxLen)
+ strcpy(prefixName, profileName);
+ else {
+ str = profileName + len - maxLen / 2;
+ mir_snprintf(prefixName, maxLen / 2, "%s", profileName);
+ strcat(prefixName, str);
+ }
+}
+
+
+// **
+// ** Everything below is just Miranda init/uninit stuff
+// **
+
+
+static int ModulesLoaded(WPARAM wParam,LPARAM lParam)
+{
+
+ char eventPrefix[MAX_PATH+1], eventName[MAX_PATH+1];
+
+ LoadProcsLibrary();
+ if (bWindowsNT && dWinVer >= 5)
+ MyGetLastInputInfo = (BOOL (WINAPI *)(PLASTINPUTINFO)) GetProcAddress(GetModuleHandle("user32"), "GetLastInputInfo");
+ else
+ MyGetLastInputInfo = NULL;
+
+ createProtocolList();
+ LoadSettings();
+
+ // Create some synchronisation objects
+ createEventPrefix(eventPrefix, MAX_PATH - 14);
+ mir_snprintf(eventName, sizeof(eventName), "%s/FddFlashEvent", eventPrefix);
+ hFlashEvent = CreateEvent(NULL, FALSE, FALSE, eventName);
+ mir_snprintf(eventName, sizeof(eventName), "%s/FddExitEvent", eventPrefix);
+ hExitEvent = CreateEvent(NULL, FALSE, FALSE, eventName);
+
+ hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FlashThreadFunction, NULL, 0, &IDThread);
+
+ hMsgEventHook = HookEvent(ME_DB_EVENT_ADDED, PluginMessageEventHook);
+ hOptionsInitialize = HookEvent(ME_OPT_INITIALISE, InitializeOptions);
+ hEnableService = CreateServiceFunction(MS_FDDNOTIFY_ENABLE, EnableService);
+ hDisableService = CreateServiceFunction(MS_FDDNOTIFY_DISABLE, DisableService);
+ hStartBlinkService = CreateServiceFunction(MS_FDDNOTIFY_STARTBLINK, StartBlinkService);
+ hEventsOpenedService = CreateServiceFunction(MS_FDDNOTIFY_EVENTSOPENED, EventsWereOpenedService);
+ hFlashingEventService = CreateServiceFunction(MS_FDDNOTIFY_FLASHINGACTIVE, IsFlashingActiveService);
+
+ if (ServiceExists("DBEditorpp/RegisterSingleModule"))
+ CallService("DBEditorpp/RegisterSingleModule", (WPARAM)FDDMODULE, 0);
+ if (ServiceExists(MS_UPDATE_REGISTERFL))
+ CallService(MS_UPDATE_REGISTERFL, (WPARAM)2070, (LPARAM)&pluginInfo);
+
+ return 0;
+}
+
+
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+
+ hInst = hinstDLL;
+
+ return TRUE;
+
+}
+
+
+
+__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+
+ return &pluginInfo;
+
+}
+
+
+
+int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+
+ pluginLink = link;
+
+ GetWindowsVersion();
+
+ if (!OpenFddDevice()) {
+ MessageBox(NULL, Translate("Could not open PortTalk device. Check installation of the driver."), Translate("Error"), MB_OK | MB_ICONSTOP );
+ return 0;
+ }
+ hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
+
+ return 0;
+}
+
+
+
+void destroyProtocolList(void)
+{
+ int i;
+
+ for(i=0; i < ProtoList.protoCount; i++)
+ if (ProtoList.protoInfo[i].szProto)
+ free(ProtoList.protoInfo[i].szProto);
+
+ ProtoList.protoCount = 0;
+ if (ProtoList.protoInfo)
+ free(ProtoList.protoInfo);
+}
+
+
+int __declspec(dllexport) Unload(void)
+{
+
+ UnhookWindowsHooks();
+ if (hModulesLoaded)
+ UnhookEvent(hModulesLoaded);
+ if (hMsgEventHook)
+ UnhookEvent(hMsgEventHook);
+ if (hOptionsInitialize)
+ UnhookEvent(hOptionsInitialize);
+ if (hEnableService)
+ DestroyServiceFunction(hEnableService);
+ if (hDisableService)
+ DestroyServiceFunction(hDisableService);
+ if (hStartBlinkService)
+ DestroyServiceFunction(hStartBlinkService);
+ if (hEventsOpenedService)
+ DestroyServiceFunction(hEventsOpenedService);
+ if (hFlashingEventService)
+ DestroyServiceFunction(hFlashingEventService);
+
+ // Wait for thread to exit
+ SetEvent(hExitEvent);
+ WaitForSingleObject(hThread, INFINITE);
+
+ RestoreLEDState();
+ CloseFddDevice();
+
+ UnloadProcsLibrary();
+ destroyProcessList();
+ destroyProtocolList();
+
+ return 0;
+}
+
+
+// ========================== Windows hooks ==========================
+int HookWindowsHooks()
+{
+ if (wReminderCheck)
+ hReminderTimer = SetTimer(NULL,0, wReminderCheck * 60000, ReminderTimer);
+
+ if (bFlashUntil & UNTIL_REATTENDED)
+ switch (bMirandaOrWindows) {
+ case ACTIVE_WINDOWS:
+ if (!MyGetLastInputInfo) {
+ if (hMouseHook == NULL)
+ hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseHookFunction, hInst, 0);
+ if (hKeyBoardHook == NULL)
+ hKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, KeyBoardHookFunction, hInst, 0);
+ }
+ break;
+ case ACTIVE_MIRANDA:
+ if (hMirandaMouseHook == NULL)
+ hMirandaMouseHook = SetWindowsHookEx(WH_MOUSE, MirandaMouseHookFunction, NULL, GetCurrentThreadId());
+ if (hMirandaKeyBoardHook == NULL)
+ hMirandaKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, MirandaKeyBoardHookFunction, NULL, GetCurrentThreadId());
+ if (hMirandaWndProcHook == NULL)
+ hMirandaWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, MirandaWndProcHookFunction, NULL, GetCurrentThreadId());
+ }
+
+ return 0;
+}
+
+int UnhookWindowsHooks()
+{
+ if (hReminderTimer)
+ KillTimer(NULL, hReminderTimer);
+ if (hMouseHook)
+ UnhookWindowsHookEx(hMouseHook);
+ if (hKeyBoardHook)
+ UnhookWindowsHookEx(hKeyBoardHook);
+ if (hMirandaMouseHook)
+ UnhookWindowsHookEx(hMirandaMouseHook);
+ if (hMirandaKeyBoardHook)
+ UnhookWindowsHookEx(hMirandaKeyBoardHook);
+ if (hMirandaWndProcHook)
+ UnhookWindowsHookEx(hMirandaWndProcHook);
+
+ hReminderTimer = 0;
+ hMouseHook = hKeyBoardHook = hMirandaMouseHook = hMirandaKeyBoardHook = hMirandaWndProcHook = NULL;
+
+ return 0;
+}
+
+static LRESULT CALLBACK MouseHookFunction(int code, WPARAM wParam, LPARAM lParam)
+{
+ if (code >= 0) {
+ /* This should handle all mouse buttons ... */
+ if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK))
+ dwLastInput = GetTickCount();
+ /* ... and here it is either mouse move, hover, leave or something unexpected */
+ else {
+ PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam;
+ POINT pt = mouseInfo->pt;
+ if (pt.x!=lastGlobalMousePos.x || pt.y!=lastGlobalMousePos.y) {
+ lastGlobalMousePos = pt;
+ dwLastInput = GetTickCount();
+ }
+ }
+ }
+
+ return CallNextHookEx(hMouseHook, code, wParam, lParam);
+}
+
+static LRESULT CALLBACK KeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam)
+{
+ if (code >= 0)
+ dwLastInput = GetTickCount();
+
+ return CallNextHookEx(hKeyBoardHook, code, wParam, lParam);
+}
+
+static LRESULT CALLBACK MirandaMouseHookFunction(int code, WPARAM wParam, LPARAM lParam)
+{
+ static POINT lastMousePos = {0, 0};
+
+ if (code >= 0) {
+ /* Movement mouse messages are for some reason incoming in inactive/background window too, that is not input */
+ DWORD pid;
+ GetWindowThreadProcessId(GetForegroundWindow(), &pid);
+ if(pid == GetCurrentProcessId()) {
+ /* This should handle all mouse buttons ... */
+ if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK))
+ dwLastInput = GetTickCount();
+ /* ... and here it is either mouse move, hover, leave or something unexpected */
+ else {
+ PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam;
+ POINT pt = mouseInfo->pt;
+ if (pt.x!=lastMousePos.x || pt.y!=lastMousePos.y) {
+ lastMousePos = pt;
+ dwLastInput = GetTickCount();
+ }
+ }
+ }
+ }
+
+ return CallNextHookEx(hMirandaMouseHook, code, wParam, lParam);
+}
+
+static LRESULT CALLBACK MirandaKeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) {
+
+ if (code >= 0)
+ dwLastInput = GetTickCount();
+
+ return CallNextHookEx(hMirandaKeyBoardHook, code, wParam, lParam);
+}
+
+static LRESULT CALLBACK MirandaWndProcHookFunction(int code, WPARAM wParam, LPARAM lParam) {
+
+ if (code >= 0) {
+ /* WM_ACTIVATEAPP with nonzero wParam means someone brought miranda to foreground, that equals to input */
+ PCWPSTRUCT cwpInfo = (PCWPSTRUCT)lParam;
+ if(cwpInfo->message == WM_ACTIVATEAPP && cwpInfo->wParam)
+ dwLastInput = GetTickCount();
+ }
+
+ return CallNextHookEx(hMirandaWndProcHook, code, wParam, lParam);
+}
+
+
+//===================== Check Window Message function =====================
+
+// Took this snippet of code from "EventNotify" by micron-x, thx *g*
+// and updated with NGEventNotify and pete's patch
+// checks if the message-dialog window is already opened and returns:
+// NULL - No window found
+// Handle to the parent window
+
+HWND findMessageWindow(HANDLE hContact)
+{
+ HWND hwnd;
+ char newtitle[256];
+ char *szProto, *contactName, *szStatus;
+ CONTACTINFO ci = {0};
+
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ contactName = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0);
+ szStatus = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, szProto==NULL?ID_STATUS_OFFLINE:DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE), 0);
+
+ mir_snprintf(newtitle, sizeof(newtitle), "%s (%s): %s", contactName, szStatus, Translate("Message Received"));
+ if(hwnd = FindWindow(NULL, newtitle))
+ return hwnd;
+
+ mir_snprintf(newtitle, sizeof(newtitle), "%s %s", contactName, szStatus);
+ if(hwnd = FindWindow(NULL, newtitle))
+ return hwnd;
+ mir_snprintf(newtitle, sizeof(newtitle), "%s (%s): %s", contactName, szStatus, Translate("Message Session"));
+ if(hwnd = FindWindow(NULL, newtitle))
+ return hwnd;
+ mir_snprintf(newtitle, sizeof(newtitle), "%s (%s): %s", contactName, szStatus, Translate("Message Session is typing..."));
+ if(hwnd = FindWindow(NULL, newtitle))
+ return hwnd;
+ // search for the nconvers++ message window that uses the UIN
+ ci.cbSize = sizeof(CONTACTINFO);
+ ci.dwFlag = CNF_UNIQUEID;
+ ci.hContact = hContact;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) {
+ switch(ci.type) {
+ case CNFT_BYTE:
+ mir_snprintf(newtitle, sizeof(newtitle), "%s (%d) %s", contactName, ci.bVal, szStatus);
+ break;
+ case CNFT_WORD:
+ mir_snprintf(newtitle, sizeof(newtitle), "%s (%d) %s", contactName, ci.wVal, szStatus);
+ break;
+ case CNFT_DWORD:
+ mir_snprintf(newtitle, sizeof(newtitle), "%s (%d) %s", contactName, ci.dVal, szStatus);
+ break;
+ case CNFT_ASCIIZ:
+ mir_snprintf(newtitle, sizeof(newtitle), "%s (%s) %s", contactName, ci.pszVal, szStatus);
+ break;
+ }
+ if(hwnd = FindWindow(NULL, newtitle))
+ return hwnd;
+ }
+
+ return NULL;
+}
+
+BOOL CheckMsgWnd(HANDLE hContact, BOOL *focus)
+{
+ if (ServiceExists(MS_MSG_GETWINDOWDATA)) { // use the new Window API
+ MessageWindowData mwd;
+ MessageWindowInputData mwid;
+ mwid.cbSize = sizeof(MessageWindowInputData);
+ mwid.hContact = hContact;
+ mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+ mwd.cbSize = sizeof(MessageWindowData);
+ mwd.hContact = hContact;
+ if (!CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd) && mwd.hwndWindow) {
+ *focus = mwd.uState & MSG_WINDOW_STATE_FOCUS;
+ return TRUE;
+ }
+ } else { // old way: find it by using the window class & title
+ HWND hwnd;
+
+ if(hwnd = findMessageWindow(hContact)) {
+ *focus = hwnd==GetForegroundWindow();
+ return TRUE;
+ }
+ }
+
+ *focus = FALSE;
+ return FALSE;
+}
diff --git a/fddnotify/options.c b/fddnotify/options.c new file mode 100644 index 0000000..51d24dd --- /dev/null +++ b/fddnotify/options.c @@ -0,0 +1,785 @@ +/*
+
+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.
+
+*/
+
+#define WIN32_LEAN_AND_MEAN
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+#include <commctrl.h>
+#include <commdlg.h>
+#include "fdd.h"
+#include "resource.h"
+#include "constants.h"
+#include "protolist.h"
+#include "EnumProc.h"
+#include "../headers_c/newpluginapi.h"
+#include "../headers_c/m_clist.h"
+#include "../headers_c/m_database.h"
+#include "../headers_c/m_langpack.h"
+#include "../headers_c/m_options.h"
+#include "../headers_c/m_protosvc.h"
+#include "../headers_c/m_protocols.h"
+
+#ifndef ListView_SetCheckState
+#define ListView_SetCheckState(hLv, iItem, bCheck) ListView_SetItemState(hLv, iItem, bCheck ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1), LVIS_STATEIMAGEMASK)
+#endif
+
+void LoadSettings(void);
+int InitializeOptions(WPARAM,LPARAM);
+INT_PTR CALLBACK DlgProcOptions(HWND, UINT, WPARAM, LPARAM);
+INT_PTR CALLBACK DlgProcProtoOptions(HWND, UINT, WPARAM, LPARAM);
+INT_PTR CALLBACK DlgProcBasicOptions(HWND, UINT, WPARAM, LPARAM);
+INT_PTR CALLBACK DlgProcEffectOptions(HWND, UINT, WPARAM, LPARAM);
+INT_PTR CALLBACK DlgProcProcesses(HWND, UINT, WPARAM, LPARAM);
+void previewFlashing(BOOL);
+static void PreviewThread(void *);
+void createProcessListAux(void);
+void destroyProcessListAux(void);
+char *NumberToDBSetting(const char*, int);
+
+
+extern HINSTANCE hInst;
+extern BOOL bWindowsNT;
+
+extern BYTE bFlashOnMsg;
+extern BYTE bFlashOnURL;
+extern BYTE bFlashOnFile;
+extern BYTE bFlashOnOther;
+extern BYTE bFullScreenMode;
+extern BYTE bScreenSaverRunning;
+extern BYTE bWorkstationLocked;
+extern BYTE bProcessesAreRunning;
+extern BYTE bWorkstationActive;
+extern BYTE bFlashIfMsgOpen;
+extern BYTE bFlashIfMsgOlder;
+extern WORD wSecondsOlder;
+extern BYTE bFlashUntil;
+extern WORD wBlinksNumber;
+extern BYTE bMirandaOrWindows;
+extern WORD wStatusMap;
+extern WORD wReminderCheck;
+extern WORD wStartDelay;
+extern BYTE bFlashSpeed;
+extern BYTE bFlashIfMsgWinNotTop;
+
+extern PROTOCOL_LIST ProtoList;
+extern PROCESS_LIST ProcessList;
+
+HWND hwndProto, hwndBasic, hwndEffect, hwndCurrentTab;
+
+char *AttendedName[]={"Miranda", "Windows"};
+
+PROCESS_LIST ProcessListAux;
+
+
+// **
+// ** Initialize the Miranda options page
+// **
+int InitializeOptions(WPARAM wParam,LPARAM lParam)
+{
+
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize = sizeof(odp);
+ odp.position = 0;
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS);
+ odp.pszTitle = Translate("Floppy Flash");
+ odp.pszGroup = Translate("Plugins");
+ odp.groupPosition = 910000000;
+ odp.flags=ODPF_BOLDGROUPS;
+ odp.pfnDlgProc = DlgProcOptions;
+ odp.nIDBottomSimpleControl = 0;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ return 0;
+}
+
+
+INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ HWND tc;
+ TCITEM tci;
+ tc = GetDlgItem(hwndDlg, IDC_TABS);
+ tci.mask = TCIF_TEXT;
+ tci.pszText = Translate("Protocols");
+ TabCtrl_InsertItem(tc, 0, &tci);
+ tci.pszText = Translate("Rules");
+ TabCtrl_InsertItem(tc, 1, &tci);
+ tci.pszText = Translate("Flashing");
+ TabCtrl_InsertItem(tc, 2, &tci);
+
+ hwndProto = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PROTO_OPTIONS), hwndDlg, DlgProcProtoOptions, (LPARAM) NULL);
+ SetWindowPos(hwndProto, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ ShowWindow(hwndProto, SW_SHOW);
+ hwndBasic = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_BASIC_OPTIONS), hwndDlg, DlgProcBasicOptions, (LPARAM) NULL);
+ SetWindowPos(hwndBasic, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ hwndEffect = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EFFECT_OPTIONS), hwndDlg, DlgProcEffectOptions, (LPARAM) NULL);
+ SetWindowPos(hwndEffect, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ hwndCurrentTab = hwndProto;
+ return TRUE;
+ }
+ case WM_COMMAND:
+ break;
+ case WM_NOTIFY:
+ {
+ switch (((LPNMHDR) lParam)->code) {
+ case TCN_SELCHANGE:
+ switch (wParam) {
+ case IDC_TABS:
+ {
+ HWND hwnd;
+ switch (TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS))) {
+ default:
+ case 0:
+ hwnd = hwndProto;
+ break;
+ case 1:
+ hwnd = hwndBasic;
+ break;
+ case 2:
+ hwnd = hwndEffect;
+ break;
+ }
+ if (hwnd!=hwndCurrentTab) {
+ ShowWindow(hwnd, SW_SHOW);
+ ShowWindow(hwndCurrentTab, SW_HIDE);
+ hwndCurrentTab = hwnd;
+ }
+ }
+ break;
+ }
+ break;
+ case PSN_APPLY:
+ SendMessage(hwndProto, WM_NOTIFY, wParam, lParam);
+ SendMessage(hwndBasic, WM_NOTIFY, wParam, lParam);
+ SendMessage(hwndEffect, WM_NOTIFY, wParam, lParam);
+ return TRUE;
+ }
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+
+INT_PTR CALLBACK DlgProcProtoOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static BOOL initDlg=FALSE;
+
+ switch (msg) {
+
+ case WM_INITDIALOG:
+ initDlg=TRUE;
+ TranslateDialogDefault(hwndDlg);
+
+ // proto list
+ {
+ int i;
+ LVCOLUMN lvCol;
+ LVITEM lvItem;
+ HWND hList = GetDlgItem(hwndDlg, IDC_PROTOCOLLIST);
+
+ // create columns
+ ListView_SetExtendedListViewStyleEx(hList, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
+ memset(&lvCol, 0, sizeof(lvCol));
+ lvCol.mask = LVCF_WIDTH|LVCF_TEXT;
+ lvCol.pszText = Translate("Protocol");
+ lvCol.cx = 118;
+ ListView_InsertColumn(hList, 0, &lvCol);
+ // fill
+ memset(&lvItem, 0, sizeof(lvItem));
+ lvItem.mask = LVIF_TEXT|LVIF_PARAM;
+ lvItem.cchTextMax = 256;
+ lvItem.iItem = 0;
+ lvItem.iSubItem = 0;
+ for(i=0; i < ProtoList.protoCount; i++) {
+ char protoName[MAX_PATH+1];
+
+ if(ProtoList.protoInfo[i].visible) {
+ lvItem.lParam = (LPARAM)ProtoList.protoInfo[i].szProto;
+ CallProtoService(ProtoList.protoInfo[i].szProto, PS_GETNAME, sizeof(protoName), (LPARAM)protoName);
+ lvItem.pszText = protoName;
+ ListView_InsertItem(hList, &lvItem);
+ ListView_SetCheckState(hList, lvItem.iItem, ProtoList.protoInfo[i].enabled);
+ lvItem.iItem++;
+ }
+ }
+ }
+
+ initDlg=FALSE;
+ return TRUE;
+
+ case WM_NOTIFY:
+ {
+ //Here we have pressed either the OK or the APPLY button.
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR)lParam)->code) {
+ case PSN_APPLY:
+ // enabled protos
+ {
+ int i;
+ LVITEM lvItem;
+ HWND hList = GetDlgItem(hwndDlg, IDC_PROTOCOLLIST);
+
+ memset(&lvItem, 0, sizeof(lvItem));
+ lvItem.mask = LVIF_PARAM;
+ lvItem.iSubItem = 0;
+ for (i=0; i < ListView_GetItemCount(hList); i++) {
+ lvItem.iItem = i;
+ ListView_GetItem(hList, &lvItem);
+ DBWriteContactSettingByte(NULL, FDDMODULE, (char *)lvItem.lParam, (BYTE)!!ListView_GetCheckState(hList, lvItem.iItem));
+ }
+ }
+
+ LoadSettings();
+
+ return TRUE;
+ } // switch code - 0
+ break;
+ case IDC_PROTOCOLLIST:
+ switch(((NMHDR*)lParam)->code) {
+ case LVN_ITEMCHANGED:
+ {
+ NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam;
+
+ if (!initDlg && ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK))
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ }
+ break;
+ } // switch code - IDC_PROTOCOLLIST
+ break;
+ } //switch idFrom
+ }
+ break; //End WM_NOTIFY
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+INT_PTR CALLBACK DlgProcBasicOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ int i;
+ static BOOL initDlg=FALSE;
+
+ switch (msg) {
+
+ case WM_INITDIALOG:
+ initDlg=TRUE;
+ TranslateDialogDefault(hwndDlg);
+
+ createProcessListAux();
+
+ CheckDlgButton(hwndDlg, IDC_ONMESSAGE, bFlashOnMsg ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ONURL, bFlashOnURL ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ONFILE, bFlashOnFile ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ONOTHER, bFlashOnOther ? BST_CHECKED:BST_UNCHECKED);
+
+ CheckDlgButton(hwndDlg, IDC_FSCREEN, bFullScreenMode ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SSAVER, bScreenSaverRunning ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_LOCKED, bWorkstationLocked ? BST_CHECKED:BST_UNCHECKED);
+ if (!bWindowsNT)
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOCKED), FALSE);
+ CheckDlgButton(hwndDlg, IDC_PGMS, bProcessesAreRunning ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ACTIVE, bWorkstationActive ? BST_CHECKED:BST_UNCHECKED);
+
+ CheckDlgButton(hwndDlg, IDC_IFOPEN, bFlashIfMsgOpen ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_IFNOTTOP, bFlashIfMsgWinNotTop ? BST_CHECKED:BST_UNCHECKED);
+ if (!bFlashIfMsgOpen)
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IFNOTTOP), FALSE);
+ CheckDlgButton(hwndDlg, IDC_IFOLDER, bFlashIfMsgOlder ? BST_CHECKED:BST_UNCHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SOLDER), 0);
+ SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0));
+ SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETPOS, 0, MAKELONG(wSecondsOlder, 0));
+ if (!bFlashIfMsgOlder) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SOLDER), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_OLDERSPIN), FALSE);
+ }
+
+ CheckDlgButton(hwndDlg, IDC_UNTILBLK, bFlashUntil&UNTIL_NBLINKS ? BST_CHECKED:BST_UNCHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SBLINK), 0);
+ SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0));
+ SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(wBlinksNumber, 0));
+ if (!(bFlashUntil & UNTIL_NBLINKS)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SBLINK), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), FALSE);
+ }
+ CheckDlgButton(hwndDlg, IDC_UNTILATTENDED, bFlashUntil&UNTIL_REATTENDED ? BST_CHECKED:BST_UNCHECKED);
+ for (i=0; i < 2; i++) {
+ int index = SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)AttendedName[i]);
+ if (index != CB_ERR && index != CB_ERRSPACE)
+ SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_SETCURSEL, (WPARAM)bMirandaOrWindows, 0);
+ if (!(bFlashUntil & UNTIL_REATTENDED))
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MIRORWIN), FALSE);
+ CheckDlgButton(hwndDlg, IDC_UNTILOPEN, bFlashUntil&UNTIL_EVENTSOPEN ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_UNTILCOND, bFlashUntil&UNTIL_CONDITIONS ? BST_CHECKED:BST_UNCHECKED);
+
+ CheckDlgButton(hwndDlg, IDC_ONLINE, wStatusMap&MAP_ONLINE ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_AWAY, wStatusMap&MAP_AWAY ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_NA, wStatusMap&MAP_NA ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_OCCUPIED, wStatusMap&MAP_OCCUPIED ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DND, wStatusMap&MAP_DND ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_FREECHAT, wStatusMap&MAP_FREECHAT ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_INVISIBLE, wStatusMap&MAP_INVISIBLE ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ONTHEPHONE, wStatusMap&MAP_ONTHEPHONE ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_OUTTOLUNCH, wStatusMap&MAP_OUTTOLUNCH ? BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_OFFLINE, wStatusMap&MAP_OFFLINE ? BST_CHECKED:BST_UNCHECKED);
+
+ SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SREMCHECK), 0);
+ SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETRANGE32, 0, MAKELONG(UD_MAXVAL, 0));
+ SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETPOS, 0, MAKELONG(wReminderCheck, 0));
+
+ initDlg=FALSE;
+ return TRUE;
+
+ case WM_VSCROLL:
+ case WM_HSCROLL:
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ break;
+
+ case WM_DESTROY:
+ destroyProcessListAux();
+ break;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_ONMESSAGE:
+ case IDC_ONURL:
+ case IDC_ONFILE:
+ case IDC_ONOTHER:
+ case IDC_IFOPEN:
+ case IDC_IFNOTTOP:
+ case IDC_IFOLDER:
+ case IDC_UNTILBLK:
+ case IDC_UNTILATTENDED:
+ case IDC_MIRORWIN:
+ case IDC_UNTILOPEN:
+ case IDC_UNTILCOND:
+ case IDC_FSCREEN:
+ case IDC_SSAVER:
+ case IDC_LOCKED:
+ case IDC_PGMS:
+ case IDC_ACTIVE:
+ case IDC_ONLINE:
+ case IDC_AWAY:
+ case IDC_NA:
+ case IDC_OCCUPIED:
+ case IDC_DND:
+ case IDC_FREECHAT:
+ case IDC_INVISIBLE:
+ case IDC_ONTHEPHONE:
+ case IDC_OUTTOLUNCH:
+ case IDC_OFFLINE:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IFNOTTOP), IsDlgButtonChecked(hwndDlg, IDC_IFOPEN) == BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SOLDER), IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_OLDERSPIN), IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SBLINK), IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MIRORWIN), IsDlgButtonChecked(hwndDlg, IDC_UNTILATTENDED) == BST_CHECKED);
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case IDC_SOLDER:
+ if(HIWORD(wParam) == EN_CHANGE && !initDlg) {
+ BOOL translated;
+ int val = GetDlgItemInt(hwndDlg, IDC_SOLDER, &translated, FALSE);
+ if (translated && val < 1)
+ SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETPOS, 0, MAKELONG(val, 0));
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ }
+ return TRUE;
+ case IDC_SBLINK:
+ if(HIWORD(wParam) == EN_CHANGE && !initDlg) {
+ BOOL translated;
+ int val = GetDlgItemInt(hwndDlg, IDC_SBLINK, &translated, FALSE);
+ if (translated && val < 1)
+ SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(val, 0));
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ }
+ return TRUE;
+ case IDC_ASSIGNPGMS:
+ if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_PROCESSES), hwndDlg, DlgProcProcesses, 0) == IDC_OKPGM)
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case IDC_SREMCHECK:
+ if(HIWORD(wParam) == EN_CHANGE && !initDlg)
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ return TRUE;
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ unsigned int j;
+ BYTE untilMap = 0;
+ WORD statusMap = 0;
+ //Here we have pressed either the OK or the APPLY button.
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR)lParam)->code) {
+ case PSN_APPLY:
+ DBWriteContactSettingByte(NULL, FDDMODULE, "onmsg", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONMESSAGE) == BST_CHECKED ? 1:0));
+ DBWriteContactSettingByte(NULL, FDDMODULE, "onurl", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONURL) == BST_CHECKED ? 1:0));
+ DBWriteContactSettingByte(NULL, FDDMODULE, "onfile", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONFILE) == BST_CHECKED ? 1:0));
+ DBWriteContactSettingByte(NULL, FDDMODULE, "onother", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONOTHER) == BST_CHECKED ? 1:0));
+
+ DBWriteContactSettingByte(NULL, FDDMODULE, "fscreenmode", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_FSCREEN) == BST_CHECKED ? 1:0));
+ DBWriteContactSettingByte(NULL, FDDMODULE, "ssaverrunning", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SSAVER) == BST_CHECKED ? 1:0));
+ DBWriteContactSettingByte(NULL, FDDMODULE, "wstationlocked", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_LOCKED) == BST_CHECKED ? 1:0));
+ DBWriteContactSettingByte(NULL, FDDMODULE, "procsrunning", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_PGMS) == BST_CHECKED ? 1:0));
+ DBWriteContactSettingByte(NULL, FDDMODULE, "wstationactive", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ACTIVE) == BST_CHECKED ? 1:0));
+
+ DBWriteContactSettingByte(NULL, FDDMODULE, "ifmsgopen", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFOPEN) == BST_CHECKED ? 1:0));
+ DBWriteContactSettingByte(NULL, FDDMODULE, "ifmsgnottop", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFNOTTOP) == BST_CHECKED ? 1:0));
+ DBWriteContactSettingByte(NULL, FDDMODULE, "ifmsgolder", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED ? 1:0));
+ DBWriteContactSettingWord(NULL, FDDMODULE, "secsolder", (WORD)SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_GETPOS, 0, 0));
+
+ if(IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED)
+ untilMap |= UNTIL_NBLINKS;
+ if (IsDlgButtonChecked(hwndDlg, IDC_UNTILATTENDED) == BST_CHECKED)
+ untilMap |= UNTIL_REATTENDED;
+ if (IsDlgButtonChecked(hwndDlg, IDC_UNTILOPEN) == BST_CHECKED)
+ untilMap |= UNTIL_EVENTSOPEN;
+ if (IsDlgButtonChecked(hwndDlg, IDC_UNTILCOND) == BST_CHECKED)
+ untilMap |= UNTIL_CONDITIONS;
+ DBWriteContactSettingByte(NULL, FDDMODULE, "funtil", untilMap);
+ DBWriteContactSettingWord(NULL, FDDMODULE, "nblinks", (WORD)SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingByte(NULL, FDDMODULE, "mirorwin", (BYTE)SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_GETCURSEL, 0, 0), 0));
+
+ if(IsDlgButtonChecked(hwndDlg, IDC_ONLINE) == BST_CHECKED)
+ statusMap |= MAP_ONLINE;
+ if(IsDlgButtonChecked(hwndDlg, IDC_AWAY) == BST_CHECKED)
+ statusMap |= MAP_AWAY;
+ if(IsDlgButtonChecked(hwndDlg, IDC_NA) == BST_CHECKED)
+ statusMap |= MAP_NA;
+ if(IsDlgButtonChecked(hwndDlg, IDC_OCCUPIED) == BST_CHECKED)
+ statusMap |= MAP_OCCUPIED;
+ if(IsDlgButtonChecked(hwndDlg, IDC_DND) == BST_CHECKED)
+ statusMap |= MAP_DND;
+ if(IsDlgButtonChecked(hwndDlg, IDC_FREECHAT) == BST_CHECKED)
+ statusMap |= MAP_FREECHAT;
+ if(IsDlgButtonChecked(hwndDlg, IDC_INVISIBLE) == BST_CHECKED)
+ statusMap |= MAP_INVISIBLE;
+ if(IsDlgButtonChecked(hwndDlg, IDC_ONTHEPHONE) == BST_CHECKED)
+ statusMap |= MAP_ONTHEPHONE;
+ if(IsDlgButtonChecked(hwndDlg, IDC_OUTTOLUNCH) == BST_CHECKED)
+ statusMap |= MAP_OUTTOLUNCH;
+ if(IsDlgButtonChecked(hwndDlg, IDC_OFFLINE) == BST_CHECKED)
+ statusMap |= MAP_OFFLINE;
+ DBWriteContactSettingWord(NULL, FDDMODULE, "status", statusMap);
+
+ DBWriteContactSettingWord(NULL, FDDMODULE, "remcheck", (WORD)SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_GETPOS, 0, 0));
+
+ for (i=0, j=0; j < ProcessListAux.count; j++)
+ if (ProcessListAux.szFileName[j])
+ DBWriteContactSettingString(NULL, FDDMODULE, NumberToDBSetting("process", i++), ProcessListAux.szFileName[j]);
+ DBWriteContactSettingWord(NULL, FDDMODULE, "processcount", (WORD)i);
+ while (!DBDeleteContactSetting(NULL, FDDMODULE, NumberToDBSetting("process", i++)));
+
+ LoadSettings();
+
+ return TRUE;
+ } // switch code
+ break;
+ } //switch idFrom
+ }
+ break; //End WM_NOTIFY
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+INT_PTR CALLBACK DlgProcEffectOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static BOOL initDlg=FALSE;
+
+ switch (msg) {
+
+ case WM_INITDIALOG:
+ initDlg=TRUE;
+ TranslateDialogDefault(hwndDlg);
+
+ SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SDELAY), 0);
+ SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETRANGE32, 0, MAKELONG(UD_MAXVAL, 0));
+ SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETPOS, 0, MAKELONG(wStartDelay, 0));
+
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, FALSE, MAKELONG(0, 5));
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, bFlashSpeed);
+
+ initDlg=FALSE;
+ return TRUE;
+
+ case WM_VSCROLL:
+ case WM_HSCROLL:
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ break;
+
+ case WM_DESTROY:
+ previewFlashing(FALSE);
+ break;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_SPEED:
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case IDC_SDELAY:
+ if(HIWORD(wParam) == EN_CHANGE && !initDlg)
+ SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case IDC_PREVIEW:
+ previewFlashing(IsDlgButtonChecked(hwndDlg, IDC_PREVIEW) == BST_CHECKED);
+ return TRUE;
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ //Here we have pressed either the OK or the APPLY button.
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR)lParam)->code) {
+ case PSN_APPLY:
+ DBWriteContactSettingWord(NULL, FDDMODULE, "sdelay", (WORD)SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_GETPOS, 0, 0));
+
+ DBWriteContactSettingByte(NULL, FDDMODULE, "speed", (BYTE)SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0));
+
+ LoadSettings();
+
+ return TRUE;
+ } // switch code
+ break;
+ } //switch idFrom
+ }
+ break; //End WM_NOTIFY
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+// PreviewThread globals
+extern int nWaitDelay;
+BOOL bPreviewSemaphore, bPreview;
+
+
+//Preview Flashing functions
+
+void previewFlashing(BOOL buttonState)
+{
+ DWORD threadID = 0;
+
+ bPreview = buttonState;
+
+ if (!bPreview || bPreviewSemaphore) // turn off flashing or already running
+ return;
+
+ bPreviewSemaphore = TRUE;
+ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreviewThread, NULL, 0, &threadID);
+}
+
+static void PreviewThread(void *dummy)
+{
+ BYTE data = 0;
+
+ if (wStartDelay > 0)
+ Sleep(wStartDelay * 1000);
+
+ while (bPreview) {
+ data = !data;
+ ToggleFddLight(0, data);
+ Sleep(nWaitDelay);
+ }
+
+ ToggleFddLight(0, 0);
+
+ bPreviewSemaphore = FALSE;
+}
+
+
+INT_PTR CALLBACK DlgProcProcesses(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ unsigned int i;
+
+ switch (msg) {
+
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+
+ SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, EM_LIMITTEXT, MAX_PATH, 0);
+
+ for (i=0; i < ProcessListAux.count; i++)
+ if (ProcessListAux.szFileName[i]) {
+ int index = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)ProcessListAux.szFileName[i]);
+ if (index != CB_ERR && index != CB_ERRSPACE)
+ SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i);
+ }
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE);
+ if (SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0) == 0)
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE);
+ else
+ SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETCURSEL, 0, 0);
+
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_PROGRAMS:
+ switch (HIWORD(wParam)) {
+ int item;
+ char szFileName[MAX_PATH+1];
+
+ case CBN_SELENDOK:
+ case CBN_SELCHANGE:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE);
+ break;
+ case CBN_EDITCHANGE:
+ GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, sizeof(szFileName));
+ if ((item = SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)szFileName)) == CB_ERR) { //new program
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE);
+ } else {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE);
+ }
+ break;
+ }
+ break;
+ case IDC_ADDPGM:
+ {
+ int item;
+ char szFileName[MAX_PATH+1];
+
+ GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, sizeof(szFileName));
+ if (!szFileName[0])
+ break;
+ item = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_ADDSTRING, 0, (LPARAM)szFileName);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE);
+ }
+ break;
+ case IDC_DELETEPGM:
+ {
+ int item;
+ char szFileName[MAX_PATH+1];
+
+ GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, sizeof(szFileName));
+ item = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_FINDSTRINGEXACT, -1, (LPARAM)szFileName);
+ SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_DELETESTRING, (WPARAM)item, 0);
+ if (SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0) == 0) {
+ SetDlgItemText(hwndDlg, IDC_PROGRAMS, "");
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE);
+ } else
+ SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETCURSEL, 0, 0);
+ }
+ break;
+ case IDC_OKPGM:
+ destroyProcessListAux();
+
+ ProcessListAux.count = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0);
+ ProcessListAux.szFileName = (char **)malloc(ProcessListAux.count * sizeof(char *));
+ if (!ProcessListAux.szFileName)
+ ProcessListAux.count = 0;
+ else
+ for (i=0; i < ProcessListAux.count; i++) {
+ char szFileNameAux[MAX_PATH+1];
+
+ SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETLBTEXT, (WPARAM)i, (LPARAM)szFileNameAux);
+ ProcessListAux.szFileName[i] = (char *)malloc(strlen(szFileNameAux) + 1);
+ if (ProcessListAux.szFileName[i])
+ strcpy(ProcessListAux.szFileName[i], szFileNameAux);
+ }
+
+ case IDC_CANCELPGM:
+ EndDialog(hwndDlg, LOWORD(wParam));
+ break;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+
+void createProcessListAux(void)
+{
+ unsigned int i;
+
+ ProcessListAux.count = ProcessList.count;
+ ProcessListAux.szFileName = (char **)malloc(ProcessListAux.count * sizeof(char *));
+ if (!ProcessListAux.szFileName)
+ ProcessListAux.count = 0;
+ else
+ for (i=0; i < ProcessListAux.count; i++)
+ if (!ProcessList.szFileName[i])
+ ProcessListAux.szFileName[i] = NULL;
+ else {
+ ProcessListAux.szFileName[i] = (char *)malloc(strlen(ProcessList.szFileName[i]) + 1);
+ if (ProcessListAux.szFileName[i])
+ strcpy(ProcessListAux.szFileName[i], ProcessList.szFileName[i]);
+ }
+
+}
+
+
+void destroyProcessListAux(void)
+{
+ unsigned int i;
+
+ for(i=0; i < ProcessListAux.count; i++)
+ if (ProcessListAux.szFileName[i])
+ free(ProcessListAux.szFileName[i]);
+
+ if (ProcessListAux.szFileName)
+ free(ProcessListAux.szFileName);
+
+ ProcessListAux.count = 0;
+ ProcessListAux.szFileName = NULL;
+}
+
+
+char *NumberToDBSetting(const char* name, int sequence)
+{
+ static char returnString[50];
+
+ _snprintf(returnString, sizeof(returnString), "%s%d", name, sequence);
+
+ return returnString;
+}
diff --git a/fddnotify/protolist.h b/fddnotify/protolist.h new file mode 100644 index 0000000..434dd55 --- /dev/null +++ b/fddnotify/protolist.h @@ -0,0 +1,28 @@ +/*
+
+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.
+
+*/
+
+typedef struct {
+ char *szProto;
+ BOOL enabled;
+ BOOL visible;
+} PROTOCOL_INFO;
+
+typedef struct {
+ int protoCount;
+ PROTOCOL_INFO *protoInfo;
+} PROTOCOL_LIST;
diff --git a/fddnotify/resource.h b/fddnotify/resource.h new file mode 100644 index 0000000..a9f1438 --- /dev/null +++ b/fddnotify/resource.h @@ -0,0 +1,65 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resources.rc
+//
+#define IDD_OPTIONS 150
+#define IDD_PROTO_OPTIONS 151
+#define IDD_BASIC_OPTIONS 152
+#define IDD_EFFECT_OPTIONS 153
+#define IDD_PROCESSES 154
+#define IDC_ONMESSAGE 1000
+#define IDC_ONFILE 1001
+#define IDC_ONURL 1002
+#define IDC_ONOTHER 1003
+#define IDC_IFOPEN 1004
+#define IDC_IFNOTTOP 1005
+#define IDC_IFOLDER 1006
+#define IDC_SOLDER 1007
+#define IDC_OLDERSPIN 1008
+#define IDC_UNTILBLK 1009
+#define IDC_SBLINK 1010
+#define IDC_BLINKSPIN 1011
+#define IDC_UNTILATTENDED 1012
+#define IDC_MIRORWIN 1013
+#define IDC_UNTILOPEN 1014
+#define IDC_UNTILCOND 1015
+#define IDC_FSCREEN 1016
+#define IDC_SSAVER 1017
+#define IDC_LOCKED 1018
+#define IDC_PGMS 1019
+#define IDC_ASSIGNPGMS 1020
+#define IDC_ACTIVE 1021
+#define IDC_ONLINE 1022
+#define IDC_AWAY 1023
+#define IDC_NA 1024
+#define IDC_OCCUPIED 1025
+#define IDC_DND 1026
+#define IDC_FREECHAT 1027
+#define IDC_INVISIBLE 1028
+#define IDC_ONTHEPHONE 1029
+#define IDC_OUTTOLUNCH 1030
+#define IDC_OFFLINE 1031
+#define IDC_REMCHECK 1032
+#define IDC_SREMCHECK 1033
+#define IDC_SDELAY 1034
+#define IDC_DELAYSPIN 1035
+#define IDC_SPEED 1036
+#define IDC_PREVIEW 1037
+#define IDC_PROTOCOLLIST 1038
+#define IDC_PROGRAMS 1039
+#define IDC_ADDPGM 1040
+#define IDC_DELETEPGM 1041
+#define IDC_OKPGM 1042
+#define IDC_CANCELPGM 1043
+#define IDC_TABS 2000
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1044
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/fddnotify/resources.rc b/fddnotify/resources.rc new file mode 100644 index 0000000..0dd398b --- /dev/null +++ b/fddnotify/resources.rc @@ -0,0 +1,238 @@ +//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPTIONS DIALOGEX 0, 0, 323, 245
+STYLE DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "Tab1",IDC_TABS,"SysTabControl32",TCS_FIXEDWIDTH | 0x8,0,
+ 0,317,245
+END
+
+IDD_PROTO_OPTIONS DIALOGEX 1, 15, 314, 229
+STYLE DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Protocols to check",IDC_STATIC,81,6,149,143
+ CONTROL "",IDC_PROTOCOLLIST,"SysListView32",LVS_REPORT |
+ LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER |
+ WS_TABSTOP,105,25,100,108
+END
+
+IDD_BASIC_OPTIONS DIALOGEX 1, 15, 314, 229
+STYLE DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "Events to react on",IDC_STATIC,8,6,147,68
+ CONTROL "Incoming messages",IDC_ONMESSAGE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,24,18,127,10
+ CONTROL "Incoming files",IDC_ONFILE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,24,31,127,10
+ CONTROL "Incoming URLs",IDC_ONURL,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,24,44,127,10
+ CONTROL "Everything else",IDC_ONOTHER,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,24,57,128,10
+ GROUPBOX "Message-Event only",IDC_STATIC,8,79,147,57
+ CONTROL "Blink if message window is open",IDC_IFOPEN,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,24,91,126,10
+ CONTROL " ... and not in foreground",IDC_IFNOTTOP,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,24,104,125,10
+ CONTROL "Only if last is",IDC_IFOLDER,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,24,117,54,10
+ EDITTEXT IDC_SOLDER,81,116,36,13,ES_NUMBER
+ CONTROL "Spin1",IDC_OLDERSPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,107,116,
+ 9,13
+ LTEXT "sec. old",IDC_STATIC,119,118,29,10
+ GROUPBOX "Flash until",IDC_STATIC,8,141,147,78
+ CONTROL "",IDC_UNTILBLK,"Button",BS_AUTOCHECKBOX | WS_GROUP,24,
+ 156,11,10
+ EDITTEXT IDC_SBLINK,36,154,44,13,ES_NUMBER
+ CONTROL "Spin1",IDC_BLINKSPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,68,154,
+ 9,13
+ LTEXT "seconds",IDC_STATIC,83,156,67,10
+ CONTROL "",IDC_UNTILATTENDED,"Button",BS_AUTOCHECKBOX,24,171,11,
+ 10
+ COMBOBOX IDC_MIRORWIN,36,169,44,96,CBS_DROPDOWNLIST | WS_TABSTOP
+ LTEXT "is re-attended",IDC_STATIC,83,171,67,10
+ CONTROL "Events are opened",IDC_UNTILOPEN,"Button",
+ BS_AUTOCHECKBOX,24,186,125,10
+ CONTROL "End of 'notify when' conditions",IDC_UNTILCOND,"Button",
+ BS_AUTOCHECKBOX,24,200,126,10
+ GROUPBOX "Notify when",IDC_STATIC,160,6,147,68
+ CONTROL "Full Screen mode",IDC_FSCREEN,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,173,16,117,10
+ CONTROL "Screen Saver is running",IDC_SSAVER,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,173,27,117,10
+ CONTROL "Workstation is Locked (2000/XP)",IDC_LOCKED,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,173,38,117,10
+ CONTROL "Defined programs are running",IDC_PGMS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,173,49,111,10
+ PUSHBUTTON "...",IDC_ASSIGNPGMS,287,51,15,9
+ CONTROL "All other situations",IDC_ACTIVE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,173,60,117,10
+ GROUPBOX "Only notify if status is",IDC_STATIC,160,79,147,107
+ CONTROL "Online",IDC_ONLINE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,173,90,65,9
+ CONTROL "Away",IDC_AWAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 173,100,128,9
+ CONTROL "Occupied",IDC_OCCUPIED,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,173,120,128,9
+ CONTROL "NA",IDC_NA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,
+ 110,128,9
+ CONTROL "DND",IDC_DND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,
+ 130,127,9
+ CONTROL "Free for chat",IDC_FREECHAT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,173,140,127,9
+ CONTROL "Invisible",IDC_INVISIBLE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,173,150,128,9
+ CONTROL "On the phone",IDC_ONTHEPHONE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,173,160,128,9
+ CONTROL "Out to lunch",IDC_OUTTOLUNCH,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,173,170,127,9
+ GROUPBOX "Pending Events",IDC_STATIC,160,191,147,28
+ LTEXT "Remind me every",IDC_STATIC,173,202,58,9
+ EDITTEXT IDC_SREMCHECK,231,200,37,13,ES_NUMBER
+ CONTROL "Spin1",IDC_REMCHECK,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,257,200,
+ 9,13
+ LTEXT "minutes",IDC_STATIC,271,202,30,9
+ CONTROL "Offline",IDC_OFFLINE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,242,90,61,9
+END
+
+IDD_EFFECT_OPTIONS DIALOGEX 1, 15, 314, 229
+STYLE DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "Wait before starting flashing",IDC_STATIC,8,6,147,54
+ EDITTEXT IDC_SDELAY,29,26,39,14,ES_NUMBER
+ LTEXT "seconds",IDC_STATIC,72,28,80,9
+ GROUPBOX "Flash speed",IDC_STATIC,160,6,147,54
+ CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_AUTOTICKS |
+ WS_TABSTOP,170,32,127,19
+ RTEXT "Fast",IDC_STATIC,238,17,50,9
+ LTEXT "Slow",IDC_STATIC,178,17,55,8
+ CONTROL "Spin1",IDC_DELAYSPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,57,27,9,
+ 12
+ CONTROL "&Preview",IDC_PREVIEW,"Button",BS_AUTOCHECKBOX |
+ BS_PUSHLIKE,125,173,63,14
+END
+
+IDD_PROCESSES DIALOG DISCARDABLE 175, 60, 176, 98
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Set program list"
+FONT 8, "MS Sans Serif"
+BEGIN
+ LTEXT "Program",IDC_STATIC,13,20,34,9
+ COMBOBOX IDC_PROGRAMS,53,18,107,96,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Add",IDC_ADDPGM,36,41,44,14
+ PUSHBUTTON "Delete",IDC_DELETEPGM,99,41,44,14
+ DEFPUSHBUTTON "OK",IDC_OKPGM,119,77,50,14
+ PUSHBUTTON "Cancel",IDC_CANCELPGM,63,77,50,14
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ RIGHTMARGIN, 317
+ END
+
+ IDD_BASIC_OPTIONS, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 220
+ END
+END
+#endif // APSTUDIO_INVOKED
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// French (Canada) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRC)
+#ifdef _WIN32
+LANGUAGE LANG_FRENCH, SUBLANG_FRENCH_CANADIAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // French (Canada) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
|