共用方式為


IHttpTokenEntry::GetSid 方法

傳回使用者的安全性識別碼。

語法

virtual PSID GetSid(  
   VOID  
) = 0;  

參數

此方法不會採用任何參數。

傳回值

安全性識別碼的指標 (SID) 。

備註

註冊GL_CACHE_OPERATION事件的CGlobalModule衍生類別會收到CGlobalModule::OnGlobalCacheCacheOperationvirtual 方法上的參數 ICacheProvider指標。 您可以藉由呼叫ICacheProvider::GetCacheRecord方法來擷取IHttpCacheSpecificData指標,在某些情況下,您可以將此 IHttpCacheSpecificData 指標向下轉型為IHttpTokenEntry指標。 接著,您可以呼叫 GetSid 方法來擷取安全性識別碼。

如需下播規則的詳細資訊,請參閱 ICacheProvider::GetCacheRecord

實作者的注意事項

IHttpTokenEntry 實作者負責使用此資料的記憶體管理;因此, IHttpTokenEntry 使用動態記憶體配置的實作者必須在不再需要指標時處置 PSID 指標。

來電者的附注

IHttpTokenEntry 實作者負責使用此資料的記憶體管理;因此,當不再需要此資料時, IHttpTokenEntry 用戶端不得處置傳 PSID 回的指標。 此外,用戶端不得變更此 PSID 參考的記憶體狀態,因為會擲回存取違規,否則資料會變成無效。

範例

下列程式碼範例示範如何建立全域模組來接 GL_CACHE_OPERATION 聽和GL_CACHE_CLEANUP事件,然後將資訊寫入 IHttpTokenEntry 事件檢視器。

警告

IIS 7 會在事件檢視器中產生大量的事件。 為了避免在生產環境中發生記錄溢位錯誤,您通常應該避免將快取資訊寫入事件記錄檔。 為了示範目的,此程式碼範例只會以偵錯模式將專案寫入事件檢視器。

#pragma warning( disable : 4290 )
#pragma warning( disable : 4530 )

#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <tchar.h>
#include <initguid.h>
#include <httptrace.h>
#include <httpserv.h>
#include <httpcach.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 ToString method converts a HANDLE to a wstring.
    // h: the HANDLE to convert to a wstring.
    // return: the HANDLE as a wstring.
    static wstring ToString(HANDLE h)
    {
        // If the HANDLE is NULL, return the "NULL" string.
        if (NULL == h)
        {
            return L"NULL";
        }

        // If the HANDLE is not valid, return 
        // the INVALID_HANDLE_VALUE as a string.
        if (INVALID_HANDLE_VALUE == h)
        {
            return L"INVALID_HANDLE_VALUE";
        }

        // The HANDLE is valid.
        return L"valid";
    }

    // 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 CEventException class is 
// an exception that can be thrown 
// when writing an event fails.
class CEventException
{
public:
    // Creates the CEventException class.
    // str: the wstring that could 
    // not be written to a log.
    CEventException(const wstring& str)
        : m_string(str)
    {
        
    }

    // Creates the destructor for 
    // the CEventException class.
    virtual ~CEventException()
    {

    }

private:
    // Specify the wstring that could
    // not be written to an event viewer.
    wstring m_string;
};

// 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 CGlobalCacheModule class creates the CGlobalModule 
// class and registers for GL_CACHE_OPERATION and 
// GL_CACHE_CLEANUP events.
class CGlobalCacheModule : public CGlobalModule
{
public:
    // Creates the destructor for the 
    // CGlobalCacheModule class.
    virtual ~CGlobalCacheModule()
    {

    }

    // The RegisterGlobalModule method creates and registers 
    // a new CGlobalCacheModule for GL_CACHE_OPERATION and 
    // GL_CACHE_CLEANUP events.
    // dwServerVersion: the current server version.
    // pModuleInfo: the current IHttpModuleRegistrationInfo pointer.
    // pGlobalInfo: the current IHttpServer pointer.
    // return: 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.
        CGlobalCacheModule* traceModule = 
            new CGlobalCacheModule();

        // Return an out-of-memory error if the traceModule 
        // is NULL after the call to the new operator.
        if (NULL == traceModule)
        {            
            return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
        }        

        // Attempt to set global notification for both 
        // GL_CACHE_OPERATION and GL_CACHE_CLEANUP events 
        // by using the traceModule as a listener.
        HRESULT hr = pModuleInfo->SetGlobalNotifications
            (traceModule, GL_CACHE_OPERATION | GL_CACHE_CLEANUP);

        // If the SetGlobalNotifications method 
        // fails, return the HRESULT.
        if (FAILED(hr))
        {
            return hr;
        }

        // Set the priority to PRIORITY_ALIAS_FIRST, 
        // which will populate the data as much as possible.
        hr = pModuleInfo->SetPriorityForGlobalNotification(
            GL_CACHE_OPERATION, PRIORITY_ALIAS_FIRST);

        // Return the HRESULT from the call to 
        // the SetGlobalNotifications method.
        return hr;
    }
    // The OnGlobalCacheOperation method is called 
    // when GL_CACHE_OPERATION operations occur.
    // pProvider: the current ICacheProvider pointer.
    // return: GL_NOTIFICATION_CONTINUE if the event
    // log is written; otherwise, GL_NOTIFICATION_HANDLED.
    virtual GLOBAL_NOTIFICATION_STATUS OnGlobalCacheOperation
    (
        IN ICacheProvider* pProvider
    )
    {
        // The OnGlobalCacheOperation must return if the 
        // pProvider parameter is NULL because this pointer 
        // is needed for data to write to the event log.
        if (NULL == pProvider)
        {
            return GL_NOTIFICATION_CONTINUE;
        }

        try
        {
            // Get the IHttpCacheSpecificData pointer 
            // from the ICacheProvider element.
            IHttpCacheSpecificData* cacheSpecificData = 
                pProvider->GetCacheRecord();

            // Write the IHttpCacheSpecificData 
            // pointer information to the event log.
            Write(cacheSpecificData);
        }
        // A CEventException is thrown 
        // if any Write method cannot 
        // write to the event log.
        catch (CEventException)
        {
            return GL_NOTIFICATION_HANDLED;
        }

        // Return GL_NOTIFICATION_CONTINUE so that 
        // other listeners will receive the event.
        return GL_NOTIFICATION_CONTINUE;
    }

    // The OnGlobalCacheCleanup method is called 
    // when GL_CACHE_CLEANUP events occur.
    // return: GL_NOTIFICATION_CONTINUE.
    virtual GLOBAL_NOTIFICATION_STATUS OnGlobalCacheCleanup(VOID)
    {
        // Return GL_NOTIFICATION_CONTINUE so that 
        // other listeners will receive this event.
        return GL_NOTIFICATION_CONTINUE;
    }

    // PRE: none.
    // POST: the Terminate method calls delete on 
    // this, which releases the memory for the current 
    // CGlobalCacheModule pointer on the heap.
    virtual VOID Terminate(VOID)
    {
        delete this;
    }
protected:
    // Creates the constructor for 
    // the CGlobalCacheModule class.
    // The constructor initializes the 
    // private m_eventWriter to write 
    // to the IISADMIN event log.
    CGlobalCacheModule() : m_eventWriter(L"IISADMIN")
    {

    }

    // The ReportInfo method writes the 
    // formatted name and value of a method 
    // call to the event log.
    // name: the name of the method or property.
    // value: the value of the 
    // method or the property.
    // throws: a CEventException exception.
    void ReportInfo
    (
        const wstring& name,
        const wstring& value
    ) throw (CEventException)
    {
        // Create a formatted string to
        // write to the event log.
        wstring infoString =
            name + wstring(L":  ") + value;
        // Attempt to write the formatted 
        // string to the event log. If the 
        // ReportInfo method call fails,
        // throw a CEventException exception.
        if (!m_eventWriter.ReportInfo(infoString))
        {
            throw CEventException(infoString);
        }        
    }

    // The Write method writes IHttpTokenEntry 
    // pointer information to the event log.
    // tokenEntry: the IHttpTokenEntry 
    // pointer to write.
    // throws: a CEventException exception.
    void Write
    (
        IHttpTokenEntry* tokenEntry        
    ) throw (CEventException)
    {
        // If the tokenEntry parameter is NULL, 
        // throw a CEventException exception.
        if (NULL == tokenEntry)
        {
            CEventException ce
                (L"NULL IHttpTokenEntry pointer");
            throw ce;
        }

        // Get the SID from the 
        // IHttpTokenEntry pointer.
        PSID sidPSID = tokenEntry->GetSid();

        // Convert the SID to a wstring.
        wstring sid = CConvert::ToString(sidPSID);

        // Write the SID information 
        // to the event log.
        ReportInfo(L"IHttpTokenEntry::GetSid", sid);
    }

    // The Write method writes IHttpCacheSpecificData
    // pointer information to the event log.
    // cacheSpecificData: the IHttpCacheSpecificData
    // pointer to write.
    // throws: a CEventException exception.
    void Write
    (
        IHttpCacheSpecificData* cacheSpecificData        
    ) throw (CEventException)
    {
        // If the cacheSpecificData is NULL, 
        // return. IHttpCacheSpecificData 
        // pointer data is optional.
        if (NULL == cacheSpecificData)
        {
            return;
        }

        // Get the IHttpCacheKey pointer from the 
        // IHttpCacheSpecificData pointer.
        IHttpCacheKey* cacheKey = 
            cacheSpecificData->GetCacheKey();

        // If the cacheKey is non-NULL, get its name.
        // This may allow downcasting to a more specific 
        // IHttpCacheSpecificData pointer type.
        if (NULL != cacheKey)
        {
            // Get the cache name from the cacheKey.
            wstring cacheKeyName = cacheKey->GetCacheName();

            // If the cacheKeyName is TOKEN_CACHE_NAME, the
            // IHttpCacheSpecificData pointer can be 
            // downcast to an IHttpTokenEntry pointer.
            if (TOKEN_CACHE_NAME == cacheKeyName)
            {
                // Attempt to cast the IHttpCacheSpecificData 
                // pointer to an IHttpTokenEntry pointer.                
                IHttpTokenEntry* tokenEntry =
                    dynamic_cast<IHttpTokenEntry*>(cacheSpecificData);
                // Write the IHttpTokenEntry pointer
                // information to the event log.
                Write(tokenEntry);
            }
        }
    }

private:
    // Specify the event 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
// CGlobalCacheModule::RegisterGlobalModule
// method.
HRESULT
__stdcall
RegisterModule(
    DWORD dwServerVersion,
    IHttpModuleRegistrationInfo* pModuleInfo,
    IHttpServer* pGlobalInfo
)
{        
    // Call the static method for initialization.
    return CGlobalCacheModule::RegisterGlobalModule            
        (dwServerVersion, 
         pModuleInfo, 
         pGlobalInfo);             
}

上述程式碼會將新的事件寫入事件檢視器,其中 [資料] 方塊包含類似下列的字串。

IHttpTokenEntry::GetSid: valid  

您的模組必須匯出 RegisterModule 函式。 您可以為專案建立模組定義 (.def) 檔案,或使用 參數編譯模組 /EXPORT:RegisterModule 來匯出此函式。 如需詳細資訊,請參閱 逐步解說:使用機器碼建立 Request-Level HTTP 模組

您可以選擇性地使用呼叫慣例編譯器代碼, __stdcall (/Gz) 而不是明確宣告每個函式的呼叫慣例。

規格需求

類型 描述
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
標頭 Httpserv.h

另請參閱

IHttpTokenEntry 介面