Как програмно узнать имя файла на который ссылается ярлык

Тема в разделе "WASM.BEGINNERS", создана пользователем assch, 3 июн 2011.

  1. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    В интернете нашёл один исходник (наверное на С или Делфи)
    В качестве примера перечисленных действий ниже приведен текст функции,
    которая принимает в качестве параметра имя ярлыка и выводит на консоль
    полное имя файла, на который этот ярлык ссылается.
    Описание алгоритма:
    1 - Инициализировать, если это еще не было сделано,
    COM-библиотеку вызовом функции CoInitialize (или CoInitializeEx).
    2 - Создать с помощью функции CoCreateInstance экземпляр COM-класса ShellLink
    и получить указатель на его интерфейс IPersistFile.
    3 - Загрузить вызовом метода Load требуемый ярлык, указав желаемый режим доступа
    к его свойствам — чтение (STGM_READ), запись (STGM_WRITE) или чтение/запись (STGM_READWRITE).
    4 - Получить указатель на интерфейс IShellLink „нашего“ COM-объекта, вызвав метод QueryInterface
    через полученный ранее указатель на IPersistFile.
    5 - Если существует вероятность того, что объект, на который ссылается ярлык,
    был перемещен — вызвать через полученный указатель метод Resolve для поиска объекта.
    6 - Получить и (или) назначить требуемые свойства ярлыка, вызвав через указатель на IShellLink
    его методы GetXxxx и (или) SetXxxx соответственно.
    7 - При необходимости — сохранить сделанные изменения с помощью метода Save интерфейса IPersistFile.
    8 - „Отпустить“ полученные интерфейсы, вызвав для каждого из них метод Release.
    9 - Завершить, если это необходимо, работу с COM-библиотекой вызовом функции CoUninitialize
    (перед этим можно вызвать функцию CoFreeUnusedLibraries для выгрузки из памяти
    всех неиспользуемых более COM-серверов).
    Попробывал реализовать это на асемблере.Но увы не получается.
    Нашёл файл shlobj.inc где (вроде бы) указаны эти константы и макрос "coinvoke" (хотя могу и ошибатся
    и это из другой оперы) Правда с методом "Load" я не разобрался и реализовал его на бум лазаря.
    Скорее всего ошибка в нём .Может кто в курсе что здесь не так, а то я по части COM не силён.
    Или на асемблере есть другие методы реализации этого действия?
     
  2. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    Я брат тоже в com не силен, но прочитав название темы и немного подумав(совсем чуть-чуть) я решил, что ярлык это обычный фаил с расширением .lnk. А раз это фаил значит его можно просмотреть в шестнадцатиричном редакторе, что я и сделал. А когда я это сделал то я там увидел, что перед полным именем файла стоят магические буковки pA+7 байтов. Я подумал случайность и как безумный начал открывать все ярлыки, что есть на моем компе. И как всегда понял, что в нашем мире случайностей не бывает, везде эти буквы+7 байт. Думаю теперь тебе не будет сложно реализовать свой замысел без всяких com. Ну а если не хватит тяму, то проси помощи. А я за сим откланиваюсь и иду спать. Всем доброй ночи!
     
  3. litrovith

    litrovith Member

    Публикаций:
    0
    Регистрация:
    20 июн 2007
    Сообщения:
    509
    assch, и ещё раз перечитиайте п.6 вашего алгоритма, а то получается 'смотрю в книгу вижу фигу'.
     
  4. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    litrovith Спасибо за подсказку

    Вместо

    Код (Text):
    1. invoke GetPath,addr tBuf,1024,addr pFin,0
    нужно

    Код (Text):
    1. coinvoke psl, IShellLink, GetPath,addr tBuf,256,addr pFin,0
    Код выше исправил
     
  5. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    Я вчера счень сильно затупил написав #2. Сегодня решил начать писать прогу выводящую полное имя файла не используя com-интерфейсы, и понял, что я очень сильно ошибался. Никаких сигнатур там нет! Но как долго я не гуглил, я так и не смог найти описание структуры .lnk, кроме её описание Jesse Hager-ом. Я так и не смог разобраться от куда берется смещение полного имени, наверное из-за моего плохого знания английского, но как мне показалось, его описание не полностью соответствует действительности. Так что реализация через com-интерфейс самое простое и наверное правильное решение. А может есть у кого описание структуры данного формата файла?
     
  6. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Решение с ком интерфейсом уже найдено (помог разобратся litrovith)
    Но твоя задумка насчёт того что бы вытащить путь к файлу из самого линка мне пондравилась
    и я думаю (ради интереса) это можно реализовать
     
  7. OldDino

    OldDino New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    44
    Неужели Google перестал работать? Я в три секунды нашел информацию от Microsoft - Shell Link (.LNK) Binary File Format. :) http://pdfcast.org/pdf/ms-shllink-pdf
     
  8. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Идея обойтись без ком интерфейсов мне пондравилась, и я написал функцию которая
    вытаскивает путь из линк файла. Алгоритм может быть не совсем правильный и в плотную я
    её не тестировал но вроде бы работает (если у кого не сработает то значит в алгоритме
    ошибка).Если кому интересно то код представляю (может кто нибудь что нибудь подправит)

     
  9. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    OldDino Вы молодец, спасибо! Если у меня еще раз не получится нагуглить в течении суток, то разрешите обратиться к Вам за помощью, думаю Вы сможете уделить мне три секунды Вашего драгоценного времени :)
    assch
    Ваш код не пробовал, но и так вижу что чушь. Сегодня я сходил по ссылке OldDino
    и накидал такой код на fasm:
    Код (Text):
    1. format PE GUI 4.0
    2. include 'F:\fasm\INCLUDE\WIN32AX.INC'
    3. MAXSIZE equ 260
    4. ofn   OPENFILENAME <>
    5. .data
    6. FilterString db "Ярлык",0,"*.lnk",0,0
    7. buffer db MAXSIZE dup(0)
    8. hFile        dd ?
    9. dlina        dd ?
    10. filebuf      db ?
    11. .code
    12. start:
    13.            mov  [ofn.lStructSize],sizeof.OPENFILENAME
    14.            mov  [ofn.hwndOwner], NULL
    15.            mov  [ofn.lpstrFilter],FilterString
    16.            mov  [ofn.lpstrFile],buffer
    17.            mov  [ofn.nMaxFile],MAXSIZE
    18.    invoke GetOpenFileName, addr ofn
    19.    invoke CreateFile,addr buffer,GENERIC_READ or GENERIC_WRITE,\
    20.            FILE_SHARE_READ or FILE_SHARE_WRITE,\
    21.            NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
    22.            mov [hFile],eax
    23.    invoke GetFileSize,[hFile],NULL
    24.            mov [dlina],eax
    25.    invoke ReadFile,[hFile],addr filebuf,[dlina],dlina,NULL
    26.    invoke CloseHandle,[hFile]
    27.             mov eax,filebuf+6Ah
    28.             mov bx,word[filebuf+4Ch]
    29.             add ax,bx
    30.             mov bx,[eax]
    31.             add ax,bx
    32.    invoke  MessageBox,HWND_DESKTOP,eax,'Ярлык ссылается на:',MB_OK
    33.    invoke ExitProcess,0
    34. .end start
    Пробовал на разных осях под админом, все прекрасно работает. Скомпилированый exe, для тех кому лень, прилагаю
     
  10. OldDino

    OldDino New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    44
    Благодарю за добрые слова. Если смогу, то помогу.
     
  11. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    Вчера я написал
    Сегодня решил попробовать на 64 разрядной семерке свой код. Запускаю, открываю первый попавшийся ярлык, моя прога показывает полный путь и сам запускаемый .exe. Я как ребенок радуюсь и начинаю тыкать на разные ярлыки и тут тыкнул в корелдрафт и вместо путь мусор. У меня аж глаз задергался. Тыкаю в ярлык скайпа, ситуация повтаряется. Я минут пять нахожусь в ступоре, затем правой кнопкой мыши захожу в свойства ярлыка скайпа и вижу, что там путь и exe так же не видны. Вечером, если будет время посмотрю в чем у них там хитрость. А может кто так знает тайну этих хитрых ярлыков? И зачем оно вообще у них так сделано?
     
  12. OldDino

    OldDino New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    44
    А вот если бы выложить сюда эти файлы, все бы посмотрели...
     
  13. amdf

    amdf New Member

    Публикаций:
    0
    Регистрация:
    1 фев 2011
    Сообщения:
    39
    Некоторые ярлыки ссылаются на файл не по его пути, а, похоже, через NTFS Object ID. В винде есть служба link tracking, и такой ярлык всегда будет указывать на файл, если даже перемещать его в пределах диска.
     
  14. amdf

    amdf New Member

    Публикаций:
    0
    Регистрация:
    1 фев 2011
    Сообщения:
    39
    Чтобы узнать имя файла нужно
    1) Вытащить NTFS Object ID. Тип - GUID
    2) Открыть файл через OpenFileById(). Эта функция в kernel32.dll начиная с Vista. Чтобы работало в предыдущих версиях Windows нужно подключать в проект fileextd.lib от Microsoft.
    3) С помощью GetFileInformationByHandleEx() получить имя файла.
     
  15. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    OldDino помогите пожалуйста найти описание структуры формата ".ani " (подвижного указателя)
     
  16. litrovith

    litrovith Member

    Публикаций:
    0
    Регистрация:
    20 июн 2007
    Сообщения:
    509
    http://wasm.ru/forum/viewtopic.php?id=11378
     
  17. OldDino

    OldDino New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    44
    А вот этого - http://en.wikipedia.org/wiki/Graphics_Interchange_Format#Animated_GIF - не хватит? Вместе с этим - www.dca.fee.unicamp.br/~martino/disciplinas/ea978/spec-gif89a.pdf ?

    А вдобавок - http://www.botos.com/anigif.html . И еще - http://www.etsimo.uniovi.es/gifanim/gifabout.htm#net-extension

    Но, думаю, стоило бы сначала ознакомиться с содержанием ссылки, которую привел litrovith.
     
  18. OldDino

    OldDino New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    44
    А вот этого - http://en.wikipedia.org/wiki/Graphics_Interchange_Format#Animated_GIF - не хватит? Вместе с этим - www.dca.fee.unicamp.br/~martino/disciplinas/ea978/spec-gif89a.pdf ?

    А вдобавок - http://www.botos.com/anigif.html . И еще - http://www.etsimo.uniovi.es/gifanim/gifabout.htm#net-extension

    Но, думаю, стоило бы сначала ознакомиться с содержанием ссылки, которую привел litrovith.
     
  19. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    OldDino Все ваши ссылки к сожелению про " GIF " формат, а мне нужен формат " ANI "
    Он тоже из разряда анимации но по структуре мне кажется другой
    Например в окне программы легко можно отобразить файл формата " ICO " (иконка)
    Также если вместо иконки выбрать файл формата " ANI " то анимация будет налицо
    А вот с " GIF " форматом (имеется ввиду анимационный гиф) такой фокус не пройдёт
    Чтобы его запустить в окне программы придётся применить совсем другую многоходовую комбинацию функций
    Насчёт поиска, я тоже пытаюсь гуглить но к сожелению пока не удаётся найти то что нужно.
    Ну ладно будем искать.
     
  20. OldDino

    OldDino New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    44
    http://en.wikipedia.org/wiki/ANI_(file_format)

    http://msdn.microsoft.com/en-us/library/ee415713.aspx

    Этот?