Esempio n. 1
0
    METADATA_RECORD mrPluginId;
    ::ZeroMemory(&mrPluginId, sizeof(mrPluginId));

    mrPluginId.dwMDIdentifier = MD_LOG_PLUGIN_MOD_ID;
    mrPluginId.dwMDAttributes = METADATA_INHERIT;
    mrPluginId.dwMDUserType = IIS_MD_UT_SERVER;
    mrPluginId.dwMDDataType = ALL_METADATA;
    mrPluginId.dwMDDataLen = 0;
    mrPluginId.pbMDData = NULL;
    
    hr = ::StringCchPrintfW(wzKey, countof(wzKey), L"/LM/Logging/%s", wzLogFormat);
    ExitOnFailure(hr, "failed to format logging metabase key name");

    // verify that we have this log format available in IIS
    hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mrKeyType);
    ExitOnFailure1(hr, "Failed to find specified Log format key in IIS for log format: %ls", wzLogFormat);
    ExitOnNull(mrKeyType.pbMDData, hr, E_POINTER, "Request for Log format key in IIS for log format returned success, but value was NULL");

    if (0 != lstrcmpW(L"IIsLogModule", (LPCWSTR)mrKeyType.pbMDData))
    {
        ExitOnFailure1(hr = E_UNEXPECTED, "Found invalid log format in IIS: %ls", (LPCWSTR)mrKeyType.pbMDData);
    }

    // find the GUID for that log format
    hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzKey, &mrPluginId);
    ExitOnFailure1(hr, "Failed to retrieve IISLog format GUID. Key: %ls", wzKey);
    ExitOnNull(mrPluginId.pbMDData, hr, E_POINTER, "Retrieval of IISLog format GUID returned success, but value was NULL");

    hr = ::StringCchCopyW(wzGUID, cchGUID, (LPCWSTR)mrPluginId.pbMDData);
    ExitOnFailure1(hr, "failed to copy metabase value: %ls", (LPCWSTR)mrPluginId.pbMDData);
Esempio n. 2
0
HRESULT ScaWriteWebError(IMSAdminBase* piMetabase, int iParentType, LPCWSTR wzRoot, SCA_WEB_ERROR* psweList)
{
//    AssertSz(0, "Debug ScaWriteWebError here");
    Assert(*wzRoot && psweList);

    HRESULT hr = S_OK;

    DWORD cchData = 0;
    LPWSTR pwzSearchKey = NULL;
    LPWSTR pwz = NULL;
    LPWSTR pwzErrors = NULL;

    LPWSTR pwzCodeSubCode = NULL;
    LPWSTR pwzAcceptableCodeSubCode = NULL;
    LPCWSTR wzFoundCodeSubCode = NULL;
    DWORD_PTR dwFoundCodeSubCodeIndex = 0xFFFFFFFF;
    BOOL fOldValueFound = FALSE;
    LPWSTR pwzAcceptableErrors = NULL;

    LPWSTR pwzNewError = NULL;

    METADATA_RECORD mr;
    ::ZeroMemory(&mr, sizeof(mr));

    ExitOnNull(piMetabase, hr, E_INVALIDARG, "Failed to write web error, because no metabase was provided");
    ExitOnNull(wzRoot, hr, E_INVALIDARG, "Failed to write web error, because no root was provided");

    // get the set of all valid custom errors from the metabase
    mr.dwMDIdentifier = MD_CUSTOM_ERROR_DESC;
    mr.dwMDAttributes = METADATA_INHERIT;
    mr.dwMDUserType = IIS_MD_UT_SERVER;
    mr.dwMDDataType = ALL_METADATA;
    mr.dwMDDataLen = cchData = 0;
    mr.pbMDData = NULL;

    hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC/Info", &mr);
    ExitOnFailure(hr, "Unable to get set of acceptable error codes for this server.");

    pwzAcceptableErrors = reinterpret_cast<LPWSTR>(mr.pbMDData);

    // Check if web errors already exist here
    mr.dwMDIdentifier = MD_CUSTOM_ERROR;
    mr.dwMDAttributes = METADATA_INHERIT;
    mr.dwMDUserType = IIS_MD_UT_SERVER;
    mr.dwMDDataType = ALL_METADATA;
    mr.dwMDDataLen = cchData = 0;
    mr.pbMDData = NULL;

    hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzRoot, &mr);
    if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr)
    {
        //
        // If we don't have one already, find an appropriate one to start with
        //

        // we can walk up key by key and look for custom errors to inherit

        hr = StrAllocConcat(&pwzSearchKey, wzRoot, 0);
        ExitOnFailure1(hr, "Failed to copy root string: %ls", wzRoot);

        pwz = pwzSearchKey + lstrlenW(pwzSearchKey);

        while (NULL == pwzErrors)
        {
            // find the last slash
            while (*pwz != '/' && pwz != pwzSearchKey)
                pwz --;

            if (pwz == pwzSearchKey)
                break;

            *pwz = L'\0';

            // Try here.  If it's not found, keep walking up the path
            hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, pwzSearchKey, &mr);
            if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr)
                hr = S_FALSE;
            ExitOnFailure1(hr, "failed to discover default error values to start with for web root: %ls while walking up the tree", wzRoot);

            if (S_OK == hr)
            {
                pwzErrors = reinterpret_cast<LPWSTR>(mr.pbMDData);
                break;
            }

            // Don't keep going if we're at the root
            if (0 == lstrcmpW(pwz + 1, L"W3SVC"))
                break;
        }
    }
    else
    {
        pwzErrors = reinterpret_cast<LPWSTR>(mr.pbMDData);
    }
    ExitOnFailure1(hr, "failed to discover default error values to start with for web root: %ls", wzRoot);

    // The above code should have come up with some value to start pwzErrors off with.  Make sure it did.
    if (NULL == pwzErrors)
    {
        ExitOnFailure1(hr = E_UNEXPECTED, "failed to discover default error values to start with for web root: %ls", wzRoot);
    }

    // Loop through the web errors
    for (SCA_WEB_ERROR* pswe = psweList; pswe; pswe = pswe->psweNext)
    {
        // Assume that we will have to replace 
        fOldValueFound = TRUE;

        // If the subcode is 0, that means "*" in MD_CUSTOM_ERROR (thus the special formatting logic)
        if (0 == pswe->iSubCode)
        {
            hr = StrAllocFormatted(&pwzCodeSubCode, L"%d,*", pswe->iErrorCode);
            ExitOnFailure(hr, "failed to create error code string while installing web error");
        }
        else
        {
            hr = StrAllocFormatted(&pwzCodeSubCode, L"%d,%d", pswe->iErrorCode, pswe->iSubCode);
            ExitOnFailure(hr, "failed to create error code,subcode string while installing web error");
        }

        hr = MultiSzFindSubstring(pwzErrors, pwzCodeSubCode, &dwFoundCodeSubCodeIndex, &wzFoundCodeSubCode);
        ExitOnFailure1(hr, "failed to find existing error code,subcode: %ls", pwzCodeSubCode);

        // If we didn't find this error code/sub code pair in the list already, make sure it's acceptable to add
        if (S_FALSE == hr)
        {
            //
            // Make sure this error code/sub code pair is in the "acceptable" list
            //

            // If the subcode is 0, that means "0" in MD_CUSTOM_ERROR_DESC (no special formatting logic needed)
            hr = StrAllocFormatted(&pwzAcceptableCodeSubCode, L"%d,%d", pswe->iErrorCode, pswe->iSubCode);
            ExitOnFailure(hr, "failed to create error code,subcode string while installing web error");

            // We don't care where it is, just whether it's there or not
            hr = MultiSzFindSubstring(pwzAcceptableErrors, pwzAcceptableCodeSubCode, NULL, NULL);
            ExitOnFailure1(hr, "failed to find whether or not error code, subcode: %ls is supported", pwzCodeSubCode);

            if (S_FALSE == hr)
            {
                WcaLog(LOGMSG_VERBOSE, "Skipping error code, subcode: %ls because it is not supported by the server.", pwzCodeSubCode);
                continue;
            }

            // If we didn't find it (and its an acceptable error) then we have nothing to replace
            fOldValueFound = FALSE;
        }

        // Set up the new error string if needed
        if (*(pswe->wzFile))
        {
            hr = StrAllocFormatted(&pwzNewError, L"%s,FILE,%s", pwzCodeSubCode, pswe->wzFile);
            ExitOnFailure2(hr, "failed to create new error code string with code,subcode: %ls, file: %ls", pwzCodeSubCode, pswe->wzFile);
        }
        else if (*(pswe->wzURL))
        {
            hr = StrAllocFormatted(&pwzNewError, L"%s,URL,%s", pwzCodeSubCode, pswe->wzURL);
            ExitOnFailure2(hr, "failed to create new error code string with code,subcode: %ls, file: %ls", pwzCodeSubCode, pswe->wzFile);
        }
        else if (fOldValueFound)
        {
            // If no File or URL was specified, they want a default error so remove the old value from the MULTISZ and move on
            hr = MultiSzRemoveString(&pwzErrors, dwFoundCodeSubCodeIndex);
            ExitOnFailure1(hr, "failed to remove string for error code sub code: %ls in order to make it 'default'", pwzCodeSubCode);
            continue;
        }

        // If we have something to replace, replace it, otherwise, put it at the beginning (order shouldn't matter)
        if (fOldValueFound)
        {
            hr = MultiSzReplaceString(&pwzErrors, dwFoundCodeSubCodeIndex, pwzNewError);
            ExitOnFailure1(hr, "failed to replace old error string with new error string for error code,subcode: %ls", pwzCodeSubCode);
        }
        else
        {
            hr = MultiSzPrepend(&pwzErrors, NULL, pwzNewError);
            ExitOnFailure1(hr, "failed to prepend new error string for error code,subcode: %ls", pwzCodeSubCode);
        }
    }

    // now write the CustomErrors to the metabase
    if (weptWeb == iParentType)
    {
        hr = ScaWriteMetabaseValue(piMetabase, wzRoot, L"/Root", MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzErrors);
        ExitOnFailure(hr, "Failed to write Web Error to /Root");
    }
    else
    {
        hr = ScaWriteMetabaseValue(piMetabase, wzRoot, NULL, MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzErrors);
        ExitOnFailure(hr, "Failed to write Web Error");
    }

LExit:
    ReleaseStr(pwzErrors);
    ReleaseStr(pwzSearchKey);
    ReleaseStr(pwzCodeSubCode);
    ReleaseStr(pwzAcceptableCodeSubCode);
    ReleaseStr(pwzAcceptableErrors);

    return hr;
}