| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652 | 
							- //---------------------------------------------------------------------------
 
- #include <vcl.h>
 
- #pragma hdrstop
 
- #include <Consts.hpp>
 
- #include <shlobj.h>
 
- #include <stdio.h>
 
- #define INITGUID
 
- #include <propkey.h>
 
- #include <powrprof.h>
 
- #include <Common.h>
 
- #include <TextsWin.h>
 
- #include <TextsCore.h>
 
- #include <HelpWin.h>
 
- #include <Exceptions.h>
 
- #include <CoreMain.h>
 
- #include <RemoteFiles.h>
 
- #include <PuttyTools.h>
 
- #include "GUITools.h"
 
- #include "VCLCommon.h"
 
- #include "Setup.h"
 
- #include "Tools.h"
 
- #include <WinHelpViewer.hpp>
 
- #include <PasTools.hpp>
 
- #include <System.Win.ComObj.hpp>
 
- #include <StrUtils.hpp>
 
- #include <WinConfiguration.h>
 
- #include <ProgParams.h>
 
- //---------------------------------------------------------------------------
 
- // WORKAROUND
 
- // VCL includes wininet.h (even with NO_WIN32_LEAN_AND_MEAN)
 
- // and it cannot be combined with winhttp.h as of current Windows SDK.
 
- // This is hack to allow that.
 
- // https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/8f468d9f-3f15-452c-803d-fc63ab3f684e/cannot-use-both-winineth-and-winhttph
 
- #undef BOOLAPI
 
- #undef SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
 
- #undef SECURITY_FLAG_IGNORE_CERT_CN_INVALID
 
- #define URL_COMPONENTS URL_COMPONENTS_ANOTHER
 
- #define URL_COMPONENTSA URL_COMPONENTSA_ANOTHER
 
- #define URL_COMPONENTSW URL_COMPONENTSW_ANOTHER
 
- #define LPURL_COMPONENTS LPURL_COMPONENTS_ANOTHER
 
- #define LPURL_COMPONENTSA LPURL_COMPONENTS_ANOTHER
 
- #define LPURL_COMPONENTSW LPURL_COMPONENTS_ANOTHER
 
- #define INTERNET_SCHEME INTERNET_SCHEME_ANOTHER
 
- #define LPINTERNET_SCHEME LPINTERNET_SCHEME_ANOTHER
 
- #define HTTP_VERSION_INFO HTTP_VERSION_INFO_ANOTHER
 
- #define LPHTTP_VERSION_INFO LPHTTP_VERSION_INFO_ANOTHER
 
- #include <winhttp.h>
 
- #undef URL_COMPONENTS
 
- #undef URL_COMPONENTSA
 
- #undef URL_COMPONENTSW
 
- #undef LPURL_COMPONENTS
 
- #undef LPURL_COMPONENTSA
 
- #undef LPURL_COMPONENTSW
 
- #undef INTERNET_SCHEME
 
- #undef LPINTERNET_SCHEME
 
- #undef HTTP_VERSION_INFO
 
- #undef LPHTTP_VERSION_INFO
 
- //---------------------------------------------------------------------------
 
- #pragma package(smart_init)
 
- //---------------------------------------------------------------------------
 
- TFontStyles __fastcall IntToFontStyles(int value)
 
- {
 
-   TFontStyles Result;
 
-   for (int i = fsBold; i <= fsStrikeOut; i++)
 
-   {
 
-     if (value & 1)
 
-     {
 
-       Result << (TFontStyle)i;
 
-     }
 
-     value >>= 1;
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- int __fastcall FontStylesToInt(const TFontStyles value)
 
- {
 
-   int Result = 0;
 
-   for (int i = fsStrikeOut; i >= fsBold; i--)
 
-   {
 
-     Result <<= 1;
 
-     if (value.Contains((TFontStyle)i))
 
-     {
 
-       Result |= 1;
 
-     }
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall SameFont(TFont * Font1, TFont * Font2)
 
- {
 
-   // keep in sync with TFontConfiguration::operator !=
 
-   return
 
-     SameText(Font1->Name, Font2->Name) && (Font1->Height == Font2->Height) &&
 
-     (Font1->Charset == Font2->Charset) && (Font1->Style == Font2->Style);
 
- }
 
- //---------------------------------------------------------------------------
 
- TColor __fastcall GetWindowTextColor(TColor BackgroundColor, TColor Color)
 
- {
 
-   if (Color == TColor(0))
 
-   {
 
-     // Could use current theme TMT_TEXTCOLOR - see https://github.com/ysc3839/win32-darkmode/
 
-     Color = (IsDarkColor(BackgroundColor) ? clWhite : clWindowText);
 
-     SetContrast(Color, BackgroundColor, 180);
 
-   }
 
-   return Color;
 
- }
 
- //---------------------------------------------------------------------------
 
- TColor __fastcall GetWindowColor(TColor Color)
 
- {
 
-   if (Color == TColor(0))
 
-   {
 
-     // Could use current theme TMT_FILLCOLOR - see https://github.com/ysc3839/win32-darkmode/
 
-     Color = (WinConfiguration->UseDarkTheme() ? static_cast<TColor>(RGB(0x20, 0x20, 0x20)) : clWindow);
 
-   }
 
-   return Color;
 
- }
 
- //---------------------------------------------------------------------------
 
- TColor __fastcall GetBtnFaceColor()
 
- {
 
-   return WinConfiguration->UseDarkTheme() ? TColor(RGB(43, 43, 43)) : clBtnFace;
 
- }
 
- //---------------------------------------------------------------------------
 
- TColor __fastcall GetNonZeroColor(TColor Color)
 
- {
 
-   // 0,0,0 is "default color"
 
-   if (Color == TColor(0))
 
-   {
 
-     // use near-black instead
 
-     Color = TColor(RGB(1, 1, 1));
 
-   }
 
-   return Color;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall CenterFormOn(TForm * Form, TControl * CenterOn)
 
- {
 
-   TPoint ScreenPoint = CenterOn->ClientToScreen(TPoint(0, 0));
 
-   Form->Left = ScreenPoint.x + (CenterOn->Width / 2) - (Form->Width / 2);
 
-   Form->Top = ScreenPoint.y + (CenterOn->Height / 2) - (Form->Height / 2);
 
- }
 
- //---------------------------------------------------------------------------
 
- UnicodeString __fastcall GetListViewStr(TListView * ListView)
 
- {
 
-   UnicodeString Result;
 
-   for (int Index = 0; Index < ListView->Columns->Count; Index++)
 
-   {
 
-     AddToList(Result, IntToStr(ListView->Column[Index]->Width), L",");
 
-   }
 
-   // WORKAROUND
 
-   // Adding an additional comma after the list,
 
-   // to ensure that old versions that did not expect the pixels-per-inch part,
 
-   // stop at the comma, otherwise they try to parse the
 
-   // "last-column-width;pixels-per-inch" as integer and throw.
 
-   // For the other instance of this hack, see TCustomListViewColProperties.GetParamsStr
 
-   Result += L",;" + SavePixelsPerInch(ListView);
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall LoadListViewStr(TListView * ListView, UnicodeString ALayoutStr)
 
- {
 
-   UnicodeString LayoutStr = CutToChar(ALayoutStr, L';', true);
 
-   int PixelsPerInch = LoadPixelsPerInch(CutToChar(ALayoutStr, L';', true), ListView);
 
-   int Index = 0;
 
-   while (!LayoutStr.IsEmpty() && (Index < ListView->Columns->Count))
 
-   {
 
-     int Width;
 
-     if (TryStrToInt(CutToChar(LayoutStr, L',', true), Width))
 
-     {
 
-       ListView->Column[Index]->Width = LoadDimension(Width, PixelsPerInch, ListView);
 
-     }
 
-     Index++;
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall LoadFormDimensions(
 
-   const UnicodeString & LeftStr, const UnicodeString & TopStr, const UnicodeString & RightStr, const UnicodeString & BottomStr,
 
-   int PixelsPerInch, Forms::TMonitor * Monitor, TForm * Form, TRect & Bounds, bool & DefaultPos)
 
- {
 
-   int Left = StrToDimensionDef(LeftStr, PixelsPerInch, Form, Bounds.Left);
 
-   int Top = StrToDimensionDef(TopStr, PixelsPerInch, Form, Bounds.Top);
 
-   DefaultPos = (Left == -1) && (Top == -1);
 
-   if (!DefaultPos)
 
-   {
 
-     Bounds.Left = Left;
 
-     Bounds.Top = Top;
 
-   }
 
-   else
 
-   {
 
-     Bounds.Left = 0;
 
-     Bounds.Top = 0;
 
-   }
 
-   Bounds.Right = StrToDimensionDef(RightStr, PixelsPerInch, Form, Bounds.Right);
 
-   Bounds.Bottom = StrToDimensionDef(BottomStr, PixelsPerInch, Form, Bounds.Bottom);
 
-   // move to the target monitor
 
-   OffsetRect(Bounds, Monitor->Left, Monitor->Top);
 
-   // reduce window size to that of monitor size
 
-   // (this does not cut window into monitor!)
 
-   if (Bounds.Width() > Monitor->WorkareaRect.Width())
 
-   {
 
-     Bounds.Right -= (Bounds.Width() - Monitor->WorkareaRect.Width());
 
-   }
 
-   if (Bounds.Height() > Monitor->WorkareaRect.Height())
 
-   {
 
-     Bounds.Bottom -= (Bounds.Height() - Monitor->WorkareaRect.Height());
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall RestoreForm(UnicodeString Data, TForm * Form, bool PositionOnly)
 
- {
 
-   DebugAssert(Form);
 
-   if (!Data.IsEmpty())
 
-   {
 
-     Forms::TMonitor * Monitor = FormMonitor(Form);
 
-     UnicodeString LeftStr = CutToChar(Data, L';', true);
 
-     UnicodeString TopStr = CutToChar(Data, L';', true);
 
-     UnicodeString RightStr = CutToChar(Data, L';', true);
 
-     UnicodeString BottomStr = CutToChar(Data, L';', true);
 
-     TWindowState State = (TWindowState)StrToIntDef(CutToChar(Data, L';', true), (int)wsNormal);
 
-     int PixelsPerInch = LoadPixelsPerInch(CutToChar(Data, L';', true), Form);
 
-     TRect OriginalBounds = Form->BoundsRect;
 
-     int OriginalPixelsPerInch = Form->PixelsPerInch;
 
-     Form->WindowState = State;
 
-     if (State == wsNormal)
 
-     {
 
-       bool DefaultPos;
 
-       TRect Bounds = OriginalBounds;
 
-       LoadFormDimensions(LeftStr, TopStr, RightStr, BottomStr, PixelsPerInch, Monitor, Form, Bounds, DefaultPos);
 
-       if (DefaultPos ||
 
-           ((Bounds.Left < Monitor->Left) ||
 
-            (Bounds.Left > Monitor->Left + Monitor->WorkareaRect.Width() - 20) ||
 
-            (Bounds.Top < Monitor->Top) ||
 
-            (Bounds.Top > Monitor->Top + Monitor->WorkareaRect.Height() - 20)))
 
-       {
 
-         bool ExplicitPlacing = !Monitor->Primary;
 
-         if (!ExplicitPlacing)
 
-         {
 
-           TPosition Position;
 
-           if ((Application->MainForm == NULL) || (Application->MainForm == Form))
 
-           {
 
-             Position = poDefaultPosOnly;
 
-           }
 
-           else
 
-           {
 
-             Position = poOwnerFormCenter;
 
-           }
 
-           // If handle is allocated already, changing Position reallocates it, what brings lot of nasty side effects.
 
-           if (Form->HandleAllocated() && (Form->Position != Position))
 
-           {
 
-             ExplicitPlacing = true;
 
-           }
 
-           else
 
-           {
 
-             Form->Width = Bounds.Width();
 
-             Form->Height = Bounds.Height();
 
-           }
 
-         }
 
-         if (ExplicitPlacing)
 
-         {
 
-           // when positioning on non-primary monitor, we need
 
-           // to handle that ourselves, so place window to center
 
-           if (!PositionOnly)
 
-           {
 
-             Form->SetBounds(Monitor->Left + ((Monitor->Width - Bounds.Width()) / 2),
 
-               Monitor->Top + ((Monitor->Height - Bounds.Height()) / 2),
 
-               Bounds.Width(), Bounds.Height());
 
-           }
 
-           if (!Form->HandleAllocated())
 
-           {
 
-             Form->Position = poDesigned;
 
-           }
 
-         }
 
-       }
 
-       else
 
-       {
 
-         Form->Position = poDesigned;
 
-         if (!PositionOnly)
 
-         {
 
-           Form->BoundsRect = Bounds;
 
-           // If setting bounds moved the form to another monitor with non-default DPI,
 
-           // recalculate the size to avoid rounding issues
 
-           // (as the form was very likely moved to the monitor, where the sizes were saved)
 
-           // See also TCustomScpExplorerForm::DoShow()
 
-           if (OriginalPixelsPerInch != Form->PixelsPerInch)
 
-           {
 
-             TRect Bounds2 = OriginalBounds;
 
-             LoadFormDimensions(LeftStr, TopStr, RightStr, BottomStr, PixelsPerInch, Monitor, Form, Bounds2, DefaultPos);
 
-             DebugAssert(!DefaultPos);
 
-             Form->BoundsRect = Bounds2;
 
-           }
 
-         }
 
-       }
 
-     }
 
-     else if (State == wsMaximized)
 
-     {
 
-       Form->Position = poDesigned;
 
-       if (!PositionOnly)
 
-       {
 
-         TRect Bounds2 = Form->BoundsRect;
 
-         OffsetRect(Bounds2, Monitor->Left, Monitor->Top);
 
-         Form->BoundsRect = Bounds2;
 
-       }
 
-     }
 
-   }
 
-   else if (Form->Position == poDesigned)
 
-   {
 
-     Form->Position = poDefaultPosOnly;
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- UnicodeString __fastcall StoreForm(TCustomForm * Form)
 
- {
 
-   DebugAssert(Form);
 
-   TRect Bounds = Form->BoundsRect;
 
-   OffsetRect(Bounds, -Form->Monitor->Left, -Form->Monitor->Top);
 
-   UnicodeString Result =
 
-     FORMAT(L"%d;%d;%d;%d;%d;%s", (SaveDimension(Bounds.Left), SaveDimension(Bounds.Top),
 
-       SaveDimension(Bounds.Right), SaveDimension(Bounds.Bottom),
 
-       // we do not want WinSCP to start minimized next time (we cannot handle that anyway).
 
-       // note that WindowState is wsNormal when window in minimized for some reason.
 
-       // actually it is wsMinimized only when minimized by MSVDM
 
-       (int)(Form->WindowState == wsMinimized ? wsNormal : Form->WindowState),
 
-       SavePixelsPerInch(Form)));
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall RestoreFormSize(UnicodeString Data, TForm * Form)
 
- {
 
-   // This has to be called only after DoFormWindowProc(CM_SHOWINGCHANGED).
 
-   // See comment in ResizeForm.
 
-   UnicodeString WidthStr = CutToChar(Data, L',', true);
 
-   UnicodeString HeightStr = CutToChar(Data, L',', true);
 
-   int PixelsPerInch = LoadPixelsPerInch(CutToChar(Data, L',', true), Form);
 
-   int Width = StrToDimensionDef(WidthStr, PixelsPerInch, Form, Form->Width);
 
-   int Height = StrToDimensionDef(HeightStr, PixelsPerInch, Form, Form->Height);
 
-   ResizeForm(Form, Width, Height);
 
- }
 
- //---------------------------------------------------------------------------
 
- UnicodeString __fastcall StoreFormSize(TForm * Form)
 
- {
 
-   return FORMAT(L"%d,%d,%s", (Form->Width, Form->Height, SavePixelsPerInch(Form)));
 
- }
 
- //---------------------------------------------------------------------------
 
- static void __fastcall ExecuteProcessAndReadOutput(const
 
-   UnicodeString & Command, const UnicodeString & HelpKeyword, UnicodeString & Output)
 
- {
 
-   if (!CopyCommandToClipboard(Command))
 
-   {
 
-     SECURITY_ATTRIBUTES SecurityAttributes;
 
-     ZeroMemory(&SecurityAttributes, sizeof(SecurityAttributes));
 
-     SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
 
-     SecurityAttributes.bInheritHandle = TRUE;
 
-     SecurityAttributes.lpSecurityDescriptor = NULL;
 
-     HANDLE PipeRead = INVALID_HANDLE_VALUE;
 
-     HANDLE PipeWrite = INVALID_HANDLE_VALUE;
 
-     if (!CreatePipe(&PipeRead, &PipeWrite, &SecurityAttributes, 0) ||
 
-         !SetHandleInformation(PipeRead, HANDLE_FLAG_INHERIT, 0))
 
-     {
 
-       throw EOSExtException(FMTLOAD(EXECUTE_APP_ERROR, (Command)));
 
-     }
 
-     PROCESS_INFORMATION ProcessInformation;
 
-     ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
 
-     try
 
-     {
 
-       try
 
-       {
 
-         STARTUPINFO StartupInfo;
 
-         ZeroMemory(&StartupInfo, sizeof(StartupInfo));
 
-         StartupInfo.cb = sizeof(STARTUPINFO);
 
-         StartupInfo.hStdError = PipeWrite;
 
-         StartupInfo.hStdOutput = PipeWrite;
 
-         StartupInfo.wShowWindow = SW_HIDE;
 
-         StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
 
-         if (!CreateProcess(NULL, Command.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &StartupInfo, &ProcessInformation))
 
-         {
 
-           throw EOSExtException(FMTLOAD(EXECUTE_APP_ERROR, (Command)));
 
-         }
 
-       }
 
-       __finally
 
-       {
 
-         // If we do not close the handle here, the ReadFile below would get stuck once the app finishes writting,
 
-         // as it still sees that someone "can" write to the pipe.
 
-         CloseHandle(PipeWrite);
 
-       }
 
-       DWORD BytesAvail;
 
-       while (PeekNamedPipe(PipeRead, NULL, 0, NULL, &BytesAvail, NULL))
 
-       {
 
-         if (BytesAvail > 0)
 
-         {
 
-           char Buffer[4096];
 
-           DWORD BytesToRead = std::min(BytesAvail, static_cast<unsigned long>(sizeof(Buffer)));
 
-           DWORD BytesRead;
 
-           if (ReadFile(PipeRead, Buffer, BytesToRead, &BytesRead, NULL))
 
-           {
 
-             Output += UnicodeString(UTF8String(Buffer, BytesRead));
 
-           }
 
-         }
 
-         // Same as in ExecuteShellCheckedAndWait
 
-         Sleep(50);
 
-         Application->ProcessMessages();
 
-       }
 
-       DWORD ExitCode;
 
-       if (DebugAlwaysTrue(GetExitCodeProcess(ProcessInformation.hProcess, &ExitCode)) &&
 
-           (ExitCode != 0))
 
-       {
 
-         UnicodeString Buf = Output;
 
-         UnicodeString Buf2;
 
-         if (ExtractMainInstructions(Buf, Buf2))
 
-         {
 
-           throw ExtException(Output, UnicodeString(), HelpKeyword);
 
-         }
 
-         else
 
-         {
 
-           throw ExtException(MainInstructions(FMTLOAD(COMMAND_FAILED_CODEONLY, (static_cast<int>(ExitCode)))), Output, HelpKeyword);
 
-         }
 
-       }
 
-     }
 
-     __finally
 
-     {
 
-       CloseHandle(ProcessInformation.hProcess);
 
-       CloseHandle(ProcessInformation.hThread);
 
-     }
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall ExecuteProcessChecked(
 
-   const UnicodeString & Command, const UnicodeString & HelpKeyword, UnicodeString * Output)
 
- {
 
-   if (Output == NULL)
 
-   {
 
-     ExecuteShellChecked(Command);
 
-   }
 
-   else
 
-   {
 
-     ExecuteProcessAndReadOutput(Command, HelpKeyword, *Output);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall ExecuteProcessCheckedAndWait(
 
-   const UnicodeString & Command, const UnicodeString & HelpKeyword, UnicodeString * Output)
 
- {
 
-   if (Output == NULL)
 
-   {
 
-     ExecuteShellCheckedAndWait(Command, &Application->ProcessMessages);
 
-   }
 
-   else
 
-   {
 
-     ExecuteProcessAndReadOutput(Command, HelpKeyword, *Output);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall IsKeyPressed(int VirtualKey)
 
- {
 
-   return FLAGSET(GetAsyncKeyState(VirtualKey), 0x8000);
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall UseAlternativeFunction()
 
- {
 
-   return IsKeyPressed(VK_SHIFT);
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall OpenInNewWindow()
 
- {
 
-   return UseAlternativeFunction();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall ExecuteNewInstance(const UnicodeString & Param, const UnicodeString & AdditionalParams)
 
- {
 
-   UnicodeString Arg = Param;
 
-   if (!Arg.IsEmpty())
 
-   {
 
-     Arg = FORMAT(L"\"%s\" %s", (Arg, TProgramParams::FormatSwitch(NEWINSTANCE_SWICH)));
 
-     if (!AdditionalParams.IsEmpty())
 
-     {
 
-       Arg += L" " + AdditionalParams;
 
-     }
 
-   }
 
-   ExecuteShellChecked(Application->ExeName, Arg);
 
- }
 
- //---------------------------------------------------------------------------
 
- IShellLink * __fastcall CreateDesktopShortCut(const UnicodeString & Name,
 
-   const UnicodeString &File, const UnicodeString & Params, const UnicodeString & Description,
 
-   int SpecialFolder, int IconIndex, bool Return)
 
- {
 
-   IShellLink* pLink = NULL;
 
-   if (SpecialFolder < 0)
 
-   {
 
-     SpecialFolder = CSIDL_DESKTOPDIRECTORY;
 
-   }
 
-   try
 
-   {
 
-     if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
 
-          IID_IShellLink, (void **) &pLink)))
 
-     {
 
-       try
 
-       {
 
-         pLink->SetPath(File.c_str());
 
-         pLink->SetDescription(Description.c_str());
 
-         pLink->SetArguments(Params.c_str());
 
-         pLink->SetShowCmd(SW_SHOW);
 
-         // Explicitly setting icon file,
 
-         // without this icons are not shown at least in Windows 7 jumplist
 
-         pLink->SetIconLocation(File.c_str(), IconIndex);
 
-         IPersistFile* pPersistFile;
 
-         if (!Return &&
 
-             SUCCEEDED(pLink->QueryInterface(IID_IPersistFile, (void **)&pPersistFile)))
 
-         {
 
-           try
 
-           {
 
-             LPMALLOC      ShellMalloc;
 
-             LPITEMIDLIST  DesktopPidl;
 
-             wchar_t DesktopDir[MAX_PATH];
 
-             OleCheck(SHGetMalloc(&ShellMalloc));
 
-             try
 
-             {
 
-               OleCheck(SHGetSpecialFolderLocation(NULL, SpecialFolder, &DesktopPidl));
 
-               OleCheck(SHGetPathFromIDList(DesktopPidl, DesktopDir));
 
-             }
 
-             __finally
 
-             {
 
-               ShellMalloc->Free(DesktopPidl);
 
-               ShellMalloc->Release();
 
-             }
 
-             WideString strShortCutLocation(DesktopDir);
 
-             // Name can contain even path (e.g. to create quick launch icon)
 
-             strShortCutLocation += UnicodeString(L"\\") + Name + L".lnk";
 
-             OleCheck(pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE));
 
-           }
 
-           __finally
 
-           {
 
-             pPersistFile->Release();
 
-           }
 
-         }
 
-         // this is necessary for Windows 7 taskbar jump list links
 
-         IPropertyStore * PropertyStore;
 
-         if (SUCCEEDED(pLink->QueryInterface(IID_IPropertyStore, (void**)&PropertyStore)))
 
-         {
 
-           PROPVARIANT Prop;
 
-           Prop.vt = VT_LPWSTR;
 
-           Prop.pwszVal = Name.c_str();
 
-           PropertyStore->SetValue(PKEY_Title, Prop);
 
-           PropertyStore->Commit();
 
-           PropertyStore->Release();
 
-         }
 
-       }
 
-       catch(...)
 
-       {
 
-         pLink->Release();
 
-         throw;
 
-       }
 
-       if (!Return)
 
-       {
 
-         pLink->Release();
 
-         pLink = NULL;
 
-       }
 
-     }
 
-   }
 
-   catch(Exception & E)
 
-   {
 
-     throw ExtException(&E, LoadStr(CREATE_SHORTCUT_ERROR));
 
-   }
 
-   return pLink;
 
- }
 
- //---------------------------------------------------------------------------
 
- IShellLink * __fastcall CreateAppDesktopShortCut(
 
-   const UnicodeString & Name, const UnicodeString & AParams, const UnicodeString & Description,
 
-   int SpecialFolder, int IconIndex, bool Return)
 
- {
 
-   UnicodeString ParamValue = Configuration->GetIniFileParamValue();
 
-   UnicodeString Params;
 
-   if (!ParamValue.IsEmpty())
 
-   {
 
-     Params = TProgramParams::FormatSwitch(INI_SWITCH) + L"=" + AddQuotes(ParamValue);
 
-   }
 
-   AddToList(Params, AParams, L" ");
 
-   return CreateDesktopShortCut(Name, Application->ExeName, Params, Description, SpecialFolder, IconIndex, Return);
 
- }
 
- //---------------------------------------------------------------------------
 
- IShellLink * __fastcall CreateDesktopSessionShortCut(
 
-   const UnicodeString & SessionName, UnicodeString Name,
 
-   const UnicodeString & AdditionalParams, int SpecialFolder, int IconIndex,
 
-   bool Return)
 
- {
 
-   bool DefaultsOnly;
 
-   UnicodeString InfoTip;
 
-   bool IsFolder = StoredSessions->IsFolder(SessionName);
 
-   bool IsWorkspace = StoredSessions->IsWorkspace(SessionName);
 
-   if (IsFolder || IsWorkspace)
 
-   {
 
-     InfoTip = FMTLOAD(
 
-       (IsFolder ? SHORTCUT_INFO_TIP_FOLDER : SHORTCUT_INFO_TIP_WORKSPACE),
 
-       (SessionName));
 
-     if (Name.IsEmpty())
 
-     {
 
-       // no slashes in filename
 
-       Name = UnixExtractFileName(SessionName);
 
-     }
 
-   }
 
-   else
 
-   {
 
-     // this should not be done for workspaces and folders
 
-     TSessionData * SessionData =
 
-       StoredSessions->ParseUrl(EncodeUrlString(SessionName), NULL, DefaultsOnly);
 
-     InfoTip =
 
-       FMTLOAD(SHORTCUT_INFO_TIP, (SessionName, SessionData->InfoTip));
 
-     if (Name.IsEmpty())
 
-     {
 
-       // no slashes in filename
 
-       Name = SessionData->LocalName;
 
-     }
 
-     delete SessionData;
 
-   }
 
-   return
 
-     CreateAppDesktopShortCut(ValidLocalFileName(Name),
 
-       FORMAT(L"\"%s\"%s%s", (EncodeUrlString(SessionName), (AdditionalParams.IsEmpty() ? L"" : L" "), AdditionalParams)),
 
-       InfoTip, SpecialFolder, IconIndex, Return);
 
- }
 
- //---------------------------------------------------------------------------
 
- void ValidateMask(const UnicodeString & Mask, int ForceDirectoryMasks)
 
- {
 
-   TFileMasks Masks(ForceDirectoryMasks);
 
-   Masks = Mask;
 
- }
 
- //---------------------------------------------------------------------------
 
- template<class TEditControl>
 
- void __fastcall ValidateMaskEditT(const UnicodeString & Mask, TEditControl * Edit, int ForceDirectoryMasks)
 
- {
 
-   DebugAssert(Edit != NULL);
 
-   if (!IsCancelButtonBeingClicked(Edit))
 
-   {
 
-     try
 
-     {
 
-       ValidateMask(Mask, ForceDirectoryMasks);
 
-     }
 
-     catch(EFileMasksException & E)
 
-     {
 
-       ShowExtendedException(&E);
 
-       Edit->SetFocus();
 
-       // This does not work for TEdit and TMemo (descendants of TCustomEdit) anymore,
 
-       // as it re-selects whole text on exception in TCustomEdit.CMExit
 
-       Edit->SelStart = E.ErrorStart - 1;
 
-       Edit->SelLength = E.ErrorLen;
 
-       Abort();
 
-     }
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall ValidateMaskEdit(TComboBox * Edit)
 
- {
 
-   ValidateMaskEditT(Edit->Text, Edit, -1);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall ValidateMaskEdit(TEdit * Edit)
 
- {
 
-   ValidateMaskEditT(Edit->Text, Edit, -1);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall ValidateMaskEdit(TMemo * Edit, bool Directory)
 
- {
 
-   if (!IsCancelButtonBeingClicked(Edit))
 
-   {
 
-     UnicodeString Mask = TFileMasks::ComposeMaskStr(GetUnwrappedMemoLines(Edit), Directory);
 
-     ValidateMaskEditT(Mask, Edit, Directory ? 1 : 0);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- TStrings * __fastcall GetUnwrappedMemoLines(TMemo * Memo)
 
- {
 
-   // This removes soft linebreaks when text in memo wraps
 
-   // (Memo->Lines includes soft linebreaks, while Memo->Text does not)
 
-   return TextToStringList(Memo->Text);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall ExitActiveControl(TForm * Form)
 
- {
 
-   if (Form->ActiveControl != NULL)
 
-   {
 
-     TNotifyEvent OnExit = ((TEdit*)Form->ActiveControl)->OnExit;
 
-     if (OnExit != NULL)
 
-     {
 
-       OnExit(Form->ActiveControl);
 
-     }
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall IsWinSCPUrl(const UnicodeString & Url)
 
- {
 
-   UnicodeString HomePageUrl = LoadStr(HOMEPAGE_URL);
 
-   UnicodeString HttpHomePageUrl = ChangeUrlProtocol(HomePageUrl, HttpProtocol);
 
-   DebugAssert(HomePageUrl != HttpHomePageUrl);
 
-   return
 
-     StartsText(HomePageUrl, Url) ||
 
-     StartsText(HttpHomePageUrl, Url);
 
- }
 
- //---------------------------------------------------------------------------
 
- UnicodeString __fastcall SecureUrl(const UnicodeString & Url)
 
- {
 
-   UnicodeString Result = Url;
 
-   if (IsWinSCPUrl(Url) && IsHttpUrl(Url))
 
-   {
 
-     Result = ChangeUrlProtocol(Result, HttpsProtocol);
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall OpenBrowser(UnicodeString URL)
 
- {
 
-   if (IsWinSCPUrl(URL))
 
-   {
 
-     DebugAssert(!IsHttpUrl(URL));
 
-     URL = CampaignUrl(URL);
 
-   }
 
-   if (!CopyCommandToClipboard(URL))
 
-   {
 
-     ShellExecute(Application->Handle, L"open", URL.c_str(), NULL, NULL, SW_SHOWNORMAL);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall OpenFolderInExplorer(const UnicodeString & Path)
 
- {
 
-   if ((int)ShellExecute(Application->Handle, L"explore",
 
-       (wchar_t*)Path.data(), NULL, NULL, SW_SHOWNORMAL) <= 32)
 
-   {
 
-     throw Exception(FMTLOAD(EXPLORE_LOCAL_DIR_ERROR, (Path)));
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall OpenFileInExplorer(const UnicodeString & Path)
 
- {
 
-   PCIDLIST_ABSOLUTE Folder = ILCreateFromPathW(ApiPath(Path).c_str());
 
-   SHOpenFolderAndSelectItems(Folder, 0, NULL, 0);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall ShowHelp(const UnicodeString & AHelpKeyword)
 
- {
 
-   // see also AppendUrlParams
 
-   UnicodeString HelpKeyword = AHelpKeyword;
 
-   const wchar_t FragmentSeparator = L'#';
 
-   UnicodeString HelpPath = CutToChar(HelpKeyword, FragmentSeparator, false);
 
-   UnicodeString HelpUrl = FMTLOAD(DOCUMENTATION_KEYWORD_URL2, (HelpPath, Configuration->ProductVersion, GUIConfiguration->AppliedLocaleHex));
 
-   AddToList(HelpUrl, HelpKeyword, FragmentSeparator);
 
-   OpenBrowser(HelpUrl);
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall IsFormatInClipboard(unsigned int Format)
 
- {
 
-   bool Result = OpenClipboard(0);
 
-   if (Result)
 
-   {
 
-     Result = IsClipboardFormatAvailable(Format);
 
-     CloseClipboard();
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- HANDLE __fastcall OpenTextFromClipboard(const wchar_t *& Text)
 
- {
 
-   HANDLE Result = NULL;
 
-   if (OpenClipboard(0))
 
-   {
 
-     // Check also for CF_TEXT?
 
-     Result = GetClipboardData(CF_UNICODETEXT);
 
-     if (Result != NULL)
 
-     {
 
-       Text = static_cast<const wchar_t*>(GlobalLock(Result));
 
-     }
 
-     else
 
-     {
 
-       CloseClipboard();
 
-     }
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall CloseTextFromClipboard(HANDLE Handle)
 
- {
 
-   if (Handle != NULL)
 
-   {
 
-     GlobalUnlock(Handle);
 
-   }
 
-   CloseClipboard();
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall TextFromClipboard(UnicodeString & Text, bool Trim)
 
- {
 
-   const wchar_t * AText = NULL;
 
-   HANDLE Handle = OpenTextFromClipboard(AText);
 
-   bool Result = (Handle != NULL);
 
-   if (Result)
 
-   {
 
-     // For all current uses (URL pasting, key/fingerprint pasting, known_hosts pasting, "more messages" copying,
 
-     // permissions pasting), 64KB is large enough.
 
-     const size_t Limit = 64*1024;
 
-     size_t Size = GlobalSize(Handle);
 
-     if (Size > Limit)
 
-     {
 
-       Text = UnicodeString(AText, Limit);
 
-     }
 
-     else
 
-     {
 
-       Text = AText;
 
-     }
 
-     if (Trim)
 
-     {
 
-       Text = Text.Trim();
 
-     }
 
-     CloseTextFromClipboard(Handle);
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall NonEmptyTextFromClipboard(UnicodeString & Text)
 
- {
 
-   return
 
-     TextFromClipboard(Text, true) &&
 
-     !Text.IsEmpty();
 
- }
 
- //---------------------------------------------------------------------------
 
- static bool __fastcall GetResource(
 
-   const UnicodeString ResName, void *& Content, unsigned long & Size)
 
- {
 
-   HRSRC Resource = FindResourceEx(HInstance, RT_RCDATA, ResName.c_str(),
 
-     MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
 
-   bool Result = (Resource != NULL);
 
-   if (Result)
 
-   {
 
-     Size = SizeofResource(HInstance, Resource);
 
-     if (!Size)
 
-     {
 
-       throw Exception(FORMAT(L"Cannot get size of resource %s", (ResName)));
 
-     }
 
-     Content = LoadResource(HInstance, Resource);
 
-     if (!Content)
 
-     {
 
-       throw Exception(FORMAT(L"Cannot read resource %s", (ResName)));
 
-     }
 
-     Content = LockResource(Content);
 
-     if (!Content)
 
-     {
 
-       throw Exception(FORMAT(L"Cannot lock resource %s", (ResName)));
 
-     }
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall DumpResourceToFile(const UnicodeString ResName,
 
-   const UnicodeString FileName)
 
- {
 
-   void * Content;
 
-   unsigned long Size;
 
-   bool Result = GetResource(ResName, Content, Size);
 
-   if (Result)
 
-   {
 
-     FILE * f = _wfopen(ApiPath(FileName).c_str(), L"wb");
 
-     if (!f)
 
-     {
 
-       throw Exception(FORMAT(L"Cannot create file %s", (FileName)));
 
-     }
 
-     if (fwrite(Content, 1, Size, f) != Size)
 
-     {
 
-       throw Exception(FORMAT(L"Cannot write to file %s", (FileName)));
 
-     }
 
-     fclose(f);
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- UnicodeString __fastcall ReadResource(const UnicodeString ResName)
 
- {
 
-   void * Content;
 
-   unsigned long Size;
 
-   UnicodeString Result;
 
-   if (GetResource(ResName, Content, Size))
 
-   {
 
-     Result = UnicodeString(UTF8String(static_cast<char*>(Content), Size));
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- template <class T>
 
- void __fastcall BrowseForExecutableT(T * Control, UnicodeString Title,
 
-   UnicodeString Filter, bool FileNameCommand, bool Escape)
 
- {
 
-   UnicodeString Executable, Program, Params, Dir;
 
-   Executable = Control->Text;
 
-   if (FileNameCommand)
 
-   {
 
-     ReformatFileNameCommand(Executable);
 
-   }
 
-   SplitCommand(Executable, Program, Params, Dir);
 
-   TOpenDialog * FileDialog = new TOpenDialog(Application);
 
-   try
 
-   {
 
-     if (Escape)
 
-     {
 
-       Program = ReplaceStr(Program, L"\\\\", L"\\");
 
-     }
 
-     UnicodeString ExpandedProgram = ExpandEnvironmentVariables(Program);
 
-     FileDialog->FileName = ExpandedProgram;
 
-     UnicodeString InitialDir = ExtractFilePath(ExpandedProgram);
 
-     if (!InitialDir.IsEmpty())
 
-     {
 
-       FileDialog->InitialDir = InitialDir;
 
-     }
 
-     FileDialog->Filter = Filter;
 
-     FileDialog->Title = Title;
 
-     if (FileDialog->Execute())
 
-     {
 
-       TNotifyEvent PrevOnChange = Control->OnChange;
 
-       Control->OnChange = NULL;
 
-       try
 
-       {
 
-         // preserve unexpanded file, if the destination has not changed actually
 
-         if (!IsPathToSameFile(ExpandedProgram, FileDialog->FileName))
 
-         {
 
-           Program = FileDialog->FileName;
 
-           if (Escape)
 
-           {
 
-             Program = ReplaceStr(Program, L"\\", L"\\\\");
 
-           }
 
-         }
 
-         Control->Text = FormatCommand(Program, Params);
 
-       }
 
-       __finally
 
-       {
 
-         Control->OnChange = PrevOnChange;
 
-       }
 
-       if (Control->OnExit != NULL)
 
-       {
 
-         Control->OnExit(Control);
 
-       }
 
-     }
 
-   }
 
-   __finally
 
-   {
 
-     delete FileDialog;
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall BrowseForExecutable(TEdit * Control, UnicodeString Title,
 
-   UnicodeString Filter, bool FileNameCommand, bool Escape)
 
- {
 
-   BrowseForExecutableT(Control, Title, Filter, FileNameCommand, Escape);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall BrowseForExecutable(TComboBox * Control, UnicodeString Title,
 
-   UnicodeString Filter, bool FileNameCommand, bool Escape)
 
- {
 
-   BrowseForExecutableT(Control, Title, Filter, FileNameCommand, Escape);
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall FontDialog(TFont * Font)
 
- {
 
-   bool Result;
 
-   TFontDialog * Dialog = new TFontDialog(Application);
 
-   try
 
-   {
 
-     Dialog->Device = fdScreen;
 
-     Dialog->Options = TFontDialogOptions() << fdForceFontExist;
 
-     Dialog->Font = Font;
 
-     Result = Dialog->Execute();
 
-     if (Result)
 
-     {
 
-       Font->Assign(Dialog->Font);
 
-     }
 
-   }
 
-   __finally
 
-   {
 
-     delete Dialog;
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall SaveDialog(UnicodeString Title, UnicodeString Filter,
 
-   UnicodeString DefaultExt, UnicodeString & FileName)
 
- {
 
-   bool Result;
 
-   #if 0
 
-   TFileSaveDialog * Dialog = new TFileSaveDialog(Application);
 
-   try
 
-   {
 
-     Dialog->Title = Title;
 
-     FilterToFileTypes(Filter, Dialog->FileTypes);
 
-     Dialog->DefaultExtension = DefaultExt;
 
-     Dialog->FileName = FileName;
 
-     UnicodeString DefaultFolder = ExtractFilePath(FileName);
 
-     if (!DefaultFolder.IsEmpty())
 
-     {
 
-       Dialog->DefaultFolder = DefaultFolder;
 
-     }
 
-     Dialog->Options = Dialog->Options << fdoOverWritePrompt << fdoForceFileSystem <<
 
-       fdoPathMustExist << fdoNoReadOnlyReturn;
 
-     Result = Dialog->Execute();
 
-     if (Result)
 
-     {
 
-       FileName = Dialog->FileName;
 
-     }
 
-   }
 
-   __finally
 
-   {
 
-     delete Dialog;
 
-   }
 
-   #else
 
-   TSaveDialog * Dialog = new TSaveDialog(Application);
 
-   try
 
-   {
 
-     Dialog->Title = Title;
 
-     Dialog->Filter = Filter;
 
-     Dialog->DefaultExt = DefaultExt;
 
-     Dialog->FileName = FileName;
 
-     UnicodeString InitialDir = ExtractFilePath(FileName);
 
-     if (!InitialDir.IsEmpty())
 
-     {
 
-       Dialog->InitialDir = InitialDir;
 
-     }
 
-     Dialog->Options = Dialog->Options << ofOverwritePrompt << ofPathMustExist <<
 
-       ofNoReadOnlyReturn;
 
-     Result = Dialog->Execute();
 
-     if (Result)
 
-     {
 
-       FileName = Dialog->FileName;
 
-     }
 
-   }
 
-   __finally
 
-   {
 
-     delete Dialog;
 
-   }
 
-   #endif
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall CopyToClipboard(UnicodeString Text)
 
- {
 
-   HANDLE Data;
 
-   void * DataPtr;
 
-   if (OpenClipboard(0))
 
-   {
 
-     try
 
-     {
 
-       size_t Size = (Text.Length() + 1) * sizeof(wchar_t);
 
-       Data = GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, Size);
 
-       try
 
-       {
 
-         DataPtr = GlobalLock(Data);
 
-         try
 
-         {
 
-           memcpy(DataPtr, Text.c_str(), Size);
 
-           EmptyClipboard();
 
-           SetClipboardData(CF_UNICODETEXT, Data);
 
-         }
 
-         __finally
 
-         {
 
-           GlobalUnlock(Data);
 
-         }
 
-       }
 
-       catch(...)
 
-       {
 
-         GlobalFree(Data);
 
-         throw;
 
-       }
 
-     }
 
-     __finally
 
-     {
 
-       CloseClipboard();
 
-     }
 
-   }
 
-   else
 
-   {
 
-     throw Exception(Vcl_Consts_SCannotOpenClipboard);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall CopyToClipboard(TStrings * Strings)
 
- {
 
-   if (Strings->Count > 0)
 
-   {
 
-     CopyToClipboard(StringsToText(Strings));
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall IsWin64()
 
- {
 
-   static int Result = -1;
 
-   if (Result < 0)
 
-   {
 
-     Result = 0;
 
-     BOOL Wow64Process = FALSE;
 
-     if (IsWow64Process(GetCurrentProcess(), &Wow64Process))
 
-     {
 
-       if (Wow64Process)
 
-       {
 
-         Result = 1;
 
-       }
 
-     }
 
-   }
 
-   return (Result > 0);
 
- }
 
- //---------------------------------------------------------------------------
 
- static void __fastcall AcquireShutDownPrivileges()
 
- {
 
-   HANDLE Token;
 
-   // Get a token for this process.
 
-   Win32Check(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token));
 
-   TOKEN_PRIVILEGES Priv;
 
-   ZeroMemory(&Priv, sizeof(Priv));
 
-   // Get the LUID for the shutdown privilege.
 
-   // For hibernate/suspend, you need the same:
 
-   // https://stackoverflow.com/q/959589/850848
 
-   Win32Check(LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &Priv.Privileges[0].Luid));
 
-   Priv.PrivilegeCount = 1;  // one privilege to set
 
-   Priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
-   // Get the shutdown privilege for this process.
 
-   Win32Check(AdjustTokenPrivileges(Token, FALSE, &Priv, 0, (PTOKEN_PRIVILEGES)NULL, 0));
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall ShutDownWindows()
 
- {
 
-   AcquireShutDownPrivileges();
 
-   // Shut down the system and force all applications to close.
 
-   Win32Check(ExitWindowsEx(EWX_SHUTDOWN | EWX_POWEROFF,
 
-     SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED));
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall SuspendWindows()
 
- {
 
-   AcquireShutDownPrivileges();
 
-   // https://docs.microsoft.com/en-us/windows/win32/api/powrprof/nf-powrprof-setsuspendstate
 
-   Win32Check(SetSuspendState(false, false, false));
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall EditSelectBaseName(HWND Edit)
 
- {
 
-   UnicodeString Text;
 
-   Text.SetLength(GetWindowTextLength(Edit) + 1);
 
-   GetWindowText(Edit, Text.c_str(), Text.Length());
 
-   int P = Text.LastDelimiter(L".");
 
-   if (P > 0)
 
-   {
 
-     // SendMessage does not work, if edit control is not fully
 
-     // initialized yet
 
-     PostMessage(Edit, EM_SETSEL, 0, P - 1);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- static void __fastcall ConvertKey(UnicodeString & FileName, TKeyType Type)
 
- {
 
-   UnicodeString Passphrase;
 
-   UnicodeString Comment;
 
-   if (IsKeyEncrypted(Type, FileName, Comment))
 
-   {
 
-     if (!InputDialog(
 
-           LoadStr(PASSPHRASE_TITLE),
 
-           FORMAT(LoadStr(PROMPT_KEY_PASSPHRASE), (Comment)),
 
-           Passphrase, HELP_NONE, NULL, false, NULL, false))
 
-     {
 
-       Abort();
 
-     }
 
-   }
 
-   TPrivateKey * PrivateKey = LoadKey(Type, FileName, Passphrase);
 
-   try
 
-   {
 
-     FileName = ChangeFileExt(FileName, FORMAT(L".%s", (PuttyKeyExt)));
 
-     if (!SaveDialog(LoadStr(CONVERTKEY_SAVE_TITLE), LoadStr(CONVERTKEY_SAVE_FILTER), PuttyKeyExt, FileName))
 
-     {
 
-       Abort();
 
-     }
 
-     SaveKey(ktSSH2, FileName, Passphrase, PrivateKey);
 
-     MessageDialog(MainInstructions(FMTLOAD(CONVERTKEY_SAVED, (FileName))), qtInformation, qaOK);
 
-   }
 
-   __finally
 
-   {
 
-     FreeKey(PrivateKey);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- static void __fastcall DoVerifyKey(
 
-   UnicodeString & FileName, TSshProt SshProt, bool Convert, bool CanIgnore)
 
- {
 
-   if (!FileName.Trim().IsEmpty())
 
-   {
 
-     FileName = ExpandEnvironmentVariables(FileName);
 
-     TKeyType Type = KeyType(FileName);
 
-     // reason _wfopen failed
 
-     int Error = errno;
 
-     UnicodeString Message;
 
-     UnicodeString HelpKeyword = HELP_LOGIN_KEY_TYPE;
 
-     UnicodeString PuttygenPath;
 
-     std::unique_ptr<TStrings> MoreMessages;
 
-     switch (Type)
 
-     {
 
-       case ktOpenSSHPEM:
 
-       case ktOpenSSHNew:
 
-       case ktSSHCom:
 
-         {
 
-           UnicodeString TypeName = ((Type == ktOpenSSHPEM) || (Type == ktOpenSSHNew)) ? L"OpenSSH" : L"ssh.com";
 
-           Message = FMTLOAD(KEY_TYPE_UNSUPPORTED2, (FileName, TypeName));
 
-           if (Convert)
 
-           {
 
-             Configuration->Usage->Inc(L"PrivateKeyConvertSuggestionsNative");
 
-             UnicodeString ConvertMessage = FMTLOAD(KEY_TYPE_CONVERT3, (TypeName, RemoveMainInstructionsTag(Message)));
 
-             Message = UnicodeString();
 
-             if (MoreMessageDialog(ConvertMessage, NULL, qtConfirmation, qaOK | qaCancel, HelpKeyword) == qaOK)
 
-             {
 
-               ConvertKey(FileName, Type);
 
-               Configuration->Usage->Inc(L"PrivateKeyConverted");
 
-             }
 
-             else
 
-             {
 
-               Abort();
 
-             }
 
-           }
 
-           else
 
-           {
 
-             HelpKeyword = HELP_KEY_TYPE_UNSUPPORTED;
 
-           }
 
-         }
 
-         break;
 
-       case ktSSH1:
 
-       case ktSSH2:
 
-         if ((Type == ktSSH1) != (SshProt == ssh1only))
 
-         {
 
-           Message =
 
-             MainInstructions(
 
-               FMTLOAD(KEY_TYPE_DIFFERENT_SSH,
 
-                 (FileName, (Type == ktSSH1 ? L"SSH-1" : L"PuTTY SSH-2"))));
 
-         }
 
-         break;
 
-       case ktSSH1Public:
 
-       case ktSSH2PublicRFC4716:
 
-       case ktSSH2PublicOpenSSH:
 
-         // noop
 
-         // Do not even bother checking SSH protocol version
 
-         break;
 
-       case ktUnopenable:
 
-         Message = MainInstructions(FMTLOAD(KEY_TYPE_UNOPENABLE, (FileName)));
 
-         if (Error != ERROR_SUCCESS)
 
-         {
 
-           MoreMessages.reset(TextToStringList(SysErrorMessageForError(Error)));
 
-         }
 
-         break;
 
-       default:
 
-         DebugFail();
 
-         // fallthru
 
-       case ktUnknown:
 
-         Message = MainInstructions(FMTLOAD(KEY_TYPE_UNKNOWN2, (FileName)));
 
-         break;
 
-     }
 
-     if (!Message.IsEmpty())
 
-     {
 
-       Configuration->Usage->Inc(L"PrivateKeySelectErrors");
 
-       unsigned int Answers = (CanIgnore ? (qaIgnore | qaAbort) : qaOK);
 
-       if (MoreMessageDialog(Message, MoreMessages.get(), qtWarning, Answers, HelpKeyword) != qaIgnore)
 
-       {
 
-         Abort();
 
-       }
 
-     }
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall VerifyAndConvertKey(UnicodeString & FileName, TSshProt SshProt, bool CanIgnore)
 
- {
 
-   DoVerifyKey(FileName, SshProt, true, CanIgnore);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall VerifyKey(UnicodeString FileName, TSshProt SshProt)
 
- {
 
-   DoVerifyKey(FileName, SshProt, false, true);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall VerifyCertificate(const UnicodeString & FileName)
 
- {
 
-   if (!FileName.Trim().IsEmpty())
 
-   {
 
-     try
 
-     {
 
-       CheckCertificate(FileName);
 
-     }
 
-     catch (Exception & E)
 
-     {
 
-       if (ExceptionMessageDialog(&E, qtWarning, L"", qaIgnore | qaAbort) == qaAbort)
 
-       {
 
-         Abort();
 
-       }
 
-     }
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall DetectSystemExternalEditor(
 
-   bool AllowDefaultEditor,
 
-   UnicodeString & Executable, UnicodeString & ExecutableDescription,
 
-   UnicodeString & UsageState, bool & TryNextTime)
 
- {
 
-   bool Result = false;
 
-   UnicodeString TempName = ExcludeTrailingBackslash(WinConfiguration->TemporaryDir()) + L".txt";
 
-   if (FileExists(ApiPath(TempName)))
 
-   {
 
-     TryNextTime = true;
 
-     UsageState = "F";
 
-   }
 
-   else
 
-   {
 
-     unsigned int File = FileCreate(ApiPath(TempName));
 
-     if (File == (unsigned int)INVALID_HANDLE_VALUE)
 
-     {
 
-       TryNextTime = true;
 
-       UsageState = "F";
 
-     }
 
-     else
 
-     {
 
-       FileClose(File);
 
-       try
 
-       {
 
-         wchar_t ExecutableBuf[MAX_PATH];
 
-         if (!SUCCEEDED(FindExecutable(TempName.c_str(), NULL, ExecutableBuf)))
 
-         {
 
-           UsageState = "N";
 
-         }
 
-         else
 
-         {
 
-           Executable = ExecutableBuf;
 
-           if (Executable.IsEmpty() ||
 
-               !FileExists(ApiPath(Executable)))
 
-           {
 
-             UsageState = "N";
 
-           }
 
-           else
 
-           {
 
-             UnicodeString ExecutableName = ExtractFileName(Executable);
 
-             if (!AllowDefaultEditor &&
 
-                 SameText(ExecutableName, TEditorPreferences::GetDefaultExternalEditor()))
 
-             {
 
-               UsageState = "P";
 
-               Executable = L"";
 
-             }
 
-             else if (SameText(ExecutableName, "openwith.exe"))
 
-             {
 
-               UsageState = "W";
 
-               Executable = L"";
 
-             }
 
-             else
 
-             {
 
-               try
 
-               {
 
-                 ExecutableDescription = Configuration->GetFileDescription(Executable);
 
-               }
 
-               catch(...)
 
-               {
 
-               }
 
-               if (ExecutableDescription.IsEmpty())
 
-               {
 
-                 ExecutableDescription = ExecutableName;
 
-               }
 
-               Result = true;
 
-             }
 
-           }
 
-         }
 
-       }
 
-       __finally
 
-       {
 
-         DeleteFile(ApiPath(TempName));
 
-       }
 
-     }
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- // this was moved to global scope in past in some attempt to fix crashes,
 
- // not sure it really helped
 
- WINHTTP_CURRENT_USER_IE_PROXY_CONFIG IEProxyInfo;
 
- //---------------------------------------------------------------------------
 
- static bool __fastcall GetProxyUrlFromIE(UnicodeString & Proxy)
 
- {
 
-   bool Result = false;
 
-   memset(&IEProxyInfo, 0, sizeof(IEProxyInfo));
 
-   if (WinHttpGetIEProxyConfigForCurrentUser(&IEProxyInfo))
 
-   {
 
-     if (IEProxyInfo.lpszProxy != NULL)
 
-     {
 
-       UnicodeString IEProxy = IEProxyInfo.lpszProxy;
 
-       Proxy = L"";
 
-       while (Proxy.IsEmpty() && !IEProxy.IsEmpty())
 
-       {
 
-         UnicodeString Str = CutToChar(IEProxy, L';', true);
 
-         if (Str.Pos(L"=") == 0)
 
-         {
 
-           Proxy = Str;
 
-         }
 
-         else
 
-         {
 
-           UnicodeString Protocol = CutToChar(Str, L'=', true);
 
-           if (SameText(Protocol, L"http"))
 
-           {
 
-             Proxy = Str;
 
-           }
 
-         }
 
-       }
 
-       GlobalFree(IEProxyInfo.lpszProxy);
 
-       Result = true;
 
-     }
 
-     if (IEProxyInfo.lpszAutoConfigUrl != NULL)
 
-     {
 
-       GlobalFree(IEProxyInfo.lpszAutoConfigUrl);
 
-     }
 
-     if (IEProxyInfo.lpszProxyBypass != NULL)
 
-     {
 
-       GlobalFree(IEProxyInfo.lpszProxyBypass);
 
-     }
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall AutodetectProxy(UnicodeString & HostName, int & PortNumber)
 
- {
 
-   bool Result = false;
 
-   /* First we try for proxy info direct from the registry if
 
-      it's available. */
 
-   UnicodeString Proxy;
 
-   WINHTTP_PROXY_INFO ProxyInfo;
 
-   memset(&ProxyInfo, 0, sizeof(ProxyInfo));
 
-   if (WinHttpGetDefaultProxyConfiguration(&ProxyInfo))
 
-   {
 
-     if (ProxyInfo.lpszProxy != NULL)
 
-     {
 
-       Proxy = ProxyInfo.lpszProxy;
 
-       GlobalFree(ProxyInfo.lpszProxy);
 
-       Result = true;
 
-     }
 
-     if (ProxyInfo.lpszProxyBypass != NULL)
 
-     {
 
-       GlobalFree(ProxyInfo.lpszProxyBypass);
 
-     }
 
-   }
 
-   /* The next fallback is to get the proxy info from MSIE.  This is also
 
-      usually much quicker than WinHttpGetProxyForUrl(), although sometimes
 
-      it seems to fall back to that, based on the longish delay involved.
 
-      Another issue with this is that it won't work in a service process
 
-      that isn't impersonating an interactive user (since there isn't a
 
-      current user), but in that case we just fall back to
 
-      WinHttpGetProxyForUrl() */
 
-   if (!Result)
 
-   {
 
-     Result = GetProxyUrlFromIE(Proxy);
 
-   }
 
-   if (Result)
 
-   {
 
-     if (Proxy.Trim().IsEmpty())
 
-     {
 
-       Result = false;
 
-     }
 
-     else
 
-     {
 
-       HostName = CutToChar(Proxy, L':', true);
 
-       PortNumber = StrToIntDef(Proxy, ProxyPortNumber);
 
-     }
 
-   }
 
-   // We can also use WinHttpGetProxyForUrl, but it is lengthy
 
-   // See the source address of the code for example
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- //---------------------------------------------------------------------------
 
- class TWinHelpTester : public TInterfacedObject, public IWinHelpTester
 
- {
 
- public:
 
-   virtual bool __fastcall CanShowALink(const UnicodeString ALink, const UnicodeString FileName);
 
-   virtual bool __fastcall CanShowTopic(const UnicodeString Topic, const UnicodeString FileName);
 
-   virtual bool __fastcall CanShowContext(const int Context, const UnicodeString FileName);
 
-   virtual TStringList * __fastcall GetHelpStrings(const UnicodeString ALink);
 
-   virtual UnicodeString __fastcall GetHelpPath();
 
-   virtual UnicodeString __fastcall GetDefaultHelpFile();
 
-   IUNKNOWN
 
- };
 
- //---------------------------------------------------------------------------
 
- class TCustomHelpSelector : public TInterfacedObject, public IHelpSelector
 
- {
 
- public:
 
-   __fastcall TCustomHelpSelector(const UnicodeString & Name);
 
-   virtual int __fastcall SelectKeyword(TStrings * Keywords);
 
-   virtual int __fastcall TableOfContents(TStrings * Contents);
 
-   IUNKNOWN
 
- private:
 
-   UnicodeString FName;
 
- };
 
- //---------------------------------------------------------------------------
 
- void __fastcall AssignHelpSelector(IHelpSelector * HelpSelector)
 
- {
 
-   _di_IHelpSystem HelpSystem;
 
-   if (GetHelpSystem(HelpSystem))
 
-   {
 
-     HelpSystem->AssignHelpSelector(HelpSelector);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall InitializeCustomHelp(ICustomHelpViewer * HelpViewer)
 
- {
 
-   _di_IHelpManager HelpManager;
 
-   RegisterViewer(HelpViewer, HelpManager);
 
-   // Register dummy tester that disables win help
 
-   WinHelpTester = new TWinHelpTester();
 
-   AssignHelpSelector(new TCustomHelpSelector(HelpViewer->GetViewerName()));
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall FinalizeCustomHelp()
 
- {
 
-   AssignHelpSelector(NULL);
 
- }
 
- //---------------------------------------------------------------------------
 
- //---------------------------------------------------------------------------
 
- bool __fastcall TWinHelpTester::CanShowALink(const UnicodeString ALink,
 
-   const UnicodeString FileName)
 
- {
 
-   return !Application->HelpFile.IsEmpty();
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall TWinHelpTester::CanShowTopic(const UnicodeString Topic,
 
-   const UnicodeString FileName)
 
- {
 
-   DebugFail();
 
-   return !Application->HelpFile.IsEmpty();
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall TWinHelpTester::CanShowContext(const int /*Context*/,
 
-   const UnicodeString FileName)
 
- {
 
-   DebugFail();
 
-   return !Application->HelpFile.IsEmpty();
 
- }
 
- //---------------------------------------------------------------------------
 
- TStringList * __fastcall TWinHelpTester::GetHelpStrings(const UnicodeString ALink)
 
- {
 
-   DebugFail();
 
-   TStringList * Result = new TStringList();
 
-   Result->Add(ViewerName + L": " + ALink);
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- UnicodeString __fastcall TWinHelpTester::GetHelpPath()
 
- {
 
-   // never called on windows anyway
 
-   return ExtractFilePath(Application->HelpFile);
 
- }
 
- //---------------------------------------------------------------------------
 
- UnicodeString __fastcall TWinHelpTester::GetDefaultHelpFile()
 
- {
 
-   return Application->HelpFile;
 
- }
 
- //---------------------------------------------------------------------------
 
- //---------------------------------------------------------------------------
 
- __fastcall TCustomHelpSelector::TCustomHelpSelector(const UnicodeString & Name) :
 
-   FName(Name)
 
- {
 
- }
 
- //---------------------------------------------------------------------------
 
- int __fastcall TCustomHelpSelector::SelectKeyword(TStrings * /*Keywords*/)
 
- {
 
-   DebugFail();
 
-   return 0;
 
- }
 
- //---------------------------------------------------------------------------
 
- int __fastcall TCustomHelpSelector::TableOfContents(TStrings * Contents)
 
- {
 
-   return Contents->IndexOf(FName);
 
- }
 
 
  |