Передача адреса структуры

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
KiloGraf
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 142
Зарегистрирован: 21.10.2004 (Чт) 7:37
Откуда: берутся такие глупые вопросы?

Передача адреса структуры

Сообщение KiloGraf » 04.07.2013 (Чт) 4:11

Немного почитал тему Как найти хендл контрола, но не стал там постить, дабы у меня вопрос немного отклоняется от той темы.

Суть такова. Есть функция в широко извесной длл'ки, которая в качестве аргумента принимает структуру...к примеру:

Код: Выделить всё
Private Type RAROpenArchiveData
  ArcName As String
  OpenMode As Long
  OpenResult As Long
  CmtBuf As String
  CmtBufSize As Long
  CmtSize As Long
  CmtState As Long
End Type

Public Declare Function RAROpenArchive Lib "unrar.dll" (ByRef ArchiveData As RAROpenArchiveData) As Long


Но у меня данная длл'ка загружена уже в памяти, и не совсем традиционным способом. И чё-та я вошел в тупик, никак не могу передать ей структуру.

В общем, создал некий враппер для функции, но проблему не могу решить.
Входящий адрес функции в памяти передается через pProc...

Вариант первый похоже как-то обрабатывает структуру, так как в OpenResult содержится код ошибки, отличный от первоначального нулевого значения (GetMem4 принимает входящие как Any):

Код: Выделить всё
Private Const ASM_PUSH As Byte = &H68  'PUSH ...
Private Const ASM_CALL As Byte = &HE8  'CALL ...
Private Const ASM_RETN10 = &H10C2&     'RETN 10

Private Function CallWinowProc4(ByVal pProc As Long, ByRef ArchiveData As RAROpenArchiveData) As Long
  Dim Proc(13) As Byte  'Буфер для варианта процедуры CallWinowProc@4
  Dim lngAddr As Long
  Dim lngOffset As Long
 
  lngAddr = VarPtr(Proc(0))
  lngOffset = lngAddr
 
  PutMem1 lngOffset, ASM_PUSH               'PUSH ...
  lngOffset = lngOffset + 1
  GetMem4 VarPtr(ArchiveData), ByVal lngOffset  'Arg
  lngOffset = lngOffset + 4
 
  PutMem1 lngOffset, ASM_CALL               'CALL ...
  lngOffset = lngOffset + 1
  PutMem4 lngOffset, pProc - lngOffset - 4  'pProc
  lngOffset = lngOffset + 4
  PutMem4 lngOffset, ASM_RETN10             'RETN 10
 
  CallWinowProc4 = CallWindowProc(lngAddr, 0, 0, 0, 0)
End Function


Вариант второй вообще вылетает с ошибкой на невозможность писать в память по левому адресу, и соответственно схлопывается:

Код: Выделить всё
Private Function CallWinowProc28(ByVal pProc As Long, ByRef ArchiveData As RAROpenArchiveData) As Long
  Dim Proc(43) As Byte  'Буфер для варианта процедуры CallWinowProc@28
  Dim lngAddr As Long
  Dim lngOffset As Long
 
  lngAddr = VarPtr(Proc(0))
  lngOffset = lngAddr
 
  PutMem1 lngOffset, ASM_PUSH               'PUSH ...
  lngOffset = lngOffset + 1
  GetMem4 VarPtr(ArchiveData.CmtState), ByVal lngOffset    'Arg7
  lngOffset = lngOffset + 4
 
  PutMem1 lngOffset, ASM_PUSH               'PUSH ...
  lngOffset = lngOffset + 1
  GetMem4 VarPtr(ArchiveData.CmtSize), ByVal lngOffset     'Arg6
  lngOffset = lngOffset + 4
 
  PutMem1 lngOffset, ASM_PUSH               'PUSH ...
  lngOffset = lngOffset + 1
  GetMem4 VarPtr(ArchiveData.CmtBufSize), ByVal lngOffset  'Arg5
  lngOffset = lngOffset + 4
 
  PutMem1 lngOffset, ASM_PUSH               'PUSH ...
  lngOffset = lngOffset + 1
  GetMem4 VarPtr(ArchiveData.CmtBuf), ByVal lngOffset      'Arg4
  lngOffset = lngOffset + 4
 
  PutMem1 lngOffset, ASM_PUSH               'PUSH ...
  lngOffset = lngOffset + 1
  GetMem4 VarPtr(ArchiveData.OpenResult), ByVal lngOffset  'Arg3
  lngOffset = lngOffset + 4
 
  PutMem1 lngOffset, ASM_PUSH               'PUSH ...
  lngOffset = lngOffset + 1
  GetMem4 VarPtr(ArchiveData.OpenMode), ByVal lngOffset    'Arg2
  lngOffset = lngOffset + 4
 
  PutMem1 lngOffset, ASM_PUSH               'PUSH ...
  lngOffset = lngOffset + 1
  GetMem4 VarPtr(ArchiveData.ArcName), ByVal lngOffset     'Arg1
  lngOffset = lngOffset + 4
 
  PutMem1 lngOffset, ASM_CALL               'CALL ...
  lngOffset = lngOffset + 1
  PutMem4 lngOffset, pProc - lngOffset - 4  'pProc
  lngOffset = lngOffset + 4
  PutMem4 lngOffset, ASM_RETN10             'RETN 10 
  CallWinowProc28 = CallWindowProc(lngAddr, 0, 0, 0, 0)
End Function


Кто-нибудь может подскажет, где я туплю? Как мне передать эту структуру?
Nonsense in BASIC. © 1982 ...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Передача адреса структуры

Сообщение Хакер » 04.07.2013 (Чт) 6:01

KiloGraf писал(а):Но у меня данная длл'ка загружена уже в памяти, и не совсем традиционным способом.

Не стоит играть в загадки. Что за нетрадиционный образ — рассказывай.

KiloGraf писал(а):В общем, создал некий враппер для функции, но проблему не могу решить.

А смысл? В чём изначальная задача.

Реализация переходника ужасная. Во-первых, код располагается не стеке. Во-вторых, есть кирпич.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

KiloGraf
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 142
Зарегистрирован: 21.10.2004 (Чт) 7:37
Откуда: берутся такие глупые вопросы?

Re: Передача адреса структуры

Сообщение KiloGraf » 04.07.2013 (Чт) 7:23

Нетрадиционный метод - это у меня свой загрузчик...
...по секциям, с импорт/экспортом, с релоками, с расстановкой защиты, и инициализацией DllMain

Переходник я где-то здесь видел, возможно даже в 'кирпичах'...но только он видоизменен для визуализации, что упрощает отладку. Да и выглядит он у меня совсем иначе.

Изначальная задача, это полностью дописать свой загрузчик, вернее, найти все недоделки, которые я мог упустить при его написании.
А данная проблема возникла потому, что к загрузчику хочу приложить несколько примеров загрузки и использования различных библиотек.

------ Добавил спустя час ------

Похоже я нашел, в чём я затупил!
Позабыл о том, что надо было избавится от юникода в стоковых аргументах структуры.

Враппер функций у меня другой, и в данном примере передается адрес банальным способом - VapPtr(StructData)

------ Добавил спустя сутки ------

Хакер писал(а):Реализация переходника ужасная. Во-первых, код располагается не стеке. Во-вторых, ...


Про переходник я уже говорил, что он только для понятности был приведен, в качестве примера на форуме.
А вот про стек...
...совсем забыл сказать, что не совсем корректное замечание!!!

Как раз именно в стек помещаются все указатели перед вызовом, если бы внимательно взглянуть...
...иначе, откуда бы они прилетали? ))
Nonsense in BASIC. © 1982 ...


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot, Google-бот, Yandex-бот и гости: 40

    TopList