Firebird Server Client and VS CRT.

Привет всем.

Сегодня, в очередной раз помогая с устранением проблемы «[dbobj] Загрузка динамической библиотеки «fbclient.dll»», обратил внимание на одну странную несогласованность файлов из дистрибутива Firebird 2.5.2.26539 (разрядность не имеет значения):

  • fbclient.dll
  • Microsoft.VC80.CRT.manifest
  • msvcp80.dll
  • msvcr80.dll


fbclient.dll имеет внутри себя манифест вида

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

То есть он хочет работать с CRT версии 8.0.50608.0

Microsoft.VC80.CRT.manifest описывает CRT с версией 8.0.50608.0

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <noInheritable/>
    <assemblyIdentity 
        type="win32" 
        name="Microsoft.VC80.CRT" 
        version="8.0.50608.0" 
        processorArchitecture="x86" 
        publicKeyToken="1fc8b3b9a1e18e3b"
    />
    <file name="msvcr80.dll"/>
    <file name="msvcp80.dll"/>
    <file name="msvcm80.dll"/>
</assembly>

А сами файлы msvcp80.dll и msvcr80.dll имеют версию 8.0.50727.42. Внутри манифестов не обнаружено.

Взял нормальный, оригинальный 32х-битный редистр CRT с версией 8.0.50727.42. С помощью Total Commander’a, гугла, 7Zip-а и «понятно кого», вытащил из него манифест с этими двумя DLL. DLL-и с точностью до байта совпали с теми, что я взял из дистрибутива FB. Манифест выглядит так:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <noInheritable></noInheritable>
    <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.42" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    <file name="msvcr80.dll" hash="2a0d797a8c5eac76e54e98db9682e0938c614b45" hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>phRUExlAeZ8BwmlD8VlO5udAnRE=</dsig:DigestValue></asmv2:hash></file>
    <file name="msvcp80.dll" hash="cc4ca55fb6aa6b7bb8577ab4b649ab77e42f8f91" hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>7AY1JqoUvK3u/6bYWbOagGgAFbc=</dsig:DigestValue></asmv2:hash></file>
    <file name="msvcm80.dll" hash="55e8e87bbde00d1d96cc119ccd94e0c02c9a2768" hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>hWq8zazTsMeKVxWFBa6bnv4hEOw=</dsig:DigestValue></asmv2:hash></file>
</assembly>

Попутно я еще обнаружил в этом редистре такой элемент — _14242_policy_8_0_Microsoft_VC80_CRT_x86.msm. Из которого извлек следующий манифест:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <assemblyIdentity type="win32-policy" name="policy.8.0.Microsoft.VC80.CRT" version="8.0.50727.42" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
            <bindingRedirect oldVersion="8.0.41204.256-8.0.50608.0" newVersion="8.0.50727.42"/>
            
        </dependentAssembly>
    </dependency>

</assembly>

bindingRedirect, судя по смыслу, говорит что 8.0.50727.42 замещает в том числе и нашу подозрительную 8.0.50608.0.

Тут у меня закралась мысль — а что если проверить клиента с его родным CRT на голой XP? Неужели винда не увидит, что манифест для 8.0.50608.0, а сами DLL имеют версию 8.0.50727.42?

Увы — не увидела! Более того, я потом еще взял и подсунул такие же DLL от 8.0.50727.6195 — fbclient.dll переварил и их тоже. Если заменить манифест, то fbclient.dll, что ожидаемо, перестает грузиться:

[dbobj] Загрузка динамической библиотеки «e:\temp\2013_02_14\fb2\fbclient.dll».
Приложение не было запущено, поскольку оно некорректно настроено. Повторная установка приложения может решить данную проблему.
WIN32 Error: 0x36B1

А вот если установить redistr 8.0.50727.6195 нормальным образом, то fbclient.dll начинает грузиться и работать. Наверное благодаря появившемуся файлу «d:\WINDOWS\WinSxS\Policies\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773\8.0.50727.6195.policy» с таким содержимым:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <assemblyIdentity type="win32-policy" name="policy.8.0.Microsoft.VC80.CRT" version="8.0.50727.6195" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
            <bindingRedirect oldVersion="8.0.41204.256-8.0.50608.0" newVersion="8.0.50727.6195"/>
            <bindingRedirect oldVersion="8.0.50727.42-8.0.50727.6195" newVersion="8.0.50727.6195"/>
        </dependentAssembly>
    </dependency>

</assembly>

Подведем краткий итог.
1. Сервер скомпилирован для CRT 8.0.50608.0, но поставляется с 8.0.50727.42. И эта странная схема работает.
2. Вместо бинарников 8.0.50727.42 можно положить более свежую версию CRT. И это будет работать, потому что — см. пункт 1.
3. Если установить более новый редистр для VS2005 CRT (версия 8.0.50727.6195 — последняя из мне известных), то этого будет достаточно для работы официальных сборок Firebird 2.5.2 без собственной копии VS2005 CRT. Ну, по крайней мере, клиент точно работает.

Но, не смотря на все эти открытия с заменой, в клиентскую область нашего сайта я положил архивы 32х и 64х битных клиентов для Firebird 2.5.2.26539 с его родным VS CRT. Так что, если у вас есть аккаунт на сайте IBProvider-а, можно загрузить их оттуда. Помимо самих файлов серверного клиента, в архиве лежит readme.txt на изуверском английском, в котором кратно объясняется «что это и как использовать вместо с IBProvider-ом».

2 комментария

Влад  on 20 февраля, 2013

Дима, версия бинарника и версия сборки — не есть одно и то же.

Для извлечения манифестов не нужно

>>> Total Commander’a, гугла, 7Zip-а и «понятно кого» <<<

достаточно сделать RTFM и воспользоваться предназначенной для этого утилитой mt 🙂

Kovalenko  on 20 февраля, 2013

Насчет извлечения манифеста.

Мне же был нужен манифест не самого vcredist_x64.exe, а манифест (CRT) который в нем упакован.

О mt.exe я немного слышал, но сомневаюсь чтобы он мог расковыривать MSI/MSM 🙂


Насчет версии бинарника и версии сборки…

Кажется, я начинаю вьезжать. Обнаружил в VS2005 (пропатчен) такую штуку:

#ifndef _CRT_ASSEMBLY_VERSION
#if defined _USE_RTM_VERSION
#define _CRT_ASSEMBLY_VERSION «8.0.50608.0» <--- вот оно. #else #define _CRT_ASSEMBLY_VERSION "8.0.50727.6195" #endif #endif Правда вы у себя эти _CRT_ASSEMBLY_VERSION/_USE_RTM_VERSION вроде нигде не устанавливаете. Значит у вас на сборке стоит девственная 2005 студия, но которой подсунули (а может она изначально такая) бинарники CRT 8.0.50727.42.

Leave a Comment