PHP: Как вы определяете, является ли файл ярлыком на платформах Windows? - PullRequest
1 голос
/ 11 апреля 2011

За исключением любого стороннего расширения, еще не связанного с PHP, есть ли способ определить, является ли данный файл на компьютере Windows ярлыком / ссылкой? Встроенная функция is_link работает только на * nix-платформах, поэтому следующее выполнение на машине с Windows не вернет ожидаемого:

$filePath = 'C:\somefile.lnk'; // path to shortcut file
var_dump(is_file($filePath)); // returns true
var_dump(is_link($filePath)); // returns false

Это может вызвать проблемы при попытке работать с целевым файлом ярлыка и запустить сам файл ярлыка. Первые четыре байта ярлыка обычно выглядят как 4c 00 00 00. Но не кажется надежным, что эта последовательность начальных байтов всегда ограничена ярлыками.

Дополнительный вопрос: как извлечь целевой путь из файла ярлыка? (Примечание: readlink(), кажется, возвращает путь к самому файлу ярлыка).

Редактировать: просто чтобы избежать проблем, файлы ярлыков mime-типа в соответствии с PHP, использующие finfo или mime_content_type, представляют собой «application / octet-stream», который действительно не поможет .

1 Ответ

1 голос
/ 11 апреля 2011

Так же, как заполнить ответ. Написал это несколько лет назад, не уверен, работает ли он с текущими версиями Windows.

Для проверки магических байтов просто используйте:

 $bin = file_get_contents("file.lnk", 2048);
 if (substr($bin, 0, 20) == "L\000\000\000\001\024\002\000\000\000\000\000\300\000\000\000\000\000\000F") {

А если вы хотите извлечь путь (и):

  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, "\000"));
                    $file = substr($bin, $p_file, 704);
                    $file = substr($file, 0, strpos($file, "\000"));
                    $res["path"] = $path;
                    $res["file"] = $file;
            }

            return($res);
    }

http://code.google.com/p/8bits/downloads/detail?name=The_Windows_Shortcut_File_Format.pdf

...