@@ -565,6 +565,21 @@ findArgv0End(const wchar_t *buffer, int bufferLength)
565565 *** COMMAND-LINE PARSING ***
566566\******************************************************************************/
567567
568+ // Adapted from https://stackoverflow.com/a/65583702
569+ typedef struct AppExecLinkFile { // For tag IO_REPARSE_TAG_APPEXECLINK
570+ DWORD reparseTag ;
571+ WORD reparseDataLength ;
572+ WORD reserved ;
573+ ULONG version ;
574+ wchar_t stringList [MAX_PATH * 4 ]; // Multistring (Consecutive UTF-16 strings each ending with a NUL)
575+ /* There are normally 4 strings here. Ex:
576+ Package ID: L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe"
577+ Entry Point: L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe!PythonRedirector"
578+ Executable: L"C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.17.106910_x64__8wekyb3d8bbwe\AppInstallerPythonRedirector.exe"
579+ Applic. Type: L"0" // Integer as ASCII. "0" = Desktop bridge application; Else sandboxed UWP application
580+ */
581+ } AppExecLinkFile ;
582+
568583
569584int
570585parseCommandLine (SearchInfo * search )
@@ -756,6 +771,55 @@ _shebangStartsWith(const wchar_t *buffer, int bufferLength, const wchar_t *prefi
756771}
757772
758773
774+ int
775+ ensure_no_redirector_stub (wchar_t * filename , wchar_t * buffer )
776+ {
777+ // Make sure we didn't find a reparse point that will open the Microsoft Store
778+ // If we did, pretend there was no shebang and let normal handling take over
779+ WIN32_FIND_DATAW findData ;
780+ HANDLE hFind = FindFirstFileW (buffer , & findData );
781+ if (!hFind ) {
782+ // Let normal handling take over
783+ debug (L"# Did not find %s on PATH\n" , filename );
784+ return RC_NO_SHEBANG ;
785+ }
786+
787+ FindClose (hFind );
788+
789+ if (!(findData .dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
790+ findData .dwReserved0 & IO_REPARSE_TAG_APPEXECLINK )) {
791+ return 0 ;
792+ }
793+
794+ HANDLE hReparsePoint = CreateFileW (buffer , 0 , FILE_SHARE_READ , NULL , OPEN_EXISTING , FILE_FLAG_OPEN_REPARSE_POINT , NULL );
795+ if (!hReparsePoint ) {
796+ // Let normal handling take over
797+ debug (L"# Did not find %s on PATH\n" , filename );
798+ return RC_NO_SHEBANG ;
799+ }
800+
801+ AppExecLinkFile appExecLink ;
802+
803+ if (!DeviceIoControl (hReparsePoint , FSCTL_GET_REPARSE_POINT , NULL , 0 , & appExecLink , sizeof (appExecLink ), NULL , NULL )) {
804+ // Let normal handling take over
805+ debug (L"# Did not find %s on PATH\n" , filename );
806+ CloseHandle (hReparsePoint );
807+ return RC_NO_SHEBANG ;
808+ }
809+
810+ CloseHandle (hReparsePoint );
811+
812+ const wchar_t * redirectorPackageId = L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe" ;
813+
814+ if (0 == wcscmp (appExecLink .stringList , redirectorPackageId )) {
815+ debug (L"# ignoring redirector that would launch store\n" );
816+ return RC_NO_SHEBANG ;
817+ }
818+
819+ return 0 ;
820+ }
821+
822+
759823int
760824searchPath (SearchInfo * search , const wchar_t * shebang , int shebangLength )
761825{
@@ -817,6 +881,11 @@ searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength)
817881 return RC_BAD_VIRTUAL_PATH ;
818882 }
819883
884+ int result = ensure_no_redirector_stub (filename , buffer );
885+ if (result ) {
886+ return result ;
887+ }
888+
820889 // Check that we aren't going to call ourselves again
821890 // If we are, pretend there was no shebang and let normal handling take over
822891 if (GetModuleFileNameW (NULL , filename , MAXLEN ) &&
0 commit comments