Condividi tramite


Metodo IGlobalRSCAQueryProvider::GetFunctionParameters

Restituisce i parametri della chiamata di funzione dinamica che ha causato l'evento.

Sintassi

virtual PCWSTR GetFunctionParameters(  
   VOID  
) const = 0;  

Parametri

Questo metodo non accetta parametri.

Valore restituito

Puntatore a una stringa Unicode con terminazione Null costante contenente i parametri della chiamata di funzione dinamica che ha causato l'evento.

Commenti

Le classi derivate CGlobalModule che si registrano per gli eventi GL_RSCA_QUERY ricevono un puntatore IGlobalRscaQueryProvider come parametro nel metodo CGlobalModule::OnGlobalRSCAQueryvirtual. È quindi possibile recuperare i parametri della funzione chiamando il GetFunctionParameters metodo sul IGlobalRSCAQueryProvider puntatore.

Il valore restituito del GetFunctionParameters metodo dipende dall'implementazione. È consigliabile usare le informazioni seguenti come linea guida, ma potrebbe non essere corretta in tutti gli scenari:

  • L'implementatore predefinito delle interfacce IProtocolManager, IPmCustomActions, IPmHealthAndIdleMonitor e IPmListenerChannelManager genera eventi quando si chiamano i metodi IRSCA_WorkerProcess::EnumerateAppDomains e IRSCA_AppDomain::Unload . Questi metodi eseguono il mapping rispettivamente ai valori PMH_App_Domain_Enum_V1 e PMH_App_Domain_Unload_V1, che vengono restituiti quando si chiama il metodo GetFunctionName . I parametri di questa funzione sono, a sua volta, restituiti quando si chiama GetFunctionParameters.

  • L'implementatore IGlobalRSCAQueryProvider riceve il nome della funzione e i valori dei parametri della funzione come stringhe quando viene generato uno degli eventi IRSCA_AppDomain e l'implementatore contiene riferimenti a queste stringhe. Se una stringa è NULL, GetFunctionParameters restituisce la stringa vuota. In caso contrario, GetFunctionParameters restituisce un puntatore a questa stringa condivisa.

Note per gli implementatori

IGlobalRSCAQueryProvider gli implementatori sono responsabili della gestione della memoria con questi dati; pertanto, IGlobalRSCAQueryProvider gli implementatori che usano l'allocazione dinamica della memoria devono rilasciare o chiamare delete sul PCWSTR puntatore quando non è più necessario.

Note per i chiamanti

IGlobalRSCAQueryProvider gli implementatori sono responsabili della gestione della memoria con questi dati; pertanto, IGlobalRSCAQueryProvider i client non devono rilasciare o chiamare delete sul puntatore restituito PCWSTR quando questi dati non sono più necessari. Inoltre, i client non devono eseguire il cast di questi dati a un puntatore che non è un const oggetto o modificare lo stato della memoria a cui fa riferimento questo PCWSTR, perché verrà generata una violazione di accesso o i dati diventeranno non validi.

Esempio

Nell'esempio di codice seguente viene illustrato come creare un modulo globale in ascolto di eventi GL_RSCA_QUERY e quindi scrive le informazioni sui parametri della funzione nel Visualizzatore eventi.

Attenzione

IIS 7 genera un numero elevato di eventi nel Visualizzatore eventi. Per evitare un errore di overflow del log in un ambiente di produzione, è in genere consigliabile evitare di scrivere informazioni sulla cache nel registro eventi. A scopo dimostrativo, questo esempio di codice scrive una voce nella Visualizzatore eventi solo in modalità di debug.

#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 parameters from the 
        // IGlobalRSCAQueryProvider pointer.
        wstring parameters = 
            pProvider->GetFunctionParameters();

        // Write the parameter information
        // to the event writer.
        m_eventWriter.ReportInfo
            (L"Parameters:  " + parameters);

        // 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);             
}

Per altre informazioni su come creare e distribuire un modulo DLL nativo, vedere Procedura dettagliata: Creazione di un modulo HTTP Request-Level tramite codice nativo.

Il codice precedente scrive un evento nel registro applicazioni del Visualizzatore eventi, in cui la casella Dati contiene una stringa simile alla seguente:

Parameters:  

Facoltativamente, è possibile compilare il codice usando la convenzione di chiamata __stdcall (/Gz) anziché dichiarare in modo esplicito la convenzione di chiamata per ogni funzione.

Requisiti

Tipo Descrizione
Client - IIS 7.0 in Windows Vista
- IIS 7.5 in Windows 7
- IIS 8.0 in Windows 8
- IIS 10.0 in Windows 10
Server - IIS 7.0 in Windows Server 2008
- IIS 7.5 in Windows Server 2008 R2
- IIS 8.0 in Windows Server 2012
- IIS 8.5 in Windows Server 2012 R2
- IIS 10.0 in Windows Server 2016
Prodotto - 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
Intestazione Httpserv.h

Vedere anche

Interfaccia IGlobalRSCAQueryProvider