PHP: Hvordan bestemmer du, om en fil er en genvej på Windows-platforme?

Indlæg af Hanne Mølgaard Plasc

Problem



Ekskluderer en tredjepartsudvidelse, der ikke allerede er bundtet med PHP, Er der nogen metode til at bestemme, om en given fil på en Windows-maskine er en genvej/link? Den indbyggede funktion is\_link fungerer kun på * nix-platforme, så følgende løb på en Windows-maskine returnerer ikke, hvad der kan forventes:


$filePath = 'C:somefile.lnk'; // path to shortcut file
var\_dump(is\_file($filePath)); // returns true
var\_dump(is\_link($filePath)); // returns false


Dette ville medføre problemer, når du forsøger at arbejde med målfilen i genvejen, og afvikle betjeningen i selve genvejsfilen. De første fire bytes af en genvej synes at være typisk 4c 00 00 00. Men det virker ikke pålideligt, at denne åbningsbytesekvens er altid begrænset til genveje.


Sidespørgsmål: Hvordan udpakker du målbanen fra en genvejfil? (Bemærk: readlink() synes at returnere stien til genvejsfilen selv.


Rediger: for at gemme nogle problemer, er mime-typen af ​​genvejsfiler ifølge PHP ved hjælp af finfo eller mime\_content\_type 'application/octet-stream', som virkelig vandt ' t hjælp.

Bedste reference


Ligesom udfylde svar. Skrev det for mange år siden, ikke sikker på om det virker med de nuværende Windows-versioner.


For at tjekke de magiske bytes skal du blot bruge:


 $bin = file\_get\_contents("file.lnk", 2048);
 if (substr($bin, 0, 20) == "L0000000124020000000000300000000000000F") {


Og hvis du vil udtrække stien (r):


  function decode\_windows\_visual\_shortcut($bin) {

            # taken from "The Windows Shortcut File Format.pdf" V1.0 as
            # reverse-engineered by Jesse Hager <jessehager@iname.com> 

            if (!defined("WIN\_LNK\_F\_ITEMLIST")) {

                    define("WIN\_LNK\_F\_ITEMLIST", 1);
                    define("WIN\_LNK\_F\_FILE", 2);
                    define("WIN\_LNK\_F\_DESC", 4);
                    define("WIN\_LNK\_F\_RELATIVE", 8);
                    define("WIN\_LNK\_F\_WORKDIR", 16);
                    define("WIN\_LNK\_F\_CMDARGS", 32);
                    define("WIN\_LNK\_F\_ICON", 64);   
                    define("WIN\_LNK\_F2\_DIR", 16);   

                    function bread(&$bin, &$p, $bytes=4) {
                            $h = bin2hex( strrev($s = substr($bin, $p, $bytes)) );
                            $v = base\_convert($h, 16, 10);
                            $p += $bytes;
                            return($v);  
                    }
            }

            $res = array();
            $p = 0x14;
            $fl=$res["flags"] = bread($bin,$p);
            $res["t\_attr"] = bread($bin,$p);   
            $p = 0x4C;

            if ($fl & WIN\_LNK\_F\_ITEMLIST) {
                    #-- don't need this
                    $p += bread($bin,$p,2);
            }

            if ($fl & WIN\_LNK\_F\_FILE) {
                    #-- File Location Info
                    $p0 = $p;
                    $p = $p0 + 0x10;
                    $p\_path = $p0 + bread($bin,$p);
                    $p = $p0 + 0x18;
                    $p\_file = $p0 + bread($bin,$p);
                    $path = substr($bin, $p\_path, 704);
                    $path = substr($path, 0, strpos($path, "00"));
                    $file = substr($bin, $p\_file, 704);
                    $file = substr($file, 0, strpos($file, "00"));
                    $res["path"] = $path;
                    $res["file"] = $file;
            }

            return($res);
    }


http://code.google.com/p/8bits/downloads/detail?name=The\_Windows\_Shortcut\_File\_Format.pdf[9]