Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.06.2011, 20:03   #1
assch
Пользователь
 
Регистрация: 13.09.2010
Сообщений: 65
По умолчанию Как програмно узнать имя файла на который ссылается ярлык

В интернете нашёл один исходник (наверное на С или Делфи)
В качестве примера перечисленных действий ниже приведен текст функции,
которая принимает в качестве параметра имя ярлыка и выводит на консоль
полное имя файла, на который этот ярлык ссылается.
Описание алгоритма:
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-серверов).


Код:
void print_shortcut_target(LPCTSTR pszShortcut)
{
   IPersistFile* ppf;
   IShellLink* pshl;
   WIN32_FIND_DATA wfd;

   // инициализируем COM-библиотеку
   ::CoInitialize(NULL);

   // создаем COM-объект и получаем указатель на IPersistFile
   ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
      IID_IPersistFile, reinterpret_cast<void**>(&ppf));

   // загружаем ярлык
#if defined(_UNICODE)
   ppf->Load(pszShortcut, STGM_READ);
#else
   LPWSTR pwszTemp = new WCHAR[_MAX_PATH];
   mbstowcs(pwszTemp, pszShortcut, _MAX_PATH);
   ppf->Load(pwszTemp, STGM_READ);
   delete[] pwszTemp;
#endif

   // получаем указатель на IShellLink
   ppf->QueryInterface(IID_IShellLink, reinterpret_cast<void**>(&pshl));

   // ищем объект, на который ссылается ярлык
   pshl->Resolve(NULL, SLR_ANY_MATCH | SLR_NO_UI);

   // получаем имя объекта и выводим его на консоль
   LPTSTR pszTarget = new TCHAR[_MAX_PATH];
   pshl->GetPath(pszTarget, _MAX_PATH, &wfd, 0);
   _putts(pszTarget);
   delete[] pszTarget;

   // убираем за собой
   pshl->Release();
   ppf->Release();

   // завершаем работу с COM-библиотекой
   ::CoFreeUnusedLibraries();
   ::CoUninitialize();
Попробывал реализовать это на асемблере.Но увы не получается.
Нашёл файл shlobj.inc где (вроде бы) указаны эти константы и макрос "coinvoke" (хотя могу и ошибатся
и это из другой оперы) Правда с методом "Load" я не разобрался и реализовал его на бум лазаря.
Скорее всего ошибка в нём .Может кто в курсе что здесь не так, а то я по части COM не силён.
Или на асемблере есть другие методы реализации этого действия?

Код:
.386
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\ole32.inc

include shlobj.inc

includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\ole32.lib


.data
CLSID_ShellLink	   GUID	 <0021401H, 0000H, 0000H, \
                         <0C0H, 00H, 00H, 00H, 00H, 00H, 00H, 046H>>
IID_IShellLink	   GUID	 <00214EEH, 0000H, 0000H, \
                         <0C0H, 00H, 00H, 00H, 00H, 00H, 00H, 046H>>
IID_IPersistFile   GUID	 <000010BH, 0000H, 0000H, \
		                 <0C0H, 00H, 00H, 00H, 00H, 00H, 00H, 046H>>

buffer   db "C:\Documents and Settings\Хозяин\Рабочий стол\Google Chrome.lnk",0
box      db " ",0

ppf	     dd	 0
psl	     dd	 0
Char     dd      0
tBuf     dd 256 dup (?)
Unicod   dd 256 dup (?)
pFin     WIN32_FIND_DATA <0>

.code
start:
invoke CoInitialize,0
invoke CoCreateInstance, offset CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, \
                         offset IID_IPersistFile, offset ppf
invoke MultiByteToWideChar,0,0,addr buffer,-1,addr Unicod,addr Char
coinvoke ppf, IPersistFile, Load, offset Unicod, STGM_READ
coinvoke ppf, IShellLink, QueryInterface, offset IID_IShellLink, offset psl
invoke GetPath,addr tBuf,1024,addr pFin,0
invoke MessageBox,0,addr tBuf,addr box,20h
invoke CoUninitialize
invoke ExitProcess,0

end start
Вложения
Тип файла: rar Com.rar (3.0 Кб, 13 просмотров)
assch вне форума Ответить с цитированием
Старый 04.06.2011, 03:28   #2
litrovith
Пользователь
 
Регистрация: 15.07.2008
Сообщений: 28
По умолчанию

assch, причём здесь gdi32 ???. Вместо
Код:
invoke GetPath,addr tBuf,1024,addr pFin,0
нужно
Код:
coinvoke psl, IShellLink, GetPath,addr tBuf,256,addr pFin,0
litrovith вне форума Ответить с цитированием
Старый 04.06.2011, 04:35   #3
assch
Пользователь
 
Регистрация: 13.09.2010
Сообщений: 65
По умолчанию

litrovith Большое спасибо
Век живи век учись
assch вне форума Ответить с цитированием
Старый 05.06.2011, 23:22   #4
assch
Пользователь
 
Регистрация: 13.09.2010
Сообщений: 65
По умолчанию

Попробывал реализовать идею обойтись без ком интерфейсов, и написал функцию которая вытаскивает путь из линк файла. Алгоритм может быть не совсем правильный и в плотную я её не тестировал но вроде бы работает (если у кого не сработает то значит в алгоритме ошибка).Если кому интересно то код представляю (может кто нибудь что нибудь подправит)
Код:
.386
.model flat, stdcall
option casemap :none

PathLnk   proto :dword

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

.data
box     db ' ',0
fName   db 'C:\Documents and Settings\Хозяин\Рабочий стол\Google Chrome.lnk',0

.code
start:

invoke MessageBox,0,addr fName,addr box,20h
invoke PathLnk,addr fName
invoke MessageBox,0,addr fName,addr box,20h
invoke  ExitProcess,0

PathLnk proc Fbuf
local Fx [256]:dword
pushad
invoke  CreateFile,Fbuf,GENERIC_READ,0,0,3,0,0
mov edi,eax
invoke  GetFileSize,eax,0
mov esi,eax
invoke  GetProcessHeap
mov ebx,eax
invoke  HeapAlloc,ebx,0,esi
mov edx,eax
push eax
invoke  ReadFile,edi,eax,esi,Fx,0
invoke  CloseHandle,edi
pop eax
push eax
invoke  HeapFree,ebx,0,eax
pop eax

M1:
.if byte ptr [eax] == 010h

.if byte ptr [eax+1] == 00h
.else
jmp M2
.endif

.if byte ptr [eax+2] == 00h
.else
jmp M2
.endif

.if byte ptr [eax+3] == 00h
.else
jmp M2
.endif

.if byte ptr [eax+4] == 00h
.else
jmp M2
.endif

.if byte ptr [eax+6] == 03ah
.else
jmp M2
.endif

.if byte ptr [eax+7] == 05ch
jmp M3
.else
jmp M2
.endif

.endif

M2:
.if esi <= 0
jmp M0
.else
add eax,1
dec esi
jmp M1
.endif

M3:
add eax,5
xor ecx,ecx

M4:
.if byte ptr [eax] == 00h
.else

.if esi <= 0
jmp M0
.else
dec esi
inc ecx
add eax,1
jmp M4
.endif

.endif

mov  byte ptr [eax],0
sub eax,ecx
invoke lstrcpy,Fbuf,eax

M0:
popad
ret
PathLnk endp

end start
assch вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как програмно отключить ярлык "Мой компьютер"? bananasus Общие вопросы Delphi 2 15.04.2011 22:48
как узнать имя загружаемого файла? pufystyj PHP 3 06.03.2011 12:41
Узнать путь и имя файла который находится под курсором? Kostia Win Api 4 20.11.2009 12:16
Как програмно узнать размер файла? Дима я Общие вопросы C/C++ 3 09.10.2009 21:37
Как узнать имя файла??? Shurik Hacker Работа с сетью в Delphi 3 20.11.2007 17:06