Написание своих плагинов

Задавайте вопросы, пишите сюда все что не касается других тем.

Moderators: Korney San, Qwertiy, marcipan, igelizm

Forum rules
Справочная система менеджера закачек Download Master:
http://westbyte.com/dm/help/
Post Reply
Verholom
Posts: 4
Joined: 18 Jul 2013, 11:11 Thu

Написание своих плагинов

Post by Verholom »

Я наверное чего-то не понимаю... Пытаюсь написать свой плагин к ИДА... Софтина не хочет запускать его, пишет, что для работы плагина нужна более новая версия ИДА. Я так понимаю, что заковыка в возврате нужжной версии при загрузке плагина. Я переписал на дельфийский пример, взятый с сайта на FreeBASIC (у нас в конторе в почете ассемблер, поэтому FreeBASIC юзаем в качестве транслятора) . Бесит другое: почему плагин, написанный на ВБ6, работает, а мой нет... Вот весь код:

Code: Select all

#Pragma Once
#Define UNICODE

#Include "windows.bi"

#Ifndef BSTR
Type BSTR As WString Ptr
#EndIf

#Ifdef Allocate
	#Undef Allocate
#EndIf
#Define Allocate(cx) GlobalAlloc(GMEM_FIXED+GMEM_ZEROINIT,cx)

#Ifdef DeAllocate
	#Undef DeAllocate
#EndIf
#Define DeAllocate(pv) GlobalFree(pv)

#Define DM_OK 0

'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Type OLE_OBJECT
	As Any Ptr		pVtbl
	As UInteger	dwRefCount
End Type

Type OLE_IUnknown
	As Function  (ByVal ppItf As Any Ptr Ptr,ByVal IID As Any Ptr, ByVal pp As Any Ptr Ptr) As UInteger	QueryInterface
	As Function  (ByVal ppItf As Any Ptr Ptr) As UInteger												AddRef
	As Function  (ByVal ppItf As Any Ptr Ptr) As UInteger												Release
End Type



'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Type IDMInterface extends OLE_IUnknown
	As Function ( ByVal Action As BSTR, ByVal Parameters As BSTR,ByVal pInterfaceHost As IDMInterface Ptr) As UInteger DoAction
End Type

Type IDMPluginObject extends OLE_OBJECT
	As IDMInterface Ptr	DMHost
End Type

Type IDMPluginInterface extends OLE_IUnknown
	As Function (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger							getID
	As Function (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger 							GetName
	As Function (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger 							GetVersion
	As Function (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr,ByVal Lang As BSTR) As UInteger 		GetDescription
	As Function (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger 							GetEmail
	As Function (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger 							GetHomepage
	As Function (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger 							GetCopyright
	As Function (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger 							GetMinAppVersion
	As Function (ByVal pThis As IDMPluginObject Ptr,ByVal DMHost As IDMInterface Ptr) As UInteger 			PluginInit
	As Function (ByVal pThis As IDMPluginObject Ptr, ByVal Params As BSTR) As UInteger 						PluginConfigure
	As Function (ByVal pThis As IDMPluginObject Ptr) As UInteger												BeforeUnload
	As Function (ByVal Result As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr, ByVal EventType As BSTR, ByVal EventData As BSTR) As UInteger EventRaised
End Type

'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Declare Function IDMPluginInterface_QueryInterface (ByVal pItf As IDMPluginObject Ptr,ByVal IID As Any Ptr, ByVal pp As Any Ptr Ptr) As UInteger 
Declare Function IDMPluginInterface_AddRef (ByVal pItf As IDMPluginObject Ptr) As UInteger
Declare Function IDMPluginInterface_Release (ByVal pItf As IDMPluginObject Ptr) As UInteger
Declare Function IDMPluginInterface_getId  (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
Declare Function IDMPluginInterface_GetName (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
Declare Function IDMPluginInterface_GetVersion  (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
Declare Function IDMPluginInterface_GetDescription (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr,ByVal Lang As BSTR) As UInteger
Declare Function IDMPluginInterface_GetEmail (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
Declare Function IDMPluginInterface_GetHomepage (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
Declare Function IDMPluginInterface_GetCopyright (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
Declare Function IDMPluginInterface_GetMinAppVersion (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
Declare Function IDMPluginInterface_PluginInit (ByVal pThis As IDMPluginObject Ptr,ByVal DMHost As IDMInterface Ptr) As UInteger
Declare Function IDMPluginInterface_PluginConfigure (ByVal pThis As IDMPluginObject Ptr, ByVal Params As BSTR) As UInteger
Declare Function IDMPluginInterface_BeforeUnload (ByVal pThis As IDMPluginObject Ptr) As UInteger
Declare Function IDMPluginInterface_EventRaised (ByVal Result As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr, ByVal EventType As BSTR, ByVal EventData As BSTR) As UInteger

'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Extern "WINDOWS-MS"
Declare Function RegisterPlugIn(ByVal ppPluginObject As IDMPluginObject Ptr Ptr) As UInteger									'Export
End Extern
Declare Function DllMain(ByVal hInstance As Any Ptr, ByVal dwReason As UInteger, ByVal pvReserved As Any Ptr) As UInteger	'DllEntryPoint

'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function IDMPluginObject_New(size As UInteger) As Any Ptr
	Dim As IDMPluginObject Ptr objRet
	Dim As IDMPluginInterface Ptr pitf
	
	objRet=Cast(IDMPluginObject Ptr,Allocate(SizeOf(IDMPluginObject)))
	objRet->pVtbl=Cast(Any Ptr,Allocate(SizeOf(IDMPluginInterface)))
	
	objRet->dwRefCount =				    1
	pitf=								    objRet->pVtbl
	pitf->QueryInterface=				@IDMPluginInterface_QueryInterface
	pitf->AddRef=						@IDMPluginInterface_AddRef
	pitf->Release=						@IDMPluginInterface_Release
	pitf->getId=						@IDMPluginInterface_getId
	pitf->GetName=					@IDMPluginInterface_GetName
	pitf->GetVersion=					@IDMPluginInterface_GetVersion
	pitf->GetDescription=				@IDMPluginInterface_GetDescription
	pitf->GetEmail=					@IDMPluginInterface_GetEmail
	pitf->GetHomepage=				@IDMPluginInterface_GetHomepage
	pitf->GetCopyright=				@IDMPluginInterface_GetCopyright
	pitf->GetMinAppVersion=			@IDMPluginInterface_GetMinAppVersion
	pitf->PluginInit=					@IDMPluginInterface_PluginInit
	pitf->PluginConfigure=				@IDMPluginInterface_PluginConfigure
	pitf->BeforeUnload=				@IDMPluginInterface_BeforeUnload
	pitf->EventRaised=					@IDMPluginInterface_EventRaised
	
	Return Cast(Any Ptr,objRet)
End Function

Function IDMPluginObject_Delete(ByVal objRet As  IDMPluginObject Ptr) As UInteger
	If objRet = NULL Then GoTo IDMPluginObject_Delete_Exit
	
	If objRet->pVtbl Then _
		DeAllocate(Cast(Any Ptr,objRet->pVtbl))
	DeAllocate(objRet)
	
IDMPluginObject_Delete_Exit:
	Return 0UL
End Function


'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Function IDMPluginInterface_QueryInterface (ByVal pItf As IDMPluginObject Ptr,ByVal IID As Any Ptr, ByVal pp As Any Ptr Ptr) As UInteger 
 	pItf->dwRefCount+=1
 	pp[0]=Cast(Any Ptr,pItf)
 	
 	Return DM_OK
 End Function
 
Function IDMPluginInterface_AddRef (ByVal pItf As IDMPluginObject Ptr) As UInteger
 	pItf->dwRefCount += 1
 	Return pitf->dwRefCount
End Function
 
Function IDMPluginInterface_Release (ByVal pItf As IDMPluginObject Ptr) As UInteger
 	pItf->dwRefCount -= 1
 	Return pitf->dwRefCount
End Function
 

'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
'#Define def_ID					Cast(Any Ptr, @WStr("{974C86E7-44AD-4C6B-B90C-67A563DEA75}"))
#Define def_ID					Cast(Any Ptr, @WStr("VERHOLOM"))
#Define def_Name				@WStr("Íàçâàíèå íàøåãî ïëàãèíà")
#Define def_Version			@WStr("0.1.1.1")
#Define def_Description		@WStr("Ñàìûé õîðîøèé ïëàãèí")
#Define def_Email				@WStr("assembler_c@ukr.net")
#Define def_Homepage		@WStr("verholom.narod.ru")
#Define def_Copyright			@WStr("(c) Vitaly Golovanoff aka VerhoLom")
#Define def_MinAppVersion	@WStr("5.0.2")

 Function IDMPluginInterface_getId  (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
 	v[0]=def_ID
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_GetName (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
 	v[0]=def_Name
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_GetVersion  (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
 	v[0]=def_Version
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_GetDescription (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr,ByVal Lang As BSTR) As UInteger
 	v[0]=def_Description
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_GetEmail (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
 	v[0]=def_Email
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_GetHomepage (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
 	v[0]=def_Homepage
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_GetCopyright (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
 	v[0]=def_Copyright
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_GetMinAppVersion (ByVal v As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr) As UInteger
 	v[0]=def_MinAppVersion
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_PluginInit (ByVal pThis As IDMPluginObject Ptr,ByVal DMHost As IDMInterface Ptr) As UInteger
 	pThis->DMHost = DMHost
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_PluginConfigure (ByVal pThis As IDMPluginObject Ptr, ByVal Params As BSTR) As UInteger
 	MessageBox(GetActiveWindow(),@WStr("IDMPluginInterface_PluginConfigure "),Params,MB_APPLMODAL)
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_BeforeUnload (ByVal pThis As IDMPluginObject Ptr) As UInteger
 	Return DM_OK
 End Function
 
 Function IDMPluginInterface_EventRaised (ByVal Result As BSTR Ptr, ByVal pThis As IDMPluginObject Ptr, ByVal EventType As BSTR, ByVal EventData As BSTR) As UInteger
 	MessageBox(GetActiveWindow(),@WStr("IDMPluginInterface_EventRaised"),EventData,MB_APPLMODAL)
 	Return DM_OK
 End Function


Extern "WINDOWS-MS"

Function RegisterPlugIn(ByVal ppPluginObject As IDMPluginObject Ptr Ptr) As UInteger
	ppPluginObject[0] = IDMPluginObject_New(SizeOf(IDMPluginObject))
	Return DM_OK
End Function

End Extern

Function DllMain(ByVal hInstance As Any Ptr, ByVal dwReason As UInteger, ByVal pvReserved As Any Ptr) As UInteger
	Select Case dwReason
		
		Case DLL_PROCESS_ATTACH:	GoTo DLL_MAIN_DLL_PROCESS_ATTACH
		Case DLL_PROCESS_DETACH:	GoTo DLL_MAIN_DLL_PROCESS_DETACH
		Case Else:						GoTo DLL_MAIN_EXIT
		
	End Select
	
DLL_MAIN_DLL_PROCESS_ATTACH:
	GoTo DLL_MAIN_EXIT
	
DLL_MAIN_DLL_PROCESS_DETACH:
	
DLL_MAIN_EXIT:
	Return DM_OK + 1
	
End Function
Собирается все это дело в МАСМ32... Ну да, извращенно, но мне нравится... В чем прикол, почему плагин не подключается и в списке плагинов я не вижу его имя?
Image
Qwertiy
Гуру
Posts: 764
Joined: 07 Jan 2011, 1:45 Fri
Location: Россия

Post by Qwertiy »

Verholom wrote:Пытаюсь написать свой плагин к ИДА...
К IDA или к DM?
Verholom wrote:Бесит другое: почему плагин, написанный на ВБ6, работает, а мой нет...
Что-то мне подсказывает, что это неверно:

Code: Select all

#Define def_Version			@WStr("0.1.1.1")
И да, строки должны быть в юникоде.

PS: А плагин случайно не для этого http://downloadmaster.net/forum/viewtopi ... =1&t=27186?
Пожалуйста, посмотрите: Использование ссылок в тексте сообщений
Поддерживаются браузеры: Опера 12, Хром, Firefox.
Обновлено: 21.09.2012. Надо бы ещё подправить и обновить...
Ссылки на файлы обновлены: 24.05.2013.
Verholom
Posts: 4
Joined: 18 Jul 2013, 11:11 Thu

Re: Написание своих плагинов

Post by Verholom »

Тут вайд-строки, 2-байтовые... Большой разницы между ИДой и ДМ не вижу, ибо скачал оба примера с сайта, и оба работают одинаково :mrgreen: . Я же говорю, подсунул чкачанный с форумов vbstreets.ru плагин, написанный на VB6 еще для ДМ, он работает.... Версия, на которую Вы меня ткнули - это версия моего плагина, но есть еще функция GetMinAppVersion, о которую, видимо и спотыкается ДМ... Хотя ВБшный плагин с такими же возвращаемыми данными отрабатывает нормально... Загадка, однако... :cry:

Зачем надо: учет чего качаем в сети в оффисе... Все пользуются тлько хромом и доступ к настройкам закрыт...
Qwertiy
Гуру
Posts: 764
Joined: 07 Jan 2011, 1:45 Fri
Location: Россия

Post by Qwertiy »

Verholom wrote:Версия, на которую Вы меня ткнули - это версия моего плагина, но есть еще функция GetMinAppVersion, о которую, видимо и спотыкается ДМ...
Сорри, я перепутал поля для версии плагина и для для минимальной версии DM. Я подумал про эту строку:
Verholom wrote:

Code: Select all

#Define def_MinAppVersion   @WStr("5.0.2")
а именно, что должно быть 3 числа, а не 4. Но здесь всё нормально.
Verholom wrote:Тут вайд-строки, 2-байтовые...
А длина строки перед самой строкой имеется?
Verholom wrote:Зачем надо: учет чего качаем в сети в оффисе... Все пользуются тлько хромом и доступ к настройкам закрыт...
Непонятно. Скачивать можно и в обход DM в любом случае.

PS: А вообще, интересно, что ты тут появился как раз когда я написал про плагин на VB6.
Пожалуйста, посмотрите: Использование ссылок в тексте сообщений
Поддерживаются браузеры: Опера 12, Хром, Firefox.
Обновлено: 21.09.2012. Надо бы ещё подправить и обновить...
Ссылки на файлы обновлены: 24.05.2013.
marcipan
Гуру
Posts: 1400
Joined: 11 Jun 2005, 3:55 Sat
Location: Санкт-Петербург

Re:

Post by marcipan »

Qwertiy wrote:
Verholom wrote:Пытаюсь написать свой плагин к ИДА...
К IDA или к DM?
ДМ вечная бетка от ИДА. Пользователи ДМ, тестеры ИДА. Сорри за оффтоп.
Windows 7 х64, Google Chrome 54.0.2840.99, ИЕ11 \ DM 6.10.2.1527
Verholom
Posts: 4
Joined: 18 Jul 2013, 11:11 Thu

Re:

Post by Verholom »

Qwertiy wrote: А длина строки перед самой строкой имеется?
Пробовал - вылет... :evil: Хотя вот функция возврата ВБ-шной строки :?: :

Code: Select all

Function GetVBString(ByVal wstrBuffer As WString ptr) As WString Ptr
	Dim As UInteger dwCch=lstrlen(wstrBuffer) 'длина строки
	Dim As Any Ptr lpBuf=Allocate(dwCch+SizeOf(UInteger)) 'выделяем память под нее и под размер
	
	'пишем размер
	Cast(UInteger Ptr,lpBuf)[0]=dwCch
	lpBuf+=SizeOf(UInteger) 'и сдвигаем указатель на 4 байта. Теперь у нас указатель на нормальную ВБ-строку
	'копируем исходную строку в буффер
	lstrcat(Cast(LPTSTR,lpBuf),Cast(LPTSTR,wstrBuffer))
	'возврат с указателем на строку, на 4 байта позади нее - длина...
	Return lpBuf
End Function
Qwertiy
Гуру
Posts: 764
Joined: 07 Jan 2011, 1:45 Fri
Location: Россия

Post by Qwertiy »

Verholom wrote:
Qwertiy wrote:А длина строки перед самой строкой имеется?
Пробовал - вылет... :evil:
Не, я фигню спросил. На скриншоте же заполнены сайт с копирайтом, значит формат строк он понимает.
Verholom wrote:Хотя вот функция возврата ВБ-шной строки :?: :
По-моему, это баг:

Code: Select all

   Dim As UInteger dwCch=lstrlen(wstrBuffer) 'длина строки
   Dim As Any Ptr lpBuf=Allocate(dwCch+SizeOf(UInteger)) 'выделяем память под нее и под размер
Во-первых, не учитывается завершающий 0, а во-вторых, запрашиваетя память в байтах без удвоения числа символов.
Ну и наконец, используется слишком много строковых функций, которые непонятно что делают реально. Например, с какого перепуга там конкатенация? А где она возьмёт длину строки, к которой ты дописываешь вторую?
Пожалуйста, посмотрите: Использование ссылок в тексте сообщений
Поддерживаются браузеры: Опера 12, Хром, Firefox.
Обновлено: 21.09.2012. Надо бы ещё подправить и обновить...
Ссылки на файлы обновлены: 24.05.2013.
Verholom
Posts: 4
Joined: 18 Jul 2013, 11:11 Thu

Re:

Post by Verholom »

Qwertiy wrote:
Verholom wrote:
Qwertiy wrote:А длина строки перед самой строкой имеется?
Пробовал - вылет... :evil:
Не, я фигню спросил. На скриншоте же заполнены сайт с копирайтом, значит формат строк он понимает.
Verholom wrote:Хотя вот функция возврата ВБ-шной строки :?: :
По-моему, это баг:

Code: Select all

   Dim As UInteger dwCch=lstrlen(wstrBuffer) 'длина строки
   Dim As Any Ptr lpBuf=Allocate(dwCch+SizeOf(UInteger)) 'выделяем память под нее и под размер
Во-первых, не учитывается завершающий 0, а во-вторых, запрашиваетя память в байтах без удвоения числа символов.
Ну и наконец, используется слишком много строковых функций, которые непонятно что делают реально. Например, с какого перепуга там конкатенация? А где она возьмёт длину строки, к которой ты дописываешь вторую?
lstrlen работает с вайд символами, если объявлен символ UNICODE. МСДН ясно об этом говорит... Соответственно, она и считает по 2 байта... А конкатенация - просто делаю новую строку в памяти и копирую туда все, что передается... Она работает, я месаджбоксы выводил, все нормадьно показывает...
Qwertiy
Гуру
Posts: 764
Joined: 07 Jan 2011, 1:45 Fri
Location: Россия

Post by Qwertiy »

Verholom wrote:lstrlen работает с вайд символами, если объявлен символ UNICODE. МСДН ясно об этом говорит... Соответственно, она и считает по 2 байта... А конкатенация - просто делаю новую строку в памяти и копирую туда все, что передается... Она работает, я месаджбоксы выводил, все нормадьно показывает...
Не знаю, что там работает, но не должно.
1. Длина строки считается для юникодной строки, но в символах, а не в байтах, верно? Получили n символов. Завершающий 0 не посчитан.
2. Надо запросить 4+2*(n+1) байт? а в коде 4+n байт, насколько я понимаю. Даже если я ошибаюсь и там 4+2*n байт, то ещё двух не хватает.
3. Записали длину n символов в массив, остальная часть массива не инициализируется (или Бейсик её сам нулями заполнил?). Кстати, если я не прав про размер в символах, то записытать надо не это число, а его половину, верно?
4. Вызвали конкатенацию.
4а. Она прочитала записанную длину строки n и добавила исходную строку после неё, плохо.
4б. Она стала искать конец строки в виде нулевого символа, но массив заполнен мусором, снова плохо.
5. Кто сказал, что вызванная функция конкатенации не запишет длину строки сама, если она работает с bstr?
6. Есть функция для создания BSTR, зачем использовать Allocate?

И вообще, я же сказал:
Qwertiy wrote:Не, я фигню спросил. На скриншоте же заполнены сайт с копирайтом, значит формат строк он понимает.
так что забей на ручное формирование строки (= верни как было). Ошибка где-то ещё. Проверь порядок функций в интерфейсе, например.
Пожалуйста, посмотрите: Использование ссылок в тексте сообщений
Поддерживаются браузеры: Опера 12, Хром, Firefox.
Обновлено: 21.09.2012. Надо бы ещё подправить и обновить...
Ссылки на файлы обновлены: 24.05.2013.
Post Reply