Буду описывать только то, что делал сам... И работает.
Все ниже примеры из ISA SDK.
В MSDN - ISA SDK имеется
Фильтры приложения ISA.
----------------------------
1. На компьютере с 2 сетевыми картами устанавливаем Microsoft ISA Server 200x.
2. Загружаем ISA SDK (заголовки, idl)
3. Создаем DLL (используя ATL COM AppWizard).
4. Добавляем файлы заголовков и .idl к проекту
import "oaidl.idl"; // строка создается мастером
import "oсidl.idl"; // строка создается мастером
import "wspfwext.idl"; // эту строку добавляешь ты
5. Процесс компиляции создает другие файлы (wspfwext.h и wspfwext_i.c).
6. Добавляем инструкцию include для wspfwext.h в файл заголовка stdafx.h:
7. Сгенерированный MIDL файл wspfwext_i.c содержит GUIDs для интерфейсов фильтра.
Включи его в один из .cpp файлов.
8. Cоздаем объект фильтра реализующего интерфейс IFWXFilter.
Объект фильтра будет контролировать события fwx_AcceptedConnection.
8.a) Вставь новый объект ATL (Simple Object), со следующими свойствами
• Интерфейс - IFWXFilter
• Атрибуты:
Threading model - free
Interface - Custom
Aggregation - No
8.b) Отредактируй файл project.idl. Поскольку интерфейс IFWXFilter и его GUID уже определены в wspfwext.idl, ты должен удалить код определения IFWXFilter, который генерируется в project.idl
мастером. UUID в этом коде только для примера.
[
object,
uuid(20F10C85-2C5E-11D2-8C3D-006094EB63EF),
helpstring("IFWXFilter Interface-),
pointer_default(unique)
]
interface IFWXFilter : IUnknown
{
};
8.c) Добавь объявление методов IFWXFilter. Используй wspfwext.h, чтобы получить прототипы методов IFWXFilter и добавить их в секцию public определения класса project.h. Обрати внимание, что надо удалить = 0 из методов. Вставь следующий код:
// IFWXFilter
virtual HRESULT STDMETHODCALLTYPE FilterInit(
/* [in] */ IFWXFirewall __RPC_FAR *pIFWXFirewall,
/* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents);
virtual HRESULT STDMETHODCALLTYPE FilterShutdown(void);
virtual HRESULT STDMETHODCALLTYPE AttachToSession(
/* [in] */ IFWXSession __RPC_FAR *piSession,
/* [out] */ IFWXSessionFilter __RPC_FAR *__RPC_FAR *piSessionFilter,
/* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents);
8.d) Добавь реализацию методов IFWXFilter. Используй wspfwext.h, чтобы получить прототипы методов IFWXFilter и добавить их в SMTPfilter.cpp с реализацией кода.
Начни с простой реализации, например:
return E_NOTIMPL;
Реализованный код должен выглядеть следующим образом:
// CSSSFilter
HRESULT STDMETHODCALLTYPE CSSSFilter::FilterInit(
/* [in] */ IFWXFirewall __RPC_FAR *pIFWXFirewall,
/* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CSSSFilter::FilterShutdown( void)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CSSSFilter::AttachToSession(
/* [in] */ IFWXSession __RPC_FAR *piSession,
/* [out] */ IFWXSessionFilter __RPC_FAR *__RPC_FAR *piSessionFilter,
/* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents)
{
return E_NOTIMPL;
}
8.d) Скомпилируй проект.
8.e) Добавь код конструктора объекта SSSFilter, и реализуй метод IFWXFilter::FilterInit. Служба брандмауэра вызывает этот метод при старте. В методе IFWXFilter::FilterInit сохрани указатель на интерфейс IFWXFirewall, который используется позже. Теперь определи набор начальных событий, которые фильтр будет контролировать. Этот пример контролирует события fwx_AcceptedConnection и fwx_Bind_Tcp. Однако, для лучшего быстродействия, лучше контролировать минимальный набор событий на уровне IFWXFilter. Поэтому, наш фильтр будет контролировать событие fwx_Bind_Tcp для порта 25 и событие fwx_AcceptedConnection. Мы также должны определить порт, с которого хотитм получать события. В этом примере порт 25.
В SSSfilter.h, добавь следующий код:
private:
CComPtr<IFWXFirewall> m_pIFWXFirewall;
FwxFilterHookEvents m_FwxFilterHookEvents;
FwxPortRangeEvents m_FwxPortRangeEvents;
В SSSfilter.h, определи местонахождение конструктора по умолчанию, удали {}, и добавьте точку с запятой как показано:
CSSSFilter();
{ //удалить
} //удалить
и напиши следующий код конструктора объекта и реализацию FilterInit в SSSFilter.cpp (замени простое выполнение, которое вставил предварительно):
CSSSFilter::CSSSFilter ()
{
m_FwxPortRangeEvents.StartPort = 25;
m_FwxPortRangeEvents.EndPort = 25;
m_FwxPortRangeEvents.dwSocketEvents =
DWORD(FWX_ALL_SOURCES // Источник события клиент NAT и брандмауэра
| fwx_Bind_Tcp); // Мониторинг привязывается на этот уровнь
m_FwxFilterHookEvents.dwGlobalEvents = 0;
m_FwxFilterHookEvents.dwNumPortRanges = 1;
m_FwxFilterHookEvents.FwxPortRangeEvents = &m_FwxPortRangeEvents;
}
HRESULT STDMETHODCALLTYPE CSSSFilter::FilterInit(
/* [in] */ IFWXFirewall __RPC_FAR *pIFWXFirewall,
/* [out] */ FwxFilterHookEvents __RPC_FAR *__RPC_FAR *ppFilterHookEvents)
{
m_pIFWXFirewall = pIFWXFirewall;
return m_pIFWXFirewall->DuplicateFilterHookEvents (&m_FwxFilterHookEvents,
ppFilterHookEvents);
}
8.f) Реализуй метод IFWXFilter::FilterShutdown. Это - запрос на закрытие фильтра. Поскольку этот фильтр не содержит ссылки на любой другой объект, кроме интерфейса брандмауэра, он может просто возвратить S_OK. Это должно быть вставлено в SSSfilter.cpp, вместо предварительно вставленного возврата E_NOTIMPL.
HRESULT STDMETHODCALLTYPE CSSSFilter::FilterShutdown( void)
{
return S_OK;
}
8.g) Скомпилируй проект.
P.S.: Если есть интерес, потом что нибудь добавлю
P.P.S: Смотри ISA SDK. Там все отлично расписано.