IGlobalRSCAQueryProvider::GetFunctionName メソッド
イベントの原因となった動的関数呼び出しの名前を返します。
構文
virtual PCWSTR GetFunctionName(
VOID
) const = 0;
パラメーター
このメソッドは、パラメーターを受け取りません。
戻り値
イベントの原因となった関数の名前を含む、null で終わる定数 Unicode 文字列へのポインター。
解説
GL_RSCA_QUERY イベントに登録する CGlobalModule 派生クラスは、CGlobalModule::OnGlobalRSCAQuery メソッドのパラメーターとして IGlobalRscaQueryProvidervirtual
ポインターを受け取ります。 その後、ポインターで メソッドを呼び出すことで、 GetFunctionName
関数名を IGlobalRSCAQueryProvider
取得できます。
メソッドの戻り値は実装 GetFunctionName
によって異なります。 ガイドラインとして次の情報を使用する必要がありますが、すべてのシナリオで正しくない場合があります。
IProtocolManager、IPmCustomActions、IPmHealthAndIdleMonitor、および IPmListenerChannelManager インターフェイスの既定の実装者は、IRSCA_WorkerProcess::EnumerateAppDomains メソッドと IRSCA_AppDomain::Unload メソッドを呼び出すとイベントを発生させます。 これらのメソッドは、 を呼び出
GetFunctionName
したときに返されるPMH_App_Domain_Enum_V1とPMH_App_Domain_Unload_V1の値にそれぞれマップされます。 この関数のパラメーターは、 GetFunctionParameters メソッドを呼び出すと返されます。実装者は
IGlobalRSCAQueryProvider
、 IRSCA_AppDomain イベントのいずれかが 発生したときに関数名と関数パラメーター値を文字列として受け取り、実装者はこれらの文字列への参照を保持します。 文字列が NULL の場合は、GetFunctionName
空の文字列を返します。 それ以外の場合は、GetFunctionName
この共有文字列へのポインターを返します。
実装側の注意
IGlobalRSCAQueryProvider
実装者は、このデータを使用したメモリ管理を担当します。したがって、IGlobalRSCAQueryProvider
動的メモリ割り当てを使用する実装者は、不要になったときにポインターをPCWSTR
解放または呼び出すdelete
必要があります。
呼び出し元に関する注意事項
IGlobalRSCAQueryProvider
実装者は、このデータを使用したメモリ管理を担当します。そのため、IGlobalRSCAQueryProvider
このデータが不要になった場合、クライアントは返されたPCWSTR
ポインターを解放したり、 を呼び出delete
したりすることはできません。 さらに、アクセス違反が発生するか、データが無効になるため、クライアントはこのデータを ポインター const
にキャストしたり、この PCWSTR
によって参照されるメモリの状態を変更したりしてはなりません。
例
次のコード例では、GL_RSCA_QUERY イベントをリッスンし、関数名情報をイベント ビューアーに書き込むグローバル モジュールを作成する方法を示します。
注意事項
IIS 7 では、イベント ビューアーで多数のイベントが生成されます。 運用環境でログ オーバーフロー エラーが発生しないようにするには、通常、イベント ログにキャッシュ情報を書き込むのを避ける必要があります。 デモの目的で、このコード例では、デバッグ モードでのみイベント ビューアーにエントリを書き込みます。
#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <tchar.h>
#include <httpserv.h>
#include <string>
using namespace std;
// The CConvert class mirrors the Convert class that is
// defined in the .NET Framework. It converts primitives
// and other data types to wstring types.
class CConvert
{
public:
// The ToByteString converts a double-byte
// character string to a single-byte string.
// str: the double-byte string to convert.
// return: a single-byte string copied from str.
static string ToByteString(const wstring& str)
{
// Get the length of the
// double-byte string.
size_t length = str.length();
// Create a temporary char pointer.
char* byteChar = new char[length+1];
byteChar[0] = '\0';
// Copy the double-byte character string
// into the single-byte string.
size_t charsReturned = 0;
wcstombs_s(&charsReturned, byteChar,
length+1, str.c_str(), length+1);
// Create a string to return.
string retString = byteChar;
// Delete the temporary string and
// set that string to NULL.
delete[] byteChar;
byteChar = NULL;
// Return the single-byte string.
return retString;
}
};
// The CEventWriter class writes XML
// documents and strings to the event log.
class CEventWriter
{
public:
// Creates the CEventWriter class.
// name: the name of the
// event log to open.
CEventWriter(const wstring& name)
{
#ifdef UNICODE
m_eventLog = RegisterEventSource(NULL, name.c_str());
#else
string multiName = CConvert::ToByteString(name);
m_eventLog = RegisterEventSource(NULL, multiName.c_str());
#endif
}
// Creates the destructor for the
// CEventWriter class. This destructor
// closes the HANDLE to the event
// log if that HANDLE is open.
virtual ~CEventWriter()
{
// If the HANDLE to the event
// log is open, close it.
if (NULL != m_eventLog)
{
// Deregister the event log HANDLE.
DeregisterEventSource(m_eventLog);
// Set the HANDLE to NULL.
m_eventLog = NULL;
}
}
// The ReportInfo method writes
// a wstring to the event log.
// info: the wstring to write.
// return: true if the event log is written.
BOOL ReportInfo(const wstring& info)
{
return ReportEvent(EVENTLOG_INFORMATION_TYPE, info);
}
protected:
// The ReportEvent method accepts an event type
// and a wstring, and attempts to write that
// event to the event log.
// type: the type of the event.
// data: the wstring to write to the event log.
// return: true if the event log is written;
// otherwise, false.
BOOL ReportEvent(WORD type, const wstring& data)
{
// If the m_eventLog HANDLE
// is NULL, return false.
if (NULL == m_eventLog)
{
return FALSE;
}
#ifndef _DEBUG
// If the current build is not debug,
// return so the event log is not written.
return TRUE;
#endif
#ifdef UNICODE
// The unicode version of the ReportEvent
// method requires double-byte strings.
PCWSTR arr[1];
arr[0] = data.c_str();
return ::ReportEvent(m_eventLog,
type,
0, 0, NULL, 1,
0, arr, (void*)arr);
#else
// The non-unicode version of the ReportEvent
// method requires single-byte strings.
string multiByte =
CConvert::ToByteString(data);
LPCSTR arr[1];
arr[0] = multiByte.c_str();
return ::ReportEvent(m_eventLog,
type,
0, 0, NULL, 1,
0, arr, (void*)arr);
#endif
}
private:
// Specify the HANDLE to the
// event log for writing.
HANDLE m_eventLog;
};
// The CRSCAGlobalModule class creates the CGlobalModule
// class and registers for GL_RSCA_QUERY and events.
class CRSCAGlobalModule : public CGlobalModule
{
public:
// Creates the destructor for the
// CGlobalCacheModule class.
virtual ~CRSCAGlobalModule()
{
}
// The RegisterGlobalModule method creates and registers
// a new CRSCAGlobalModule for GL_RSCA_QUERY events.
// dwServerVersion: the current server version.
// pModuleInfo: the current IHttpModuleRegistrationInfo pointer.
// pGlobalInfo: the current IHttpServer pointer.
// return: E_INVALIDARG if the IHttpServer pointer
// is NULL; ERROR_NOT_ENOUGH_MEMORY if the heap is out of
// memory; otherwise, the value from the call to the
// SetGlobalNotifications method on the pModuleInfo pointer.
static HRESULT RegisterGlobalModule
(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo* pModuleInfo,
IHttpServer* pGlobalInfo
)
{
// The pGlobalInfo parmeter must be
// non-NULL because the constructor
// for the CGlobalCacheModule class
// requires a non-NULL pointer to a
// valid IHttpServer pointer.
if (NULL == pGlobalInfo)
{
return E_INVALIDARG;
}
// Create a new CGlobalCacheModule pointer.
CRSCAGlobalModule* rscaModule =
new CRSCAGlobalModule();
// Return an out-of-memory error
// if the traceModule is NULL
// after the call to the new operator.
if (NULL == rscaModule)
{
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
}
// Attempt to set global notification
// for GL_RSCA_QUERY events by using
// the rscaModule as a listener.
HRESULT hr = pModuleInfo->SetGlobalNotifications
(rscaModule, GL_RSCA_QUERY);
// Return the HRESULT from the call to
// the SetGlobalNotifications method.
return hr;
}
// The OnGlobalRSCAQuery method is the event
// handler method for the GL_RSCA_QUERY event.
// pProvider: the IGlobalRSCAQueryProvider pointer.
// return: GL_NOTIFICATION_CONTINUE.
virtual GLOBAL_NOTIFICATION_STATUS OnGlobalRSCAQuery
(
IN IGlobalRSCAQueryProvider* pProvider
)
{
// Return GL_NOTIFICATION_CONTINUE if the
// IGlobalRSCAQueryProvider pointer is NULL.
if (NULL == pProvider)
{
return GL_NOTIFICATION_CONTINUE;
}
// Get the name of the function from
// the IGlobalRSCAQueryProvider pointer.
wstring functionName =
pProvider->GetFunctionName();
// Write the function name
// information to the event writer.
m_eventWriter.ReportInfo
(L"Function Name: " + functionName);
// Return GL_NOTIFICATION_CONTINUE so
// other listeners will receive this event.
return GL_NOTIFICATION_CONTINUE;
}
// The Terminate method is a pure virtual
// method that all non-abstract CGlobalModule
// classes must implement. Calls delete on this.
virtual VOID Terminate(VOID)
{
delete this;
}
protected:
// Creates the CRSCAGlobalModule class.
// Initializes the CEventWriter to write
// to the event log using the IISADMIN key.
CRSCAGlobalModule() : m_eventWriter(L"IISADMIN")
{
}
private:
// Specify the CEventWriter writer.
CEventWriter m_eventWriter;
};
// The RegisterModule method is the
// main entry point for the DLL.
// dwServerVersion: the current server version.
// pModuleInfo: the current
// IHttpModuleRegistrationInfo pointer.
// pGlobalInfo: the current IHttpServer pointer.
// return: the value returned by calling the
// CRSCAGlobalModule::RegisterGlobalModule
// method.
HRESULT
__stdcall
RegisterModule(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo* pModuleInfo,
IHttpServer* pGlobalInfo
)
{
// Call the static method for initialization.
return CRSCAGlobalModule::RegisterGlobalModule
(dwServerVersion,
pModuleInfo,
pGlobalInfo);
}
ネイティブ DLL モジュールを作成してデプロイする方法の詳細については、「 チュートリアル: ネイティブ コードを使用したRequest-Level HTTP モジュールの作成」を参照してください。
上記のコードでは、イベント ビューアーのアプリケーション ログに 2 つの新しいイベントが書き込まれます。ここで、[データ] ボックスには次のような文字列が含まれています。
Function Name: PMH_App_Domain_Enum_V1
必要に応じて、各関数の呼び出し規則を明示的に宣言するのではなく、__stdcall (/Gz)
呼び出し規則を使用してコードをコンパイルできます。
要件
Type | 説明 |
---|---|
Client | - Windows Vista 上の IIS 7.0 - Windows 7 上の IIS 7.5 - Windows 8 上の IIS 8.0 - Windows 10の IIS 10.0 |
サーバー | - Windows Server 2008 の IIS 7.0 - Windows Server 2008 R2 の IIS 7.5 - Windows Server 2012 の IIS 8.0 - Windows Server 2012 R2 の IIS 8.5 - Windows Server 2016の IIS 10.0 |
製品 | - IIS 7.0、IIS 7.5、IIS 8.0、IIS 8.5、IIS 10.0 - IIS Express 7.5、IIS Express 8.0、IIS Express 10.0 |
Header | Httpserv.h |