:: Visual Foxpro, Foxpro for DOS
Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Crispy
Автор

Сообщений: 18571
Дата регистрации: 16.05.2005
Данные три статьи решают как минимум две проблемы современных фокс-приложений:
1) очень легкое и простое повышение прав для фокс-приложений при работе их под Windows 7, причем уже сразу встроенное в само приложение, без необходимости каких-либо изменений в настройках системы.
2) возможность использования в своих приложениях OCX без необходимости их прописывания в реестре, что дает возможность размещать OCX во "внутренностях" собственных каталогов программы, не регистрируя ее вовсе, что делает ее недоступной для внешних программ и не засоряет реестр.

Информация, в которой была ссылка на первую из статей, как-то мелькнула с подачи Пивы в курилке, и естественно канула там в лету, по сути в бездонный колодец, где наверняка мало кто догадается когда-либо искать эту ссылку. К тому же сами статьи написаны на английском, что несколько затрудняет их чтение для человека, не владеющего английским в совершенстве.
Поэтому мне показалось, что было бы неплохо разместить переводы данных статей именно здесь на форуме.
Переводы мной сделаны в попытке передать довольно своеобразный легкий и разговорный язык автора, поэтому обороты речи в каких-то местах могут толковаться возможно и чуть иначе. Однако надеюсь чисто логических ошибок все же не насовершал. В любом случае для себя считаю эти статьи довольно-таки полезными и не жалею усилий, затраченных на их перевод.

Также мне кажется было бы интересно обсудить здесь эти проблемы.
Предлагаю высказываться всем, кому они интересны, у кого есть свои собственные решения, либо же какие-то вопросы в отношении предмета данных статей.
Ratings: 0 negative/1 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Crispy
Автор

Сообщений: 18571
Дата регистрации: 16.05.2005
* Статья с блога Крейга Бойда ч.1. (в моем переводе)
* 25 сентября 2007 г.
* www.sweetpotatosoftware.com
*
* Файлы PE, UAC, Reg-free COM, и Другой Сумасшедший Материал - Часть 1
* Я сочувствую вам
В посте блога от 14-го августа Лайза Слейтер Николлс (Lisa Slater Nicholls) переживала по поводу того,
что Vista Toolkit, часть Sedna, не включает возможности по управлению учетными записями пользователя.
На что я говорю лишь: "Я не могу не согласиться с вами, Лайза!".
Как многие из вас знают, я - разработчик, который выполнял работу для Microsoft по созданию Vista Toolkit.
В то же время, я хотел бы, чтобы вы помнили, что не я устанавливал приоритеты для Vista Toolkit, и не я
принимал окончательные решения о том, что должно быть включено или не включено в Toolkit, поэтому я и
действительно сочувствую - и Лайзе, и всей остальной части тех из вас, чьи пожелания не исполнились.
* Один Разработчик МОЖЕТ Иметь Значение
* сообщество МОЖЕТ создавать будущее
Я сказал, что Сообщество может управлять всем непосредственно из Visual FoxPro. Без ресурсного ядра?
Да, даже без ядра, в рантайме Visual FoxPro или в IDE. И Microsoft-не-Microsoft, я лично! - хочу представить
сообществу FoxPro некоторые сумасшедшие, очень прикольные недокументированные возможности Vista Toolkit.
Итак, давайте начнем с этой записи в блоге, и может быть чуть более правильнее после этого сможем понять,
что мы можем сделать, чтобы открыть кому-то глаза на возможности удовлетворения тех потребностей,
которые Сообщество Фокса хотело бы удовлетворить...
* Что в Следующих Нескольких Записях в блоге?
+ Несколько мыслей о структуре Visual FoxPro EXE или DLL.
+ Как вы можете заменить manifest в Visual FoxPro EXE или DLL, чтобы получить Повышенные Права Доступа.
+ Как вы можете заменить manifest в Visual FoxPro EXE или DLL, чтобы получить Reg-free COM.
+ Как добавить или заменить строки в строковой таблице ресурсов Visual FoxPro EXE или DLL
и почему бы вы нуждались или хотели бы сделать это.
+ Как зарегистрировать VFP COM серверы, которые требуют установки разрешений должным образом так,
чтобы их классы OLEPublic могли использовать код из исполняемых программ, загруженных под
ограниченной учетной записью пользователя (LUA).
+ Как использовать код из объекта COM, требующего установленных разрешений, используя новое установленное
именование COM, CoGetObject и Sys (3096).
* Во-первых, Особые Благодарности
Прежде, чем начать по сути этой записи и других в блоге, я хотел бы еще раз поблагодарить Bo Durban из
Moxie Data, Inc., который заглядывал без предупреждения время от времени, чтобы выручать меня с частью из
того, что я собираюсь показать. Он помогал мне в таком количестве во всем сделанном, что заслуживает
поистине сердечной признательности.
Теперь после всего сказанного давайте наконец рассмотрим этот сумасшедший очень прикольный материал.
* Структура Переносимых Исполняемых Файлов
Пока что я не буду копаться в этом слишком глубоко. Оставлю подобное для будущих записей в блоге.
Сейчас же важно знать, что понимание структуры Переносимого Исполняемого файла (PE) играет главную роль
в том, что я делаю, и, что еще более важно, что именно, я в состоянии сделать с исполняемыми файлами Visual FoxPro.
Понимание формата PE дает вам огромную власть и позволяет совершать вещи, которые вы, как разработчик,
иначе были бы не в состоянии сделать.
Формат PE используется для всех видов файлов: EXE, DLL, OCX, OBJ, SYS, и даже апплетов Панели Управления.
Они все в формате PE, и таким образом, если вы знаете, как прочитать один из них - вы знаете, как
прочитать их все. В то же время, не думайте, что структура файла PE определяется доступным прямым способом.
Сразу же в самом начале PE вы столкнетесь со связкой байтов, составляющих заголовок DOS (заглушка), и они
укажут вам на начало выполнимого кода NT_HEADER, который сопровождает IMAGE_FILE_HEADER, затем
IMAGE_OPTIONAL_HEADER, IMAGE_OPTIONAL_HEADER_NT и т.п. - ad nauseum [до отвращения(лат.) - прим.пер.].
В любом случае, если вы зароетесь достаточно глубоко, то подъедете к IMAGE_SECTION_HEADER, который
обеспечивает базовые адреса и смещения - и таким образом вы смогли бы обнаружить часть действительно
интересного материала в файле PE. Этот интересный материал состоял бы из таких вещей как:
Импорт, Экспорт, Ресурсы (Иконки, Строка Таблиц и Конфигураций) файла PE.
Все эти различные части и многие другие, о которых я не упомянул, в файле PE располагаются одна за другой
в памяти, либо же их структуры содержат то, что может показать вам, где их найти - относительно друг друга
в некотором роде.
Так, если вы захотите прочитать нечто из файла PE, вы просто находите местоположение искомого и его размер,
и по сути таким образом уже и прочитываете нужное.
* Вход по абсолютному адресу в PE
Если вы хотите войти по абсолютному адресу в файл PE, чтобы получить лучшее представление о том, что я вообще
говорю, скачайте и установите у себя что-либо наподобие:
"Resource Hacker" www.angusj.com и/или "CFF Explorer" www.ntcore.com
Я преднамеренно упускаю многие детали в этой записи в блоге, потому что по большей части нам нет необходимости
читать или управлять нашими PE-файлами и DLL, используя функции низкого уровня. Из-за того - что, к счастью,
Microsoft обеспечила достаточно вызовов API, которые мы и можем использовать намного более легким способом.
Впрочем, тут вы можете назвать меня лгуном после того, что увидите в коде в моих последующих записях в блоге.
Потому что сказать: "более изящным способом" - было бы более точным определением.
Для тех из вас, кто хочет входить по абсолютному адресу в файл PE, используя Visual FoxPro и Функции Файла
Низкого уровня, воспользуйтесь кодом, приведенным ниже. Просто загрузите prg и выберите свой файл PE (EXE, DLL,
и т.п.). Посмотрите на массив aPEFile в окне Debug Locals отладчика, когда сработает Set Step On выше вызова
FClose, либо шагая по коду, байт за байтом, как они считываются.
Также не даю изобилия комментариев, поскольку там и без того вполне достаточно много имен структур, чтобы вы
смогли проделать интернет-поиски, если пожелаете дополнительной информации о том, что это, и чему оно служит.
* Замена manifest-а в PE-файле Visual FoxPro
Каждый из вас, кто смотрел на исполняемый файл FoxPro в Блокноте, возможно замечал, что есть некий XML-участок
вблизи конца файла. Этот XML и является фактически manifest-ом файла. Так вот, этот самый manifest может
использоваться, чтобы проделывать некоторые реально крутые вещи, и я покажу часть из них в моей следующей
записи в блоге.
* Прохождение по частям PE-файла в Visual FoxPro
* (только для информационных целей)
PUBLIC lnVirtualResourceAddress
LOCAL i
SET ESCAPE ON
m.lcFile = GETFILE()
IF FILE(m.lcFile)
m.hFile = FOPEN(m.lcFile,0)
m.lnFileSize = FSEEK(m.hFile, 0, 2)
=FSEEK(m.hFile, 0, 0)
DIMENSION aPEFile(5000)
* Получение DOS заголовка - IMAGE_DOS_HEADER
m.lnElementCounter = 1
FOR i = 1 TO 30 skip 2
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
ENDFOR
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && e_lfanew - точка, откуда запускается PE-файл
* Переход к заголовку NT Header
=FSEEK(m.hFile, aPEFile(m.lnElementCounter), 0)
* Сигнатура PE-файла
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && IMAGE_NT_SIGNATURE - из ImageSignatureTypes
* IMAGE_FILE_HEADER
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
* IMAGE_OPTIONAL_HEADER
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,1),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,1),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
* IMAGE_OPTIONAL_HEADER_NT
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS")
* IMAGE_DATA_DIRECTORY
* IMAGE_DIRECTORY_ENTRY_EXPORT
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_IMPORT
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_RESOURCE
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_EXCEPTION
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_SECURITY
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_BASERELOC
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_DEBUG
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_ARCHITECTURE
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_GLOBALPTR
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_TLS
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_IAT
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* IMAGE_DIRECTORY_ENTRY_DOTNET_METADATA
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* ?
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
* 248
* IMAGE_SECTION_HEADER
FOR i = 1 TO 8
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = FREAD(m.hFile,8) && Name
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Virtual Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Raw Size
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Raw Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Reloc Address
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Linenumbers
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS") && Relocations Number
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS") && Linenumbers Number
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Characteristics
ENDFOR
* 568
m.lnFilePointer = 568
m.lnVirtualResourceAddress = aPEFile(174)
m.InitialResourceDirectoryAddress = aPEFile(176)
GetImageResourceDirectory(m.InitialResourceDirectoryAddress, m.InitialResourceDirectoryAddress, hFile, m.lnFilePointer, @aPEFile, @lnElementCounter)
SET STEP ON
?FCLOSE(m.hfile)
ENDIF
*************************
FUNCTION GetImageResourceDirectory(lnLocation, lnInitialLocation, hFile, lnFilePointer, aPEFile, lnElementCounter)
*************************
* Private Type IMAGE_RESOURCE_DIRECTORY
* Characteristics As Long '\\Кажется всегда нуль?
* TimeDateStamp As Long
* MajorVersion As Integer
* MinorVersion As Integer
* NumberOfNamedEntries As Integer
* NumberOfIdEntries As Integer
* End Type
m.lnFilePointer = lnLocation
=FSEEK(m.hFile, m.lnFilePointer, 0)
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Characteristics
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && TimeDateStamp
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS") && MajorVersion
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS") && MinorVersion
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS") && NumberOfNamedEntries
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,2),"RS") && NumberOfIdEntries
m.lnFilePointer = m.lnFilePointer + 16
GetImageResourceDirectoryEntries(aPEFile(m.lnElementCounter), m.lnInitialLocation, hFile, lnFilePointer, @aPEFile, @lnElementCounter)
ENDFUNC
*************************
FUNCTION GetImageResourceDirectoryEntries(lnNumberofEntries, lnInitialLocation, hFile, lnFilePointer, aPEFile, lnElementCounter)
*************************
* Private Type IMAGE_RESOURCE_DIRECTORY_ENTRY
* dwName As Long
* dwDataOffset As Long
* CodePage As Long
* Reserved As Long
* End Type
LOCAL llHighBitSet, lnOffset, lcOffset, lnLocation, i
FOR i = 1 TO lnNumberofEntries && NumberOfIdEntries
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && dwName (ID)
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && dwDataOffset
m.lnFilePointer = m.lnFilePointer + 8
m.lnOffset = aPEFile(m.lnElementCounter) + 2147483648
m.llHighBitSet = m.lnOffset <= 2147483648
IF m.llHighBitSet && Точки к другому Каталогу Ресурса
m.lnLocation = m.lnOffset + m.lnInitialLocation
GetImageResourceDirectory(m.lnLocation, m.lnInitialLocation, m.hFile, m.lnFilePointer, @aPEFile, @lnElementCounter)
ELSE && Точки к данным
* dwName is offset, dwDataOffset is size
m.lnLocation = aPEFile(m.lnElementCounter) + m.lnInitialLocation
GetResourceDataEntry(m.lnLocation, aPEFile(m.lnElementCounter-2), m.hFile, m.lnInitialLocation, @aPEFile, @lnElementCounter)
ENDIF
=FSEEK(m.hFile, m.lnFilePointer, 0)
ENDFOR
ENDFUNC
*************************
FUNCTION GetResourceDataEntry(lnLocation, lnSize, hFile, lnInitialLocation, aPEFile, lnElementCounter)
*************************
IF lnLocation > 0 AND lnSize > 0
=FSEEK(m.hFile, lnLocation, 0)
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && OffSet
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Size
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && CodePage
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = CTOBIN(FREAD(m.hFile,4),"RS") && Reserved
GetResourceData((aPEFile(m.lnElementCounter-3) - m.lnVirtualResourceAddress) + lnInitialLocation, aPEFile(m.lnElementCounter-2), m.hFile, @aPEFile, @lnElementCounter)
ELSE
SET STEP ON
ENDIF
ENDFUNC
*************************
FUNCTION GetResourceData(lnLocation, lnSize, hFile, aPEFile, lnElementCounter)
*************************
IF lnLocation > 0 AND lnSize > 0
=FSEEK(m.hFile, m.lnLocation, 0)
m.lnElementCounter = m.lnElementCounter + 1
aPEFile(m.lnElementCounter) = FREAD(m.hFile, m.lnSize)
ELSE
SET STEP ON
ENDIF
ENDFUNC


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)




Исправлено 2 раз(а). Последнее : Crispy, 27.05.11 16:05
Ratings: 0 negative/1 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Crispy
Автор

Сообщений: 18571
Дата регистрации: 16.05.2005
* Статья с блога Крейга Бойда ч.2 (в моем переводе)
* 25 сентября 2007 г.
* www.sweetpotatosoftware.com
*
* Файлы PE, UAC, Reg-free COM, и Другой Сумасшедший Материал - Часть 2
* В прошлый Раз
В части 1 этой статьи я показал в общих чертах, что я вообще собираюсь показать, а также дал некоторую краткую
информацию относительно формата PE. В конце я привел некоторый код, который позволяет разработчику Visual FoxPro
проходить по некоторым из структур PE и данным. В этой же записи в блоге, я собираюсь показать вам, как вы можете
отредактировать manifest в Файле PE, и как это может облегчить установку разрешений в Vista UAC и Reg-Free COM.
* Manifest-ы в PE-файлах Visual FoxPro
Некоторое время назад Visual FoxPro Team начала добавлять информацию о конфигурации в качестве ресурса в Visual
FoxPro DLL и EXE-файлах. Эта информация о конфигурации - фактически Манифест Приложения (Application Manifest).
Давайте бросим беглый взгляд на один пример. Загрузите нижеприведенный код, и укажите в качестве выбора любой
файл VFP - EXE или DLL.
Declare Long LoadLibrary In WIN32API String
Declare Long FindResource In WIN32API Long, Long, Long
Declare Long LoadResource In WIN32API Long, Long
Declare Long SizeofResource In WIN32API Long, Long
Declare Long FreeLibrary In WIN32API Long
Declare Long FreeResource In WIN32API Long
Local lcModule, hModule
m.lcModule = Getfile("EXE|DLL")
m.hModule = LoadLibrary(m.lcModule)
m.lnRsrc = FindResource(m.hModule, 1, 24)
m.lnMem = LoadResource(m.hModule, m.lnRsrc)
m.lnSize = SizeofResource(m.hModule, m.lnRsrc)
m.lcManifest = Sys(2600, m.lnMem, m.lnSize)
FreeResource(m.lnMem)
FreeLibrary(m.hModule)
?m.lcManifest
Вы должны увидеть что-то наподобие такого:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
type="win32"
name="Microsoft.VisualFoxPro"
processorArchitecture="x86"
/>
<description>Visual FoxPro</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
language="*"
processorArchitecture="x86"
publicKeyToken="6595b64144ccf1df"
/>
</dependentAssembly>
</dependency>
</assembly>
* Visual FoxPro 9.0 SP2
Теперь, те из вас, кто выбрали EXE или DLL, построенный в VFP9 SP2, отметят, что ваш manifest xml -
не то же самое, что я показал выше. В VFP9 SP2 он имеет дополнительный узел trustinfo, который подобен:
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
Этот trustinfo-узел используется для безопасного связывания, и определяет способ, которым контроль за
учетной записью пользователя на Vista реагирует на начало вашего PE-файла, и что ему дозволяется делать, когда он
загружается. Отметьте узел requestedExecutionLevel, и особенно атрибут уровня, который он содержит: "asInvoker" -
и означает в основном - загружать ли ваше приложение с наименьшим количеством возможных привелегий (его фактически
назвали когда-то leastPrivelege - если не изменяет память).
Т.е., если ваши пользователи не щелкают правой кнопкой мыши на вашем приложении, выбирая "Загрузить от имени
Администратора", или создавая ярлык вашего приложения, который позволяет Vista всегда запускать его от имени
Администратора, то ваше приложение предполагает быть очень ограниченным в том, что оно может сделать в Vista.
Фактически это вроде бы и хорошо, но... чуть больше об этом - через мгновение.
Ведь по большей части именно это и становится реальным геммороем и одной из главных жалоб, одинаковых и от
разработчиков и от пользователей в Vista.
* Так мы можем Изменить manifest?
Да, конечно же, ведь Microsoft встроил в Visual Foxpro Project Info или через диалоги Project Build возможность
изменения этих настроек уровня выполнения, ведь так?
Нет. Не так. До самой последней Беты SP2 я так и не увидел ничего подобного. А теперь это им уже и не обязательно,
тем более, что они забросили нас (хотя соглашусь, что неплохо было бы иметь такую настройку). Вероятная причина,
по которой они не сделали этого, состоит в том, что Microsoft постановил, что Сертификат для Windows Vista требует,
чтобы приложения были помечены asInvoker. Если вы должны выполнить задачи, которые требуют более высокого уровня
привелегий, то вам необходимо запросить эти привелегии - как в примерах класса по установке разрешений VFP COM
сервера, который вы создавали. Более подробно о требованиях для UAC, можно прочитать в документе Word, загружаемом
с Microsoft.com:
download.microsoft.com
Ну так что же, означает ли все это, что мы никак не можем поднять уровень выполнения, изменяя manifest? Нет.
Вы все-таки можете сделать это. Только это не тот способ, которым Microsoft хочет, чтобы вы делали это, и даже
не молитесь о получении одной из тех миленьких Эмблем Vista для вашего приложения, если поступите так.
Да и вообще не молитесь об этом, если только вы не один из тех немногих счастливчиков, которым предоставляется
специальное исключение от Microsoft, потому что вы в состоянии обсудить с ними свой случай достаточно хорошо.
Тут я отступаю...
Если же вы решите изменить уровень, тогда у вас есть две возможности: highestAvailable и requireAdministrator.
Но проблема состоит в том, что, даже если вы знаете их, в настоящее время нет никакого средства в Visual FoxPro,
чтобы изменить их. Давайте рассмотрим решение, которое исследовал Кэлвин Хсиа (Calvin Hsia) в одной из записей
своего блога:
[url]http://blogs.msdn.com/b/calvin_hsia/archive/2007/04/13/add-a-manifest-to-control-your-application-vista-uac-behavior.aspx[/url]
* Изменение манифеста
Если бы вы почитали блог Кэлвина, то отметили бы, что между прочим он в основном использует вызов UpdateResource
API и делает какие-то странные махинации с концом манифеста FoxPro. UpdateResource API как раз и делает то, что и
подразумевает ее имя. Она обновляет ресурс в файле PE, а так как манифест - ресурс в приложении Visual FoxPro 9.0,
то все это вполне может использоваться, чтобы обновить манифест.
Только что же такое проделывает Кэлвин, когда идет до конца файла, выделяя пары 14-байтовых структур?
Хорошо, что рядом Bo Durban, и я могу сделать вывод, что те две структуры в конце файла PE Visual FoxPro используются
для указания на компиляцию приложения VFP и некоторую информацию typelib/registration в пределах выполнения.
Вы, возможно, слышали когда-то, что VFP PE отличается от нормального PE тем, что в нем реально выполняется
только рантайм библиотека VFP, которая и загружает внутренние FXP или APP.
Так что похоже есть некоторая правда в данном коде Кэлвина. В любом случае, он разбирает на составляющие собственно
материал VFP, чтобы защитить его, затем когда UpdateResource произведен, завершая свой замысел, он возвращает их
назад (хотя я полагаю, он делает маленькую ошибку, откладывая материал назад). Довольно гладко, не так ли?
Так, при использовании техники, которую обрисовывал в общих чертах Кэлвин, мы можем заменить манифест в приложении
Visual FoxPro, и таким образом изменить способ, которым наше приложение ведет себя под UAC в Vista.
Эта техника работает и на VFP9 SP1, так же как на SP2, и в этом смысле все работало бы и на предыдущих версиях
Visual FoxPro также, но все же лучше, если вы модернизируетесь до VFP9 и тогда отправитесь вместе с нами в эту
поездку.
[attachment 12122 staiya_3_pic.jpg]
Выше (слева-направо):
1) Скриншот PE-файла Visual FoxPro на Vista Ultimate с уровнем выполнения, помеченным как "asInvoker".
2) Скриншот PE-файла Visual FoxPro на Vista Ultimate с уровнем выполнения, помеченным как "requireAdministrator"
путем модификации манифеста, вложенного в exe. Обратите внимание на "значок щита", который Vista добавляет к
значку exe, чтобы обозначить, что он требует администраторских привелегий.
3) Автоматический диалог, который Vista Ultimate показывает, когда exe отмечен с "requireAdministrator"
уровнем выполнения. Пользователю больше не нужно щелкать правой кнопкой мыши на exe, чтобы загружать его от имени
Администратора. Повышенные разрешения будут затребованы, как только exe начнет выполняться.
* Reg-Free COM
В дополнение к изменению уровня выполнения вашего приложения на Vista UAC Вы можете также использовать эту
технику, чтобы облегчить Reg-free COM в Windows XP и Vista. Reg-free COM разработан, чтобы облегчить DLL-Hell
определенных версий и выполнение на местах. Кроме того, если вы собираетесь использовать развертывание
ClickOnce в будущем, это поможет, так как ClickOnce не регистрирует компоненты COM. Об этом я буду говорить
на сессии по ClickOnce на Southwest Fox в этом году:
www.sweetpotatosoftware.com
Я был бы более, чем счастлив, более подробно побеседовать некоторое время с любым, кто изучает этот материал,
(блог не всегда способствует этому в должной мере), так, если вы предполагаете быть свободны 18-ого октября,
заскакивайте и регистрируйтесь на конференции:
www.sweetpotatosoftware.com
и я рад буду видеть вас там.
Так вот, как я и говорил прежде, бесстыдно заявляя о "супер-удивительном, которое не будет пропущено" на
конференции Southwest Fox, мы можем фактически использовать манифест приложения для размещения в наших приложениях
Visual FoxPro информации, которую обычно необходимо прописывать в реестр, регистрируя наши компоненты COM
через regsvr32. На что это похоже? Ну, точно так же, как проблемы безопасности были решены, добавлением узла
"trustInfo", Reg-free материал COM становится возможным, добавлением узла "file".
Давайте посмотрим, на что это похоже...
<file name="regfree.dll">
<comClass description="regfree.adder"
clsid="{99A4ADD8-5A6A-40C1-89FF-50B5E8267B69}"
progid="regfree.adder"
threadingModel="Both"/>
</file>
Как Вы можете видеть, в этом XML есть признак имени узла файла, в данном случае это "regfree.dll", в котором
есть вложенный (дочерний) узел, названный comClass, где находятся описание (description), clsid, progid, и
информация threadingModel для класса OLEPublic. Это - все, что есть там. Так что, когда все это добавляется к
предыдущим модификациям безопасности, вы должны получить манифест, который несколько походит на следующий...
<?xml version="1.0" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" type="win32" name="Microsoft.VisualFoxPro" processorArchitecture="x86"/>
<description>Visual FoxPro</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" language="*" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<file name="regfreedll.dll">
<comClass description="regfreedll.adder" clsid="{99A4ADD8-5A6A-40C1-89FF-50B5E8267B69}" progid="regfreedll.adder" threadingModel="Both"/>
</file>
</assembly>
Немного грязновато, но вы видите основную идею, а я съэкономлю сколько-то времени, не прибегая к необходимости
форматировать этот XML, который я вытащил из одного из моих VFP exe-шников. Теперь, с манифестом в приложении
мне не нужно регистрировать некую regfree.dll ни на XP, ни в Vista. Ну только, если религия запрещает пользоваться
таким, запуская непременно под Windows 2000 или Windows 98, тогда мой dll конечно придется регистрировать.
Regfree.dll содержит только один класс, класс Adder, но если бы он содержал больше, тогда я вставил бы
дополнительные comClass узлы для каждого из классов, которые использовал бы в своем Exe, а если бы у меня было
больше, чем один DLL или OCX, тогда я добавил бы больше узлов file. Таким образом, у вас и получается Reg-free COM.
* Манифест приложения Модификации Класса
Так как у нас нет способа проделать все это непосредственно в Visual FoxPro, думаю, я создам класс, чтобы было
проще обращаться со всем этим. По-видимому, класс может быть расширен в соединении с hook-ами проекта и гладким
интерфейсом, чтобы реально дать нам профессиональный способ обработки всего нужного в пределах Visual FoxPro IDE.
Кроме того, этот класс будет работать с другими Файлами PE, у него есть некоторый специфический код VFP для этого,
но он выполнится, только если файл PE, который вы изменяете, был собран в VFP.
Например, вы можете применять его для vfp9.exe, чтобы заставить всегда загружаться от имени Администратора под
Vista... Что было бы ну уже совсем против соглашения EULA, так что, пожалуйста, не делайте такого.
Заметьте, я лишь говорю: вот если бы это не было против EULA, то вы могли бы делать что-то подобное.
* Далее
В моей следующей записи в блоге я покажу вам, как управлять строковой таблицей ресурсов в Файле PE, используя
Visual FoxPro, а также покажу, как вы можете использовать новое именование повышения COM и CoGetObject, чтобы
облегчить приведенные классы, которые требуют повышенных разрешений для приложения Visual FoxPro, загруженного
asInvoker. Это позволит разработчикам Visual FoxPro запускать приложения, как это для них нужно, на Windows
Vista, и лишь повышать разрешения в меру необходимости. Давая больше совместимости с Vista и власти разработчику.
* Выше головы!
Скоро я собираюсь показать минифильтр, который я написал в C с дополнительным DLL, который я написал в C ++,
он позволит разработчикам Visual FoxPro полностью шифровать и расшифровывать данные Visual FoxPro на лету.
Он будет несколько походить на Cryptor, делая это, как я полагаю более безопасно, ну и конечно же, он будет
свободно распространяемым. После этого мы будем рассматривать использование Элементов ActiveX, таких как MSChart,
непосредственно в отчете, используя FLL, который я написал с Bo Durban, который один из моих клиентов, достаточно
хорошо относящийся к моим акциям, и затем мы создадим и ещё некоторый другой сумасшедший материал.
Но прямо сейчас я собираюсь посходить с ума некоторое время на материале Vista. У нас есть много другого материала,
чтобы покрыть в этом материале UAC прежде, чем я покажу вам все части, как они соединяются, и код, который мы
должны использовать затем.
Так что, я завершаю и предлагаю вам код прикладного класса модификатора манифеста (достаточно скопировать-
вставить его в prg, загрузить, и выбрав приложение VFP, в котором вы хотите изменить манифест - если собираетесь
добавить сервер COM, затем убедиться, что изменили путь и имя в вызове метода AddCOMModule для вашего фактического
файла).
* Модификация манифеста приложения и код примера
*!* пример использования
LOCAL loModuleResourceEditor
m.loModuleResourceEditor = CREATEOBJECT("ModuleResourceEditor")
m.loModuleResourceEditor.Module = GETFILE("EXE|DLL|OCX|CPL")
m.loModuleResourceEditor.ExecutionLevel = 3 && требование Администратора
?m.loModuleResourceEditor.AddCOMModule("D:\Documents and Settings\Craig Boyd\Desktop\RegFreeComTest\regfreedll.dll")
?m.loModuleResourceEditor.CreateNewModuleManifest()
?m.loModuleResourceEditor.ApplyNewManifest()
?m.loModuleResourceEditor.AddStringToStringTable("RegFreeDll Adder",101)
DEFINE CLASS ModuleResourceEditor AS CUSTOM
DIMENSION aCOMFiles(1) && массив, проводящий добавление COM модулей в манифест для REG-Free COM
COMFileCount = 0 && используется внутренне объявление aCOMFiles
ExecutionLevel = 1 && asInvoker по умолчанию
Module = "" && EXE/OCX/DLL/и т.п. те, чьи манифесты будут модифицированы
Manifest = "" && новый манифест
DefaultManifest = "" && манифест, используемый, если манифест не найден в модуле
LastError = 0 && номер ошибки, возвращаемый GetLastError()
*******************************
FUNCTION Init()
*******************************
this.aCOMFiles(1) = .F.
ENDFUNC
*******************************
FUNCTION AddCOMModule(tcCOMModuleName)
*******************************
IF FILE(m.tcCOMModuleName)
this.COMFileCount = this.COMFileCount + 1
DIMENSION this.aCOMFiles(this.COMFileCount)
this.aCOMFiles(this.COMFileCount) = m.tcCOMModuleName
=ASORT(This.aCOMFiles,1,-1,0,1)
RETURN .T.
ELSE
RETURN .F.
ENDIF
ENDFUNC
*******************************
FUNCTION RemoveCOMModule(tcCOMModuleName)
*******************************
LOCAL lnFoundAt
m.lnFoundAt = ASCAN(this.aCOMFiles, m.tcCOMModuleName)
IF m.lnFoundAt > 0
this.aCOMFiles(m.lnFoundAt) = .F.
ENDIF
ENDFUNC
*******************************
FUNCTION ApplyNewManifest()
*******************************
#DEFINE RT_MANIFEST 24
LOCAL hFile, lnPosition, lnSize, hModule, lcStruct, lnCounter, ;
llVFPModule, lnResult, llReturn, lcManifestXML
LOCAL ARRAY laVFPSections[2]
m.llReturn = .F.
IF !FILE(This.Module)
*!* свойства модуля не содержатся в файле или не были установлены.
RETURN m.llReturn
endif
IF Empty(This.Manifest)
*!* свойства манифеста не были установлены.
RETURN m.llReturn
endif
SET STEP ON
DECLARE INTEGER BeginUpdateResource IN WIN32API STRING, INTEGER
DECLARE INTEGER EndUpdateResource IN WIN32API INTEGER, INTEGER
DECLARE INTEGER UpdateResource IN WIN32API INTEGER, INTEGER, INTEGER, INTEGER, STRING @, INTEGER
DECLARE INTEGER GetLastError IN WIN32API
m.llVFPModule = .T. && принять этот модуль как VFPModule
*!* защищенная часть APP и инфа Typelib/Registration
m.hFile = FOPEN(This.Module)
m.lnPosition = FSEEK(m.hFile,0,2) && Go EOF and Get Size
FOR m.lnCounter = 1 TO 2
=FSEEK(m.hFile, m.lnPosition - 14, 0)
m.lcStruct = FREAD(m.hFile, 14)
m.lnSize = CTOBIN(SUBSTR(m.lcStruct, 11, 4), "4sr") && последние 4 байта содержат размер
IF m.lnSize > m.lnPosition OR m.lnSize < 0 OR (m.lnCounter = 1 AND m.lnSize = 0)
m.llVFPModule = .F.
EXIT
ENDIF
IF m.lnSize != 0
=FSEEK(m.hFile, m.lnPosition - m.lnSize, 0)
m.laVFPSections[m.lnCounter] = FREAD(m.hFile, m.lnSize)
IF m.lnCounter = 1 AND LEFT(m.laVFPSections[1],3) != 0hFEF2FF
m.llVFPModule = .F.
EXIT
ENDIF
ELSE
m.laVFPSections[m.lnCounter] = m.lcStruct
ENDIF
m.lnPosition = m.lnPosition - m.lnSize
ENDFOR
=FCLOSE(m.hFile)
*!* обновление манифеста в модуле
m.hModule = BeginUpdateResource(This.Module, 0)
m.lcManifestXML = This.Manifest
m.lnResult = UpdateResource(m.hModule, RT_MANIFEST, 1, 1033, @m.lcManifestXML, LEN(m.lcManifestXML))
IF EndUpdateResource(m.hModule, 0) = 0
this.LastError = TRANSFORM(GetLastError())
ELSE
m.llReturn = .T.
ENDIF
IF m.llVFPModule
*!* восстановлдение части APP и Typelib
m.hFile = FOPEN(This.Module, 2)
m.lnPosition = FSEEK(m.hFile, 0, 2)
FOR m.lnCounter = 2 TO 1 STEP -1
=FWRITE(m.hFile, m.laVFPSections[m.lnCounter])
ENDFOR
=FCLOSE(m.hFile)
ENDIF
RETURN m.llReturn
ENDFUNC
***********************
FUNCTION AddStringToStringTable(tcString, tnStringIndex) && проход -1 для tnStringIndex добавить в конец строковой таблицы
***********************
#DEFINE RT_STRING 6
LOCAL hFile, lnPosition, lnSize, hModule, lcStruct, ;
lnCounter, llVFPModule, lnResult, lnReturn, lcBaseStringTable, lcNewStringTable
LOCAL ARRAY laVFPSections[2]
m.lnReturn = -1
IF !FILE(This.Module)
*!* свойства модуля не появились в файле или не были установлены.
RETURN m.lnReturn
endif
IF Empty(m.tcString)
*!* параметры не были установлены.
RETURN m.lnReturn
endif
DECLARE INTEGER BeginUpdateResource IN WIN32API STRING, INTEGER
DECLARE INTEGER EndUpdateResource IN WIN32API INTEGER, INTEGER
DECLARE INTEGER UpdateResource IN WIN32API INTEGER, INTEGER, INTEGER, INTEGER, STRING @, INTEGER
DECLARE INTEGER GetLastError IN WIN32API
m.llVFPModule = .T. && принять этот модуль как VFPModule
*!* защищенная часть APP и Typelib
m.hFile = FOPEN(This.Module)
m.lnPosition = FSEEK(m.hFile,0,2) && Go EOF and Get Size
FOR m.lnCounter = 1 TO 2
=FSEEK(m.hFile, m.lnPosition - 14, 0)
m.lcStruct = FREAD(m.hFile, 14)
m.lnSize = CTOBIN(SUBSTR(m.lcStruct, 11, 4), "4sr") && последние 4 байта содержат размер
IF m.lnSize > m.lnPosition OR m.lnSize < 0 OR (m.lnCounter = 1 AND m.lnSize = 0)
m.llVFPModule = .F.
EXIT
ENDIF
IF m.lnSize != 0
=FSEEK(m.hFile, m.lnPosition - m.lnSize, 0)
m.laVFPSections[m.lnCounter] = FREAD(m.hFile, m.lnSize)
IF m.lnCounter = 1 AND LEFT(m.laVFPSections[1],3) != 0hFEF2FF
m.llVFPModule = .F.
EXIT
ENDIF
ELSE
m.laVFPSections[m.lnCounter] = m.lcStruct
ENDIF
m.lnPosition = m.lnPosition - m.lnSize
ENDFOR
=FCLOSE(m.hFile)
SET STEP ON
m.lcBaseStringTable = This.GetStringResource(1, RT_STRING)
m.lnLastStringIndex = This.GetStringTableCount(m.lcBaseStringTable)
DO case
CASE m.tnStringIndex < 0
m.tcString = This.GetFormattedStringForStringTable(m.tcString)
m.lcNewStringTable = m.lcBaseStringTable + m.tcString
CASE m.tnStringIndex > m.lnLastStringIndex
m.tcString = This.GetFormattedStringForStringTable(m.tcString)
m.lcNewStringTable = m.lcBaseStringTable + REPLICATE(0h0000, m.tnStringIndex - m.lnLastStringIndex) + m.tcString
OTHERWISE
m.lcNewStringTable = This.ReplaceStringTableString(m.lcBaseStringTable, m.tnStringIndex, m.tcString)
ENDCASE
*!* обновить строковую таблицу в модуле
m.hModule = BeginUpdateResource(This.Module, 0)
m.lnResult = UpdateResource(m.hModule, RT_STRING, 1, 1033, @m.lcNewStringTable, LEN(m.lcNewStringTable))
IF EndUpdateResource(m.hModule, 0) = 0
this.LastError = TRANSFORM(GetLastError())
ELSE
m.lnReturn = IIF(m.tnStringIndex < 0, m.lnLastStringIndex + 1, m.tnStringIndex)
ENDIF
IF m.llVFPModule
*!* восстановить часть APP и Typelib
m.hFile = FOPEN(This.Module, 2)
m.lnPosition = FSEEK(m.hFile, 0, 2)
FOR m.lnCounter = 2 TO 1 STEP -1
=FWRITE(m.hFile, m.laVFPSections[m.lnCounter])
ENDFOR
=FCLOSE(m.hFile)
ENDIF
RETURN m.lnReturn
ENDFUNC
***********************
FUNCTION CreateNewModuleManifest()
***********************
#DEFINE RT_MANIFEST 24
LOCAL lcBaseManifest, lcLevelXML, lcModuleName, lnCounter, ;
lcProgID, lcNameSpace, lcFileXML, lccomClassXML, lnClassCounter, ;
loDOM AS MSXML2.DOMDocument, loParentNode AS MSXML2.IXMLDOMELEMENT, ;
loNode AS MSXML2.IXMLDOMELEMENT, loNewLevelNode AS MSXML2.IXMLDOMELEMENT, ;
loTempNode AS MSXML2.IXMLDOMELEMENT, loTypeLib AS TLI.TypeLibInfo
IF !FILE(This.Module)
*!* свойства модуля не появились в файле или не были установлены.
RETURN .F.
ENDIF
This.Manifest = ""
*!* взять манифест из модуля или создать один
m.lcBaseManifest = This.GetStringResource(1, RT_MANIFEST)
IF EMPTY(m.lcBaseManifest)
IF EMPTY(this.DefaultManifest)
m.lcBaseManifest = This.GetDefaultManifest()
ELSE
m.lcBaseManifest = this.DefaultManifest
ENDIF
ENDIF
m.loDOM = CREATEOBJECT("MSXML2.DOMDocument.4.0")
IF m.loDOM.LOADXML(m.lcBaseManifest)
m.lcNameSpace = m.loDOM.firstChild.NEXTSIBLING.getAttribute("xmlns")
*!* добавить или заменить уровень выполнения
IF TYPE("This.ExecutionLevel") = "N"
m.loNode = m.loDOM.selectSingleNode('//*[local-name()="trustInfo"]')
IF !ISNULL(m.loNode)
m.loParentNode = m.loNode.parentNode
m.loParentNode.removeChild(m.loNode)
ENDIF
m.lcLevelXML = This.GetExecutionLevelXML()
m.loNewLevelNode = This.GetNodeFromXML(m.lcLevelXML, m.lcNameSpace)
IF !ISNULL(m.loNewLevelNode)
m.loDOM.selectSingleNode('//*[local-name()="assembly"]').appendChild(m.loNewLevelNode)
ENDIF
ENDIF
m.loDOM.setProperty("SelectionNamespaces", "xmlns:pe='" + m.lcNameSpace + "'")
*!* добавить или заменить Reg-Free COM
IF TYPE("This.aCOMFiles",1) = "A"
m.loTypeLib = CREATEOBJECT("TLI.TypeLibInfo")
IF TYPE("m.loTypeLib") = "O"
FOR m.lnCounter = 1 TO ALEN(This.aCOMFiles,1)
IF TYPE("This.aCOMFiles(m.lnCounter)") = "C" AND FILE(This.aCOMFiles(m.lnCounter))
m.loTypeLib.ContainingFile = This.aCOMFiles(m.lnCounter)
FOR m.lnClassCounter = 1 TO m.loTypeLib.TypeInfoCount
m.loTypeInfo = m.loTypeLib.TypeInfos(m.lnClassCounter)
IF m.loTypeInfo.TypeKind = 5
m.lcModuleName = JUSTFNAME(m.loTypeLib.ContainingFile)
m.lcProgID = m.loTypeLib.NAME + "." + m.loTypeLib.TypeInfos(m.lnClassCounter).NAME
m.loNode = m.loDOM.selectSingleNode('//*[local-name()="file"][translate(@name,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")="' + LOWER(m.lcModuleName) + '"]')
IF ISNULL(m.loNode)
m.lcFileXML = This.GetCOMFileXML(m.lcModuleName)
m.loNewLevelNode = This.GetNodeFromXML(m.lcFileXML, m.lcNameSpace)
IF !ISNULL(m.loNewLevelNode)
m.loNode = m.loDOM.selectSingleNode('//*[local-name()="assembly"]').appendChild(m.loNewLevelNode)
ENDIF
ELSE
FOR EACH loTempNode IN m.loNode.childNodes
IF m.loTempNode.nodeName = "comClass"
IF LOWER(m.loTempNode.getAttribute("progid")) = LOWER(m.lcProgID)
m.loTempNode.parentNode.removeChild(m.loTempNode)
EXIT
ENDIF
ENDIF
NEXT
ENDIF
m.lccomClassXML = This.GetcomClassXML(m.lcModuleName, m.lcProgID, m.loTypeInfo.GUID, m.loTypeInfo.HELPSTRING)
m.loNewLevelNode = This.GetNodeFromXML(m.lccomClassXML, m.lcNameSpace)
IF !ISNULL(m.loNewLevelNode)
m.loNode.appendChild(m.loNewLevelNode)
ENDIF
ENDIF
ENDFOR
ENDIF
ENDFOR
ENDIF
ENDIF
This.Manifest = m.loDOM.XML
ENDIF
RETURN .T.
ENDFUNC
***********************
FUNCTION GetDefaultManifest()
***********************
LOCAL lcReturn
TEXT TO m.lcReturn textmerge noshow
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
type="win32"
name="<<tcModuleName>>"
processorArchitecture="x86"/>
<description><<tcModuleName>></description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
language="*"
processorArchitecture="x86"
publicKeyToken="6595b64144ccf1df"/>
</dependentAssembly>
</dependency>
</assembly>
ENDTEXT
RETURN m.lcReturn
ENDFUNC
***********************
FUNCTION GetStringTableCount(tcStringTable)
***********************
LOCAL lnReturn, lnCounter, lnStringSize
m.lnReturn = 0
FOR m.lnCounter = 1 TO LEN(m.tcStringTable) STEP 2
m.lnStringSize = CTOBIN(SUBSTR(m.tcStringTable,m.lnCounter,2),"2RS") * 2
m.lnReturn = m.lnReturn + 1
m.lnCounter = m.lnCounter + m.lnStringSize
ENDFOR
RETURN m.lnReturn
ENDFUNC
***********************
FUNCTION GetStringTableString(tcStringTable, tnIndex)
***********************
LOCAL lnIndex, lnCounter, lnStringSize, lcReturn
m.lnIndex = 0
m.lcReturn = ""
FOR m.lnCounter = 1 TO LEN(tcStringTable) STEP 2
m.lnStringSize = CTOBIN(SUBSTR(tcStringTable,m.lnCounter,2),"2RS") * 2
m.lnIndex = m.lnIndex + 1
IF m.lnIndex = m.tnIndex
m.lcReturn = STRCONV(SUBSTR(m.tcStringTable, m.lnCounter + 2, m.lnStringSize),6)
EXIT
ENDIF
m.lnCounter = m.lnCounter + m.lnStringSize
ENDFOR
RETURN m.lcReturn
ENDFUNC
***********************
FUNCTION GetFormattedStringForStringTable(tcString)
***********************
LOCAL lcReturn, lnLen
m.lnLen = LEN(m.tcString)
m.lcReturn = BINTOC(m.lnLen,"2RS") + STRCONV(m.tcString,5) && + IIF(MOD(m.lnLen,2) = 1,0h0000,"")
RETURN m.lcReturn
ENDFUNC
***********************
FUNCTION ReplaceStringTableString(tcStringTable, tnIndex, tcReplacementString)
***********************
LOCAL lnIndex, lnCounter, lnStringSize, lcReturn
m.lnIndex = 0
m.lcReturn = ""
m.tnIndex = m.tnIndex + 1
FOR m.lnCounter = 1 TO LEN(tcStringTable) STEP 2
m.lnStringSize = CTOBIN(SUBSTR(tcStringTable,m.lnCounter,2),"2RS") * 2
m.lnIndex = m.lnIndex + 1
IF m.lnIndex = m.tnIndex
m.lcReturn = STUFF(m.tcStringTable, m.lnCounter, m.lnStringSize + 2, This.GetFormattedStringForStringTable(tcReplacementString))
EXIT
ENDIF
m.lnCounter = m.lnCounter + m.lnStringSize
ENDFOR
RETURN m.lcReturn
ENDFUNC
***********************
FUNCTION GetStringResource(tnName, tnType)
***********************
LOCAL lcModule, hModule, lcReturn, lnResource, lnSize, hGlobal
DECLARE LONG LoadLibrary IN WIN32API STRING
DECLARE LONG FindResource IN WIN32API LONG, LONG, LONG
DECLARE LONG LoadResource IN WIN32API LONG, LONG
*!* DECLARE LONG LockResource IN WIN32API LONG
DECLARE LONG SizeofResource IN WIN32API LONG, LONG
DECLARE LONG FreeLibrary IN WIN32API LONG
DECLARE LONG FreeResource IN WIN32API LONG
m.hModule = LoadLibrary(This.Module)
m.lnResource = FindResource(m.hModule, tnName, tnType)
m.hGlobal = LoadResource(m.hModule, m.lnResource)
m.lnSize = SizeofResource(m.hModule, m.lnResource)
*!* LockResource(m.lnMem)
m.lcReturn = SYS(2600, m.hGlobal, m.lnSize)
FreeResource(m.hGlobal)
FreeLibrary(m.hModule)
RETURN m.lcReturn
ENDFUNC
***********************
FUNCTION GetNodeFromXML(tcXML, tcNameSpace)
***********************
LOCAL loDOMTemp AS MSXML2.DOMDocument, loNode AS MSXML2.IXMLDOMELEMENT
m.loNode = NULL
m.loDOMTemp = CREATEOBJECT("MSXML2.DOMDocument.4.0")
IF m.loDOMTemp.LOADXML([<dummy xmlns="] + m.tcNameSpace + [">] + m.tcXML + [</dummy>])
m.loNode = m.loDOMTemp.firstChild.firstChild
ENDIF
RETURN m.loNode
ENDFUNC
*****************************
FUNCTION GetExecutionLevelXML()
*****************************
*!*
*!* This.ExecutionLevel = 1 - asInvoker, 2 - highestAvailable, 3 - requireAdministrator
*!*
*!* asInvoker — модуль выполняется с теми же разрешенийми, что и его родительский процесс (прежде известный как leastPrivilege)
*!* highestAvailable — модуль выполняет с самыми высокими привилегиями, которые может получить текущий пользователь
*!* requireAdministrator — модуль выполняется только для администраторов (включается оверлей щита для символа модуля)
*!*
*****************************
LOCAL lcLevel, lcReturn
m.lcLevel = ICASE(This.ExecutionLevel = 2, "highestAvailable", This.ExecutionLevel = 3, "requireAdministrator", "asInvoker")
TEXT TO m.lcReturn TEXTMERGE NOSHOW
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="<<m.lcLevel>>" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
ENDTEXT
RETURN m.lcReturn
ENDFUNC
*****************************
FUNCTION GetCOMFileXML(tcModuleName)
*****************************
LOCAL lcReturn
TEXT TO m.lcReturn TEXTMERGE NOSHOW
<file name="<<LOWER(JUSTFNAME(tcModuleName))>>">
</file>
ENDTEXT
RETURN m.lcReturn
ENDFUNC
*****************************
FUNCTION GetcomClassXML(tcModuleName, tcProgID, tcCLSID, tcDescription)
*****************************
LOCAL lcReturn && tcCLSID
*!* m.lcCLSID = CLSIDFromProgIDEx(m.tcProgID)
IF PCOUNT() < 4
m.tcDescription = m.tcProgID
ENDIF
TEXT TO m.lcReturn TEXTMERGE NOSHOW
<comClass description="<<m.tcDescription>>"
clsid="<<m.tcCLSID>>"
progid="<<m.tcProgID>>"
threadingModel="Both"/>
ENDTEXT
RETURN m.lcReturn
ENDFUNC
*****************************
FUNCTION GetLastErrorMessage(tnError)
*****************************
#DEFINE FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
LOCAL lcBuffer
DECLARE INTEGER GetLastError IN win32api
DECLARE INTEGER FormatMessage IN kernel32.DLL ;
INTEGER dwFlags, ;
STRING @lpSource, ;
INTEGER dwMessageId, ;
INTEGER dwLanguageId, ;
STRING @lpBuffer, ;
INTEGER nSize, ;
INTEGER Arguments
m.lcBuffer = SPACE(128)
=FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 'WINERROR.H', m.tnError, 0, @m.lcBuffer, 128 , 0)
RETURN m.lcBuffer
ENDFUNC
ENDDEFINE


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)




Исправлено 1 раз(а). Последнее : Crispy, 27.05.11 16:01
Ratings: 0 negative/1 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Crispy
Автор

Сообщений: 18571
Дата регистрации: 16.05.2005
* Статья с блога Крейга Бойда. (в моем переводе)
* 3 августа 2009 г.
* www.sweetpotatosoftware.com
*
* Применение манифеста приложения во время компиляции с Projecthook
* Некоторое время назад...
Я сделал запись в блоге "Файлы PE, UAC, Reg-без COM, и Другой Сумасшедший Материал - Часть 2", в которой говорилось,
как детально рассмотреть и отредактировать манифест, вставленный в скомпилированные модули VFP.
Я также не торопясь объяснял, почему кто-то будет хотеть сделать такую вещь. Главные две причины, по которым
большинство разработчиков VFP захочет это сделать:
- повышение уровня разрешений под Контролем за Учетной записью пользователя Windows (UAC), и
- возможность загружать Reg-Free COM (в частности использование OCX без регистрации в реестре - прим.пер.).
Я предполагаю, что может также возникать потребность редактировать или добавлять последовательности в ресурс
строковой таблицы файла PE (ну это для меньшинства разработчиков VFP), что также предусмотрено.
В то время как код и понятия, детализированные в той предыдущей записи в блоге, были продвинуты и довольно-таки
прилично (раз уж я действительно выступаю так самостоятельно), кто-то пострадал от ряда ошибок, и большинство
разработчиков VFP, вероятно, сочло это более, чем трудоемким в осуществлении "из коробки" тех своих проектов, что
нуждались в повышенных разрешениях UAC или в Reg-free COM.
Я попытаюсь сделать вещи немного более прямыми и без ошибок в этой новой записи в блоге.
* Введение в Класс ProjectHook
Есть много подробной информации о классе ProjectHook-онлайн, в том числе и в справочном файле VFP 9.0 SP2 (скачайте
последний самый подробный справочный файл на VFPX), поэтому я не буду здесь входить в большое количество деталей.
Я просто укажу легкий способ применить новый манифест к выполнимому VFP-файлу после того, как создан проект.
Класс ProjectHook обеспечивает случай BeforeBuild, где я могу получить полный путь EXE, который будет построен, и
случай AfterBuild, который позволяет мне немедленно выполнить операции после того, как EXE построен. Так этот класс
обеспечил в точности все, в чем я нуждался, и сделал испльзование измененного манифеста легким и приятным.
* Как Использовать ProjectHookEx.vcx
Чтобы использовать projecthookex.vcx (скачать его можно внизу этой записи в блоге), вы просто должны распаковать
и скопировать его куда-нибудь, и затем открыть один из своих проектов и войти в диалог Project Info (доступно по
правому клику мыши на проекте или в разделе Project в системном меню) и установить свойства Project Class как
показано на следующем скрин-шоте...
[attachment 12123 addprojecthook.jpg]
...затем просто нажмите OK, выйдите из своего проекта и вновь откройте его. Класс projecthook не отображается, пока
вы вновь не открываете проект после установки свойства Project Class.
Настройки по умолчанию для hookex класса установлены так, чтобы манифест по умолчанию для VFP 9.0 SP2, в котором
trustinfo установлен в asInvoker, был изменен на requireAdministrator. Посмотрите в событии AfterBuild hookex-а
код, который выполняет это (короткий и приятный). Вы увидете пару прокомментированных строк кода в AfterBuild,
которые показывают, как получить Reg-Free COM, и также отредактровать строки таблицы ресурсов. В любом случае,
как только Project Class установлен для вашего проекта, hookex будет иллюстрироваться примерами и готов работать
в любое время, пока вы открываете и разрабатываете свой проект. Когда манифест будет применен, он начнет
отображаться на экране, таким образом, вы можете видеть его, с гарантией, что он был применен (вы можете отключить
это, если пожелаете, изменяя в редакторе классов showmanifestafterapplying).
* Кому-то Внешние Манифесты?
Те из вас, кто предпочитает использовать внешние манифесты для своих исполняемых файлов, могут получить их,
изменив в редакторе классов свойство externalmanifest. Крутизна этого состоит в том, что файл myproj.exe.manifest
создается в той же самой директории, что и ваши выполнимые файлы, при этом внутренний манифест в них удаляется,
чтобы препятствовать его вмешательству в ваш внешний манифест. Теперь вы можете редактировать внешний манифест,
используя свой любимый XML-редактор или даже блокнот. Это было одним из усовершенствований, добавленных к тому,
чего нет в коде, который я поместил в оригинальной записи в блоге касательно манифестов собранных приложений PE.
* Что Дальше
Много усовершенствований и улучшений (например автоматический поиск проектом всех компонентов COM, автоматически
добавляющий их к манифест), который может быть приделан к этому классу, и я надеюсь, что мои читатели внесут свои
предложения и даже попробуют свои силы в написании кода.
Тут www.sweetpotatosoftware.com есть серия хороших использований класса ProjectHook VFP.
Я хотел бы получать известия от вас, в чем вы чувствуете потребности, что могло бы помочь улучшить класс ProjectHook.
Но я буду рад даже если вы всего лишь прочитаете все это, загрузите библиотеку классов и будете использовать ее.
До следующего раза... VFP - это скалы!
Скачать последнюю версию библиотеки классов ProjectHookEx (12 КБ приблизительно):
www.sweetpotatosoftware.com


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)




Исправлено 1 раз(а). Последнее : Crispy, 27.05.11 16:02
Ratings: 0 negative/1 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
Сложить бы это в архивчик и в файловый архив.


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Да с форматированием оформить
Кстати, в ряде случаев число неPE-ных секций фоксового exe-ника может быть и больше 2-х (часть анти-рефоксовских средств плодят эти самые секции), так что код Кэлвина, на который ссылается Крейг, всё-же более точный.
P.S. Надеюсь у автора было получено разрешение на публикацию перевода
P.P.S. Про Reg-Free COM действительно была тема, я помню давал ссылку на статью (но не применительно к фоксу, а так сказать "вообще") и приводил некоторые комментарии к этому механизму.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Pliskin

Сообщений: 2959
Откуда: Новосибирск
Дата регистрации: 19.11.2003
Спасибо!
Полезная инфа!
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
ssa
Сложить бы это в архивчик и в файловый архив.
А мне кажется, этому место в статьях.
В любом другом месте, будет трудно найти, да и по духу, она туда просится.


------------------
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Crispy
Автор

Сообщений: 18571
Дата регистрации: 16.05.2005
Igor Korolyov
P.P.S. Про Reg-Free COM действительно была тема, я помню давал ссылку на статью (но не применительно к фоксу, а так сказать "вообще") и приводил некоторые комментарии к этому механизму.

Кстати действительно забыл упомянуть, что благодаря именно твоему совету о Reg-Free COM при обсуждении AdobeFlash OCX в одном из форумов forum.foxclub.ru как раз-таки и вышел на топик Пивы в курилке forum.foxclub.ru откуда уже и попал на эту самую статью - по ссылке от Ромы.
Так что теперь историческая справедливость уже в точности соблюдена. (плюс не лишние все-таки тут ссылки)

Igor Korolyov
P.S. Надеюсь у автора было получено разрешение на публикацию перевода

Да вроде статья в открытом доступе, и как бы даже без оговорок на запреты по цитированию. Тем более, что все ссылки полностью выдержаны, причем во всех заголовках есть примечания, что данный вариант изложения всего того, что там помимо кода, и следует как бы понимать лишь как вариант перевода. Естественно не претендующего на абсолют.
Да и насколько я понял и по всему стилю изложения и по ряду фраз и пунктов, автор - явно наш человек, т.е. не какого-то там мелкого микро-софта/порядочности, а самого что ни на есть крупного - фокспрошного.
Впрочем можно конечно же и написать ему письмо с вопросом (да вот вечером и напишу из дома, а то тут попытался, но проблемы с ящиком). Хотя, исходя из вышеизложенного, не думаю, чтобы он как-то особо возражал, разве что возможно не сразу сможет ответить.


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
NMA

Сообщений: 164
Дата регистрации: 20.02.2006
Больше переводов: хороших и разных.

Журнал FoxTalk (русское издание) в апреле 2010 года начал публикацию статьи
"PE-файлы, контроль учетных записей (UAC),COM без регистрации и другие невероятные вещи"
по материалам блога Крега Бойда (Craig Boyd), которую благополучно завершил в августе этого же года. Там же, кстати, публиковалось и решение Кэлвина Ся.

newsletter.narod.ru



Исправлено 1 раз(а). Последнее : NMA, 30.05.11 13:58
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Crispy
Автор

Сообщений: 18571
Дата регистрации: 16.05.2005
NMA
Больше переводов: хороших и разных.

Так что, не надо было ничего делать?


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)
Ratings: 0 negative/1 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
NMA

Сообщений: 164
Дата регистрации: 20.02.2006
Crispy
NMA
Больше переводов: хороших и разных.

Так что, не надо было ничего делать?

Делайте, конечно, кто ж запретит.
Просто к сведению, что этот материал можно было прочитать по-русски еще в прошлом году - есть профильный журнал.




Исправлено 1 раз(а). Последнее : NMA, 30.05.11 16:08
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
MichaelD

Сообщений: 7578
Дата регистрации: 14.05.2005
Э... если правильно понимаю,

В файле с расширением .manifest в xml формате лежит информация того, что обычно представляет собой .tlb, что в свою очередь, позволяет создавать классы из dll-сборок как бы "налету" (минуя механизм использования реестра, как основного носителя информации о COM-интерфейсе компоненты)?

Если так, то это здорово конечно
- описание интефейса всегда ношу с собой в виде manifest-файла (возможно встроенного в сам исполнимый модуль)
- используем спец-загрузчик, позволяющий создавать объекты (подобный CoCreateInstance API и по CLSID по данным из реестра для зарегистрированной COM-компоненте)...

Если так, то ну да

- способ "слегка обновлён"
- "явной регистрации" в реестр для компоненты не требуется, ибо может поднимать аналог ITypeLib-а из манифеста непосредственно...

... Т.е. получается какой-то "маркетинговый шум" "из ничего", как мне представляется... Или заблуждаюсь? ;)


------------------
С уважением,
Михаил Дроздов, Пермь, Россия
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Михаил, это просто одно из "улучшений" WinXP - там реально АПИ "классовой работы" изменён, чтобы учитывать манифесты - это полезно не только в плане "всё своё ношу с собой", но и в плане Side-by-Side - т.е. когда конфликтуют программы требующие разных версий одной и той-же компоненты.
Изменён только загрузчик, сам TypeLib этим способом не заменятся...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Crispy
Автор

Сообщений: 18571
Дата регистрации: 16.05.2005
NMA
Журнал FoxTalk (русское издание) в апреле 2010 года начал публикацию статьи
"PE-файлы, контроль учетных записей (UAC),COM без регистрации и другие невероятные вещи"
по материалам блога Крега Бойда (Craig Boyd), которую благополучно завершил в августе этого же года. Там же, кстати, публиковалось и решение Кэлвина Ся.

newsletter.narod.ru

NMA
Просто к сведению, что этот материал можно было прочитать по-русски еще в прошлом году - есть профильный журнал.

Что-то не понял, где же там сами переводы-то по этой приведенной ссылке. Ничего кроме анонсов. Конкретную ссылку тогда уж неплохо бы куда-то в более реальное место. Какие-то коды в архиве "для всех статей кроме Крег Бойд" конечно любопытно, только они похоже из несколько другой оперы. А английский текст от MS про UAC тоже как бы не особо в айс. В статье Крейга ссылка на него и так была.
Первая часть архива у них куда-то улетела напрочь (выброс на 404 страницу). А вторая часть содержит только две версии неплохой конечно утилитки ResourceHacker, но которые у меня в принципе и без того давно уже есть.


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
NMA

Сообщений: 164
Дата регистрации: 20.02.2006
Crispy
Что-то не понял, где же там сами переводы-то по этой приведенной ссылке. Ничего кроме анонсов. Конкретную ссылку тогда уж неплохо бы куда-то в более реальное место. Какие-то коды в архиве "для всех статей кроме Крег Бойд" конечно любопытно, только они похоже из несколько другой оперы. А английский текст от MS про UAC тоже как бы не особо в айс. В статье Крейга ссылка на него и так была.
Первая часть архива у них куда-то улетела напрочь (выброс на 404 страницу). А вторая часть содержит только две версии неплохой конечно утилитки ResourceHacker, но которые у меня в принципе и без того давно уже есть.

Да, журнал, ессно, не бесплатный, чтобы его прочитать, надо на него подписаться. Это, конечно, не есть гут.
Ratings: 1 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
Crispy
Автор

Сообщений: 18571
Дата регистрации: 16.05.2005
Мда. Однако это как бы не ессно. ;) По-крайней мере для фокса. "Это не наши методы, товарищ Шурик".(с)


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)
Ratings: 0 negative/1 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
NMA

Сообщений: 164
Дата регистрации: 20.02.2006
Crispy
Мда. Однако это как бы не ессно. ;) По-крайней мере для фокса. "Это не наши методы, товарищ Шурик".(с)

Не "ессно"?! Не знаю, не знаю... давно ли Fox стал бесплатным?
Сообщество сообществом, а денежки - врозь.
Впрочем, сдаюсь. К черту платные журналы, книги, программы и т.п.!
Open source рулит! ;)
P.S. Елки, но кушать же хоцца.



Исправлено 1 раз(а). Последнее : NMA, 31.05.11 11:43
Ratings: 0 negative/0 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
alextash

Сообщений: 2281
Откуда: НСК
Дата регистрации: 03.05.2006
Fox не бесплатен, но дружеская помощь - да
Ratings: 0 negative/1 positive
Re: Повышение прав приложения при работе под Windows 7 и работа OCX без регистрации
_vit

Сообщений: 5175
Дата регистрации: 29.07.2002
Я сегодня увидел свет.

Оказывается, если в папку с проектом положить файл манифеста, то при компиляции фокс (9SP2 по крайней мере) внедряет этот манифест в генерируемый екзешник.
Так что с ProjectHookEx можно не парится.

Подробности тута www.west-wind.com
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 24 (Гостей: 24)

© 2000-2024 Fox Club 
Яндекс.Метрика