Share via


Sinkutil.cpp (Post-Categorizer)

Sinkutil.cpp

Important This sample code may not fully verify that strings passed to it are in fact null-terminated, nor that the referenced string buffers are large enough to store the generated contents. Your production code should always verify the validity and size of data passed as null-terminated strings before using, copying or adding to them. Using more-safe versions of the standard C string-handling functions is also recommended.

//------------------------------------------------------------
//
// File: Sinkutil.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-------------------------------------------------------------

#include "stdafx.h"
#include "SinkUtil.h"
#include "crtdbg.h"
#include "stdio.h"
#include "windows.h"
#include "string.h"

//-------------------------------------------------------------
//
// Function: ConvertStringtoCLSID
//
// Synopsis: Utility function to convert a string to a GUID. Uses CLSIDFromString
//
// Arguments:
//      [in]
//      LPSTR pszString,
//
//      [out]
//      LPGUID pguid)
//
// Returns:
//          S_OK if the function succeeded
//
//-------------------------------------------------------------
HRESULT ConvertStringtoCLSID(
    LPSTR pszString,
    LPGUID pguid)
{
    #define GUID_STRING_SIZE 39

    HRESULT hr= S_OK;
    WCHAR szWGuid[GUID_STRING_SIZE];
    LPSTR pszSrc;
    LPWSTR pszWDest;
    PCFunctEnterEx((LPARAM)0, "ConvertStringtoCLSID");

    if(pszString == NULL) {
        hr = E_INVALIDARG;
        goto CLEANUP;
    }

    pszSrc = pszString;

    if(*pszSrc != '{') {

        PCDebugTraceEx((LPARAM)0,"GUID should start with '{'");
        hr = E_INVALIDARG;
        goto CLEANUP;
    }

    // Convert to Unicode while you are copying to your temporary buffer.
    // Do not worry about non-ANSI characters; this is a GUID string.

    pszWDest = szWGuid;

    while((*pszSrc) && (*pszSrc != '}') &&
          (pszWDest &#060 &szWGuid[GUID_STRING_SIZE - 2])) {

        *pszWDest++ = *pszSrc++;
    }

    // On success, pszSrc will point to '}' (the last character of the GUID string).

    if(*pszSrc != '}') {

        PCDebugTraceEx((LPARAM)0,"End of GUID not found");
        hr = E_INVALIDARG;
        goto CLEANUP;
    }


    // pszDest will still be in range and have two chars left thanks
    // to the condition in the preceding while loop.

    *pszWDest++ = '}';
    *pszWDest = '\0';

    // Borrow the functionality of CLSIDFromString to get the 16-byte
    // GUID from the GUID string.

     hr = CLSIDFromString(
        szWGuid,
        pguid);

 CLEANUP:

    PCDebugTraceEx((LPARAM)0, "result %08lx", hr);
    PCFunctLeaveEx((LPARAM)0);
    return hr;
}

//------------------------------------------------------------
//
// Function: ShowMessage
//
// Synopsis: Utility function to display string in the debugger
//
// Arguments:
//      [in]
//      LPTSTR szMessage,
//      ...                     - variable argument list
//
// Returns:
//          S_OK if the function succeeded
//
//------------------------------------------------------------

BOOL ShowMessage(
    LPTSTR szMessage, ...)
{
    BOOL fRet = TRUE;
    LPSTR pszErrorMessage = NULL;
    BOOL fFormatMessage = FALSE;
    TCHAR szBuffer[1024];
    LPTSTR psz;

    va_list ap;
    va_start(ap, szMessage);

    if(vswprintf_s (szBuffer, ARRAYSIZE(szBuffer), szMessage, ap) &#060=
       0)
      {
         goto CLEANUP;
      }

    _ASSERT(lstrlen(szBuffer) + 1 &#060 sizeof(szBuffer));

    psz = szBuffer + lstrlen(szBuffer);
    if(*psz != '\n')
    { // Append a CRLF
        *psz++ = '\r';
        *psz++ = '\n';
        *psz = '\0';
    }
    OutputDebugString(szBuffer);                                                    \

    CLEANUP:

    return fRet;
}



//------------------------------------------------------------
//
// Function: CAttrEntry::operator new
//
// Synopsis: Operator overload new function to set the attribute name and GUID easily
//
// Arguments:
//
//  size_t - [in] passed in sizeof CAttrEntry
//  pszName - [in] Name of attribute
//  pszGuid -   [in] Stringised GUID
//
// Returns:
//  pMem if allocation is successful; otherwise returns NULL
//
//-------------------------------------------------------------
void * CAttrEntry::operator new(size_t size, TCHAR * pszName, TCHAR * pszGuid)
{
    HRESULT hr = S_OK;
    CAttrEntry * pAttrTemp = NULL;
    BYTE * pMem = new BYTE[size + lstrlen(pszName)+1];
    if(!pMem) {
        hr = E_OUTOFMEMORY;
        goto CLEANUP;
    }
    pAttrTemp = (CAttrEntry *) pMem;
    pAttrTemp->m_pszAttrName = (TCHAR *) (pMem + size);
    strcpy_s(pAttrTemp->m_pszAttrName,size,pszName);

    hr = ConvertStringtoCLSID(
        pszGuid,
        &(pAttrTemp->m_gGuid));

    if (FAILED(hr))
        goto CLEANUP;

    CLEANUP:
        if (FAILED(hr)) {
            if (pMem) {
                delete [] pMem;
                pMem = NULL;
            }
        }
        return (PVOID) pMem;
}

//------------------------------------------------------------
//
// Function: CAttrEntry::operator delete
//
// Synopsis: Operator overload delete function
//
// Arguments:
//
//  size_t - [in] passed in sizeof CAttrEntry
//  p - [in] Pointer to Memory
//
//
//
//-------------------------------------------------------------

void  CAttrEntry::operator delete(void *pMem, size_t size)
{
    delete [] (PBYTE) pMem;
}

//------------------------------------------------------------
//
// Function: CAttrList::AddEntry
//
// Synopsis: Linklist utility to add entries to a list
//
// Arguments:
//
//  pszName - [in] Name of attribute
//  pszGuid -   [in] Stringised GUID
//
// Returns:
//  S_OK if successful
//
//-------------------------------------------------------------
HRESULT CAttrList::AddEntry(TCHAR * pszName, TCHAR * pszGuid)
{
    HRESULT hr = S_OK;
    CAttrEntry * pNewEntry;
    pNewEntry = new (pszName, pszGuid) CAttrEntry();
    if(!pNewEntry) {
        hr = E_OUTOFMEMORY;
        goto CLEANUP;
    }

    if(m_pHead == NULL)
        m_pHead = m_pTail = pNewEntry;
    else {
        m_pTail->m_pNext = pNewEntry;
        m_pTail = pNewEntry;
        m_pTail->m_pNext = NULL;
    }
    m_dwEntries++;

    CLEANUP:
    return hr;
}

//------------------------------------------------------------
//
// Function: HrReadRegParams
//
// Synopsis: Reads the same registry keys set for the CatReader and CatReadex Sinks
//           Reads Clients attributes from registry. It then maintains a list
//           of them.
//           The following is the format in which the client must add attributes to the
//           registry. Customers who use this sink must create and associate a new GUID for
//           each required attribute. Both the GUID and attribute names are of the REG_SZ type.
//
//          [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\CatReader]
//              "officeLocation"="{8C515674-E27B-4924-95BD-7CB0FB24D9B1}"
//              "sAMAccountType"="{AC515674-E27B-4924-95BD-7CB0FB24D9B2}"
//
//
// Arguments:
//      CAttrList *pAttrList - The Link List
//
// Returns:
//  S_OK if successful
//
//------------------------------------------------------------
HRESULT HrReadRegParams(CAttrList * pAttrList)
{
    #define MAX_ATTR_SIZE 256
    #define MAX_GUID_SIZE 40

    HRESULT hr = S_OK;
    LONG    lError = 0;
    HKEY    hKey = NULL;
    TCHAR szBuffer[MAX_ATTR_SIZE] ;
    TCHAR szGuid[MAX_GUID_SIZE];
    DWORD dwSize = MAX_ATTR_SIZE ;
    DWORD dwIndex = 0;
    DWORD   dwType = 0;
    DWORD   dwcbGuid = MAX_GUID_SIZE;

    PCFunctEnter("HrReadRegParams");


    lError = RegOpenKeyEx(
        HKEY_LOCAL_MACHINE,
        PC_REGKEY_PATH,
        0,
        KEY_READ,
        &hKey);
    hr = HRESULT_FROM_WIN32(lError);
    if(FAILED(hr)) {
        PCErrorTraceEx((LPARAM)0, "Unable to open RegKey %s",
        PC_REGKEY_PATH);
        goto CLEANUP;
    }


    // Enumerate all values of the key.
    // When there are no more values, it should return ERROR_NO_MORE_ITEMS.

    lError = RegEnumValue(hKey,
        dwIndex,
        szBuffer,
        &dwSize,
        NULL,
        &dwType,
        (LPBYTE) szGuid,
        &dwcbGuid);
    hr = HRESULT_FROM_WIN32(lError);

    while ( SUCCEEDED(hr) ) {
        if(dwType == REG_SZ) {
            PCDebugTraceEx((LPARAM)0, "Found Attribute %s Guid %s",
                szBuffer, szGuid);
            hr = pAttrList->AddEntry(szBuffer, szGuid);
            if(FAILED(hr))
                goto CLEANUP;
        }
        else {
            // There might be other good registry keys.
            PCDebugTraceEx((LPARAM)0, "Reg Value %s Not String Type",
                szBuffer);
        }
        dwIndex++;
        dwSize = MAX_ATTR_SIZE;
        dwcbGuid = MAX_GUID_SIZE;

        lError = RegEnumValue(hKey,
            dwIndex,
            szBuffer,
            &dwSize,
            NULL,
            &dwType,
            (LPBYTE) szGuid,
            &dwcbGuid);

        hr = HRESULT_FROM_WIN32(lError);
    }

    if(hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
        hr = S_OK;

    if(FAILED(hr)) {
        PCErrorTraceEx((LPARAM)0, "Reading registry failed. Initialization failed.");
        goto CLEANUP;
    }

    //
    // Attributes were found.
    //
    if ( pAttrList->ListCount() > 0 ) {
        hr  = S_OK;
    }
    else {
        hr = E_FAIL;
        PCErrorTraceEx((LPARAM)0, "No attributes were found in the registry.");
        goto CLEANUP;
    }

 CLEANUP:
    if(hKey != NULL)
        RegCloseKey(hKey);

    PCDebugTraceEx((LPARAM)0, "result %08lx", hr);
    PCDebugTraceEx((LPARAM)0, "returning S_OK", hr);
    PCFunctLeave();
    return hr;
}