Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π‘ΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ БОМ. Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 32

Автор Π”ΠΎΠ½Π°Π»ΡŒΠ΄ Бокс

' просим gorilla Π΅ΡΡ‚ΡŒ Π±Π°Π½Π°Π½Ρ‹

ape.EatBanana

End Sub


ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ вСрсия этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π° Visual Basic ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ интСрфСйс IApeClass для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Π­Ρ‚ΠΎ связано с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Visual Basic Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс IClassFactory ΠΈΠ·-Π·Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ языка.


ΠœΠΎΠ½ΠΈΠΊΠ΅Ρ€Ρ‹ ΠΈ композиция

ΠœΠΎΠ½ΠΈΠΊΠ΅Ρ€Ρ‹ часто ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ΡΡ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ΠΎΠ², Ρ‡Ρ‚ΠΎΠ±Ρ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ тСкстового описания ΠΏΡƒΡ‚ΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ ΠΏΠΎ иСрархиям ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΡΡ‚ΡƒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ этого Ρ‚ΠΈΠΏΠ° управлСния, Π² БОМ прСдусмотрСна стандартная рСализация ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ΠΎΠ², которая, Π±ΡƒΠ΄ΡƒΡ‡ΠΈ поставлСнной справа ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π°, Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΡΠ²ΡΠ·Π°Ρ‚ΡŒ ссылку с Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Π² ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ. Π’Π°ΠΊΠΎΠΉ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ называСтся ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ΠΎΠΌ элСмСнта (Item Moniker) ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ интСрфСйс ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° IOleItemContainer для прСобразования ΠΈΠΌΠ΅Π½ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² интСрфСйсный ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ.

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΠΎΠ΅ имя ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ элСмСнта использован Π² Ρ‚Π°Π½Π΄Π΅ΠΌΠ΅ с классовым ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ΠΎΠΌ:


clsid:571F1680-CC83-11d0-8C48-0080C73925BA:!Ursus


ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ использованиС символа "!" для отдСлСния ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ Class Moniker ΠΎΡ‚ ΠΈΠΌΠ΅Π½ΠΈ элСмСнта (item name) Β«UrsusΒ». ΠŸΡ€ΠΈ Π°Π½Π°Π»ΠΈΠ·Π΅ MkParseDisplayName сначала ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ прСфикс "clsid " Π² качСствС ProgID для ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚Π° с Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ Π‘lass Moniker. Π—Π°Ρ‚Π΅ΠΌ MkParseDisplayName ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠΈΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Class Moniker ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‡Π°ΡΡ‚ΡŒ строки – ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ, сколько ΠΎΠ½Π° смоТСт Ρ€Π°ΡΠΏΠΎΠ·Π½Π°Ρ‚ΡŒ. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π‘lass Moniker ΠΈΠ·Π²Π»Π΅ΠΊ свой GUID ΠΈΠ· строки, Π΅Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ всС Π΅Ρ‰Π΅ нуТдаСтся Π² Π°Π½Π°Π»ΠΈΠ·Π΅: !Ursus

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ это имя ΠΈΠΌΠ΅Π΅Ρ‚ смысл Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² области дСйствия ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ΠΎΠΌ слСва ΠΎΡ‚ Π½Π΅Π³ΠΎ, фактичСски MkParseDisplayName присваиваСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΌΡƒ Π»Π΅Π²ΠΎΠΌΡƒ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Ρƒ (ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Ρƒ классового Ρ‚ΠΈΠΏΠ°) ΠΈ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ½ ΠΈΠΌΠ΅Π½ΡƒΠ΅Ρ‚ (ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ класса Gorilla) ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡΡ‚Π°Π²ΡˆΡƒΡŽΡΡ Ρ‡Π°ΡΡ‚ΡŒ строки. Для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Π°Π½Π°Π»ΠΈΠ·Π° ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΡ‹Ρ… ΠΈΠΌΠ΅Π½ БОМ опрСдСляСт стандартный интСрфСйс IParseDisplayName:


[ object,uuid(0000011a-0000-0000-C000-000000000046) ]

interface IParseDisplayName : IUnknown

{

// convert display name to a moniker

// ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΠΎΠ΅ имя Π² ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€

HRESULT ParseDisplayName( [in, unique] IBindCtx *pbc, [in] LPOLESTR pszDisplayName, [out] ULONG *pchEaten, [out] IMoniker **ppmkOut );

}


Π’ случаС ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ, использованного Π² этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ класса Gorilla потрСбуСтся Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ IParseDisplayName ΠΈ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ строку "!Ursus" Π² ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ MkParseDisplayName поставит справа ΠΎΡ‚ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π° классового Ρ‚ΠΈΠΏΠ°. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ трСбуСтся стандартный ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ элСмСнта, Ρ‚ΠΎ достаточно Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ:


STDMETHODIMP GorillaClass::ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)

{

// create an item moniker using explicit API function

// создаСм ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΡΠ²Π½ΡƒΡŽ API-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ

HRESULT hr = CreateItemMoniker(OLESTR("!"), pszDisplayName + 1, ppmkOut);

// indicate how many characters were parsed

// ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ, сколько символов Π±Ρ‹Π»ΠΎ ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ

if (SUCCEEDED(hr)) *pchEaten = wcslen(pszDisplayName);

else *pchEaten = 0; return hr;

}


ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π½Π΅ дСлаСтся ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ. Π—Π΄Π΅ΡΡŒ просто убираСтся Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ символ "!", ΠΈ ΠΈΠ· ΠΎΡΡ‚Π°Π²ΡˆΠ΅ΠΉΡΡ части ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ создаСтся Π½ΠΎΠ²Ρ‹ΠΉ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ элСмСнта.

Π’Π°ΠΊ ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΎ ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ Π΄Π²Π° ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π°, Ρ‚ΠΎ MkParseDisplayName Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ±ΠΈΡ€Π°Ρ‚ΡŒ эти ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Ρ‹ вмСстС, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π³Ρ€ΡƒΠΏΠΏΠΎΠ²ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ‚Π½Ρ‹ΠΉ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ (generic composite moniker). Π“Ρ€ΡƒΠΏΠΏΠΎΠ²ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ‚Π½Ρ‹ΠΉ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ просто ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π΄Π²Π° ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π° вмСстС. РСализация Π³Ρ€ΡƒΠΏΠΏΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ‚Π½ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π° BindToObject сначала связываСт ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ справа, пСрСдавая Π΅ΠΌΡƒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ слСва Ρ‡Π΅Ρ€Π΅Π· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ pmkToLeft. Π­Ρ‚ΠΎ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ псСвдокодом:


// pseudo-code from OLE32.0LL

// псСвдокод из OLE32.DLL

STDMETHODIMP GenericComposite::BindToObject (IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppv)

{

return m_pmkRight->BindToObject(pbc, m_pmkLeft, riid, ppv);

}


Π­Ρ‚Π° рСализация дСмонстрируСт, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ справа являСтся Π·Π½Π°Ρ‡Π°Ρ‰ΠΈΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² области дСйствия ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π°, находящСгося слСва ΠΎΡ‚ Π½Π΅Π³ΠΎ. Π’ случаС Π³Ρ€ΡƒΠΏΠΏΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ‚Π½ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π°, использованного Π² Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ элСмСнта ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ классовый ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ ΠΊΠ°ΠΊ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ pmkToLeft Π²ΠΎ врСмя связывания.

Π Π°Π½Π΅Π΅ ΠΌΡ‹ установили, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ элСмСнта ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ интСрфСйс IOleItemContainer для связывания интСрфСйсного указатСля. НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ псСвдокод для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π° элСмСнта Π’indToObject:


// pseudo-code from OLE32.DLL

// псСвдокод из OLE32.DLL

STDMETHODIMP ItemMoniker::BindToObject(

IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppv)

{

// assume failure

// допускаСм Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ сбоя

*ppv = 0;

if (pmkToLeft == 0)

//requires a scope – трСбуСтся ΠΎΠ±Π»Π°ΡΡ‚ΡŒ дСйствия return

E_INVALIDARG;

// first bind moniker to left

// сначала привязываСм ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ слСва

IOleItemContainer *poic = 0;

HRESULT hr = pmkToLeft->BindToObject(pbc, 0, IID_IOleItemContainer, (void**)&poic);

if (SUCCEEDED(hr))

{

// cache the bound object in binding context

// ΠΊΡΡˆΠΈΡ€ΡƒΠ΅ΠΌ связанный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π² контСкстС связывания

pbc->RegisterObjectBound(poic);

// get bind speed from Bind Context

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ быстроту связывания ΠΈΠ· контСкста связывания

DWORD dwBindSpeed = this->MyGetSpeedFromCtx(pbc);

// ask object for named sub-object

// Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΎΠ± ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΏΠΎΠ΄ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅

hr = poic->GetObject(m_pszItem, dwBindSpeed, pbc, riid, ppv);

poic->Release();

}

}


Π­Ρ‚Π° рСализация ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠΉ ΠΊΠΎΠ΄:


HRESULT GetUrsus(IApe *&rpApe)

{

const OLECHAR pwsz[] = OLESTR(Β«clsid:571F1680-CC83-11d0-8C48-0080C73925BA:!UrsusΒ»);

return CoGetObject(pwsz, 0, IID_IApe, (void**)&rpApe);

}


эквивалСнтСн ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ:


HRESULT GetUrsus(IApe *&rpApe) {

IOleItemContainer *poic = 0;

HRESULT hr = CoGetClassObject(CLSID_Gorilla, CLSCTX_ALL,

0, IID_IOleItemContainer, (void**)&poic);

if (SUCCEEDED(hr)) {

hr = poic->GetObject(OLESTR(Β«UrsusΒ»), BINDSPEED_INFINITE,

0, IID_IApe, (void**)&rpApe);

poic->Release();

}

return hr; }


ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ изоляции (indirection), обСспСчСнный использованиСм CoGetObject, позволяСт ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΠΌΠ΅Π½ΡΡ‚ΡŒ ΡΡ‚Ρ€Π°Ρ‚Π΅Π³ΠΈΡŽ связывания просто ΠΏΡƒΡ‚Π΅ΠΌ чтСния Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΡ‹Ρ… ΠΈΠΌΠ΅Π½ ΠΈΠ· Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ ΠΈΠ· ΠΊΠ»ΡŽΡ‡Π° рССстра.


ΠœΠΎΠ½ΠΈΠΊΠ΅Ρ€Ρ‹ ΠΈ ΡΠΎΡ…Ρ€Π°Π½ΡΠ΅ΠΌΠΎΡΡ‚ΡŒ

ΠžΠ±ΡΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€ΠΎΠ² Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π½Ρ‹ΠΌ Π±Π΅Π· обсуТдСния Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π° (File Moniker). Напомним, Ρ‡Ρ‚ΠΎ БОМ прСдусматриваСт Ρ‚Ρ€ΠΈ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π° Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΠΈ: привязываниС ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ класса, привязываниС ΠΊ Π½ΠΎΠ²Ρ‹ΠΌ экзСмплярам класса ΠΈ привязываниС ΠΊ постоянным ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ, хранящимся Π² Ρ„Π°ΠΉΠ»Π°Ρ…. Π’ Π΄Π°Π½Π½ΠΎΠΉ Π³Π»Π°Π²Π΅ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π»ΠΈΡΡŒ ΠΏΠ΅Ρ€Π²Ρ‹Π΅ Π΄Π²Π° ΠΈΠ· этих ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²ΠΎΠ². Π’Ρ€Π΅Ρ‚ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² основан Π½Π° API-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ БОМ CoGetInstanceFromFile:


HRESULT CoGetInstanceFromFile( [in, unique] COSERVERINFO *pcsi,

// host/security info – информация ΠΎ хостС/бСзопасности

[in, unique] CLSID *pClsid,

// explicit CLSID (opt) – явный CLSID (opt)

[in, unique] IUnknown *punk0uter,

// for aggregation – для агрСгирования

[in] DWORD dwClsCtx,

// locality? β€“ локализация?

[in] DWORD grfMode,

// file open mode – Ρ€Π΅ΠΆΠΈΠΌ открытия Ρ„Π°ΠΉΠ»Π°

[in] OLECHAR *pwszName,

// file name of object – Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ΅ имя ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°

[in] DWORD cmqi,

// how many interfaces? β€“ сколько интСрфСйсов?

[out, size_is(cmqi)] MULTI_QI *prgmq

// where to put itfs – ΠΊΡƒΠ΄Π° ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ интСрфСйсы

);


Π­Ρ‚Π° функция ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π½Π° Π²Ρ…ΠΎΠ΄ имя Ρ„Π°ΠΉΠ»Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ относится ΠΊ постоянному ΡΠΎΡΡ‚ΠΎΡΠ½ΠΈΡŽ (persistent state) ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°[1]. CoGetInstanceFromFile удостовСряСтся Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ исполняСтся, послС Ρ‡Π΅Π³ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ нСсколько интСрфСйсных ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° (Ρ€Π΅)Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. Π§Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ эту Ρ€Π°Π±ΠΎΡ‚Ρƒ, CoGetInstanceFromFile Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ трСбуСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ CLSID Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. CLSID трСбуСтся ΠΏΠΎ Π΄Π²ΡƒΠΌ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌ. Если ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π½Π΅ исполняСтся, Ρ‚ΠΎ CLSID Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ БОМ для создания Π½ΠΎΠ²ΠΎΠ³ΠΎ экзСмпляра, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ ΠΎΡ‚ постоянного (находящСгося Π² Ρ„Π°ΠΉΠ»Π΅) ΠΎΠ±Ρ€Π°Π·Π°. Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, Ссли Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π½Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ хост-имя Π΄ΠΎ запроса Π½Π° Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΡŽ, Ρ‚ΠΎ БОМ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ CLSID для выяснСния Ρ‚ΠΎΠ³ΠΎ, Π½Π° ΠΊΠ°ΠΊΠΎΠΉ машинС слСдуСт Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚[2].

Если CLSID Π½Π΅ пСрСдаСтся явно Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ, Ρ‚ΠΎ CoGetInstanceFromFile ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ CLSID ΠΈΠ· самого Ρ„Π°ΠΉΠ»Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Ρ‹Π·ΠΎΠ²Π° API-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ БОМ GetClassFile:


HRESULT GetClassFile([in, string) OLECHAR *pwszFileName, [out] CLSID *pclsid);


Для опрСдСлСния Ρ‚ΠΈΠΏΠ° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, содСрТащСгося Π² Ρ„Π°ΠΉΠ»Π΅, GetClassFile ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΈΠ· Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Ρ„Π°ΠΉΠ»Π°, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΈΠ· рССстра.

ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ класс ΠΈ хост-машина, БОМ исслСдуСт ROT (Running Object Table – Ρ‚Π°Π±Π»ΠΈΡ†Π° ΠΈΡΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΡ…ΡΡ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²) Π½Π° Ρ†Π΅Π»Π΅Π²ΠΎΠΉ хост-машинС для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ΡΡΠ½ΠΈΡ‚ΡŒ, являСтся Π»ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΡƒΠΆΠ΅ Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ. Π’Π°Π±Π»ΠΈΡ†Π° ROT являСтся инструмСнтом SCM, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Ρ‹ Π² экзСмпляры ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΈΡΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΡ…ΡΡ Π½Π° локальной хост-машинС. ΠžΠΆΠΈΠ΄Π°Π΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ постоянныС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ сСбя Π² локальной ROT Π²ΠΎ врСмя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ΅ имя постоянного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² качСствС ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π°, БОМ прСдусматриваСт стандартный Ρ‚ΠΈΠΏ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Π° – Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ имя Ρ„Π°ΠΉΠ»Π° Π² интСрфСйс IMoniker. Π€Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ ΠΌΠΎΠ½ΠΈΠΊΠ΅Ρ€Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒΡΡ Π»ΠΈΠ±ΠΎ ΠΏΡƒΡ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ Π² МkParseDisplayName , Π»ΠΈΠ±ΠΎ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ явной API-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ CreateFileMoniker: