]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-100107: Make py.exe launcher ignore app aliases that launch Microsoft Store (GH...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 25 Jan 2024 00:40:45 +0000 (01:40 +0100)
committerGitHub <noreply@github.com>
Thu, 25 Jan 2024 00:40:45 +0000 (00:40 +0000)
(cherry picked from commit d5c21c12c17b6e4db2378755af8e3699516da187)

Co-authored-by: Vincent Cunningham <flagrama@users.noreply.github.com>
Misc/NEWS.d/next/Windows/2024-01-23-00-05-05.gh-issue-100107.lkbP_Q.rst [new file with mode: 0644]
PC/launcher2.c

diff --git a/Misc/NEWS.d/next/Windows/2024-01-23-00-05-05.gh-issue-100107.lkbP_Q.rst b/Misc/NEWS.d/next/Windows/2024-01-23-00-05-05.gh-issue-100107.lkbP_Q.rst
new file mode 100644 (file)
index 0000000..388d61a
--- /dev/null
@@ -0,0 +1 @@
+The ``py.exe`` launcher will no longer attempt to run the Microsoft Store redirector when launching a script containing a ``/usr/bin/env`` shebang
index bb500d4b6bfb070a3ccda7ed2e6b519e742da753..0387700cb72113d9c88e88af931b66c94f55a278 100644 (file)
@@ -565,6 +565,21 @@ findArgv0End(const wchar_t *buffer, int bufferLength)
  ***                          COMMAND-LINE PARSING                          ***
 \******************************************************************************/
 
+// Adapted from https://stackoverflow.com/a/65583702
+typedef struct AppExecLinkFile { // For tag IO_REPARSE_TAG_APPEXECLINK
+    DWORD reparseTag;
+    WORD reparseDataLength;
+    WORD reserved;
+    ULONG version;
+    wchar_t stringList[MAX_PATH * 4];  // Multistring (Consecutive UTF-16 strings each ending with a NUL)
+    /* There are normally 4 strings here. Ex:
+        Package ID:  L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe"
+        Entry Point: L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe!PythonRedirector"
+        Executable:  L"C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.17.106910_x64__8wekyb3d8bbwe\AppInstallerPythonRedirector.exe"
+        Applic. Type: L"0"   // Integer as ASCII. "0" = Desktop bridge application; Else sandboxed UWP application
+    */
+} AppExecLinkFile;
+
 
 int
 parseCommandLine(SearchInfo *search)
@@ -756,6 +771,55 @@ _shebangStartsWith(const wchar_t *buffer, int bufferLength, const wchar_t *prefi
 }
 
 
+int
+ensure_no_redirector_stub(wchar_t* filename, wchar_t* buffer)
+{
+    // Make sure we didn't find a reparse point that will open the Microsoft Store
+    // If we did, pretend there was no shebang and let normal handling take over
+    WIN32_FIND_DATAW findData;
+    HANDLE hFind = FindFirstFileW(buffer, &findData);
+    if (!hFind) {
+        // Let normal handling take over
+        debug(L"# Did not find %s on PATH\n", filename);
+        return RC_NO_SHEBANG;
+    }
+
+    FindClose(hFind);
+
+    if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
+        findData.dwReserved0 & IO_REPARSE_TAG_APPEXECLINK)) {
+        return 0;
+    }
+
+    HANDLE hReparsePoint = CreateFileW(buffer, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL);
+    if (!hReparsePoint) {
+        // Let normal handling take over
+        debug(L"# Did not find %s on PATH\n", filename);
+        return RC_NO_SHEBANG;
+    }
+
+    AppExecLinkFile appExecLink;
+
+    if (!DeviceIoControl(hReparsePoint, FSCTL_GET_REPARSE_POINT, NULL, 0, &appExecLink, sizeof(appExecLink), NULL, NULL)) {
+        // Let normal handling take over
+        debug(L"# Did not find %s on PATH\n", filename);
+        CloseHandle(hReparsePoint);
+        return RC_NO_SHEBANG;
+    }
+
+    CloseHandle(hReparsePoint);
+
+    const wchar_t* redirectorPackageId = L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe";
+
+    if (0 == wcscmp(appExecLink.stringList, redirectorPackageId)) {
+        debug(L"# ignoring redirector that would launch store\n");
+        return RC_NO_SHEBANG;
+    }
+
+    return 0;
+}
+
+
 int
 searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength)
 {
@@ -817,6 +881,11 @@ searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength)
         return RC_BAD_VIRTUAL_PATH;
     }
 
+    int result = ensure_no_redirector_stub(filename, buffer);
+    if (result) {
+        return result;
+    }
+
     // Check that we aren't going to call ourselves again
     // If we are, pretend there was no shebang and let normal handling take over
     if (GetModuleFileNameW(NULL, filename, MAXLEN) &&