From 487f2baa9d6f564ffb416d13b9c8d9bc776c0804 Mon Sep 17 00:00:00 2001 From: Igal Tabachnik Date: Thu, 28 Apr 2016 14:46:45 +0300 Subject: [PATCH 1/3] Adding a new '-buffer' switch, allowing to replace the contents of the editor from the specified file. This is needed to replace the text buffer from a temp. save file between re-launching as elevated. --- src/Notepad2.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Notepad2.c b/src/Notepad2.c index 8f2dc84c..3ef100e3 100644 --- a/src/Notepad2.c +++ b/src/Notepad2.c @@ -94,6 +94,7 @@ TBBUTTON tbbMainWnd[] = { {0,IDT_FILE_NEW,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0}, WCHAR szIniFile[MAX_PATH] = L""; WCHAR szIniFile2[MAX_PATH] = L""; +WCHAR szBufferFile[MAX_PATH] = L""; BOOL bSaveSettings; BOOL bSaveRecentFiles; BOOL bSaveFindReplace; @@ -373,6 +374,7 @@ int flagQuietCreate = 0; int flagUseSystemMRU = 0; int flagRelaunchElevated = 0; int flagDisplayHelp = 0; +int flagBufferFile = 0; @@ -875,8 +877,16 @@ HWND InitInstance(HINSTANCE hInstance,LPSTR pszCmdLine,int nCmdShow) if (OpenFileDlg(hwndMain,tchFile,COUNTOF(tchFile),lpFileArg)) bOpened = FileLoad(FALSE,FALSE,FALSE,FALSE,tchFile); } - else { - if (bOpened = FileLoad(FALSE,FALSE,FALSE,FALSE,lpFileArg)) { + else + { + LPCWSTR lpFileToOpen = flagBufferFile ? szBufferFile : lpFileArg; + if (bOpened = FileLoad(FALSE, FALSE, FALSE, FALSE, lpFileToOpen)) { + if (flagBufferFile) { + lstrcpy(szCurFile, lpFileArg); + bModified = TRUE; + SetWindowTitle(hwndMain, uidsAppTitle, fIsElevated, IDS_UNTITLED, lpFileArg, + iPathNameFormat, bModified, IDS_READONLY, bReadOnly, szTitleExcerpt); + } if (flagJumpTo) { // Jump to position EditJumpTo(hwndEdit,iInitialLine,iInitialColumn); EditEnsureSelectionVisible(hwndEdit); @@ -6031,6 +6041,14 @@ void ParseCommandLine() else flagUseSystemMRU = 1; } + else if (StrCmpNI(lp1,L"buffer",CSTRLEN(L"buffer")) == 0) { + if (ExtractFirstArgument(lp2, lp1, lp2)) { + StrCpyN(szBufferFile, lp1, COUNTOF(szBufferFile)); + TrimString(szBufferFile); + PathUnquoteSpaces(szBufferFile); + flagBufferFile = 1; + } + } else switch (*CharUpper(lp1)) { From 292bfa9041712107e932c16328a896a1621641a9 Mon Sep 17 00:00:00 2001 From: Igal Tabachnik Date: Thu, 28 Apr 2016 21:16:01 +0300 Subject: [PATCH 2/3] Adding a prompt to launch an elevated Notepad2 with the contents of the current buffer, saved to a temp file --- src/Helpers.c | 2 +- src/Notepad2.c | 83 +++++++++++++++++++++++++++++++++++++++---------- src/Notepad2.h | 2 +- src/Notepad2.rc | 1 + src/resource.h | 1 + 5 files changed, 70 insertions(+), 19 deletions(-) diff --git a/src/Helpers.c b/src/Helpers.c index 8138467b..2fce1250 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -1656,7 +1656,7 @@ BOOL MRU_AddFile(LPMRULIST pmru,LPCWSTR pszFile,BOOL bRelativePath,BOOL bUnexpan int i; for (i = 0; i < pmru->iSize; i++) { - if (lstrcmpi(pmru->pszItems[i],pszFile) == 0) { + if (!pmru->pszItems[i] || lstrcmpi(pmru->pszItems[i],pszFile) == 0) { LocalFree(pmru->pszItems[i]); break; } diff --git a/src/Notepad2.c b/src/Notepad2.c index 3ef100e3..8a75ef48 100644 --- a/src/Notepad2.c +++ b/src/Notepad2.c @@ -641,7 +641,7 @@ int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpCmdLine,int n StrCat(wchWndClass,L"B"); // Relaunch with elevated privileges - if (RelaunchElevated()) + if (RelaunchElevated(NULL)) return(0); // Try to run multiple instances @@ -7134,11 +7134,53 @@ BOOL FileSave(BOOL bSaveAlways,BOOL bAsk,BOOL bSaveAs,BOOL bSaveCopy) if (lstrlen(szCurFile) != 0) lstrcpy(tchFile,szCurFile); - SetWindowTitle(hwndMain,uidsAppTitle,fIsElevated,IDS_UNTITLED,szCurFile, - iPathNameFormat,bModified || iEncoding != iOriginalEncoding, - IDS_READONLY,bReadOnly,szTitleExcerpt); + if (!fIsElevated && dwLastIOError == ERROR_ACCESS_DENIED) + { + if (IDYES == MsgBox(MBYESNOWARN, IDS_ERR_ACCESSDENIED, tchFile)) + { + WCHAR lpTempPathBuffer[MAX_PATH]; + WCHAR szTempFileName[MAX_PATH]; - MsgBox(MBWARN,IDS_ERR_SAVEFILE,tchFile); + if (GetTempPath(MAX_PATH, lpTempPathBuffer) && + GetTempFileName(lpTempPathBuffer, TEXT("N2"), 0, szTempFileName)) + { + if (FileIO(FALSE, szTempFileName, FALSE, &iEncoding, &iEOLMode, NULL, NULL, &bCancelDataLoss, TRUE)) + { + WCHAR szArguments[2 * MAX_PATH + 64] = L""; + LPWSTR lpCmdLine = GetCommandLine(); + LPWSTR lpExe = LocalAlloc(LPTR, sizeof(WCHAR)*(lstrlen(lpCmdLine) + 1)); + LPWSTR lpArgs = LocalAlloc(LPTR, sizeof(WCHAR)*(lstrlen(lpCmdLine) + 1)); + + ExtractFirstArgument(lpCmdLine, lpExe, lpArgs); + + wsprintf(szArguments, L"/buffer %s %s", szTempFileName, lpArgs); + if (szCurFile) + { + if (!StrStr(szArguments, szCurFile)) { + PathQuoteSpaces(szCurFile); + wsprintf(szArguments, L"%s %s", szArguments, szCurFile); + } + } + + flagRelaunchElevated = 1; + if (RelaunchElevated(szArguments)) + { + LocalFree(lpExe); + LocalFree(lpArgs); + exit(0); + } + } + } + } + } + else + { + SetWindowTitle(hwndMain,uidsAppTitle,fIsElevated,IDS_UNTITLED,szCurFile, + iPathNameFormat,bModified || iEncoding != iOriginalEncoding, + IDS_READONLY,bReadOnly,szTitleExcerpt); + + MsgBox(MBWARN,IDS_ERR_SAVEFILE,tchFile); + } } return(fSuccess); @@ -7590,43 +7632,50 @@ BOOL RelaunchMultiInst() { // RelaunchElevated() // // -BOOL RelaunchElevated() { +BOOL RelaunchElevated(LPCWSTR lpArgs) { if (!IsVista() || fIsElevated || !flagRelaunchElevated || flagDisplayHelp) return(FALSE); else { - LPWSTR lpCmdLine; - LPWSTR lpArg1, lpArg2; + LPWSTR lpCmdLine, lpExe; STARTUPINFO si; SHELLEXECUTEINFO sei; + BOOL bShouldFree = FALSE; si.cb = sizeof(STARTUPINFO); GetStartupInfo(&si); lpCmdLine = GetCommandLine(); - lpArg1 = LocalAlloc(LPTR,sizeof(WCHAR)*(lstrlen(lpCmdLine) + 1)); - lpArg2 = LocalAlloc(LPTR,sizeof(WCHAR)*(lstrlen(lpCmdLine) + 1)); - ExtractFirstArgument(lpCmdLine,lpArg1,lpArg2); + lpExe = LocalAlloc(LPTR, sizeof(WCHAR)*(lstrlen(lpCmdLine) + 1)); + if (!lpArgs) { + lpArgs = LocalAlloc(LPTR,sizeof(WCHAR)*(lstrlen(lpCmdLine) + 1)); + ExtractFirstArgument(lpCmdLine, lpExe, lpArgs); + bShouldFree = TRUE; + } + else { + ExtractFirstArgument(lpCmdLine, lpExe, NULL); + } - if (lstrlen(lpArg1)) { + if (lstrlen(lpArgs)) { ZeroMemory(&sei,sizeof(SHELLEXECUTEINFO)); sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.fMask = SEE_MASK_FLAG_NO_UI | /*SEE_MASK_NOASYNC*/0x00000100 | /*SEE_MASK_NOZONECHECKS*/0x00800000; sei.hwnd = GetForegroundWindow(); sei.lpVerb = L"runas"; - sei.lpFile = lpArg1; - sei.lpParameters = lpArg2; + sei.lpFile = lpExe; + sei.lpParameters = lpArgs; sei.lpDirectory = g_wchWorkingDirectory; - sei.nShow = si.wShowWindow; + sei.nShow = si.wShowWindow ? si.wShowWindow : SW_SHOWNORMAL; ShellExecuteEx(&sei); } - LocalFree(lpArg1); - LocalFree(lpArg2); + if (bShouldFree) + LocalFree(lpArgs); + LocalFree(lpExe); return(TRUE); } diff --git a/src/Notepad2.h b/src/Notepad2.h index a4c71df2..524f8b6c 100644 --- a/src/Notepad2.h +++ b/src/Notepad2.h @@ -100,7 +100,7 @@ BOOL InitApplication(HINSTANCE); HWND InitInstance(HINSTANCE,LPSTR,int); BOOL ActivatePrevInst(); BOOL RelaunchMultiInst(); -BOOL RelaunchElevated(); +BOOL RelaunchElevated(LPCWSTR); void SnapToDefaultPos(HWND); void ShowNotifyIcon(HWND,BOOL); void SetNotifyIconTitle(HWND); diff --git a/src/Notepad2.rc b/src/Notepad2.rc index 7803b2a9..3c96ceba 100644 --- a/src/Notepad2.rc +++ b/src/Notepad2.rc @@ -1576,6 +1576,7 @@ BEGIN IDS_ASK_ENCODING2 "You are about to change the encoding of an empty file from ANSI to non-ANSI. Note that this will clear the undo history, as it can't be synchronized with the new encoding. Continue?" IDS_ERR_ENCODINGNA "Code page conversion tables for the selected encoding are not available on your system." IDS_ERR_UNICODE "Error converting this Unicode file.\nData will be lost if the file is saved!" + IDS_ERR_ACCESSDENIED "The file ""%s"" cannot be saved and may be protected.\n\nDo you want to launch Notepad2-mod as Administrator?" END STRINGTABLE diff --git a/src/resource.h b/src/resource.h index 734421a3..0b7b6b80 100644 --- a/src/resource.h +++ b/src/resource.h @@ -423,6 +423,7 @@ #define IDS_WRITEINI_FAIL 50038 #define IDS_SETTINGSNOTSAVED 50039 #define IDS_EXPORT_FAIL 50040 +#define IDS_ERR_ACCESSDENIED 50041 #define IDS_CMDLINEHELP 60000 // Next default values for new objects From 56e27f30df365f7f58eb7d932cdc3e9f55480c4f Mon Sep 17 00:00:00 2001 From: Igal Tabachnik Date: Sun, 1 May 2016 22:53:21 +0300 Subject: [PATCH 3/3] Adding selecting a correct lexer based on the original filename after restart --- src/Notepad2.c | 11 ++++++----- src/Notepad2.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Notepad2.c b/src/Notepad2.c index 8a75ef48..108cc7a8 100644 --- a/src/Notepad2.c +++ b/src/Notepad2.c @@ -883,6 +883,8 @@ HWND InitInstance(HINSTANCE hInstance,LPSTR pszCmdLine,int nCmdShow) if (bOpened = FileLoad(FALSE, FALSE, FALSE, FALSE, lpFileToOpen)) { if (flagBufferFile) { lstrcpy(szCurFile, lpFileArg); + if (!flagLexerSpecified) + Style_SetLexerFromFile(hwndEdit, szCurFile); bModified = TRUE; SetWindowTitle(hwndMain, uidsAppTitle, fIsElevated, IDS_UNTITLED, lpFileArg, iPathNameFormat, bModified, IDS_READONLY, bReadOnly, szTitleExcerpt); @@ -7154,11 +7156,10 @@ BOOL FileSave(BOOL bSaveAlways,BOOL bAsk,BOOL bSaveAs,BOOL bSaveCopy) ExtractFirstArgument(lpCmdLine, lpExe, lpArgs); wsprintf(szArguments, L"/buffer %s %s", szTempFileName, lpArgs); - if (szCurFile) + if (lstrlen(tchFile)) { - if (!StrStr(szArguments, szCurFile)) { - PathQuoteSpaces(szCurFile); - wsprintf(szArguments, L"%s %s", szArguments, szCurFile); + if (!StrStrI(szArguments, tchFile)) { + wsprintf(szArguments, L"%s %s", szArguments, tchFile); } } @@ -7632,7 +7633,7 @@ BOOL RelaunchMultiInst() { // RelaunchElevated() // // -BOOL RelaunchElevated(LPCWSTR lpArgs) { +BOOL RelaunchElevated(LPWSTR lpArgs) { if (!IsVista() || fIsElevated || !flagRelaunchElevated || flagDisplayHelp) return(FALSE); diff --git a/src/Notepad2.h b/src/Notepad2.h index 524f8b6c..8e8d1d99 100644 --- a/src/Notepad2.h +++ b/src/Notepad2.h @@ -100,7 +100,7 @@ BOOL InitApplication(HINSTANCE); HWND InitInstance(HINSTANCE,LPSTR,int); BOOL ActivatePrevInst(); BOOL RelaunchMultiInst(); -BOOL RelaunchElevated(LPCWSTR); +BOOL RelaunchElevated(LPWSTR); void SnapToDefaultPos(HWND); void ShowNotifyIcon(HWND,BOOL); void SetNotifyIconTitle(HWND);