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