@@ -572,6 +572,21 @@ findArgv0End(const wchar_t *buffer, int bufferLength)
572
572
*** COMMAND-LINE PARSING ***
573
573
\******************************************************************************/
574
574
575
+ // Adapted from https://stackoverflow.com/a/65583702
576
+ typedef struct AppExecLinkFile { // For tag IO_REPARSE_TAG_APPEXECLINK
577
+ DWORD reparseTag ;
578
+ WORD reparseDataLength ;
579
+ WORD reserved ;
580
+ ULONG version ;
581
+ wchar_t stringList [MAX_PATH * 4 ]; // Multistring (Consecutive UTF-16 strings each ending with a NUL)
582
+ /* There are normally 4 strings here. Ex:
583
+ Package ID: L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe"
584
+ Entry Point: L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe!PythonRedirector"
585
+ Executable: L"C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.17.106910_x64__8wekyb3d8bbwe\AppInstallerPythonRedirector.exe"
586
+ Applic. Type: L"0" // Integer as ASCII. "0" = Desktop bridge application; Else sandboxed UWP application
587
+ */
588
+ } AppExecLinkFile ;
589
+
575
590
576
591
int
577
592
parseCommandLine (SearchInfo * search )
@@ -763,6 +778,55 @@ _shebangStartsWith(const wchar_t *buffer, int bufferLength, const wchar_t *prefi
763
778
}
764
779
765
780
781
+ int
782
+ ensure_no_redirector_stub (wchar_t * filename , wchar_t * buffer )
783
+ {
784
+ // Make sure we didn't find a reparse point that will open the Microsoft Store
785
+ // If we did, pretend there was no shebang and let normal handling take over
786
+ WIN32_FIND_DATAW findData ;
787
+ HANDLE hFind = FindFirstFileW (buffer , & findData );
788
+ if (!hFind ) {
789
+ // Let normal handling take over
790
+ debug (L"# Did not find %s on PATH\n" , filename );
791
+ return RC_NO_SHEBANG ;
792
+ }
793
+
794
+ FindClose (hFind );
795
+
796
+ if (!(findData .dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
797
+ findData .dwReserved0 & IO_REPARSE_TAG_APPEXECLINK )) {
798
+ return 0 ;
799
+ }
800
+
801
+ HANDLE hReparsePoint = CreateFileW (buffer , 0 , FILE_SHARE_READ , NULL , OPEN_EXISTING , FILE_FLAG_OPEN_REPARSE_POINT , NULL );
802
+ if (!hReparsePoint ) {
803
+ // Let normal handling take over
804
+ debug (L"# Did not find %s on PATH\n" , filename );
805
+ return RC_NO_SHEBANG ;
806
+ }
807
+
808
+ AppExecLinkFile appExecLink ;
809
+
810
+ if (!DeviceIoControl (hReparsePoint , FSCTL_GET_REPARSE_POINT , NULL , 0 , & appExecLink , sizeof (appExecLink ), NULL , NULL )) {
811
+ // Let normal handling take over
812
+ debug (L"# Did not find %s on PATH\n" , filename );
813
+ CloseHandle (hReparsePoint );
814
+ return RC_NO_SHEBANG ;
815
+ }
816
+
817
+ CloseHandle (hReparsePoint );
818
+
819
+ const wchar_t * redirectorPackageId = L"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe" ;
820
+
821
+ if (0 == wcscmp (appExecLink .stringList , redirectorPackageId )) {
822
+ debug (L"# ignoring redirector that would launch store\n" );
823
+ return RC_NO_SHEBANG ;
824
+ }
825
+
826
+ return 0 ;
827
+ }
828
+
829
+
766
830
int
767
831
searchPath (SearchInfo * search , const wchar_t * shebang , int shebangLength )
768
832
{
@@ -826,6 +890,11 @@ searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength)
826
890
return RC_BAD_VIRTUAL_PATH ;
827
891
}
828
892
893
+ int result = ensure_no_redirector_stub (filename , buffer );
894
+ if (result ) {
895
+ return result ;
896
+ }
897
+
829
898
// Check that we aren't going to call ourselves again
830
899
// If we are, pretend there was no shebang and let normal handling take over
831
900
if (GetModuleFileNameW (NULL , filename , MAXLEN ) &&
0 commit comments