From 6947bf39094feaa786b8eaf93b74eea34a775ea6 Mon Sep 17 00:00:00 2001 From: Damien Gerard Date: Thu, 9 Mar 2017 01:53:57 +0900 Subject: [PATCH] winmain: add newline at the end of file winmain: move local functions to anonymous namespace winmain: remove redundant static keyword winmain: add newline at the end of file winmain: move UAC related code to anonymous function winmain: declare MSGFLT_ADD/MSGFLT_ALLOW only if not already defined winmain: check only for emptiness parameters: move winKeyDefs & scintKeyDefs & PGNSI to anonymous names parameters: remove redundant static/inline keywords misc: remove unused source code Closes #3030 --- .../Process/ProcessAvecThread/Process.cpp | 265 ------------------ .../MISC/Process/ProcessAvecThread/Process.h | 98 ------- .../Process/ProcessAvecThread/ProcessThread.h | 100 ------- PowerEditor/src/Parameters.cpp | 16 +- PowerEditor/src/winmain.cpp | 85 +++--- 5 files changed, 57 insertions(+), 507 deletions(-) delete mode 100644 PowerEditor/src/MISC/Process/ProcessAvecThread/Process.cpp delete mode 100644 PowerEditor/src/MISC/Process/ProcessAvecThread/Process.h delete mode 100644 PowerEditor/src/MISC/Process/ProcessAvecThread/ProcessThread.h diff --git a/PowerEditor/src/MISC/Process/ProcessAvecThread/Process.cpp b/PowerEditor/src/MISC/Process/ProcessAvecThread/Process.cpp deleted file mode 100644 index 26086a37f..000000000 --- a/PowerEditor/src/MISC/Process/ProcessAvecThread/Process.cpp +++ /dev/null @@ -1,265 +0,0 @@ -// This file is part of Notepad++ project -// Copyright (C)2003 Don HO -// -// 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. -// -// Note that the GPL places important restrictions on "derived works", yet -// it does not provide a detailed definition of that term. To avoid -// misunderstandings, we consider an application to constitute a -// "derivative work" for the purpose of this license if it does any of the -// following: -// 1. Integrates source code from Notepad++. -// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable -// installer, such as those produced by InstallShield. -// 3. Links to a library or executes a program that does any of the above. -// -// 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., 675 Mass Ave, Cambridge, MA 02139, USA. - - -#include "precompiledHeaders.h" -#include "process.h" -//#include "SysMsg.h" - - - - -BOOL Process::run() -{ - BOOL result = TRUE; - - // stdout & stderr pipes for process to write - HANDLE hPipeOutW = NULL; - HANDLE hPipeErrW = NULL; - - HANDLE hListenerStdOutThread = NULL; - HANDLE hListenerStdErrThread = NULL; - - HANDLE hListenerEvent[2]; - hListenerEvent[0] = NULL; - hListenerEvent[1] = NULL; - - SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; // inheritable handle - - try - { - // Create stdout pipe - if (!::CreatePipe(&_hPipeOutR, &hPipeOutW, &sa, 0)) - error(TEXT("CreatePipe"), result, 1000); - - // Create stderr pipe - if (!::CreatePipe(&_hPipeErrR, &hPipeErrW, &sa, 0)) - error(TEXT("CreatePipe"), result, 1001); - - STARTUPINFO startup; - PROCESS_INFORMATION procinfo; - ::ZeroMemory(&startup, sizeof(startup)); - startup.cb = sizeof(startup); - startup.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; - startup.wShowWindow = SW_HIDE; // hidden console window - startup.hStdInput = NULL; // not used - startup.hStdOutput = hPipeOutW; - startup.hStdError = hPipeErrW; - - BOOL started = ::CreateProcess(NULL, // command is part of input string - _command, // (writeable) command string - NULL, // process security - NULL, // thread security - TRUE, // inherit handles flag - CREATE_SUSPENDED, // flags - NULL, // inherit environment - _curDir, // inherit directory - &startup, // STARTUPINFO - &procinfo); // PROCESS_INFORMATION - - _hProcess = procinfo.hProcess; - _hProcessThread = procinfo.hThread; - - if (!started) - error(TEXT("CreateProcess"), result, 1002); - - hListenerEvent[0] = ::CreateEvent(NULL, FALSE, FALSE, TEXT("listenerEvent")); - if (!hListenerEvent[0]) - error(TEXT("CreateEvent"), result, 1003); - - hListenerEvent[1] = ::CreateEvent(NULL, FALSE, FALSE, TEXT("listenerStdErrEvent")); - if (!hListenerEvent[1]) - error(TEXT("CreateEvent"), result, 1004); - - hListenerStdOutThread = ::CreateThread(NULL, 0, staticListenerStdOut, this, 0, NULL); - if (!hListenerStdOutThread) - error(TEXT("CreateThread"), result, 1005); - - hListenerStdErrThread = ::CreateThread(NULL, 0, staticListenerStdErr, this, 0, NULL); - if (!hListenerStdErrThread) - error(TEXT("CreateThread"), result, 1006); - - ::WaitForSingleObject(_hProcess, INFINITE); - ::WaitForMultipleObjects(2, hListenerEvent, TRUE, INFINITE); - } - catch (int /*coderr*/) - {} - - // on va fermer toutes les handles - if (hPipeOutW) - ::CloseHandle(hPipeOutW); - if (hPipeErrW) - ::CloseHandle(hPipeErrW); - if (_hPipeOutR) - ::CloseHandle(_hPipeOutR); - if (_hPipeErrR) - ::CloseHandle(_hPipeErrR); - if (hListenerStdOutThread) - ::CloseHandle(hListenerStdOutThread); - if (hListenerStdErrThread) - ::CloseHandle(hListenerStdErrThread); - if (hListenerEvent[0]) - ::CloseHandle(hListenerEvent[0]); - if (hListenerEvent[1]) - ::CloseHandle(hListenerEvent[1]); - - return result; -} - - -#define MAX_LINE_LENGTH 1024 - -void Process::listenerStdOut() -{ - DWORD bytesAvail = 0; - BOOL result = 0; - HANDLE hListenerEvent = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("listenerEvent")); - - TCHAR bufferOut[MAX_LINE_LENGTH + 1]; - - int nExitCode = STILL_ACTIVE; - - DWORD outbytesRead; - - ::ResumeThread(_hProcessThread); - - bool goOn = true; - while (goOn) - { // got data - memset(bufferOut,0x00,MAX_LINE_LENGTH + 1); - int size = sizeof(bufferOut) - sizeof(TCHAR); - - Sleep(50); - - if (!::PeekNamedPipe(_hPipeOutR, bufferOut, size, &outbytesRead, &bytesAvail, NULL)) - { - bytesAvail = 0; - goOn = false; - break; - } - - if (outbytesRead) - { - result = :: ReadFile(_hPipeOutR, bufferOut, size, &outbytesRead, NULL); - if ((!result) && (outbytesRead == 0)) - { - goOn = false; - break; - } - } - - bufferOut[outbytesRead] = '\0'; - generic_string s; - s.assign(bufferOut); - _stdoutStr += s; - - if (::GetExitCodeProcess(_hProcess, (unsigned long*)&nExitCode)) - { - if (nExitCode != STILL_ACTIVE) - { - goOn = false; - break; // EOF condition - } - } - //else - //break; - } - _exitCode = nExitCode; - - if (!::SetEvent(hListenerEvent)) - { - systemMessage(TEXT("Thread listenerStdOut")); - } -} - -void Process::listenerStdErr() -{ - DWORD bytesAvail = 0; - BOOL result = 0; - HANDLE hListenerEvent = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("listenerStdErrEvent")); - - TCHAR bufferErr[MAX_LINE_LENGTH + 1]; - int nExitCode = STILL_ACTIVE; - - ::ResumeThread(_hProcessThread); - - bool goOn = true; - while (goOn) - { // got data - memset(bufferErr, 0x00, MAX_LINE_LENGTH + 1); - size_t size = sizeof(bufferErr) - sizeof(TCHAR); - - Sleep(50); - DWORD errbytesRead; - if (!::PeekNamedPipe(_hPipeErrR, bufferErr, size, &errbytesRead, &bytesAvail, NULL)) - { - bytesAvail = 0; - goOn = false; - break; - } - - if (errbytesRead) - { - result = :: ReadFile(_hPipeErrR, bufferErr, size, &errbytesRead, NULL); - if ((!result) && (errbytesRead == 0)) - { - goOn = false; - break; - } - } - bufferErr[errbytesRead] = '\0'; - generic_string s; - s.assign(bufferErr); - _stderrStr += s; - - if (::GetExitCodeProcess(_hProcess, (unsigned long*)&nExitCode)) - { - if (nExitCode != STILL_ACTIVE) - { - goOn = false; - break; // EOF condition - } - } - //else - //break; - } - //_exitCode = nExitCode; - - if (!::SetEvent(hListenerEvent)) - { - systemMessage(TEXT("Thread stdout listener")); - } -} - - -void Process::error(const TCHAR *txt2display, BOOL & returnCode, int errCode) -{ - systemMessage(txt2display); - returnCode = FALSE; - throw int(errCode); -} - diff --git a/PowerEditor/src/MISC/Process/ProcessAvecThread/Process.h b/PowerEditor/src/MISC/Process/ProcessAvecThread/Process.h deleted file mode 100644 index d4f8c6d24..000000000 --- a/PowerEditor/src/MISC/Process/ProcessAvecThread/Process.h +++ /dev/null @@ -1,98 +0,0 @@ -// This file is part of Notepad++ project -// Copyright (C)2003 Don HO -// -// 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. -// -// Note that the GPL places important restrictions on "derived works", yet -// it does not provide a detailed definition of that term. To avoid -// misunderstandings, we consider an application to constitute a -// "derivative work" for the purpose of this license if it does any of the -// following: -// 1. Integrates source code from Notepad++. -// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable -// installer, such as those produced by InstallShield. -// 3. Links to a library or executes a program that does any of the above. -// -// 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., 675 Mass Ave, Cambridge, MA 02139, USA. - - -#pragma once - -#include -//#include -using namespace std; - -class Process -{ -public: - Process() {} - Process(const TCHAR *cmd, const TCHAR *cDir) - { - lstrcpy(_command, cmd); - lstrcpy(_curDir, cDir); - } - - BOOL run(); - - const TCHAR * getStdout() const { - return _stdoutStr.c_str(); - } - - const TCHAR * getStderr() const { - return _stderrStr.c_str(); - } - - int getExitCode() const { - return _exitCode; - } - - bool hasStdout() { - return (_stdoutStr.compare(TEXT("")) != 0); - } - - bool hasStderr() { - return (_stderrStr.compare(TEXT("")) != 0); - } - -protected: - // LES ENTREES - TCHAR _command[256]; - TCHAR _curDir[256]; - - // LES SORTIES - generic_string _stdoutStr; - generic_string _stderrStr; - int _exitCode = 0; - - // LES HANDLES - HANDLE _hPipeOutR = nullptr; - HANDLE _hPipeErrR = nullptr; - HANDLE _hProcess = nullptr; - HANDLE _hProcessThread = nullptr; - - //UINT _pid; // process ID assigned by caller - - static DWORD WINAPI staticListenerStdOut(void * myself){ - static_cast(myself)->listenerStdOut(); - return 0; - }; - static DWORD WINAPI staticListenerStdErr(void * myself) { - static_cast(myself)->listenerStdErr(); - return 0; - }; - void listenerStdOut(); - void listenerStdErr(); - void error(const TCHAR *txt2display, BOOL & returnCode, int errCode); -}; - - diff --git a/PowerEditor/src/MISC/Process/ProcessAvecThread/ProcessThread.h b/PowerEditor/src/MISC/Process/ProcessAvecThread/ProcessThread.h deleted file mode 100644 index a6274fd94..000000000 --- a/PowerEditor/src/MISC/Process/ProcessAvecThread/ProcessThread.h +++ /dev/null @@ -1,100 +0,0 @@ -// This file is part of Notepad++ project -// Copyright (C)2003 Don HO -// -// 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. -// -// Note that the GPL places important restrictions on "derived works", yet -// it does not provide a detailed definition of that term. To avoid -// misunderstandings, we consider an application to constitute a -// "derivative work" for the purpose of this license if it does any of the -// following: -// 1. Integrates source code from Notepad++. -// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable -// installer, such as those produced by InstallShield. -// 3. Links to a library or executes a program that does any of the above. -// -// 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., 675 Mass Ave, Cambridge, MA 02139, USA. - - -#ifndef PROCESS_THREAD_H -#define PROCESS_THREAD_H - -#include "process.h" - -class ProcessThread -{ -public: - ProcessThread(const TCHAR *appName, const TCHAR *cmd, const TCHAR *cDir, HWND hwnd) - : _hwnd(hwnd) - { - lstrcpy(_appName, appName); - lstrcpy(_command, cmd); - lstrcpy(_curDir, cDir); - } - - BOOL run() - { - HANDLE hEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("localVarProcessEvent")); - - _hProcessThread = ::CreateThread(NULL, 0, staticLauncher, this, 0, NULL); - - ::WaitForSingleObject(hEvent, INFINITE); - - ::CloseHandle(hEvent); - return TRUE; - } - - -protected: - // ENTREES - TCHAR _appName[256]; - TCHAR _command[256]; - TCHAR _curDir[256]; - HWND _hwnd; - HANDLE _hProcessThread; - - static DWORD WINAPI staticLauncher(void *myself) - { - ((ProcessThread *)myself)->launch(); - return TRUE; - } - - bool launch() - { - HANDLE hEvent = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("localVarProcessEvent")); - HWND hwnd = _hwnd; - TCHAR appName[256]; - lstrcpy(appName, _appName); - HANDLE hMyself = _hProcessThread; - - Process process(_command, _curDir); - - if (!::SetEvent(hEvent)) - systemMessage(TEXT("Thread launcher")); - - process.run(); - - int code = process.getExitCode(); - TCHAR codeStr[256]; - generic_sprintf(codeStr, TEXT("%s : %0.4X"), appName, code); - ::MessageBox(hwnd, process.getStdout(), codeStr, MB_OK); - - if (process.hasStderr()) - ::MessageBox(hwnd, process.getStderr(), codeStr, MB_OK); - - ::CloseHandle(hMyself); - return true; - } -}; - -#endif PROCESS_THREAD_H diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 6796bb157..399daa58a 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -39,6 +39,8 @@ using namespace std; +namespace // anonymous namespace +{ struct WinMenuKeyDefinition //more or less matches accelerator table definition, easy copy/paste @@ -513,10 +515,8 @@ typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); -namespace // anonymous namespace -{ - static int strVal(const TCHAR *str, int base) + int strVal(const TCHAR *str, int base) { if (!str) return -1; if (!str[0]) return 0; @@ -529,17 +529,17 @@ namespace // anonymous namespace } - static int decStrVal(const TCHAR *str) + int decStrVal(const TCHAR *str) { return strVal(str, 10); } - static int hexStrVal(const TCHAR *str) + int hexStrVal(const TCHAR *str) { return strVal(str, 16); } - static int getKwClassFromName(const TCHAR *str) + int getKwClassFromName(const TCHAR *str) { if (!lstrcmp(TEXT("instre1"), str)) return LANG_INDEX_INSTR; if (!lstrcmp(TEXT("instre2"), str)) return LANG_INDEX_INSTR2; @@ -556,13 +556,13 @@ namespace // anonymous namespace } - static inline size_t getAsciiLenFromBase64Len(size_t base64StrLen) + size_t getAsciiLenFromBase64Len(size_t base64StrLen) { return (base64StrLen % 4) ? 0 : (base64StrLen - base64StrLen / 4); } - static int base64ToAscii(char *dest, const char *base64Str) + int base64ToAscii(char *dest, const char *base64Str) { static const int base64IndexArray[123] = { diff --git a/PowerEditor/src/winmain.cpp b/PowerEditor/src/winmain.cpp index 944488a07..03e27f7a2 100644 --- a/PowerEditor/src/winmain.cpp +++ b/PowerEditor/src/winmain.cpp @@ -33,9 +33,53 @@ typedef std::vector ParamVector; +namespace +{ + + +void allowWmCopydataMessages(Notepad_plus_Window& notepad_plus_plus, const NppParameters* pNppParameters, winVer ver) +{ + #ifndef MSGFLT_ADD + const DWORD MSGFLT_ADD = 1; + #endif + #ifndef MSGFLT_ALLOW + const DWORD MSGFLT_ALLOW = 1; + #endif + // Tell UAC that lower integrity processes are allowed to send WM_COPYDATA messages to this process (or window) + // This allows opening new files to already opened elevated Notepad++ process via explorer context menu. + if (ver >= WV_VISTA || ver == WV_UNKNOWN) + { + HMODULE hDll = GetModuleHandle(TEXT("user32.dll")); + if (hDll) + { + // According to MSDN ChangeWindowMessageFilter may not be supported in future versions of Windows, + // that is why we use ChangeWindowMessageFilterEx if it is available (windows version >= Win7). + if (pNppParameters->getWinVersion() == WV_VISTA) + { + typedef BOOL (WINAPI *MESSAGEFILTERFUNC)(UINT message,DWORD dwFlag); + + MESSAGEFILTERFUNC func = (MESSAGEFILTERFUNC)::GetProcAddress( hDll, "ChangeWindowMessageFilter" ); + + if (func) + func(WM_COPYDATA, MSGFLT_ADD); + } + else + { + typedef BOOL (WINAPI *MESSAGEFILTERFUNCEX)(HWND hWnd,UINT message,DWORD action,VOID* pChangeFilterStruct); + + MESSAGEFILTERFUNCEX func = (MESSAGEFILTERFUNCEX)::GetProcAddress( hDll, "ChangeWindowMessageFilterEx" ); + + if (func) + func(notepad_plus_plus.getHSelf(), WM_COPYDATA, MSGFLT_ALLOW, NULL ); + } + } + } +} + + bool checkSingleFile(const TCHAR *commandLine) { - if (!commandLine || lstrlen(commandLine) == 0) + if (!commandLine || commandLine[0] == TEXT('\0')) return false; TCHAR fullpath[MAX_PATH] = {0}; @@ -242,7 +286,7 @@ const TCHAR FLAG_OPENSESSIONFILE[] = TEXT("-openSession"); const TCHAR FLAG_RECURSIVE[] = TEXT("-r"); -static void doException(Notepad_plus_Window & notepad_plus_plus) +void doException(Notepad_plus_Window & notepad_plus_plus) { Win32Exception::removeHandler(); //disable exception handler after excpetion, we dont want corrupt data structurs to crash the exception handler ::MessageBox(Notepad_plus_Window::gNppHWND, TEXT("Notepad++ will attempt to save any unsaved data. However, dataloss is very likely."), TEXT("Recovery initiating"), MB_OK | MB_ICONINFORMATION); @@ -264,6 +308,7 @@ static void doException(Notepad_plus_Window & notepad_plus_plus) } +} // namespace @@ -449,39 +494,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) try { notepad_plus_plus.init(hInstance, NULL, quotFileName.c_str(), &cmdLineParams); - - // Tell UAC that lower integrity processes are allowed to send WM_COPYDATA messages to this process (or window) - // This allows opening new files to already opened elevated Notepad++ process via explorer context menu. - if (ver >= WV_VISTA || ver == WV_UNKNOWN) - { - HMODULE hDll = GetModuleHandle(TEXT("user32.dll")); - if (hDll) - { - // According to MSDN ChangeWindowMessageFilter may not be supported in future versions of Windows, - // that is why we use ChangeWindowMessageFilterEx if it is available (windows version >= Win7). - if (pNppParameters->getWinVersion() == WV_VISTA) - { - typedef BOOL (WINAPI *MESSAGEFILTERFUNC)(UINT message,DWORD dwFlag); - const DWORD MSGFLT_ADD = 1; - - MESSAGEFILTERFUNC func = (MESSAGEFILTERFUNC)::GetProcAddress( hDll, "ChangeWindowMessageFilter" ); - - if (func) - func(WM_COPYDATA, MSGFLT_ADD); - } - else - { - typedef BOOL (WINAPI *MESSAGEFILTERFUNCEX)(HWND hWnd,UINT message,DWORD action,VOID* pChangeFilterStruct); - const DWORD MSGFLT_ALLOW = 1; - - MESSAGEFILTERFUNCEX func = (MESSAGEFILTERFUNCEX)::GetProcAddress( hDll, "ChangeWindowMessageFilterEx" ); - - if (func) - func(notepad_plus_plus.getHSelf(), WM_COPYDATA, MSGFLT_ALLOW, NULL ); - } - } - } - + allowWmCopydataMessages(notepad_plus_plus, pNppParameters, ver); bool going = true; while (going) { @@ -534,4 +547,4 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) } return static_cast(msg.wParam); -} \ No newline at end of file +}