From b6a9f2268ee98c3ec09cfe1082640b29b91944b8 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Sat, 4 Sep 2021 04:31:26 +0300 Subject: [PATCH] Rewrite ``AppxReparse.exe`` to JNA No need to have separate tool for that GitOrigin-RevId: 3019b647cb3b9ce9c01967deace0e4fbed834302 --- bin/win/AppxReparse.exe | Bin 59416 -> 0 bytes .../AppxReparseTool/AppxReparse.rc | Bin 5206 -> 0 bytes .../AppxReparseTool/AppxReparseTool.vcxproj | 145 ------------------ .../AppxReparseTool.vcxproj.filters | 40 ----- .../AppxReparseTool.vcxproj.user | 4 - native/WinElevator/AppxReparseTool/README.txt | 19 --- .../WinElevator/AppxReparseTool/appxreparse.c | 93 ----------- native/WinElevator/AppxReparseTool/resource.h | 16 -- native/WinElevator/Elevator.sln | 10 -- native/WinElevator/README.txt | 7 +- python/intellij.python.community.impl.iml | 1 + .../python/sdk/flavors/WinAppxTools.kt | 95 ++++++++++-- 12 files changed, 84 insertions(+), 346 deletions(-) delete mode 100644 bin/win/AppxReparse.exe delete mode 100644 native/WinElevator/AppxReparseTool/AppxReparse.rc delete mode 100644 native/WinElevator/AppxReparseTool/AppxReparseTool.vcxproj delete mode 100644 native/WinElevator/AppxReparseTool/AppxReparseTool.vcxproj.filters delete mode 100644 native/WinElevator/AppxReparseTool/AppxReparseTool.vcxproj.user delete mode 100644 native/WinElevator/AppxReparseTool/README.txt delete mode 100644 native/WinElevator/AppxReparseTool/appxreparse.c delete mode 100644 native/WinElevator/AppxReparseTool/resource.h diff --git a/bin/win/AppxReparse.exe b/bin/win/AppxReparse.exe deleted file mode 100644 index c3e84982e0fe9a8dd457e43f2f78274271f90b0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59416 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 K*naF)`+orBRLxuf diff --git a/native/WinElevator/AppxReparseTool/AppxReparse.rc b/native/WinElevator/AppxReparseTool/AppxReparse.rc deleted file mode 100644 index e74e559e5e874bfd7681b6aefb5e240ac1fe457d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5206 zcmd6rTW=ai6vxkVrGAGkereRmHc4Lkh%rXA*jVAxRI+3_Hg>3NgSe!%l+T{z_n+Zp zciF`aKf&c7%zHo|*}doVO*mUA;P2Z9tAx|S+zaP! z1D<6JnDv>p?QbAmeoyTPNSn3umkhi2xO6@z*2FHWHonD5 zV|zgVIo6RKdT9NQ-xgZe(Np$l0Dr|;^~nGG;NM{1h?lqj?pe$wiqWyaR*Ixs^xiHu z-11I$w`P|vAtxt<{&Rh{65QM(I{Bxms~d8K%-_S#8J$mE*aB@YMn^B zB%azlqWg&_S&P|&##^FRH2UP*i@>!F^bBa9xfvqUA%3n)?CQ)*Xm>ex1h(L<-!0R{sj9tVC^ST0&jSgIl0@F=V96)V=3id|5nE{Nh-=Tj-yN%VS4i8kf47i#YfIi`9N zA9<~;wiKgHw$sS^dAHUsozMEt>uav6GR7Yc*Q_xhGcWmVklV^vePb^}be*skc6LV= z5nPxFs}|YYSUHmr!7qusII7FD=g{vEfqiOE@4GOZ`bnr7O{6=eUUbR*1nU3UYdqKv z)D@L!)rhs_2u{rvIa5lJLiHQ|kbY%`o$`9EoZB$(rGbzygSXoO}%{Pc*dn%@WP=KFtM8eFZ{8E}b;a8dxV{<{`-AnInx}qLI?aI2 z=sBm1F{50La!ziIV`yeO*q9m4u?O98=!xgdNsvtWqn@nB+l1JQ9hhYHoe5_p-+U{H z@;T~~RMGEnIjS4cmA}=!Pnp%ZzLfLr(n58vy^ozIGnYhthXwH8*o zn}p6w_r(Njjd@dD)7`$smo~AFSWx$HRjx^}r*7}M(d)LY%B8ch%IQX`e*<(wOu$o} zQ)FIeypV+VtXwg|A2_3oRBeuOtJ@HDQ56s2h^nGp_4{eL`@kIUu9CPFI*&Tvva`?y zdkmJ%EvkslmF< - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {FFD92D09-1024-48E0-B3AB-DA83171B8F42} - AppxReparseTool - 10.0.18362.0 - AppxReparse - - - - Application - true - v141 - Unicode - - - Application - false - v141 - true - Unicode - - - Application - true - v141 - Unicode - - - Application - false - v141 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - Level3 - MaxSpeed - true - true - true - true - Speed - - - Console - true - true - - - - - Level3 - Disabled - true - true - - - Console - - - - - Level3 - Disabled - true - true - - - Console - - - - - Level3 - MaxSpeed - true - true - true - true - - - Console - true - true - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/native/WinElevator/AppxReparseTool/AppxReparseTool.vcxproj.filters b/native/WinElevator/AppxReparseTool/AppxReparseTool.vcxproj.filters deleted file mode 100644 index d3f668cf84d4..000000000000 --- a/native/WinElevator/AppxReparseTool/AppxReparseTool.vcxproj.filters +++ /dev/null @@ -1,40 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - - - Header Files - - - - - Resource Files - - - - - Resource Files - - - - - - \ No newline at end of file diff --git a/native/WinElevator/AppxReparseTool/AppxReparseTool.vcxproj.user b/native/WinElevator/AppxReparseTool/AppxReparseTool.vcxproj.user deleted file mode 100644 index 6e2aec7aefc8..000000000000 --- a/native/WinElevator/AppxReparseTool/AppxReparseTool.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/native/WinElevator/AppxReparseTool/README.txt b/native/WinElevator/AppxReparseTool/README.txt deleted file mode 100644 index f170bbb0d26c..000000000000 --- a/native/WinElevator/AppxReparseTool/README.txt +++ /dev/null @@ -1,19 +0,0 @@ -AppX apps are installed in "C:\Program Files\WindowsApps\". -You can't run them directly. Instead, you must use reparse point from -"%LOCALAPPDATA%\Microsoft\WindowsApps" (this folder is under the %PATH%) - -Reparse point is the special structure on NTFS level that stores "reparse tag" (type) and some type-specific data. -When a user accesses such files, Windows redirects the request to the appropriate target. -So, files in "%LOCALAPPDATA%\Microsoft\WindowsApps" are reparse points to AppX apps, and AppX can only be launched via them. - -But for Python, there can be a reparse point that points to Windows store, so Store is opened when Python is not installed. -There is no official way to tell if "python.exe" points to AppX python or AppX "Windows Store". - -MS provides API (via DeviceIOControl) to read reparse point structure. -There is also a reparse point tag for "AppX link" in SDK. -Reparse data is undocumented, but it is just an array of wide chars with some unprintable chars at the beginning. - -This tool reads reparse point info and tries to fetch AppX name, so we can see if it points to Store or not. -See https://youtrack.jetbrains.com/issue/PY-43082 - -Output is unicode 16-LE diff --git a/native/WinElevator/AppxReparseTool/appxreparse.c b/native/WinElevator/AppxReparseTool/appxreparse.c deleted file mode 100644 index 9ba4a859218e..000000000000 --- a/native/WinElevator/AppxReparseTool/appxreparse.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include - -// Accepts path to AppX reparse point in "%LOCALAPPDATA%\Microsoft\WindowsApps" -// Returns name of AppX or error if wrong reparse point - -typedef struct -{ - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - wchar_t DATA[1024]; //1024 wide chars should be enough for AppX name -} REPARSE_DATA_BUFFER; - -static DWORD _ProcessError(const wchar_t* place) -{ - const DWORD error = GetLastError(); - fwprintf(stderr, L"%ls: error %ld", place, error); - return error; -} - -int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) -{ - if (argc != 2) - { - fwprintf(stderr, L"Provide path to app"); - return -1; - } - const wchar_t* path = argv[1]; - - HANDLE file = CreateFileW( - path, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT, - NULL); - if (file == INVALID_HANDLE_VALUE) - { - return _ProcessError(L"CreateFile"); - } - - REPARSE_DATA_BUFFER buffer; - ZeroMemory(&buffer, sizeof(buffer)); - DWORD numOfBytes = 0; - - if (!DeviceIoControl( - file, - FSCTL_GET_REPARSE_POINT, - NULL, - 0, - &buffer, - sizeof(buffer), - &numOfBytes, - NULL - )) - { - CloseHandle(file); - return _ProcessError(L"DeviceIoCtl"); - } - - if (numOfBytes == 0 || buffer.ReparseTag != IO_REPARSE_TAG_APPEXECLINK) - { - fwprintf(stderr, L"Not a reparse point"); - CloseHandle(file); - return -1; - } - - - const WCHAR* textStart = buffer.DATA; - // Data consists of several unprintable (<32) chars following human-readable name of AppX - // Search for first printable (>32) char. - USHORT firstPrintableChar; - const USHORT maxChars = buffer.ReparseDataLength / sizeof(WCHAR); - for (firstPrintableChar = 0; (!iswprint(*textStart)) && firstPrintableChar < maxChars; firstPrintableChar++, - textStart++) - { - } - if (firstPrintableChar == maxChars) - { - fwprintf(stderr, L"No printable chars in data"); - CloseHandle(file); - return -1; - } - //stdlib wprintf will convert chars to 1-byte charset, which may break non-ascii chars (if any) - // we print wide chars (16 bit LE) directly to stdout - const DWORD textLenInBytes = wcsnlen_s(textStart, maxChars - firstPrintableChar) * sizeof(WCHAR); - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), textStart, textLenInBytes, &numOfBytes, NULL); - CloseHandle(file); - return 0; -} diff --git a/native/WinElevator/AppxReparseTool/resource.h b/native/WinElevator/AppxReparseTool/resource.h deleted file mode 100644 index d083e0c6a168..000000000000 --- a/native/WinElevator/AppxReparseTool/resource.h +++ /dev/null @@ -1,16 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by AppxReparse.rc -// -#define IDI_ICON1 101 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/native/WinElevator/Elevator.sln b/native/WinElevator/Elevator.sln index 4d663dc7a2b0..14b657754efc 100644 --- a/native/WinElevator/Elevator.sln +++ b/native/WinElevator/Elevator.sln @@ -18,8 +18,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.txt = README.txt EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppxReparseTool", "AppxReparseTool\AppxReparseTool.vcxproj", "{FFD92D09-1024-48E0-B3AB-DA83171B8F42}" -EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution elevShared\elevShared.vcxitems*{45d41acc-2c3c-43d2-bc10-02aa73ffc7c7}*SharedItemsImports = 9 @@ -49,14 +47,6 @@ Global {9D71A73C-2570-488A-958B-A126F4EEECB7}.Release|x64.Build.0 = Release|x64 {9D71A73C-2570-488A-958B-A126F4EEECB7}.Release|x86.ActiveCfg = Release|Win32 {9D71A73C-2570-488A-958B-A126F4EEECB7}.Release|x86.Build.0 = Release|Win32 - {FFD92D09-1024-48E0-B3AB-DA83171B8F42}.Debug|x64.ActiveCfg = Debug|x64 - {FFD92D09-1024-48E0-B3AB-DA83171B8F42}.Debug|x64.Build.0 = Debug|x64 - {FFD92D09-1024-48E0-B3AB-DA83171B8F42}.Debug|x86.ActiveCfg = Debug|Win32 - {FFD92D09-1024-48E0-B3AB-DA83171B8F42}.Debug|x86.Build.0 = Debug|Win32 - {FFD92D09-1024-48E0-B3AB-DA83171B8F42}.Release|x64.ActiveCfg = Release|x64 - {FFD92D09-1024-48E0-B3AB-DA83171B8F42}.Release|x64.Build.0 = Release|x64 - {FFD92D09-1024-48E0-B3AB-DA83171B8F42}.Release|x86.ActiveCfg = Release|Win32 - {FFD92D09-1024-48E0-B3AB-DA83171B8F42}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/native/WinElevator/README.txt b/native/WinElevator/README.txt index 8f08da06121f..13d6f68240c2 100644 --- a/native/WinElevator/README.txt +++ b/native/WinElevator/README.txt @@ -1,6 +1,3 @@ -This project consists of two tools: "launcher and elevator" and "appxreparse". - - Launcher and elevator: With UAC enabled, even an administrator has a limited access token and can't modify some folders like "Program Files". @@ -20,14 +17,12 @@ But if std(out|err|in) are redirected to files or pipes, attaching to a console In this case, the launcher creates named pipes, the elevator connects to them and provides their handlers as handlers for the newly created process. The launcher then creates threads to read/write them to the console. -For "AppxReparse" see README inside the project. ------- How to build. ToolChain: VisualStudio 2017 SDK: 8.1 (for "launcher and elevator") -Win10 10.0.18362 (for "appx reparse") You may open .sln from Visual Studio or use msbuild from VS command prompt: msbuild Elevator.sln /p:Configuration=release /property:Platform=x86 @@ -56,5 +51,5 @@ Check no error -------- How to check errors. -Both tools report errors as error codes, stderr and event log under "Application". +Tool reports errors as error codes, stderr and event log under "Application". No event ids are registered, but you can check eventId and find an appropriate ReportEvent call. diff --git a/python/intellij.python.community.impl.iml b/python/intellij.python.community.impl.iml index e9515070aabe..96e11a8aa9b7 100644 --- a/python/intellij.python.community.impl.iml +++ b/python/intellij.python.community.impl.iml @@ -78,5 +78,6 @@ + \ No newline at end of file diff --git a/python/src/com/jetbrains/python/sdk/flavors/WinAppxTools.kt b/python/src/com/jetbrains/python/sdk/flavors/WinAppxTools.kt index a4d280b4f331..2d216a28babc 100644 --- a/python/src/com/jetbrains/python/sdk/flavors/WinAppxTools.kt +++ b/python/src/com/jetbrains/python/sdk/flavors/WinAppxTools.kt @@ -1,11 +1,16 @@ // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.jetbrains.python.sdk.flavors -import com.intellij.openapi.application.PathManager +import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.util.SystemInfo +import com.sun.jna.platform.win32.Kernel32 +import com.sun.jna.platform.win32.Kernel32.* +import com.sun.jna.platform.win32.Ntifs +import com.sun.jna.platform.win32.WinioctlUtil +import com.sun.jna.ptr.IntByReference import java.io.File import java.io.FilenameFilter -import java.util.concurrent.TimeUnit +import java.nio.ByteBuffer /** * AppX packages installed to AppX volume (see ``Get-AppxDefaultVolume``, ``Get-AppxPackage``). @@ -18,7 +23,7 @@ import java.util.concurrent.TimeUnit * But when executed, they are processed by NTFS filter and redirected to their real location in AppX volume. * * There may be ``python.exe`` there, but it may point to Windows Store (so it can be installed when accessed) or to the real python. - * There is no Java API to see reparse point destination, so we use native app (See ``appxreparse.c`` and README in the same folder). + * There is no Java API to see reparse point destination, so we use JNA. * This tool returns AppX name (either ``PythonSoftwareFoundation...`` or ``DesktopAppInstaller..``). * We use it to check if ``python.exe`` is real python or WindowsStore mock. */ @@ -42,23 +47,19 @@ fun getAppxFiles(expectedProduct: String, filePattern: Regex): Collection ?.filterKeys { expectedProduct in it } ?.values ?: emptyList() + /** - * If file is AppX reparse point link -- return it's product name + * If file is AppX reparse point link -- return its product name */ val File.appxProduct: String? get() { if (parentFile?.equals(userAppxFolder) != true) return null - val reparseTool = PathManager.findBinFile("AppxReparse.exe")!! - // Intellij API prohibits running external processes under Read action or on EDT, so we use java api as it is done for registry - val process = Runtime.getRuntime().exec(arrayOf(reparseTool.toFile().absolutePath, absolutePath)) - // It is much faster in most cases, but since this code may run under EDT we limit it - if (!process.waitFor(1, TimeUnit.SECONDS)) return null - if (process.exitValue() != 0) return null - // appxreparse outputs wide chars (2 bytes), they are LE on Intel - val output = process.inputStream.readBytes().toString(Charsets.UTF_16LE) - return if (storeMarker !in output) output else null + return getAppxTag(absolutePath)?.let { + if (storeMarker !in it) it else null + } } + /** * Path to ``%LOCALAPPDATA%\Microsoft\WindowsApps`` */ @@ -72,3 +73,71 @@ private val userAppxFolder = if (appsPath.exists()) appsPath else null } } + + +// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/c8e77b37-3909-4fe6-a4ea-2b9d423b1ee4 +private const val IO_REPARSE_TAG_APPEXECLINK = 0x8000001B + +/** + * AppX apps are installed in "C:\Program Files\WindowsApps\". +You can't run them directly. Instead, you must use reparse point from +"%LOCALAPPDATA%\Microsoft\WindowsApps" (this folder is under the %PATH%) + +Reparse point is the special structure on NTFS level that stores "reparse tag" (type) and some type-specific data. +When a user accesses such files, Windows redirects the request to the appropriate target. +So, files in "%LOCALAPPDATA%\Microsoft\WindowsApps" are reparse points to AppX apps, and AppX can only be launched via them. + +But for Python, there can be a reparse point that points to Windows store, so Store is opened when Python is not installed. +There is no official way to tell if "python.exe" points to AppX python or AppX "Windows Store". + +MS provides API (via DeviceIOControl) to read reparse point structure. +There is also a reparse point tag for "AppX link" in SDK. +Reparse data is undocumented, but it is just an array of wide chars with some unprintable chars at the beginning. + +This tool reads reparse point info and tries to fetch AppX name, so we can see if it points to Store or not. +See https://youtrack.jetbrains.com/issue/PY-43082 + +Output is unicode 16-LE + */ +private fun getAppxTag(path: String): String? { + if (!SystemInfo.isWin10OrNewer) return null + val kernel = INSTANCE + val logger = Logger.getInstance(Kernel32::class.java) + val file = kernel.CreateFile(path, GENERIC_READ, FILE_SHARE_READ, null, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, null) + if (file == INVALID_HANDLE_VALUE) { + logger.warn("Invalid handle for $path") + return null + } + val buffer = Ntifs.REPARSE_DATA_BUFFER() + val bytesRead = IntByReference() + if (!kernel.DeviceIoControl(file, WinioctlUtil.FSCTL_GET_REPARSE_POINT, null, 0, buffer.pointer, buffer.size(), bytesRead, null)) { + logger.warn("DeviceIoControl error ${kernel.GetLastError()}") + return null + } + if (bytesRead.value < 1) { + logger.warn("0 bytes read") + return null + } + buffer.read() + if (buffer.ReparseTag != IO_REPARSE_TAG_APPEXECLINK.toInt()) { + logger.warn("Wrong tag ${buffer.ReparseTag}") + return null + } + // output is array of LE 2 bytes chars: \0\0\0[text]\0[junk] + val charBuffer = Charsets.UTF_16LE.decode(ByteBuffer.wrap(buffer.u.genericReparseBuffer.DataBuffer)) + var from = 0 + var to = 0 + var startFound = false + for ((i, char) in charBuffer.withIndex()) { + val validChar = Character.getType(char) != Character.CONTROL.toInt() + if (validChar && !startFound) { + from = i + startFound = true + } + if (!validChar && startFound) { + to = i + break + } + } + return charBuffer.substring(from, to) +} \ No newline at end of file