Сущность технологии СОМ. Библиотека программиста
Шрифт:
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;
}
else if (strstr(argv[i], «/host:») == argv[i])
{
if (pcsi != 0)
return Usage;
mbstowcs(wszHostName, argv[i] + 6, 1024);
pcsi = &csi;
}
else if (strstr(argv[i], «/password:») == argv[i])
{
mbstowcs(wszPassword, argv[i] + 10, 1024);
cai.PasswordLength = wcslen(wszPassword);
}
else if (strstr(argv[i],
{
if (pcai != 0 || bAnonymous)
return Usage;
char *pszDelim = strchr(argv[i] + 7, '\\');
if (pszDelim == 0)
return Usage;
*pszDelim = 0;
pszDelim++;
mbstowcs(wszDomainName, argv[i] + 6, 1024);
cai.DomainLength = wcslen(wszDomainName);
mbstowcs(wszUserName, pszDelim, 1024);
cai.UserLength = wcslen(wszUserName);
pcai = &cai;
}
}
if (action == ACTION_NONE)
return Usage;
HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr))
return hr;
// allow anonymous callbacks from chat server
hr = CoInitializeSecurity(0, -1, 0, 0,
RPC_C_AUTHN_LEVEL_NONE,
RPC_C_IMP_LEVEL_ANONYMOUS,
0, EOAC_NONE, 0);
if (SUCCEEDED(hr))
{
// grab the requested session manager
IChatSessionManager *pcsm = 0;
hr = CoGetClassObject(CLSID_ChatSession, CLSCTX_ALL,
pcsi, IID_IChatSessionManager,
(void**)&pcsm);
if (SUCCEEDED(hr))
{
// apply security blanket if desired
if (!bAnonymous)
hr = CoSetProxyBlanket(pcsm, RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE, 0,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IDENTIFY,
pcai, EOAC_NONE);
// dispatch request
switch (action)
{
case ACTION_CHAT:
Chat(wszSessionName, pcsm, pcai, bAnonymous);
break;
case ACTION_DELETE_SESSION:
Delete(wszSessionName, pcsm);
break;
case ACTION_LIST_SESSION_NAMES:
List(pcsm);
break;
default:
Usage;
}
// release session manager
pcsm->Release;
}
}
CoUninitialize;
return hr;
}
/////////////////////////////////////////////////////
//
// ChatSession.h
//
// Copyright 1997, Don Box/Addison Wesley
//
// This code accompanies the book "The Component
// Object Model" from Addison Wesley. Blah blah blah
//
//
#ifndef _CHATSESSION_H
#define _CHATSESSION_H
// this pragma shuts up the compiler warnings due to
// the pre MSC11SP1 debugger choking on long template names.
#pragma warning(disable:4786)
#define _WIN32_WINNT 0x403
#include <windows.h>
#include <map>
#include <vector>
#include <string>
using namespace std;
// bring in IDL-generated interface definitions
#include
«..\include\COMChat.h»// this class models a particular chat session
class ChatSession : public IChatSession
{
friend class StatementEnumerator;
LONG m_cRef;
CRITICAL_SECTION m_csStatementLock;
CRITICAL_SECTION m_csAdviseLock;
OLECHAR m_wszSessionName[1024];
bool m_bIsDeleted;
bool m_bAllowAnonymousAccess;
vector<wstring> m_statements;
struct LISTENER
{
LISTENER *pPrev;
LISTENER *pNext;
OLECHAR *pwszUser;
IChatSessionEvents *pItf;
};
LISTENER *m_pHeadListeners;
void SLock(void);
void SUnlock(void);
void ALock(void);
void AUnlock(void);
bool CheckAccess(const OLECHAR *pwszUser);
protected:
virtual ~ChatSession(void);
void Fire_OnNewStatement(const OLECHAR *pwszUser,
const OLECHAR *pwszStatement);
void Fire_OnNewUser(const OLECHAR *pwszUser);
void Fire_OnUserLeft(const OLECHAR *pwszUser);
public:
ChatSession(const OLECHAR *pwszSessionName,
bool bAllowAnonymousAccess);
void Disconnect(void);
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IChatSession methods
STDMETHODIMP get_SessionName(OLECHAR **ppwsz);
STDMETHODIMP Say(const OLECHAR *pwszStatement);
STDMETHODIMP GetStatements(IEnumString **ppes);
STDMETHODIMP Advise(IChatSessionEvents *pEventSink,
DWORD *pdwReg);
STDMETHODIMP Unadvise(DWORD dwReg);
};
// this class enumerates the statements of a session
class StatementEnumerator : public IEnumString
{
LONG m_cRef;
ChatSession *m_pThis;
vector<wstring>::iterator m_cursor;
CRITICAL_SECTION m_csLock;
protected:
void Lock(void);
void Unlock(void);
virtual ~StatementEnumerator(void);
public:
StatementEnumerator(ChatSession *pThis);
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IEnumString methods
STDMETHODIMP Next(ULONG cElems, OLECHAR **rgElems,
ULONG *pcFetched);
STDMETHODIMP Skip(ULONG cElems);
STDMETHODIMP Reset(void);
STDMETHODIMP Clone(IEnumString **ppes);
};
// this class models the management of chat sessions