Тема: Как AutoCAD определяет версию ARX-приложения?

Вопрос к уважаемым знатокам: как автокад определяет, что загружаемое приложение имеет нужную версию? По всей видимости дело не ограничивается вызовом функции acrxGetApiVersion.

Re: Как AutoCAD определяет версию ARX-приложения?

IMHO - ограничивается именно этой функцией. Другое дело, что она кроме своего основного действия, а именно возврата версии, производит еще какие-то не очень понятные мне манипуляции:

--- u:\components\global\src\objectdbx\rx\api\libinit.cpp ----------------------
0710E000  push        ebp
0710E001  mov         ebp,esp
0710E003  sub         esp,8
0710E006  push        esi
0710E007  jmp         _acrxGetApiVersion+0Dh (710E00Dh)
0710E009  add         byte ptr [eax],al
0710E00B  adc         byte ptr [eax],al
0710E00D  cmp         dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)],0
0710E014  jne         _acrxGetApiVersion+0E8h (710E0E8h)
0710E01A  mov         dword ptr [ebp-4],100000h
0710E021  mov         eax,dword ptr [ebp+8]
0710E024  mov         dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)],eax
0710E029  movsx       ecx,word ptr [_RTC_ErrorLevels+56h (7119D26h)]
0710E030  cmp         ecx,110Fh
0710E036  je          _acrxGetApiVersion+0D9h (710E0D9h)
0710E03C  mov         dword ptr [ebp-8],0
0710E043  jmp         _acrxGetApiVersion+4Eh (710E04Eh)
0710E045  mov         edx,dword ptr [ebp-8]
0710E048  add         edx,1
0710E04B  mov         dword ptr [ebp-8],edx
0710E04E  cmp         dword ptr [ebp-8],15h
0710E052  jge         _acrxGetApiVersion+80h (710E080h)
0710E054  mov         eax,dword ptr [ebp-8]
0710E057  movzx       esi,byte ptr _RTC_ErrorLevels+48h (7119D18h)[eax]
0710E05E  mov         eax,dword ptr [ebp-8]
0710E061  imul        eax,eax,25h
0710E064  cdq
0710E065  mov         ecx,16h
0710E06A  idiv        eax,ecx
0710E06C  mov         ecx,edx
0710E06E  shl         esi,cl
0710E070  mov         edx,dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)]
0710E076  xor         edx,esi
0710E078  mov         dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)],edx
0710E07E  jmp         _acrxGetApiVersion+45h (710E045h)
0710E080  movsx       eax,byte ptr [_RTC_ErrorLevels+156h (7119E26h)]
0710E087  movsx       ecx,byte ptr [_RTC_ErrorLevels+159h (7119E29h)]
0710E08E  imul        eax,ecx
0710E091  movsx       edx,byte ptr [_RTC_ErrorLevels+158h (7119E28h)]
0710E098  imul        edx,edx,3
0710E09B  sub         eax,edx
0710E09D  movsx       ecx,byte ptr [_RTC_ErrorLevels+15Ah (7119E2Ah)]
0710E0A4  and         ecx,7
0710E0A7  shl         eax,cl
0710E0A9  movsx       ecx,byte ptr [_RTC_ErrorLevels+157h (7119E27h)]
0710E0B0  xor         eax,ecx
0710E0B2  movsx       edx,byte ptr [_RTC_ErrorLevels+15Ah (7119E2Ah)]
0710E0B9  or          edx,3
0710E0BC  imul        eax,edx
0710E0BF  movsx       ecx,byte ptr [_RTC_ErrorLevels+159h (7119E29h)]
0710E0C6  shl         ecx,18h
0710E0C9  add         eax,ecx
0710E0CB  mov         edx,dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)]
0710E0D1  xor         edx,eax
0710E0D3  mov         dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)],edx
0710E0D9  mov         eax,dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)]
0710E0DE  xor         eax,dword ptr [ebp-4]
0710E0E1  mov         dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)],eax
0710E0E6  jmp         _acrxGetApiVersion+100h (710E100h)
0710E0E8  mov         ecx,dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)]
0710E0EE  xor         ecx,dword ptr [ebp+8]
0710E0F1  mov         dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)],ecx
0710E0F7  mov         edx,dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)]
0710E0FD  mov         dword ptr [ebp-4],edx
0710E100  cmp         dword ptr [ebp+8],0
0710E104  jne         _acrxGetApiVersion+110h (710E110h)
0710E106  mov         dword ptr [__afxForceSTDAFX+8Ch (711A32Ch)],0
0710E110  mov         eax,dword ptr [ebp-4]
0710E113  pop         esi
0710E114  mov         esp,ebp
0710E116  pop         ebp
0710E117  ret

Re: Как AutoCAD определяет версию ARX-приложения?

P.S. Такой результат можно получить в AutoCAD 2006 если создать свое приложение в режиме Debug, подключиться к процессу acad.exe, поставить breakpoint на acrxGetApiVersion и загрузить свое приложение. Так что никаких секретов я не расскрываю. smile

Re: Как AutoCAD определяет версию ARX-приложения?

Подлейшая функция!
Из-за ее пакостей не получается сделать "левый" ARX в посторонней среде и загрузить в AutoCAD. В R14 она только возвращала число.

Re: Как AutoCAD определяет версию ARX-приложения?

Перед тем, как поднять тему, некоторое время разбирался с  acrxGetApiVersion. Если подменить ее своим вариантом функции, или даже сделать jmp из библиотечной в свою функцию, то библиотека даже не загружается (ИМХО), по крайней мере дело даже не доходит до DLL_main(ATTACH_PROCESS). Поэтому я и предположил, что автокад еще до вызова acrxGetApiVersion (и даже до LoadLibrary) проводит с файлом какие-то манипуляции. Может кто-нибудь подскажет, куда копать? Лезть вслепую в дебри acad.exe ?

Re: Как AutoCAD определяет версию ARX-приложения?

> Мансур
А зачем тебе это надо? Зачем лезть в эти дебри?
Ещё до вызова каких-либо функций Автокад проверят каким компиляторм была собрана библиотека. Поэтому сделал так: написал переходник, который соответствует требованиями Автокада, но в acrxEntryPoint заргружает другой модуль передаёт ему управление.

Re: Как AutoCAD определяет версию ARX-приложения?

> archimag
Совершенно согласен с тем, что не нужно лезть в эти дебри. А вот компилятор (IMHO) AutoCAD не проверяет. Тут все проще и одновременно сложнее.

> Мансур
Есть еще несколько соображений:
1) Экспортируется еще и функция
_SetacrxPtp - это функция-заглушка (т.е. ничего не делает, но должна присутствовать)
2) Несмотря на отсутствие директивы, указывающую линкеру базовую точку, базовая точка arx-файлов 10000000h и это можно проверить до загрузки
3) Есть еще функция с интересным названием _acrxDllMain@12 (но она не экспортируется).
Только боюсь здесь копать - не перекопать... Так что прислушайся к совету archimag - голова целее будет smile

Re: Как AutoCAD определяет версию ARX-приложения?

> archimag
насчет переходника были точно такие же мысли. Значит идея верна :).
>Александр Ривилис
Согласен с тем, что вы согласны, что не стоит туда лезть.
А если серьезно, то мой проект MtmdLoadDll получился размером ~10кб, из которых половина - нулевые байты. Моего кода - четверть. Остальное - непонятно что. Вот и решил немного поразбираться и ужать arx до самого минимума. CRT я отбросил за ненадобностью, в качестве EntryPoint указываю напрямую DLL_main. A на acrxGetApiVersion споткнулся.
Конечно для более серьезный проектов сей метод неприемлем абсолютно. Но почему бы и не залезть в чащу (иногда)?