HRESULT ScaRemoveProperty( IMSAdminBase* piMetabase, SCA_PROPERTY* psp ) { Assert(piMetabase); HRESULT hr = S_OK; DWORD dwValue; ExitOnNull(psp, hr, E_INVALIDARG, "Failed to remove property because no property to remove was given"); if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_IIS5_ISOLATION_MODE)) { dwValue = 0; hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_STANDARD_APP_MODE_ENABLED, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); ExitOnFailure(hr, "failed to clear IIs5IsolationMode"); } else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH)) { dwValue = 0xFFFFFFFF; // This unchecks the box hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_MAX_GLOBAL_BANDWIDTH, METADATA_NO_ATTRIBUTES , IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); ExitOnFailure(hr, "failed to clear MaxGlobalBandwidth"); } else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_LOG_IN_UTF8)) { dwValue = 0; hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_LOG_IN_UTF_8, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); ExitOnFailure(hr, "failed to clear LogInUTF8"); } LExit: return hr; }
HRESULT ScaSslCertificateWriteMetabase( __in IMSAdminBase* piMetabase, __in LPCWSTR wzWebBase, __in SCA_WEB_SSL_CERTIFICATE* pswscList ) { HRESULT hr = S_OK; BLOB blob; for (SCA_WEB_SSL_CERTIFICATE* pswsc = pswscList; pswsc; pswsc = pswsc->pNext) { // Write: /W3SVC/1:SslCertStoreName = "MY", "CA", "Root", etc. hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_SSL_CERT_STORE_NAME, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, static_cast<LPVOID>(pswsc->wzStoreName)); ExitOnFailure(hr, "Failed to write SslCertStoreName"); // Write: /W3SVC/1:SslCertHash = <blob> blob.pBlobData = pswsc->rgbSHA1Hash; blob.cbSize = countof(pswsc->rgbSHA1Hash); hr = ScaWriteMetabaseValue(piMetabase, wzWebBase, L"", MD_SSL_CERT_HASH, METADATA_INHERIT, IIS_MD_UT_SERVER, BINARY_METADATA, static_cast<LPVOID>(&blob)); ExitOnFailure(hr, "Failed to write SslCertHash"); } LExit: return hr; }
HRESULT ScaWebDirsInstall(IMSAdminBase* piMetabase, SCA_WEBDIR* pswdList, SCA_APPPOOL * psapList) { HRESULT hr = S_OK; SCA_WEBDIR* pswd = pswdList; int i; while (pswd) { // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created if (WcaIsReInstalling(pswd->isInstalled, pswd->isAction)) { if (pswd->fHasApplication) { hr = ScaDeleteApp(piMetabase, pswd->wzWebDirRoot); ExitOnFailure(hr, "Failed to remove application for WebDir as part of a reinstall"); } } // if we are installing the web site if (WcaIsInstalling(pswd->isInstalled, pswd->isAction)) { hr = ScaCreateMetabaseKey(piMetabase, pswd->wzWebDirRoot, L""); ExitOnFailure(hr, "Failed to create key for WebDir"); hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebDirectory"); ExitOnFailure(hr, "Failed to write key type for for WebDir"); i = 0x4000003e; // 1073741886: default directory browsing rights hr = ScaWriteMetabaseValue(piMetabase, pswd->wzWebDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i)); ExitOnFailure(hr, "Failed to set directory browsing for WebDir"); // get the security information for this web if (pswd->fHasProperties) { ScaWriteWebDirProperties(piMetabase, pswd->wzWebDirRoot, &pswd->swp); ExitOnFailure(hr, "Failed to write properties for WebDir"); } // get the application information for this web directory if (pswd->fHasApplication) { hr = ScaWriteWebApplication(piMetabase, pswd->wzWebDirRoot, &pswd->swapp, psapList); ExitOnFailure(hr, "Failed to write application for WebDir"); } } pswd = pswd->pswdNext; } LExit: return hr; }
HRESULT ScaFiltersInstall(IMSAdminBase* piMetabase, SCA_FILTER* psfList) { HRESULT hr = S_OK; SCA_FILTER* psf = psfList; while (psf) { if (WcaIsInstalling(psf->isInstalled, psf->isAction)) { hr = ScaCreateMetabaseKey(piMetabase, psf->wzFilterRoot, psf->wzKey); ExitOnFailure1(hr, "Failed to create key for filter '%S'", psf->wzKey); hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsFilter"); ExitOnFailure1(hr, "Failed to write key type for filter '%S'", psf->wzKey); // filter path hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_FILTER_IMAGE_PATH, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)psf->wzPath); ExitOnFailure1(hr, "Failed to write Path for filter '%S'", psf->wzKey); // filter description hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_FILTER_DESCRIPTION, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)psf->wzDescription); ExitOnFailure1(hr, "Failed to write Description for filter ''%S", psf->wzKey); // filter flags if (MSI_NULL_INTEGER != psf->iFlags) { hr = ScaWriteMetabaseValue(piMetabase, psf->wzFilterRoot, psf->wzKey, MD_FILTER_FLAGS, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)psf->iFlags)); ExitOnFailure1(hr, "Failed to write Flags for filter '%S'", psf->wzKey); } // filter load order if (MSI_NULL_INTEGER != psf->iLoadOrder) { hr = ScaAddFilterToLoadOrder(piMetabase, psf->wzFilterRoot, psf->wzKey, psf->iLoadOrder); ExitOnFailure1(hr, "Failed to add filter '%S' to load order", psf->wzKey); } } psf = psf->psfNext; } LExit: return hr; }
HRESULT ScaWriteProperty( IMSAdminBase* piMetabase, SCA_PROPERTY* psp ) { Assert(piMetabase); HRESULT hr = S_OK; DWORD dwValue; LPWSTR wz = NULL; ExitOnNull(psp, hr, E_INVALIDARG, "Failed to write property because no property to write was given"); // // Figure out what setting we're writing and write it // if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_IIS5_ISOLATION_MODE)) { dwValue = 1; hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_STANDARD_APP_MODE_ENABLED, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); ExitOnFailure(hr, "failed to set IIs5IsolationMode"); } else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_MAX_GLOBAL_BANDWIDTH)) { dwValue = wcstoul(psp->wzValue, &wz, 10) * 1024; // remember, the value shown is in kilobytes, the value saved is in bytes hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_MAX_GLOBAL_BANDWIDTH, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); ExitOnFailure(hr, "failed to set MaxGlobalBandwidth"); } else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_LOG_IN_UTF8)) { dwValue = 1; hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, MD_GLOBAL_LOG_IN_UTF_8, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); ExitOnFailure(hr, "failed to set LogInUTF8"); } else if (0 == lstrcmpW(psp->wzProperty, wzIISPROPERTY_ETAG_CHANGENUMBER)) { dwValue = wcstoul(psp->wzValue, &wz, 10); hr = ScaWriteMetabaseValue(piMetabase, L"/LM/W3SVC", NULL, /*MD_ETAG_CHANGENUMBER*/ 2039, METADATA_INHERIT, IIS_MD_UT_SERVER, DWORD_METADATA, (LPVOID)((DWORD_PTR)dwValue)); ExitOnFailure(hr, "failed to set EtagChangenumber"); } LExit: return hr; }
HRESULT ScaWebAppExtensionsWrite(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, SCA_WEB_APPLICATION_EXTENSION* pswappextList ) { HRESULT hr = S_OK; LPWSTR wzAppExt = NULL; DWORD cchAppExt; WCHAR wzAppExtension[1024]; WCHAR wzAppExtensions[65536]; SCA_WEB_APPLICATION_EXTENSION* pswappext = NULL; if (!pswappextList) ExitFunction(); ::ZeroMemory(wzAppExtensions, sizeof(wzAppExtensions)); wzAppExt = wzAppExtensions; cchAppExt = countof(wzAppExtensions); pswappext = pswappextList; while (pswappext) { if (0 == lstrcmpW(wzAppExtension, L"*")) StringCchPrintfW(wzAppExtension, countof(wzAppExtension), L"*,%s,%d", pswappext->wzExecutable, pswappext->iAttributes); else if (*pswappext->wzExtension) StringCchPrintfW(wzAppExtension, countof(wzAppExtension), L".%s,%s,%d", pswappext->wzExtension, pswappext->wzExecutable, pswappext->iAttributes); else // blank means "*" (all) StringCchPrintfW(wzAppExtension, countof(wzAppExtension), L"*,%s,%d", pswappext->wzExecutable, pswappext->iAttributes); // if verbs were specified and not the keyword "all" if (pswappext->wzVerbs[0] && CSTR_EQUAL != CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pswappext->wzVerbs, -1, L"all", -1)) { StringCchCatW(wzAppExtension, countof(wzAppExtension), L","); StringCchCatW(wzAppExtension, countof(wzAppExtension), pswappext->wzVerbs); } StringCchCopyW(wzAppExt, cchAppExt, wzAppExtension); wzAppExt += lstrlenW(wzAppExtension) + 1; cchAppExt -= lstrlenW(wzAppExtension) + 1; pswappext = pswappext->pswappextNext; } if (*wzAppExtensions) { hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_SCRIPT_MAPS, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzAppExtensions); ExitOnFailure1(hr, "Failed to write AppExtension: '%S'", wzAppExtension); } LExit: return hr; }
HRESULT ScaWriteMimeMap(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, SCA_MIMEMAP* psmmList) { HRESULT hr = S_OK; WCHAR wzMimeMap[8192]; WCHAR *pwzNext = wzMimeMap; const WCHAR *pwzMac = wzMimeMap + countof(wzMimeMap); // used to properly create the MULTI_SZ // fill the MULTI_SZ wzMimeMap buffer for the MimeMap attribute ::ZeroMemory(wzMimeMap, sizeof(wzMimeMap)); for (SCA_MIMEMAP* psmm = psmmList; psmm; psmm = psmm->psmmNext) { hr = ::StringCchPrintfW(pwzNext, max(0, pwzMac - pwzNext), L"%s,%s", psmm->wzExtension, psmm->wzMimeType); ExitOnFailure(hr, "Failed to set MimeMap string"); pwzNext += lstrlenW(pwzNext) + 1; // reserve space for null Assert(pwzNext <= pwzMac); } if (pwzNext != wzMimeMap) { // now write the CustomErrors to the metabase hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_MIME_MAP, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzMimeMap); ExitOnFailure(hr, "Failed to write MimeMap"); } else { WcaLog(LOGMSG_VERBOSE, "Skipping ScaWriteMimeMap() - no mappings found."); ExitFunction1(hr = S_FALSE); } LExit: return hr; }
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; }
HRESULT ScaVirtualDirsInstall( __in IMSAdminBase* piMetabase, __in SCA_VDIR* psvdList, __in SCA_APPPOOL * psapList ) { Assert(piMetabase); HRESULT hr = S_OK; SCA_VDIR* psvd = psvdList; int i; while (psvd) { // On reinstall, we have to uninstall the old application, otherwise a duplicate will be created if (WcaIsReInstalling(psvd->isInstalled, psvd->isAction)) { if (psvd->fHasApplication) { hr = ScaDeleteApp(piMetabase, psvd->wzVDirRoot); ExitOnFailure(hr, "Failed to remove application for WebVDir as part of a reinstall"); } } if (WcaIsInstalling(psvd->isInstalled, psvd->isAction)) { hr = ScaCreateMetabaseKey(piMetabase, psvd->wzVDirRoot, L""); ExitOnFailure(hr, "Failed to create key for VirtualDir"); hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, (LPVOID)L"IIsWebVirtualDir"); ExitOnFailure(hr, "Failed to write key type for for VirtualDir"); i = 0x4000003e; // 1073741886; // default directory browsing rights hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_DIRECTORY_BROWSING, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)i)); ExitOnFailure(hr, "Failed to set directory browsing for VirtualDir"); hr = ScaWriteMetabaseValue(piMetabase, psvd->wzVDirRoot, L"", MD_VR_PATH, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)psvd->wzDirectory); ExitOnFailure(hr, "Failed to write Directory for VirtualDir"); if (psvd->fHasProperties) { ScaWriteWebDirProperties(piMetabase, psvd->wzVDirRoot, &psvd->swp); ExitOnFailure(hr, "Failed to write directory properties for VirtualDir"); } if (psvd->fHasApplication) { hr = ScaWriteWebApplication(piMetabase, psvd->wzVDirRoot, &psvd->swapp, psapList); ExitOnFailure(hr, "Failed to write application for VirtualDir"); } if (psvd->psmm) { hr = ScaWriteMimeMap(piMetabase, psvd->wzVDirRoot, psvd->psmm); ExitOnFailure(hr, "Failed to write mimemap for VirtualDir"); } if (psvd->pshh) { hr = ScaWriteHttpHeader(piMetabase, psvd->wzVDirRoot, psvd->pshh); ExitOnFailure(hr, "Failed to write custom HTTP headers for VirtualDir"); } if (psvd->pswe) { hr = ScaWriteWebError(piMetabase, weptVDir, psvd->wzVDirRoot, psvd->pswe); ExitOnFailure(hr, "Failed to write custom web errors for VirtualDir"); } } psvd = psvd->psvdNext; } LExit: return hr; }
HRESULT ScaWriteWebDirProperties( __in IMSAdminBase* piMetabase, __in LPCWSTR wzRootOfWeb, __inout SCA_WEB_PROPERTIES* pswp ) { HRESULT hr = S_OK; DWORD dw = 0; WCHAR wz[METADATA_MAX_NAME_LEN + 1]; // write the access permissions to the metabase if (MSI_NULL_INTEGER != pswp->iAccess) { hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ACCESS_PERM, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iAccess)); ExitOnFailure(hr, "Failed to write access permissions for Web"); } if (MSI_NULL_INTEGER != pswp->iAuthorization) { hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_AUTHORIZATION, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iAuthorization)); ExitOnFailure(hr, "Failed to write authorization for Web"); } if (pswp->fHasUser) { Assert(pswp->scau.wzName); // write the user name if (*pswp->scau.wzDomain) { hr = ::StringCchPrintfW(wz, countof(wz), L"%s\\%s", pswp->scau.wzDomain, pswp->scau.wzName); ExitOnFailure(hr, "Failed to format domain\\username string"); } else { hr = ::StringCchCopyW(wz, countof(wz), pswp->scau.wzName); ExitOnFailure(hr, "Failed to copy user name"); } hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ANONYMOUS_USER_NAME, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)wz); ExitOnFailure(hr, "Failed to write anonymous user name for Web"); // write the password hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ANONYMOUS_PWD, METADATA_INHERIT | METADATA_SECURE, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->scau.wzPassword); ExitOnFailure(hr, "Failed to write anonymous user password for Web"); // store whether IIs controls password dw = (pswp->fIIsControlledPassword) ? TRUE : FALSE; hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ANONYMOUS_USE_SUBAUTH, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); ExitOnFailure(hr, "Failed to write if IIs controls user password for Web"); } if (MSI_NULL_INTEGER != pswp->fLogVisits) { // The sense of this boolean value is reversed - it is "don't log", not "log visits." dw = (pswp->fLogVisits) ? FALSE : TRUE; hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_DONT_LOG, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); ExitOnFailure(hr, "Failed to write authorization for Web"); } if (MSI_NULL_INTEGER != pswp->fIndex) { dw = (pswp->fIndex) ? TRUE : FALSE; hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_IS_CONTENT_INDEXED, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); ExitOnFailure(hr, "Failed to write authorization for Web"); } if (pswp->fHasDefaultDoc) { hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_DEFAULT_LOAD_FILE, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->wzDefaultDoc); ExitOnFailure(hr, "Failed to write default documents for Web"); } if (MSI_NULL_INTEGER != pswp->fAspDetailedError) { dw = (pswp->fAspDetailedError) ? TRUE : FALSE; hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SCRIPTERRORSSENTTOBROWSER, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)dw)); ExitOnFailure(hr, "Failed to write ASP script error for Web"); } if (pswp->fHasHttpExp) { hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_HTTP_EXPIRES, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->wzHttpExp); ExitOnFailure(hr, "Failed to write HTTP Expiration for Web"); } if (MSI_NULL_INTEGER != pswp->iCacheControlMaxAge) { hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_CC_MAX_AGE, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iCacheControlMaxAge)); ExitOnFailure(hr, "Failed to write Cache Control Max Age for Web"); } if (pswp->fHasCacheControlCustom) { hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_CC_OTHER, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)pswp->wzCacheControlCustom); ExitOnFailure(hr, "Failed to write Cache Control Custom for Web"); } if (pswp->fNoCustomError) { memset(wz, 0, sizeof(wz)); hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wz); ExitOnFailure(hr, "Failed to write Custom Error for Web"); } if (MSI_NULL_INTEGER != pswp->iAccessSSLFlags) { hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_SSL_ACCESS_PERM, METADATA_INHERIT, IIS_MD_UT_FILE, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswp->iAccessSSLFlags)); ExitOnFailure(hr, "Failed to write AccessSSLFlags for Web"); } if (*pswp->wzAuthenticationProviders) { hr = ::StringCchCopyW(wz, countof(wz), pswp->wzAuthenticationProviders); ExitOnFailure(hr, "Failed to copy authentication providers string"); hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_NTAUTHENTICATION_PROVIDERS, METADATA_INHERIT, IIS_MD_UT_FILE, STRING_METADATA, (LPVOID)wz); ExitOnFailure(hr, "Failed to write AuthenticationProviders for Web"); } LExit: return hr; }
HRESULT ScaWebAppExtensionsWrite( __in IMSAdminBase* piMetabase, __in LPCWSTR wzRootOfWeb, __in SCA_WEB_APPLICATION_EXTENSION* pswappextList ) { HRESULT hr = S_OK; LPWSTR wzAppExt = NULL; DWORD cchAppExt; WCHAR wzAppExtension[1024]; WCHAR wzAppExtensions[65536]; SCA_WEB_APPLICATION_EXTENSION* pswappext = NULL; if (!pswappextList) { ExitFunction(); } ::ZeroMemory(wzAppExtensions, sizeof(wzAppExtensions)); wzAppExt = wzAppExtensions; cchAppExt = countof(wzAppExtensions); pswappext = pswappextList; while (pswappext) { // if all (represented by "*" or blank) if (0 == lstrcmpW(pswappext->wzExtension, L"*") || 0 == lstrlenW(pswappext->wzExtension)) { hr = ::StringCchPrintfW(wzAppExtension, countof(wzAppExtension), L"*,%s,%d", pswappext->wzExecutable, pswappext->iAttributes); ExitOnFailure(hr, "Failed to format *,executable,attributes string"); } else { hr = ::StringCchPrintfW(wzAppExtension, countof(wzAppExtension), L".%s,%s,%d", pswappext->wzExtension, pswappext->wzExecutable, pswappext->iAttributes); ExitOnFailure(hr, "Failed to format extension,executable,attributes string"); } // if verbs were specified and not the keyword "all" if (pswappext->wzVerbs[0] && CSTR_EQUAL != CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pswappext->wzVerbs, -1, L"all", -1)) { hr = ::StringCchCatW(wzAppExtension, countof(wzAppExtension), L","); ExitOnFailure(hr, "Failed to concatenate comma to app extension string"); hr = ::StringCchCatW(wzAppExtension, countof(wzAppExtension), pswappext->wzVerbs); ExitOnFailure(hr, "Failed to concatenate verb to app extension string"); } hr = ::StringCchCopyW(wzAppExt, cchAppExt, wzAppExtension); ExitOnFailure(hr, "Failed to copy app extension string"); wzAppExt += lstrlenW(wzAppExtension) + 1; cchAppExt -= lstrlenW(wzAppExtension) + 1; pswappext = pswappext->pswappextNext; } if (*wzAppExtensions) { hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_SCRIPT_MAPS, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, wzAppExtensions); ExitOnFailure1(hr, "Failed to write AppExtension: '%ls'", wzAppExtension); } LExit: return hr; }