@@ -565,6 +565,21 @@ findArgv0End(const wchar_t *buffer, int bufferLength)
565
565
*** COMMAND-LINE PARSING ***
566
566
\******************************************************************************/
567
567
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
+
568
583
569
584
int
570
585
parseCommandLine (SearchInfo * search )
@@ -756,6 +771,55 @@ _shebangStartsWith(const wchar_t *buffer, int bufferLength, const wchar_t *prefi
756
771
}
757
772
758
773
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
+
759
823
int
760
824
searchPath (SearchInfo * search , const wchar_t * shebang , int shebangLength )
761
825
{
@@ -817,6 +881,11 @@ searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength)
817
881
return RC_BAD_VIRTUAL_PATH ;
818
882
}
819
883
884
+ int result = ensure_no_redirector_stub (filename , buffer );
885
+ if (result ) {
886
+ return result ;
887
+ }
888
+
820
889
// Check that we aren't going to call ourselves again
821
890
// If we are, pretend there was no shebang and let normal handling take over
822
891
if (GetModuleFileNameW (NULL , filename , MAXLEN ) &&
0 commit comments