Update of /cvsroot/wix/wix/src/ca/serverca/scasched In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18778/src/ca/serverca/scasched Modified Files: scasched.cpp scavdir.cpp scavdir.h scaweb.cpp scaweb.h scaweberr.cpp scaweberr.h scaweblog.cpp scawebprop.cpp scawebsvcext.cpp Log Message: sca - support no logging for all websites sca - support INTERACTIVE user in secureobj sca - fix many small code quality/crash prevention bugs wixca - support XmlFile processing tallow - don't print out invalid Registry/@Name attributes votive - small fixes, lots of clean-up votive - install wixui libraries binder - better error reporting when cab can't find files linker - correctly handle ControlEventArg modularization compiler - remove deprecated code compiler - add support for new XmlFile action dark - clean up dark to not use old deprecated code paths localizer - allow same codepage to be provided multiple times localizer - allow comments at top of file Index: scavdir.h =================================================================== RCS file: /cvsroot/wix/wix/src/ca/serverca/scasched/scavdir.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** scavdir.h 2 May 2005 05:48:37 -0000 1.1 --- scavdir.h 20 Aug 2005 11:48:54 -0000 1.2 *************** *** 51,55 **** // mime mappings ! struct SCA_MIMEMAP* psmm; SCA_VDIR* psvdNext; --- 51,58 ---- // mime mappings ! SCA_MIMEMAP* psmm; ! ! // custom web errors ! SCA_WEB_ERROR* pswe; SCA_VDIR* psvdNext; *************** *** 57,61 **** HRESULT __stdcall ScaVirtualDirsRead(IMSAdminBase* piMetabase, ! SCA_WEB* pswList, SCA_VDIR** ppsvdList, SCA_MIMEMAP** ppsmmList); HRESULT ScaVirtualDirsInstall(IMSAdminBase* piMetabase, SCA_VDIR* psvdList, SCA_APPPOOL * psapList); --- 60,64 ---- HRESULT __stdcall ScaVirtualDirsRead(IMSAdminBase* piMetabase, ! SCA_WEB* pswList, SCA_VDIR** ppsvdList, SCA_MIMEMAP** ppsmmList, SCA_WEB_ERROR** ppsweList); HRESULT ScaVirtualDirsInstall(IMSAdminBase* piMetabase, SCA_VDIR* psvdList, SCA_APPPOOL * psapList); Index: scaweb.cpp =================================================================== RCS file: /cvsroot/wix/wix/src/ca/serverca/scasched/scaweb.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** scaweb.cpp 7 Jul 2005 00:29:51 -0000 1.2 --- scaweb.cpp 20 Aug 2005 11:48:54 -0000 1.3 *************** *** 55,59 **** HRESULT ScaWebsRead(IMSAdminBase* piMetabase, ! SCA_WEB** ppswList) { Assert(piMetabase && ppswList); --- 55,59 ---- HRESULT ScaWebsRead(IMSAdminBase* piMetabase, ! SCA_WEB** ppswList, SCA_WEB_ERROR** ppsweList) { Assert(piMetabase && ppswList); *************** *** 280,285 **** // get the errors ! hr = ScaGetWebErrors(piMetabase, psw->wzKey, &psw->psweList); ! ExitOnFailure(hr, "Failed to get Custom Errors"); // get the log information for this web --- 280,288 ---- // get the errors ! if ( *ppsweList) ! { ! hr = ScaGetWebError(weptWeb, psw->wzKey, ppsweList, &(psw->psweList)); ! ExitOnFailure(hr, "Failed to get Custom Errors"); ! } // get the log information for this web *************** *** 434,438 **** // Free the errors list first ! ScaWebErrorsFreeList(pswDelete->psweList); ::HeapFree(::GetProcessHeap(), 0, pswDelete); } --- 437,441 ---- // Free the errors list first ! ScaWebErrorFreeList(pswDelete->psweList); ::HeapFree(::GetProcessHeap(), 0, pswDelete); } *************** *** 863,868 **** // write the errors ! hr = ScaWriteWebErrors(piMetabase, psw->wzWebBase, psw->psweList); ! ExitOnFailure(hr, "Failed to write Custom Errors"); // write the log information to the metabase --- 866,874 ---- // write the errors ! if (psw->psweList) ! { ! hr = ScaWriteWebError(piMetabase, weptWeb, psw->wzWebBase, psw->psweList); ! ExitOnFailure1(hr, "Failed to write custom web errors for Web site: %S", psw->wzKey); ! } // write the log information to the metabase Index: scavdir.cpp =================================================================== RCS file: /cvsroot/wix/wix/src/ca/serverca/scasched/scavdir.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** scavdir.cpp 2 May 2005 05:48:37 -0000 1.1 --- scavdir.cpp 20 Aug 2005 11:48:54 -0000 1.2 *************** *** 31,35 **** HRESULT __stdcall ScaVirtualDirsRead(IMSAdminBase* piMetabase, ! SCA_WEB* pswList, SCA_VDIR** ppsvdList, SCA_MIMEMAP** ppsmmList) { Assert(piMetabase && ppsvdList); --- 31,35 ---- HRESULT __stdcall ScaVirtualDirsRead(IMSAdminBase* piMetabase, ! SCA_WEB* pswList, SCA_VDIR** ppsvdList, SCA_MIMEMAP** ppsmmList, SCA_WEB_ERROR** ppsweList) { Assert(piMetabase && ppsvdList); *************** *** 131,143 **** pvdir->fHasApplication = TRUE; } ! if (*ppsmmList) { ! hr = WcaGetRecordString(hRec, vdqVDir, &pwzData); ! ExitOnFailure(hr, "Failed to get VDir for VirtualDir"); ! if (*pwzData) ! { ! hr = ScaGetMimeMap(mmptVDir, pwzData, ppsmmList, &pvdir->psmm); ! ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); ! } } } --- 131,148 ---- pvdir->fHasApplication = TRUE; } ! ! hr = WcaGetRecordString(hRec, vdqVDir, &pwzData); ! ExitOnFailure(hr, "Failed to get VDir for VirtualDir"); ! ! if (*pwzData && *ppsmmList) { ! hr = ScaGetMimeMap(mmptVDir, pwzData, ppsmmList, &pvdir->psmm); ! ExitOnFailure(hr, "Failed to get mimemap for VirtualDir"); ! } ! ! if (*pwzData && *ppsweList) ! { ! hr = ScaGetWebError(weptVDir, pwzData, ppsweList, &pvdir->pswe); ! ExitOnFailure(hr, "Failed to get custom web errors for VirtualDir"); } } *************** *** 187,190 **** --- 192,196 ---- ExitOnFailure(hr, "Failed to write application for VirtualDir"); } + if (psvd->psmm) { *************** *** 192,195 **** --- 198,207 ---- ExitOnFailure(hr, "Failed to write mimemap for VirtualDir"); } + + if (psvd->pswe) + { + hr = ScaWriteWebError(piMetabase, weptVDir, psvd->wzVDirRoot, psvd->pswe); + ExitOnFailure(hr, "Failed to write custom web errors for VirtualDir"); + } } *************** *** 238,241 **** --- 250,258 ---- } + if (psvdDelete->pswe) + { + ScaWebErrorFreeList(psvdDelete->pswe); + } + ::HeapFree(::GetProcessHeap(), 0, psvdDelete); } Index: scaweberr.cpp =================================================================== RCS file: /cvsroot/wix/wix/src/ca/serverca/scasched/scaweberr.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** scaweberr.cpp 2 May 2005 05:48:37 -0000 1.1 --- scaweberr.cpp 20 Aug 2005 11:48:54 -0000 1.2 *************** *** 19,597 **** #include "precomp.h" ! // types ! LPCWSTR vcsTypeDefault = L"DEFAULT"; ! LPCWSTR vcsTypeFile = L"FILE"; ! LPCWSTR vcsTypeUrl = L"URL"; ! // temporary buffer sizes ! // adjust as necessary - this is enough for currently supported error codes ! const UINT MAX_ERRORS = 64; ! // must be able to hold null-terminated records in the following format ! // [error code (3 digits max)],[sub code (3 digits max)],[type (FILE|URL = 4 chars max)],[path (MAX_ERROR_PATHLENGTH)] ! // = 13 characters + MAX_ERROR_PATHLENGTH + 1 null ! const UINT MAX_ERROR_VALUELENGTH = 13 + MAX_ERROR_PATHLENGTH + 1; ! // must be able to hold a double terminating null ! const UINT MAX_ERROR_BUFFERSIZE = MAX_ERRORS * MAX_ERROR_VALUELENGTH + 1; ! // sql queries -- the set of selected columns must match the enum ! LPCWSTR vcsWebErrorQuerySubCodeNonNull = ! L"SELECT `ErrorCode`, `SubCode`, `Type`, `Web_`, `Component_`, `Path`, `VirtualDir_`, `FileName` " ! L"FROM `IIsWebError` WHERE `Web_`=? AND `SubCode` IS NOT NULL ORDER BY `ErrorCode`, `SubCode`"; ! LPCWSTR vcsWebErrorQuerySubCodeNull = ! L"SELECT `ErrorCode`, `SubCode`, `Type`, `Web_`, `Component_`, `Path`, `VirtualDir_`, `FileName` " ! L"FROM `IIsWebError` WHERE `Web_`=? AND `SubCode` IS NULL ORDER BY `ErrorCode`, `SubCode`"; ! enum eWebErrorQuery { weqErrorCode = 1, weqSubCode, weqType, weqWeb, weqComponent, weqPath, weqVirtualDir, weqFileName }; ! // prototypes for private helper functions ! int CompareSwek(SCA_WEB_ERROR_KEY swekL, SCA_WEB_ERROR_KEY swekR); ! HRESULT SortSwekValidKeys(SCA_WEB_ERROR_KEY_VALID rgswekValid[], UINT cKeys); ! HRESULT InitSweFromRecord(PMSIHANDLE hRec, SCA_WEB_ERROR *pswe, int iType); ! SCA_WEB_ERROR *AddWebErrorToList(SCA_WEB_ERROR *psweList); ! HRESULT ScaGetWebErrors(IMSAdminBase *piMetabase, LPCWSTR wzRootOfWeb, SCA_WEB_ERROR **ppsweList) { ! // AssertSz(FALSE, "Uncomment and place breakpoint on subsequent line to debug."); ! Assert(piMetabase && wzRootOfWeb && ppsweList); HRESULT hr = S_OK; PMSIHANDLE hView, hRec; - LPWSTR pwzData = NULL; ! DWORD cchData = 0; ! SCA_WEB_ERROR *pswe = NULL, *psweFirstForCode = NULL; ! UINT iKey = 0, cKeys = 0, cErrors = 0; ! int iType = 0; ! SCA_WEB_ERROR_KEY swekCurrent; ! ! WCHAR *pwzNext = NULL, *pwzComma = NULL; // used to properly read the MULTI_SZ ! WCHAR wzNumber[4]; // up to three digits plus NULL ! ! METADATA_RECORD mr; ! ::ZeroMemory(&mr, sizeof(mr)); ! SCA_WEB_ERROR_KEY_VALID rgswekValid[MAX_ERRORS]; ! ::ZeroMemory(rgswekValid, sizeof(rgswekValid)); ! ! // get the set of 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 valid custom error descriptions for this server."); ! pwzNext = (WCHAR*) mr.pbMDData; ! for (iKey = 0; iKey < MAX_ERRORS && pwzNext && *pwzNext; iKey++) ! { ! // look up to three digits plus the comma for the code ! for (pwzComma = pwzNext; pwzComma && *pwzComma && *pwzComma != L',' && pwzComma - pwzNext <= 4; pwzComma++); ! if (!pwzComma || *pwzComma != L',') ! ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA), "Could not find code.") ! hr = StringCchCopyNW(wzNumber, countof(wzNumber), pwzNext, pwzComma - pwzNext); ! ExitOnFailure(hr, "Could not copy number to buffer."); ! rgswekValid[iKey].swek.iErrorCode = _wtoi(wzNumber); ! // move past comma ! pwzNext = pwzComma + 1; ! ! // look up to three digits plus the comma for the sub code ! for (pwzComma = pwzNext; pwzComma && *pwzComma && *pwzComma != L',' && pwzComma - pwzNext <= 4; pwzComma++); ! if (!pwzComma || *pwzComma != L',') ! ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA), "Could not find sub code.") ! hr = StringCchCopyNW(wzNumber, countof(wzNumber), pwzNext, pwzComma - pwzNext); ! ExitOnFailure(hr, "Could not copy number to buffer."); ! rgswekValid[iKey].swek.iSubCode = _wtoi(wzNumber); ! // update to point to next string ! pwzNext += lstrlenW(pwzNext) + 1; ! } ! cKeys = iKey; ! Assert(cKeys < MAX_ERRORS); ! if (!(cKeys > 0 && cKeys < MAX_ERRORS)) ! ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA), "Number of custom error descritions for this server is invalid.") ! // sort keys ! hr = SortSwekValidKeys(rgswekValid, cKeys); ! ExitOnFailure(hr, "Sorting of valid keys failed."); ! // reset cchData since from here on out it'll be used in conjunction w/pwzData ! cchData = 0; ! // check to see what tables are available ! if (S_OK != WcaTableExists(L"IIsWebError")) ! { ! WcaLog(LOGMSG_VERBOSE, "Skipping ScaGetWebErrors() - required tables not present."); ! hr = S_FALSE; ! goto LExit; } ! // loop through all the errors in the MSI table w/non-null subcode and, ! // for each error, see if the error exists in the set of valid keys ! // if so, add the entry ! hr = WcaOpenView(vcsWebErrorQuerySubCodeNonNull, &hView); ! ExitOnFailure(hr, "Failed to open view on IIsWebError table of entries w/non-null sub codes"); ! ! hRec = ::MsiCreateRecord(1); ! if (!hRec) ! { ! hr = E_OUTOFMEMORY; ! ExitOnFailure(hr, "Failed to create record for lookup."); ! } ! hr = WcaSetRecordString(hRec, 1, wzRootOfWeb); ! ExitOnFailure(hr, "Failed to set current web for query"); ! ! hr = WcaExecuteView(hView, hRec); ! ExitOnFailure(hr, "Failed to execute view on IIsWebError table of entries w/non-null sub codes"); ! iKey = 0; ! while (iKey < cKeys && S_OK == (hr = WcaFetchRecord(hView, &hRec))) ! { ! #if DEBUG ! // check that web matches ! hr = WcaGetRecordString(hRec, weqWeb, &pwzData); ! ExitOnFailure(hr, "Failed to get IIsWebError.Web_"); ! Assert(0 == lstrcmpW(wzRootOfWeb, pwzData)); ! #endif ! // get type ! hr = WcaGetRecordInteger(hRec, weqType, &iType); ! ExitOnFailure(hr, "Failed to get IIsWebError.Type"); ! Assert(wetDefault == iType || wetFile == iType || wetUrl == iType); ! if (!(wetDefault == iType || wetFile == iType || wetUrl == iType)) ! { ! hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); ! ExitOnFailure(hr, "Invalid custom error type.") ! } ! // get error code ! hr = WcaGetRecordInteger(hRec, weqErrorCode, &swekCurrent.iErrorCode); ! ExitOnFailure(hr, "Failed to get IIsWebError.ErrorCode"); ! Assert(400 <= swekCurrent.iErrorCode && 600 > swekCurrent.iErrorCode); ! if (!(400 <= swekCurrent.iErrorCode && 600 > swekCurrent.iErrorCode)) ! { ! hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); ! ExitOnFailure(hr, "Invalid custom error code"); ! } ! // get sub code ! hr = WcaGetRecordInteger(hRec, weqSubCode, &swekCurrent.iSubCode); ! ExitOnFailure(hr, "Failed to get IIsWebError.SubCode"); ! Assert(0 <= swekCurrent.iSubCode && 1000 > swekCurrent.iSubCode); ! if (!(0 <= swekCurrent.iSubCode && 1000 > swekCurrent.iSubCode)) ! { ! hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); ! ExitOnFailure(hr, "Invalid custom error sub code"); ! } ! ! // skip any valid keys less than this error code, sub code ! for (; iKey < cKeys && CompareSwek(rgswekValid[iKey].swek, swekCurrent) < 0; iKey++); ! // if there is a matching key, handle entry (there should probably only be one) ! for (; iKey < cKeys && CompareSwek(rgswekValid[iKey].swek, swekCurrent) == 0; iKey++) { ! // skip the code if it has been handled ! if (rgswekValid[iKey].fHandled) ! continue; ! ! rgswekValid[iKey].fHandled = TRUE; ! ! // no entry is necessary for default ! if (wetDefault == iType) ! continue; ! // add an error entry if we don't have too many ! Assert(MAX_ERRORS > cErrors); ! if (!(MAX_ERRORS > cErrors)) { ! hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); ! ExitOnFailure(hr, "Too many custom error entries."); } ! cErrors++; ! ! *ppsweList = AddWebErrorToList(*ppsweList); ! if (!*ppsweList) { ! hr = E_OUTOFMEMORY; ! break; } ! pswe = *ppsweList; ! Assert(pswe); ! ! // copy the key ! pswe->swek.iErrorCode = swekCurrent.iErrorCode; ! pswe->swek.iSubCode = swekCurrent.iSubCode; ! ! // init values from record ! hr = InitSweFromRecord(hRec, pswe, iType); ! ExitOnFailure(hr, "Could not initialize entry from record."); ! ! // set the error NULL so it doesn't accidentally get freed below ! pswe = NULL; } } ! if (E_NOMOREITEMS == hr) ! hr = S_OK; ! ExitOnFailure(hr, "Failure while processing errors"); ! // loop through all the errors in the MSI table w/null subcode and, ! // for each error, find all matching errors in the set of valid keys ! // that haven't been set already and set the values appropriately ! hr = WcaOpenView(vcsWebErrorQuerySubCodeNull, &hView); ! ExitOnFailure(hr, "Failed to open view on IIsWebError table of entries w/null sub codes"); ! hRec = ::MsiCreateRecord(1); ! if (!hRec) ! { ! hr = E_OUTOFMEMORY; ! ExitOnFailure(hr, "Failed to create record for lookup."); ! } ! hr = WcaSetRecordString(hRec, 1, wzRootOfWeb); ! ExitOnFailure(hr, "Failed to set current web for query"); ! hr = WcaExecuteView(hView, hRec); ! ExitOnFailure(hr, "Failed to execute view on IIsWebError table of entries w/null sub codes"); ! iKey = 0; ! swekCurrent.iSubCode = 0; // we don't care about this in this loop ! while (iKey < cKeys && S_OK == (hr = WcaFetchRecord(hView, &hRec))) ! { ! #if DEBUG ! // check that web matches ! hr = WcaGetRecordString(hRec, weqWeb, &pwzData); ! ExitOnFailure(hr, "Failed to get IIsWebError.Web_"); ! Assert(0 == lstrcmpW(wzRootOfWeb, pwzData)); ! #endif ! // get type ! hr = WcaGetRecordInteger(hRec, weqType, &iType); ! ExitOnFailure(hr, "Failed to get IIsWebError.Type"); ! Assert(wetDefault == iType || wetFile == iType || wetUrl == iType); ! if (!(wetDefault == iType || wetFile == iType || wetUrl == iType)) ! { ! hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); ! ExitOnFailure(hr, "Invalid custom error type.") ! } ! // get error code ! hr = WcaGetRecordInteger(hRec, weqErrorCode, &swekCurrent.iErrorCode); ! ExitOnFailure(hr, "Failed to get IIsWebError.ErrorCode"); ! Assert(400 <= swekCurrent.iErrorCode && 600 > swekCurrent.iErrorCode); ! if (!(400 <= swekCurrent.iErrorCode && 600 > swekCurrent.iErrorCode)) ! { ! hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); ! ExitOnFailure(hr, "Invalid custom error code"); ! } ! #if DEBUG ! // check that sub code is null ! hr = WcaGetRecordInteger(hRec, weqSubCode, &swekCurrent.iSubCode); ! Assert(S_FALSE == hr); ! if (S_FALSE == hr) ! hr = S_OK; ! ExitOnFailure(hr, "Failed to get IIsWebError.SubCode"); ! #endif ! // skip any valid error codes less than this error code ! for (; iKey < cKeys && rgswekValid[iKey].swek.iErrorCode < swekCurrent.iErrorCode; iKey++) ! ; ! // for all matching error codes, handle entry ! psweFirstForCode = NULL; ! for (; iKey < cKeys && rgswekValid[iKey].swek.iErrorCode == swekCurrent.iErrorCode; iKey++) ! { ! // skip the code if it has been handled ! if (rgswekValid[iKey].fHandled) ! continue; ! rgswekValid[iKey].fHandled = TRUE; ! // no entry is necessary for default ! if (wetDefault == iType) ! continue; ! // add an error entry if we don't have too many ! Assert(MAX_ERRORS > cErrors); ! if (!(MAX_ERRORS > cErrors)) ! { ! hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); ! ExitOnFailure(hr, "Too many custom error entries."); ! } ! cErrors++; ! *ppsweList = AddWebErrorToList(*ppsweList); ! if (!*ppsweList) ! { ! hr = E_OUTOFMEMORY; ! break; ! } ! pswe = *ppsweList; ! Assert(pswe); ! // copy the key ! pswe->swek.iErrorCode = rgswekValid[iKey].swek.iErrorCode; ! pswe->swek.iSubCode = rgswekValid[iKey].swek.iSubCode; ! if (psweFirstForCode) ! { ! // copy from the first item w/this code for subsequent keys ! hr = StringCchCopyW(pswe->wzComponent, countof(pswe->wzComponent), psweFirstForCode->wzComponent); ! ExitOnFailure(hr, "Could not copy component from first entry."); ! pswe->isInstalled = psweFirstForCode->isInstalled; ! pswe->isAction = psweFirstForCode->isAction; ! pswe->wetType = psweFirstForCode->wetType; ! hr = StringCchCopyW(pswe->wzPath, countof(pswe->wzPath), psweFirstForCode->wzPath); ! ExitOnFailure(hr, "Could not copy path from first entry."); ! } ! else { ! // this is the first item w/this code--need to get values ! psweFirstForCode = pswe; ! ! // init values from record ! hr = InitSweFromRecord(hRec, pswe, iType); ! ExitOnFailure(hr, "Could not initialize entry from record."); } ! // set the error NULL so it doesn't accidentally get freed below ! pswe = NULL; } } ! if (E_NOMOREITEMS == hr) ! hr = S_OK; ! ExitOnFailure(hr, "Failure while processing errors"); ! ! LExit: ! MetaFreeValue(&mr); ! ! if (pswe) ! ScaWebErrorsFreeList(pswe); ! ! ReleaseStr(pwzData); ! return hr; ! } ! ! int CompareSwek(SCA_WEB_ERROR_KEY swekL, SCA_WEB_ERROR_KEY swekR) ! { ! return swekL.iErrorCode != swekR.iErrorCode ? ! swekL.iErrorCode - swekR.iErrorCode : ! swekL.iSubCode - swekR.iSubCode; ! } ! ! HRESULT SortSwekValidKeys(SCA_WEB_ERROR_KEY_VALID rgswekValid[], UINT cKeys) ! { ! HRESULT hr = S_OK; ! UINT iKey, iKeyMin, cKeysProcessed; ! SCA_WEB_ERROR_KEY_VALID swekValidMin; ! ! Assert(rgswekValid && cKeys > 0); ! if (!(rgswekValid && cKeys > 0)) ! ExitOnFailure(hr = E_INVALIDARG, "Invalid args to the SortSwekValidKeys"); ! // Simple selection sort ! for (cKeysProcessed = 0; cKeysProcessed < cKeys; cKeysProcessed++) { ! iKeyMin = cKeysProcessed; ! // Look for the smallest remaining key ! for (iKey = iKeyMin + 1; iKey < cKeys; iKey++) { ! if (CompareSwek(rgswekValid[iKeyMin].swek, rgswekValid[iKey].swek) > 0) ! iKeyMin = iKey; } ! ! // If a smaller key has been found, swap ! Assert(iKeyMin >= cKeysProcessed); ! if (iKeyMin > cKeysProcessed) { ! swekValidMin.swek.iErrorCode = rgswekValid[iKeyMin].swek.iErrorCode; ! swekValidMin.swek.iSubCode = rgswekValid[iKeyMin].swek.iSubCode; ! swekValidMin.fHandled = rgswekValid[iKeyMin].fHandled; ! ! rgswekValid[iKeyMin].swek.iErrorCode = rgswekValid[cKeysProcessed].swek.iErrorCode; ! rgswekValid[iKeyMin].swek.iSubCode = rgswekValid[cKeysProcessed].swek.iSubCode; ! rgswekValid[iKeyMin].fHandled = rgswekValid[cKeysProcessed].fHandled; ! ! rgswekValid[cKeysProcessed].swek.iErrorCode = swekValidMin.swek.iErrorCode; ! rgswekValid[cKeysProcessed].swek.iSubCode = swekValidMin.swek.iSubCode; ! rgswekValid[cKeysProcessed].fHandled = swekValidMin.fHandled; } - } ! LExit: ! return hr; ! } ! HRESULT InitSweFromRecord(PMSIHANDLE hRec, SCA_WEB_ERROR *pswe, int iType) ! { ! Assert(hRec && pswe && (wetFile == iType || wetUrl == iType)); ! HRESULT hr = S_OK; ! UINT er = ERROR_SUCCESS; ! LPWSTR pwzData = NULL; ! LPWSTR pwzData2 = NULL; ! LPWSTR pwzVirtualDir = NULL; ! DWORD dwLen; ! DWORD dwNonSlash; ! ExitOnNull(pswe, hr, E_INVALIDARG, "pswe was null"); ! // set the type and get the error page path or url ! pswe->wetType = (eWebErrorType) iType; ! if (wetFile == pswe->wetType) ! { ! // get path to error page ! hr = WcaGetRecordFormattedString(hRec, weqPath, &pwzData); ! ExitOnFailure(hr, "Failed to get IIsWebError.Path"); ! hr = StringCchCopyW(pswe->wzPath, countof(pswe->wzPath), pwzData); ! ExitOnFailure(hr, "Failed to copy path to entry"); ! // get component from Component_ column ! hr = WcaGetRecordString(hRec, weqComponent, &pwzData); ! ExitOnFailure(hr, "Failed to get IIsWebError.Component_"); ! hr = StringCchCopyW(pswe->wzComponent, countof(pswe->wzComponent), pwzData); ! ExitOnFailure(hr, "Failed to copy component to entry"); ! } ! else ! { ! // get virtual directory to error page ! hr = WcaGetRecordString(hRec, weqVirtualDir, &pwzVirtualDir); ! ExitOnFailure(hr, "Failed to get IIsWebError.VirtualDir_"); ! // get url path from alias and filename ! hr = ScaVirtualDirGetAlias(pwzVirtualDir, &pwzData); ! ExitOnFailure(hr, "Failed to get Alias from VirtualDir for IIsWebError"); ! // remove trailing forward-slash(es) ! dwLen = lstrlenW(pwzData); ! while (dwLen > 0 && pwzData[dwLen-1] == L'/') { ! pwzData[dwLen-1] = L'\0'; ! dwLen--; } ! // find the first non-forward-slash ! dwNonSlash = 0; ! while (dwNonSlash < dwLen && pwzData[dwNonSlash] == L'/') { ! dwNonSlash++; } - hr = WcaGetRecordString(hRec, weqFileName, &pwzData2); - ExitOnFailure(hr, "Failed to get IIsWebError.FileName"); - - hr = StringCchPrintfW(pswe->wzPath, countof(pswe->wzPath), L"/%s/%s", &pwzData[dwNonSlash], pwzData2); - ExitOnFailure(hr, "Failed to get virtual path for IIsWebError"); ! // get component from VirtualDir ! hr = ScaVirtualDirGetComponent(pwzVirtualDir, &pwzData); ! ExitOnFailure(hr, "Failed to get Component_ from VirtualDir IIsWebError"); ! StringCchCopyW(pswe->wzComponent, countof(pswe->wzComponent), pwzData); ! ExitOnFailure(hr, "Failed to copy component to entry"); } ! // get component install state ! er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pswe->wzComponent, &pswe->isInstalled, &pswe->isAction); ! hr = HRESULT_FROM_WIN32(er); ! ExitOnFailure(hr, "Failed to get Component state for IIsWebError"); LExit: ! ReleaseStr(pwzData); ! ReleaseStr(pwzData2); ! ReleaseStr(pwzVirtualDir); return hr; } ! HRESULT ScaWriteWebErrors(IMSAdminBase *piMetabase, LPCWSTR wzRootOfWeb, ! SCA_WEB_ERROR *psweList) { - // AssertSz(FALSE, "Uncomment and place breakpoint on subsequent line to debug."); - Assert(piMetabase && wzRootOfWeb); - HRESULT hr = S_OK; - SCA_WEB_ERROR *pswe; - - WCHAR wzErrors[MAX_ERROR_BUFFERSIZE]; - WCHAR *pwzNext = wzErrors; // used to properly create the MULTI_SZ - UINT cErrors = 0; - - // fill the MULTI_SZ wzErrors buffer for the CustomError attribute - ::ZeroMemory(wzErrors, sizeof(wzErrors)); - for (pswe = psweList; pswe; pswe = pswe->psweNext) - { - if (WcaIsInstalling(pswe->isInstalled, pswe->isAction)) - { - // check that type, error code, and sub code, and - // number of errors are valid - Assert(wetFile == pswe->wetType || wetUrl == pswe->wetType); - if (!(wetFile == pswe->wetType || wetUrl == pswe->wetType)) - { - hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); - ExitOnFailure(hr, "Invalid custom error type.") - } - - Assert(400 <= pswe->swek.iErrorCode && 600 > pswe->swek.iErrorCode); - if (!(400 <= pswe->swek.iErrorCode && 600 > pswe->swek.iErrorCode)) - { - hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); - ExitOnFailure(hr, "Invalid custom error code"); - } - - Assert(0 <= pswe->swek.iSubCode && 1000 > pswe->swek.iSubCode); - if (!(0 <= pswe->swek.iSubCode && 1000 > pswe->swek.iSubCode)) - { - hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); - ExitOnFailure(hr, "Invalid custom error sub code"); - } - - Assert(MAX_ERRORS > cErrors); - if (!(MAX_ERRORS > cErrors)) - { - hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - ExitOnFailure(hr, "Too many custom error entries."); - } - cErrors++; - - if (0 == pswe->swek.iSubCode) - { - hr = StringCchPrintfW(pwzNext, MAX_ERROR_VALUELENGTH, L"%d,*,%s,%s", - pswe->swek.iErrorCode, - (pswe->wetType == wetFile ? vcsTypeFile : vcsTypeUrl), - pswe->wzPath); - ExitOnFailure(hr, "Unable to write entry for custom error"); - } - else - { - hr = StringCchPrintfW(pwzNext, MAX_ERROR_VALUELENGTH, L"%d,%d,%s,%s", - pswe->swek.iErrorCode, pswe->swek.iSubCode, - (pswe->wetType == wetFile) ? vcsTypeFile : vcsTypeUrl, - pswe->wzPath); - ExitOnFailure(hr, "Unable to write entry for custom error"); - } ! pwzNext += lstrlenW(pwzNext) + 1; // reserve space for null ! } ! } ! if (0 < cErrors) ! { ! // now write the CustomErrors to the metabase ! hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, L"/Root", MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzErrors); ! ExitOnFailure(hr, "Failed to write CustomError for Web"); ! } ! else ! { ! hr = S_FALSE; ! WcaLog(LOGMSG_VERBOSE, "Skipping ScaWriteWebErrors() - no errors for current web."); ! goto LExit; ! } LExit: --- 19,359 ---- #include "precomp.h" ! LPCWSTR vcsWebErrorQuery = ! L"SELECT `ErrorCode`, `SubCode`, `ParentType`, `ParentValue`, `File`, `URL` " ! L"FROM `IIsWebError` ORDER BY `ErrorCode`, `SubCode`"; ! enum eWebErrorQuery { weqErrorCode = 1, weqSubCode, weqParentType, weqParentValue, weqFile, weqURL }; ! static HRESULT AddWebErrorToList(SCA_WEB_ERROR** ppsweList); ! void ScaWebErrorFreeList(SCA_WEB_ERROR *psweList) ! { ! SCA_WEB_ERROR *psweDelete = psweList; ! while (psweList) ! { ! psweDelete = psweList; ! psweList = psweList->psweNext; ! ::HeapFree(::GetProcessHeap(), 0, psweDelete); ! } ! } ! HRESULT ScaWebErrorRead(SCA_WEB_ERROR **ppsweList) { ! // AssertSz(0, "Debug ScaWebErrorRead here"); ! Assert(ppsweList); HRESULT hr = S_OK; + UINT er = 0; PMSIHANDLE hView, hRec; LPWSTR pwzData = NULL; ! SCA_WEB_ERROR* pswe; ! // bail quickly if the IIsWebError table isn't around ! if (S_OK != WcaTableExists(L"IIsWebError")) ! { ! WcaLog(LOGMSG_VERBOSE, "Skipping ScaGetWebErrors() - required tables not present."); ! ExitFunction1(hr = S_FALSE); ! } ! // loop through all the mimemappings ! hr = WcaOpenExecuteView(vcsWebErrorQuery, &hView); ! ExitOnFailure(hr, "Failed to open view on IIsMimeMap table"); ! while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) ! { ! hr = AddWebErrorToList(ppsweList); ! ExitOnFailure(hr, "failed to add mime map to list"); ! pswe = *ppsweList; ! hr = WcaGetRecordInteger(hRec, weqErrorCode, &(pswe->iErrorCode)); ! ExitOnFailure(hr, "failed to get IIsWebError.ErrorCode"); ! hr = WcaGetRecordInteger(hRec, weqSubCode, &(pswe->iSubCode)); ! ExitOnFailure(hr, "failed to get IIsWebError.SubCode"); ! hr = WcaGetRecordInteger(hRec, weqParentType, &(pswe->iParentType)); ! ExitOnFailure(hr, "failed to get IIsWebError.ParentType"); ! hr = WcaGetRecordString(hRec, weqParentValue, &pwzData); ! ExitOnFailure(hr, "Failed to get IIsWebError.ParentValue"); ! hr = StringCchCopyW(pswe->wzParentValue, countof(pswe->wzParentValue), pwzData); ! ExitOnFailure(hr, "Failed to copy IIsWebError.ParentValue"); ! hr = WcaGetRecordFormattedString(hRec, weqFile, &pwzData); ! ExitOnFailure(hr, "Failed to get IIsWebError.File"); ! hr = StringCchCopyW(pswe->wzFile, countof(pswe->wzFile), pwzData); ! ExitOnFailure(hr, "Failed to copy IIsWebError.File"); ! hr = WcaGetRecordFormattedString(hRec, weqURL, &pwzData); ! ExitOnFailure(hr, "Failed to get IIsWebError.URL"); ! hr = StringCchCopyW(pswe->wzURL, countof(pswe->wzURL), pwzData); ! ExitOnFailure(hr, "Failed to copy IIsWebError.URL"); ! // If they've specified both a file and a URL, that's invalid ! if (*(pswe->wzFile) && *(pswe->wzURL)) ! ExitOnFailure2(hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA), "Both File and URL specified for web error. File: %S, URL: %S", pswe->wzFile, pswe->wzURL); } ! if (E_NOMOREITEMS == hr) ! hr = S_OK; ! ExitOnFailure(hr, "Failure while processing web errors"); ! LExit: ! ReleaseNullStr(pwzData); ! return hr; ! } ! HRESULT ScaGetWebError(int iParentType, LPCWSTR wzParentValue, SCA_WEB_ERROR **ppsweList, SCA_WEB_ERROR **ppsweOut) ! { ! HRESULT hr = S_OK; ! SCA_WEB_ERROR* psweAdd = NULL; ! SCA_WEB_ERROR* psweLast = NULL; ! *ppsweOut = NULL; ! ! if (!*ppsweList) ! return hr; ! SCA_WEB_ERROR* pswe = *ppsweList; ! while (pswe) ! { ! if (iParentType == pswe->iParentType && 0 == lstrcmpW(wzParentValue, pswe->wzParentValue)) { ! // Found a match, take this one out of the list and add it to the matched out list ! psweAdd = pswe; ! if (psweLast) { ! // If we're not at the beginning of the list tell the last node about it's new next (since we're taking away it's current next) ! psweLast->psweNext = psweAdd->psweNext; } ! else { ! // If we are at the beginning (no psweLast) update the beginning (since we're taking it) ! *ppsweList = pswe->psweNext; } + pswe = pswe->psweNext; // move on ! // Add the one we've removed to the beginning of the out list ! psweAdd->psweNext = *ppsweOut; ! *ppsweOut = psweAdd; ! } ! else ! { ! psweLast = pswe; // remember the last we that didn't match ! pswe = pswe->psweNext; // move on } } ! return hr; ! } ! HRESULT ScaWriteWebError(IMSAdminBase* piMetabase, int iParentType, LPCWSTR wzRoot, SCA_WEB_ERROR* psweList) ! { ! // AssertSz(0, "Debug ScaWriteWebError here"); ! Assert(piMetabase && wzRoot && *wzRoot && psweList); ! HRESULT hr = S_OK; ! DWORD cchData = 0; ! BOOL fFoundDefault = FALSE; ! LPWSTR pwzSearchKey = NULL; ! LPWSTR pwz = NULL; ! LPWSTR pwzErrors = NULL; ! LPWSTR pwzCodeSubCode = NULL; ! LPWSTR pwzAcceptableCodeSubCode = NULL; ! LPCWSTR wzFoundCodeSubCode = NULL; ! DWORD dwFoundCodeSubCodeIndex = -1; ! BOOL fOldValueFound = FALSE; ! LPWSTR pwzAcceptableErrors = NULL; ! LPWSTR pwzNewError = NULL; ! METADATA_RECORD mr; ! ::ZeroMemory(&mr, sizeof(mr)); ! // 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: %S", 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: %S 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: %S", 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: %S", 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: %S", 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: %S is supported", pwzCodeSubCode); ! if (S_FALSE == hr) ! { ! WcaLog(LOGMSG_VERBOSE, "Skipping error code, subcode: %S 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: %S, file: %S", 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: %S, file: %S", 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: %S 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: %S", pwzCodeSubCode); ! } ! else ! { ! hr = MultiSzPrepend(&pwzErrors, NULL, pwzNewError); ! ExitOnFailure1(hr, "failed to prepend new error string for error code,subcode: %S", 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 MimeMap"); ! } ! else ! { ! hr = ScaWriteMetabaseValue(piMetabase, wzRoot, NULL, MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzErrors); ! ExitOnFailure(hr, "Failed to write MimeMap"); ! } LExit: ! ReleaseNullStr(pwzErrors); ! ReleaseNullStr(pwzSearchKey); ! ReleaseNullStr(pwzCodeSubCode); ! ReleaseNullStr(pwzAcceptableCodeSubCode); ! ReleaseNullStr(pwzAcceptableErrors); return hr; } ! static HRESULT AddWebErrorToList(SCA_WEB_ERROR** ppsweList) { HRESULT hr = S_OK; ! SCA_WEB_ERROR* pswe = (SCA_WEB_ERROR*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**ppsweList)); ! ExitOnNull(pswe, hr, E_OUTOFMEMORY, "failed to allocate memory for new web error list element"); ! pswe->psweNext = *ppsweList; ! *ppsweList = pswe; LExit: *************** *** 599,622 **** } ! ! void ScaWebErrorsFreeList(SCA_WEB_ERROR *psweList) { ! SCA_WEB_ERROR *psweDelete = psweList; while (psweList) { ! psweDelete = psweList; psweList = psweList->psweNext; - - ::HeapFree(::GetProcessHeap(), 0, psweDelete); } - } - ! // private helper functions ! SCA_WEB_ERROR *AddWebErrorToList(SCA_WEB_ERROR *psweList) ! { ! SCA_WEB_ERROR *pswe = (SCA_WEB_ERROR*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*psweList)); ! if (pswe) ! pswe->psweNext = psweList; ! return pswe; } --- 361,376 ---- } ! HRESULT ScaWebErrorCheckList(SCA_WEB_ERROR* psweList) { ! if (!psweList) ! return S_OK; ! while (psweList) { ! WcaLog(LOGMSG_STANDARD, "WebError code: %d subcode: %d for parent: %S not used!",psweList->iErrorCode, psweList->iSubCode, psweList->wzParentValue); psweList = psweList->psweNext; } ! return E_FAIL; } + Index: scaweblog.cpp =================================================================== RCS file: /cvsroot/wix/wix/src/ca/serverca/scasched/scaweblog.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** scaweblog.cpp 2 May 2005 05:48:37 -0000 1.1 --- scaweblog.cpp 20 Aug 2005 11:48:54 -0000 1.2 *************** *** 141,145 **** // if they specified a log format, look up its GUID in the metabase ! if (*pswl->wzFormat) { hr = LookupLogFormatGUID(piMetabase, pswl->wzFormat, pswl->wzFormatGUID, countof(pswl->wzFormatGUID)); --- 141,145 ---- // if they specified a log format, look up its GUID in the metabase ! if (*pswl->wzFormat && 0 != lstrcmpW(pswl->wzFormat, L"none")) { hr = LookupLogFormatGUID(piMetabase, pswl->wzFormat, pswl->wzFormatGUID, countof(pswl->wzFormatGUID)); *************** *** 169,177 **** if (*pswl->wzFormat) { ! Assert(*pswl->wzFormatGUID); ! ! // write the GUID for the log format for the web to the metabase ! hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_LOG_PLUGIN_ORDER, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, pswl->wzFormatGUID); ! ExitOnFailure1(hr, "Failed to write Log GUID for Web: %S", wzWebBase); } --- 169,189 ---- if (*pswl->wzFormat) { ! if (0 == lstrcmpW(pswl->wzFormat, L"none")) ! { ! // user wishes for Logging to be turned 'off' ! hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_LOG_TYPE, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)0)); ! ExitOnFailure1(hr, "Failed to write Log Type for Web: %S", wzWebBase); ! } ! else ! { ! Assert(*pswl->wzFormatGUID); ! ! // write the GUID for the log format for the web to the metabase ! hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_LOG_PLUGIN_ORDER, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, pswl->wzFormatGUID); ! ExitOnFailure1(hr, "Failed to write Log GUID for Web: %S", wzWebBase); ! ! hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_LOG_TYPE, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)1)); ! ExitOnFailure1(hr, "Failed to write Log Type for Web: %S", wzWebBase); ! } } Index: scaweb.h =================================================================== RCS file: /cvsroot/wix/wix/src/ca/serverca/scasched/scaweb.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** scaweb.h 7 Jul 2005 00:29:51 -0000 1.2 --- scaweb.h 20 Aug 2005 11:48:54 -0000 1.3 *************** *** 86,90 **** // prototypes HRESULT ScaWebsRead(IMSAdminBase* piMetabase, ! SCA_WEB** ppswList); HRESULT ScaWebsGetBase(IMSAdminBase* piMetabase, SCA_WEB* pswList, --- 86,90 ---- // prototypes HRESULT ScaWebsRead(IMSAdminBase* piMetabase, ! SCA_WEB** ppswList, SCA_WEB_ERROR** psweList); HRESULT ScaWebsGetBase(IMSAdminBase* piMetabase, SCA_WEB* pswList, Index: scaweberr.h =================================================================== RCS file: /cvsroot/wix/wix/src/ca/serverca/scasched/scaweberr.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** scaweberr.h 2 May 2005 05:48:37 -0000 1.1 --- scaweberr.h 20 Aug 2005 11:48:54 -0000 1.2 *************** *** 18,66 **** //------------------------------------------------------------------------------------------------- ! #ifndef MAX ! #define MAX( a, b ) (((a)>(b))?(a):(b)) ! #endif ! ! // this should be kept in sync with %msi%\src\sdl\inc\sca.sdh ! enum eWebErrorType { wetDefault = 0, wetFile, wetUrl }; ! ! // must be enough to hold path or url (/Alias/FileName) ! const UINT MAX_ERROR_PATHLENGTH = MAX(MAX_PATH, MAX_DARWIN_KEY + MAX_DARWIN_COLUMN + 2); ! struct SCA_WEB_ERROR_KEY { int iErrorCode; int iSubCode; - }; ! struct SCA_WEB_ERROR ! { ! // Key ! SCA_WEB_ERROR_KEY swek; ! ! // darwin information ! WCHAR wzComponent[MAX_DARWIN_KEY + 1]; ! INSTALLSTATE isInstalled; ! INSTALLSTATE isAction; ! // Type (FILE or URL) and path/url ! eWebErrorType wetType; ! WCHAR wzPath[MAX_ERROR_PATHLENGTH + 1]; SCA_WEB_ERROR *psweNext; }; - struct SCA_WEB_ERROR_KEY_VALID - { - // Key - SCA_WEB_ERROR_KEY swek; - - BOOL fHandled; - }; - // prototypes ! HRESULT ScaGetWebErrors(IMSAdminBase *piMetabase, LPCWSTR wzRootOfWeb, SCA_WEB_ERROR **ppsweList); ! HRESULT ScaWriteWebErrors(IMSAdminBase *piMetabase, LPCWSTR wzRootOfWeb, SCA_WEB_ERROR *psweList); ! ! void ScaWebErrorsFreeList(SCA_WEB_ERROR *psweList); --- 18,42 ---- //------------------------------------------------------------------------------------------------- ! enum eWebErrorParentType { weptVDir = 1, weptWeb }; ! struct SCA_WEB_ERROR { int iErrorCode; int iSubCode; ! int iParentType; ! WCHAR wzParentValue[MAX_DARWIN_KEY + 1]; ! WCHAR wzFile[MAX_PATH]; ! WCHAR wzURL[MAX_PATH]; // TODO: this needs to be bigger than MAX_PATH SCA_WEB_ERROR *psweNext; }; // prototypes ! HRESULT ScaWebErrorRead(SCA_WEB_ERROR **ppsweList); ! void ScaWebErrorFreeList(SCA_WEB_ERROR *psweList); ! HRESULT ScaWebErrorCheckList(SCA_WEB_ERROR* psweList); ! HRESULT ScaGetWebError(int iParentType, LPCWSTR wzParentValue, SCA_WEB_ERROR **ppsweList, SCA_WEB_ERROR **ppsweOut); ! HRESULT ScaWriteWebError(IMSAdminBase* piMetabase, int iParentType, LPCWSTR wzRoot, SCA_WEB_ERROR* psweList); Index: scawebsvcext.cpp =================================================================== RCS file: /cvsroot/wix/wix/src/ca/serverca/scasched/scawebsvcext.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** scawebsvcext.cpp 13 Jul 2005 10:21:51 -0000 1.2 --- scawebsvcext.cpp 20 Aug 2005 11:48:54 -0000 1.3 *************** *** 105,111 **** Assert(piMetabase); - if(!psWseList) - ExitFunction(); - HRESULT hr = S_OK; METADATA_RECORD mr; --- 105,108 ---- *************** *** 115,118 **** --- 112,121 ---- DWORD cchWebSvcExtList = 0; + if(!psWseList) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebSvcExtCommit() because there are no web service extensions in the list"); + ExitFunction(); + } + // Get current set of web service extensions. ::ZeroMemory(&mr, sizeof(mr)); *************** *** 127,131 **** if( MD_ERROR_DATA_NOT_FOUND == hr) { ! WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallWebSvcExt() because WebSvcExtRestrictionList value is not present"); ExitFunction(); } --- 130,134 ---- if( MD_ERROR_DATA_NOT_FOUND == hr) { ! WcaLog(LOGMSG_VERBOSE, "Skipping ScaWebSvcExtCommit() because WebSvcExtRestrictionList value is not present"); ExitFunction(); } Index: scawebprop.cpp =================================================================== RCS file: /cvsroot/wix/wix/src/ca/serverca/scasched/scawebprop.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** scawebprop.cpp 7 Jul 2005 00:29:51 -0000 1.2 --- scawebprop.cpp 20 Aug 2005 11:48:54 -0000 1.3 *************** *** 85,89 **** --- 85,92 ---- hr = WcaGetRecordInteger(hRec, wpqLogVisits, &pswp->fLogVisits); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.LogVisits"); + hr = WcaGetRecordInteger(hRec, wpqIndex, &pswp->fIndex); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.Index"); hr = WcaGetRecordString(hRec, wpqDefaultDoc, &pwzData); *************** *** 103,106 **** --- 106,110 ---- hr = WcaGetRecordInteger(hRec, wpqAspDetailedError, &pswp->fAspDetailedError); + ExitOnFailure(hr, "Failed to get IIsWebDirProperties.AspDetailedError"); hr = WcaGetRecordString(hRec, wpqHttpExp, &pwzData); *************** *** 139,142 **** --- 143,148 ---- hr = WcaGetRecordInteger(hRec, wpqNoCustomError, &pswp->fNoCustomError); ExitOnFailure(hr, "failed to get IIsWebDirProperties.NoCustomError"); + if (MSI_NULL_INTEGER == pswp->fNoCustomError) + pswp->fNoCustomError = FALSE; hr = WcaGetRecordInteger(hRec, wpqAccessSSLFlags, &pswp->iAccessSSLFlags); Index: scasched.cpp =================================================================== RCS file: /cvsroot/wix/wix/src/ca/serverca/scasched/scasched.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** scasched.cpp 13 Jul 2005 10:21:51 -0000 1.4 --- scasched.cpp 20 Aug 2005 11:48:54 -0000 1.5 *************** *** 65,68 **** --- 65,69 ---- SCA_PROPERTY *pspList = NULL; SCA_WEBSVCEXT* psWseList = NULL; + SCA_WEB_ERROR* psweList = NULL; // initialize *************** *** 114,118 **** MessageExitOnFailure(hr, msierrIISFailedReadAppPool, "failed to read IIsAppPool table"); ! hr = ScaWebsRead(piMetabase, &pswList); MessageExitOnFailure(hr, msierrIISFailedReadWebs, "failed to read IIsWebSite table"); --- 115,126 ---- MessageExitOnFailure(hr, msierrIISFailedReadAppPool, "failed to read IIsAppPool table"); ! // MimeMap and Error need to be read before the virtual directory and web read ! hr = ScaMimeMapRead(&psmmList); ! MessageExitOnFailure(hr, msierrIISFailedReadMimeMap, "failed to read IIsMimeMap table"); ! ! hr = ScaWebErrorRead(&psweList); ! MessageExitOnFailure(hr, msierrIISFailedReadWebError, "failed to read IIsWebError table"); ! ! hr = ScaWebsRead(piMetabase, &pswList, &psweList); MessageExitOnFailure(hr, msierrIISFailedReadWebs, "failed to read IIsWebSite table"); *************** *** 120,128 **** MessageExitOnFailure(hr, msierrIISFailedReadWebDirs, "failed to read IIsWebDir table"); ! // MimeMap needs to be read before the virtual directory read ! hr = ScaMimeMapRead(&psmmList); ! MessageExitOnFailure(hr, msierrIISFailedReadMimeMap, "failed to read IIsMimeMap table"); ! ! hr = ScaVirtualDirsRead(piMetabase, pswList, &psvdList, &psmmList); MessageExitOnFailure(hr, msierrIISFailedReadVDirs, "failed to read IIsWebVirtualDir table"); --- 128,132 ---- MessageExitOnFailure(hr, msierrIISFailedReadWebDirs, "failed to read IIsWebDir table"); ! hr = ScaVirtualDirsRead(piMetabase, pswList, &psvdList, &psmmList, &psweList); MessageExitOnFailure(hr, msierrIISFailedReadVDirs, "failed to read IIsWebVirtualDir table"); *************** *** 209,212 **** --- 213,222 ---- } + if (psweList) + { + ScaWebErrorCheckList(psweList); + ScaWebErrorFreeList(psweList); + } + if (piMetabase) piMetabase->Release(); |