ΠΠΎΠ΄Π΅Π»Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π‘ΠΠ ΡΠ°ΡΡΠΈΡΠΈΠ»Π° ΡΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ, Π·Π°ΡΡΠ°Π²ΠΈΠ² ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π²Π½ΠΈΠΊΠ°ΡΡ Π²ΠΎ Π²Π·Π°ΠΈΠΌΠΎΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠΌ ΠΈ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠ΅ΠΉ. ΠΠΎΠ΄Π΅Π»Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Ρ MTS ΡΠ°ΠΊΠΆΠ΅ ΡΠ°ΡΡΠΈΡΡΠ΅Ρ ΠΌΠΎΠ΄Π΅Π»Ρ Π‘ΠΠ, ΠΏΠΎΠ±ΡΠΆΠ΄Π°Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π²Π½ΠΈΠΊΠ°ΡΡ ΡΠ°ΠΊΠΆΠ΅ ΠΈ Π²ΠΎ Π²Π·Π°ΠΈΠΌΠΎΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ ΠΈ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ. Π€ΡΠ½Π΄Π°ΠΌΠ΅Π½ΡΠ°Π»ΡΠ½ΡΠΉ ΠΏΡΠΈΠ½ΡΠΈΠΏ MTS Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈ ΡΠΌΠΎΠ΄Π΅Π»ΠΈΡΠΎΠ²Π°Π½ ΠΊΠ°ΠΊ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΈ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅, Π½ΠΎ Π΅Π³ΠΎ ΡΠΈΠ·ΠΈΡΠ΅ΡΠΊΠ°Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠ²Π½ΠΎ ΡΠ°Π·Π»ΠΈΡΠ°ΡΡ ΡΡΠΈ ΠΏΠΎΠ½ΡΡΠΈΡ. Π―Π²Π½ΠΎ ΡΠ°Π·ΡΠ΅ΡΠΈΠ² MTS ΡΠΏΡΠ°Π²Π»ΡΡΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΌΠΎΠΆΠ΅Ρ ΡΡΠΈΠ»ΠΈΡΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΡ ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΠΎΠΉ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΠΈΠ·ΠΌΠΎΠΌ ΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΎΠΉ, Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°ΡΠΈΠ΅ΠΉ ΠΎΡΠΈΠ±ΠΎΠΊ, Π½Π΅ΠΏΡΠΎΡΠΈΠ²ΠΎΡΠ΅ΡΠΈΠ²ΠΎΡΡΡΡ Π΄Π°Π½Π½ΡΡ , Π° ΡΠ°ΠΊΠΆΠ΅ ΠΊΠΎΠ½ΡΡΠΎΠ»Π΅ΠΌ Π΄ΠΎΡΡΡΠΏΠ° Π½Π° ΡΡΠΎΠ²Π½Π΅ ΠΌΠ΅Π»ΠΊΠΈΡ ΡΡΡΡΠΊΡΡΡΠ½ΡΡ Π΅Π΄ΠΈΠ½ΠΈΡ (fine-grain). ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ Π±ΠΎΠ»ΡΡΡΡ ΡΠ°ΡΡΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΠΌΠΎΠΆΠ½ΠΎ Π½Π΅ Π·Π°ΠΏΠΈΡΡΠ²Π°ΡΡ Π² Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΡΠΉ Π±Π»ΠΎΠΊ Ρ ΠΈΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΡΠΌΠΈ vptr (ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡΠΈΠΌΠΈ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠ°). ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ Π² MTS ΠΏΡΠ΅Π΄ΡΡΠΌΠΎΡΡΠ΅Π½Ρ ΡΡΠ΅Π΄ΡΡΠ²Π° Π΄Π»Ρ Π·Π°ΠΏΠΈΡΠΈ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π»ΠΈΠ±ΠΎ Π² Π΄Π»ΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅, Π»ΠΈΠ±ΠΎ Π²ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ΅ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅. ΠΡΠΎ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ ΠΏΠΎΠ΄ ΠΊΠΎΠ½ΡΡΠΎΠ»Π΅ΠΌ ΡΡΠ΅Π΄Ρ MTS Π½Π° ΡΡΠ°ΠΏΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ, ΠΈ ΠΊ Π½Π΅ΠΌΡ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡΠΉ Π΄ΠΎΡΡΡΠΏ Π΄Π»Ρ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² ΠΎΠ±ΡΠ΅ΠΊΡΠ°, ΠΏΡΠΈΡΠ΅ΠΌ Π½Π΅ Π½ΡΠΆΠ½ΠΎ Π·Π°Π±ΠΎΡΠΈΡΡΡΡ ΠΎΠ± ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΎΠΉ ΠΈ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΠΎΡΡΠΈ Π΄Π°Π½Π½ΡΡ . Π‘ΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΎΡΡΠ°Π²Π°ΡΡΡΡ ΠΏΠΎΡΡΠΎΡΠ½Π½ΡΠΌ Π² ΡΠ»ΡΡΠ°Π΅ ΡΠ±ΠΎΡ ΠΌΠ°ΡΠΈΠ½Ρ ΠΈΠ»ΠΈ Π½Π΅ΡΡΠ°ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠ΅ΠΊΡΠ°ΡΠ΅Π½ΠΈΡ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ Π² Π΄ΠΎΠ»Π³ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ΅ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅, ΠΈ MTS Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ Π»ΠΈΡΡ Π½ΠΈΡΡΠΎΠΆΠ½ΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π²ΠΎ Π²ΡΠ΅ΠΉ ΡΠ΅ΡΠΈ. ΠΠ΅ΡΠ΅Ρ ΠΎΠ΄Π½ΠΎΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π·Π°ΠΏΠΈΡΠ°Π½ΠΎ Π² ΠΏΠ°ΠΌΡΡΡ, ΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌΡΡ MTS, ΠΏΡΠΈΡΠ΅ΠΌ MTS Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ ΡΠΎ, ΡΡΠΎ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΡ ΠΊ ΠΏΠ°ΠΌΡΡΠΈ Π±ΡΠ΄ΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΡΠΌΠΈ β Π²ΠΎ ΠΈΠ·Π±Π΅ΠΆΠ°Π½ΠΈΠ΅ ΠΏΠΎΡΡΠΈ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ.
ΠΠ°ΠΊ Π² ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°Ρ Π½Π° Π±Π°Π·Π΅ ΠΊΠ»Π°ΡΡΠΎΠ² ΠΈ Π½Π° Π±Π°Π·Π΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ², ΠΌΠΎΠ΄Π΅Π»Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ MTS, ΠΊΠΎΠ½ΡΡΡΡΠΈΡΡΡΡΠ°Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅, ΡΡΠ΅Π±ΡΠ΅Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ Π²Π½ΠΈΠΌΠ°Π½ΠΈΡ ΠΈ Π΄ΠΈΡΡΠΈΠΏΠ»ΠΈΠ½Ρ ΡΠΎ ΡΡΠΎΡΠΎΠ½Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°. Π ΡΡΠ°ΡΡΡΡ, ΠΊΠ°ΠΊ ΠΈ Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Π½Π° Π±Π°Π·Π΅ ΠΊΠ»Π°ΡΡΠΎΠ² ΠΈ Π½Π° Π±Π°Π·Π΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ², ΠΌΠΎΠ΄Π΅Π»Ρ MTS, ΠΊΠΎΠ½ΡΡΡΡΠΈΡΡΡΡΠ°Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅, ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΏΡΠΈΠ½ΡΡΠ° ΠΏΠΎΡΡΠ΅ΠΏΠ΅Π½Π½ΠΎ. ΠΠΎΠ½Π΅ΡΠ½ΠΎ, ΠΏΠΎΡΠ°Π³ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ½ΡΡΠΈΠ΅ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π° MTS Π±ΡΠ΄ΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΡΡΠ΅ΠΏΠ΅Π½Π½ΠΎ. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ MTS ΡΠΎ ΡΠΊΠΎΡΠΎΡΡΡΡ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΉ ΠΌΠ΅ΡΡΠ½ΠΎΠΉ ΠΊΡΠ»ΡΡΡΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ.
ΠΠΎΡΠ»Π΅ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² MTS ΠΈ Π‘ΠΠ Π² ΡΠ°ΠΌΠΊΠ°Ρ ΡΠΈΡΠΌΡ Microsoft ΡΡΠ°Π»ΠΎ ΡΡΠ½ΠΎ, ΡΡΠΎ MTS ΡΠ²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠ°Π³ Π² ΡΠ²ΠΎΠ»ΡΡΠΈΠΈ Π‘ΠΠ. Π― Π³ΠΎΡΡΡΠΎ ΠΏΡΠΈΠ·ΡΠ²Π°Ρ Π²ΡΠ΅Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π‘ΠΠ Π²ΠΊΠ»ΡΡΠΈΡΡΡΡ Π² ΡΡΡ ΡΡΠ΅ΡΡΡ Π²ΠΎΠ»Π½Ρ ΡΠ°Π·Π²ΠΈΡΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ.
ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π. ΠΠ·Π±ΡΠ°Π½Π½ΡΠΉ ΠΊΠΎΠ΄
ΠΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄, ΡΠΎΠΏΡΠΎΠ²ΠΎΠΆΠ΄Π°ΡΡΠΈΠΉ Π΄Π°Π½Π½ΡΡ ΠΊΠ½ΠΈΠ³Ρ, ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π·Π°ΠΊΠΎΠ½ΡΠ΅Π½Π½ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π‘ΠΠ (Π‘ΠΠ Chat) Π² ΡΠΎΠ²ΠΎΠΊΡΠΏΠ½ΠΎΡΡΠΈ Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΎΠΉ ΠΊΠΎΠ΄ΠΎΠ² ΡΡΠΈΠ»ΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π½ΡΡ Π°Π²ΡΠΎΡΠΎΠΌ. ΠΡΠΎΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π³ΡΡΠ·ΠΈΡΡ Π² ΡΠ»Π΅ΠΊΡΡΠΎΠ½Π½ΠΎΠΉ ΡΠΎΡΠΌΠ΅ ΠΏΠΎ Π°Π΄ΡΠ΅ΡΡ http://www.develop.com/essentialcom. ΠΠ»Ρ ΡΠ΄ΠΎΠ±ΡΡΠ²Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π‘ΠΠ Chat ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΎ Π·Π΄Π΅ΡΡ Π² ΠΎΡΠΏΠ΅ΡΠ°ΡΠ°Π½Π½ΠΎΠΉ ΡΠΎΡΠΌΠ΅.
Π‘ΠΠ Chat (ΡΠ°Ρ) ΡΠ²Π»ΡΠ΅ΡΡΡ Π·Π°ΠΊΠΎΠ½ΡΠ΅Π½Π½ΠΎΠΉ Π‘ΠΠ-ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΎΠΉ, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ ΡΠ°ΡΡΡΠ΅Π΄ΠΎΡΠΎΡΠ΅Π½Π½ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡ, ΡΠΎΡΡΠΎΡΡΠ΅Π΅ ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΠ°Π·Π΄Π΅Π»ΠΎΠ². ΠΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΠΈΡ ΠΈΠ· ΡΡΠ΅Ρ Π΄Π²ΠΎΠΈΡΠ½ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ²:
comchat.exe β ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΠ²Π½ΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ,
comchatps.dll β ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ½ΡΠΉ ΠΌΠ°ΡΡΠ°Π»Π΅Ρ Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² Π‘ΠΠ Chat,
client.exe β ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΎΡΠ½ΠΎΠ²Π°Π½Π½ΠΎΠ΅ Π½Π° ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ.
ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π±Π°Π·ΠΈΡΡΠ΅ΡΡΡ Π½Π° Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΠΎΠΌ ΠΊΠ»Π°ΡΡΠ΅ Π‘ΠΠ (CLSID_ChatSession). ΠΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½Π° ΡΠΈΡ. B.1, ΠΎΠ±ΡΠ΅ΠΊΡ ΠΊΠ»Π°ΡΡΠ° ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ IChatSessionManager, Π° ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ΅Π°Π½Ρ ΡΠ²ΡΠ·ΠΈ (chat session) ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ IChatSession . ΠΠ»ΠΈΠ΅Π½ΡΡ, ΠΆΠ΅Π»Π°ΡΡΠΈΠ΅ ΠΏΠΎΠ»ΡΡΠ°ΡΡ ΠΈΠ·Π²Π΅ΡΠ΅Π½ΠΈΡ ΡΠ°ΡΠ°, Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ΄ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ IChatSessionEvents ΠΊ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΡΠ΅Π°Π½ΡΠ° ΡΠ²ΡΠ·ΠΈ.
/////////////////////////////////////////////////////
//
// COMChat.idl
//
// Copyright 1997, Don Box/Addison Wesley
//
// This code accompanies the book "The Component
// Object Model" from Addison Wesley. Blah blah blah
//
//
interface IChatSessionEvents;
[
uuid(5223A050-2441-11d1-AF4F-0060976AA886),
object
]
interface IChatSession : IUnknown
{
import Β«objidl.idlΒ»;
[propget] HRESULT SessionName([out, string] OLECHAR **ppwsz);
HRESULT Say([in, string] const OLECHAR *pwszStatement);
HRESULT GetStatements([out] IEnumString **ppes);
HRESULT Advise([in] IChatSessionEvents *pEventSink,
[out] DWORD *pdwReg);
HRESULT Unadvise([in] DWORD dwReg);
}
[
uuid(5223A051-2441-11d1-AF4F-0060976AA886),
object
]
interface IChatSessionEvents : IUnknown
{
import Β«objidl.idlΒ»;
HRESULT OnNewUser([in, string] const OLECHAR *pwszUser);
HRESULT OnUserLeft([in, string] const OLECHAR *pwszUser);
HRESULT OnNewStatement([in, string] const OLECHAR *pwszUser,
[in, string] const OLECHAR *pwszStmnt);
}
[
uuid(5223A052-2441-11d1-AF4F-0060976AA886),
object
]
interface IChatSessionManager : IUnknown
{
import Β«objidl.idlΒ»;
HRESULT GetSessionNames([out] IEnumString **ppes);
HRESULT FindSession([in, string] const OLECHAR *pwszName,
[in] BOOL bDontCreate,
[in] BOOL bAllowAnonymousAccess,
[out] IChatSession **ppcs);
HRESULT DeleteSession([in, string] const OLECHAR *pwszName);
}
cpp_quote(Β«DEFINE_GUID(CLSID_ChatSession,0x5223a053,0x2441,Β»)
cpp_quote(Β«0x11d1,0xaf,0x4f,0x0,0x60,0x97,0x6a,0xa8,0x86);Β»)
/////////////////////////////////////////////////////
//
// client.cpp
//
// Copyright 1997, Don Box/Addison Wesley
//
// This code accompanies the book "The Component
// Object Model" from Addison Wesley. Blah blah blah
//
//
#define _WIN32_WINNT 0x403
#include <windows.h>
#include <stdio.h>
#include <initguid.h>
#include <wchar.h>
#include Β«../include/COMChat.hΒ»
#include Β«../include/COMChat_i.cΒ»
void Error(HRESULT hr, const char *psz)
{
printf(Β«%s failed and returned 0x%x\nΒ», psz, hr);
}
// utility function to print command line syntax
int Usage(void)
{
const char *psz =
Β«usage: client.exe <action> <user> <host>\nΒ»
Β« where:\nΒ»
Β« action = /sessions|/chat:session|/delete:session\nΒ»
Β« user = /user:domain\\user /password:pw |Β»
Β«/anonymous | <nothing>\nΒ»
Β« host = /host:hostname | <nothing>\nΒ»;
printf(psz);
return -1;
}
// utility function for printing a list of strings
void PrintAllStrings(IEnumString *pes)
{
enum { CHUNKSIZE = 64 };
OLECHAR *rgpwsz[CHUNKSIZE];
ULONG cFetched;
HRESULT hr;
do
{
hr = pes->Next(CHUNKSIZE, rgpwsz, &cFetched);
if (SUCCEEDED(hr))
{
for (ULONG i = 0; i < cFetched; i++)
if (rgpwsz[i])
{
wprintf(L"%s\n", rgpwsz[i]);
CoTaskMemFree(rgpwsz[i]);
}
}
} while (hr == S_OK);
}
// utility function to print initial state of
// a chat session
void PrintToDate(IChatSession *pcs)
{
IEnumString *pes = 0;
HRESULT hr = pcs->GetStatements(&pes);
if (SUCCEEDED(hr))
{
PrintAllStrings(pes);
pes->Release();
}
}
// this class implements the callback interface
// that receives chat notifications. It simply
// prints the event to the console
class EventSink : public IChatSessionEvents
{
public:
STDMETHODIMP QueryInterface(REFIID riid, void**ppv)
{
if (riid == IID_IUnknown)
*ppv = static_cast<IChatSessionEvents*>(this);
else if (riid == IID_IChatSessionEvents)
*ppv = static_cast<IChatSessionEvents*>(this);
else
return (*ppv = 0), E_NOINTERFACE;
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) AddRef(void)
{
return 2;
}
STDMETHODIMP_(ULONG) Release(void)
{
return 1;
}
STDMETHODIMP OnNewStatement(const OLECHAR *pwszUser,
const OLECHAR *pwszStmt)
{
wprintf(L"%-14s: %s\n", pwszUser, pwszStmt);
return S_OK;
}
STDMETHODIMP OnNewUser(const OLECHAR *pwszUser)
{
wprintf(L"\n\n>>> Say Hello to %s\n\n", pwszUser);
return S_OK;
}
STDMETHODIMP OnUserLeft(const OLECHAR *pwszUser)
{
wprintf(L"\n\n>>> Say Bye to %s\n\n", pwszUser);
return S_OK;
}
};
// type of operations this client can perform
enum ACTION
{
ACTION_NONE,
ACTION_CHAT,
ACTION_DELETE_SESSION,
ACTION_LIST_SESSION_NAMES,
};
// run chat command
void Chat(const OLECHAR *pwszSession,
IChatSessionManager *pcsm, // manager
COAUTHIDENTITY *pcai, // user
bool bAnonymous) // anonymous
{
// create or get the named session
IChatSession *pcs = 0;
HRESULT hr = pcsm->FindSession(pwszSession, FALSE,
TRUE, &pcs);
if (SUCCEEDED(hr))
{
// adjust security blanket for session interface
if (!bAnonymous)
hr = CoSetProxyBlanket(pcs, RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE, 0,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IDENTIFY,
pcai, EOAC_NONE);
// catch up on past messages
PrintToDate(pcs);
// hook up event sink to receive new messages
EventSink es;
DWORD dwReg;
hr = pcs->Advise(&es, &dwReg);
if (SUCCEEDED(hr))
{
// run UI loop to get statements from console and send them
OLECHAR wszStmt[4096];
while (_getws(wszStmt))
{
hr = pcs->Say(wszStmt);
if (FAILED(hr))
Error(hr, Β«SayΒ»);
}
// tear down connection for event sink
pcs->Unadvise(dwReg);
}
else
Error(hr, Β«AdviseΒ»);
// release chat session
pcs->Release();
}
else
Error(hr, Β«FindSessionΒ»);
}
// run delete command
void Delete(const OLECHAR *pwszSession,
IChatSessionManager *pcsm)
{
HRESULT hr = pcsm->DeleteSession(pwszSession);
if (FAILED(hr))
Error(hr, Β«DeleteSessionΒ»);
}
// run list command
void List(IChatSessionManager *pcsm)
{
IEnumString *pes = 0;
HRESULT hr = pcsm->GetSessionNames(&pes);
if (SUCCEEDED(hr))
{
printf(Β«Active Sessions:\nΒ»);
PrintAllStrings(pes);
pes->Release();
}
}
int main(int argc, char **argv)
{
// declare client control state
bool bAnonymous = false;
static OLECHAR wszSessionName[1024];
static OLECHAR wszDomainName[1024];
static OLECHAR wszUserName[1024];
static OLECHAR wszPassword[1024];
static OLECHAR wszHostName[1024];
COSERVERINFO csi = { 0, wszHostName, 0, 0 };
COSERVERINFO *pcsi = 0;
COAUTHIDENTITY cai = {
wszUserName,
0,
wszDomainName,
0,
wszPassword,
0,
SEC_WINNT_AUTH_IDENTITY_UNICODE
};
static COAUTHIDENTITY *pcai = 0;
static ACTION action = ACTION_NONE;
// parse command line
for (int i = 1; i < argc; i++)
{
if (strcmp(argv[i], Β«/anonymousΒ») == 0)
bAnonymous = true;
else if (strstr(argv[i], Β«/delete:Β») == argv[i])
{
if (action != ACTION_NONE)
return Usage();
action = ACTION_DELETE_SESSION;
mbstowcs(wszSessionName, argv[i] + 8, 1024);
}
else if (strstr(argv[i], Β«/chat:Β») == argv[i])
{
if (action != ACTION_NONE)
return Usage();
action = ACTION_CHAT;
mbstowcs(wszSessionName, argv[i] + 6, 1024);
}
else if (strcmp(argv[i], Β«/sessionsΒ») == 0)
{
if (action != ACTION_NONE)
return Usage();
action = ACTION_LIST_SESSION_NAMES;