| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. |
| 2 | |
| 3 | #include "precomp.h" |
| 4 | |
| 5 | // sql queries |
| 6 | enum eWebApplicationQuery { wappqName = 1, wappqIsolation, wappqAllowSession, |
| 7 | wappqSessionTimeout, wappqBuffer, wappqParentPaths, |
| 8 | wappqDefaultScript, wappqScriptTimeout, |
| 9 | wappqServerDebugging, wappqClientDebugging, wappqAppPool, wappqApplication}; |
| 10 | |
| 11 | |
| 12 | HRESULT ScaGetWebApplication(MSIHANDLE /*hViewApplications*/, |
| 13 | LPCWSTR pwzApplication, |
| 14 | __in WCA_WRAPQUERY_HANDLE hWebAppQuery, |
| 15 | __in WCA_WRAPQUERY_HANDLE hWebAppExtQuery, |
| 16 | SCA_WEB_APPLICATION* pswapp) |
| 17 | { |
| 18 | HRESULT hr = S_OK; |
| 19 | |
| 20 | MSIHANDLE hRec; |
| 21 | LPWSTR pwzData = NULL; |
| 22 | |
| 23 | // Reset back to the first record |
| 24 | WcaFetchWrappedReset(hWebAppQuery); |
| 25 | |
| 26 | // get the application information |
| 27 | hr = WcaFetchWrappedRecordWhereString(hWebAppQuery, wappqApplication, pwzApplication, &hRec); |
| 28 | if (S_OK == hr) |
| 29 | { |
| 30 | // application name |
| 31 | hr = WcaGetRecordString(hRec, wappqName, &pwzData); |
| 32 | ExitOnFailure(hr, "Failed to get Name of App"); |
| 33 | hr = ::StringCchCopyW(pswapp->wzName, countof(pswapp->wzName), pwzData); |
| 34 | if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) |
| 35 | { |
| 36 | // The application name is sometimes truncated to IIS's supported length, so ignore insufficient buffer errors here |
| 37 | WcaLog(LOGMSG_VERBOSE, "Application name \"%ls\" truncated to fit IIS's supported %d-character length", pwzData, MAX_APP_NAME); |
| 38 | hr = S_OK; |
| 39 | } |
| 40 | ExitOnFailure(hr, "Failed to copy name string to webapp object"); |
| 41 | |
| 42 | hr = WcaGetRecordInteger(hRec, wappqIsolation, &pswapp->iIsolation); |
| 43 | ExitOnFailure(hr, "Failed to get App isolation: '%ls'", pswapp->wzName); |
| 44 | |
| 45 | hr = WcaGetRecordInteger(hRec, wappqAllowSession, &pswapp->fAllowSessionState); |
| 46 | |
| 47 | hr = WcaGetRecordInteger(hRec, wappqSessionTimeout, &pswapp->iSessionTimeout); |
| 48 | |
| 49 | hr = WcaGetRecordInteger(hRec, wappqBuffer, &pswapp->fBuffer); |
| 50 | |
| 51 | hr = WcaGetRecordInteger(hRec, wappqParentPaths, &pswapp->fParentPaths); |
| 52 | |
| 53 | hr = WcaGetRecordString(hRec, wappqDefaultScript, &pwzData); |
| 54 | ExitOnFailure(hr, "Failed to get default scripting language for App: '%ls'", pswapp->wzName); |
| 55 | hr = ::StringCchCopyW(pswapp->wzDefaultScript, countof(pswapp->wzDefaultScript), pwzData); |
| 56 | ExitOnFailure(hr, "Failed to copy default script string to webapp object"); |
| 57 | |
| 58 | // asp script timeout |
| 59 | hr = WcaGetRecordInteger(hRec, wappqScriptTimeout, &pswapp->iScriptTimeout); |
| 60 | ExitOnFailure(hr, "Failed to get scripting timeout for App: '%ls'", pswapp->wzName); |
| 61 | |
| 62 | // asp server-side script debugging |
| 63 | hr = WcaGetRecordInteger(hRec, wappqServerDebugging, &pswapp->fServerDebugging); |
| 64 | |
| 65 | // asp client-side script debugging |
| 66 | hr = WcaGetRecordInteger(hRec, wappqClientDebugging, &pswapp->fClientDebugging); |
| 67 | |
| 68 | hr = WcaGetRecordString(hRec, wappqAppPool, &pwzData); |
| 69 | ExitOnFailure(hr, "Failed to get AppPool for App: '%ls'", pswapp->wzName); |
| 70 | hr = ::StringCchCopyW(pswapp->wzAppPool, countof(pswapp->wzAppPool), pwzData); |
| 71 | ExitOnFailure(hr, "failed to copy AppPool: '%ls' for App: '%ls'", pwzData, pswapp->wzName); |
| 72 | |
| 73 | // app extensions |
| 74 | hr = ScaWebAppExtensionsRead(pwzApplication, hWebAppExtQuery, &pswapp->pswappextList); |
| 75 | ExitOnFailure(hr, "Failed to read AppExtensions for App: '%ls'", pswapp->wzName); |
| 76 | |
| 77 | hr = S_OK; |
| 78 | } |
| 79 | else if (E_NOMOREITEMS == hr) |
| 80 | { |
| 81 | WcaLog(LOGMSG_STANDARD, "Error: Cannot locate IIsWebApplication.Application='%ls'", pwzApplication); |
| 82 | hr = E_FAIL; |
| 83 | } |
| 84 | else |
| 85 | ExitOnFailure(hr, "Error matching Application rows"); |
| 86 | |
| 87 | // Let's check that there isn't more than one record found - if there is, throw an assert like WcaFetchSingleRecord() would |
| 88 | HRESULT hrTemp = WcaFetchWrappedRecordWhereString(hWebAppQuery, wappqApplication, pwzApplication, &hRec); |
| 89 | if (SUCCEEDED(hrTemp)) |
| 90 | { |
| 91 | AssertSz(E_NOMOREITEMS == hrTemp, "ScaGetWebApplication found more than one record"); |
| 92 | } |
| 93 | |
| 94 | LExit: |
| 95 | ReleaseStr(pwzData); |
| 96 | |
| 97 | return hr; |
| 98 | } |
| 99 | |
| 100 | |
| 101 | HRESULT ScaWriteWebApplication(IMSAdminBase* piMetabase, LPCWSTR wzRootOfWeb, |
| 102 | SCA_WEB_APPLICATION* pswapp, SCA_APPPOOL * psapList) |
| 103 | { |
| 104 | HRESULT hr = S_OK; |
| 105 | WCHAR wzAppPoolName[MAX_PATH]; |
| 106 | |
| 107 | hr = ScaCreateApp(piMetabase, wzRootOfWeb, pswapp->iIsolation); |
| 108 | ExitOnFailure(hr, "Failed to create ASP App"); |
| 109 | |
| 110 | // Medium Isolation seems to have to be set through the metabase |
| 111 | if (2 == pswapp->iIsolation) |
| 112 | { |
| 113 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_APP_ISOLATED, METADATA_INHERIT, IIS_MD_UT_WAM, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->iIsolation)); |
| 114 | ExitOnFailure(hr, "Failed to write isolation value for App: '%ls'", pswapp->wzName); |
| 115 | } |
| 116 | |
| 117 | // application name |
| 118 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_APP_FRIENDLY_NAME, METADATA_INHERIT, IIS_MD_UT_WAM, STRING_METADATA, pswapp->wzName); |
| 119 | ExitOnFailure(hr, "Failed to write Name of App: '%ls'", pswapp->wzName); |
| 120 | |
| 121 | // allow session state |
| 122 | if (MSI_NULL_INTEGER != pswapp->fAllowSessionState) |
| 123 | { |
| 124 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ALLOWSESSIONSTATE, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fAllowSessionState)); |
| 125 | ExitOnFailure(hr, "Failed to write allow session information for App: '%ls'", pswapp->wzName); |
| 126 | } |
| 127 | |
| 128 | // session timeout |
| 129 | if (MSI_NULL_INTEGER != pswapp->iSessionTimeout) |
| 130 | { |
| 131 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SESSIONTIMEOUT, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->iSessionTimeout)); |
| 132 | ExitOnFailure(hr, "Failed to write session timeout for App: '%ls'", pswapp->wzName); |
| 133 | } |
| 134 | |
| 135 | // asp buffering |
| 136 | if (MSI_NULL_INTEGER != pswapp->fBuffer) |
| 137 | { |
| 138 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_BUFFERINGON, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fBuffer)); |
| 139 | ExitOnFailure(hr, "Failed to write buffering flag for App: '%ls'", pswapp->wzName); |
| 140 | } |
| 141 | |
| 142 | // asp parent paths |
| 143 | if (MSI_NULL_INTEGER != pswapp->fParentPaths) |
| 144 | { |
| 145 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ENABLEPARENTPATHS, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fParentPaths)); |
| 146 | ExitOnFailure(hr, "Failed to write parent paths flag for App: '%ls'", pswapp->wzName); |
| 147 | } |
| 148 | |
| 149 | // default scripting language |
| 150 | if (*pswapp->wzDefaultScript) |
| 151 | { |
| 152 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SCRIPTLANGUAGE, METADATA_INHERIT, ASP_MD_UT_APP, STRING_METADATA, pswapp->wzDefaultScript); |
| 153 | ExitOnFailure(hr, "Failed to write default scripting language for App: '%ls'", pswapp->wzName); |
| 154 | } |
| 155 | |
| 156 | // asp script timeout |
| 157 | if (MSI_NULL_INTEGER != pswapp->iScriptTimeout) |
| 158 | { |
| 159 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_SCRIPTTIMEOUT, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->iScriptTimeout)); |
| 160 | ExitOnFailure(hr, "Failed to write script timeout for App: '%ls'", pswapp->wzName); |
| 161 | } |
| 162 | |
| 163 | // asp server-side script debugging |
| 164 | if (MSI_NULL_INTEGER != pswapp->fServerDebugging) |
| 165 | { |
| 166 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ENABLESERVERDEBUG, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fServerDebugging)); |
| 167 | ExitOnFailure(hr, "Failed to write ASP server-side script debugging flag for App: '%ls'", pswapp->wzName); |
| 168 | } |
| 169 | |
| 170 | // asp server-side script debugging |
| 171 | if (MSI_NULL_INTEGER != pswapp->fClientDebugging) |
| 172 | { |
| 173 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_ASP_ENABLECLIENTDEBUG, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, (LPVOID)((DWORD_PTR)pswapp->fClientDebugging)); |
| 174 | ExitOnFailure(hr, "Failed to write ASP client-side script debugging flag for App: '%ls'", pswapp->wzName); |
| 175 | } |
| 176 | |
| 177 | // AppPool |
| 178 | if (*pswapp->wzAppPool && NULL != psapList) |
| 179 | { |
| 180 | hr = ScaFindAppPool(piMetabase, pswapp->wzAppPool, wzAppPoolName, countof(wzAppPoolName), psapList); |
| 181 | ExitOnFailure(hr, "failed to find app pool: %ls", pswapp->wzAppPool); |
| 182 | hr = ScaWriteMetabaseValue(piMetabase, wzRootOfWeb, NULL, MD_APP_APPPOOL_ID, METADATA_INHERIT, IIS_MD_UT_SERVER, STRING_METADATA, wzAppPoolName); |
| 183 | ExitOnFailure(hr, "Failed to write default AppPool for App: '%ls'", pswapp->wzName); |
| 184 | } |
| 185 | |
| 186 | if (pswapp->pswappextList) |
| 187 | { |
| 188 | hr = ScaWebAppExtensionsWrite(piMetabase, wzRootOfWeb, pswapp->pswappextList); |
| 189 | ExitOnFailure(hr, "Failed to write AppExtensions for App: '%ls'", pswapp->wzName); |
| 190 | } |
| 191 | |
| 192 | LExit: |
| 193 | return hr; |
| 194 | } |