-
-
Notifications
You must be signed in to change notification settings - Fork 33.6k
gh-100107: Make Py launcher ignore app aliases that launch Microsoft Store #114358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
028712f
5fa3ca9
8f652d1
adca3a9
9783c95
1cf0235
ac0c60d
ba7fe3e
eeecc2e
6c819f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -571,6 +571,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 | ||||||
|
|
@@ -826,6 +841,72 @@ searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength) | |||||
| return RC_BAD_VIRTUAL_PATH; | ||||||
| } | ||||||
|
|
||||||
| // 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) { | ||||||
| if (GetLastError() == ERROR_FILE_NOT_FOUND) { | ||||||
| debug(L"# %s on disappeared\n", buffer); | ||||||
| // The file found on PATH disappeared. Alias probably disabled by user while trying to run, let normal handling take over | ||||||
| RC_NO_SHEBANG; | ||||||
| } | ||||||
|
|
||||||
| // Other errors should cause us to break | ||||||
| winerror(0, L"Failed to find %s on PATH\n", filename); | ||||||
| return RC_BAD_VIRTUAL_PATH; | ||||||
| } | ||||||
|
|
||||||
|
||||||
| if (findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && | ||||||
| findData.dwReserved0 & IO_REPARSE_TAG_APPEXECLINK) { | ||||||
|
||||||
| const size_t bufSize = sizeof(AppExecLinkFile); | ||||||
| wchar_t appExecLinkBuf[sizeof(AppExecLinkFile)]; | ||||||
|
||||||
|
|
||||||
| HANDLE hReparsePoint = CreateFileW(buffer, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL); | ||||||
| if (!hReparsePoint) { | ||||||
| if (GetLastError() == ERROR_FILE_NOT_FOUND) { | ||||||
| debug(L"# %s on disappeared\n", buffer); | ||||||
| // The file found on PATH disappeared. Alias probably disabled by user while trying to run, let normal handling take over | ||||||
| RC_NO_SHEBANG; | ||||||
| } | ||||||
|
||||||
|
|
||||||
| // Other errors should cause us to break | ||||||
| winerror(0, L"Failed to find %s on PATH\n", filename); | ||||||
| return RC_BAD_VIRTUAL_PATH; | ||||||
| } | ||||||
|
|
||||||
| if (!DeviceIoControl(hReparsePoint, FSCTL_GET_REPARSE_POINT, NULL, 0, appExecLinkBuf, bufSize, NULL, NULL)) { | ||||||
| if (GetLastError() == ERROR_FILE_NOT_FOUND) { | ||||||
| debug(L"# %s on disappeared\n", buffer); | ||||||
| // The file found on PATH disappeared. Alias probably disabled by user while trying to run, let normal handling take over | ||||||
| RC_NO_SHEBANG; | ||||||
| } | ||||||
|
||||||
|
|
||||||
| // Other errors should cause us to break | ||||||
| winerror(0, L"Failed to find %s on PATH\n", filename); | ||||||
| return RC_BAD_VIRTUAL_PATH; | ||||||
| } | ||||||
|
|
||||||
| CloseHandle(hReparsePoint); | ||||||
|
|
||||||
| AppExecLinkFile* appExecLinkFilePtr; | ||||||
|
|
||||||
| appExecLinkFilePtr = (AppExecLinkFile*)&appExecLinkBuf; | ||||||
|
|
||||||
| wchar_t redirectorPackageId[] = L"Microsoft.DesktopAppInstaller"; | ||||||
|
||||||
| wchar_t redirectorPackageId[] = L"Microsoft.DesktopAppInstaller"; | |
| const wchar_t *redirectorPackageId = L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe"; |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A simple wcscmp ought to be fine here if you use the full package name. As far as I'm aware, the publisher ID has never changed and never will (it's always some kind of hash of "Microsoft").
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's start by refactoring all this out into another function
ensure_no_redirector_stubthat either returns0(okay) or the RC constant that should be returned from here.