浏览代码

Adding parent process to session log and counters

(cherry picked from commit a4236a7cef5ba923a89474c6bc5d89638542e06e)

Source commit: 62da34b202f938f156f60cc3deb8520f20e0efe3
Martin Prikryl 5 年之前
父节点
当前提交
782298652c
共有 6 个文件被更改,包括 125 次插入4 次删除
  1. 1 1
      deployment/winscpsetup.iss
  2. 2 2
      source/WinSCP.cbproj
  3. 91 0
      source/core/Common.cpp
  4. 1 0
      source/core/Common.h
  5. 1 0
      source/core/SessionInfo.cpp
  6. 29 1
      source/windows/WinMain.cpp

+ 1 - 1
deployment/winscpsetup.iss

@@ -1419,7 +1419,7 @@ begin
       // old style counter
       // old style counter
       UsageData := UsageData + Format('TypicalInstallation:%d,', [Integer(IsTypicalInstallation)]);
       UsageData := UsageData + Format('TypicalInstallation:%d,', [Integer(IsTypicalInstallation)]);
 
 
-      UsageData := UsageData + 'InstallationsUser+,';
+      UsageData := UsageData + 'InstallationsUser+,InstallationParentProcess@,';
 
 
       Installations := 0; // default, if the counter does not exist
       Installations := 0; // default, if the counter does not exist
       RegQueryDWordValue(HKEY_LOCAL_MACHINE, '{#RegistryKey}', 'Installations', Installations);
       RegQueryDWordValue(HKEY_LOCAL_MACHINE, '{#RegistryKey}', 'Installations', Installations);

+ 2 - 2
source/WinSCP.cbproj

@@ -49,7 +49,7 @@
 	</PropertyGroup>
 	</PropertyGroup>
 	<PropertyGroup Condition="'$(Base)'!=''">
 	<PropertyGroup Condition="'$(Base)'!=''">
 		<_TCHARMapping>wchar_t</_TCHARMapping>
 		<_TCHARMapping>wchar_t</_TCHARMapping>
-		<AllPackageLibs>vcl.lib;rtl.lib;vclx.lib;ws2_32.lib;secur32.lib;My.lib;DriveDir.lib;DragDropP.lib;tb2k.lib;tbxp.lib;bcbie.lib;Crypt32.lib;PngComponents.lib;xmlrtl.lib;vclactnband.lib;vclimg.lib;winhttp.lib;jcl.lib;vclie.lib;urlmon.lib;shlwapi.lib;powrprof.lib;soaprtl.lib;fmx.lib;dbrtl.lib;inet.lib</AllPackageLibs>
+		<AllPackageLibs>vcl.lib;rtl.lib;vclx.lib;ws2_32.lib;secur32.lib;My.lib;DriveDir.lib;DragDropP.lib;tb2k.lib;tbxp.lib;bcbie.lib;Crypt32.lib;PngComponents.lib;xmlrtl.lib;vclactnband.lib;vclimg.lib;winhttp.lib;jcl.lib;vclie.lib;urlmon.lib;shlwapi.lib;powrprof.lib;soaprtl.lib;fmx.lib;dbrtl.lib;inet.lib;psapi.lib</AllPackageLibs>
 		<BCC_AllWarnings>true</BCC_AllWarnings>
 		<BCC_AllWarnings>true</BCC_AllWarnings>
 		<BCC_ExtendedErrorInfo>true</BCC_ExtendedErrorInfo>
 		<BCC_ExtendedErrorInfo>true</BCC_ExtendedErrorInfo>
 		<BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
 		<BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
@@ -106,7 +106,7 @@
 	<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
 	<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
 		<ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>
 		<ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>
 		<ILINK_LibraryPath>$(INTERM_PATH)\Win32\Debug\;$(BDS)\lib\Win32\Debug\;$(BDS)\lib\Win32\Release\;$(BDS)\lib\Win32\Release\psdk\;$(ILINK_LibraryPath)</ILINK_LibraryPath>
 		<ILINK_LibraryPath>$(INTERM_PATH)\Win32\Debug\;$(BDS)\lib\Win32\Debug\;$(BDS)\lib\Win32\Release\;$(BDS)\lib\Win32\Release\psdk\;$(ILINK_LibraryPath)</ILINK_LibraryPath>
-		<LinkPackageStatics>vcl.lib;rtl.lib;vclx.lib;ws2_32.lib;secur32.lib;My.lib;DriveDir.lib;DragDropP.lib;tb2k.lib;tbxp.lib;bcbie.lib;Crypt32.lib;PngComponents.lib;xmlrtl.lib;vclactnband.lib;vclimg.lib;winhttp.lib;jcl.lib;vclie.lib;urlmon.lib;shlwapi.lib;powrprof.lib;soaprtl.lib;fmx.lib;dbrtl.lib;inet.lib</LinkPackageStatics>
+		<LinkPackageStatics>vcl.lib;rtl.lib;vclx.lib;ws2_32.lib;secur32.lib;My.lib;DriveDir.lib;DragDropP.lib;tb2k.lib;tbxp.lib;bcbie.lib;Crypt32.lib;PngComponents.lib;xmlrtl.lib;vclactnband.lib;vclimg.lib;winhttp.lib;jcl.lib;vclie.lib;urlmon.lib;shlwapi.lib;powrprof.lib;soaprtl.lib;fmx.lib;dbrtl.lib;inet.lib;psapi.lib</LinkPackageStatics>
 	</PropertyGroup>
 	</PropertyGroup>
 	<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
 	<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
 		<ILINK_LibraryPath>$(INTERM_PATH)\Win64\Debug\;$(BDS)\lib\Win64\Debug\;$(BDS)\lib\Win64\Release\;$(BDS)\lib\Win64\Release\psdk\;$(ILINK_LibraryPath)</ILINK_LibraryPath>
 		<ILINK_LibraryPath>$(INTERM_PATH)\Win64\Debug\;$(BDS)\lib\Win64\Debug\;$(BDS)\lib\Win64\Release\;$(BDS)\lib\Win64\Release\psdk\;$(ILINK_LibraryPath)</ILINK_LibraryPath>

+ 91 - 0
source/core/Common.cpp

@@ -13,6 +13,8 @@
 #include <shlobj.h>
 #include <shlobj.h>
 #include <limits>
 #include <limits>
 #include <shlwapi.h>
 #include <shlwapi.h>
+#include <tlhelp32.h>
+#include <psapi.h>
 #include <CoreMain.h>
 #include <CoreMain.h>
 #include <openssl/pkcs12.h>
 #include <openssl/pkcs12.h>
 #include <openssl/pem.h>
 #include <openssl/pem.h>
@@ -4078,3 +4080,92 @@ void SetStringValueEvenIfEmpty(TStrings * Strings, const UnicodeString & Name, c
     Strings->Values[Name] = Value;
     Strings->Values[Name] = Value;
   }
   }
 }
 }
+//---------------------------------------------------------------------------
+DWORD __fastcall GetParentProcessId(HANDLE Snapshot, DWORD ProcessId)
+{
+  DWORD Result = 0;
+
+  PROCESSENTRY32 ProcessEntry;
+  memset(&ProcessEntry, sizeof(ProcessEntry), 0);
+  ProcessEntry.dwSize = sizeof(PROCESSENTRY32);
+
+  if (Process32First(Snapshot, &ProcessEntry))
+  {
+    do
+    {
+      if (ProcessEntry.th32ProcessID == ProcessId)
+      {
+        Result = ProcessEntry.th32ParentProcessID;
+      }
+    } while (Process32Next(Snapshot, &ProcessEntry));
+  }
+  return Result;
+}
+//---------------------------------------------------------------------------
+UnicodeString ParentProcessName;
+//---------------------------------------------------------------------------
+UnicodeString __fastcall GetAncestorProcessName(int Levels)
+{
+  UnicodeString Result;
+  bool Parent = (Levels == 1);
+  if (Parent && !ParentProcessName.IsEmpty())
+  {
+    Result = ParentProcessName;
+  }
+  else
+  {
+    try
+    {
+      HANDLE Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+
+      DWORD ProcessId = GetCurrentProcessId();
+
+      while ((Levels > 0) && (ProcessId != 0))
+      {
+        ProcessId = GetParentProcessId(Snapshot, ProcessId);
+        Levels--;
+      }
+
+      if (ProcessId == 0)
+      {
+        Result = L"err-notfound";
+      }
+      else
+      {
+        HANDLE Process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessId);
+        if (!Process)
+        {
+          // is common, when the parent process is installer, so we ignore it
+          Result = UnicodeString();
+        }
+        else
+        {
+          Result.SetLength(MAX_PATH);
+          DWORD Len = GetModuleFileNameEx(Process, NULL, Result.c_str(), Result.Length());
+          if (Len == 0)
+          {
+            Result = L"err-name";
+          }
+          else
+          {
+            Result.SetLength(Len);
+            Result = ExtractProgramName(FormatCommand(Result, UnicodeString()));
+          }
+          CloseHandle(Process);
+        }
+      }
+
+      CloseHandle(Snapshot);
+    }
+    catch (...)
+    {
+      Result = L"err-except";
+    }
+
+    if (Parent)
+    {
+      ParentProcessName = Result;
+    }
+  }
+  return Result;
+}

+ 1 - 0
source/core/Common.h

@@ -183,6 +183,7 @@ bool __fastcall IsRealFile(const UnicodeString & FileName);
 UnicodeString GetOSInfo();
 UnicodeString GetOSInfo();
 UnicodeString GetEnvironmentInfo();
 UnicodeString GetEnvironmentInfo();
 void SetStringValueEvenIfEmpty(TStrings * Strings, const UnicodeString & Name, const UnicodeString & Value);
 void SetStringValueEvenIfEmpty(TStrings * Strings, const UnicodeString & Name, const UnicodeString & Value);
+UnicodeString __fastcall GetAncestorProcessName(int Levels = 1);
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 struct TSearchRecSmart : public TSearchRec
 struct TSearchRecSmart : public TSearchRec
 {
 {

+ 1 - 0
source/core/SessionInfo.cpp

@@ -1175,6 +1175,7 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
     ADF(L"Local account: %s", (UserName));
     ADF(L"Local account: %s", (UserName));
     ADF(L"Working directory: %s", (GetCurrentDir()));
     ADF(L"Working directory: %s", (GetCurrentDir()));
     ADF(L"Process ID: %d", (int(GetCurrentProcessId())));
     ADF(L"Process ID: %d", (int(GetCurrentProcessId())));
+    ADF(L"Parent process: %s", (GetAncestorProcessName()));
     ADF(L"Command-line: %s", (GetCmdLineLog()));
     ADF(L"Command-line: %s", (GetCmdLineLog()));
     if (FConfiguration->LogProtocol >= 1)
     if (FConfiguration->LogProtocol >= 1)
     {
     {

+ 29 - 1
source/windows/WinMain.cpp

@@ -19,6 +19,7 @@
 #include "Tools.h"
 #include "Tools.h"
 #include "WinApi.h"
 #include "WinApi.h"
 #include <DateUtils.hpp>
 #include <DateUtils.hpp>
+#include <StrUtils.hpp>
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 #pragma package(smart_init)
 #pragma package(smart_init)
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
@@ -323,10 +324,25 @@ void __fastcall Usage(UnicodeString Param)
         UnicodeString Key = Pair.SubString(1, Pair.Length() - 1).Trim();
         UnicodeString Key = Pair.SubString(1, Pair.Length() - 1).Trim();
         Configuration->Usage->Inc(Key);
         Configuration->Usage->Inc(Key);
       }
       }
+      else if (Pair[Pair.Length()] == L'@')
+      {
+        UnicodeString Key = Pair.SubString(1, Pair.Length() - 1).Trim();
+        UnicodeString Value;
+        if (SameText(Key, L"InstallationParentProcess"))
+        {
+          Value = GetAncestorProcessName(3).LowerCase();
+        }
+        else
+        {
+          Value = L"err-unknown-key";
+        }
+        Configuration->Usage->Set(Key, Value);
+      }
       else
       else
       {
       {
         UnicodeString Key = CutToChar(Pair, L':', true);
         UnicodeString Key = CutToChar(Pair, L':', true);
-        Configuration->Usage->Set(Key, Pair.Trim());
+        UnicodeString Value = Pair.Trim();
+        Configuration->Usage->Set(Key, Value);
       }
       }
     }
     }
   }
   }
@@ -512,6 +528,18 @@ void __fastcall UpdateStaticUsage()
   Configuration->Usage->Set(L"NetFrameworkVersion", GetNetVersionStr());
   Configuration->Usage->Set(L"NetFrameworkVersion", GetNetVersionStr());
   Configuration->Usage->Set(L"PowerShellVersion", GetPowerShellVersionStr());
   Configuration->Usage->Set(L"PowerShellVersion", GetPowerShellVersionStr());
 
 
+  UnicodeString ParentProcess = GetAncestorProcessName();
+  // do not record the installer as a parent process
+  if (!ParentProcess.IsEmpty() &&
+      (!StartsText(L"winscp-", ParentProcess) || !EndsText(L"-setup", ParentProcess)))
+  {
+    UnicodeString ParentProcesses = Configuration->Usage->Get(L"ParentProcesses");
+    std::unique_ptr<TStringList> ParentProcessesList(CreateSortedStringList());
+    ParentProcessesList->CommaText = ParentProcesses;
+    ParentProcessesList->Add(ParentProcess.LowerCase());
+    Configuration->Usage->Set(L"ParentProcesses", ParentProcessesList->CommaText);
+  }
+
   WinConfiguration->UpdateStaticUsage();
   WinConfiguration->UpdateStaticUsage();
 
 
 }
 }