diff --git a/THIRD-PARTY-NOTICES b/THIRD-PARTY-NOTICES index a6470f40de..d1bf499032 100644 --- a/THIRD-PARTY-NOTICES +++ b/THIRD-PARTY-NOTICES @@ -35,3 +35,52 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +License notice for IIS-Common +------------------------------------ + +MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE + +License notice for IIS-Setup +------------------------------------ + +MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/ANCMPackageResolver/ANCMPackageResolver.csproj b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMPackageResolver/ANCMPackageResolver.csproj new file mode 100644 index 0000000000..e09c9574bb --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/ANCMPackageResolver/ANCMPackageResolver.csproj @@ -0,0 +1,26 @@ + + + netstandard1.0 + true + true + $(RepositoryRoot).deps\ANCM + + + + + + + + + + $(RepositoryRoot).deps\ANCM; + + + $(RestoreSources); + https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json; + https://api.nuget.org/v3/index.json; + https://dotnet.myget.org/F/dotnet-core/api/v3/index.json; + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/Directory.Build.props b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/Directory.Build.props new file mode 100644 index 0000000000..2f47372910 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/Directory.Build.props @@ -0,0 +1,15 @@ + + + + + + + $(_TwoDigitYear)$(_ThreeDigitDayOfYear) + $(PRODUCT_MAJOR) + $(PRODUCT_MINOR) + $(BUILD_MAJOR) + $(BUILD_MINOR) + BLDVERMAJOR=$(BLDVERMAJOR);BLDVERMINOR=$(BLDVERMINOR);BLDNUMMAJOR=$(BLDNUMMAJOR);BLDNUMMINOR=$(BLDNUMMINOR);$(DefineConstants) + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.cpp new file mode 100644 index 0000000000..48d826f720 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.cpp @@ -0,0 +1,184 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +#include + +DECLARE_DEBUG_PRINT_OBJECT( "proxyCA.dll" ); + +HINSTANCE g_hinst; + +BOOL WINAPI +DllMain( + HINSTANCE hModule, + DWORD dwReason, + LPVOID lpReserved + ) +{ + UNREFERENCED_PARAMETER( lpReserved ); + switch( dwReason ) + { + case DLL_PROCESS_ATTACH: + CREATE_DEBUG_PRINT_OBJECT; + DisableThreadLibraryCalls( hModule ); + g_hinst = hModule; + break; + + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} + + +struct COMPRESSION_MIME_TYPE +{ + PCWSTR pszMimeType; + BOOL fEnabled; +}; + +COMPRESSION_MIME_TYPE gMimeTypes[] = + { { L"text/event-stream", FALSE} }; + +UINT +WINAPI +RegisterANCMCompressionCA( + IN MSIHANDLE + ) +{ + HRESULT hr = S_OK; + DWORD i; + VARIANT varName; + IAppHostWritableAdminManager * pAdminMgr = NULL; + IAppHostElement * pHttpCompressionSection = NULL; + IAppHostElement * pDynamicCompressionElement = NULL; + IAppHostElementCollection * pMimeTypeCollection = NULL; + IAppHostElement * pMimeTypeElement = NULL; + + VariantInit(&varName); + + hr = CoCreateInstance(__uuidof(AppHostWritableAdminManager), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(IAppHostWritableAdminManager), + (VOID **)&pAdminMgr); + if (FAILED(hr)) + { + goto exit; + } + + hr = pAdminMgr->GetAdminSection(L"system.webServer/httpCompression", + L"MACHINE/WEBROOT/APPHOST", + &pHttpCompressionSection); + if (FAILED(hr)) + { + goto exit; + } + + hr = pHttpCompressionSection->GetElementByName(L"dynamicTypes", + &pDynamicCompressionElement); + if (FAILED(hr)) + { + goto exit; + } + + hr = pDynamicCompressionElement->get_Collection(&pMimeTypeCollection); + if (FAILED(hr)) + { + goto exit; + } + + hr = pMimeTypeCollection->get_Count(&i); + if (FAILED(hr) || i == 0) + { + // failure or DynamicCmpression is not enabled + goto exit; + } + + for (i=0; i<_countof(gMimeTypes); i++) + { + hr = pMimeTypeCollection->CreateNewElement(L"add", + &pMimeTypeElement); + if (FAILED(hr)) + { + goto exit; + } + + hr = VariantAssign(&varName, + gMimeTypes[i].pszMimeType); + if (FAILED(hr)) + { + goto exit; + } + + hr = SetElementProperty(pMimeTypeElement, + L"mimeType", + &varName); + if (FAILED(hr)) + { + goto exit; + } + VariantClear(&varName); + + varName.vt = VT_BOOL; + varName.boolVal = gMimeTypes[i].fEnabled ? VARIANT_TRUE : VARIANT_FALSE; + + hr = SetElementProperty(pMimeTypeElement, + L"enabled", + &varName); + if (FAILED(hr)) + { + goto exit; + } + VariantClear(&varName); + + hr = pMimeTypeCollection->AddElement(pMimeTypeElement); + if (FAILED(hr) && + hr != HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) + { + goto exit; + } + + pMimeTypeElement->Release(); + pMimeTypeElement = NULL; + } + + hr = pAdminMgr->CommitChanges(); + + exit: + + VariantClear(&varName); + + if (pMimeTypeElement != NULL) + { + pMimeTypeElement->Release(); + pMimeTypeElement = NULL; + } + + if (pMimeTypeCollection != NULL) + { + pMimeTypeCollection->Release(); + pMimeTypeCollection = NULL; + } + + if (pDynamicCompressionElement != NULL) + { + pDynamicCompressionElement->Release(); + pDynamicCompressionElement = NULL; + } + + if (pHttpCompressionSection != NULL) + { + pHttpCompressionSection->Release(); + pHttpCompressionSection = NULL; + } + + if (pAdminMgr != NULL) + { + pAdminMgr->Release(); + pAdminMgr = NULL; + } + + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_SUCCESS; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.def b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.def new file mode 100644 index 0000000000..3518cde35f --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.def @@ -0,0 +1,23 @@ +LIBRARY aspnetcoreCA + +EXPORTS + + ; IIS Common Config custom actions + + IISScheduleInstallCA + IISScheduleUninstallCA + IISExecuteCA + IISBeginTransactionCA + IISRollbackTransactionCA + IISCommitTransactionCA + + CheckForSharedConfigurationCA + + ScheduleInstallWindowsHotfixCA + ExecuteInstallWindowsHotfixCA + ExecuteCleanUpWindowsHotfixCA + ScheduleRebootIfRequiredCA + + RegisterANCMCompressionCA + + CheckForServicesRunningCA diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.rc b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.rc new file mode 100644 index 0000000000..8f05349435 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.rc @@ -0,0 +1,10 @@ +#define VER_FILETYPE VFT_DLL +#define RC_VERSION_INTERNAL_NAME "aspnetcoreCA\0" +#define RC_VERSION_ORIGINAL_FILE_NAME "aspnetcoreCA.dll\0" +#define RC_VERSION_FILE_DESCRIPTION "IIS AspNet Core Support Module Custom Action DLL\0" +#define PRODUCT_MAJOR 7 +#define PRODUCT_MINOR 1 +#define BUILD_MAJOR 1972 +#define BUILD_MINOR 0 + +#include diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.vcxproj b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.vcxproj new file mode 100644 index 0000000000..9d621fb37b --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/aspnetcoreCA.vcxproj @@ -0,0 +1,98 @@ + + + + + $(MSBuildThisFileDirectory)..\ + + + + <_IIS-SetupExportsPath>$(ANCM-Setup)IIS-Setup\build\exports.props + + + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {7C27E72F-54D0-4820-8CFA-5E4BE640974B} + aspnetcoreca + aspnetcoreCA + + + + DynamicLibrary + v141 + Unicode + + + true + + + + $(IIS-Common)version;$(IIS-Common)Include;$(IIS-Setup)iisca\lib;$(WIX)sdk\$(WixPlatformToolset)\inc;$(AdditionalIncludeDirectories) + + + + true + $(AdditionalIncludeDirectories) + + + httpapi.lib;shlwapi.lib;ahadmin.lib;xmllite.lib;msi.lib;Version.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + aspnetcoreCA.def + $(OutDir)$(TargetName).lib + /NODEFAULTLIB:MSVCRT %(AdditionalOptions) + + + + + + + + + + + + $(IIS-Common)version + + + + + {7324770c-0871-4d73-be3d-5e2f3e9e1b1e} + + + {b54a8f61-60de-4ad9-87ca-d102f230678e} + + + + + + + This project is trying to import a missing file: {0}. + + + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/avoid_restart.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/avoid_restart.cpp new file mode 100644 index 0000000000..b0e4753c44 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/CustomAction/avoid_restart.cpp @@ -0,0 +1,244 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +#include +#include + +HRESULT +GetServiceCurrentState( + __in LPCWSTR pszServiceName, + __out SERVICE_STATUS * pServiceStatus +) +{ + HRESULT hr = S_OK; + SC_HANDLE hServiceControlManager = NULL; + SC_HANDLE hService = NULL; + + hServiceControlManager = OpenSCManager( NULL, // Local machine + NULL, + STANDARD_RIGHTS_READ ); + if ( hServiceControlManager == NULL ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto Finished; + } + + hService = OpenService( hServiceControlManager, + pszServiceName, + SERVICE_QUERY_STATUS ); + if ( hService == NULL ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto Finished; + } + + if ( !QueryServiceStatus( hService, + pServiceStatus ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto Finished; + } + +Finished: + + if ( hService != NULL ) + { + CloseServiceHandle( hService ); + hService = NULL; + } + + if ( hServiceControlManager != NULL ) + { + CloseServiceHandle( hService ); + hService = NULL; + } + + return hr; +} + +BOOL +IsServiceRunning( + const SERVICE_STATUS & ServiceStatus +) +{ + switch( ServiceStatus.dwCurrentState ) + { + case SERVICE_RUNNING: + case SERVICE_START_PENDING: + case SERVICE_CONTINUE_PENDING: + return TRUE; + default: + return FALSE; + } +} + +HRESULT +IsQfeInstalled( + __in LPCWSTR pszQfeName, + __out BOOL * pfIsInstalled +) +{ + HRESULT hr = S_OK; + CComPtr< IWbemLocator > pLocator; + CComPtr< IWbemServices > pService; + CComPtr< IEnumWbemClassObject > pEnumerator; + ULONG Count = 0; + CComPtr< IWbemClassObject > pProcessor; + CComBSTR bstrNamespace; + CComBSTR bstrQueryLanguage; + CComBSTR bstrQuery; + + if ( FAILED( hr = bstrNamespace.Append( L"root\\CIMV2", 10 ) ) || + FAILED( hr = bstrQueryLanguage.Append( L"WQL", 3 ) ) || + FAILED( hr = bstrQuery.Append( L"SELECT HotFixID FROM Win32_QuickFixEngineering WHERE HotFixID='" ) ) || + FAILED( hr = bstrQuery.Append( pszQfeName ) ) || + FAILED( hr = bstrQuery.Append( L"'", 1 ) ) ) + { + goto Finished; + } + + hr = CoCreateInstance( __uuidof(WbemAdministrativeLocator), + NULL, // pUnkOuter + CLSCTX_INPROC_SERVER, + __uuidof(IWbemLocator), + reinterpret_cast< void** >( &pLocator ) ); + if ( FAILED( hr ) ) + { + goto Finished; + } + + hr = pLocator->ConnectServer( bstrNamespace, + NULL, // strUser + NULL, // strPassword + NULL, // strLocale + WBEM_FLAG_CONNECT_USE_MAX_WAIT, + NULL, // strAuthority + NULL, // pCtx + &pService ); + if ( FAILED( hr ) ) + { + goto Finished; + } + + // + // Set the proxy so that impersonation of the client occurs. + // + hr = CoSetProxyBlanket( pService, + RPC_C_AUTHN_DEFAULT, + RPC_C_AUTHZ_NONE, + NULL, + RPC_C_AUTHN_LEVEL_CONNECT, + RPC_C_IMP_LEVEL_IMPERSONATE, + NULL, + EOAC_NONE); + if ( FAILED( hr ) ) + { + goto Finished; + } + + hr = pService->ExecQuery( bstrQueryLanguage, + bstrQuery, + WBEM_FLAG_FORWARD_ONLY, + NULL, + &pEnumerator ); + if ( FAILED( hr ) ) + { + goto Finished; + } + + hr = pEnumerator->Next( WBEM_INFINITE, + 1L, + &pProcessor, + &Count ); + if ( FAILED( hr ) ) + { + goto Finished; + } + + *pfIsInstalled = Count > 0; + +Finished: + + return hr; +} + +UINT +WINAPI +CheckForServicesRunningCA( + MSIHANDLE hInstall +) +{ + HRESULT hr = S_OK; + BOOL fIsServiceRunning = FALSE; + SERVICE_STATUS ServiceStatus; + LPCWSTR rgServiceNames[] = { L"WAS", L"WMSVC" }; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + // + // Check if any pService is running. + // + for( DWORD Index = 0; Index < _countof( rgServiceNames ); Index ++ ) + { + hr = GetServiceCurrentState( rgServiceNames[Index], + &ServiceStatus ); + if ( hr == HRESULT_FROM_WIN32( ERROR_SERVICE_DOES_NOT_EXIST ) ) + { + hr = S_OK; + } + else if ( FAILED( hr ) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"Failed to query the state of the service '%s' hr=0x%x", + rgServiceNames[Index], + hr ); + DBGERROR_HR(hr); + goto Finished; + } + else + { + fIsServiceRunning = IsServiceRunning( ServiceStatus ); + if ( fIsServiceRunning ) + { + break; + } + } + } + + if ( fIsServiceRunning ) + { + BOOL fQfeInstalled = FALSE; + + hr = IsQfeInstalled( L"KB954438", + &fQfeInstalled ); + if ( FAILED( hr ) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"Failed to query the hotfix 'KB949172' information hr=0x%x", + hr ); + DBGERROR_HR(hr); + goto Finished; + } + + if ( fQfeInstalled ) + { + // + // hotfix is already installed. + // + goto Finished; + } + + IISLogClose(); + return LogMsiCustomActionError( hInstall, 30003 ); + } + +Finished: + + IISLogClose(); + + // TODO Wire up when Rollback CA's are wired up + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_SUCCESS; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props b/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props new file mode 100644 index 0000000000..63b61c1a81 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Directory.Build.props @@ -0,0 +1,35 @@ + + + + + + $(RepositoryRoot)src\Installers\Windows\AspNetCoreModule-Setup\ + $(AspNetCoreSetupRoot)IIS-Setup\ + $(IIS-Setup)IIS-Common\ + + CustomAction=$(AspNetCoreSetupRoot)CustomAction\bin\$(Configuration)\$(Platform)\aspnetcoreca.dll + + $(RepositoryRoot).deps\ANCM\Microsoft.AspNetCore.AspNetCoreModule\$(MicrosoftAspNetCoreAspNetCoreModulePackageVersion)\ + $(RepositoryRoot).deps\ANCM\Microsoft.AspNetCore.AspNetCoreModuleV2\$(MicrosoftAspNetCoreAspNetCoreModuleV2PackageVersion)\ + + $(PreBuiltANCMSchema)contentFiles\any\any\ + $(PreBuiltANCMV2Schema)contentFiles\any\any\ + + 2.0.0 + ANCMOutOfProcessHandlerVersion=$(ANCMOutOfProcessHandlerVersion);$(DefineConstants) + PreBuiltANCMRoot=$(PreBuiltANCMRoot);PreBuiltANCMV2Root=$(PreBuiltANCMV2Root);$(DefineConstants) + $(CustomActionVariable);PreBuiltANCMSchema=$(PreBuiltANCMSchema);PreBuiltANCMV2Schema=$(PreBuiltANCMV2Schema);$(DefineConstants) + + <_TwoDigitYear>$([MSBuild]::Subtract($([System.DateTime]::UtcNow.Year), 2000)) + <_ThreeDigitDayOfYear>$([System.DateTime]::UtcNow.DayOfYear.ToString().PadLeft(3, '0')) + + + $(_TwoDigitYear)$(_ThreeDigitDayOfYear) + $(PRODUCT_MAJOR) + $(PRODUCT_MINOR) + $(BUILD_MAJOR) + $(BUILD_MINOR) + BLDVERMAJOR=$(BLDVERMAJOR);BLDVERMINOR=$(BLDVERMINOR);BLDNUMMAJOR=$(BLDNUMMAJOR);BLDNUMMINOR=$(BLDNUMMINOR);$(DefineConstants) + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Common.sln b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Common.sln new file mode 100644 index 0000000000..5b48ec6769 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Common.sln @@ -0,0 +1,41 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27120.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonLib", "lib\CommonLib.vcxproj", "{B54A8F61-60DE-4AD9-87CA-D102F230678E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reftrace", "reftrace\reftrace.vcxproj", "{A2599642-CBE5-4230-8511-3DC2D81874BE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Debug|x64.ActiveCfg = Debug|x64 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Debug|x64.Build.0 = Debug|x64 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Debug|x86.ActiveCfg = Debug|Win32 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Debug|x86.Build.0 = Debug|Win32 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Release|x64.ActiveCfg = Release|x64 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Release|x64.Build.0 = Release|x64 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Release|x86.ActiveCfg = Release|Win32 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Release|x86.Build.0 = Release|Win32 + {A2599642-CBE5-4230-8511-3DC2D81874BE}.Debug|x64.ActiveCfg = Debug|x64 + {A2599642-CBE5-4230-8511-3DC2D81874BE}.Debug|x64.Build.0 = Debug|x64 + {A2599642-CBE5-4230-8511-3DC2D81874BE}.Debug|x86.ActiveCfg = Debug|Win32 + {A2599642-CBE5-4230-8511-3DC2D81874BE}.Debug|x86.Build.0 = Debug|Win32 + {A2599642-CBE5-4230-8511-3DC2D81874BE}.Release|x64.ActiveCfg = Release|x64 + {A2599642-CBE5-4230-8511-3DC2D81874BE}.Release|x64.Build.0 = Release|x64 + {A2599642-CBE5-4230-8511-3DC2D81874BE}.Release|x86.ActiveCfg = Release|Win32 + {A2599642-CBE5-4230-8511-3DC2D81874BE}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {81F5A61A-A12A-4F53-B0F9-C0E541CA6567} + EndGlobalSection +EndGlobal diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/acache.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/acache.h new file mode 100644 index 0000000000..83e39fd7ff --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/acache.h @@ -0,0 +1,116 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#include "percpu.h" + + +class ALLOC_CACHE_HANDLER +{ +public: + + ALLOC_CACHE_HANDLER( + VOID + ); + + ~ALLOC_CACHE_HANDLER( + VOID + ); + + HRESULT + Initialize( + DWORD cbSize, + LONG nThreshold + ); + + LPVOID + Alloc( + VOID + ); + + VOID + Free( + __in LPVOID pMemory + ); + + +private: + + VOID + CleanupLookaside( + VOID + ); + + DWORD + QueryDepthForAllSLists( + VOID + ); + + LONG m_nThreshold; + DWORD m_cbSize; + + PER_CPU * m_pFreeLists; + + // + // Total heap allocations done over the lifetime. + // Note that this is not interlocked, it is just a hint for debugging. + // + volatile LONG m_nTotal; + + LONG m_nFillPattern; + +public: + + static + HRESULT + StaticInitialize( + VOID + ); + + static + VOID + StaticTerminate( + VOID + ); + + static + BOOL + IsPageheapEnabled(); + +private: + + static LONG sm_nFillPattern; + static HANDLE sm_hHeap; +}; + + +// You can use ALLOC_CACHE_HANDLER as a per-class allocator +// in your C++ classes. Add the following to your class definition: +// +// protected: +// static ALLOC_CACHE_HANDLER* sm_palloc; +// public: +// static void* operator new(size_t s) +// { +// IRTLASSERT(s == sizeof(C)); +// IRTLASSERT(sm_palloc != NULL); +// return sm_palloc->Alloc(); +// } +// static void operator delete(void* pv) +// { +// IRTLASSERT(pv != NULL); +// if (sm_palloc != NULL) +// sm_palloc->Free(pv); +// } +// +// Obviously, you must initialize sm_palloc before you can allocate +// any objects of this class. +// +// Note that if you derive a class from this base class, the derived class +// must also provide its own operator new and operator delete. If not, the +// base class's allocator will be called, but the size of the derived +// object will almost certainly be larger than that of the base object. +// Furthermore, the allocator will not be used for arrays of objects +// (override operator new[] and operator delete[]), but this is a +// harder problem since the allocator works with one fixed size. diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/ahutil.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/ahutil.h new file mode 100644 index 0000000000..a39c09bb73 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/ahutil.h @@ -0,0 +1,264 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +HRESULT +SetElementProperty( + IN IAppHostElement * pElement, + IN CONST WCHAR * szPropName, + IN CONST VARIANT * varPropValue + ); + +HRESULT +SetElementStringProperty( + IN IAppHostElement * pElement, + IN CONST WCHAR * szPropName, + IN CONST WCHAR * szPropValue + ); + +HRESULT +GetElementStringProperty( + IN IAppHostElement * pElement, + IN CONST WCHAR * szPropName, + OUT BSTR * pbstrPropValue + ); + +HRESULT +GetElementStringProperty( + IN IAppHostElement * pElement, + IN CONST WCHAR * szPropName, + OUT STRU * pstrPropValue + ); + +HRESULT +GetElementBoolProperty( + IN IAppHostElement * pElement, + IN LPCWSTR pszPropertyName, + OUT BOOL * pBool + ); + +HRESULT +GetElementBoolProperty( + IN IAppHostElement * pElement, + IN LPCWSTR pszPropertyName, + OUT bool * pBool + ); + +HRESULT +GetElementChildByName( + IN IAppHostElement * pElement, + IN LPCWSTR pszElementName, + OUT IAppHostElement ** ppChildElement + ); + +HRESULT +GetElementDWORDProperty( + IN IAppHostElement * pElement, + IN LPCWSTR pszPropertyName, + OUT DWORD * pdwValue + ); + +HRESULT +GetElementINTProperty( + IN IAppHostElement * pElement, + IN LPCWSTR pszPropertyName, + OUT INT * pintValue + ); + +HRESULT +GetElementLONGLONGProperty( + IN IAppHostElement * pElement, + IN LPCWSTR pszPropertyName, + OUT LONGLONG * pllValue +); + + +HRESULT +GetElementRawTimeSpanProperty( + IN IAppHostElement * pElement, + IN LPCWSTR pszPropertyName, + OUT ULONGLONG * pulonglong + ); + +#define FIND_ELEMENT_CASE_SENSITIVE 0x00000000 +#define FIND_ELEMENT_CASE_INSENSITIVE 0x00000001 + +HRESULT +DeleteElementFromCollection( + IAppHostElementCollection *pCollection, + CONST WCHAR * szKeyName, + CONST WCHAR * szKeyValue, + ULONG BehaviorFlags, + BOOL * pfDeleted + ); + +HRESULT +DeleteAllElementsFromCollection( + IAppHostElementCollection *pCollection, + CONST WCHAR * szKeyName, + CONST WCHAR * szKeyValue, + ULONG BehaviorFlags, + UINT * pNumDeleted + ); + +HRESULT +FindElementInCollection( + IAppHostElementCollection *pCollection, + CONST WCHAR * szKeyName, + CONST WCHAR * szKeyValue, + ULONG BehaviorFlags, + OUT ULONG * pIndex + ); + +HRESULT +VariantAssign( + IN OUT VARIANT * pv, + IN CONST WCHAR * sz + ); + +HRESULT +GetLocationFromFile( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szLocationPath, + OUT IAppHostConfigLocation ** ppLocation, + OUT BOOL * pFound + ); + +HRESULT +GetSectionFromLocation( + IN IAppHostConfigLocation * pLocation, + IN CONST WCHAR * szSectionName, + OUT IAppHostElement ** ppSectionElement, + OUT BOOL * pFound + ); + +HRESULT +GetAdminElement( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szElementName, + OUT IAppHostElement ** pElement + ); + +HRESULT +ClearAdminElement( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szElementName + ); + +HRESULT +ClearElementFromAllSites( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szElementName + ); + +HRESULT +ClearElementFromAllLocations( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szElementName + ); + +HRESULT +ClearLocationElements( + IN IAppHostConfigLocation * pLocation, + IN CONST WCHAR * szElementName + ); + +HRESULT +CompareElementName( + IN IAppHostElement * pElement, + IN CONST WCHAR * szNameToMatch, + OUT BOOL * pMatched + ); + +HRESULT +ClearChildElementsByName( + IN IAppHostChildElementCollection * pCollection, + IN CONST WCHAR * szElementName, + OUT BOOL * pFound + ); + +HRESULT +GetSitesCollection( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + OUT IAppHostElementCollection ** pSitesCollection + ); + +HRESULT +GetLocationCollection( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + OUT IAppHostConfigLocationCollection ** pLocationCollection + ); + +struct ENUM_INDEX +{ + VARIANT Index; + ULONG Count; +}; + +HRESULT +FindFirstElement( + IN IAppHostElementCollection * pCollection, + OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ); + +HRESULT +FindNextElement( + IN IAppHostElementCollection * pCollection, + IN OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ); + +HRESULT +FindFirstChildElement( + IN IAppHostChildElementCollection * pCollection, + OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ); + +HRESULT +FindNextChildElement( + IN IAppHostChildElementCollection * pCollection, + IN OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ); + +HRESULT +FindFirstLocation( + IN IAppHostConfigLocationCollection * pCollection, + OUT ENUM_INDEX * pIndex, + OUT IAppHostConfigLocation ** pLocation + ); + +HRESULT +FindNextLocation( + IN IAppHostConfigLocationCollection * pCollection, + IN OUT ENUM_INDEX * pIndex, + OUT IAppHostConfigLocation ** pLocation + ); + +HRESULT +FindFirstLocationElement( + IN IAppHostConfigLocation * pLocation, + OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ); + +HRESULT +FindNextLocationElement( + IN IAppHostConfigLocation * pLocation, + IN OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ); + +HRESULT GetSharedConfigEnabled( + BOOL * pfIsSharedConfig +); \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/base64.hxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/base64.hxx new file mode 100644 index 0000000000..871c7e8e0f --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/base64.hxx @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _BASE64_HXX_ +#define _BASE64_HXX_ + +DWORD +Base64Encode( + __in_bcount( cbDecodedBufferSize ) VOID * pDecodedBuffer, + IN DWORD cbDecodedBufferSize, + __out_ecount_opt( cchEncodedStringSize ) PWSTR pszEncodedString, + IN DWORD cchEncodedStringSize, + __out_opt DWORD * pcchEncoded + ); + +DWORD +Base64Decode( + __in PCWSTR pszEncodedString, + __out_opt VOID * pDecodeBuffer, + __in DWORD cbDecodeBufferSize, + __out_opt DWORD * pcbDecoded + ); + +DWORD +Base64Encode( + __in_bcount( cbDecodedBufferSize ) VOID * pDecodedBuffer, + IN DWORD cbDecodedBufferSize, + __out_ecount_opt( cchEncodedStringSize ) PSTR pszEncodedString, + IN DWORD cchEncodedStringSize, + __out_opt DWORD * pcchEncoded + ); + +DWORD +Base64Decode( + __in PCSTR pszEncodedString, + __out_opt VOID * pDecodeBuffer, + __in DWORD cbDecodeBufferSize, + __out_opt DWORD * pcbDecoded + ); + +#endif // _BASE64_HXX_ + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/buffer.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/buffer.h new file mode 100644 index 0000000000..63e567be4d --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/buffer.h @@ -0,0 +1,271 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#include + + +// +// BUFFER_T class shouldn't be used directly. Use BUFFER specialization class instead. +// The only BUFFER_T partners are STRU and STRA classes. +// BUFFER_T cannot hold other but primitive types since it doesn't call +// constructor and destructor. +// +// Note: Size is in bytes. +// +template +class BUFFER_T +{ +public: + + BUFFER_T() + : m_cbBuffer( sizeof(m_rgBuffer) ), + m_fHeapAllocated( false ), + m_pBuffer(m_rgBuffer) + /*++ + Description: + + Default constructor where the inline buffer is used. + + Arguments: + + None. + + Returns: + + None. + + --*/ + { + } + + BUFFER_T( + __inout_bcount(cbInit) T* pbInit, + __in DWORD cbInit + ) : m_pBuffer( pbInit ), + m_cbBuffer( cbInit ), + m_fHeapAllocated( false ) + /*++ + Description: + + Instantiate BUFFER, initially using pbInit as buffer + This is useful for stack-buffers and inline-buffer class members + (see STACK_BUFFER and INLINE_BUFFER_INIT below) + + BUFFER does not free pbInit. + + Arguments: + + pbInit - Initial buffer to use. + cbInit - Size of pbInit in bytes (not in elements). + + Returns: + + None. + + --*/ + { + _ASSERTE( NULL != pbInit ); + _ASSERTE( cbInit > 0 ); + } + + ~BUFFER_T() + { + if( IsHeapAllocated() ) + { + _ASSERTE( NULL != m_pBuffer ); + HeapFree( GetProcessHeap(), 0, m_pBuffer ); + m_pBuffer = NULL; + m_cbBuffer = 0; + m_fHeapAllocated = false; + } + } + + T* + QueryPtr( + VOID + ) const + { + // + // Return pointer to data buffer. + // + return m_pBuffer; + } + + DWORD + QuerySize( + VOID + ) const + { + // + // Return number of bytes. + // + return m_cbBuffer; + } + + __success(return == true) + bool + Resize( + const SIZE_T cbNewSize, + const bool fZeroMemoryBeyondOldSize = false + ) + /*++ + Description: + + Resizes the buffer. + + Arguments: + + cbNewSize - Size in bytes to grow to. + fZeroMemoryBeyondOldSize + - Whether to zero the region of memory of the + new buffer beyond the original size. + + Returns: + + TRUE on success, FALSE on failure. + + --*/ + { + PVOID pNewMem; + + if ( cbNewSize <= m_cbBuffer ) + { + return true; + } + + if ( cbNewSize > MAXDWORD ) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return false; + } + + DWORD dwHeapAllocFlags = fZeroMemoryBeyondOldSize ? HEAP_ZERO_MEMORY : 0; + + if( IsHeapAllocated() ) + { + pNewMem = HeapReAlloc( GetProcessHeap(), dwHeapAllocFlags, m_pBuffer, cbNewSize ); + } + else + { + pNewMem = HeapAlloc( GetProcessHeap(), dwHeapAllocFlags, cbNewSize ); + } + + if( pNewMem == NULL ) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return false; + } + + if( !IsHeapAllocated() ) + { + // + // First time this block is allocated. Copy over old contents. + // + memcpy_s( pNewMem, static_cast(cbNewSize), m_pBuffer, m_cbBuffer ); + m_fHeapAllocated = true; + } + + m_pBuffer = reinterpret_cast(pNewMem); + m_cbBuffer = static_cast(cbNewSize); + + _ASSERTE( m_pBuffer != NULL ); + + return true; + } + +private: + + bool + IsHeapAllocated( + VOID + ) const + { + return m_fHeapAllocated; + } + + // + // The default inline buffer. + // This member should be at the beginning for alignment purposes. + // + T m_rgBuffer[LENGTH]; + + // + // Is m_pBuffer dynamically allocated? + // + bool m_fHeapAllocated; + + // + // Size of the buffer as requested by client in bytes. + // + DWORD m_cbBuffer; + + // + // Pointer to buffer. + // + __field_bcount_full(m_cbBuffer) + T* m_pBuffer; +}; + +// +// Resizes the buffer by 2 if the ideal size is bigger +// than the buffer length. That give us lg(n) allocations. +// +// Use template inferring like: +// +// BUFFER buff; +// hr = ResizeBufferByTwo(buff, 100); +// +template +HRESULT +ResizeBufferByTwo( + BUFFER_T& Buffer, + SIZE_T cbIdealSize, + bool fZeroMemoryBeyondOldSize = false +) +{ + if (cbIdealSize > Buffer.QuerySize()) + { + if (!Buffer.Resize(max(cbIdealSize, static_cast(Buffer.QuerySize() * 2)), + fZeroMemoryBeyondOldSize)) + { + return E_OUTOFMEMORY; + } + } + return S_OK; +} + + +// +// +// Lots of code uses BUFFER class to store a bunch of different +// structures, so m_rgBuffer needs to be 8 byte aligned when it is used +// as an opaque buffer. +// +#define INLINED_BUFFER_LEN 32 +typedef BUFFER_T BUFFER; + +// +// Assumption of macros below for pointer alignment purposes +// +C_ASSERT( sizeof(VOID*) <= sizeof(ULONGLONG) ); + +// +// Declare a BUFFER that will use stack memory of +// bytes. If the buffer overflows then a heap buffer will be allocated. +// +#define STACK_BUFFER( _name, _size ) \ + ULONGLONG __aqw##_name[ ( ( (_size) + sizeof(ULONGLONG) - 1 ) / sizeof(ULONGLONG) ) ]; \ + BUFFER _name( (BYTE*)__aqw##_name, sizeof(__aqw##_name) ) + +// +// Macros for declaring and initializing a BUFFER that will use inline memory +// of bytes as a member of an object. +// +#define INLINE_BUFFER( _name, _size ) \ + ULONGLONG __aqw##_name[ ( ( (_size) + sizeof(ULONGLONG) - 1 ) / sizeof(ULONGLONG) ) ]; \ + BUFFER _name; + +#define INLINE_BUFFER_INIT( _name ) \ + _name( (BYTE*)__aqw##_name, sizeof( __aqw##_name ) ) diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/datetime.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/datetime.h new file mode 100644 index 0000000000..82ac441abd --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/datetime.h @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _DATETIME_H_ +#define _DATETIME_H_ + +BOOL +StringTimeToFileTime( + PCSTR pszTime, + ULONGLONG * pulTime +); + +#endif + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/dbgutil.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/dbgutil.h new file mode 100644 index 0000000000..9a33cca394 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/dbgutil.h @@ -0,0 +1,102 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _DBGUTIL_H_ +#define _DBGUTIL_H_ + +#include + +// +// TODO +// Using _CrtDbg implementation. If hooking is desired +// wrappers should be provided here so that we can reimplement +// if neecessary. +// +// IF_DEBUG/DEBUG FLAGS +// +// registry configuration +// + +// +// Debug error levels for DEBUG_FLAGS_VAR. +// + +#define DEBUG_FLAG_INFO 0x00000001 +#define DEBUG_FLAG_WARN 0x00000002 +#define DEBUG_FLAG_ERROR 0x00000004 + +// +// Predefined error level values. These are backwards from the +// windows definitions. +// + +#define DEBUG_FLAGS_INFO (DEBUG_FLAG_ERROR | DEBUG_FLAG_WARN | DEBUG_FLAG_INFO) +#define DEBUG_FLAGS_WARN (DEBUG_FLAG_ERROR | DEBUG_FLAG_WARN) +#define DEBUG_FLAGS_ERROR (DEBUG_FLAG_ERROR) +#define DEBUG_FLAGS_ANY (DEBUG_FLAG_INFO | DEBUG_FLAG_WARN | DEBUG_FLAG_ERROR) + +// +// Global variables to control tracing. Generally per module +// + +#ifndef DEBUG_FLAGS_VAR +#define DEBUG_FLAGS_VAR g_dwDebugFlags +#endif + +#ifndef DEBUG_LABEL_VAR +#define DEBUG_LABEL_VAR g_szDebugLabel +#endif + +extern PCSTR DEBUG_LABEL_VAR; +extern DWORD DEBUG_FLAGS_VAR; + +// +// Module should make this declaration globally. +// + +#define DECLARE_DEBUG_PRINT_OBJECT( _pszLabel_ ) \ + PCSTR DEBUG_LABEL_VAR = _pszLabel_; \ + DWORD DEBUG_FLAGS_VAR = DEBUG_FLAGS_ANY; \ + +#define DECLARE_DEBUG_PRINT_OBJECT2( _pszLabel_, _dwLevel_ ) \ + PCSTR DEBUG_LABEL_VAR = _pszLabel_; \ + DWORD DEBUG_FLAGS_VAR = _dwLevel_; \ + +// +// This doesn't do anything now. Should be safe to call in dll main. +// + +#define CREATE_DEBUG_PRINT_OBJECT + +// +// Trace macros +// + +#define DBG_CONTEXT _CRT_WARN, __FILE__, __LINE__, DEBUG_LABEL_VAR + +#ifdef DEBUG +#define DBGINFO(args) \ + {if( DEBUG_FLAGS_VAR & DEBUG_FLAG_INFO ) { _CrtDbgReport args; }} +#define DBGWARN(args) \ + {if( DEBUG_FLAGS_VAR & DEBUG_FLAG_WARN ) { _CrtDbgReport args; }} +#define DBGERROR(args) \ + {if( DEBUG_FLAGS_VAR & DEBUG_FLAG_ERROR ) { _CrtDbgReport args; }} +#else +#define DBGINFO +#define DBGWARN +#define DBGERROR +#endif + +#define DBGPRINTF DBGINFO + +// +// Simple error traces +// + +#define DBGERROR_HR( _hr_ ) \ + DBGERROR(( DBG_CONTEXT, "hr=0x%x\n", _hr_ )) + +#define DBGERROR_STATUS( _status_ ) \ + DBGERROR(( DBG_CONTEXT, "status=%d\n", _status_ )) + +#endif diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/debugutil.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/debugutil.h new file mode 100644 index 0000000000..39033973ce --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/debugutil.h @@ -0,0 +1,124 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#define DEBUG_FLAG_INFO 0x00000001 +#define DEBUG_FLAG_WARN 0x00000002 +#define DEBUG_FLAG_ERROR 0x00000004 + +// +// Predefined error level values. These are backwards from the +// windows definitions. +// + +#define DEBUG_FLAGS_INFO (DEBUG_FLAG_ERROR | DEBUG_FLAG_WARN | DEBUG_FLAG_INFO) +#define DEBUG_FLAGS_WARN (DEBUG_FLAG_ERROR | DEBUG_FLAG_WARN) +#define DEBUG_FLAGS_ERROR (DEBUG_FLAG_ERROR) +#define DEBUG_FLAGS_ANY (DEBUG_FLAG_INFO | DEBUG_FLAG_WARN | DEBUG_FLAG_ERROR) + +#define DEBUG_FLAGS_REGISTRY_LOCATION_A "DebugFlags" + +extern DWORD g_dwDebugFlags; + +static +BOOL +IfDebug( + DWORD dwFlag + ) +{ + return ( dwFlag & g_dwDebugFlags ); +} + +static +VOID +DebugPrint( + DWORD dwFlag, + LPCSTR szString + ) +{ + STBUFF strOutput; + HRESULT hr; + + if ( IfDebug( dwFlag ) ) + { + hr = strOutput.Printf( "[dipmodule.dll] %s\r\n", + szString ); + + if ( FAILED( hr ) ) + { + goto Finished; + } + + OutputDebugStringA( strOutput.QueryStr() ); + } + +Finished: + + return; +} + +static +VOID +DebugPrintf( +DWORD dwFlag, +LPCSTR szFormat, +... +) +{ + STBUFF strCooked; + STBUFF strOutput; + va_list args; + HRESULT hr; + + if ( IfDebug( dwFlag ) ) + { + va_start( args, szFormat ); + + hr = strCooked.Vsprintf( (LPSTR)szFormat, args ); + + va_end( args ); + + if ( FAILED( hr ) ) + { + goto Finished; + } + + DebugPrint( dwFlag, strCooked.QueryStr() ); + } + +Finished: + + return; +} + +static void ReadDebugFlagFromRegistryKey(const char* pszRegKey, IN DWORD dwDefault) +{ + HKEY hkey = NULL; + g_dwDebugFlags = dwDefault; + DWORD dwType; + DWORD dwBuffer; + DWORD cbBuffer = sizeof(dwBuffer); + + DWORD dwError = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + pszRegKey, + 0, + KEY_READ, + &hkey); + if ( dwError == NO_ERROR && hkey != NULL) + { + dwError = RegQueryValueExA( hkey, + DEBUG_FLAGS_REGISTRY_LOCATION_A, + NULL, + &dwType, + (LPBYTE)&dwBuffer, + &cbBuffer ); + if( ( dwError == NO_ERROR ) && ( dwType == REG_DWORD ) ) + { + g_dwDebugFlags = dwBuffer; + } + RegCloseKey( hkey); + hkey = NULL; + } +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/hashfn.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/hashfn.h new file mode 100644 index 0000000000..a86b0a1358 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/hashfn.h @@ -0,0 +1,325 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef __HASHFN_H__ +#define __HASHFN_H__ + + +// Produce a scrambled, randomish number in the range 0 to RANDOM_PRIME-1. +// Applying this to the results of the other hash functions is likely to +// produce a much better distribution, especially for the identity hash +// functions such as Hash(char c), where records will tend to cluster at +// the low end of the hashtable otherwise. LKRhash applies this internally +// to all hash signatures for exactly this reason. + +inline DWORD +HashScramble(DWORD dwHash) +{ + // Here are 10 primes slightly greater than 10^9 + // 1000000007, 1000000009, 1000000021, 1000000033, 1000000087, + // 1000000093, 1000000097, 1000000103, 1000000123, 1000000181. + + // default value for "scrambling constant" + const DWORD RANDOM_CONSTANT = 314159269UL; + // large prime number, also used for scrambling + const DWORD RANDOM_PRIME = 1000000007UL; + + return (RANDOM_CONSTANT * dwHash) % RANDOM_PRIME ; +} + + +// Faster scrambling function suggested by Eric Jacobsen + +inline DWORD +HashRandomizeBits(DWORD dw) +{ + return (((dw * 1103515245 + 12345) >> 16) + | ((dw * 69069 + 1) & 0xffff0000)); +} + + +// Small prime number used as a multiplier in the supplied hash functions +const DWORD HASH_MULTIPLIER = 101; + +#undef HASH_SHIFT_MULTIPLY + +#ifdef HASH_SHIFT_MULTIPLY +# define HASH_MULTIPLY(dw) (((dw) << 7) - (dw)) +#else +# define HASH_MULTIPLY(dw) ((dw) * HASH_MULTIPLIER) +#endif + +// Fast, simple hash function that tends to give a good distribution. +// Apply HashScramble to the result if you're using this for something +// other than LKRhash. + +inline DWORD +HashString( + const char* psz, + DWORD dwHash = 0) +{ + // force compiler to use unsigned arithmetic + const unsigned char* upsz = (const unsigned char*) psz; + + for ( ; *upsz; ++upsz) + dwHash = HASH_MULTIPLY(dwHash) + *upsz; + + return dwHash; +} + +inline DWORD +HashString( + __in_ecount(cch) const char* psz, + __in DWORD cch, + __in DWORD dwHash +) +{ + // force compiler to use unsigned arithmetic + const unsigned char* upsz = (const unsigned char*) psz; + + for (DWORD Index = 0; + Index < cch; + ++Index, ++upsz) + { + dwHash = HASH_MULTIPLY(dwHash) + *upsz; + } + + return dwHash; +} + + +// Unicode version of above + +inline DWORD +HashString( + const wchar_t* pwsz, + DWORD dwHash = 0) +{ + for ( ; *pwsz; ++pwsz) + dwHash = HASH_MULTIPLY(dwHash) + *pwsz; + + return dwHash; +} + +// Based on length of the string instead of null-terminating character + +inline DWORD +HashString( + __in_ecount(cch) const wchar_t* pwsz, + __in DWORD cch, + __in DWORD dwHash +) +{ + for (DWORD Index = 0; + Index < cch; + ++Index, ++pwsz) + { + dwHash = HASH_MULTIPLY(dwHash) + *pwsz; + } + + return dwHash; +} + + +// Quick-'n'-dirty case-insensitive string hash function. +// Make sure that you follow up with _stricmp or _mbsicmp. You should +// also cache the length of strings and check those first. Caching +// an uppercase version of a string can help too. +// Again, apply HashScramble to the result if using with something other +// than LKRhash. +// Note: this is not really adequate for MBCS strings. + +inline DWORD +HashStringNoCase( + const char* psz, + DWORD dwHash = 0) +{ + const unsigned char* upsz = (const unsigned char*) psz; + + for ( ; *upsz; ++upsz) + dwHash = HASH_MULTIPLY(dwHash) + + (*upsz & 0xDF); // strip off lowercase bit + + return dwHash; +} + +inline DWORD +HashStringNoCase( + __in_ecount(cch) + const char* psz, + SIZE_T cch, + DWORD dwHash) +{ + const unsigned char* upsz = (const unsigned char*) psz; + + for (SIZE_T Index = 0; + Index < cch; + ++Index, ++upsz) + { + dwHash = HASH_MULTIPLY(dwHash) + + (*upsz & 0xDF); // strip off lowercase bit + } + return dwHash; +} + + +// Unicode version of above + +inline DWORD +HashStringNoCase( + const wchar_t* pwsz, + DWORD dwHash = 0) +{ + for ( ; *pwsz; ++pwsz) + dwHash = HASH_MULTIPLY(dwHash) + (*pwsz & 0xFFDF); + + return dwHash; +} + +// Unicode version of above with length + +inline DWORD +HashStringNoCase( + __in_ecount(cch) + const wchar_t* pwsz, + SIZE_T cch, + DWORD dwHash) +{ + for (SIZE_T Index = 0; + Index < cch; + ++Index, ++pwsz) + { + dwHash = HASH_MULTIPLY(dwHash) + (*pwsz & 0xFFDF); + } + return dwHash; +} + + +// HashBlob returns the hash of a blob of arbitrary binary data. +// +// Warning: HashBlob is generally not the right way to hash a class object. +// Consider: +// class CFoo { +// public: +// char m_ch; +// double m_d; +// char* m_psz; +// }; +// +// inline DWORD Hash(const CFoo& rFoo) +// { return HashBlob(&rFoo, sizeof(CFoo)); } +// +// This is the wrong way to hash a CFoo for two reasons: (a) there will be +// a 7-byte gap between m_ch and m_d imposed by the alignment restrictions +// of doubles, which will be filled with random data (usually non-zero for +// stack variables), and (b) it hashes the address (rather than the +// contents) of the string m_psz. Similarly, +// +// bool operator==(const CFoo& rFoo1, const CFoo& rFoo2) +// { return memcmp(&rFoo1, &rFoo2, sizeof(CFoo)) == 0; } +// +// does the wrong thing. Much better to do this: +// +// DWORD Hash(const CFoo& rFoo) +// { +// return HashString(rFoo.m_psz, +// HASH_MULTIPLIER * Hash(rFoo.m_ch) +// + Hash(rFoo.m_d)); +// } +// +// Again, apply HashScramble if using with something other than LKRhash. + +inline DWORD +HashBlob( + const void* pv, + size_t cb, + DWORD dwHash = 0) +{ + const BYTE * pb = static_cast(pv); + + while (cb-- > 0) + dwHash = HASH_MULTIPLY(dwHash) + *pb++; + + return dwHash; +} + + + +// +// Overloaded hash functions for all the major builtin types. +// Again, apply HashScramble to result if using with something other than +// LKRhash. +// + +inline DWORD Hash(const char* psz) +{ return HashString(psz); } + +inline DWORD Hash(const unsigned char* pusz) +{ return HashString(reinterpret_cast(pusz)); } + +inline DWORD Hash(const signed char* pssz) +{ return HashString(reinterpret_cast(pssz)); } + +inline DWORD Hash(const wchar_t* pwsz) +{ return HashString(pwsz); } + +inline DWORD +Hash( + const GUID* pguid, + DWORD dwHash = 0) +{ + + return * reinterpret_cast(const_cast(pguid)) + dwHash; +} + +// Identity hash functions: scalar values map to themselves +inline DWORD Hash(char c) +{ return c; } + +inline DWORD Hash(unsigned char uc) +{ return uc; } + +inline DWORD Hash(signed char sc) +{ return sc; } + +inline DWORD Hash(short sh) +{ return sh; } + +inline DWORD Hash(unsigned short ush) +{ return ush; } + +inline DWORD Hash(int i) +{ return i; } + +inline DWORD Hash(unsigned int u) +{ return u; } + +inline DWORD Hash(long l) +{ return l; } + +inline DWORD Hash(unsigned long ul) +{ return ul; } + +inline DWORD Hash(float f) +{ + // be careful of rounding errors when computing keys + union { + float f; + DWORD dw; + } u; + u.f = f; + return u.dw; +} + +inline DWORD Hash(double dbl) +{ + // be careful of rounding errors when computing keys + union { + double dbl; + DWORD dw[2]; + } u; + u.dbl = dbl; + return u.dw[0] * HASH_MULTIPLIER + u.dw[1]; +} + +#endif // __HASHFN_H__ diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/hashtable.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/hashtable.h new file mode 100644 index 0000000000..9a299ca1af --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/hashtable.h @@ -0,0 +1,666 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#include +#include "rwlock.h" +#include "prime.h" + +template +class HASH_NODE +{ + template + friend class HASH_TABLE; + + HASH_NODE( + _Record * pRecord, + DWORD dwHash + ) : _pNext (NULL), + _pRecord (pRecord), + _dwHash (dwHash) + {} + + ~HASH_NODE() + { + _ASSERTE(_pRecord == NULL); + } + + private: + // Next node in the hash table look-aside + HASH_NODE<_Record> *_pNext; + + // actual record + _Record * _pRecord; + + // hash value + DWORD _dwHash; +}; + +template +class HASH_TABLE +{ +protected: + typedef BOOL + (PFN_DELETE_IF)( + _Record * pRecord, + PVOID pvContext + ); + + typedef VOID + (PFN_APPLY)( + _Record * pRecord, + PVOID pvContext + ); + +public: + HASH_TABLE( + VOID + ) + : _ppBuckets( NULL ), + _nBuckets( 0 ), + _nItems( 0 ) + { + } + + virtual + ~HASH_TABLE(); + + virtual + VOID + ReferenceRecord( + _Record * pRecord + ) = 0; + + virtual + VOID + DereferenceRecord( + _Record * pRecord + ) = 0; + + virtual + _Key + ExtractKey( + _Record * pRecord + ) = 0; + + virtual + DWORD + CalcKeyHash( + _Key key + ) = 0; + + virtual + BOOL + EqualKeys( + _Key key1, + _Key key2 + ) = 0; + + DWORD + Count( + VOID + ) const; + + bool + IsInitialized( + VOID + ) const; + + virtual + VOID + Clear(); + + HRESULT + Initialize( + DWORD nBucketSize + ); + + virtual + VOID + FindKey( + _Key key, + _Record ** ppRecord + ); + + virtual + HRESULT + InsertRecord( + _Record * pRecord + ); + + virtual + VOID + DeleteKey( + _Key key + ); + + virtual + VOID + DeleteIf( + PFN_DELETE_IF pfnDeleteIf, + PVOID pvContext + ); + + VOID + Apply( + PFN_APPLY pfnApply, + PVOID pvContext + ); + +private: + + __success(*ppNode != NULL && return != FALSE) + BOOL + FindNodeInternal( + _Key key, + DWORD dwHash, + __deref_out + HASH_NODE<_Record> ** ppNode, + __deref_opt_out + HASH_NODE<_Record> *** pppPreviousNodeNextPointer = NULL + ); + + VOID + DeleteNode( + HASH_NODE<_Record> * pNode + ) + { + if (pNode->_pRecord != NULL) + { + DereferenceRecord(pNode->_pRecord); + pNode->_pRecord = NULL; + } + + delete pNode; + } + + VOID + RehashTableIfNeeded( + VOID + ); + + HASH_NODE<_Record> ** _ppBuckets; + DWORD _nBuckets; + DWORD _nItems; + // + // Allow to use lock object in const methods. + // + mutable + CWSDRWLock _tableLock; +}; + +template +HRESULT +HASH_TABLE<_Record,_Key>::Initialize( + DWORD nBuckets +) +{ + HRESULT hr = S_OK; + + if ( nBuckets == 0 ) + { + hr = E_INVALIDARG; + goto Failed; + } + + if (nBuckets >= MAXDWORD/sizeof(HASH_NODE<_Record> *)) + { + hr = E_INVALIDARG; + goto Failed; + } + + _ASSERTE(_ppBuckets == NULL ); + if ( _ppBuckets != NULL ) + { + hr = E_INVALIDARG; + goto Failed; + } + + hr = _tableLock.Init(); + if ( FAILED( hr ) ) + { + goto Failed; + } + + _ppBuckets = (HASH_NODE<_Record> **)HeapAlloc( + GetProcessHeap(), + HEAP_ZERO_MEMORY, + nBuckets*sizeof(HASH_NODE<_Record> *)); + if (_ppBuckets == NULL) + { + hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + goto Failed; + } + _nBuckets = nBuckets; + + return S_OK; + +Failed: + + if (_ppBuckets) + { + HeapFree(GetProcessHeap(), + 0, + _ppBuckets); + _ppBuckets = NULL; + } + + return hr; +} + + +template +HASH_TABLE<_Record,_Key>::~HASH_TABLE() +{ + if (_ppBuckets == NULL) + { + return; + } + + _ASSERTE(_nItems == 0); + + HeapFree(GetProcessHeap(), + 0, + _ppBuckets); + _ppBuckets = NULL; + _nBuckets = 0; +} + +template< class _Record, class _Key> +DWORD +HASH_TABLE<_Record,_Key>::Count() const +{ + return _nItems; +} + +template< class _Record, class _Key> +bool +HASH_TABLE<_Record,_Key>::IsInitialized( + VOID +) const +{ + return _ppBuckets != NULL; +} + + +template +VOID +HASH_TABLE<_Record,_Key>::Clear() +{ + HASH_NODE<_Record> *pCurrent; + HASH_NODE<_Record> *pNext; + + // This is here in the off cases where someone instantiates a hashtable + // and then does an automatic "clear" before its destruction WITHOUT + // ever initializing it. + if ( ! _tableLock.QueryInited() ) + { + return; + } + + _tableLock.ExclusiveAcquire(); + + for (DWORD i=0; i<_nBuckets; i++) + { + pCurrent = _ppBuckets[i]; + _ppBuckets[i] = NULL; + while (pCurrent != NULL) + { + pNext = pCurrent->_pNext; + DeleteNode(pCurrent); + pCurrent = pNext; + } + } + + _nItems = 0; + _tableLock.ExclusiveRelease(); +} + +template +__success(*ppNode != NULL && return != FALSE) +BOOL +HASH_TABLE<_Record,_Key>::FindNodeInternal( + _Key key, + DWORD dwHash, + __deref_out + HASH_NODE<_Record> ** ppNode, + __deref_opt_out + HASH_NODE<_Record> *** pppPreviousNodeNextPointer +) +/*++ + Return value indicates whether the item is found + key, dwHash - key and hash for the node to find + ppNode - on successful return, the node found, on failed return, the first + node with hash value greater than the node to be found + pppPreviousNodeNextPointer - the pointer to previous node's _pNext + + This routine may be called under either read or write lock +--*/ +{ + HASH_NODE<_Record> **ppPreviousNodeNextPointer; + HASH_NODE<_Record> *pNode; + BOOL fFound = FALSE; + + ppPreviousNodeNextPointer = _ppBuckets + (dwHash % _nBuckets); + pNode = *ppPreviousNodeNextPointer; + while (pNode != NULL) + { + if (pNode->_dwHash == dwHash) + { + if (EqualKeys(key, + ExtractKey(pNode->_pRecord))) + { + fFound = TRUE; + break; + } + } + else if (pNode->_dwHash > dwHash) + { + break; + } + + ppPreviousNodeNextPointer = &(pNode->_pNext); + pNode = *ppPreviousNodeNextPointer; + } + + __analysis_assume( (pNode == NULL && fFound == FALSE) || + (pNode != NULL && fFound == TRUE ) ); + *ppNode = pNode; + if (pppPreviousNodeNextPointer != NULL) + { + *pppPreviousNodeNextPointer = ppPreviousNodeNextPointer; + } + return fFound; +} + +template +VOID +HASH_TABLE<_Record,_Key>::FindKey( + _Key key, + _Record ** ppRecord +) +{ + HASH_NODE<_Record> *pNode; + + *ppRecord = NULL; + + DWORD dwHash = CalcKeyHash(key); + + _tableLock.SharedAcquire(); + + if (FindNodeInternal(key, dwHash, &pNode) && + pNode->_pRecord != NULL) + { + ReferenceRecord(pNode->_pRecord); + *ppRecord = pNode->_pRecord; + } + + _tableLock.SharedRelease(); +} + +template +HRESULT +HASH_TABLE<_Record,_Key>::InsertRecord( + _Record * pRecord +) +/*++ + This method inserts a node for this record and also empty nodes for paths + in the heirarchy leading upto this path + + The insert is done under only a read-lock - this is possible by keeping + the hashes in a bucket in increasing order and using interlocked operations + to actually insert the item in the hash-bucket lookaside list and the parent + children list + + Returns HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) if the record already exists. + Never leak this error to the end user because "*file* already exists" may be confusing. +--*/ +{ + BOOL fLocked = FALSE; + _Key key = ExtractKey(pRecord); + DWORD dwHash = CalcKeyHash(key); + HRESULT hr = S_OK; + HASH_NODE<_Record> * pNewNode; + HASH_NODE<_Record> * pNextNode; + HASH_NODE<_Record> ** ppPreviousNodeNextPointer; + + // + // Ownership of pRecord is not transferred to pNewNode yet, so remember + // to either set it to null before deleting pNewNode or add an extra + // reference later - this is to make sure we do not do an extra ref/deref + // which users may view as getting flushed out of the hash-table + // + pNewNode = new HASH_NODE<_Record>(pRecord, dwHash); + if (pNewNode == NULL) + { + hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + goto Finished; + } + + _tableLock.SharedAcquire(); + fLocked = TRUE; + + do + { + // + // Find the right place to add this node + // + if (FindNodeInternal(key, dwHash, &pNextNode, &ppPreviousNodeNextPointer)) + { + // + // If node already there, return error + // + pNewNode->_pRecord = NULL; + DeleteNode(pNewNode); + + // + // We should never leak this error to the end user + // because "file already exists" may be confusing. + // + hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); + goto Finished; + } + + // + // If another node got inserted in between, we will have to retry + // + pNewNode->_pNext = pNextNode; + } while (InterlockedCompareExchangePointer((PVOID *)ppPreviousNodeNextPointer, + pNewNode, + pNextNode) != pNextNode); + // pass ownership of pRecord now + if (pRecord != NULL) + { + ReferenceRecord(pRecord); + pRecord = NULL; + } + InterlockedIncrement((LONG *)&_nItems); + +Finished: + + if (fLocked) + { + _tableLock.SharedRelease(); + } + + if (SUCCEEDED(hr)) + { + RehashTableIfNeeded(); + } + + return hr; +} + +template +VOID +HASH_TABLE<_Record,_Key>::DeleteKey( + _Key key +) +{ + HASH_NODE<_Record> *pNode; + HASH_NODE<_Record> **ppPreviousNodeNextPointer; + + DWORD dwHash = CalcKeyHash(key); + + _tableLock.ExclusiveAcquire(); + + if (FindNodeInternal(key, dwHash, &pNode, &ppPreviousNodeNextPointer)) + { + *ppPreviousNodeNextPointer = pNode->_pNext; + DeleteNode(pNode); + _nItems--; + } + + _tableLock.ExclusiveRelease(); +} + +template +VOID +HASH_TABLE<_Record,_Key>::DeleteIf( + PFN_DELETE_IF pfnDeleteIf, + PVOID pvContext +) +{ + HASH_NODE<_Record> *pNode; + HASH_NODE<_Record> **ppPreviousNodeNextPointer; + + _tableLock.ExclusiveAcquire(); + + for (DWORD i=0; i<_nBuckets; i++) + { + ppPreviousNodeNextPointer = _ppBuckets + i; + pNode = *ppPreviousNodeNextPointer; + while (pNode != NULL) + { + // + // Non empty nodes deleted based on DeleteIf, empty nodes deleted + // if they have no children + // + if (pfnDeleteIf(pNode->_pRecord, pvContext)) + { + *ppPreviousNodeNextPointer = pNode->_pNext; + DeleteNode(pNode); + _nItems--; + } + else + { + ppPreviousNodeNextPointer = &pNode->_pNext; + } + + pNode = *ppPreviousNodeNextPointer; + } + } + + _tableLock.ExclusiveRelease(); +} + +template +VOID +HASH_TABLE<_Record,_Key>::Apply( + PFN_APPLY pfnApply, + PVOID pvContext +) +{ + HASH_NODE<_Record> *pNode; + + _tableLock.SharedAcquire(); + + for (DWORD i=0; i<_nBuckets; i++) + { + pNode = _ppBuckets[i]; + while (pNode != NULL) + { + if (pNode->_pRecord != NULL) + { + pfnApply(pNode->_pRecord, pvContext); + } + + pNode = pNode->_pNext; + } + } + + _tableLock.SharedRelease(); +} + +template +VOID +HASH_TABLE<_Record,_Key>::RehashTableIfNeeded( + VOID +) +{ + HASH_NODE<_Record> **ppBuckets; + DWORD nBuckets; + HASH_NODE<_Record> *pNode; + HASH_NODE<_Record> *pNextNode; + HASH_NODE<_Record> **ppNextPointer; + HASH_NODE<_Record> *pNewNextNode; + DWORD nNewBuckets; + + // + // If number of items has become too many, we will double the hash table + // size (we never reduce it however) + // + if (_nItems <= PRIME::GetPrime(2*_nBuckets)) + { + return; + } + + _tableLock.ExclusiveAcquire(); + + nNewBuckets = PRIME::GetPrime(2*_nBuckets); + + if (_nItems <= nNewBuckets) + { + goto Finished; + } + + nBuckets = nNewBuckets; + if (nBuckets >= 0xffffffff/sizeof(HASH_NODE<_Record> *)) + { + goto Finished; + } + ppBuckets = (HASH_NODE<_Record> **)HeapAlloc( + GetProcessHeap(), + HEAP_ZERO_MEMORY, + nBuckets*sizeof(HASH_NODE<_Record> *)); + if (ppBuckets == NULL) + { + goto Finished; + } + + // + // Take out nodes from the old hash table and insert in the new one, make + // sure to keep the hashes in increasing order + // + for (DWORD i=0; i<_nBuckets; i++) + { + pNode = _ppBuckets[i]; + while (pNode != NULL) + { + pNextNode = pNode->_pNext; + + ppNextPointer = ppBuckets + (pNode->_dwHash % nBuckets); + pNewNextNode = *ppNextPointer; + while (pNewNextNode != NULL && + pNewNextNode->_dwHash <= pNode->_dwHash) + { + ppNextPointer = &pNewNextNode->_pNext; + pNewNextNode = pNewNextNode->_pNext; + } + pNode->_pNext = pNewNextNode; + *ppNextPointer = pNode; + + pNode = pNextNode; + } + } + + HeapFree(GetProcessHeap(), 0, _ppBuckets); + _ppBuckets = ppBuckets; + _nBuckets = nBuckets; + ppBuckets = NULL; + +Finished: + + _tableLock.ExclusiveRelease(); +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/http_xp.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/http_xp.h new file mode 100644 index 0000000000..400d8ec855 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/http_xp.h @@ -0,0 +1,2797 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef __HTTP_H__ +#define __HTTP_H__ + +#pragma once + +#if _WIN32_WINNT >= 0x0501 + +// +// HTTPAPI is available on +// +// a) WinXP SP2 and higher +// b) Windows 2003 and higher +// c) Vista and higher. +// + + + + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + + +// +// Flags for HttpInitialize() and HttpTerminate(). +// + +// +// HTTP_INITIALIZE_SERVER - Initializes the HTTP API layer and driver for +// applications using server APIs. +// +// HTTP_INITIALIZE_CONFIG - Initializes the HTTP API layer and driver for +// applications using HTTP configuration APIs. +// +// +// Notes - +// +// 1. These flags can be used in combination. +// +// 2. HttpTerminate() must be called for each call to HttpInitialize() made +// with each flag set when invoking HttpInitialize. For example, one +// could make two calls to HttpInitialize() setting HTTP_INITIALIZE_SERVER +// the first time and HTTP_INITIALIZE_CONFIG the second time. One call +// to HttpTerminate() with both flags set suffices to clean up both +// calls to HttpInitialize(). +// + +#define HTTP_INITIALIZE_SERVER 0x00000001 +#define HTTP_INITIALIZE_CONFIG 0x00000002 + +#if _WIN32_WINNT <= 0x0501 +#define BUILD_IIS_FOR_XP 1 +#endif + +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + +// +// Following section defines the properties supported by the +// server side HTTP API. +// + +typedef enum _HTTP_SERVER_PROPERTY +{ + // + // Used for enabling server side authentication. + // + + HttpServerAuthenticationProperty, + + // + // Used for enabling logging. + // + + HttpServerLoggingProperty, + + // + // Used for setting QoS properties. + // + + HttpServerQosProperty, + + // + // Used for configuring timeouts. + // + + HttpServerTimeoutsProperty, + + // + // Used for limiting request queue lengths. + // + + HttpServerQueueLengthProperty, + + // + // Used for manipulating the state. + // + + HttpServerStateProperty, + + // + // Used for modifying the verbosity level of 503 type responses + // generated by server side API. + // + + HttpServer503VerbosityProperty, + + // + // Used for manipulating Url Group to Request Queue association. + // + + HttpServerBindingProperty, + + // + // Extended authentication property. + // + + HttpServerExtendedAuthenticationProperty, + + // + // Listening endpoint property. + // + + HttpServerListenEndpointProperty + + // + // Authentication channel binding property + // + +#endif +#if _WIN32_WINNT >= _WIN32_WINNT_WIN7 || BUILD_IIS_FOR_XP + + ,HttpServerChannelBindProperty + + // + // IP Protection level policy for a Url Group. + // + + ,HttpServerProtectionLevelProperty +#endif +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + + +} HTTP_SERVER_PROPERTY, *PHTTP_SERVER_PROPERTY; + + +#define HTTP_MAX_SERVER_QUEUE_LENGTH 0x7FFFFFFF +#define HTTP_MIN_SERVER_QUEUE_LENGTH 1 + +// +// Generic property flags. Each structure defining a property info typically +// contain an element of this type. +// + +typedef struct _HTTP_PROPERTY_FLAGS +{ + ULONG Present:1; + +} HTTP_PROPERTY_FLAGS, *PHTTP_PROPERTY_FLAGS; + +// +// Enabled state. +// + +typedef enum _HTTP_ENABLED_STATE +{ + HttpEnabledStateActive, + HttpEnabledStateInactive, + +} HTTP_ENABLED_STATE, *PHTTP_ENABLED_STATE; + + +typedef struct _HTTP_STATE_INFO +{ + HTTP_PROPERTY_FLAGS Flags; + HTTP_ENABLED_STATE State; + +} HTTP_STATE_INFO, *PHTTP_STATE_INFO; + +// +// Defines the verbosity level for a request queue which will be used +// when sending "503 - Service Unavailable" type error responses. Note that +// this setting only affects the error responses generated internally +// by HTTPAPI. +// + +typedef enum _HTTP_503_RESPONSE_VERBOSITY +{ + // + // Instead of sending a 503 response, the connection will be reset. + // This is the default behavior. + // + Http503ResponseVerbosityBasic, + + // + // Will send a 503 w/ a generic reason phrase. + // + Http503ResponseVerbosityLimited, + + // + // Will send a 503 w/ a detailed reason phrase. + // + Http503ResponseVerbosityFull + +} HTTP_503_RESPONSE_VERBOSITY, *PHTTP_503_RESPONSE_VERBOSITY; + +// +// Network QoS related. +// + +typedef enum _HTTP_QOS_SETTING_TYPE +{ + HttpQosSettingTypeBandwidth, + HttpQosSettingTypeConnectionLimit, + HttpQosSettingTypeFlowRate + +} HTTP_QOS_SETTING_TYPE, *PHTTP_QOS_SETTING_TYPE; + +typedef struct _HTTP_QOS_SETTING_INFO +{ + HTTP_QOS_SETTING_TYPE QosType; + PVOID QosSetting; +} HTTP_QOS_SETTING_INFO, *PHTTP_QOS_SETTING_INFO; + +typedef struct _HTTP_CONNECTION_LIMIT_INFO +{ + HTTP_PROPERTY_FLAGS Flags; + ULONG MaxConnections; + +} HTTP_CONNECTION_LIMIT_INFO, *PHTTP_CONNECTION_LIMIT_INFO; + +typedef struct _HTTP_BANDWIDTH_LIMIT_INFO +{ + HTTP_PROPERTY_FLAGS Flags; + ULONG MaxBandwidth; + +} HTTP_BANDWIDTH_LIMIT_INFO, *PHTTP_BANDWIDTH_LIMIT_INFO; + +typedef struct _HTTP_FLOWRATE_INFO +{ + HTTP_PROPERTY_FLAGS Flags; + ULONG MaxBandwidth; + ULONG MaxPeakBandwidth; + ULONG BurstSize; + +} HTTP_FLOWRATE_INFO, *PHTTP_FLOWRATE_INFO; + +// +// Bandwidth throttling limit can not be set lower than the following +// number. The value is in bytes/sec. +// + +#define HTTP_MIN_ALLOWED_BANDWIDTH_THROTTLING_RATE ((ULONG)1024) + +// +// Distinguished value for bandwidth, connection limits and logging rollover +// size indicating "no limit". +// + +#define HTTP_LIMIT_INFINITE ((ULONG)-1) + +// +// Timeout information. +// + +// +// For manipulating global timeout settings. +// These timers run when connection does not belong to any application. +// Value zero is not allowed for driver wide timeout settings. +// + +typedef enum _HTTP_SERVICE_CONFIG_TIMEOUT_KEY +{ + IdleConnectionTimeout = 0, + HeaderWaitTimeout + +} HTTP_SERVICE_CONFIG_TIMEOUT_KEY, *PHTTP_SERVICE_CONFIG_TIMEOUT_KEY; + +typedef USHORT HTTP_SERVICE_CONFIG_TIMEOUT_PARAM, + *PHTTP_SERVICE_CONFIG_TIMEOUT_PARAM; + +// +// To set a timeout value use the set structure. To query/delete use the key +// directly. When you query a timeout value the output buffer must be exactly +// the sizeof param. +// + +typedef struct _HTTP_SERVICE_CONFIG_TIMEOUT_SET +{ + HTTP_SERVICE_CONFIG_TIMEOUT_KEY KeyDesc; + HTTP_SERVICE_CONFIG_TIMEOUT_PARAM ParamDesc; + +} HTTP_SERVICE_CONFIG_TIMEOUT_SET, *PHTTP_SERVICE_CONFIG_TIMEOUT_SET; + +// +// For manipulating application specific timeout settings. +// These timers run when there's a request being processed on a connection +// and HTTPAPI has already associated the request with an application. +// Setting a timeout value to zero will cause HTTPAPI to revert to default. +// + +typedef struct _HTTP_TIMEOUT_LIMIT_INFO +{ + HTTP_PROPERTY_FLAGS Flags; + + // + // Timeouts configured in seconds. + // + + USHORT EntityBody; + USHORT DrainEntityBody; + USHORT RequestQueue; + + // + // Following two timeouts are only enforced after first request on + // connection is routed to the application. These will not manipulate + // the driver wide timeouts. + // + + USHORT IdleConnection; + USHORT HeaderWait; + + // + // Timeouts configured in bytes/second. + // This timer can be turned off by setting it to MAXULONG. + // + + ULONG MinSendRate; + +} HTTP_TIMEOUT_LIMIT_INFO, *PHTTP_TIMEOUT_LIMIT_INFO; + +// +// Controls whether IP-based URLs should listen on the specific IP or wildcard. +// + +typedef struct _HTTP_LISTEN_ENDPOINT_INFO +{ + HTTP_PROPERTY_FLAGS Flags; + + BOOLEAN EnableSharing; + +} HTTP_LISTEN_ENDPOINT_INFO, *PHTTP_LISTEN_ENDPOINT_INFO; + + +typedef struct _HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS +{ + USHORT DomainNameLength; + PWSTR DomainName; + USHORT RealmLength; + PWSTR Realm; +} HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS, + *PHTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS; + +typedef struct _HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS +{ + USHORT RealmLength; + PWSTR Realm; +} HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS, + *PHTTP_SERVER_AUTHENTICATION_BASIC_PARAMS; + +// +// Definitions used for setting server side authentication property. +// + +#define HTTP_AUTH_ENABLE_BASIC (0x00000001) +#define HTTP_AUTH_ENABLE_DIGEST (0x00000002) +#define HTTP_AUTH_ENABLE_NTLM (0x00000004) +#define HTTP_AUTH_ENABLE_NEGOTIATE (0x00000008) +#define HTTP_AUTH_ENABLE_KERBEROS (0x00000010) + +#define HTTP_AUTH_ENABLE_ALL \ + (HTTP_AUTH_ENABLE_BASIC |\ + HTTP_AUTH_ENABLE_DIGEST |\ + HTTP_AUTH_ENABLE_NTLM |\ + HTTP_AUTH_ENABLE_NEGOTIATE |\ + HTTP_AUTH_ENABLE_KERBEROS) + + +C_ASSERT(HTTP_AUTH_ENABLE_NEGOTIATE > HTTP_AUTH_ENABLE_NTLM); +C_ASSERT(HTTP_AUTH_ENABLE_NTLM > HTTP_AUTH_ENABLE_DIGEST); +C_ASSERT(HTTP_AUTH_ENABLE_DIGEST > HTTP_AUTH_ENABLE_BASIC); + +#define HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING (0x01) +#define HTTP_AUTH_EX_FLAG_CAPTURE_CREDENTIAL (0x02) + +typedef struct _HTTP_SERVER_AUTHENTICATION_INFO +{ + HTTP_PROPERTY_FLAGS Flags; + + ULONG AuthSchemes; + + BOOLEAN ReceiveMutualAuth; + BOOLEAN ReceiveContextHandle; + BOOLEAN DisableNTLMCredentialCaching; + + UCHAR ExFlags; + + HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS DigestParams; + HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS BasicParams; + +} HTTP_SERVER_AUTHENTICATION_INFO, *PHTTP_SERVER_AUTHENTICATION_INFO; + +#if _WIN32_WINNT >= _WIN32_WINNT_WIN7 || BUILD_IIS_FOR_XP + +// +// Definitions for setting authentication channel binding properties +// + +typedef enum _HTTP_SERVICE_BINDING_TYPE +{ + HttpServiceBindingTypeNone = 0, + HttpServiceBindingTypeW, + HttpServiceBindingTypeA + +} HTTP_SERVICE_BINDING_TYPE; + +typedef struct _HTTP_SERVICE_BINDING_BASE +{ + HTTP_SERVICE_BINDING_TYPE Type; + +} HTTP_SERVICE_BINDING_BASE, *PHTTP_SERVICE_BINDING_BASE; + +typedef struct _HTTP_SERVICE_BINDING_A +{ + HTTP_SERVICE_BINDING_BASE Base; + PCHAR Buffer; + ULONG BufferSize; + +} HTTP_SERVICE_BINDING_A, *PHTTP_SERVICE_BINDING_A; + +typedef struct _HTTP_SERVICE_BINDING_W +{ + HTTP_SERVICE_BINDING_BASE Base; + PWCHAR Buffer; + ULONG BufferSize; + +} HTTP_SERVICE_BINDING_W, *PHTTP_SERVICE_BINDING_W; + +typedef enum _HTTP_AUTHENTICATION_HARDENING_LEVELS +{ + HttpAuthenticationHardeningLegacy = 0, + HttpAuthenticationHardeningMedium, + HttpAuthenticationHardeningStrict + +} HTTP_AUTHENTICATION_HARDENING_LEVELS; + +// +// Channel binding token verification flags. +// + +#define HTTP_CHANNEL_BIND_PROXY 0x1 +#define HTTP_CHANNEL_BIND_PROXY_COHOSTING 0x20 + +// +// Service bind verification flags +// + +#define HTTP_CHANNEL_BIND_NO_SERVICE_NAME_CHECK 0x2 +#define HTTP_CHANNEL_BIND_DOTLESS_SERVICE 0x4 + +// +// Flags triggering channel bind parameters retrieval +// + +#define HTTP_CHANNEL_BIND_SECURE_CHANNEL_TOKEN 0x8 +#define HTTP_CHANNEL_BIND_CLIENT_SERVICE 0x10 + +// +// All valid flags (mask for internal checks) +// + +typedef struct _HTTP_CHANNEL_BIND_INFO +{ + HTTP_AUTHENTICATION_HARDENING_LEVELS Hardening; + ULONG Flags; + PHTTP_SERVICE_BINDING_BASE * ServiceNames; + ULONG NumberOfServiceNames; + +} HTTP_CHANNEL_BIND_INFO, *PHTTP_CHANNEL_BIND_INFO; + +typedef struct _HTTP_REQUEST_CHANNEL_BIND_STATUS +{ + PHTTP_SERVICE_BINDING_BASE ServiceName; + PUCHAR ChannelToken; + ULONG ChannelTokenSize; + ULONG Flags; + +} HTTP_REQUEST_CHANNEL_BIND_STATUS, *PHTTP_REQUEST_CHANNEL_BIND_STATUS; + +#endif + +// +// Definitions used for setting logging property. +// + +// +// The known log fields recognized/supported by HTTPAPI. Following fields +// are used for W3C logging. Subset of them are also used for error +// logging. +// + +#define HTTP_LOG_FIELD_DATE 0x00000001 +#define HTTP_LOG_FIELD_TIME 0x00000002 +#define HTTP_LOG_FIELD_CLIENT_IP 0x00000004 +#define HTTP_LOG_FIELD_USER_NAME 0x00000008 +#define HTTP_LOG_FIELD_SITE_NAME 0x00000010 +#define HTTP_LOG_FIELD_COMPUTER_NAME 0x00000020 +#define HTTP_LOG_FIELD_SERVER_IP 0x00000040 +#define HTTP_LOG_FIELD_METHOD 0x00000080 +#define HTTP_LOG_FIELD_URI_STEM 0x00000100 +#define HTTP_LOG_FIELD_URI_QUERY 0x00000200 +#define HTTP_LOG_FIELD_STATUS 0x00000400 +#define HTTP_LOG_FIELD_WIN32_STATUS 0x00000800 +#define HTTP_LOG_FIELD_BYTES_SENT 0x00001000 +#define HTTP_LOG_FIELD_BYTES_RECV 0x00002000 +#define HTTP_LOG_FIELD_TIME_TAKEN 0x00004000 +#define HTTP_LOG_FIELD_SERVER_PORT 0x00008000 +#define HTTP_LOG_FIELD_USER_AGENT 0x00010000 +#define HTTP_LOG_FIELD_COOKIE 0x00020000 +#define HTTP_LOG_FIELD_REFERER 0x00040000 +#define HTTP_LOG_FIELD_VERSION 0x00080000 +#define HTTP_LOG_FIELD_HOST 0x00100000 +#define HTTP_LOG_FIELD_SUB_STATUS 0x00200000 + +// +// Fields that are used only for error logging. +// + +#define HTTP_LOG_FIELD_CLIENT_PORT 0x00400000 +#define HTTP_LOG_FIELD_URI 0x00800000 +#define HTTP_LOG_FIELD_SITE_ID 0x01000000 +#define HTTP_LOG_FIELD_REASON 0x02000000 +#define HTTP_LOG_FIELD_QUEUE_NAME 0x04000000 + +// +// Defines the logging type. +// + +typedef enum _HTTP_LOGGING_TYPE +{ + HttpLoggingTypeW3C, + HttpLoggingTypeIIS, + HttpLoggingTypeNCSA, + HttpLoggingTypeRaw + ,HttpLoggingTypeMaximum + +} HTTP_LOGGING_TYPE, *PHTTP_LOGGING_TYPE; + +// +// Defines the rollover type for log files. +// + +typedef enum _HTTP_LOGGING_ROLLOVER_TYPE +{ + HttpLoggingRolloverSize, + HttpLoggingRolloverDaily, + HttpLoggingRolloverWeekly, + HttpLoggingRolloverMonthly, + HttpLoggingRolloverHourly + +} HTTP_LOGGING_ROLLOVER_TYPE, *PHTTP_LOGGING_ROLLOVER_TYPE; + +// +// Log file rollover size can not be set lower than the following +// limit. The value is in bytes. +// + +#define HTTP_MIN_ALLOWED_LOG_FILE_ROLLOVER_SIZE ((ULONG)(1 * 1024 * 1024)) + +// +// Logging option flags. When used in the logging configuration alters +// some default logging behaviour. +// +// HTTP_LOGGING_FLAG_LOCAL_TIME_ROLLOVER - This flag is used to change +// the log file rollover to happen by local time based. By default +// log file rollovers happen by GMT time. +// +// HTTP_LOGGING_FLAG_USE_UTF8_CONVERSION - When set the unicode fields +// will be converted to UTF8 multibytes when writting to the log +// files. When this flag is not present, the local code page +// conversion happens. +// +// HTTP_LOGGING_FLAG_LOG_ERRORS_ONLY - +// HTTP_LOGGING_FLAG_LOG_SUCCESS_ONLY - These two flags are used to +// to do selective logging. If neither of them are present both +// types of requests will be logged. Only one these flags can be +// set at a time. They are mutually exclusive. +// + +#define HTTP_LOGGING_FLAG_LOCAL_TIME_ROLLOVER (0x00000001) +#define HTTP_LOGGING_FLAG_USE_UTF8_CONVERSION (0x00000002) +#define HTTP_LOGGING_FLAG_LOG_ERRORS_ONLY (0x00000004) +#define HTTP_LOGGING_FLAG_LOG_SUCCESS_ONLY (0x00000008) + +// +// Configuration structure used for setting the logging property. +// + +typedef struct _HTTP_LOGGING_INFO +{ + // + // Specifies whether this property exists or not. + // + + HTTP_PROPERTY_FLAGS Flags; + + // + // Optional logging flags. + // + + ULONG LoggingFlags; + + // + // Optional informatonal software directive string for W3C type logging. Not + // used for other types of logging. If nothing is provided here HTTPAPI will + // log a default string. Any arbitrary string could be used here to identify + // the application. Length cannot be greater than MAX_PATH. Lenght is in + // bytes. + // + + PCWSTR SoftwareName; + USHORT SoftwareNameLength; + + // + // Log file directory must be a fully qualified path. + // Length must be in number of bytes. + // + + USHORT DirectoryNameLength; + PCWSTR DirectoryName; + + // + // Specifies the format for the log files. + // + + HTTP_LOGGING_TYPE Format; + + // + // Bitmask value indicates which fields to be logged + // if the log format is set to W3C. This must be the 'bitwise or' + // of the HTTP_LOG_FIELD_... values. + // + + ULONG Fields; + + // + // Following fields are reserved they must be NULL and zero.. + // + + PVOID pExtFields; + USHORT NumOfExtFields; + + // + // Reserved must be zero. + // + + USHORT MaxRecordSize; + + // + // Defines the rollover type for the log files. + // + + HTTP_LOGGING_ROLLOVER_TYPE RolloverType; + + // + // Indicates the maximum size (in bytes) after which + // the log files should be rolled over. A value of -1 + // (HTTP_LIMIT_INFINITE) indicates an unlimited size. + // This value is discarded if rollover type is not set to + // HttpLoggingRolloverSize. + // + + ULONG RolloverSize; + + // + // Specifies the security descriptor to be applied to + // the log files and the sub-directories. If null we will + // inherit the system default. This security descriptor must + // be self-relative. + // + + PSECURITY_DESCRIPTOR pSecurityDescriptor; + +} HTTP_LOGGING_INFO, *PHTTP_LOGGING_INFO; + +// +// Binding information. +// + +typedef struct _HTTP_BINDING_INFO +{ + HTTP_PROPERTY_FLAGS Flags; + HANDLE RequestQueueHandle; + +} HTTP_BINDING_INFO, *PHTTP_BINDING_INFO; + +#endif +#if _WIN32_WINNT >= _WIN32_WINNT_WIN7 || BUILD_IIS_FOR_XP + +// +// Defines the protection level types for UrlGroups. +// + +typedef enum _HTTP_PROTECTION_LEVEL_TYPE +{ + // + // This option will allow edge (NAT) traversed traffic, i.e. Teredo + // for the UrlGroup, unless there is an admin rule that overwrites the + // application's intend. + // + + HttpProtectionLevelUnrestricted, + + // + // This setting will ensure that edge (NAT) traversed traffic + // will not be allowed. + // + + HttpProtectionLevelEdgeRestricted, + + // + // Below type is not supported by HTTP API. + // + + HttpProtectionLevelRestricted + + +} HTTP_PROTECTION_LEVEL_TYPE, *PHTTP_PROTECTION_LEVEL_TYPE; + +// +// Controls whether the associated UrlGroup Namespace should receive +// edge traversed traffic. By default this parameter is unspecified. +// + +typedef struct _HTTP_PROTECTION_LEVEL_INFO +{ + HTTP_PROPERTY_FLAGS Flags; + HTTP_PROTECTION_LEVEL_TYPE Level; + +} HTTP_PROTECTION_LEVEL_INFO, *PHTTP_PROTECTION_LEVEL_INFO; + +#endif +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + + +// +// Definitions for request queue manipulation. +// +// These flags are used with HttpCreateRequestQueue() API. +// +// HTTP_CREATE_REQUEST_QUEUE_FLAG_OPEN_EXISTING - To open an existing request +// queue. The request queue name must be supplied. +// +// HTTP_CREATE_REQUEST_QUEUE_FLAG_CONTROLLER - Creates the request queue and +// marks that the caller process is not willing to do send/receive (HTTP I/O)on +// the handle directly. +// + +#define HTTP_CREATE_REQUEST_QUEUE_FLAG_OPEN_EXISTING (0x00000001) +#define HTTP_CREATE_REQUEST_QUEUE_FLAG_CONTROLLER (0x00000002) + +#endif // _WIN32_WINNT >= 0x0600 + +// +// Flags for HttpReceiveHttpRequest(). +// +// HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY - Specifies that the caller would like +// any available entity body to be copied along with the protocol headers. +// +// HTTP_RECEIVE_REQUEST_FLAG_FLUSH_BODY - Specifies that the caller would like +// all of the entity bodies to be copied along with the protocol headers. +// + +#define HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY 0x00000001 +#define HTTP_RECEIVE_REQUEST_FLAG_FLUSH_BODY 0x00000002 + + +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + +// +// Flags for HttpReceiveRequestEntityBody(). +// +// HTTP_RECEIVE_REQUEST_ENTITY_BODY_FLAG_FILL_BUFFER - Specifies that the +// caller would like the buffer to get filled up with entity bodies unless +// there are no more entity bodies to be copied. +// + +#define HTTP_RECEIVE_REQUEST_ENTITY_BODY_FLAG_FILL_BUFFER 0x00000001 + +#endif // _WIN32_WINNT >= 0x0600 + + +// +// Flags for HttpSendHttpResponse() and HttpSendResponseEntityBody(). +// +// HTTP_SEND_RESPONSE_FLAG_DISCONNECT - Specifies that the network connection +// should be disconnected immediately after sending the response, overriding +// the HTTP protocol's persistent connection features, such as +// "Connection: keep-alive". +// +// HTTP_SEND_RESPONSE_FLAG_MORE_DATA - Specifies that additional entity body +// data will be sent by the caller. +// +// HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA - Specifies that a caller wants the +// response to complete as soon as possible at the cost of buffering partial +// or the entire response. +// +// HTTP_SEND_RESPONSE_FLAG_ENABLE_NAGLING - Specifies that a caller wants to +// enable the TCP nagling algorithm for this particular send. +// +// HTTP_SEND_RESPONSE_FLAG_PROCESS_RANGES - Specifies that for a range request +// a full response content is passed and a caller wants HTTP API to process +// ranges properly. +// + +#define HTTP_SEND_RESPONSE_FLAG_DISCONNECT 0x00000001 +#define HTTP_SEND_RESPONSE_FLAG_MORE_DATA 0x00000002 +#define HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA 0x00000004 +#define HTTP_SEND_RESPONSE_FLAG_ENABLE_NAGLING 0x00000008 +#define HTTP_SEND_RESPONSE_FLAG_PROCESS_RANGES 0x00000020 + + +// +// Flags for HttpFlushResponseCache(). +// +// HTTP_FLUSH_RESPONSE_FLAG_RECURSIVE - Flushes the specified URL and all +// hierarchally-related sub-URLs from the response or fragment cache. +// + +#define HTTP_FLUSH_RESPONSE_FLAG_RECURSIVE 0x00000001 + + +// +// Opaque identifiers for various HTTPAPI objects. +// + +typedef ULONGLONG HTTP_OPAQUE_ID, *PHTTP_OPAQUE_ID; + +typedef HTTP_OPAQUE_ID HTTP_REQUEST_ID, *PHTTP_REQUEST_ID; +typedef HTTP_OPAQUE_ID HTTP_CONNECTION_ID, *PHTTP_CONNECTION_ID; +typedef HTTP_OPAQUE_ID HTTP_RAW_CONNECTION_ID, *PHTTP_RAW_CONNECTION_ID; + +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + +typedef HTTP_OPAQUE_ID HTTP_URL_GROUP_ID, *PHTTP_URL_GROUP_ID; +typedef HTTP_OPAQUE_ID HTTP_SERVER_SESSION_ID, *PHTTP_SERVER_SESSION_ID; + +#endif // _WIN32_WINNT >= 0x0600 + +// +// Macros for opaque identifier manipulations. +// + +#define HTTP_NULL_ID (0ui64) +#define HTTP_IS_NULL_ID(pid) (HTTP_NULL_ID == *(pid)) +#define HTTP_SET_NULL_ID(pid) (*(pid) = HTTP_NULL_ID) + +// +// This structure defines a file byte range. +// +// If the Length field is HTTP_BYTE_RANGE_TO_EOF then the remainder of the +// file (everything after StartingOffset) is sent. +// + +#define HTTP_BYTE_RANGE_TO_EOF ((ULONGLONG)-1) + +typedef struct _HTTP_BYTE_RANGE +{ + ULARGE_INTEGER StartingOffset; + ULARGE_INTEGER Length; + +} HTTP_BYTE_RANGE, *PHTTP_BYTE_RANGE; + +// +// The type for HTTP protocol version numbers. +// + +typedef struct _HTTP_VERSION +{ + USHORT MajorVersion; + USHORT MinorVersion; + +} HTTP_VERSION, *PHTTP_VERSION; + +// +// Some useful macros for HTTP protocol version manipulation. +// + +#define HTTP_VERSION_UNKNOWN { 0, 0 } +#define HTTP_VERSION_0_9 { 0, 9 } +#define HTTP_VERSION_1_0 { 1, 0 } +#define HTTP_VERSION_1_1 { 1, 1 } + +#define HTTP_SET_VERSION(version, major, minor) \ +do { \ + (version).MajorVersion = (major); \ + (version).MinorVersion = (minor); \ +} while (0, 0) + +#define HTTP_EQUAL_VERSION(version, major, minor) \ + ((version).MajorVersion == (major) && \ + (version).MinorVersion == (minor)) + +#define HTTP_GREATER_VERSION(version, major, minor) \ + ((version).MajorVersion > (major) || \ + ((version).MajorVersion == (major) && \ + (version).MinorVersion > (minor))) + +#define HTTP_LESS_VERSION(version, major, minor) \ + ((version).MajorVersion < (major) || \ + ((version).MajorVersion == (major) && \ + (version).MinorVersion < (minor))) + +#define HTTP_NOT_EQUAL_VERSION(version, major, minor) \ + (!HTTP_EQUAL_VERSION(version, major, minor)) + +#define HTTP_GREATER_EQUAL_VERSION(version, major, minor) \ + (!HTTP_LESS_VERSION(version, major, minor)) + +#define HTTP_LESS_EQUAL_VERSION(version, major, minor) \ + (!HTTP_GREATER_VERSION(version, major, minor)) + +// +// The enum type for HTTP verbs. +// + +typedef enum _HTTP_VERB +{ + HttpVerbUnparsed, + HttpVerbUnknown, + HttpVerbInvalid, + HttpVerbOPTIONS, + HttpVerbGET, + HttpVerbHEAD, + HttpVerbPOST, + HttpVerbPUT, + HttpVerbDELETE, + HttpVerbTRACE, + HttpVerbCONNECT, + HttpVerbTRACK, // used by Microsoft Cluster Server for a non-logged trace + HttpVerbMOVE, + HttpVerbCOPY, + HttpVerbPROPFIND, + HttpVerbPROPPATCH, + HttpVerbMKCOL, + HttpVerbLOCK, + HttpVerbUNLOCK, + HttpVerbSEARCH, + + HttpVerbMaximum + +} HTTP_VERB, *PHTTP_VERB; + +// +// Symbols for all HTTP/1.1 headers and other tokens. Notice request + +// response values overlap. Make sure you know which type of header array +// you are indexing. +// +// These values are used as offsets into arrays and as token values in +// HTTP_KNOWN_HEADER arrays in HTTP_REQUEST_HEADERS and HTTP_RESPONSE_HEADERS. +// +// See RFC 2616, HTTP/1.1, for further explanation of most of these headers. +// + +typedef enum _HTTP_HEADER_ID +{ + HttpHeaderCacheControl = 0, // general-header [section 4.5] + HttpHeaderConnection = 1, // general-header [section 4.5] + HttpHeaderDate = 2, // general-header [section 4.5] + HttpHeaderKeepAlive = 3, // general-header [not in rfc] + HttpHeaderPragma = 4, // general-header [section 4.5] + HttpHeaderTrailer = 5, // general-header [section 4.5] + HttpHeaderTransferEncoding = 6, // general-header [section 4.5] + HttpHeaderUpgrade = 7, // general-header [section 4.5] + HttpHeaderVia = 8, // general-header [section 4.5] + HttpHeaderWarning = 9, // general-header [section 4.5] + + HttpHeaderAllow = 10, // entity-header [section 7.1] + HttpHeaderContentLength = 11, // entity-header [section 7.1] + HttpHeaderContentType = 12, // entity-header [section 7.1] + HttpHeaderContentEncoding = 13, // entity-header [section 7.1] + HttpHeaderContentLanguage = 14, // entity-header [section 7.1] + HttpHeaderContentLocation = 15, // entity-header [section 7.1] + HttpHeaderContentMd5 = 16, // entity-header [section 7.1] + HttpHeaderContentRange = 17, // entity-header [section 7.1] + HttpHeaderExpires = 18, // entity-header [section 7.1] + HttpHeaderLastModified = 19, // entity-header [section 7.1] + + + // Request Headers + + HttpHeaderAccept = 20, // request-header [section 5.3] + HttpHeaderAcceptCharset = 21, // request-header [section 5.3] + HttpHeaderAcceptEncoding = 22, // request-header [section 5.3] + HttpHeaderAcceptLanguage = 23, // request-header [section 5.3] + HttpHeaderAuthorization = 24, // request-header [section 5.3] + HttpHeaderCookie = 25, // request-header [not in rfc] + HttpHeaderExpect = 26, // request-header [section 5.3] + HttpHeaderFrom = 27, // request-header [section 5.3] + HttpHeaderHost = 28, // request-header [section 5.3] + HttpHeaderIfMatch = 29, // request-header [section 5.3] + + HttpHeaderIfModifiedSince = 30, // request-header [section 5.3] + HttpHeaderIfNoneMatch = 31, // request-header [section 5.3] + HttpHeaderIfRange = 32, // request-header [section 5.3] + HttpHeaderIfUnmodifiedSince = 33, // request-header [section 5.3] + HttpHeaderMaxForwards = 34, // request-header [section 5.3] + HttpHeaderProxyAuthorization = 35, // request-header [section 5.3] + HttpHeaderReferer = 36, // request-header [section 5.3] + HttpHeaderRange = 37, // request-header [section 5.3] + HttpHeaderTe = 38, // request-header [section 5.3] + HttpHeaderTranslate = 39, // request-header [webDAV, not in rfc 2518] + + HttpHeaderUserAgent = 40, // request-header [section 5.3] + + HttpHeaderRequestMaximum = 41, + + + // Response Headers + + HttpHeaderAcceptRanges = 20, // response-header [section 6.2] + HttpHeaderAge = 21, // response-header [section 6.2] + HttpHeaderEtag = 22, // response-header [section 6.2] + HttpHeaderLocation = 23, // response-header [section 6.2] + HttpHeaderProxyAuthenticate = 24, // response-header [section 6.2] + HttpHeaderRetryAfter = 25, // response-header [section 6.2] + HttpHeaderServer = 26, // response-header [section 6.2] + HttpHeaderSetCookie = 27, // response-header [not in rfc] + HttpHeaderVary = 28, // response-header [section 6.2] + HttpHeaderWwwAuthenticate = 29, // response-header [section 6.2] + + HttpHeaderResponseMaximum = 30, + + + HttpHeaderMaximum = 41 + +} HTTP_HEADER_ID, *PHTTP_HEADER_ID; + + +// +// Structure defining format of a known HTTP header. +// Name is from HTTP_HEADER_ID. +// + +typedef struct _HTTP_KNOWN_HEADER +{ + USHORT RawValueLength; // in bytes not including the NUL + PCSTR pRawValue; + +} HTTP_KNOWN_HEADER, *PHTTP_KNOWN_HEADER; + +// +// Structure defining format of an unknown header. +// + +typedef struct _HTTP_UNKNOWN_HEADER +{ + USHORT NameLength; // in bytes not including the NUL + USHORT RawValueLength; // in bytes not including the NUL + PCSTR pName; // The header name (minus the ':' character) + PCSTR pRawValue; // The header value + +} HTTP_UNKNOWN_HEADER, *PHTTP_UNKNOWN_HEADER; + +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + +// +// Log fields data structure is used for logging a request. This structure must +// be provided along with an HttpSendHttpResponse or HttpSendResponseEntityBody +// call that concludes the send. +// + +// Base structure is for future versioning. + +typedef enum _HTTP_LOG_DATA_TYPE +{ + HttpLogDataTypeFields = 0 + +} HTTP_LOG_DATA_TYPE, *PHTTP_LOG_DATA_TYPE; + +// should we DECLSPEC_ALIGN(4 or 8) == DECLSPEC_POINTERALIGN? +typedef struct _HTTP_LOG_DATA +{ + HTTP_LOG_DATA_TYPE Type; + +} HTTP_LOG_DATA, *PHTTP_LOG_DATA; + +// Current log fields data structure for of type HttpLogDataTypeFields. + +typedef struct _HTTP_LOG_FIELDS_DATA +{ + HTTP_LOG_DATA Base; + + USHORT UserNameLength; + USHORT UriStemLength; + USHORT ClientIpLength; + USHORT ServerNameLength; + USHORT ServiceNameLength; + USHORT ServerIpLength; + USHORT MethodLength; + USHORT UriQueryLength; + USHORT HostLength; + USHORT UserAgentLength; + USHORT CookieLength; + USHORT ReferrerLength; + + PWCHAR UserName; + PWCHAR UriStem; + PCHAR ClientIp; + PCHAR ServerName; + PCHAR ServiceName; + PCHAR ServerIp; + PCHAR Method; + PCHAR UriQuery; + PCHAR Host; + PCHAR UserAgent; + PCHAR Cookie; + PCHAR Referrer; + + USHORT ServerPort; + USHORT ProtocolStatus; + + ULONG Win32Status; + + HTTP_VERB MethodNum; + + USHORT SubStatus; + +} HTTP_LOG_FIELDS_DATA, *PHTTP_LOG_FIELDS_DATA; + +#endif // _WIN32_WINNT >= 0x0600 + +// +// This enum defines a data source for a particular chunk of data. +// + +typedef enum _HTTP_DATA_CHUNK_TYPE +{ + HttpDataChunkFromMemory, + HttpDataChunkFromFileHandle, + HttpDataChunkFromFragmentCache, + HttpDataChunkFromFragmentCacheEx, + + HttpDataChunkMaximum + +} HTTP_DATA_CHUNK_TYPE, *PHTTP_DATA_CHUNK_TYPE; + + +// +// This structure describes an individual data chunk. +// + +typedef struct _HTTP_DATA_CHUNK +{ + // + // The type of this data chunk. + // + + HTTP_DATA_CHUNK_TYPE DataChunkType; + + // + // The data chunk structures, one per supported data chunk type. + // + + union + { + // + // From-memory data chunk. + // + + struct + { + PVOID pBuffer; + ULONG BufferLength; + + } FromMemory; + + // + // From-file handle data chunk. + // + + struct + { + HTTP_BYTE_RANGE ByteRange; + HANDLE FileHandle; + + } FromFileHandle; + + // + // From-fragment cache data chunk. + // + + struct + { + USHORT FragmentNameLength; // in bytes not including the NUL + PCWSTR pFragmentName; + + } FromFragmentCache; + + // + // From-fragment cache data chunk that specifies a byte range. + // + + struct + { + HTTP_BYTE_RANGE ByteRange; + PCWSTR pFragmentName; // NULL-terminated string + + } FromFragmentCacheEx; + + }; + +} HTTP_DATA_CHUNK, *PHTTP_DATA_CHUNK; + +// +// HTTP API doesn't support 16 bit applications. +// Neither WIN32 nor _WIN64 was defined. +// + +C_ASSERT(TYPE_ALIGNMENT(HTTP_DATA_CHUNK) == sizeof(ULONGLONG)); + +// +// Structure defining format of request headers. +// + +typedef struct _HTTP_REQUEST_HEADERS +{ + // + // The array of unknown HTTP headers and the number of + // entries in the array. + // + + USHORT UnknownHeaderCount; + PHTTP_UNKNOWN_HEADER pUnknownHeaders; + + // + // Trailers - we don't use these currently, reserved for a future release + // + USHORT TrailerCount; // Reserved, must be 0 + PHTTP_UNKNOWN_HEADER pTrailers; // Reserved, must be NULL + + + // + // Known headers. + // + + HTTP_KNOWN_HEADER KnownHeaders[HttpHeaderRequestMaximum]; + +} HTTP_REQUEST_HEADERS, *PHTTP_REQUEST_HEADERS; + +// +// Structure defining format of response headers. +// + +typedef struct _HTTP_RESPONSE_HEADERS +{ + // + // The array of unknown HTTP headers and the number of + // entries in the array. + // + + USHORT UnknownHeaderCount; + PHTTP_UNKNOWN_HEADER pUnknownHeaders; + + // + // Trailers - we don't use these currently, reserved for a future release + // + USHORT TrailerCount; // Reserved, must be 0 + PHTTP_UNKNOWN_HEADER pTrailers; // Reserved, must be NULL + + // + // Known headers. + // + + HTTP_KNOWN_HEADER KnownHeaders[HttpHeaderResponseMaximum]; + +} HTTP_RESPONSE_HEADERS, *PHTTP_RESPONSE_HEADERS; + +// +// Structure defining format of transport address. Use pLocalAddress->sa_family +// to determine whether this is an IPv4 address (AF_INET) or IPv6 (AF_INET6). +// +// pRemoteAddress->sa_family will be the same as pLocalAddress->sa_family. +// +// SOCKADDRs are always in network order, not host order. +// + +typedef struct _HTTP_TRANSPORT_ADDRESS +{ + PSOCKADDR pRemoteAddress; + PSOCKADDR pLocalAddress; + +} HTTP_TRANSPORT_ADDRESS, *PHTTP_TRANSPORT_ADDRESS; + +// +// Structure defining format of cooked URL. +// + +typedef struct _HTTP_COOKED_URL +{ + // + // Pointers overlap and point into pFullUrl. NULL if not present. + // + + USHORT FullUrlLength; // in bytes not including the NUL + USHORT HostLength; // in bytes (no NUL) + USHORT AbsPathLength; // in bytes (no NUL) + USHORT QueryStringLength; // in bytes (no NUL) + + PCWSTR pFullUrl; // points to "http://hostname:port/abs/.../path?query" + PCWSTR pHost; // points to the first char in the hostname + PCWSTR pAbsPath; // Points to the 3rd '/' char + PCWSTR pQueryString; // Points to the 1st '?' char or NULL + +} HTTP_COOKED_URL, *PHTTP_COOKED_URL; + +// +// An opaque context for URL manipulation. +// + +typedef ULONGLONG HTTP_URL_CONTEXT; + + +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + +// +// Optional flags for URL manipulation functions. +// +// HTTP_URL_FLAG_REMOVE_ALL : When this flag is used +// when removing a Url from a url group, regardless of +// the passed URL, all of the Urls from the url group +// will be removed. +// + +#define HTTP_URL_FLAG_REMOVE_ALL 0x00000001 + + +// +// Request Authentication related. +// + +typedef enum _HTTP_AUTH_STATUS +{ + HttpAuthStatusSuccess, + HttpAuthStatusNotAuthenticated, + HttpAuthStatusFailure + +} HTTP_AUTH_STATUS, *PHTTP_AUTH_STATUS; + + +typedef enum _HTTP_REQUEST_AUTH_TYPE +{ + HttpRequestAuthTypeNone = 0, + HttpRequestAuthTypeBasic, + HttpRequestAuthTypeDigest, + HttpRequestAuthTypeNTLM, + HttpRequestAuthTypeNegotiate, + HttpRequestAuthTypeKerberos + + +} HTTP_REQUEST_AUTH_TYPE, *PHTTP_REQUEST_AUTH_TYPE; + +#endif // _WIN32_WINNT >= 0x0600 + +// +// SSL Client certificate information. +// + +typedef struct _HTTP_SSL_CLIENT_CERT_INFO +{ + ULONG CertFlags; + ULONG CertEncodedSize; + PUCHAR pCertEncoded; + HANDLE Token; + BOOLEAN CertDeniedByMapper; + +} HTTP_SSL_CLIENT_CERT_INFO, *PHTTP_SSL_CLIENT_CERT_INFO; + +#if _WIN32_WINNT >= _WIN32_WINNT_WIN7 || BUILD_IIS_FOR_XP + +// +// Flag to retrieve secure channel binding with HttpReceiveClientCertificate +// + +#define HTTP_RECEIVE_SECURE_CHANNEL_TOKEN 0x1 + +#endif + +// +// Data computed during SSL handshake. +// + +typedef struct _HTTP_SSL_INFO +{ + USHORT ServerCertKeySize; + USHORT ConnectionKeySize; + ULONG ServerCertIssuerSize; + ULONG ServerCertSubjectSize; + + PCSTR pServerCertIssuer; + PCSTR pServerCertSubject; + + PHTTP_SSL_CLIENT_CERT_INFO pClientCertInfo; + ULONG SslClientCertNegotiated; + +} HTTP_SSL_INFO, *PHTTP_SSL_INFO; + + +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + +// +// Generic request information type. +// + +typedef enum _HTTP_REQUEST_INFO_TYPE +{ + HttpRequestInfoTypeAuth + +#if _WIN32_WINNT >= _WIN32_WINNT_WIN7 + ,HttpRequestInfoTypeChannelBind +#endif + + +} HTTP_REQUEST_INFO_TYPE, *PHTTP_REQUEST_INFO_TYPE; + +typedef struct _HTTP_REQUEST_INFO +{ + HTTP_REQUEST_INFO_TYPE InfoType; + ULONG InfoLength; + PVOID pInfo; + +} HTTP_REQUEST_INFO, *PHTTP_REQUEST_INFO; + +#ifndef __SECSTATUS_DEFINED__ +typedef LONG SECURITY_STATUS; +#define __SECSTATUS_DEFINED__ +#endif // __SECSTATUS_DEFINED__ + +// +// Authentication request info structure +// + +#define HTTP_REQUEST_AUTH_FLAG_TOKEN_FOR_CACHED_CRED (0x00000001) + +typedef struct _HTTP_REQUEST_AUTH_INFO +{ + HTTP_AUTH_STATUS AuthStatus; + SECURITY_STATUS SecStatus; + + ULONG Flags; + + HTTP_REQUEST_AUTH_TYPE AuthType; + + HANDLE AccessToken; + ULONG ContextAttributes; + + // + // Optional serialized context. + // + + ULONG PackedContextLength; + ULONG PackedContextType; + PVOID PackedContext; + + // + // Optional mutual authentication data and its length in bytes. + // + + ULONG MutualAuthDataLength; + PCHAR pMutualAuthData; + + // + // For SSPI based schemes the package name is returned. Length does + // not include the terminating null and it is in bytes. + // + + USHORT PackageNameLength; + PWSTR pPackageName; + +} HTTP_REQUEST_AUTH_INFO, *PHTTP_REQUEST_AUTH_INFO; + +#endif // _WIN32_WINNT >= 0x0600 + +// +// The structure of an HTTP request for downlevel OS +// + +typedef struct _HTTP_REQUEST_V1 +{ + // + // Request flags (see HTTP_REQUEST_FLAG_* definitions below). + // + + ULONG Flags; + + // + // An opaque request identifier. These values are used by the driver + // to correlate outgoing responses with incoming requests. + // + + HTTP_CONNECTION_ID ConnectionId; + HTTP_REQUEST_ID RequestId; + + // + // The context associated with the URL prefix. + // + + HTTP_URL_CONTEXT UrlContext; + + // + // The HTTP version number. + // + + HTTP_VERSION Version; + + // + // The request verb. + // + + HTTP_VERB Verb; + + // + // The length of the verb string if the Verb field is HttpVerbUnknown. + // + + USHORT UnknownVerbLength; // in bytes not including the NUL + + // + // The length of the raw (uncooked) URL + // + + USHORT RawUrlLength; // in bytes not including the NUL + + // + // Pointer to the verb string if the Verb field is HttpVerbUnknown. + // + + PCSTR pUnknownVerb; + + // + // Pointer to the raw (uncooked) URL + // + + PCSTR pRawUrl; + + // + // The canonicalized Unicode URL + // + + HTTP_COOKED_URL CookedUrl; + + // + // Local and remote transport addresses for the connection. + // + + HTTP_TRANSPORT_ADDRESS Address; + + // + // The request headers. + // + + HTTP_REQUEST_HEADERS Headers; + + // + // The total number of bytes received from network for this request. + // + + ULONGLONG BytesReceived; + + // + // pEntityChunks is an array of EntityChunkCount HTTP_DATA_CHUNKs. The + // entity body is copied only if HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY + // was passed to HttpReceiveHttpRequest(). + // + + USHORT EntityChunkCount; + PHTTP_DATA_CHUNK pEntityChunks; + + // + // SSL connection information. + // + + HTTP_RAW_CONNECTION_ID RawConnectionId; + PHTTP_SSL_INFO pSslInfo; + +} HTTP_REQUEST_V1, *PHTTP_REQUEST_V1; + +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + +// Vista + +// +// Version 2.0 members are defined here +// N.B. One must define V2 elements in two places :( +// This is due to the fact that C++ doesn't allow anonymous +// structure declarations and one must use structure +// inheritance instead. +// + +#ifdef __cplusplus + +typedef struct _HTTP_REQUEST_V2 : _HTTP_REQUEST_V1 +{ + // + // Version 1.0 members are inherited + // Version 2.0 members are declared below + // + + // + // Additional Request Informations. + // + + USHORT RequestInfoCount; + PHTTP_REQUEST_INFO pRequestInfo; +} HTTP_REQUEST_V2, *PHTTP_REQUEST_V2; + +#else // __cplusplus + +typedef struct _HTTP_REQUEST_V2 +{ + struct _HTTP_REQUEST_V1; // Anonymous structure + + // + // Version 2.0 members are declared below + // + + // + // Additional Request Informations. + // + + USHORT RequestInfoCount; + PHTTP_REQUEST_INFO pRequestInfo; +} HTTP_REQUEST_V2, *PHTTP_REQUEST_V2; + +#endif // __cplusplus + +typedef HTTP_REQUEST_V2 HTTP_REQUEST; + +#else // _WIN32_WINNT >= 0x0600 + +typedef HTTP_REQUEST_V1 HTTP_REQUEST; + +#endif // _WIN32_WINNT >= 0x0600 + +typedef HTTP_REQUEST * PHTTP_REQUEST; + + +// +// Values for HTTP_REQUEST::Flags. Zero or more of these may be ORed together. +// +// HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS - there is more entity body +// to be read for this request. Otherwise, there is no entity body or +// all of the entity body was copied into pEntityChunks. +// HTTP_REQUEST_FLAG_IP_ROUTED - This flag indicates that the request has been +// routed based on host plus ip or ip binding.This is a hint for the application +// to include the local ip while flushing kernel cache entries build for this +// request if any. +// + +#define HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS 0x00000001 +#define HTTP_REQUEST_FLAG_IP_ROUTED 0x00000002 + + +// +// This structure describes an HTTP response. +// + +typedef struct _HTTP_RESPONSE_V1 +{ + // + // Response flags (see HTTP_RESPONSE_FLAG_* definitions below). + // + + ULONG Flags; + + // + // The raw HTTP protocol version number. + // + + HTTP_VERSION Version; + + // + // The HTTP status code (e.g., 200). + // + + USHORT StatusCode; + + // + // The HTTP reason (e.g., "OK"). This MUST not contain + // non-ASCII characters (i.e., all chars must be in range 0x20-0x7E). + // + + USHORT ReasonLength; // in bytes not including the '\0' + PCSTR pReason; + + // + // The response headers. + // + + HTTP_RESPONSE_HEADERS Headers; + + // + // pEntityChunks points to an array of EntityChunkCount HTTP_DATA_CHUNKs. + // + + USHORT EntityChunkCount; + PHTTP_DATA_CHUNK pEntityChunks; + +} HTTP_RESPONSE_V1, *PHTTP_RESPONSE_V1; + +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + +// +// Values for HTTP_RESPONSE::Flags. +// +// HTTP_RESPONSE_FLAG_MULTIPLE_ENCODINGS_AVAILABLE - Set this flag if encodings +// other than identity form are available for this resource.This flag is ignored +// if application has not asked for response to be cached. It's used as a hint +// to the Http Server API for content negotiation used when serving from the +// the kernel response cache. +// + +#define HTTP_RESPONSE_FLAG_MULTIPLE_ENCODINGS_AVAILABLE 0x00000001 + + +// Vista + +typedef enum _HTTP_RESPONSE_INFO_TYPE +{ + HttpResponseInfoTypeMultipleKnownHeaders, + HttpResponseInfoTypeAuthenticationProperty, + HttpResponseInfoTypeQoSProperty + +#if _WIN32_WINNT >= _WIN32_WINNT_WIN7 || BUILD_IIS_FOR_XP + ,HttpResponseInfoTypeChannelBind +#endif + +} HTTP_RESPONSE_INFO_TYPE, PHTTP_RESPONSE_INFO_TYPE; + +typedef struct _HTTP_RESPONSE_INFO +{ + HTTP_RESPONSE_INFO_TYPE Type; + ULONG Length; + PVOID pInfo; +} HTTP_RESPONSE_INFO, *PHTTP_RESPONSE_INFO; + +#define HTTP_RESPONSE_INFO_FLAGS_PRESERVE_ORDER 0x00000001 + +// +// This structure allows the provision of providing multiple known headers. +// + +typedef struct _HTTP_MULTIPLE_KNOWN_HEADERS +{ + // + // Known header id. + // + + HTTP_HEADER_ID HeaderId; + + ULONG Flags; + + // + // Number of headers of the same category. + // + + USHORT KnownHeaderCount; + + // + // Array of known header structures. + // + + PHTTP_KNOWN_HEADER KnownHeaders; + +} HTTP_MULTIPLE_KNOWN_HEADERS, *PHTTP_MULTIPLE_KNOWN_HEADERS; + +// +// Version 2.0 members are defined here +// N.B. One must define V2 elements in two places :( +// This is due to the fact that C++ doesn't allow anonymous +// structure declarations and one must use structure +// inheritance instead. +// + +#ifdef __cplusplus + +typedef struct _HTTP_RESPONSE_V2 : _HTTP_RESPONSE_V1 +{ + // + // Version 1.0 members are inherited + // Version 2.0 members are declared below + // + + USHORT ResponseInfoCount; + PHTTP_RESPONSE_INFO pResponseInfo; + +} HTTP_RESPONSE_V2, *PHTTP_RESPONSE_V2; + +#else // __cplusplus + +typedef struct _HTTP_RESPONSE_V2 +{ + struct _HTTP_RESPONSE_V1; + + // + // Version 2.0 members are declared below + // + + USHORT ResponseInfoCount; + PHTTP_RESPONSE_INFO pResponseInfo; +} HTTP_RESPONSE_V2, *PHTTP_RESPONSE_V2; + +#endif // __cplusplus + +typedef HTTP_RESPONSE_V2 HTTP_RESPONSE; + +#else // _WIN32_WINNT >= 0x0600 + +typedef HTTP_RESPONSE_V1 HTTP_RESPONSE; + +#endif // _WIN32_WINNT >= 0x0600 + +typedef HTTP_RESPONSE *PHTTP_RESPONSE; + +// +// Api Version. This is used to ensure compatibility between applications and +// httpapi.dll and http.sys. +// +// This must not be confused with the HTTP Protocol version. +// + +typedef struct _HTTPAPI_VERSION +{ + USHORT HttpApiMajorVersion; + USHORT HttpApiMinorVersion; + +} HTTPAPI_VERSION, *PHTTPAPI_VERSION; + + +#if _WIN32_WINNT >= 0x0600 || BUILD_IIS_FOR_XP + +// Vista + +#define HTTPAPI_VERSION_2 { 2, 0 } + +#endif // _WIN32_WINNT >= 0x0600 + +#define HTTPAPI_VERSION_1 { 1, 0 } + +#define HTTPAPI_EQUAL_VERSION(version, major, minor) \ + ((version).HttpApiMajorVersion == (major) && \ + (version).HttpApiMinorVersion == (minor)) + +#define HTTPAPI_GREATER_VERSION(version, major, minor) \ + ((version).HttpApiMajorVersion > (major) || \ + ((version).HttpApiMajorVersion == (major) && \ + (version).HttpApiMinorVersion > (minor))) + +#define HTTPAPI_LESS_VERSION(version, major, minor) \ + ((version).HttpApiMajorVersion < (major) || \ + ((version).HttpApiMajorVersion == (major) && \ + (version).HttpApiMinorVersion < (minor))) + +#define HTTPAPI_VERSION_GREATER_OR_EQUAL( version, major, minor) \ + (!HTTPAPI_LESS_VERSION(version, major, minor)) + + +// +// Cache control. +// + +// +// This enum defines the available cache policies. +// + +typedef enum _HTTP_CACHE_POLICY_TYPE +{ + HttpCachePolicyNocache, + HttpCachePolicyUserInvalidates, + HttpCachePolicyTimeToLive, + + HttpCachePolicyMaximum + +} HTTP_CACHE_POLICY_TYPE, *PHTTP_CACHE_POLICY_TYPE; + + +// +// Only cache unauthorized GETs + HEADs. +// + +typedef struct _HTTP_CACHE_POLICY +{ + HTTP_CACHE_POLICY_TYPE Policy; + ULONG SecondsToLive; + +} HTTP_CACHE_POLICY, *PHTTP_CACHE_POLICY; + +// +// Enum that is used with HttpSetServiceConfiguration(), +// HttpQueryServiceConfiguration(), and HttpDeleteServiceConfiguration() APIs. +// + +typedef enum _HTTP_SERVICE_CONFIG_ID +{ + HttpServiceConfigIPListenList, // Set, Query & Delete. + HttpServiceConfigSSLCertInfo, // Set, Query & Delete. + HttpServiceConfigUrlAclInfo, // Set, Query & Delete. + HttpServiceConfigTimeout, // Set, Query & Delete. + HttpServiceConfigCache, // Set, Query & Delete. + HttpServiceConfigMax + +} HTTP_SERVICE_CONFIG_ID, *PHTTP_SERVICE_CONFIG_ID; + +// +// Generic Query enum that can be used with HttpQueryServiceConfiguration() +// + +typedef enum _HTTP_SERVICE_CONFIG_QUERY_TYPE +{ + HttpServiceConfigQueryExact, + HttpServiceConfigQueryNext, + HttpServiceConfigQueryMax + +} HTTP_SERVICE_CONFIG_QUERY_TYPE, *PHTTP_SERVICE_CONFIG_QUERY_TYPE; + +// +// This data structure is used to define a key of the SSL certificate hash +// store. +// + +typedef struct _HTTP_SERVICE_CONFIG_SSL_KEY +{ + PSOCKADDR pIpPort; +} HTTP_SERVICE_CONFIG_SSL_KEY, *PHTTP_SERVICE_CONFIG_SSL_KEY; + +// +// This defines a record for the SSL config store. +// + +typedef struct _HTTP_SERVICE_CONFIG_SSL_PARAM +{ + ULONG SslHashLength; // Length of the SSL hash (in bytes) + PVOID pSslHash; // Pointer to the SSL hash + GUID AppId; // A unique identifier that can be used to + // identify the app that has set this parameter + + PWSTR pSslCertStoreName; // Store name to read the server certificate + // from; defaults to "MY". Certificate must be + // stored in the LOCAL_MACHINE context. + + // + // The following settings are used only for client certificates + // + + // + // DefaultCertCheckMode is a bit flag with the following semantics + // 0x1 - Client certificate will not be verified for revocation + // 0x2 - Only cached certificate revocation will be used. + // 0x4 - Enable use of the DefaultRevocationFreshnessTime setting + // 0x10000 - No usage check. + + DWORD DefaultCertCheckMode; + + // + // DefaultRevocationFreshnessTime (seconds) - How often to check for + // an updated Certificate revocation list (CRL). If this value is 0 + // then the new CRL is updated only if the previous one expires + // + + DWORD DefaultRevocationFreshnessTime; + + // + // DefaultRevocationUrlRetrievalTimeout (milliseconds) - Timeout on + // attempt to retrieve certificate revocation list from the remote URL. + // + + DWORD DefaultRevocationUrlRetrievalTimeout; + + // + // pDefaultSslCtlIdentifier - Restrict the certificate issuers that you + // want to trust. Can be a subset of the certificate issuers that are + // trusted by the machine. + // + + PWSTR pDefaultSslCtlIdentifier; + + // + // Store name under LOCAL_MACHINE where Ctl identified by + // pDefaultSslCtlIdentifier is stored. + // + + PWSTR pDefaultSslCtlStoreName; + + // + // Default Flags - see HTTP_SERVICE_CONFIG_SSL_FLAG* below. + // + + DWORD DefaultFlags; + +} HTTP_SERVICE_CONFIG_SSL_PARAM, *PHTTP_SERVICE_CONFIG_SSL_PARAM; + +#define HTTP_SERVICE_CONFIG_SSL_FLAG_USE_DS_MAPPER 0x00000001 +#define HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT 0x00000002 +#if _WIN32_WINNT < 0x0600 +#define HTTP_SERVICE_CONFIG_SSL_FLAG_NO_RAW_FILTER 0x00000004 +#endif // _WIN32_WINNT < 0x0600 + +// +// This data structure is used by HttpSetServiceConfiguration() for the +// config ID HttpServiceConfigSSLCertInfo. It's used to add a new record +// to the SSL store. +// + +typedef struct _HTTP_SERVICE_CONFIG_SSL_SET +{ + HTTP_SERVICE_CONFIG_SSL_KEY KeyDesc; + HTTP_SERVICE_CONFIG_SSL_PARAM ParamDesc; +} HTTP_SERVICE_CONFIG_SSL_SET, *PHTTP_SERVICE_CONFIG_SSL_SET; + +// +// This data structure is used by HttpQueryServiceConfiguration() for the +// config ID HttpServiceConfigSSLCertInfo. It's used to query a particular +// record from the SSL store. +// +// If QueryType is HttpServiceConfigQueryExact, then one particular record of +// the type HTTP_SERVICE_CONFIG_SSL_SET is returned. If the QueryType is +// HttpServiceConfigQueryNext, then the next instance of +// HTTP_SERVICE_CONFIG_SSL_SET is returned. In such cases, the dwToken field +// represents the cursor. For the first item, dwToken has to be 0. +// For subsequent items, dwToken has to be incremented by 1, +// until ERROR_NO_MORE_ITEMS is returned. +// + +typedef struct _HTTP_SERVICE_CONFIG_SSL_QUERY +{ + HTTP_SERVICE_CONFIG_QUERY_TYPE QueryDesc; + HTTP_SERVICE_CONFIG_SSL_KEY KeyDesc; + DWORD dwToken; +} HTTP_SERVICE_CONFIG_SSL_QUERY, *PHTTP_SERVICE_CONFIG_SSL_QUERY; + +// +// Set/Delete IP Listen-Only List record +// +// Used as a parameter to both HttpSetServiceConfiguration() and +// HttpDeleteServiceConfiguration() functions. +// + +typedef struct _HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM +{ + USHORT AddrLength; + PSOCKADDR pAddress; +} HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM, *PHTTP_SERVICE_CONFIG_IP_LISTEN_PARAM; + +// +// Query IP Listen-Only List record. +// +// Parameter to HttpQueryServiceConfiguration() for the config ID +// HttpServiceConfigIPListenList. On successful return, AddrList +// contains an array of AddrCount elements. Caller must provide a +// large enough buffer to hold all elements in one call. +// +// Caller may determine the type of each returned element by examining +// AddrList[i].ss_family. If it's AF_INET, use ((PSOCKADDR_IN) &AddrList[i]); +// otherwise, for AF_INET6, use ((PSOCKADDR_IN6) &AddrList[i]) +// to select the appropriate address type. +// + +typedef struct _HTTP_SERVICE_CONFIG_IP_LISTEN_QUERY +{ + ULONG AddrCount; + SOCKADDR_STORAGE AddrList[ANYSIZE_ARRAY]; +} HTTP_SERVICE_CONFIG_IP_LISTEN_QUERY, *PHTTP_SERVICE_CONFIG_IP_LISTEN_QUERY; + +// +// URL ACL +// +// +typedef struct _HTTP_SERVICE_CONFIG_URLACL_KEY +{ + PWSTR pUrlPrefix; + +} HTTP_SERVICE_CONFIG_URLACL_KEY, *PHTTP_SERVICE_CONFIG_URLACL_KEY; + +// +// This defines a record for the SSL config store. +// + +typedef struct _HTTP_SERVICE_CONFIG_URLACL_PARAM +{ + PWSTR pStringSecurityDescriptor; +} HTTP_SERVICE_CONFIG_URLACL_PARAM, *PHTTP_SERVICE_CONFIG_URLACL_PARAM; + + +// +// This data structure is used by HttpSetServiceConfiguration for the config ID +// HttpServiceConfigUrlAclInfo. It is used to add a new record to the URL ACL +// store. +// + +typedef struct _HTTP_SERVICE_CONFIG_URLACL_SET +{ + HTTP_SERVICE_CONFIG_URLACL_KEY KeyDesc; + HTTP_SERVICE_CONFIG_URLACL_PARAM ParamDesc; +} HTTP_SERVICE_CONFIG_URLACL_SET, *PHTTP_SERVICE_CONFIG_URLACL_SET; + + +// +// This data structure is used by HttpQueryServiceConfiguration() for the +// config ID HttpServiceConfigUrlAclInfo. It's used to query a particular +// record from the URL ACL store. +// +// If QueryType is HttpServiceConfigQueryExact, then one particular record of +// the type HTTP_SERVICE_CONFIG_URLACL_SET is returned. If the QueryType is +// HttpServiceConfigQueryNext, then the next instance of +// HTTP_SERVICE_CONFIG_URLACL_SET is returned. In such cases, the dwToken field +// represents the cursor. For the first item, dwToken has to be 0. +// For subsequent items, dwToken has to be incremented by 1, +// until ERROR_NO_MORE_ITEMS is returned. +// + +typedef struct _HTTP_SERVICE_CONFIG_URLACL_QUERY +{ + HTTP_SERVICE_CONFIG_QUERY_TYPE QueryDesc; + HTTP_SERVICE_CONFIG_URLACL_KEY KeyDesc; + DWORD dwToken; +} HTTP_SERVICE_CONFIG_URLACL_QUERY, *PHTTP_SERVICE_CONFIG_URLACL_QUERY; + +// +// Cache Paramemers +// + +// +// For manipulating global cache parameters. +// The parameters that can be changed or queued are per-uri cache size +// and cached range chunk size. +// + +typedef enum _HTTP_SERVICE_CONFIG_CACHE_KEY +{ + MaxCacheResponseSize = 0, + CacheRangeChunkSize +} HTTP_SERVICE_CONFIG_CACHE_KEY, *PHTTP_SERVICE_CONFIG_CACHE_KEY; + +typedef ULONG HTTP_SERVICE_CONFIG_CACHE_PARAM, + *PHTTP_SERVICE_CONFIG_CACHE_PARAM; + +// +// To set a cache parameter value use the set structure. To query use the key +// directly. When you query a parameter value the output buffer must be exactly +// the sizeof param. +// + +typedef struct { + HTTP_SERVICE_CONFIG_CACHE_KEY KeyDesc; + HTTP_SERVICE_CONFIG_CACHE_PARAM ParamDesc; +} HTTP_SERVICE_CONFIG_CACHE_SET, *PHTTP_SERVICE_CONFIG_CACHE_SET; + + +// +// Define our API linkage. +// + +#if !defined(HTTPAPI_LINKAGE) +#define HTTPAPI_LINKAGE DECLSPEC_IMPORT +#endif // !HTTPAPI_LINKAGE + +// +// Initialize/Terminate APIs. +// + + +// NOTE: MUST be called once before all other APIs + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpInitialize( + IN HTTPAPI_VERSION Version, + IN ULONG Flags, + __reserved IN OUT PVOID pReserved + ); + +// NOTE: MUST be called after final API call returns. + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpTerminate( + IN ULONG Flags, + __reserved IN OUT PVOID pReserved + ); + +// +// HTTP Request Queue manipulation APIs. +// +// This API is maintained for backward competibility for the first +// version of the HTTPAPI and should not be used. Instead the new +// HttpCreateRequestQueue() API must be used. +// +// Use CloseHandle() to release the handles returned by +// HttpCreateHttpHandle() API. +// + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpCreateHttpHandle( + OUT PHANDLE pReqQueueHandle, + __reserved IN ULONG Reserved + ); + +#if _WIN32_WINNT >= 0x0600 + +// +// Extended Request Queue manipulation APIs. +// +// Use HttpCloseRequestQueue() API to close the handles +// created by the HttpCreateRequestQueue API. +// + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpCreateRequestQueue( + IN HTTPAPI_VERSION Version, + IN PCWSTR pName OPTIONAL, + IN PSECURITY_ATTRIBUTES pSecurityAttributes OPTIONAL, + IN ULONG Flags OPTIONAL, + OUT PHANDLE pReqQueueHandle + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpCloseRequestQueue( + IN HANDLE ReqQueueHandle + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpSetRequestQueueProperty( + IN HANDLE Handle, + IN HTTP_SERVER_PROPERTY Property, + __in_bcount(PropertyInformationLength) IN PVOID pPropertyInformation, + IN ULONG PropertyInformationLength, + __reserved IN ULONG Reserved, + __reserved IN PVOID pReserved + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpQueryRequestQueueProperty( + IN HANDLE Handle, + IN HTTP_SERVER_PROPERTY Property, + __out_bcount_part(PropertyInformationLength, *pReturnLength) + OUT PVOID pPropertyInformation, + IN ULONG PropertyInformationLength, + __reserved IN ULONG Reserved, + __out_opt OUT PULONG pReturnLength OPTIONAL, + __reserved IN PVOID pReserved + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpShutdownRequestQueue( + IN HANDLE ReqQueueHandle + ); + +#endif // _WIN32_WINNT >= 0x0600 + +// +// SSL APIs. +// + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpReceiveClientCertificate( + IN HANDLE ReqQueueHandle, + IN HTTP_CONNECTION_ID ConnectionId, + IN ULONG Flags, + __out_bcount_part(SslClientCertInfoSize, *pBytesReceived) + OUT PHTTP_SSL_CLIENT_CERT_INFO pSslClientCertInfo, + IN ULONG SslClientCertInfoSize, + __out_opt OUT PULONG pBytesReceived OPTIONAL, + IN LPOVERLAPPED pOverlapped OPTIONAL + ); + +#if _WIN32_WINNT >= 0x0600 + +// +// Server Session APIs. +// + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpCreateServerSession( + IN HTTPAPI_VERSION Version, + OUT PHTTP_SERVER_SESSION_ID pServerSessionId, + __reserved IN ULONG Reserved + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpCloseServerSession( + IN HTTP_SERVER_SESSION_ID ServerSessionId + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpQueryServerSessionProperty( + IN HTTP_SERVER_SESSION_ID ServerSessionId, + IN HTTP_SERVER_PROPERTY Property, + __out_bcount_part(PropertyInformationLength, *pReturnLength) + OUT PVOID pPropertyInformation, + IN ULONG PropertyInformationLength, + __out_opt OUT PULONG pReturnLength OPTIONAL + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpSetServerSessionProperty( + IN HTTP_SERVER_SESSION_ID ServerSessionId, + IN HTTP_SERVER_PROPERTY Property, + __in_bcount(PropertyInformationLength) IN PVOID pPropertyInformation, + IN ULONG PropertyInformationLength + ); + +#endif // _WIN32_WINNT >= 0x0600 + +// +// Url Configuration APIs. Can only be used for V1 request queues. +// + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpAddUrl( + IN HANDLE ReqQueueHandle, + IN PCWSTR pFullyQualifiedUrl, + __reserved IN PVOID pReserved + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpRemoveUrl( + IN HANDLE ReqQueueHandle, + IN PCWSTR pFullyQualifiedUrl + ); + +#if _WIN32_WINNT >= 0x0600 + +// +// Url Group APIs. +// + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpCreateUrlGroup( + IN HTTP_SERVER_SESSION_ID ServerSessionId, + OUT PHTTP_URL_GROUP_ID pUrlGroupId, + __reserved IN ULONG Reserved + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpCloseUrlGroup( + IN HTTP_URL_GROUP_ID UrlGroupId + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpAddUrlToUrlGroup( + IN HTTP_URL_GROUP_ID UrlGroupId, + IN PCWSTR pFullyQualifiedUrl, + IN HTTP_URL_CONTEXT UrlContext OPTIONAL, + __reserved IN ULONG Reserved + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpRemoveUrlFromUrlGroup( + IN HTTP_URL_GROUP_ID UrlGroupId, + IN PCWSTR pFullyQualifiedUrl, + IN ULONG Flags + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpSetUrlGroupProperty( + IN HTTP_URL_GROUP_ID UrlGroupId, + IN HTTP_SERVER_PROPERTY Property, + __in_bcount(PropertyInformationLength) IN PVOID pPropertyInformation, + IN ULONG PropertyInformationLength + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpQueryUrlGroupProperty( + IN HTTP_URL_GROUP_ID UrlGroupId, + IN HTTP_SERVER_PROPERTY Property, + __out_bcount_part(PropertyInformationLength, *pReturnLength) + OUT PVOID pPropertyInformation, + IN ULONG PropertyInformationLength, + __out_opt OUT PULONG pReturnLength OPTIONAL + ); + +#endif // _WIN32_WINNT >= 0x0600 + +// +// HTTP Server I/O APIs. +// + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpReceiveHttpRequest( + IN HANDLE ReqQueueHandle, + IN HTTP_REQUEST_ID RequestId, + IN ULONG Flags, + __out_bcount_part(RequestBufferLength, *pBytesReceived) + OUT PHTTP_REQUEST pRequestBuffer, + IN ULONG RequestBufferLength, + __out_opt OUT PULONG pBytesReceived OPTIONAL, + IN LPOVERLAPPED pOverlapped OPTIONAL + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpReceiveRequestEntityBody( + IN HANDLE ReqQueueHandle, + IN HTTP_REQUEST_ID RequestId, + IN ULONG Flags, + __out_bcount_part(BufferLength, *pBytesReceived) OUT PVOID pBuffer, + IN ULONG BufferLength, + __out_opt OUT PULONG pBytesReceived OPTIONAL, + IN LPOVERLAPPED pOverlapped OPTIONAL + ); + +#if _WIN32_WINNT >= 0x0600 + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpSendHttpResponse( + IN HANDLE ReqQueueHandle, + IN HTTP_REQUEST_ID RequestId, + IN ULONG Flags, + IN PHTTP_RESPONSE pHttpResponse, + IN PHTTP_CACHE_POLICY pCachePolicy OPTIONAL, + OUT PULONG pBytesSent OPTIONAL, + OUT PVOID pReserved1 OPTIONAL, // must be NULL + IN ULONG Reserved2 OPTIONAL, // must be 0 + IN LPOVERLAPPED pOverlapped OPTIONAL, + IN PHTTP_LOG_DATA pLogData OPTIONAL + ); + +#else // _WIN32_WINNT >= 0x0600 + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpSendHttpResponse( + IN HANDLE ReqQueueHandle, + IN HTTP_REQUEST_ID RequestId, + IN ULONG Flags, + IN PHTTP_RESPONSE pHttpResponse, + IN PVOID pReserved1 OPTIONAL, // must be NULL + OUT PULONG pBytesSent OPTIONAL, + OUT PVOID pReserved2 OPTIONAL, // must be NULL + IN ULONG Reserved3 OPTIONAL, // must be 0 + IN LPOVERLAPPED pOverlapped OPTIONAL, + IN PVOID pReserved4 OPTIONAL // must be NULL + ); + +#endif // _WIN32_WINNT >= 0x0600 + +#if _WIN32_WINNT >= 0x0600 + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpSendResponseEntityBody( + IN HANDLE ReqQueueHandle, + IN HTTP_REQUEST_ID RequestId, + IN ULONG Flags, + IN USHORT EntityChunkCount OPTIONAL, + __in_ecount_opt(EntityChunkCount) + IN PHTTP_DATA_CHUNK pEntityChunks OPTIONAL, + OUT PULONG pBytesSent OPTIONAL, + OUT PVOID pReserved1 OPTIONAL, // must be NULL + IN ULONG Reserved2 OPTIONAL, // must be 0 + IN LPOVERLAPPED pOverlapped OPTIONAL, + IN PHTTP_LOG_DATA pLogData OPTIONAL + ); + +#else // _WIN32_WINNT >= 0x0600 + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpSendResponseEntityBody( + IN HANDLE ReqQueueHandle, + IN HTTP_REQUEST_ID RequestId, + IN ULONG Flags, + IN USHORT EntityChunkCount OPTIONAL, + __in_ecount_opt(EntityChunkCount) + IN PHTTP_DATA_CHUNK pEntityChunks OPTIONAL, + OUT PULONG pBytesSent OPTIONAL, + OUT PVOID pReserved1 OPTIONAL, // must be NULL + IN ULONG Reserved2 OPTIONAL, // must be 0 + IN LPOVERLAPPED pOverlapped OPTIONAL, + IN PVOID pReserved3 OPTIONAL // must be NULL + ); + +#endif // _WIN32_WINNT >= 0x0600 + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpWaitForDisconnect( + IN HANDLE ReqQueueHandle, + IN HTTP_CONNECTION_ID ConnectionId, + IN LPOVERLAPPED pOverlapped OPTIONAL + ); + +#if _WIN32_WINNT >= 0x0600 + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpWaitForDisconnectEx( + IN HANDLE ReqQueueHandle, + IN HTTP_CONNECTION_ID ConnectionId, + __reserved IN ULONG Reserved OPTIONAL, + IN LPOVERLAPPED pOverlapped OPTIONAL + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpCancelHttpRequest( + IN HANDLE ReqQueueHandle, + IN HTTP_REQUEST_ID RequestId, + IN LPOVERLAPPED pOverlapped OPTIONAL + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpWaitForDemandStart( + IN HANDLE ReqQueueHandle, + IN LPOVERLAPPED pOverlapped OPTIONAL + ); + + +#endif // _WIN32_WINNT >= 0x0600 + +// +// Cache manipulation APIs. +// + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpFlushResponseCache( + IN HANDLE ReqQueueHandle, + IN PCWSTR pUrlPrefix, + IN ULONG Flags, + IN LPOVERLAPPED pOverlapped OPTIONAL + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpAddFragmentToCache( + IN HANDLE ReqQueueHandle, + IN PCWSTR pUrlPrefix, + IN PHTTP_DATA_CHUNK pDataChunk, + IN PHTTP_CACHE_POLICY pCachePolicy, + IN LPOVERLAPPED pOverlapped OPTIONAL + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpReadFragmentFromCache( + IN HANDLE ReqQueueHandle, + IN PCWSTR pUrlPrefix, + IN PHTTP_BYTE_RANGE pByteRange OPTIONAL, + __out_bcount_part(BufferLength, *pBytesRead) OUT PVOID pBuffer, + IN ULONG BufferLength, + OUT PULONG pBytesRead OPTIONAL, + IN LPOVERLAPPED pOverlapped OPTIONAL + ); + +// +// Server configuration APIs +// + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpSetServiceConfiguration( + __reserved IN HANDLE ServiceHandle, + IN HTTP_SERVICE_CONFIG_ID ConfigId, + __in_bcount(ConfigInformationLength) IN PVOID pConfigInformation, + IN ULONG ConfigInformationLength, + __reserved IN LPOVERLAPPED pOverlapped + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpDeleteServiceConfiguration( + __reserved IN HANDLE ServiceHandle, + IN HTTP_SERVICE_CONFIG_ID ConfigId, + __in_bcount(ConfigInformationLength) IN PVOID pConfigInformation, + IN ULONG ConfigInformationLength, + __reserved IN LPOVERLAPPED pOverlapped + ); + +HTTPAPI_LINKAGE +ULONG +WINAPI +HttpQueryServiceConfiguration( + __reserved IN HANDLE ServiceHandle, + IN HTTP_SERVICE_CONFIG_ID ConfigId, + __in_bcount_opt(InputConfigInformationLength) + IN PVOID pInputConfigInformation OPTIONAL, + IN ULONG InputConfigInformationLength OPTIONAL, + __out_bcount_part_opt(OutputConfigInformationLength, *pReturnLength) + OUT PVOID pOutputConfigInformation OPTIONAL, + IN ULONG OutputConfigInformationLength OPTIONAL, + __out_opt OUT PULONG pReturnLength OPTIONAL, + __reserved IN LPOVERLAPPED pOverlapped + ); + + +#if BUILD_IIS_FOR_XP + +// part of the httpp.h necessary to build for XP + +// +// Counter Group. +// + +// +// Counter property description. +// + +typedef struct _HTTP_PROP_DESC +{ + ULONG Size; + ULONG Offset; + BOOLEAN WPZeros; + +} HTTP_PROP_DESC, *PHTTP_PROP_DESC; + + +// +// This enum defines the available counter groups. +// + +typedef enum _HTTP_COUNTER_GROUP +{ + HttpCounterGroupSite, + HttpCounterGroupGlobal, + + HttpCounterGroupMaximum + +} HTTP_COUNTER_GROUP, *PHTTP_COUNTER_GROUP; + +// +// Structures for IOCTL_HTTP_GET_COUNTERS. +// + +typedef struct _HTTP_COUNTER_INFO +{ + HTTP_SERVER_SESSION_ID ServerSessionId; + HTTP_COUNTER_GROUP CounterGroup; + +} HTTP_COUNTER_INFO, *PHTTP_COUNTER_INFO; + +// +// This enum defines the type of global couters. +// + +typedef enum _HTTP_GLOBAL_COUNTER_ID +{ + HttpGlobalCounterCurrentUrisCached, + HttpGlobalCounterTotalUrisCached, + HttpGlobalCounterUriCacheHits, + HttpGlobalCounterUriCacheMisses, + HttpGlobalCounterUriCacheFlushes, + HttpGlobalCounterTotalFlushedUris, + + HttpGlobalCounterMaximum + +} HTTP_GLOBAL_COUNTER_ID, *PHTTP_GLOBAL_COUNTER_ID; + + +// +// Global couters. +// + +typedef struct _HTTP_GLOBAL_COUNTERS +{ + ULONG CurrentUrisCached; + ULONG TotalUrisCached; + ULONG UriCacheHits; + ULONG UriCacheMisses; + ULONG UriCacheFlushes; + ULONG TotalFlushedUris; + +} HTTP_GLOBAL_COUNTERS, *PHTTP_GLOBAL_COUNTERS; + + +// +// This enum defines the type of site counters. +// NB: HTTP_SITE_COUNTER_ID and HTTP_SITE_COUNTERS +// must be in the same order +// + +typedef enum _HTTP_SITE_COUNTER_ID +{ + HttpSiteCounterBytesSent, + HttpSiteCounterBytesReceived, + HttpSiteCounterBytesTransfered, + HttpSiteCounterCurrentConns, + HttpSiteCounterMaxConnections, + HttpSiteCounterConnAttempts, + HttpSiteCounterGetReqs, + HttpSiteCounterHeadReqs, + HttpSiteCounterAllReqs, + HttpSiteCounterMeasuredIoBandwidthUsage, + HttpSiteCounterCurrentBlockedBandwidthBytes, + HttpSiteCounterTotalBlockedBandwidthBytes, + + HttpSiteCounterMaximum + +} HTTP_SITE_COUNTER_ID, *PHTTP_SITE_COUNTER_ID; + + +// +// Site counters. +// + +typedef struct _HTTP_SITE_COUNTERS +{ + ULONG SiteId; + ULONGLONG BytesSent; + ULONGLONG BytesReceived; + ULONGLONG BytesTransfered; + ULONG CurrentConns; + ULONG MaxConnections; + ULONG ConnAttempts; + ULONG GetReqs; + ULONG HeadReqs; + ULONG AllReqs; + ULONG MeasuredIoBandwidthUsage; + ULONG CurrentBlockedBandwidthBytes; + ULONG TotalBlockedBandwidthBytes; + +} HTTP_SITE_COUNTERS, *PHTTP_SITE_COUNTERS; + +#endif + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // _WIN32_WINNT >= 0x0501 + +#endif // __HTTP_H__ + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/httpserv_xp.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/httpserv_xp.h new file mode 100644 index 0000000000..6e9437d7ed --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/httpserv_xp.h @@ -0,0 +1,3404 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _HTTPSERV_H_ +#define _HTTPSERV_H_ + +#if (!defined(_WIN64) && !defined(WIN32)) +#error httpserv.h is only supported on WIN32 or WIN64 platforms +#endif + +#include + +#if _WIN32_WINNT >= 0x0600 +#include "http.h" +#else +#include "http_xp.h" +#endif + +// +// Request deterministic notifications +// + +// request is beginning +#define RQ_BEGIN_REQUEST 0x00000001 +// request is being authenticated +#define RQ_AUTHENTICATE_REQUEST 0x00000002 +// request is being authorized +#define RQ_AUTHORIZE_REQUEST 0x00000004 +// satisfy request from cache +#define RQ_RESOLVE_REQUEST_CACHE 0x00000008 +// map handler for request +#define RQ_MAP_REQUEST_HANDLER 0x00000010 +// acquire request state +#define RQ_ACQUIRE_REQUEST_STATE 0x00000020 +// pre-execute handler +#define RQ_PRE_EXECUTE_REQUEST_HANDLER 0x00000040 +// execute handler +#define RQ_EXECUTE_REQUEST_HANDLER 0x00000080 +// release request state +#define RQ_RELEASE_REQUEST_STATE 0x00000100 +// update cache +#define RQ_UPDATE_REQUEST_CACHE 0x00000200 +// log request +#define RQ_LOG_REQUEST 0x00000400 +// end request +#define RQ_END_REQUEST 0x00000800 + +// +// Request non-deterministic notifications +// + +// custom notification +#define RQ_CUSTOM_NOTIFICATION 0x10000000 +// send response +#define RQ_SEND_RESPONSE 0x20000000 +// read entity +#define RQ_READ_ENTITY 0x40000000 +// map a url to a physical path +#define RQ_MAP_PATH 0x80000000 + +// +// Global notifications +// + +// stop accepting new requests +#define GL_STOP_LISTENING 0x00000002 +// cache cleanup before termination +#define GL_CACHE_CLEANUP 0x00000004 +// cache operation +#define GL_CACHE_OPERATION 0x00000010 +// health check +#define GL_HEALTH_CHECK 0x00000020 +// configuration changed +#define GL_CONFIGURATION_CHANGE 0x00000040 +// file changed +#define GL_FILE_CHANGE 0x00000080 +// before request pipeline has started +#define GL_PRE_BEGIN_REQUEST 0x00000100 +// application start +#define GL_APPLICATION_START 0x00000200 +// resolve modules for an application +#define GL_APPLICATION_RESOLVE_MODULES 0x00000400 +// application end +#define GL_APPLICATION_STOP 0x00000800 +// RSCA query +#define GL_RSCA_QUERY 0x00001000 +// trace event was raised +#define GL_TRACE_EVENT 0x00002000 +// custom notification +#define GL_CUSTOM_NOTIFICATION 0x00004000 +// thread cleanup notification +#define GL_THREAD_CLEANUP 0x00008000 +// application preload notification +#define GL_APPLICATION_PRELOAD 0x00010000 + +// +// Request notification return status +// + +typedef enum REQUEST_NOTIFICATION_STATUS +{ + RQ_NOTIFICATION_CONTINUE, // continue processing + // for notification + RQ_NOTIFICATION_PENDING, // suspend processing + // for notification + RQ_NOTIFICATION_FINISH_REQUEST // finish request + // processing +}; + +// +// Out of band return codes +// + +typedef enum GLOBAL_NOTIFICATION_STATUS +{ + GL_NOTIFICATION_CONTINUE, // continue processing + // for notification + GL_NOTIFICATION_HANDLED // finish processing for + // notification +}; + +// +// Priority class aliases +// + +#define PRIORITY_ALIAS_FIRST L"FIRST" +#define PRIORITY_ALIAS_HIGH L"HIGH" +#define PRIORITY_ALIAS_MEDIUM L"MEDIUM" +#define PRIORITY_ALIAS_LOW L"LOW" +#define PRIORITY_ALIAS_LAST L"LAST" + +// +// Cache operations +// + +typedef enum CACHE_OPERATION +{ + CACHE_OPERATION_RETRIEVE, + CACHE_OPERATION_ADD, + CACHE_OPERATION_DELETE, + CACHE_OPERATION_FLUSH_PREFIX, + CACHE_OPERATION_ENUM +}; + +// +// Module identifier +// + +typedef VOID* HTTP_MODULE_ID; + +// +// Flags for IHttpContext->CloneContext() +// + +#define CLONE_FLAG_BASICS 0x01 +#define CLONE_FLAG_HEADERS 0x02 +#define CLONE_FLAG_ENTITY 0x04 +#define CLONE_FLAG_NO_PRECONDITION 0x08 +#define CLONE_FLAG_NO_DAV 0x10 + +// +// Flags for IHttpContext->ExecuteRequest() +// + +#define EXECUTE_FLAG_NO_HEADERS 0x01 +#define EXECUTE_FLAG_IGNORE_CURRENT_INTERCEPTOR 0x02 +#define EXECUTE_FLAG_IGNORE_APPPOOL 0x04 +#define EXECUTE_FLAG_DISABLE_CUSTOM_ERROR 0x08 +#define EXECUTE_FLAG_SAME_URL 0x10 +// do not flush the child response but copy it back to the parent +#define EXECUTE_FLAG_BUFFER_RESPONSE 0x20 +// child response is still eligible for http.sys caching +#define EXECUTE_FLAG_HTTP_CACHE_ELIGIBLE 0x40 + + +// +// forward declarations +// +struct HTTP_TRACE_CONFIGURATION; +struct HTTP_TRACE_EVENT; + +class IWpfSettings; +class IHttpTraceContext; + +// +// Module-specific context descriptor +// +class __declspec(uuid("f1927f76-790e-4ccb-a72e-396bdfdae05d")) +IHttpStoredContext +{ + public: + virtual + VOID + CleanupStoredContext( + VOID + ) = 0; +}; + +// +// Context container +// +class __declspec(uuid("d7fad7c9-aa27-4ab9-bd60-e55ccba3f5dc")) +IHttpModuleContextContainer +{ + public: + virtual + IHttpStoredContext * + GetModuleContext( + IN HTTP_MODULE_ID moduleId + ) = 0; + + virtual + HRESULT + SetModuleContext( + IN IHttpStoredContext * ppStoredContext, + IN HTTP_MODULE_ID moduleId + ) = 0; +}; + +// +// Dispensed context container +// +class __declspec(uuid("2ae49359-95dd-4e48-ae20-c0cb9d0bc03a")) +IDispensedHttpModuleContextContainer : public IHttpModuleContextContainer +{ +public: + virtual + VOID + ReleaseContainer( + VOID + ) = 0; +}; + +// +// Performance counter descriptor +// +class __declspec(uuid("bdfc4c4a-12a4-4744-87d8-765eb320c59f")) +IHttpPerfCounterInfo +{ + public: + virtual + VOID + IncrementCounter( + DWORD dwCounterIndex, + DWORD dwValue = 1 + ) = 0; + + virtual + VOID + DecrementCounter( + DWORD dwCounterIndex, + DWORD dwValue = 1 + ) = 0; +}; + +// +// Application descriptor +// +class __declspec(uuid("3f75d9e6-1075-422c-ad89-93a85f2d7bdc")) +IHttpApplication +{ + public: + virtual + PCWSTR + GetApplicationPhysicalPath( + VOID + ) const = 0; + + virtual + PCWSTR + GetApplicationId( + VOID + ) const = 0; + + virtual + PCWSTR + GetAppConfigPath( + VOID + ) const = 0; + + virtual + IHttpModuleContextContainer * + GetModuleContextContainer( + VOID + ) = 0; +}; + +// +// URI cache entry descriptor +// +class __declspec(uuid("7e0e6167-0094-49a1-8287-ecf6dc6e73a6")) +IHttpUrlInfo +{ + public: + virtual + IHttpModuleContextContainer * + GetModuleContextContainer( + VOID + ) = 0; + + virtual + BOOL + IsFrequentlyHit( + VOID + ) const = 0; +}; + +// +// Script map descriptor +// +class __declspec(uuid("d7fe3d77-68bc-4d4a-851f-eec9fb68017c")) +IScriptMapInfo +{ + public: + virtual + PCWSTR + GetPath( + VOID + ) const = 0; + + virtual + PCSTR + GetAllowedVerbs( + VOID + ) const = 0; + + virtual + PCWSTR + GetModules( + OUT DWORD * pcchModules = NULL + ) const = 0; + + virtual + PCWSTR + GetScriptProcessor( + OUT DWORD * pcchScriptProcessor = NULL + ) const = 0; + + virtual + PCWSTR + GetManagedType( + OUT DWORD * pcchManagedType = NULL + ) const = 0; + + virtual + BOOL + GetAllowPathInfoForScriptMappings( + VOID + ) const = 0; + + virtual + DWORD + GetRequiredAccess( + VOID + ) const = 0; + + virtual + DWORD + GetResourceType( + VOID + ) const = 0; + + virtual + BOOL + GetIsStarScriptMap( + VOID + ) const = 0; + + virtual + DWORD + GetResponseBufferLimit( + VOID + ) const = 0; + + virtual + PCWSTR + GetName( + VOID + ) const = 0; +}; + +class __declspec(uuid("fd86e6de-fb0e-47dd-820a-e0da12be46e9")) +IHttpTokenEntry; + +// +// Metadata descriptor +// +class __declspec(uuid("48b10633-825d-495e-93b0-225380053e8e")) +IMetadataInfo +{ + public: + virtual + PCWSTR + GetMetaPath( + VOID + ) const = 0; + + virtual + PCWSTR + GetVrPath( + VOID + ) const = 0; + + virtual + IHttpTokenEntry * + GetVrToken( + VOID + ) = 0; + + virtual + IHttpModuleContextContainer * + GetModuleContextContainer( + VOID + ) = 0; +}; + +// +// Provides an interface to an HTTP request object. The methods on this +// class can be used to inspect and modify request data. +// +class __declspec(uuid("e8698f7e-576e-4cac-a309-67435355faef")) +IHttpRequest +{ + public: + virtual + HTTP_REQUEST * + GetRawHttpRequest( + VOID + ) = 0; + + virtual + const HTTP_REQUEST * + GetRawHttpRequest( + VOID + ) const = 0; + + virtual + PCSTR + GetHeader( + IN PCSTR pszHeaderName, + OUT USHORT * pcchHeaderValue = NULL + ) const = 0; + + virtual + PCSTR + GetHeader( + IN HTTP_HEADER_ID ulHeaderIndex, + OUT USHORT * pcchHeaderValue = NULL + ) const = 0; + + virtual + HRESULT + SetHeader( + IN PCSTR pszHeaderName, + IN PCSTR pszHeaderValue, + IN USHORT cchHeaderValue, + IN BOOL fReplace + ) = 0; + + virtual + HRESULT + SetHeader( + IN HTTP_HEADER_ID ulHeaderIndex, + IN PCSTR pszHeaderValue, + IN USHORT cchHeaderValue, + IN BOOL fReplace + ) = 0; + + virtual + HRESULT + DeleteHeader( + IN PCSTR pszHeaderName + ) = 0; + + virtual + HRESULT + DeleteHeader( + IN HTTP_HEADER_ID ulHeaderIndex + ) = 0; + + virtual + PCSTR + GetHttpMethod( + VOID + ) const = 0; + + virtual + HRESULT + SetHttpMethod( + IN PCSTR pszHttpMethod + ) = 0; + + virtual + HRESULT + SetUrl( + IN PCWSTR pszUrl, + IN DWORD cchUrl, + IN BOOL fResetQueryString + ) = 0; + + virtual + HRESULT + SetUrl( + IN PCSTR pszUrl, + IN DWORD cchUrl, + IN BOOL fResetQueryString + ) = 0; + + virtual + BOOL + GetUrlChanged( + VOID + ) const = 0; + + virtual + PCWSTR + GetForwardedUrl( + VOID + ) const = 0; + + virtual + PSOCKADDR + GetLocalAddress( + VOID + ) const = 0; + + virtual + PSOCKADDR + GetRemoteAddress( + VOID + ) const = 0; + + virtual + HRESULT + ReadEntityBody( + OUT VOID * pvBuffer, + IN DWORD cbBuffer, + IN BOOL fAsync, + OUT DWORD * pcbBytesReceived, + OUT BOOL * pfCompletionPending = NULL + ) = 0; + + virtual + HRESULT + InsertEntityBody( + IN VOID * pvBuffer, + IN DWORD cbBuffer + ) = 0; + + virtual + DWORD + GetRemainingEntityBytes( + VOID + ) = 0; + + virtual + VOID + GetHttpVersion( + OUT USHORT * pMajorVersion, + OUT USHORT * pMinorVersion + ) const = 0; + + virtual + HRESULT + GetClientCertificate( + OUT HTTP_SSL_CLIENT_CERT_INFO ** ppClientCertInfo, + OUT BOOL * pfClientCertNegotiated + ) = 0; + + virtual + HRESULT + NegotiateClientCertificate( + IN BOOL fAsync, + OUT BOOL * pfCompletionPending = NULL + ) = 0; + + virtual + DWORD + GetSiteId( + VOID + ) const = 0; + + virtual + HRESULT + GetHeaderChanges( + IN DWORD dwOldChangeNumber, + OUT DWORD * pdwNewChangeNumber, + IN OUT PCSTR knownHeaderSnapshot[HttpHeaderRequestMaximum], + IN OUT DWORD * pdwUnknownHeaderSnapshot, + IN OUT PCSTR **ppUnknownHeaderNameSnapshot, + IN OUT PCSTR **ppUnknownHeaderValueSnapshot, + __out_ecount(HttpHeaderRequestMaximum+1) + DWORD diffedKnownHeaderIndices[HttpHeaderRequestMaximum+1], + OUT DWORD * pdwDiffedUnknownHeaders, + OUT DWORD **ppDiffedUnknownHeaderIndices + ) = 0; +}; + +class __declspec(uuid("d9244ae1-51f8-4aa1-a66d-19277c33e610")) +IHttpRequest2 : public IHttpRequest +{ + public: + virtual + HRESULT + GetChannelBindingToken( + __deref_out_bcount_part(*pTokenSize, *pTokenSize) + PBYTE * ppToken, + DWORD * pTokenSize + ) = 0; +}; + +class __declspec(uuid("cb1c40ca-70f2-41a0-add2-881f5ef57388")) +IHttpCachePolicy +{ + public: + virtual + HTTP_CACHE_POLICY * + GetKernelCachePolicy( + VOID + ) = 0; + + virtual + VOID + SetKernelCacheInvalidatorSet( + VOID + ) = 0; + + virtual + HTTP_CACHE_POLICY * + GetUserCachePolicy( + VOID + ) = 0; + + virtual + HRESULT + AppendVaryByHeader( + PCSTR pszHeader + ) = 0; + + virtual + PCSTR + GetVaryByHeaders( + VOID + ) const = 0; + + virtual + HRESULT + AppendVaryByQueryString( + PCSTR pszParam + ) = 0; + + virtual + PCSTR + GetVaryByQueryStrings( + VOID + ) const = 0; + + virtual + HRESULT + SetVaryByValue( + PCSTR pszValue + ) = 0; + + virtual + PCSTR + GetVaryByValue( + VOID + ) const = 0; + + virtual + BOOL + IsUserCacheEnabled( + VOID + ) const = 0; + + virtual + VOID + DisableUserCache( + VOID + ) = 0; + + virtual + BOOL + IsCached( + VOID + ) const = 0; + + virtual + VOID + SetIsCached( + VOID + ) = 0; + + virtual + BOOL + GetKernelCacheInvalidatorSet( + VOID + ) const = 0; +}; + +class __declspec(uuid("9f4ba807-050e-4495-ae55-8870f7e9194a")) +IHttpCachePolicy2 : public IHttpCachePolicy +{ + public: + virtual + BOOL + IsForceUpdateSet( + VOID + ) const = 0; + + virtual + VOID + SetForceUpdate( + VOID + ) = 0; +}; + +// +// Response descriptor +// +class __declspec(uuid("7e1c6b38-628f-4e6c-95dc-41237eb7f95e")) +IHttpResponse +{ + public: + virtual + HTTP_RESPONSE * + GetRawHttpResponse( + VOID + ) = 0; + + virtual + const HTTP_RESPONSE * + GetRawHttpResponse( + VOID + ) const = 0; + + virtual + IHttpCachePolicy * + GetCachePolicy( + VOID + ) = 0; + + virtual + HRESULT + SetStatus( + IN USHORT statusCode, + IN PCSTR pszReason, + IN USHORT uSubStatus = 0, + IN HRESULT hrErrorToReport = S_OK, + IN IAppHostConfigException *pException = NULL, + IN BOOL fTrySkipCustomErrors = FALSE + ) = 0; + + virtual + HRESULT + SetHeader( + IN PCSTR pszHeaderName, + IN PCSTR pszHeaderValue, + IN USHORT cchHeaderValue, + IN BOOL fReplace + ) = 0; + + virtual + HRESULT + SetHeader( + IN HTTP_HEADER_ID ulHeaderIndex, + IN PCSTR pszHeaderValue, + IN USHORT cchHeaderValue, + IN BOOL fReplace + ) = 0; + + virtual + HRESULT + DeleteHeader( + IN PCSTR pszHeaderName + ) = 0; + + virtual + HRESULT + DeleteHeader( + IN HTTP_HEADER_ID ulHeaderIndex + ) = 0; + + virtual + PCSTR + GetHeader( + IN PCSTR pszHeaderName, + OUT USHORT * pcchHeaderValue = NULL + ) const = 0; + + virtual + PCSTR + GetHeader( + IN HTTP_HEADER_ID ulHeaderIndex, + OUT USHORT * pcchHeaderValue = NULL + ) const = 0; + + virtual + VOID + Clear( + VOID + ) = 0; + + virtual + VOID + ClearHeaders( + VOID + ) = 0; + + virtual + VOID + SetNeedDisconnect( + VOID + ) = 0; + + virtual + VOID + ResetConnection( + VOID + ) = 0; + + virtual + VOID + DisableKernelCache( + ULONG reason = 9 + ) = 0; + + virtual + BOOL + GetKernelCacheEnabled( + VOID + ) const = 0; + + virtual + VOID + SuppressHeaders( + VOID + ) = 0; + + virtual + BOOL + GetHeadersSuppressed( + VOID + ) const = 0; + + virtual + HRESULT + Flush( + IN BOOL fAsync, + IN BOOL fMoreData, + OUT DWORD * pcbSent, + OUT BOOL * pfCompletionExpected = NULL + ) = 0; + + virtual + HRESULT + Redirect( + IN PCSTR pszUrl, + IN BOOL fResetStatusCode = TRUE, + IN BOOL fIncludeParameters = FALSE + ) = 0; + + virtual + HRESULT + WriteEntityChunkByReference( + IN HTTP_DATA_CHUNK * pDataChunk, + IN LONG lInsertPosition = -1 + ) = 0; + + virtual + HRESULT + WriteEntityChunks( + IN HTTP_DATA_CHUNK * pDataChunks, + IN DWORD nChunks, + IN BOOL fAsync, + IN BOOL fMoreData, + OUT DWORD * pcbSent, + OUT BOOL * pfCompletionExpected = NULL + ) = 0; + + virtual + VOID + DisableBuffering( + VOID + ) = 0; + + virtual + VOID + GetStatus( + OUT USHORT * pStatusCode, + OUT USHORT * pSubStatus = NULL, + OUT PCSTR * ppszReason = NULL, + OUT USHORT * pcchReason = NULL, + OUT HRESULT * phrErrorToReport = NULL, + OUT PCWSTR * ppszModule = NULL, + OUT DWORD * pdwNotification = NULL, + OUT IAppHostConfigException ** ppException = NULL, + OUT BOOL * pfTrySkipCustomErrors = NULL + ) = 0; + + virtual + HRESULT + SetErrorDescription( + IN PCWSTR pszDescription, + IN DWORD cchDescription, + IN BOOL fHtmlEncode = TRUE + ) = 0; + + virtual + PCWSTR + GetErrorDescription( + OUT DWORD * pcchDescription = NULL + ) = 0; + + virtual + HRESULT + GetHeaderChanges( + IN DWORD dwOldChangeNumber, + OUT DWORD * pdwNewChangeNumber, + IN OUT PCSTR knownHeaderSnapshot[HttpHeaderResponseMaximum], + IN OUT DWORD * pdwUnknownHeaderSnapshot, + IN OUT PCSTR **ppUnknownHeaderNameSnapshot, + IN OUT PCSTR **ppUnknownHeaderValueSnapshot, + __out_ecount(HttpHeaderResponseMaximum+1) + DWORD diffedKnownHeaderIndices[HttpHeaderResponseMaximum+1], + OUT DWORD * pdwDiffedUnknownHeaders, + OUT DWORD **ppDiffedUnknownHeaderIndices + ) = 0; + + virtual + VOID + CloseConnection( + VOID + ) = 0; +}; + +// +// User descriptor +// +class __declspec(uuid("8059e6f8-10ce-4d61-b47e-5a1d8d9a8b67")) +IHttpUser +{ + public: + virtual + PCWSTR + GetRemoteUserName( + VOID + ) = 0; + + virtual + PCWSTR + GetUserName( + VOID + ) = 0; + + virtual + PCWSTR + GetAuthenticationType( + VOID + ) = 0; + + virtual + PCWSTR + GetPassword( + VOID + ) = 0; + + virtual + HANDLE + GetImpersonationToken( + VOID + ) = 0; + + virtual + HANDLE + GetPrimaryToken( + VOID + ) = 0; + + virtual + VOID + ReferenceUser( + VOID + ) = 0; + + virtual + VOID + DereferenceUser( + VOID + ) = 0; + + virtual + BOOL + SupportsIsInRole( + VOID + ) = 0; + + virtual + HRESULT + IsInRole( + IN PCWSTR pszRoleName, + OUT BOOL * pfInRole + ) = 0; + + virtual + PVOID + GetUserVariable( + IN PCSTR pszVariableName + ) = 0; +}; + +#define HTTP_USER_VARIABLE_SID "SID" +#define HTTP_USER_VARIABLE_CTXT_HANDLE "CtxtHandle" +#define HTTP_USER_VARIABLE_CRED_HANDLE "CredHandle" + +class __declspec(uuid("841d9a71-75f4-4626-8b97-66046ca7e45b")) +IHttpConnectionStoredContext : public IHttpStoredContext +{ + public: + virtual + VOID + NotifyDisconnect( + VOID + ) = 0; +}; + +class __declspec(uuid("f3dd2fb3-4d11-4295-b8ab-4cb667add1fe")) +IHttpConnectionModuleContextContainer : public IHttpModuleContextContainer +{ + public: + virtual + IHttpConnectionStoredContext * + GetConnectionModuleContext( + IN HTTP_MODULE_ID moduleId + ) = 0; + + virtual + HRESULT + SetConnectionModuleContext( + IN IHttpConnectionStoredContext * ppStoredContext, + IN HTTP_MODULE_ID moduleId + ) = 0; +}; + +// +// Connection descriptor +// +class __declspec(uuid("d9a5de00-3346-4599-9826-fe88565e1226")) +IHttpConnection +{ + public: + virtual + BOOL + IsConnected( + VOID + ) const = 0; + + virtual + VOID * + AllocateMemory( + DWORD cbAllocation + ) = 0; + + virtual + IHttpConnectionModuleContextContainer * + GetModuleContextContainer( + VOID + ) = 0; +}; + +// +// Forward declarations +// +class __declspec(uuid("71e95595-8c74-44d9-88a9-f5112d5f5900")) +IHttpFileInfo; + +class __declspec(uuid("eb16a6ec-ba5d-436f-bf24-3ede13906450")) +IHttpSite; + +class __declspec(uuid("671e6d34-9380-4df4-b453-91129df02b24")) +ICustomNotificationProvider; + +class __declspec(uuid("6f3f657d-2fb8-43c6-a096-5064b41f0580")) +IHttpEventProvider; + +class CHttpModule; + +// +// IHttpContext extended interface versions (deprecated) +// +enum HTTP_CONTEXT_INTERFACE_VERSION +{ +}; + +// +// Context object representing the processing of an HTTP request +// +class __declspec(uuid("424c1b8c-a1ba-44d7-ac98-9f8f457701a5")) +IHttpContext +{ + public: + virtual + IHttpSite * + GetSite( + VOID + ) = 0; + + virtual + IHttpApplication * + GetApplication( + VOID + ) = 0; + + virtual + IHttpConnection * + GetConnection( + VOID + ) = 0; + + virtual + IHttpRequest * + GetRequest( + VOID + ) = 0; + + virtual + IHttpResponse * + GetResponse( + VOID + ) = 0; + + virtual + BOOL + GetResponseHeadersSent( + VOID + ) const = 0; + + virtual + IHttpUser * + GetUser( + VOID + ) const = 0; + + virtual + IHttpModuleContextContainer * + GetModuleContextContainer( + VOID + ) = 0; + + virtual + VOID + IndicateCompletion( + IN REQUEST_NOTIFICATION_STATUS notificationStatus + ) = 0; + + virtual + HRESULT + PostCompletion( + IN DWORD cbBytes + ) = 0; + + virtual + VOID + DisableNotifications( + IN DWORD dwNotifications, + IN DWORD dwPostNotifications + ) = 0; + + virtual + BOOL + GetNextNotification( + IN REQUEST_NOTIFICATION_STATUS status, + OUT DWORD * pdwNotification, + OUT BOOL * pfIsPostNotification, + OUT CHttpModule ** ppModuleInfo, + OUT IHttpEventProvider ** ppRequestOutput + ) = 0; + + virtual + BOOL + GetIsLastNotification( + IN REQUEST_NOTIFICATION_STATUS status + ) = 0; + + virtual + HRESULT + ExecuteRequest( + IN BOOL fAsync, + IN IHttpContext * pHttpContext, + IN DWORD dwExecuteFlags, + IN IHttpUser * pHttpUser, + OUT BOOL * pfCompletionExpected = NULL + ) = 0; + + virtual + DWORD + GetExecuteFlags( + VOID + ) const = 0; + + virtual + HRESULT + GetServerVariable( + PCSTR pszVariableName, + __deref_out_ecount(*pcchValueLength) PCWSTR * ppszValue, + __out DWORD * pcchValueLength + ) = 0; + + virtual + HRESULT + GetServerVariable( + PCSTR pszVariableName, + __deref_out_ecount(*pcchValueLength) PCSTR * ppszValue, + __out DWORD * pcchValueLength + ) = 0; + + virtual + HRESULT + SetServerVariable( + PCSTR pszVariableName, + PCWSTR pszVariableValue + ) = 0; + + virtual + VOID * + AllocateRequestMemory( + IN DWORD cbAllocation + ) = 0; + + virtual + IHttpUrlInfo * + GetUrlInfo( + VOID + ) = 0; + + virtual + IMetadataInfo * + GetMetadata( + VOID + ) = 0; + + virtual + PCWSTR + GetPhysicalPath( + OUT DWORD * pcchPhysicalPath = NULL + ) = 0; + + virtual + PCWSTR + GetScriptName( + OUT DWORD * pcchScriptName = NULL + ) const = 0; + + virtual + PCWSTR + GetScriptTranslated( + OUT DWORD * pcchScriptTranslated = NULL + ) = 0; + + virtual + IScriptMapInfo * + GetScriptMap( + VOID + ) const = 0; + + virtual + VOID + SetRequestHandled( + VOID + ) = 0; + + virtual + IHttpFileInfo * + GetFileInfo( + VOID + ) const = 0; + + virtual + HRESULT + MapPath( + PCWSTR pszUrl, + __out_bcount_opt(*pcbPhysicalPath) PWSTR pszPhysicalPath, + IN OUT DWORD * pcbPhysicalPath + ) = 0; + + virtual + HRESULT + NotifyCustomNotification( + ICustomNotificationProvider * pCustomOutput, + OUT BOOL * pfCompletionExpected + ) = 0; + + virtual + IHttpContext * + GetParentContext( + VOID + ) const = 0; + + virtual + IHttpContext * + GetRootContext( + VOID + ) const = 0; + + virtual + HRESULT + CloneContext( + IN DWORD dwCloneFlags, + OUT IHttpContext ** ppHttpContext + ) = 0; + + virtual + HRESULT + ReleaseClonedContext( + VOID + ) = 0; + + virtual + HRESULT + GetCurrentExecutionStats( + OUT DWORD * pdwNotification, + OUT DWORD * pdwNotificationStartTickCount = NULL, + OUT PCWSTR * ppszModule = NULL, + OUT DWORD * pdwModuleStartTickCount = NULL, + OUT DWORD * pdwAsyncNotification = NULL, + OUT DWORD * pdwAsyncNotificationStartTickCount = NULL + ) const = 0; + + virtual + IHttpTraceContext * + GetTraceContext( + VOID + ) const = 0; + + virtual + HRESULT + GetServerVarChanges( + IN DWORD dwOldChangeNumber, + OUT DWORD * pdwNewChangeNumber, + IN OUT DWORD * pdwVariableSnapshot, + IN OUT PCSTR ** ppVariableNameSnapshot, + IN OUT PCWSTR ** ppVariableValueSnapshot, + OUT DWORD * pdwDiffedVariables, + OUT DWORD ** ppDiffedVariableIndices + ) = 0; + + virtual + HRESULT + CancelIo( + VOID + ) = 0; + + virtual + HRESULT + MapHandler( + IN DWORD dwSiteId, + IN PCWSTR pszSiteName, + IN PCWSTR pszUrl, + IN PCSTR pszVerb, + OUT IScriptMapInfo ** ppScriptMap, + IN BOOL fIgnoreWildcardMappings = FALSE + ) = 0; + + __declspec(deprecated("This method is deprecated. Use the HttpGetExtendedInterface helper function instead.")) + virtual + HRESULT + GetExtendedInterface( + IN HTTP_CONTEXT_INTERFACE_VERSION version, + OUT PVOID * ppInterface + ) = 0; +}; + +class __declspec(uuid("9f9098d5-915c-4294-a52e-66532a232bc9")) +IHttpTraceContext +{ +public: + virtual + HRESULT + GetTraceConfiguration( + IN OUT HTTP_TRACE_CONFIGURATION * pHttpTraceConfiguration + ) = 0; + + virtual + HRESULT + SetTraceConfiguration( + IN HTTP_MODULE_ID moduleId, + IN HTTP_TRACE_CONFIGURATION * pHttpTraceConfiguration, + IN DWORD cHttpTraceConfiguration = 1 + ) = 0; + + virtual + HRESULT + RaiseTraceEvent( + IN HTTP_TRACE_EVENT * pTraceEvent + ) = 0; + + virtual + LPCGUID + GetTraceActivityId( + ) = 0; + + virtual + HRESULT + QuickTrace( + IN PCWSTR pszData1, + IN PCWSTR pszData2 = NULL, + IN HRESULT hrLastError = S_OK, + // + // 4 == TRACE_LEVEL_INFORMATION + // + IN UCHAR Level = 4 + ) = 0; +}; + +class __declspec(uuid("37776aff-852e-4eec-93a5-b85a285a95b8")) +IHttpCacheSpecificData; + +// +// Cache helpers +// +class __declspec(uuid("cdef2aad-20b3-4512-b1b1-094b3844aeb2")) +IHttpCacheKey +{ + public: + virtual + DWORD + GetHash( + VOID + ) const = 0; + + virtual + PCWSTR + GetCacheName( + VOID + ) const = 0; + + virtual + bool + GetIsEqual( + IHttpCacheKey * pCacheCompareKey + ) const = 0; + + virtual + bool + GetIsPrefix( + IHttpCacheKey * pCacheCompareKey + ) const = 0; + + virtual + VOID + Enum( + IHttpCacheSpecificData * + ) = 0; +}; + +class __declspec(uuid("37776aff-852e-4eec-93a5-b85a285a95b8")) +IHttpCacheSpecificData +{ + public: + virtual + IHttpCacheKey * + GetCacheKey( + VOID + ) const = 0; + + virtual + VOID + ReferenceCacheData( + VOID + ) = 0; + + virtual + VOID + DereferenceCacheData( + VOID + ) = 0; + + virtual + VOID + ResetTTL( + VOID + ) = 0; + + virtual + VOID + DecrementTTL( + OUT BOOL *pfTTLExpired + ) = 0; + + virtual + VOID + SetFlushed( + VOID + ) = 0; + + virtual + BOOL + GetFlushed( + VOID + ) const = 0; +}; + +// +// Site descriptor +// +class __declspec(uuid("eb16a6ec-ba5d-436f-bf24-3ede13906450")) +IHttpSite +{ + public: + virtual + DWORD + GetSiteId( + VOID + ) const = 0; + + virtual + PCWSTR + GetSiteName( + VOID + ) const = 0; + + virtual + IHttpModuleContextContainer * + GetModuleContextContainer( + VOID + ) = 0; + + virtual + IHttpPerfCounterInfo * + GetPerfCounterInfo( + VOID + ) = 0; +}; + +// +// File change monitor +// +// +class __declspec(uuid("985422da-b0cf-473b-ba9e-8148ceb3e240")) +IHttpFileMonitor +{ + public: + virtual + IHttpModuleContextContainer * + GetModuleContextContainer( + VOID + ) = 0; + + virtual + VOID + DereferenceFileMonitor( + VOID + ) = 0; +}; + +// +// File descriptor +// +// +class __declspec(uuid("71e95595-8c74-44d9-88a9-f5112d5f5900")) +IHttpFileInfo : public IHttpCacheSpecificData +{ + public: + virtual + DWORD + GetAttributes( + VOID + ) const = 0; + + virtual + VOID + GetSize( + OUT ULARGE_INTEGER * pliSize + ) const = 0; + + virtual + const BYTE * + GetFileBuffer( + VOID + ) const = 0; + + virtual + HANDLE + GetFileHandle( + VOID + ) const = 0; + + virtual + PCWSTR + GetFilePath( + VOID + ) const = 0; + + virtual + PCSTR + GetETag( + OUT USHORT * pcchETag = NULL + ) const = 0; + + virtual + VOID + GetLastModifiedTime( + OUT FILETIME * pFileTime + ) const = 0; + + virtual + PCSTR + GetLastModifiedString( + VOID + ) const = 0; + + virtual + BOOL + GetHttpCacheAllowed( + OUT DWORD * pSecondsToLive + ) const = 0; + + virtual + HRESULT + AccessCheck( + IN HANDLE hUserToken, + IN PSID pUserSid + ) = 0; + + virtual + HANDLE + GetVrToken( + VOID + ) const = 0; + + virtual + PCWSTR + GetVrPath( + VOID + ) const = 0; + + virtual + IHttpModuleContextContainer * + GetModuleContextContainer( + VOID + ) = 0; + + virtual + BOOL + CheckIfFileHasChanged( + IN HANDLE hUserToken + ) = 0; +}; + + +// +// Token-cache entry +// +class __declspec(uuid("fd86e6de-fb0e-47dd-820a-e0da12be46e9")) +IHttpTokenEntry : public IHttpCacheSpecificData +{ + public: + virtual + HANDLE + GetImpersonationToken( + VOID + ) = 0; + + virtual + HANDLE + GetPrimaryToken( + VOID + ) = 0; + + virtual + PSID + GetSid( + VOID + ) = 0; +}; + + +// +// IHttpServer extended interface versions +// +enum HTTP_SERVER_INTERFACE_VERSION +{ + HTTP_SERVER_INTERFACE_V2 +}; + + +// +// Global utility descriptor +// +class __declspec(uuid("eda2a40f-fb92-4d6d-b52b-c8c207380b4e")) +IHttpServer +{ + public: + virtual + BOOL + IsCommandLineLaunch( + VOID + ) const = 0; + + virtual + PCWSTR + GetAppPoolName( + VOID + ) const = 0; + + virtual + HRESULT + AssociateWithThreadPool( + IN HANDLE hHandle, + IN LPOVERLAPPED_COMPLETION_ROUTINE completionRoutine + ) = 0; + + virtual + VOID + IncrementThreadCount( + VOID + ) = 0; + + virtual + VOID + DecrementThreadCount( + VOID + ) = 0; + + virtual + VOID + ReportUnhealthy( + IN PCWSTR pszReasonString, + IN HRESULT hrReason + ) = 0; + + virtual + VOID + RecycleProcess( + PCWSTR pszReason + ) = 0; + + virtual + IAppHostAdminManager * + GetAdminManager( + VOID + ) const = 0; + + virtual + HRESULT + GetFileInfo( + IN PCWSTR pszPhysicalPath, + IN HANDLE hUserToken, + IN PSID pSid, + IN PCWSTR pszChangeNotificationPath, + IN HANDLE hChangeNotificationToken, + IN BOOL fCache, + OUT IHttpFileInfo ** ppFileInfo, + IN IHttpTraceContext * pHttpTraceContext = NULL + ) = 0; + + virtual + HRESULT + FlushKernelCache( + IN PCWSTR pszUrl + ) = 0; + + virtual + HRESULT + DoCacheOperation( + IN CACHE_OPERATION cacheOperation, + IN IHttpCacheKey * pCacheKey, + OUT IHttpCacheSpecificData ** ppCacheSpecificData, + IN IHttpTraceContext * pHttpTraceContext = NULL + ) = 0; + + virtual + GLOBAL_NOTIFICATION_STATUS + NotifyCustomNotification( + ICustomNotificationProvider * pCustomOutput + ) = 0; + + virtual + IHttpPerfCounterInfo * + GetPerfCounterInfo( + VOID + ) = 0; + + virtual + VOID + RecycleApplication( + PCWSTR pszAppConfigPath + ) = 0; + + virtual + VOID + NotifyConfigurationChange( + PCWSTR pszPath + ) = 0; + + virtual + VOID + NotifyFileChange( + PCWSTR pszFileName + ) = 0; + + virtual + IDispensedHttpModuleContextContainer * + DispenseContainer( + VOID + ) = 0; + + virtual + HRESULT + AddFragmentToCache( + IN HTTP_DATA_CHUNK * pDataChunk, + PCWSTR pszFragmentName + ) = 0; + + virtual + HRESULT + ReadFragmentFromCache( + PCWSTR pszFragmentName, + OUT BYTE * pvBuffer, + DWORD cbSize, + OUT DWORD * pcbCopied + ) = 0; + + virtual + HRESULT + RemoveFragmentFromCache( + PCWSTR pszFragmentName + ) = 0; + + virtual + HRESULT + GetWorkerProcessSettings( + OUT IWpfSettings ** ppWorkerProcessSettings + ) = 0; + + virtual + HRESULT + GetProtocolManagerCustomInterface( + IN PCWSTR pProtocolManagerDll, + IN PCWSTR pProtocolManagerDllInitFunction, + IN DWORD dwCustomInterfaceId, + OUT PVOID* ppCustomInterface + ) = 0; + + virtual + BOOL + SatisfiesPrecondition( + PCWSTR pszPrecondition, + BOOL * pfUnknownPrecondition = NULL + ) const = 0; + + virtual + IHttpTraceContext * + GetTraceContext( + VOID + ) const = 0; + + virtual + HRESULT + RegisterFileChangeMonitor( + PCWSTR pszPath, + HANDLE hToken, + IHttpFileMonitor ** ppFileMonitor + ) = 0; + + virtual + HRESULT + GetExtendedInterface( + IN HTTP_SERVER_INTERFACE_VERSION version, + OUT PVOID * ppInterface + ) = 0; +}; + +class __declspec(uuid("34af637e-afe8-4556-bcc1-767f8e0b4a4e")) +IHttpServer2 : public IHttpServer +{ + public: + + virtual + HRESULT + GetToken( + PCWSTR pszUserName, + PCWSTR pszPassword, + DWORD dwLogonMethod, + IHttpTokenEntry ** ppTokenEntry, + PCWSTR pszDefaultDomain = NULL, + PSOCKADDR pSockAddr = NULL, + IHttpTraceContext * pHttpTraceContext = NULL + ) = 0; + + virtual + PCWSTR + GetAppPoolConfigFile( + __out DWORD * pcchConfigFilePath = NULL + ) const = 0; + + virtual + HRESULT + GetExtendedInterface( + __in const GUID & Version1, + __in PVOID pInput, + __in const GUID & Version2, + __deref_out PVOID * ppOutput + ) = 0; +}; + +// +// Helper function to get extended HTTP interfaces. +// +// Template parameters (HttpType1 and HttpType2) +// can be deduced from the arguments to the function. +// +// Example: +// +// IHttpRequest * pHttpRequest = pHttpContext->GetRequest(); +// IHttpRequest2 * pHttpRequest2; +// HRESULT hr = HttpGetExtendedInterface(g_pHttpServer, pHttpRequest, &pHttpRequest2); +// if( SUCCEEDED(hr) ) +// { +// // Use pHttpRequest2. +// } +// +// Where pHttpContext is an IHttpContext pointer and +// g_pHttpServer is an IHttpServer pointer. +// + +template +HRESULT +HttpGetExtendedInterface( + __in IHttpServer * pHttpServer, + __in HttpType1 * pInput, + __deref_out HttpType2 ** ppOutput +) +{ + HRESULT hr; + IHttpServer2 * pHttpServer2; + hr = pHttpServer->GetExtendedInterface(HTTP_SERVER_INTERFACE_V2, + reinterpret_cast(&pHttpServer2) ); + if (SUCCEEDED(hr)) + { + hr = pHttpServer2->GetExtendedInterface(__uuidof(HttpType1), + pInput, + __uuidof(HttpType2), + reinterpret_cast(ppOutput) ); + } + return hr; +} + +// +// Notification specific output for notifications +// +class __declspec(uuid("6f3f657d-2fb8-43c6-a096-5064b41f0580")) +IHttpEventProvider +{ + public: + virtual + VOID + SetErrorStatus( + HRESULT hrError + ) = 0; +}; + +// +// Completion information for notifications +// +class __declspec(uuid("49dd20e3-d9c0-463c-8821-f3413b55cc00")) +IHttpCompletionInfo +{ + public: + virtual + DWORD + GetCompletionBytes( + VOID + ) const = 0; + + virtual + HRESULT + GetCompletionStatus( + VOID + ) const = 0; +}; + +// +// RQ_ and GL_ CUSTOM_NOTIFICATION outputs +// +class __declspec(uuid("671e6d34-9380-4df4-b453-91129df02b24")) +ICustomNotificationProvider : public IHttpEventProvider +{ + public: + virtual + PCWSTR + QueryNotificationType( + VOID + ) = 0; +}; + +// +// RQ_REQUEST_AUTHENTICATE descriptor +// +class __declspec(uuid("304d51d0-0307-45ed-83fd-dd3fc032fdfc")) +IAuthenticationProvider : public IHttpEventProvider +{ + public: + virtual + VOID + SetUser( + IN IHttpUser * pUser + ) = 0; +}; + +// +// RQ_MAP_REQUEST_HANDLER +// +class __declspec(uuid("fea3ce6b-e346-47e7-b2a6-ad265baeff2c")) +IMapHandlerProvider : public IHttpEventProvider +{ + public: + virtual + HRESULT + SetScriptName( + PCWSTR pszScriptName, + DWORD cchScriptName + ) = 0; + + virtual + VOID + SetScriptMap( + IN IScriptMapInfo * pScriptMap + ) = 0; + + virtual + VOID + SetFileInfo( + IN IHttpFileInfo * pFileInfo + ) = 0; +}; + +// +// RQ_MAP_PATH +// +class __declspec(uuid("8efdf557-a8f1-4bc9-b462-6df3b038a59a")) +IMapPathProvider : public IHttpEventProvider +{ + public: + virtual + PCWSTR + GetUrl( + ) const = 0; + + virtual + PCWSTR + GetPhysicalPath( + ) const = 0; + + virtual + HRESULT + SetPhysicalPath( + PCWSTR pszPhysicalPath, + DWORD cchPhysicalPath + ) = 0; +}; + +// +// RQ_SEND_RESPONSE +// +class __declspec(uuid("57f2e7bc-0bcf-4a9f-94a4-10e55c6e5b51")) +ISendResponseProvider : public IHttpEventProvider +{ + public: + virtual + BOOL + GetHeadersBeingSent( + VOID + ) const = 0; + + virtual + DWORD + GetFlags( + VOID + ) const = 0; + + virtual + VOID + SetFlags( + DWORD dwFlags + ) = 0; + + virtual + HTTP_LOG_DATA * + GetLogData( + VOID + ) const = 0; + + virtual + HRESULT + SetLogData( + IN HTTP_LOG_DATA *pLogData + ) = 0; + + virtual + BOOL + GetReadyToLogData( + VOID + ) const = 0; +}; + +// +// RQ_READ_ENTITY +// +class __declspec(uuid("fe6d905a-99b8-49fd-b389-cfc809562b81")) +IReadEntityProvider : public IHttpEventProvider +{ + public: + virtual + VOID + GetEntity( + OUT PVOID * ppBuffer, + OUT DWORD * pcbData, + OUT DWORD * pcbBuffer + ) = 0; + + virtual + VOID + SetEntity( + IN PVOID pBuffer, + DWORD cbData, + DWORD cbBuffer + ) = 0; +}; + +// +// GL_PRE_BEGIN_REQUEST provider +// +class __declspec(uuid("fb715d26-aff9-476a-8fc0-6b1acb3d1098")) +IPreBeginRequestProvider : public IHttpEventProvider +{ + public: + virtual + IHttpContext * + GetHttpContext( + VOID + ) = 0; +}; + +// +// GL_APPLICATION_START provider +// +class __declspec(uuid("1de2c71c-c126-4512-aed3-f4f885e14997")) +IHttpApplicationProvider : public IHttpEventProvider +{ + public: + virtual + IHttpApplication * + GetApplication( + VOID + ) = 0; +}; + +typedef IHttpApplicationProvider IHttpApplicationStartProvider; + +class __declspec(uuid("ba32d330-9ea8-4b9e-89f1-8c76a323277f")) +IHttpModuleFactory; + +// +// GL_APPLICATION_RESOLVE_MODULES provider +// +class __declspec(uuid("0617d9b9-e20f-4a9f-94f9-35403b3be01e")) +IHttpApplicationResolveModulesProvider : public IHttpApplicationProvider +{ + public: + virtual + HRESULT + RegisterModule( + IN HTTP_MODULE_ID parentModuleId, + IN IHttpModuleFactory * pModuleFactory, + IN PCWSTR pszModuleName, + IN PCWSTR pszModuleType, + IN PCWSTR pszModulePreCondition, + IN DWORD dwRequestNotifications, + IN DWORD dwPostRequestNotifications + ) = 0; + + virtual + HRESULT + SetPriorityForRequestNotification( + IN PCWSTR pszModuleName, + IN DWORD dwRequestNotification, + IN PCWSTR pszPriorityAlias + ) = 0; +}; + +// +// GL_APPLICATION_STOP provider +// +typedef IHttpApplicationProvider IHttpApplicationStopProvider; + +// +// GL_RSCA_QUERY provider +// +class __declspec(uuid("63fdc43f-934a-4ee5-bcd8-7e7b50b75605")) +IGlobalRSCAQueryProvider : public IHttpEventProvider +{ + public: + virtual + PCWSTR + GetFunctionName( + VOID + ) const = 0; + + virtual + PCWSTR + GetFunctionParameters( + VOID + ) const = 0; + + virtual + HRESULT + GetOutputBuffer( + DWORD cbBuffer, + OUT BYTE ** ppbBuffer + ) = 0; + + virtual + HRESULT + ResizeOutputBuffer( + DWORD cbNewBuffer, + DWORD cbBytesToCopy, + IN OUT BYTE ** ppbBuffer + ) = 0; + + virtual + VOID + SetResult( + DWORD cbData, + HRESULT hr + ) = 0; +}; + +// +// GL_STOP_LISTENING +// +class __declspec(uuid("41f9a601-e25d-4ac8-8a1f-635698a30ab9")) +IGlobalStopListeningProvider : public IHttpEventProvider +{ + public: + virtual + BOOL + DrainRequestsGracefully( + VOID + ) const = 0; +}; + +// +// GL_CACHE_OPERATION +// +class __declspec(uuid("58925fb9-7c5e-4684-833b-4a04e1286690")) +ICacheProvider : public IHttpEventProvider +{ + public: + virtual + CACHE_OPERATION + GetCacheOperation( + VOID + ) const = 0; + + virtual + IHttpCacheKey * + GetCacheKey( + VOID + ) const = 0; + + virtual + IHttpCacheSpecificData * + GetCacheRecord( + VOID + ) const = 0; + + virtual + VOID + SetCacheRecord( + IHttpCacheSpecificData * pCacheRecord + ) = 0; + + virtual + IHttpTraceContext * + GetTraceContext( + VOID + ) const = 0; +}; + +// +// GL_CONFIGURATION_CHANGE +// +class __declspec(uuid("3405f3b4-b3d6-4b73-b5f5-4d8a3cc642ce")) +IGlobalConfigurationChangeProvider : public IHttpEventProvider +{ + public: + virtual + PCWSTR + GetChangePath( + VOID + ) const = 0; +}; + +// +// GL_FILE_CHANGE +// +class __declspec(uuid("ece31ee5-0486-4fb0-a875-6739a2d7daf5")) +IGlobalFileChangeProvider : public IHttpEventProvider +{ +public: + virtual + PCWSTR + GetFileName( + VOID + ) const = 0; + + virtual + IHttpFileMonitor * + GetFileMonitor( + VOID + ) = 0; +}; + +// +// GL_TRACE_EVENT +// +class __declspec(uuid("7c6bb150-0310-4718-a01f-6faceb62dc1d")) +IGlobalTraceEventProvider : public IHttpEventProvider +{ + public: + virtual + HRESULT + GetTraceEvent( + OUT HTTP_TRACE_EVENT ** ppTraceEvent + ) = 0; + + virtual + BOOL + CheckSubscription( + IN HTTP_MODULE_ID ModuleId + ) = 0; + + virtual + HRESULT + GetCurrentHttpRequestContext( + OUT IHttpContext ** ppHttpContext + ) = 0; +}; + +// +// GL_THREAD_CLEANUP +// +class __declspec(uuid("6b36a149-8620-45a0-8197-00814a706e2e")) +IGlobalThreadCleanupProvider : public IHttpEventProvider +{ +public: + virtual + IHttpApplication * + GetApplication( + VOID + ) = 0; +}; + +// +// GL_APPLICATION_PRELOAD +// +class __declspec(uuid("2111f8d6-0c41-4ff7-bd45-5c04c7e91a73")) +IGlobalApplicationPreloadProvider : public IHttpEventProvider +{ +public: + virtual + HRESULT + CreateContext( + OUT IHttpContext ** ppHttpContext + ) = 0; + + virtual + HRESULT + ExecuteRequest( + IN IHttpContext * pHttpContext, + IN IHttpUser * pHttpUser + ) = 0; +}; + +class CHttpModule +{ +public: + // RQ_BEGIN_REQUEST + + virtual + REQUEST_NOTIFICATION_STATUS + OnBeginRequest( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostBeginRequest( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + // RQ_AUTHENTICATE_REQUEST + + virtual + REQUEST_NOTIFICATION_STATUS + OnAuthenticateRequest( + IN IHttpContext * pHttpContext, + IN IAuthenticationProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostAuthenticateRequest( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + // RQ_AUTHORIZE_REQUEST + + virtual + REQUEST_NOTIFICATION_STATUS + OnAuthorizeRequest( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostAuthorizeRequest( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + // RQ_RESOLVE_REQUEST_CACHE + + virtual + REQUEST_NOTIFICATION_STATUS + OnResolveRequestCache( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostResolveRequestCache( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + // RQ_MAP_REQUEST_HANDLER + + virtual + REQUEST_NOTIFICATION_STATUS + OnMapRequestHandler( + IN IHttpContext * pHttpContext, + IN IMapHandlerProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostMapRequestHandler( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + // RQ_ACQUIRE_REQUEST_STATE + + virtual + REQUEST_NOTIFICATION_STATUS + OnAcquireRequestState( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostAcquireRequestState( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + // RQ_PRE_EXECUTE_REQUEST_HANDLER + + virtual + REQUEST_NOTIFICATION_STATUS + OnPreExecuteRequestHandler( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostPreExecuteRequestHandler( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + // RQ_EXECUTE_REQUEST_HANDLER + + virtual + REQUEST_NOTIFICATION_STATUS + OnExecuteRequestHandler( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostExecuteRequestHandler( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + // RQ_RELEASE_REQUEST_STATE + + virtual + REQUEST_NOTIFICATION_STATUS + OnReleaseRequestState( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostReleaseRequestState( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + // RQ_UPDATE_REQUEST_CACHE + + virtual + REQUEST_NOTIFICATION_STATUS + OnUpdateRequestCache( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostUpdateRequestCache( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + // RQ_LOG_REQUEST + + virtual + REQUEST_NOTIFICATION_STATUS + OnLogRequest( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostLogRequest( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + // RQ_END_REQUEST + + virtual + REQUEST_NOTIFICATION_STATUS + OnEndRequest( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + virtual + REQUEST_NOTIFICATION_STATUS + OnPostEndRequest( + IN IHttpContext * pHttpContext, + IN IHttpEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + // RQ_SEND_RESPONSE + + virtual + REQUEST_NOTIFICATION_STATUS + OnSendResponse( + IN IHttpContext * pHttpContext, + IN ISendResponseProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + // RQ_MAP_PATH + + virtual + REQUEST_NOTIFICATION_STATUS + OnMapPath( + IN IHttpContext * pHttpContext, + IN IMapPathProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + // RQ_READ_ENTITY + + virtual + REQUEST_NOTIFICATION_STATUS + OnReadEntity( + IN IHttpContext * pHttpContext, + IN IReadEntityProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + // RQ_CUSTOM_NOTIFICATION + + virtual + REQUEST_NOTIFICATION_STATUS + OnCustomRequestNotification( + IN IHttpContext * pHttpContext, + IN ICustomNotificationProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + // Completion + + virtual + REQUEST_NOTIFICATION_STATUS + OnAsyncCompletion( + IN IHttpContext * pHttpContext, + IN DWORD dwNotification, + IN BOOL fPostNotification, + IN IHttpEventProvider * pProvider, + IN IHttpCompletionInfo * pCompletionInfo + ) + { + UNREFERENCED_PARAMETER( pHttpContext ); + UNREFERENCED_PARAMETER( dwNotification ); + UNREFERENCED_PARAMETER( fPostNotification ); + UNREFERENCED_PARAMETER( pProvider ); + UNREFERENCED_PARAMETER( pCompletionInfo ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CHttpModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return RQ_NOTIFICATION_CONTINUE; + } + + virtual + VOID + Dispose( + VOID + ) + { + delete this; + } + + protected: + + CHttpModule() + {} + + virtual + ~CHttpModule() + {} +}; + +class CGlobalModule +{ + public: + + // GL_STOP_LISTENING + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalStopListening( + IN IGlobalStopListeningProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_CACHE_CLEANUP + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalCacheCleanup( + VOID + ) + { + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_CACHE_OPERATION + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalCacheOperation( + IN ICacheProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_HEALTH_CHECK + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalHealthCheck( + VOID + ) + { + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_CONFIGURATION_CHANGE + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalConfigurationChange( + IN IGlobalConfigurationChangeProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_FILE_CHANGE + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalFileChange( + IN IGlobalFileChangeProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_PRE_BEGIN_REQUEST + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalPreBeginRequest( + IN IPreBeginRequestProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_APPLICATION_START + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalApplicationStart( + IN IHttpApplicationStartProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_APPLICATION_RESOLVE_MODULES + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalApplicationResolveModules( + IN IHttpApplicationResolveModulesProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_APPLICATION_STOP + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalApplicationStop( + IN IHttpApplicationStopProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_RSCA_QUERY + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalRSCAQuery( + IN IGlobalRSCAQueryProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_TRACE_EVENT + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalTraceEvent( + IN IGlobalTraceEventProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_CUSTOM_NOTIFICATION + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalCustomNotification( + IN ICustomNotificationProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + virtual + VOID + Terminate( + VOID + ) = 0; + + // GL_THREAD_CLEANUP + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalThreadCleanup( + IN IGlobalThreadCleanupProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + + // GL_APPLICATION_PRELOAD + + virtual + GLOBAL_NOTIFICATION_STATUS + OnGlobalApplicationPreload( + IN IGlobalApplicationPreloadProvider * pProvider + ) + { + UNREFERENCED_PARAMETER( pProvider ); + OutputDebugStringA( + "This module subscribed to event " + __FUNCTION__ + " but did not override the method in its CGlobalModule implementation." + " Please check the method signature to make sure it matches the corresponding method.\n"); + DebugBreak(); + + return GL_NOTIFICATION_CONTINUE; + } + +}; + +class __declspec(uuid("85c1679c-0b21-491c-afb5-c7b5c86464c4")) +IModuleAllocator +{ + public: + virtual + VOID * + AllocateMemory( + IN DWORD cbAllocation + ) = 0; +}; + +class __declspec(uuid("ba32d330-9ea8-4b9e-89f1-8c76a323277f")) +IHttpModuleFactory +{ + public: + virtual + HRESULT + GetHttpModule( + OUT CHttpModule ** ppModule, + IN IModuleAllocator * pAllocator + ) = 0; + + virtual + VOID + Terminate( + VOID + ) = 0; +}; + +// +// Register-module descriptor +// +class __declspec(uuid("07e5beb3-b798-459d-a98a-e6c485b2b3bc")) +IHttpModuleRegistrationInfo +{ + public: + virtual + PCWSTR + GetName( + VOID + ) const = 0; + + virtual + HTTP_MODULE_ID + GetId( + VOID + ) const = 0; + + virtual + HRESULT + SetRequestNotifications( + IN IHttpModuleFactory * pModuleFactory, + IN DWORD dwRequestNotifications, + IN DWORD dwPostRequestNotifications + ) = 0; + + virtual + HRESULT + SetGlobalNotifications( + IN CGlobalModule * pGlobalModule, + IN DWORD dwGlobalNotifications + ) = 0; + + virtual + HRESULT + SetPriorityForRequestNotification( + IN DWORD dwRequestNotification, + IN PCWSTR pszPriority + ) = 0; + + virtual + HRESULT + SetPriorityForGlobalNotification( + IN DWORD dwGlobalNotification, + IN PCWSTR pszPriority + ) = 0; +}; + + +// +// Register Module entry point +// + +typedef +HRESULT +(WINAPI * PFN_REGISTERMODULE)( + DWORD dwServerVersion, + IHttpModuleRegistrationInfo * pModuleInfo, + IHttpServer * pGlobalInfo +); + +#define MODULE_REGISTERMODULE "RegisterModule" + +#endif diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/hybrid_array.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/hybrid_array.h new file mode 100644 index 0000000000..4d0d5735bc --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/hybrid_array.h @@ -0,0 +1,243 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +template +class HYBRID_ARRAY +{ +public: + + HYBRID_ARRAY( + VOID + ) : m_pArray(m_InlineArray), + m_Capacity(ARRAYSIZE(m_InlineArray)) + { + } + + ~HYBRID_ARRAY() + { + if ( !QueryUsesInlineArray() ) + { + delete [] m_pArray; + m_pArray = NULL; + } + } + + SIZE_T + QueryCapacity( + VOID + ) const + { + // + // Number of elements available in the array. + // + return m_Capacity; + } + + TYPE * + QueryArray( + VOID + ) const + { + // + // Raw pointer to the current array. + // + return m_pArray; + } + + TYPE & + QueryItem( + __in const SIZE_T Index + ) + { + // + // Gets the array item giving the index. + // + return m_pArray[Index]; + } + + TYPE & + operator [] (const SIZE_T Index) + { + // + // Operator override for convenience. + // Please don't add other overloads like '++' '--' + // in order to keep it simple. + // + return m_pArray[Index]; + } + + const TYPE & + operator [] (const SIZE_T Index) const + { + return m_pArray[Index]; + } + + template + HRESULT + Copy( + __in TYPE const (&SourceArray)[SourceSize], + __in bool fHasTrivialAssign = false + ) + /*++ + + Routine Description: + + Copies a source array like: + + int source[] = { 1, 2, 3 }; + hr = hybridArray.Copy( source ); + + It will statically determinate the length of the source array. + + Arguments: + + SourceArray - The array to copy. + SourceSize - The number of array elements. + fHasTrivialAssign - True if safe to perform buffer copy. + + Return Value: + + HRESULT + + --*/ + { + return Copy( SourceArray, SourceSize, fHasTrivialAssign ); + } + + HRESULT + Copy( + __in_ecount(SourceSize) + const TYPE * pSourceArray, + __in const SIZE_T SourceSize, + __in bool fHasTrivialAssign = false + ) + /*++ + + Routine Description: + + Copies a source array. + + Arguments: + + pSourceArray - The array to copy. + SourceSize - The number of array elements. + fHasTrivialAssign - True if safe to perform buffer copy. + + Return Value: + + HRESULT + + --*/ + { + HRESULT hr; + + hr = EnsureCapacity( SourceSize, + FALSE, // fCopyPrevious + FALSE ); // fHasTrivialAssign + if ( FAILED( hr ) ) + { + return hr; + } + + if ( fHasTrivialAssign ) // Future Work: use std::tr1::has_trivial_assign + { + CopyMemory(m_pArray, pSourceArray, m_Capacity * sizeof(TYPE)); + } + else + { + for ( SIZE_T Index = 0; Index < SourceSize; ++Index ) + { + m_pArray[Index] = pSourceArray[Index]; + } + } + + return S_OK; + } + + HRESULT + EnsureCapacity( + __in const SIZE_T MinimumCapacity, + __in bool fCopyPrevious, + __in bool fHasTrivialAssign = false + ) + /*++ + + Routine Description: + + Copies a source array. + + Arguments: + + MinimumCapacity - The expected length of the array. + fCopyPrevious - Must be always explicit parameter. + True if copy previous array data. + fHasTrivialAssign - True if safe to perform buffer copy. + + Return Value: + + HRESULT + + --*/ + { + // + // Caller is responsible for calculating a length that won't cause + // too many reallocations in the future. + // + + if ( MinimumCapacity <= ARRAYSIZE(m_InlineArray) ) + { + return S_OK; + } + + TYPE * pNewArray; + + pNewArray = new TYPE[ MinimumCapacity ]; + if ( pNewArray == NULL ) + { + return E_OUTOFMEMORY; + } + + if ( fCopyPrevious ) + { + if ( fHasTrivialAssign ) + { + CopyMemory(pNewArray, m_pArray, m_Capacity * sizeof(TYPE)); + } + else + { + for ( SIZE_T Index = 0; Index < m_Capacity; ++Index ) + { + pNewArray[Index] = m_pArray[Index]; + } + } + } + + if ( QueryUsesInlineArray() ) + { + m_pArray = pNewArray; + } + else + { + delete [] m_pArray; + m_pArray = pNewArray; + } + + m_Capacity = MinimumCapacity; + + return S_OK; + } + +private: + + bool + QueryUsesInlineArray( + VOID + ) const + { + return m_pArray == m_InlineArray; + } + + TYPE m_InlineArray[SIZE]; + TYPE * m_pArray; + SIZE_T m_Capacity; +}; \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/listentry.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/listentry.h new file mode 100644 index 0000000000..04c1d1ab46 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/listentry.h @@ -0,0 +1,163 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#ifndef _LIST_ENTRY_H +#define _LIST_ENTRY_H + +// +// Doubly-linked list manipulation routines. +// + + +#define InitializeListHead32(ListHead) (\ + (ListHead)->Flink = (ListHead)->Blink = PtrToUlong((ListHead))) + + +FORCEINLINE +VOID +InitializeListHead( + IN PLIST_ENTRY ListHead + ) +{ + ListHead->Flink = ListHead->Blink = ListHead; +} + +FORCEINLINE +BOOLEAN +IsListEmpty( + IN const LIST_ENTRY * ListHead + ) +{ + return (BOOLEAN)(ListHead->Flink == ListHead); +} + +FORCEINLINE +BOOLEAN +RemoveEntryList( + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Blink; + PLIST_ENTRY Flink; + + Flink = Entry->Flink; + Blink = Entry->Blink; + Blink->Flink = Flink; + Flink->Blink = Blink; + return (BOOLEAN)(Flink == Blink); +} + +FORCEINLINE +PLIST_ENTRY +RemoveHeadList( + IN PLIST_ENTRY ListHead + ) +{ + PLIST_ENTRY Flink; + PLIST_ENTRY Entry; + + Entry = ListHead->Flink; + Flink = Entry->Flink; + ListHead->Flink = Flink; + Flink->Blink = ListHead; + return Entry; +} + + + +FORCEINLINE +PLIST_ENTRY +RemoveTailList( + IN PLIST_ENTRY ListHead + ) +{ + PLIST_ENTRY Blink; + PLIST_ENTRY Entry; + + Entry = ListHead->Blink; + Blink = Entry->Blink; + ListHead->Blink = Blink; + Blink->Flink = ListHead; + return Entry; +} + + +FORCEINLINE +VOID +InsertTailList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Blink; + + Blink = ListHead->Blink; + Entry->Flink = ListHead; + Entry->Blink = Blink; + Blink->Flink = Entry; + ListHead->Blink = Entry; +} + + +FORCEINLINE +VOID +InsertHeadList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Flink; + + Flink = ListHead->Flink; + Entry->Flink = Flink; + Entry->Blink = ListHead; + Flink->Blink = Entry; + ListHead->Flink = Entry; +} + +FORCEINLINE +VOID +AppendTailList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY ListToAppend + ) +{ + PLIST_ENTRY ListEnd = ListHead->Blink; + + ListHead->Blink->Flink = ListToAppend; + ListHead->Blink = ListToAppend->Blink; + ListToAppend->Blink->Flink = ListHead; + ListToAppend->Blink = ListEnd; +} + +FORCEINLINE +PSINGLE_LIST_ENTRY +PopEntryList( + PSINGLE_LIST_ENTRY ListHead + ) +{ + PSINGLE_LIST_ENTRY FirstEntry; + FirstEntry = ListHead->Next; + if (FirstEntry != NULL) { + ListHead->Next = FirstEntry->Next; + } + + return FirstEntry; +} + + +FORCEINLINE +VOID +PushEntryList( + PSINGLE_LIST_ENTRY ListHead, + PSINGLE_LIST_ENTRY Entry + ) +{ + Entry->Next = ListHead->Next; + ListHead->Next = Entry; +} + + +#endif diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/macros.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/macros.h new file mode 100644 index 0000000000..56a67eb1c4 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/macros.h @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _MACROS_H +#define _MACROS_H + +// +// The DIFF macro should be used around an expression involving pointer +// subtraction. The expression passed to DIFF is cast to a size_t type, +// allowing the result to be easily assigned to any 32-bit variable or +// passed to a function expecting a 32-bit argument. +// + +#define DIFF(x) ((size_t)(x)) + +// Change a hexadecimal digit to its numerical equivalent +#define TOHEX( ch ) \ + ((ch) > L'9' ? \ + (ch) >= L'a' ? \ + (ch) - L'a' + 10 : \ + (ch) - L'A' + 10 \ + : (ch) - L'0') + + +// Change a number to its Hexadecimal equivalent + +#define TODIGIT( nDigit ) \ + (CHAR)((nDigit) > 9 ? \ + (nDigit) - 10 + 'A' \ + : (nDigit) + '0') + + +inline int +SAFEIsSpace(UCHAR c) +{ + return isspace( c ); +} + +inline int +SAFEIsAlNum(UCHAR c) +{ + return isalnum( c ); +} + +inline int +SAFEIsAlpha(UCHAR c) +{ + return isalpha( c ); +} + +inline int +SAFEIsXDigit(UCHAR c) +{ + return isxdigit( c ); +} + +inline int +SAFEIsDigit(UCHAR c) +{ + return isdigit( c ); +} + +#endif // _MACROS_H diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/multisz.hxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/multisz.hxx new file mode 100644 index 0000000000..dd891b3252 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/multisz.hxx @@ -0,0 +1,225 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _MULTISZ_HXX_ +#define _MULTISZ_HXX_ + +# include + + +/*++ + class MULTISZ: + + Intention: + A light-weight multi-string class supporting encapsulated string class. + + This object is derived from BUFFER class. + It maintains following state: + + m_fValid - whether this object is valid - + used only by MULTISZ() init functions + * NYI: I need to kill this someday * + m_cchLen - string length cached when we update the string. + m_cStrings - number of strings. + + Member Functions: + There are two categories of functions: + 1) Safe Functions - which do integrity checking of state + 2) UnSafe Functions - which do not do integrity checking, but + enable writing to the data stream freely. + (someday this will be enabled as Safe versions without + problem for users) + +--*/ +class MULTISZ : public BUFFER +{ +public: + + MULTISZ() + : BUFFER (), + m_cchLen ( 0), + m_cStrings(0) + { Reset(); } + + // creates a stack version of the MULTISZ object - uses passed in stack buffer + // MULTISZ does not free this pbInit on its own. + MULTISZ( __in_bcount(cbInit) WCHAR * pbInit, DWORD cbInit) + : BUFFER( (BYTE *) pbInit, cbInit), + m_cchLen (0), + m_cStrings(0) + {} + + MULTISZ( const WCHAR * pchInit ) + : BUFFER (), + m_cchLen ( 0), + m_cStrings(0) + { AuxInit(pchInit); } + + MULTISZ( const MULTISZ & str ) + : BUFFER (), + m_cchLen ( 0), + m_cStrings(0) + { AuxInit( str.QueryStr()); } + +// BOOL IsValid(VOID) const { return ( BUFFER::IsValid()) ; } + // + // Checks and returns TRUE if this string has no valid data else FALSE + // + BOOL IsEmpty( VOID) const { return ( *QueryStr() == L'\0'); } + + BOOL Append( const WCHAR * pchInit ) { + return ((pchInit != NULL) ? (AuxAppend( pchInit, + (DWORD) (::wcslen(pchInit)) * sizeof(WCHAR) + )) : + TRUE); + } + + + BOOL Append( const WCHAR * pchInit, DWORD cchLen ) { + return ((pchInit != NULL) ? (AuxAppend( pchInit, + cchLen * sizeof(WCHAR))) : + TRUE); + } + + BOOL Append( STRU & str ) + { return AuxAppend( str.QueryStr(), + (str.QueryCCH()) * sizeof(WCHAR)); } + + // Resets the internal string to be NULL string. Buffer remains cached. + VOID Reset( VOID) + { DBG_ASSERT( QueryPtr() != NULL); + QueryStr()[0] = L'\0'; + QueryStr()[1] = L'\0'; + m_cchLen = 2; + m_cStrings = 0; + } + + BOOL Copy( const WCHAR * pchInit, IN DWORD cbLen ) { + if ( QueryPtr() ) { Reset(); } + return ( (pchInit != NULL) ? + AuxAppend( pchInit, cbLen, FALSE ): + TRUE); + } + + BOOL Copy( const MULTISZ & str ) + { return ( Copy(str.QueryStr(), str.QueryCB())); } + + // + // Returns the number of bytes in the string including the terminating + // NULLs + // + UINT QueryCB( VOID ) const + { return ( m_cchLen * sizeof(WCHAR)); } + + // + // Returns # of characters in the string including the terminating NULLs + // + UINT QueryCCH( VOID ) const { return (m_cchLen); } + + // + // Returns # of strings in the multisz. + // + + DWORD QueryStringCount( VOID ) const { return m_cStrings; } + + // + // Makes a copy of the stored string in given buffer + // + BOOL CopyToBuffer( __out_ecount_opt(*lpcch) WCHAR * lpszBuffer, LPDWORD lpcch) const; + + // + // Return the string buffer + // + WCHAR * QueryStrA( VOID ) const { return ( QueryStr()); } + WCHAR * QueryStr( VOID ) const { return ((WCHAR *) QueryPtr()); } + + // + // Makes a clone of the current string in the string pointer passed in. + // + BOOL + Clone( OUT MULTISZ * pstrClone) const + { + return ((pstrClone == NULL) ? + (SetLastError(ERROR_INVALID_PARAMETER), FALSE) : + (pstrClone->Copy( *this)) + ); + } // MULTISZ::Clone() + + // + // Recalculates the length of *this because we've modified the buffers + // directly + // + + VOID RecalcLen( VOID ) + { m_cchLen = MULTISZ::CalcLength( QueryStr(), &m_cStrings ); } + + // + // Calculate total character length of a MULTI_SZ, including the + // terminating NULLs. + // + + static DWORD CalcLength( const WCHAR * str, + LPDWORD pcStrings = NULL ); + + // + // Determine if the MULTISZ contains a specific string. + // + + BOOL FindString( const WCHAR * str ); + + BOOL FindString( STRU & str ) + { return FindString( str.QueryStr() ); } + + // + // Determine if the MULTISZ contains a specific string - case-insensitive + // + + BOOL FindStringNoCase( const WCHAR * str ); + + BOOL FindStringNoCase( STRU & str ) + { return FindStringNoCase( str.QueryStr() ); } + + // + // Used for scanning a multisz. + // + + const WCHAR * First( VOID ) const + { return *QueryStr() == L'\0' ? NULL : QueryStr(); } + + const WCHAR * Next( const WCHAR * Current ) const + { Current += ::wcslen( Current ) + 1; + return *Current == L'\0' ? NULL : Current; } + + BOOL + Equals( + MULTISZ* pmszRhs + ); + +private: + + DWORD m_cchLen; + DWORD m_cStrings; + VOID AuxInit( const WCHAR * pInit ); + BOOL AuxAppend( const WCHAR * pInit, + UINT cbStr, BOOL fAddSlop = TRUE ); + +}; + +// +// Quick macro for declaring a MULTISZ that will use stack memory of +// bytes. If the buffer overflows then a heap buffer will be allocated +// + +#define STACK_MULTISZ( name, size ) WCHAR __ach##name[size]; \ + MULTISZ name( __ach##name, sizeof( __ach##name )) + +HRESULT +SplitCommaDelimitedString( + PCWSTR pszList, + BOOL fTrimEntries, + BOOL fRemoveEmptyEntries, + MULTISZ * pmszList +); + +#endif // !_MULTISZ_HXX_ + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/multisza.hxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/multisza.hxx new file mode 100644 index 0000000000..44aa802563 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/multisza.hxx @@ -0,0 +1,225 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _MULTISZA_HXX_ +#define _MULTISZA_HXX_ + +# include + + +/*++ + class MULTISZ: + + Intention: + A light-weight multi-string class supporting encapsulated string class. + + This object is derived from BUFFER class. + It maintains following state: + + m_fValid - whether this object is valid - + used only by MULTISZ() init functions + * NYI: I need to kill this someday * + m_cchLen - string length cached when we update the string. + m_cStrings - number of strings. + + Member Functions: + There are two categories of functions: + 1) Safe Functions - which do integrity checking of state + 2) UnSafe Functions - which do not do integrity checking, but + enable writing to the data stream freely. + (someday this will be enabled as Safe versions without + problem for users) + +--*/ +class MULTISZA : public BUFFER +{ +public: + + MULTISZA() + : BUFFER (), + m_cchLen ( 0), + m_cStrings(0) + { Reset(); } + + // creates a stack version of the MULTISZA object - uses passed in stack buffer + // MULTISZA does not free this pbInit on its own. + MULTISZA( __in_bcount(cbInit) CHAR * pbInit, DWORD cbInit) + : BUFFER( (BYTE *) pbInit, cbInit), + m_cchLen (0), + m_cStrings(0) + {} + + MULTISZA( const CHAR * pchInit ) + : BUFFER (), + m_cchLen ( 0), + m_cStrings(0) + { AuxInit(pchInit); } + + MULTISZA( const MULTISZA & str ) + : BUFFER (), + m_cchLen ( 0), + m_cStrings(0) + { AuxInit( str.QueryStr()); } + +// BOOL IsValid(VOID) const { return ( BUFFER::IsValid()) ; } + // + // Checks and returns TRUE if this string has no valid data else FALSE + // + BOOL IsEmpty( VOID) const { return ( *QueryStr() == L'\0'); } + + BOOL Append( const CHAR * pchInit ) { + return ((pchInit != NULL) ? (AuxAppend( pchInit, + (DWORD) (::strlen(pchInit)) * sizeof(CHAR) + )) : + TRUE); + } + + + BOOL Append( const CHAR * pchInit, DWORD cchLen ) { + return ((pchInit != NULL) ? (AuxAppend( pchInit, + cchLen * sizeof(CHAR))) : + TRUE); + } + + BOOL Append( STRA & str ) + { return AuxAppend( str.QueryStr(), + (str.QueryCCH()) * sizeof(CHAR)); } + + // Resets the internal string to be NULL string. Buffer remains cached. + VOID Reset( VOID) + { DBG_ASSERT( QueryPtr() != NULL); + QueryStr()[0] = L'\0'; + QueryStr()[1] = L'\0'; + m_cchLen = 2; + m_cStrings = 0; + } + + BOOL Copy( const CHAR * pchInit, IN DWORD cbLen ) { + if ( QueryPtr() ) { Reset(); } + return ( (pchInit != NULL) ? + AuxAppend( pchInit, cbLen, FALSE ): + TRUE); + } + + BOOL Copy( const MULTISZA & str ) + { return ( Copy(str.QueryStr(), str.QueryCB())); } + + // + // Returns the number of bytes in the string including the terminating + // NULLs + // + UINT QueryCB( VOID ) const + { return ( m_cchLen * sizeof(CHAR)); } + + // + // Returns # of characters in the string including the terminating NULLs + // + UINT QueryCCH( VOID ) const { return (m_cchLen); } + + // + // Returns # of strings in the MULTISZA. + // + + DWORD QueryStringCount( VOID ) const { return m_cStrings; } + + // + // Makes a copy of the stored string in given buffer + // + BOOL CopyToBuffer( __out_ecount_opt(*lpcch) CHAR * lpszBuffer, LPDWORD lpcch) const; + + // + // Return the string buffer + // + CHAR * QueryStrA( VOID ) const { return ( QueryStr()); } + CHAR * QueryStr( VOID ) const { return ((CHAR *) QueryPtr()); } + + // + // Makes a clone of the current string in the string pointer passed in. + // + BOOL + Clone( OUT MULTISZA * pstrClone) const + { + return ((pstrClone == NULL) ? + (SetLastError(ERROR_INVALID_PARAMETER), FALSE) : + (pstrClone->Copy( *this)) + ); + } // MULTISZA::Clone() + + // + // Recalculates the length of *this because we've modified the buffers + // directly + // + + VOID RecalcLen( VOID ) + { m_cchLen = MULTISZA::CalcLength( QueryStr(), &m_cStrings ); } + + // + // Calculate total character length of a MULTI_SZ, including the + // terminating NULLs. + // + + static DWORD CalcLength( const CHAR * str, + LPDWORD pcStrings = NULL ); + + // + // Determine if the MULTISZA contains a specific string. + // + + BOOL FindString( const CHAR * str ); + + BOOL FindString( STRA & str ) + { return FindString( str.QueryStr() ); } + + // + // Determine if the MULTISZA contains a specific string - case-insensitive + // + + BOOL FindStringNoCase( const CHAR * str ); + + BOOL FindStringNoCase( STRA & str ) + { return FindStringNoCase( str.QueryStr() ); } + + // + // Used for scanning a MULTISZA. + // + + const CHAR * First( VOID ) const + { return *QueryStr() == L'\0' ? NULL : QueryStr(); } + + const CHAR * Next( const CHAR * Current ) const + { Current += ::strlen( Current ) + 1; + return *Current == L'\0' ? NULL : Current; } + + BOOL + Equals( + MULTISZA* pmszRhs + ); + +private: + + DWORD m_cchLen; + DWORD m_cStrings; + VOID AuxInit( const CHAR * pInit ); + BOOL AuxAppend( const CHAR * pInit, + UINT cbStr, BOOL fAddSlop = TRUE ); + +}; + +// +// Quick macro for declaring a MULTISZA that will use stack memory of +// bytes. If the buffer overflows then a heap buffer will be allocated +// + +#define STACK_MULTISZA( name, size ) CHAR __ach##name[size]; \ + MULTISZA name( __ach##name, sizeof( __ach##name )) + +HRESULT +SplitCommaDelimitedString( + PCSTR pszList, + BOOL fTrimEntries, + BOOL fRemoveEmptyEntries, + MULTISZA * pmszList +); + +#endif // !_MULTISZA_HXX_ + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/normalize.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/normalize.h new file mode 100644 index 0000000000..411c3660a4 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/normalize.h @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef __NORMALIZE_URL__H__ +#define __NORMALIZE_URL__H__ + +HRESULT +NormalizeUrl( + __inout LPSTR pszUrl +); + + +HRESULT +NormalizeUrlW( + __inout LPWSTR pszUrl +); + + + +HRESULT +UlCleanAndCopyUrl( + __in LPSTR pSource, + IN ULONG SourceLength, + OUT PULONG pBytesCopied, + __inout PWSTR pDestination, + __deref_opt_out_opt PWSTR * ppQueryString OPTIONAL +); + +HRESULT +UlInitializeParsing( + VOID +); + +HRESULT +InitializeNormalizeUrl( + VOID +); + + +#endif \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/ntassert.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/ntassert.h new file mode 100644 index 0000000000..8a8d656f21 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/ntassert.h @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#ifdef _ASSERTE + #undef _ASSERTE +#endif + +#ifdef ASSERT + #undef ASSERT +#endif + +#if defined( DBG ) && DBG + #define SX_ASSERT( _x ) ( (VOID)( ( ( _x ) ) ? TRUE : ( __annotation( L"Debug", L"AssertFail", L#_x ), DbgRaiseAssertionFailure(), FALSE ) ) ) + #define SX_ASSERTMSG( _m, _x ) ( (VOID)( ( ( _x ) ) ? TRUE : ( __annotation( L"Debug", L"AssertFail", L##_m ), DbgRaiseAssertionFailure(), FALSE ) ) ) + #define SX_VERIFY( _x ) SX_ASSERT( _x ) + #define _ASSERTE( _x ) SX_ASSERT( _x ) + #define ASSERT( _x ) SX_ASSERT( _x ) + #define assert( _x ) SX_ASSERT( _x ) + #define DBG_ASSERT( _x ) SX_ASSERT( _x ) + #define DBG_REQUIRE( _x ) SX_ASSERT( _x ) +#else + #define SX_ASSERT( _x ) ( (VOID)0 ) + #define SX_ASSERTMSG( _m, _x ) ( (VOID)0 ) + #define SX_VERIFY( _x ) ( (VOID)( ( _x ) ? TRUE : FALSE ) ) + #define _ASSERTE( _x ) ( (VOID)0 ) + #define assert( _x ) ( (VOID)0 ) + #define DBG_ASSERT( _x ) ( (VOID)0 ) + #define DBG_REQUIRE( _x ) ((VOID)(_x)) +#endif + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/percpu.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/percpu.h new file mode 100644 index 0000000000..ae59b1c805 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/percpu.h @@ -0,0 +1,305 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +template +class PER_CPU +{ +public: + + template + inline + static + HRESULT + Create( + FunctionInitializer Initializer, + __deref_out PER_CPU ** ppInstance + ); + + inline + T * + GetLocal( + VOID + ); + + template + inline + VOID + ForEach( + FunctionForEach Function + ); + + inline + VOID + Dispose( + VOID + ); + +private: + + PER_CPU( + VOID + ) + { + // + // Don't perform any operation during constructor. + // Constructor will never be called. + // + } + + ~PER_CPU( + VOID + ) + { + // + // Don't perform any operation during destructor. + // Constructor will never be called. + // + } + + template + HRESULT + Initialize( + FunctionInitializer Initializer, + DWORD NumberOfVariables, + DWORD Alignment + ); + + T * + GetObject( + DWORD Index + ); + + static + HRESULT + GetProcessorInformation( + __out DWORD * pCacheLineSize, + __out DWORD * pNumberOfProcessors + ); + + // + // Pointer to the begining of the inlined array. + // + PVOID m_pVariables; + SIZE_T m_Alignment; + SIZE_T m_VariablesCount; +}; + +template +template +inline +// static +HRESULT +PER_CPU::Create( + FunctionInitializer Initializer, + __deref_out PER_CPU ** ppInstance +) +{ + HRESULT hr = S_OK; + DWORD CacheLineSize = 0; + DWORD ObjectCacheLineSize = 0; + DWORD NumberOfProcessors = 0; + PER_CPU * pInstance = NULL; + + hr = GetProcessorInformation(&CacheLineSize, + &NumberOfProcessors); + if (FAILED(hr)) + { + goto Finished; + } + + if (sizeof(T) > CacheLineSize) + { + // + // Round to the next multiple of the cache line size. + // + ObjectCacheLineSize = (sizeof(T) + CacheLineSize-1) & (CacheLineSize-1); + } + else + { + ObjectCacheLineSize = CacheLineSize; + } + + // + // Calculate the size of the PER_CPU object, including the array. + // The first cache line is for the member variables and the array + // starts in the next cache line. + // + SIZE_T Size = CacheLineSize + NumberOfProcessors * ObjectCacheLineSize; + + pInstance = (PER_CPU*) _aligned_malloc(Size, CacheLineSize); + if (pInstance == NULL) + { + hr = E_OUTOFMEMORY; + goto Finished; + } + ZeroMemory(pInstance, Size); + + // + // The array start in the 2nd cache line. + // + pInstance->m_pVariables = reinterpret_cast(pInstance) + CacheLineSize; + + // + // Pass a disposer for disposing initialized items in case of failure. + // + hr = pInstance->Initialize(Initializer, + NumberOfProcessors, + ObjectCacheLineSize); + if (FAILED(hr)) + { + goto Finished; + } + + *ppInstance = pInstance; + pInstance = NULL; + +Finished: + + if (pInstance != NULL) + { + // + // Free the instance without disposing it. + // + pInstance->Dispose(); + pInstance = NULL; + } + + return hr; +} + +template +inline +T * +PER_CPU::GetLocal( + VOID +) +{ + // Use GetCurrentProcessorNumber (up to 64 logical processors) instead of + // GetCurrentProcessorNumberEx (more than 64 logical processors) because + // the number of processors are not densely packed per group. + // The idea of distributing variables per CPU is to have + // a scalability multiplier (could be NUMA node instead). + // + // Make sure the index don't go beyond the array size, if that happens, + // there won't be even distribution, but still better + // than one single variable. + // + return GetObject(GetCurrentProcessorNumber()); +} + +template +inline +T * +PER_CPU::GetObject( + DWORD Index +) +{ + return reinterpret_cast(static_cast(m_pVariables) + Index * m_Alignment); +} + +template +template +inline +VOID +PER_CPU::ForEach( + FunctionForEach Function +) +{ + for(DWORD Index = 0; Index < m_VariablesCount; ++Index) + { + T * pObject = GetObject(Index); + Function(pObject); + } +} + +template +VOID +PER_CPU::Dispose( + VOID +) +{ + _aligned_free(this); +} + +template +template +inline +HRESULT +PER_CPU::Initialize( + FunctionInitializer Initializer, + DWORD NumberOfVariables, + DWORD Alignment +) +/*++ + +Routine Description: + + Initialize each object using the initializer function. + If initialization for any object fails, it dispose the + objects that were successfully initialized. + +Arguments: + + Initializer - Function for initialize one object. + Signature: HRESULT Func(T*) + Dispose - Function for disposing initialized objects in case of failure. + Signature: void Func(T*) + NumberOfVariables - The length of the array of variables. + Alignment - Alignment to use for avoiding false sharing. + +Return: + + HRESULT - E_OUTOFMEMORY + +--*/ +{ + HRESULT hr = S_OK; + DWORD Index = 0; + + m_VariablesCount = NumberOfVariables; + m_Alignment = Alignment; + + for (; Index < m_VariablesCount; ++Index) + { + T * pObject = GetObject(Index); + Initializer(pObject); + } + + return hr; +} + +template +// static +HRESULT +PER_CPU::GetProcessorInformation( + __out DWORD * pCacheLineSize, + __out DWORD * pNumberOfProcessors +) +/*++ + +Routine Description: + + Gets the CPU cache-line size for the current system. + This information is used for avoiding CPU false sharing. + +Arguments: + + pCacheLineSize - The processor cache-line size. + pNumberOfProcessors - Maximum number of processors per group. + +Return: + + HRESULT - E_OUTOFMEMORY + +--*/ +{ + SYSTEM_INFO SystemInfo = { }; + + GetSystemInfo(&SystemInfo); + *pNumberOfProcessors = SystemInfo.dwNumberOfProcessors; + *pCacheLineSize = SYSTEM_CACHE_ALIGNMENT_SIZE; + + return S_OK; +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/prime.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/prime.h new file mode 100644 index 0000000000..77fcb75b8a --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/prime.h @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#include +#include + +// +// Pre-calculated prime numbers (up to 10,049,369). +// +extern __declspec(selectany) const DWORD g_Primes [] = { + 3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, + 761, 919, 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, + 12143, 14591, 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, + 130363, 156437, 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, + 968897, 1162687, 1395263, 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, + 5999471, 7199369, 7849369, 8649369, 9249369, 10049369 +}; + +class PRIME +{ +public: + + static + DWORD + GetPrime( + DWORD dwMinimum + ) + { + // + // Try to use the precalculated numbers. + // + for ( DWORD Index = 0; Index < _countof( g_Primes ); Index++ ) + { + DWORD dwCandidate = g_Primes[Index]; + if ( dwCandidate >= dwMinimum ) + { + return dwCandidate; + } + } + + // + // Do calculation. + // + for ( DWORD dwCandidate = dwMinimum | 1; + dwCandidate < MAXDWORD; + dwCandidate += 2 ) + { + if ( IsPrime( dwCandidate ) ) + { + return dwCandidate; + } + } + return dwMinimum; + } + +private: + + static + BOOL + IsPrime( + DWORD dwCandidate + ) + { + if ((dwCandidate & 1) == 0) + { + return ( dwCandidate == 2 ); + } + + DWORD dwMax = static_cast(sqrt(static_cast(dwCandidate))); + + for ( DWORD Index = 3; Index <= dwMax; Index += 2 ) + { + if ( (dwCandidate % Index) == 0 ) + { + return FALSE; + } + } + return TRUE; + } + + PRIME() {} + ~PRIME() {} +}; \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/reftrace.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/reftrace.h new file mode 100644 index 0000000000..ace85dcde2 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/reftrace.h @@ -0,0 +1,88 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _REFTRACE_H_ +#define _REFTRACE_H_ + + +#if defined(__cplusplus) +extern "C" { +#endif // __cplusplus + + +#include + + +// +// This is the number of stack backtrace values captured in each +// trace log entry. This value is chosen to make the log entry +// exactly twelve dwords long, making it a bit easier to interpret +// from within the debugger without the debugger extension. +// + +#define REF_TRACE_LOG_STACK_DEPTH 9 + +// No-op value for the Context1,2,3 parameters of WriteRefTraceLogEx +//#define REF_TRACE_EMPTY_CONTEXT ((PVOID) -1) +#define REF_TRACE_EMPTY_CONTEXT NULL + + +// +// This defines the entry written to the trace log. +// + +typedef struct _REF_TRACE_LOG_ENTRY { + + LONG NewRefCount; + CONST VOID * Context; + CONST VOID * Context1; + CONST VOID * Context2; + CONST VOID * Context3; + DWORD Thread; + PVOID Stack[REF_TRACE_LOG_STACK_DEPTH]; + +} REF_TRACE_LOG_ENTRY, *PREF_TRACE_LOG_ENTRY; + + +// +// Manipulators. +// + +PTRACE_LOG +CreateRefTraceLog( + IN LONG LogSize, + IN LONG ExtraBytesInHeader + ); + +VOID +DestroyRefTraceLog( + IN PTRACE_LOG Log + ); + +LONG +__cdecl +WriteRefTraceLog( + IN PTRACE_LOG Log, + IN LONG NewRefCount, + IN CONST VOID * Context + ); + +LONG +__cdecl +WriteRefTraceLogEx( + IN PTRACE_LOG Log, + IN LONG NewRefCount, + IN CONST VOID * Context, + IN CONST VOID * Context1, + IN CONST VOID * Context2, + IN CONST VOID * Context3 + ); + + +#if defined(__cplusplus) +} // extern "C" +#endif // __cplusplus + + +#endif // _REFTRACE_H_ + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/rwlock.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/rwlock.h new file mode 100644 index 0000000000..50b9b1ca11 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/rwlock.h @@ -0,0 +1,193 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#if (_WIN32_WINNT < 0x600) + +// +// XP implementation. +// +class CWSDRWLock +{ +public: + + CWSDRWLock() + : m_bInited(FALSE) + { + } + + ~CWSDRWLock() + { + if (m_bInited) + { + DeleteCriticalSection(&m_rwLock.critsec); + CloseHandle(m_rwLock.ReadersDoneEvent); + } + } + + BOOL QueryInited() const + { + return m_bInited; + } + + HRESULT Init() + { + HRESULT hr = S_OK; + + if (FALSE == m_bInited) + { + m_rwLock.fWriterWaiting = FALSE; + m_rwLock.LockCount = 0; + if ( !InitializeCriticalSectionAndSpinCount( &m_rwLock.critsec, 0 )) + { + DWORD dwError = GetLastError(); + hr = HRESULT_FROM_WIN32(dwError); + return hr; + } + + m_rwLock.ReadersDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if( NULL == m_rwLock.ReadersDoneEvent ) + { + DWORD dwError = GetLastError(); + hr = HRESULT_FROM_WIN32(dwError); + DeleteCriticalSection(&m_rwLock.critsec); + return hr; + } + m_bInited = TRUE; + } + + return hr; + } + + void SharedAcquire() + { + EnterCriticalSection(&m_rwLock.critsec); + InterlockedIncrement(&m_rwLock.LockCount); + LeaveCriticalSection(&m_rwLock.critsec); + } + + void SharedRelease() + { + ReleaseRWLock(); + } + + void ExclusiveAcquire() + { + EnterCriticalSection( &m_rwLock.critsec ); + + m_rwLock.fWriterWaiting = TRUE; + + // check if there are any readers active + if ( InterlockedExchangeAdd( &m_rwLock.LockCount, 0 ) > 0 ) + { + // + // Wait for all the readers to get done.. + // + WaitForSingleObject( m_rwLock.ReadersDoneEvent, INFINITE ); + } + m_rwLock.LockCount = -1; + } + + void ExclusiveRelease() + { + ReleaseRWLock(); + } + +private: + + BOOL m_bInited; + + typedef struct _RW_LOCK + { + BOOL fWriterWaiting; // Is a writer waiting on the lock? + LONG LockCount; + CRITICAL_SECTION critsec; + HANDLE ReadersDoneEvent; + } RW_LOCK, *PRW_LOCK; + + RW_LOCK m_rwLock; + +private: + + void ReleaseRWLock() + { + LONG Count = InterlockedDecrement( &m_rwLock.LockCount ); + + if ( 0 <= Count ) + { + // releasing a read lock + if (( m_rwLock.fWriterWaiting ) && ( 0 == Count )) + { + SetEvent( m_rwLock.ReadersDoneEvent ); + } + } + else + { + // Releasing a write lock + m_rwLock.LockCount = 0; + m_rwLock.fWriterWaiting = FALSE; + LeaveCriticalSection(&m_rwLock.critsec); + } + } +}; + +#else + +// +// Implementation for Windows Vista or greater. +// +class CWSDRWLock +{ +public: + + CWSDRWLock() + { + InitializeSRWLock(&m_rwLock); + } + + BOOL QueryInited() + { + return TRUE; + } + + + HRESULT Init() + { + // + // Method defined to keep compatibility with CWSDRWLock class for XP. + // + return S_OK; + } + + void SharedAcquire() + { + AcquireSRWLockShared(&m_rwLock); + } + + void SharedRelease() + { + ReleaseSRWLockShared(&m_rwLock); + } + + void ExclusiveAcquire() + { + AcquireSRWLockExclusive(&m_rwLock); + } + + void ExclusiveRelease() + { + ReleaseSRWLockExclusive(&m_rwLock); + } + +private: + + SRWLOCK m_rwLock; +}; + +#endif + +// +// Rename the lock class to a more clear name. +// +typedef CWSDRWLock READ_WRITE_LOCK; \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/statichash.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/statichash.h new file mode 100644 index 0000000000..f2c7980405 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/statichash.h @@ -0,0 +1,730 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef __STATIC_HASH__H_ +#define __STATIC_HASH__H_ + +#define STATIC_STRING_HASH_BUCKETS 131 + +// +// SERVER_VARIABLE_HASH maps server variable string to routines to eval them +// + +struct STATIC_STRING_HASH_RECORD +{ + CHAR * _pszName; + STATIC_STRING_HASH_RECORD * _pNext; + USHORT _cchName; +}; + +struct STATIC_STRING_HASH_ITER +{ + STATIC_STRING_HASH_RECORD *_pCursor; + DWORD _dwBucket; + BOOL _fRemove; +}; + +class STATIC_STRING_HASH +{ + public: + + STATIC_STRING_HASH( + BOOL fCaseSensitive = FALSE + ) : _fCaseSensitive( fCaseSensitive ) + { + Reset(); + } + + VOID + Reset() + { + ZeroMemory( &_rgBuckets, sizeof( _rgBuckets ) ); + } + + static + PCSTR + ExtractKey( + __in const STATIC_STRING_HASH_RECORD * pRecord + ) + /*++ + + Routine Description: + + Get the key out of the record + + Arguments: + + record to fetch the key from + + Return Value: + + key + + --*/ + { + DBG_ASSERT( pRecord != NULL ); + return pRecord->_pszName; + } + + VOID + InsertRecord( + __in STATIC_STRING_HASH_RECORD * pRecord + ) + /*++ + + Routine Description: + + Insert record to hash table + + Note: remember this is static hash table + There is no synchronization on the table + Exclusive acess must be assured by caller + + Arguments: + + record to fetch the key from + + Return Value: + + VOID + + --*/ + { + DWORD dwIndex; + STATIC_STRING_HASH_RECORD* pCursor; + + DBG_ASSERT( pRecord != NULL ); + DBG_ASSERT( pRecord->_pszName != NULL ); + + if(NULL == pRecord->_pszName) + { + return; + } + + if (_fCaseSensitive) + { + dwIndex = HashString( pRecord->_pszName ) % STATIC_STRING_HASH_BUCKETS; + } + else + { + dwIndex = HashStringNoCase( pRecord->_pszName ) % STATIC_STRING_HASH_BUCKETS; + } + + pCursor = _rgBuckets[ dwIndex ]; + + pRecord->_pNext = pCursor; + _rgBuckets[ dwIndex ] = pRecord; + } + + STATIC_STRING_HASH_RECORD * + FindKey( + __in PCSTR pszName, + BOOL fRemove = FALSE + ) + /*++ + + Routine Description: + + Find key in the table (and remove it optionally) + + Arguments: + + key + + Return Value: + + record containing the key + + --*/ + { + DWORD dwIndex; + STATIC_STRING_HASH_RECORD* pRecord; + STATIC_STRING_HASH_RECORD* pLastRecord = NULL; + + DBG_ASSERT( pszName != NULL ); + + if (_fCaseSensitive) + { + dwIndex = HashString( pszName ) % STATIC_STRING_HASH_BUCKETS; + } + else + { + dwIndex = HashStringNoCase( pszName ) % STATIC_STRING_HASH_BUCKETS; + } + + pRecord = _rgBuckets[ dwIndex ]; + while ( pRecord != NULL ) + { + if (_fCaseSensitive) + { + if ( strcmp( pszName, pRecord->_pszName ) == 0 ) + { + break; + } + } + else if ( _stricmp( pszName, pRecord->_pszName ) == 0 ) + { + break; + } + + pLastRecord = pRecord; + pRecord = pRecord->_pNext; + } + + if (fRemove && + pRecord != NULL) + { + if (pLastRecord != NULL) + { + pLastRecord->_pNext = pRecord->_pNext; + } + else + { + _rgBuckets[dwIndex] = pRecord->_pNext; + } + } + + return pRecord; + } + + BOOL + CheckDistribution( + IN DWORD dwConflictThreshold, + IN BOOL fToDebugger + ) + /*++ + + Routine Description: + + Simple verification on conflicts within the table + + Arguments: + + dwConflictThreshold - max number of entries tolerated per bucket + fToDebbuger - spew the entries exceeding threshold into debugger + + Return Value: + + FALSE it threshold was reached (means hash funcion may not be optimal) + + --*/ + { + BOOL fThresholdReached = FALSE; + STATIC_STRING_HASH_RECORD* pRecord; + for ( DWORD dwIndex = 0; dwIndex < STATIC_STRING_HASH_BUCKETS; dwIndex++) + { + pRecord = _rgBuckets[ dwIndex ]; + DWORD countInBucket = 0; + while ( pRecord != NULL ) + { + countInBucket++; + pRecord = pRecord->_pNext; + } + // + // print out the list of multiple entries in bucket + // + if ( countInBucket > dwConflictThreshold && fToDebugger ) + { + fThresholdReached = TRUE; + + pRecord = _rgBuckets[ dwIndex ]; + while ( pRecord != NULL ) + { + pRecord = pRecord->_pNext; + } + } + } + return fThresholdReached; + } + + STATIC_STRING_HASH_RECORD * + FindFirst( + STATIC_STRING_HASH_ITER *pIterator, + BOOL fRemove = FALSE + ) + /*++ + + Routine Description: + + Begins a new hash item enumeration. + + Arguments: + + pIterator - Supplies the context for the enumeration. + + fRemove - Supplies TRUE if the items should be removed + from the hash as they are enumerated. + + Return Value: + + The first entry in the hash if successful, NULL otherwise. + + --*/ + { + pIterator->_dwBucket = 0; + pIterator->_fRemove = fRemove; + pIterator->_pCursor = FindNextBucket(&pIterator->_dwBucket); + + if (pIterator->_fRemove && pIterator->_pCursor != NULL) + { + _rgBuckets[pIterator->_dwBucket] = pIterator->_pCursor->_pNext; + } + + return pIterator->_pCursor; + } + + STATIC_STRING_HASH_RECORD * + FindNext( + STATIC_STRING_HASH_ITER *pIterator + ) + /*++ + + Routine Description: + + Continues a hash item enumeration. + + Arguments: + + pIterator - Supplies the context for the enumeration. + + Return Value: + + The next entry in the hash if successful, NULL otherwise. + + --*/ + { + if (pIterator->_pCursor != NULL) + { + if (pIterator->_fRemove) + { + pIterator->_pCursor = _rgBuckets[pIterator->_dwBucket]; + } + else + { + pIterator->_pCursor = pIterator->_pCursor->_pNext; + } + + if (pIterator->_pCursor == NULL) + { + pIterator->_dwBucket++; + pIterator->_pCursor = FindNextBucket(&pIterator->_dwBucket); + } + } + + if (pIterator->_fRemove && pIterator->_pCursor != NULL) + { + _rgBuckets[pIterator->_dwBucket] = pIterator->_pCursor->_pNext; + } + + return pIterator->_pCursor; + } + + protected: + + STATIC_STRING_HASH_RECORD * _rgBuckets[ STATIC_STRING_HASH_BUCKETS ]; + + private: + + BOOL _fCaseSensitive; + + STATIC_STRING_HASH_RECORD * + FindNextBucket( + DWORD *pdwStartingBucket + ) + /*++ + + Routine Description: + + Scan for the next non-empty bucket. + + Arguments: + + pdwStartingBucket - Supplies a pointer to the starting + bucket index. This value is updated with the index + of the next non-empty bucket if successful. + + Return Value: + + The first entry in the next non-empty bucket if successful, + NULL otherwise. + + --*/ + { + DWORD i; + STATIC_STRING_HASH_RECORD *pScan = NULL; + + for (i = *pdwStartingBucket ; i < STATIC_STRING_HASH_BUCKETS ; i++) + { + pScan = _rgBuckets[i]; + + if (pScan != NULL) + { + break; + } + } + + *pdwStartingBucket = i; + return pScan; + } +}; + + + + +struct STATIC_WSTRING_HASH_RECORD +{ + WCHAR * _pszName; + STATIC_WSTRING_HASH_RECORD * _pNext; + USHORT _cchName; +}; + + +struct STATIC_WSTRING_HASH_ITER +{ + STATIC_WSTRING_HASH_RECORD *_pCursor; + DWORD _dwBucket; + BOOL _fRemove; +}; + + +class STATIC_WSTRING_HASH +{ + public: + STATIC_WSTRING_HASH( + BOOL fCaseSensitive = FALSE + ) : _fCaseSensitive( fCaseSensitive ) + { + Reset(); + } + + VOID + Reset() + { + ZeroMemory( &_rgBuckets, sizeof( _rgBuckets ) ); + } + + static + PCWSTR + ExtractKey( + __in const STATIC_WSTRING_HASH_RECORD * pRecord + ) + /*++ + + Routine Description: + + Get the key out of the record + + Arguments: + + record to fetch the key from + + Return Value: + + key + + --*/ + { + DBG_ASSERT( pRecord != NULL ); + return pRecord->_pszName; + } + + VOID + InsertRecord( + __in STATIC_WSTRING_HASH_RECORD * pRecord + ) + /*++ + + Routine Description: + + Insert record to hash table + + Note: remember this is static hash table + There is no synchronization on the table + Exclusive acess must be assured by caller + + Arguments: + + record to fetch the key from + + Return Value: + + VOID + + --*/ + { + DWORD dwIndex; + STATIC_WSTRING_HASH_RECORD* pCursor; + + DBG_ASSERT( pRecord != NULL ); + DBG_ASSERT( pRecord->_pszName != NULL ); + + if (_fCaseSensitive) + { + dwIndex = HashString( pRecord->_pszName ) % STATIC_STRING_HASH_BUCKETS; + } + else + { + dwIndex = HashStringNoCase( pRecord->_pszName ) % STATIC_STRING_HASH_BUCKETS; + } + + pCursor = _rgBuckets[ dwIndex ]; + + pRecord->_pNext = pCursor; + _rgBuckets[ dwIndex ] = pRecord; + } + + STATIC_WSTRING_HASH_RECORD * + FindKey( + __in PCWSTR pszName, + BOOL fRemove = FALSE + ) + /*++ + + Routine Description: + + Find key in the table (and remove it optionally) + + Arguments: + + key + + Return Value: + + record containing the key + + --*/ + { + DWORD dwIndex; + STATIC_WSTRING_HASH_RECORD* pRecord; + STATIC_WSTRING_HASH_RECORD* pLastRecord = NULL; + + DBG_ASSERT( pszName != NULL ); + + if (_fCaseSensitive) + { + dwIndex = HashString( pszName ) % STATIC_STRING_HASH_BUCKETS; + } + else + { + dwIndex = HashStringNoCase( pszName ) % STATIC_STRING_HASH_BUCKETS; + } + + pRecord = _rgBuckets[ dwIndex ]; + while ( pRecord != NULL ) + { + if ( _fCaseSensitive ) + { + if ( wcscmp( pszName, pRecord->_pszName ) == 0 ) + { + break; + } + } + else if ( _wcsicmp( pszName, pRecord->_pszName ) == 0 ) + { + break; + } + + pLastRecord = pRecord; + pRecord = pRecord->_pNext; + } + + if (fRemove && + pRecord != NULL) + { + if (pLastRecord != NULL) + { + pLastRecord->_pNext = pRecord->_pNext; + } + else + { + _rgBuckets[dwIndex] = pRecord->_pNext; + } + } + + return pRecord; + } + + BOOL + CheckDistribution( + IN DWORD dwConflictThreshold, + IN BOOL fToDebugger + ) + /*++ + + Routine Description: + + Simple verification on conflicts within the table + + Arguments: + + dwConflictThreshold - max number of entries tolerated per bucket + fToDebbuger - spew the entries exceeding threshold into debugger + + Return Value: + + FALSE it threshold was reached (means hash funcion may not be optimal) + + --*/ + { + BOOL fThresholdReached = FALSE; + STATIC_WSTRING_HASH_RECORD* pRecord; + for ( DWORD dwIndex = 0; dwIndex < STATIC_STRING_HASH_BUCKETS; dwIndex++) + { + pRecord = _rgBuckets[ dwIndex ]; + DWORD countInBucket = 0; + while ( pRecord != NULL ) + { + countInBucket++; + pRecord = pRecord->_pNext; + } + // + // print out the list of multiple entries in bucket + // + if ( countInBucket > dwConflictThreshold && fToDebugger ) + { + fThresholdReached = TRUE; + + pRecord = _rgBuckets[ dwIndex ]; + while ( pRecord != NULL ) + { + pRecord = pRecord->_pNext; + } + } + } + return fThresholdReached; + } + + STATIC_WSTRING_HASH_RECORD * + FindFirst( + STATIC_WSTRING_HASH_ITER *pIterator, + BOOL fRemove = FALSE + ) + /*++ + + Routine Description: + + Begins a new hash item enumeration. + + Arguments: + + pIterator - Supplies the context for the enumeration. + + fRemove - Supplies TRUE if the items should be removed + from the hash as they are enumerated. + + Return Value: + + The first entry in the hash if successful, NULL otherwise. + + --*/ + { + pIterator->_dwBucket = 0; + pIterator->_fRemove = fRemove; + pIterator->_pCursor = FindNextBucket(&pIterator->_dwBucket); + + if (pIterator->_fRemove && pIterator->_pCursor != NULL) + { + _rgBuckets[pIterator->_dwBucket] = pIterator->_pCursor->_pNext; + } + + return pIterator->_pCursor; + } + + STATIC_WSTRING_HASH_RECORD * + FindNext( + STATIC_WSTRING_HASH_ITER *pIterator + ) + /*++ + + Routine Description: + + Continues a hash item enumeration. + + Arguments: + + pIterator - Supplies the context for the enumeration. + + Return Value: + + The next entry in the hash if successful, NULL otherwise. + + --*/ + { + if (pIterator->_pCursor != NULL) + { + if (pIterator->_fRemove) + { + pIterator->_pCursor = _rgBuckets[pIterator->_dwBucket]; + } + else + { + pIterator->_pCursor = pIterator->_pCursor->_pNext; + } + + if (pIterator->_pCursor == NULL) + { + pIterator->_dwBucket++; + pIterator->_pCursor = FindNextBucket(&pIterator->_dwBucket); + } + } + + if (pIterator->_fRemove && pIterator->_pCursor != NULL) + { + _rgBuckets[pIterator->_dwBucket] = pIterator->_pCursor->_pNext; + } + + return pIterator->_pCursor; + } + + protected: + + STATIC_WSTRING_HASH_RECORD * _rgBuckets[ STATIC_STRING_HASH_BUCKETS ]; + + private: + + BOOL _fCaseSensitive; + + STATIC_WSTRING_HASH_RECORD * + FindNextBucket( + DWORD *pdwStartingBucket + ) + /*++ + + Routine Description: + + Scan for the next non-empty bucket. + + Arguments: + + pdwStartingBucket - Supplies a pointer to the starting + bucket index. This value is updated with the index + of the next non-empty bucket if successful. + + Return Value: + + The first entry in the next non-empty bucket if successful, + NULL otherwise. + + --*/ + { + DWORD i; + STATIC_WSTRING_HASH_RECORD *pScan = NULL; + + for (i = *pdwStartingBucket ; i < STATIC_STRING_HASH_BUCKETS ; i++) + { + pScan = _rgBuckets[i]; + + if (pScan != NULL) + { + break; + } + } + + *pdwStartingBucket = i; + return pScan; + } +}; + + +#endif //__STATIC_HASH__H_ + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/stdtypes.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/stdtypes.h new file mode 100644 index 0000000000..53a631b036 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/stdtypes.h @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +// +// Use C++ standard 'nullptr' +// + +#ifdef NULL +#undef NULL +#endif + +#ifdef __cplusplus +#ifdef _NATIVE_NULLPTR_SUPPORTED +#define NULL nullptr +#else +#define NULL 0 +#define nullptr 0 +#endif +#else +#define NULL ((void *)0) +//#define nullptr ((void *)0) +#endif diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/stringa.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/stringa.h new file mode 100644 index 0000000000..d38604014e --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/stringa.h @@ -0,0 +1,515 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#include "buffer.h" +#include "macros.h" +#include + +class STRA +{ + +public: + + STRA( + VOID + ); + + STRA( + __inout_ecount(cchInit) CHAR* pbInit, + __in DWORD cchInit + ); + + BOOL + IsEmpty( + VOID + ) const; + + BOOL + Equals( + __in PCSTR pszRhs, + __in BOOL fIgnoreCase = FALSE + ) const; + + BOOL + Equals( + __in const STRA * pstrRhs, + __in BOOL fIgnoreCase = FALSE + ) const; + + BOOL + Equals( + __in const STRA & strRhs, + __in BOOL fIgnoreCase = FALSE + ) const; + + static + BOOL + Equals( + __in PCSTR pszLhs, + __in PCSTR pszRhs, + __in bool fIgnoreCase = false + ) + { + // Return FALSE if either or both strings are NULL. + if (!pszLhs || !pszRhs) return FALSE; + + if( fIgnoreCase ) + { + return ( 0 == _stricmp( pszLhs, pszRhs ) ); + } + + return ( 0 == strcmp( pszLhs, pszRhs ) ); + } + + VOID + Trim(); + + BOOL + StartsWith( + __in const STRA * pStraPrefix, + __in bool fIgnoreCase = FALSE + ) const; + + BOOL + StartsWith( + __in const STRA & straPrefix, + __in bool fIgnoreCase = FALSE + ) const; + + BOOL + StartsWith( + __in PCSTR pszPrefix, + __in bool fIgnoreCase = FALSE + ) const; + + BOOL + EndsWith( + __in const STRA * pStraSuffix, + __in bool fIgnoreCase = FALSE + ) const; + + BOOL + EndsWith( + __in const STRA & straSuffix, + __in bool fIgnoreCase = FALSE + ) const; + + BOOL + EndsWith( + __in PCSTR pszSuffix, + __in bool fIgnoreCase = FALSE + ) const; + + INT + IndexOf( + __in CHAR charValue, + __in DWORD dwStartIndex = 0 + ) const; + + INT + IndexOf( + __in PCSTR pszValue, + __in DWORD dwStartIndex = 0 + ) const; + + INT + LastIndexOf( + __in CHAR charValue, + __in DWORD dwStartIndex = 0 + ) const; + + DWORD + QueryCB( + VOID + ) const; + + DWORD + QueryCCH( + VOID + ) const; + + DWORD + QuerySizeCCH( + VOID + ) const; + + DWORD + QuerySize( + VOID + ) const; + + __nullterminated + __bcount(this->m_cchLen) + CHAR * + QueryStr( + VOID + ) const; + + VOID + Reset( + VOID + ); + + HRESULT + Resize( + __in DWORD cchSize + ); + + HRESULT + SyncWithBuffer( + VOID + ); + + HRESULT + Copy( + __in PCSTR pszCopy + ); + + HRESULT + Copy( + __in_ecount(cbLen) + PCSTR pszCopy, + __in SIZE_T cbLen + ); + + HRESULT + Copy( + __in const STRA * pstrRhs + ); + + HRESULT + Copy( + __in const STRA & strRhs + ); + + HRESULT + CopyW( + __in PCWSTR pszCopyW + ); + + HRESULT + CopyW( + __in_ecount(cchLen) + PCWSTR pszCopyW, + __in SIZE_T cchLen, + __in UINT CodePage = CP_UTF8, + __in BOOL fFailIfNoTranslation = FALSE + ) + { + _ASSERTE( cchLen <= MAXDWORD ); + + return AuxAppendW( + pszCopyW, + static_cast(cchLen), + 0, + CodePage, + fFailIfNoTranslation + ); + } + + HRESULT + CopyWTruncate( + __in PCWSTR pszCopyWTruncate + ); + + HRESULT + CopyWTruncate( + __in_ecount(cchLen) + PCWSTR pszCopyWTruncate, + __in SIZE_T cchLen + ); + + HRESULT + Append( + __in PCSTR pszAppend + ); + + HRESULT + Append( + __in_ecount(cbLen) + PCSTR pszAppend, + __in SIZE_T cbLen + ); + + HRESULT + Append( + __in const STRA * pstrRhs + ); + + HRESULT + Append( + __in const STRA & strRhs + ); + + HRESULT + AppendW( + __in PCWSTR pszAppendW + ) + { + HRESULT hr; + size_t cchLen; + hr = StringCchLengthW( pszAppendW, + STRSAFE_MAX_CCH, + &cchLen ); + if ( FAILED( hr ) ) + { + return hr; + } + return AppendW( pszAppendW, cchLen ); + } + + HRESULT + AppendW( + __in_ecount(cchLen) + PCWSTR pszAppendW, + __in SIZE_T cchLen, + __in UINT CodePage = CP_UTF8, + __in BOOL fFailIfNoTranslation = FALSE + ) + { + _ASSERTE( cchLen <= MAXDWORD ); + if ( cchLen == 0 ) + { + return S_OK; + } + return AuxAppendW( + pszAppendW, + static_cast(cchLen), + QueryCB(), + CodePage, + fFailIfNoTranslation + ); + } + + HRESULT + AppendWTruncate( + __in PCWSTR pszAppendWTruncate + ); + + HRESULT + AppendWTruncate( + __in_ecount(cchLen) + PCWSTR pszAppendWTruncate, + __in SIZE_T cchLen + ); + + HRESULT + CopyToBuffer( + __out_bcount(*pcb) CHAR* pszBuffer, + __inout DWORD * pcb + ) const; + + HRESULT + SetLen( + __in DWORD cchLen + ); + + HRESULT + SafeSnprintf( + __in __format_string + PCSTR pszFormatString, + ... + ); + + HRESULT + SafeVsnprintf( + __in __format_string + PCSTR pszFormatString, + va_list argsList + ); + + HRESULT + Escape( + VOID + ); + + HRESULT + EscapeUtf8( + VOID + ); + + VOID + Unescape( + VOID + ); + + HRESULT + CopyWToUTF8Unescaped( + __in LPCWSTR cpchStr + ); + + HRESULT + CopyWToUTF8Unescaped( + __in_ecount(cch) + LPCWSTR cpchStr, + __in DWORD cch + ); + + HRESULT + CopyWToUTF8Escaped( + __in LPCWSTR cpchStr + ); + + HRESULT + CopyWToUTF8Escaped( + __in_ecount(cch) + LPCWSTR cpchStr, + __in DWORD cch + ); + +private: + + // + // Avoid C++ errors. This object should never go through a copy + // constructor, unintended cast or assignment. + // + STRA( const STRA &); + STRA & operator = (const STRA &); + + HRESULT + AuxAppend( + __in_ecount(cbLen) + LPCSTR pStr, + __in DWORD cbLen, + __in DWORD cbOffset + ); + + HRESULT + AuxAppendW( + __in_ecount(cchAppendW) + PCWSTR pszAppendW, + __in DWORD cchAppendW, + __in DWORD cbOffset, + __in UINT CodePage, + __in BOOL fFailIfNoTranslation + ) + { + DWORD dwFlags = 0; + + if( CP_ACP == CodePage ) + { + dwFlags = WC_NO_BEST_FIT_CHARS; + } + else if( fFailIfNoTranslation && CodePage == CP_UTF8 ) + { + // + // WC_ERR_INVALID_CHARS is only supported in Longhorn or greater. + // +#if defined( NTDDI_VERSION ) && NTDDI_VERSION >= NTDDI_LONGHORN + dwFlags |= WC_ERR_INVALID_CHARS; +#else + UNREFERENCED_PARAMETER(fFailIfNoTranslation); +#endif + } + + return AuxAppendW( pszAppendW, + cchAppendW, + cbOffset, + CodePage, + fFailIfNoTranslation, + dwFlags ); + } + + HRESULT + AuxAppendW( + __in_ecount(cchAppendW) + PCWSTR pszAppendW, + __in DWORD cchAppendW, + __in DWORD cbOffset, + __in UINT CodePage, + __in BOOL fFailIfNoTranslation, + __in DWORD dwFlags + ); + + HRESULT + AuxAppendWTruncate( + __in_ecount(cchAppendW) + __in PCWSTR pszAppendW, + __in DWORD cchAppendW, + __in DWORD cbOffset + ); + + static + int + ConvertUnicodeToCodePage( + __in_ecount(dwStringLen) + LPCWSTR pszSrcUnicodeString, + __inout BUFFER_T * pbufDstAnsiString, + __in DWORD dwStringLen, + __in UINT uCodePage + ); + + static + HRESULT + ConvertUnicodeToMultiByte( + __in_ecount(dwStringLen) + LPCWSTR pszSrcUnicodeString, + __in BUFFER_T * pbufDstAnsiString, + __in DWORD dwStringLen + ); + + static + HRESULT + ConvertUnicodeToUTF8( + __in_ecount(dwStringLen) + LPCWSTR pszSrcUnicodeString, + __in BUFFER_T * pbufDstAnsiString, + __in DWORD dwStringLen + ); + + typedef bool (* PFN_F_SHOULD_ESCAPE)(BYTE ch); + + HRESULT + EscapeInternal( + PFN_F_SHOULD_ESCAPE pfnFShouldEscape + ); + + // + // Buffer with an inline buffer of 1, + // enough to hold null-terminating character. + // + BUFFER_T m_Buff; + DWORD m_cchLen; +}; + +inline +HRESULT +AppendToString( + ULONGLONG Number, + STRA & String +) +{ + // prefast complains Append requires input + // to be null terminated, so zero initialize + // and pass the size of the buffer minus one + // to _ui64toa_s + CHAR chNumber[32] = {0}; + if (_ui64toa_s(Number, + chNumber, + sizeof(chNumber) - sizeof(CHAR), + 10) != 0) + { + return E_INVALIDARG; + } + return String.Append(chNumber); +} + +template +CHAR* InitHelper(__out CHAR (&psz)[size]) +{ + psz[0] = '\0'; + return psz; +} + +// +// Heap operation reduction macros +// +#define STACK_STRA(name, size) CHAR __ach##name[size];\ + STRA name(InitHelper(__ach##name), sizeof(__ach##name)) + +#define INLINE_STRA(name, size) CHAR __ach##name[size];\ + STRA name; + +#define INLINE_STRA_INIT(name) name(InitHelper(__ach##name), sizeof(__ach##name)) diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/stringu.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/stringu.h new file mode 100644 index 0000000000..6c8f8f755b --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/stringu.h @@ -0,0 +1,433 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#include "buffer.h" +#include + +class STRU +{ + +public: + + STRU( + VOID + ); + + STRU( + __inout_ecount(cchInit) WCHAR* pbInit, + __in DWORD cchInit + ); + + BOOL + IsEmpty( + VOID + ) const; + + BOOL + Equals( + __in const STRU * pstrRhs, + __in BOOL fIgnoreCase = FALSE + ) const + { + _ASSERTE( pstrRhs != NULL ); + return Equals( pstrRhs->QueryStr(), fIgnoreCase ); + } + + BOOL + Equals( + __in const STRU & strRhs, + __in BOOL fIgnoreCase = FALSE + ) const + { + return Equals( strRhs.QueryStr(), fIgnoreCase ); + } + + BOOL + Equals( + __in PCWSTR pszRhs, + __in BOOL fIgnoreCase = FALSE + ) const + { + _ASSERTE( NULL != pszRhs ); + if ( NULL == pszRhs ) + { + return FALSE; + } + + #if defined( NTDDI_VERSION ) && NTDDI_VERSION >= NTDDI_LONGHORN + + return ( CSTR_EQUAL == CompareStringOrdinal( QueryStr(), + QueryCCH(), + pszRhs, + -1, + fIgnoreCase ) ); + #else + + if( fIgnoreCase ) + { + return ( 0 == _wcsicmp( QueryStr(), pszRhs ) ); + } + return ( 0 == wcscmp( QueryStr(), pszRhs ) ); + + #endif + } + + + static + BOOL + Equals( + __in PCWSTR pwszLhs, + __in PCWSTR pwszRhs, + __in bool fIgnoreCase = false + ) + { + // Return FALSE if either or both strings are NULL. + if (!pwszLhs || !pwszRhs) return FALSE; + + // + // This method performs a ordinal string comparison when OS is Vista or + // greater and a culture sensitive comparison if not (XP). This is + // consistent with the existing Equals implementation (see above). + // +#if defined( NTDDI_VERSION ) && NTDDI_VERSION >= NTDDI_LONGHORN + + return ( CSTR_EQUAL == CompareStringOrdinal( pwszLhs, + -1, + pwszRhs, + -1, + fIgnoreCase ) ); +#else + + if( fIgnoreCase ) + { + return ( 0 == _wcsicmp( pwszLhs, pwszRhs ) ); + } + else + { + return ( 0 == wcscmp( pwszLhs, pwszRhs ) ); + } + +#endif + } + + VOID + Trim(); + + BOOL + StartsWith( + __in const STRU * pStruPrefix, + __in bool fIgnoreCase = FALSE + ) const + { + _ASSERTE( pStruPrefix != NULL ); + return StartsWith( pStruPrefix->QueryStr(), fIgnoreCase ); + } + + BOOL + StartsWith( + __in const STRU & struPrefix, + __in bool fIgnoreCase = FALSE + ) const + { + return StartsWith( struPrefix.QueryStr(), fIgnoreCase ); + } + + BOOL + StartsWith( + __in PCWSTR pwszPrefix, + __in bool fIgnoreCase = FALSE + ) const; + + BOOL + EndsWith( + __in const STRU * pStruSuffix, + __in bool fIgnoreCase = FALSE + ) const + { + _ASSERTE( pStruSuffix != NULL ); + return EndsWith( pStruSuffix->QueryStr(), fIgnoreCase ); + } + + BOOL + EndsWith( + __in const STRU & struSuffix, + __in bool fIgnoreCase = FALSE + ) const + { + return EndsWith( struSuffix.QueryStr(), fIgnoreCase ); + } + + BOOL + EndsWith( + __in PCWSTR pwszSuffix, + __in bool fIgnoreCase = FALSE + ) const; + + INT + IndexOf( + __in WCHAR charValue, + __in DWORD dwStartIndex = 0 + ) const; + + INT + IndexOf( + __in PCWSTR pwszValue, + __in DWORD dwStartIndex = 0 + ) const; + + INT + LastIndexOf( + __in WCHAR charValue, + __in DWORD dwStartIndex = 0 + ) const; + + DWORD + QueryCB( + VOID + ) const; + + DWORD + QueryCCH( + VOID + ) const; + + DWORD + QuerySizeCCH( + VOID + ) const; + + __nullterminated + __ecount(this->m_cchLen) + WCHAR* + QueryStr( + VOID + ) const; + + VOID + Reset( + VOID + ); + + HRESULT + Resize( + DWORD cchSize + ); + + HRESULT + SyncWithBuffer( + VOID + ); + + template + HRESULT + Copy( + __in PCWSTR const (&rgpszStrings)[size] + ) + // + // Copies an array of strings declared as stack array. For example: + // + // LPCWSTR rgExample[] { L"one", L"two" }; + // hr = str.Copy( rgExample ); + // + { + Reset(); + + return AuxAppend( rgpszStrings, _countof( rgpszStrings ) ); + } + + HRESULT + Copy( + __in PCWSTR pszCopy + ); + + HRESULT + Copy( + __in_ecount(cchLen) + PCWSTR pszCopy, + SIZE_T cchLen + ); + + HRESULT + Copy( + __in const STRU * pstrRhs + ); + + HRESULT + Copy( + __in const STRU & str + ); + + HRESULT + CopyAndExpandEnvironmentStrings( + __in PCWSTR pszSource + ); + + HRESULT + CopyA( + __in PCSTR pszCopyA + ); + + HRESULT + CopyA( + __in_bcount(cchLen) + PCSTR pszCopyA, + SIZE_T cchLen, + UINT CodePage = CP_UTF8 + ); + + template + HRESULT + Append( + __in PCWSTR const (&rgpszStrings)[size] + ) + // + // Appends an array of strings declared as stack array. For example: + // + // LPCWSTR rgExample[] { L"one", L"two" }; + // hr = str.Append( rgExample ); + // + { + return AuxAppend( rgpszStrings, _countof( rgpszStrings ) ); + } + + HRESULT + Append( + __in PCWSTR pszAppend + ); + + HRESULT + Append( + __in_ecount(cchLen) + PCWSTR pszAppend, + SIZE_T cchLen + ); + + HRESULT + Append( + __in const STRU * pstrRhs + ); + + HRESULT + Append( + __in const STRU & strRhs + ); + + HRESULT + AppendA( + __in PCSTR pszAppendA + ); + + HRESULT + AppendA( + __in_bcount(cchLen) + PCSTR pszAppendA, + SIZE_T cchLen, + UINT CodePage = CP_UTF8 + ); + + HRESULT + CopyToBuffer( + __out_bcount(*pcb) WCHAR* pszBuffer, + PDWORD pcb + ) const; + + HRESULT + CopyToBufferA( + __out_bcount(*pcb) CHAR* pszBuffer, + __inout PDWORD pcb + ) const; + + HRESULT + SetLen( + __in DWORD cchLen + ); + + HRESULT + SafeSnwprintf( + __in PCWSTR pwszFormatString, + ... + ); + + HRESULT + SafeVsnwprintf( + __in PCWSTR pwszFormatString, + va_list argsList + ); + + static + HRESULT ExpandEnvironmentVariables( + __in PCWSTR pszString, + __out STRU * pstrExpandedString + ); + +private: + + // + // Avoid C++ errors. This object should never go through a copy + // constructor, unintended cast or assignment. + // + STRU( const STRU & ); + STRU & operator = ( const STRU & ); + + HRESULT + AuxAppend( + __in_ecount(cNumStrings) + PCWSTR const rgpszStrings[], + SIZE_T cNumStrings + ); + + HRESULT + AuxAppend( + __in_bcount(cbStr) + const WCHAR* pStr, + SIZE_T cbStr, + DWORD cbOffset + ); + + HRESULT + AuxAppendA( + __in_bcount(cbStr) + const CHAR* pStr, + SIZE_T cbStr, + DWORD cbOffset, + UINT CodePage + ); + + // + // Buffer with an inline buffer of 1, + // enough to hold null-terminating character. + // + BUFFER_T m_Buff; + DWORD m_cchLen; +}; + +// +// Helps to initialize an external buffer before +// constructing the STRU object. +// +template +WCHAR* InitHelper(__out WCHAR (&psz)[size]) +{ + psz[0] = L'\0'; + return psz; +} + +// +// Heap operation reduction macros +// +#define STACK_STRU(name, size) WCHAR __ach##name[size];\ + STRU name(InitHelper(__ach##name), sizeof(__ach##name)/sizeof(*__ach##name)) + +#define INLINE_STRU(name, size) WCHAR __ach##name[size];\ + STRU name; + +#define INLINE_STRU_INIT(name) name(InitHelper(__ach##name), sizeof(__ach##name)/sizeof(*__ach##name)) + + +HRESULT +MakePathCanonicalizationProof( + IN PCWSTR pszName, + OUT STRU * pstrPath +); diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/sttimer.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/sttimer.h new file mode 100644 index 0000000000..b0fba23559 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/sttimer.h @@ -0,0 +1,243 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _STTIMER_H +#define _STTIMER_H + +class STTIMER +{ +public: + + STTIMER() + : _pTimer( NULL ) + { + fInCanel = FALSE; + } + + virtual + ~STTIMER() + { + if ( _pTimer ) + { + CancelTimer(); + + CloseThreadpoolTimer( _pTimer ); + + _pTimer = NULL; + } + } + + HRESULT + InitializeTimer( + PTP_TIMER_CALLBACK pfnCallback, + VOID * pContext, + DWORD dwInitialWait = 0, + DWORD dwPeriod = 0 + ) + { + _pTimer = CreateThreadpoolTimer( pfnCallback, + pContext, + NULL ); + + if ( !_pTimer ) + { + return HRESULT_FROM_WIN32( GetLastError() ); + } + + if ( dwInitialWait ) + { + SetTimer( dwInitialWait, + dwPeriod ); + } + + return S_OK; + } + + VOID + SetTimer( + DWORD dwInitialWait, + DWORD dwPeriod = 0 + ) + { + FILETIME ftInitialWait; + + if ( dwInitialWait == 0 && dwPeriod == 0 ) + { + // + // Special case. We are preventing new callbacks + // from being queued. Any existing callbacks in the + // queue will still run. + // + // This effectively disables the timer. It can be + // re-enabled by setting non-zero initial wait or + // period values. + // + if (_pTimer != NULL) + { + SetThreadpoolTimer(_pTimer, NULL, 0, 0); + } + + return; + } + + InitializeRelativeFileTime( &ftInitialWait, dwInitialWait ); + + SetThreadpoolTimer( _pTimer, + &ftInitialWait, + dwPeriod, + 0 ); + } + + VOID + CancelTimer() + { + // + // Disable the timer + // + if (fInCanel) + return; + + fInCanel = TRUE; + SetTimer( 0 ); + + // + // Wait until any callbacks queued prior to disabling + // have completed. + // + if (_pTimer != NULL) + WaitForThreadpoolTimerCallbacks( _pTimer, TRUE ); + + _pTimer = NULL; + fInCanel = FALSE; + } + +private: + + VOID + InitializeRelativeFileTime( + FILETIME * pft, + DWORD dwMilliseconds + ) + { + LARGE_INTEGER li; + + // + // The pftDueTime parameter expects the time to be + // expressed as the number of 100 nanosecond intervals + // times -1. + // + // To convert from milliseconds, we'll multiply by + // -10000 + // + + li.QuadPart = (LONGLONG)dwMilliseconds * -10000; + + pft->dwHighDateTime = li.HighPart; + pft->dwLowDateTime = li.LowPart; + }; + + TP_TIMER * _pTimer; + BOOL fInCanel; +}; + +class STELAPSED +{ +public: + + STELAPSED() + : _dwInitTime( 0 ), + _dwInitTickCount( 0 ), + _dwPerfCountsPerMillisecond( 0 ), + _fUsingHighResolution( FALSE ) + { + LARGE_INTEGER li; + BOOL fResult; + + _dwInitTickCount = GetTickCount64(); + + fResult = QueryPerformanceFrequency( &li ); + + if ( !fResult ) + { + goto Finished; + } + + _dwPerfCountsPerMillisecond = li.QuadPart / 1000; + + fResult = QueryPerformanceCounter( &li ); + + if ( !fResult ) + { + goto Finished; + } + + _dwInitTime = li.QuadPart / _dwPerfCountsPerMillisecond; + + _fUsingHighResolution = TRUE; + +Finished: + + return; + } + + virtual + ~STELAPSED() + { + } + + LONGLONG + QueryElapsedTime() + { + LARGE_INTEGER li; + + if ( _fUsingHighResolution && QueryPerformanceCounter( &li ) ) + { + DWORD64 dwCurrentTime = li.QuadPart / _dwPerfCountsPerMillisecond; + + if ( dwCurrentTime < _dwInitTime ) + { + // + // It's theoretically possible that QueryPerformanceCounter + // may return slightly different values on different CPUs. + // In this case, we don't want to return an unexpected value + // so we'll return zero. This is acceptable because + // presumably such a case would only happen for a very short + // time window. + // + // It would be possible to prevent this by ensuring processor + // affinity for all calls to QueryPerformanceCounter, but that + // would be undesirable in the general case because it could + // introduce unnecessary context switches and potentially a + // CPU bottleneck. + // + // Note that this issue also applies to callers doing rapid + // calls to this function. If a caller wants to mitigate + // that, they could enforce the affinitization, or they + // could implement a similar sanity check when comparing + // returned values from this function. + // + + return 0; + } + + return dwCurrentTime - _dwInitTime; + } + + return GetTickCount64() - _dwInitTickCount; + } + + BOOL + QueryUsingHighResolution() + { + return _fUsingHighResolution; + } + +private: + + DWORD64 _dwInitTime; + DWORD64 _dwInitTickCount; + DWORD64 _dwPerfCountsPerMillisecond; + BOOL _fUsingHighResolution; +}; + +#endif // _STTIMER_H \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/tracelog.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/tracelog.h new file mode 100644 index 0000000000..1caff82ce3 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/tracelog.h @@ -0,0 +1,105 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _TRACELOG_H_ +#define _TRACELOG_H_ + + +#if defined(__cplusplus) +extern "C" { +#endif // __cplusplus + + +typedef struct _TRACE_LOG { + + // + // Signature. + // + + LONG Signature; + + // + // The total number of entries available in the log. + // + + LONG LogSize; + + // + // The index of the next entry to use. + // + + LONG NextEntry; + + // + // The byte size of each entry. + // + + LONG EntrySize; + + // + // Pointer to the start of the circular buffer. + // + + PUCHAR LogBuffer; + + // + // The extra header bytes and actual log entries go here. + // + // BYTE ExtraHeaderBytes[ExtraBytesInHeader]; + // BYTE Entries[LogSize][EntrySize]; + // + +} TRACE_LOG, *PTRACE_LOG; + + +// +// Log header signature. +// + +#define TRACE_LOG_SIGNATURE ((DWORD)'gOlT') +#define TRACE_LOG_SIGNATURE_X ((DWORD)'golX') + + +// +// This macro maps a TRACE_LOG pointer to a pointer to the 'extra' +// data associated with the log. +// + +#define TRACE_LOG_TO_EXTRA_DATA(log) (PVOID)( (log) + 1 ) + + +// +// Manipulators. +// + +PTRACE_LOG +CreateTraceLog( + IN LONG LogSize, + IN LONG ExtraBytesInHeader, + IN LONG EntrySize + ); + +VOID +DestroyTraceLog( + IN PTRACE_LOG Log + ); + +LONG +WriteTraceLog( + IN PTRACE_LOG Log, + IN PVOID Entry + ); + +VOID +ResetTraceLog( + IN PTRACE_LOG Log + ); + + +#if defined(__cplusplus) +} // extern "C" +#endif // __cplusplus + + +#endif // _TRACELOG_H_ + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/treehash.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/treehash.h new file mode 100644 index 0000000000..79f5a83ead --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Include/treehash.h @@ -0,0 +1,850 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#include +#include "rwlock.h" +#include "prime.h" + +template +class TREE_HASH_NODE +{ + template + friend class TREE_HASH_TABLE; + + private: + // Next node in the hash table look-aside + TREE_HASH_NODE<_Record> *_pNext; + + // links in the tree structure + TREE_HASH_NODE * _pParentNode; + TREE_HASH_NODE * _pFirstChild; + TREE_HASH_NODE * _pNextSibling; + + // actual record + _Record * _pRecord; + + // hash value + PCWSTR _pszPath; + DWORD _dwHash; +}; + +template +class TREE_HASH_TABLE +{ +protected: + typedef BOOL + (PFN_DELETE_IF)( + _Record * pRecord, + PVOID pvContext + ); + + typedef VOID + (PFN_APPLY)( + _Record * pRecord, + PVOID pvContext + ); + +public: + TREE_HASH_TABLE( + BOOL fCaseSensitive + ) : _ppBuckets( NULL ), + _nBuckets( 0 ), + _nItems( 0 ), + _fCaseSensitive( fCaseSensitive ) + { + } + + virtual + ~TREE_HASH_TABLE(); + + virtual + VOID + ReferenceRecord( + _Record * pRecord + ) = 0; + + virtual + VOID + DereferenceRecord( + _Record * pRecord + ) = 0; + + virtual + PCWSTR + GetKey( + _Record * pRecord + ) = 0; + + DWORD + Count() + { + return _nItems; + } + + virtual + VOID + Clear(); + + HRESULT + Initialize( + DWORD nBucketSize + ); + + DWORD + CalcHash( + PCWSTR pszKey + ) + { + return _fCaseSensitive ? HashString(pszKey) : HashStringNoCase(pszKey); + } + + virtual + VOID + FindKey( + PCWSTR pszKey, + _Record ** ppRecord + ); + + virtual + HRESULT + InsertRecord( + _Record * pRecord + ); + + virtual + VOID + DeleteKey( + PCWSTR pszKey + ); + + virtual + VOID + DeleteIf( + PFN_DELETE_IF pfnDeleteIf, + PVOID pvContext + ); + + VOID + Apply( + PFN_APPLY pfnApply, + PVOID pvContext + ); + +private: + + BOOL + FindNodeInternal( + PCWSTR pszKey, + DWORD dwHash, + TREE_HASH_NODE<_Record> ** ppNode, + TREE_HASH_NODE<_Record> *** pppPreviousNodeNextPointer = NULL + ); + + HRESULT + AddNodeInternal( + PCWSTR pszPath, + DWORD dwHash, + _Record * pRecord, + TREE_HASH_NODE<_Record> * pParentNode, + TREE_HASH_NODE<_Record> ** ppNewNode + ); + + HRESULT + AllocateNode( + PCWSTR pszPath, + DWORD dwHash, + _Record * pRecord, + TREE_HASH_NODE<_Record> * pParentNode, + TREE_HASH_NODE<_Record> ** ppNewNode + ); + + VOID + DeleteNode( + TREE_HASH_NODE<_Record> * pNode + ) + { + if (pNode->_pRecord != NULL) + { + DereferenceRecord(pNode->_pRecord); + pNode->_pRecord = NULL; + } + + HeapFree(GetProcessHeap(), + 0, + pNode); + } + + VOID + DeleteNodeInternal( + TREE_HASH_NODE<_Record> ** ppPreviousNodeNextPointer, + TREE_HASH_NODE<_Record> * pNode + ); + + VOID + RehashTableIfNeeded( + VOID + ); + + TREE_HASH_NODE<_Record> ** _ppBuckets; + DWORD _nBuckets; + DWORD _nItems; + BOOL _fCaseSensitive; + CWSDRWLock _tableLock; +}; + +template +HRESULT +TREE_HASH_TABLE<_Record>::AllocateNode( + PCWSTR pszPath, + DWORD dwHash, + _Record * pRecord, + TREE_HASH_NODE<_Record> * pParentNode, + TREE_HASH_NODE<_Record> ** ppNewNode +) +{ + // + // Allocate enough extra space for pszPath + // + DWORD cchPath = (DWORD) wcslen(pszPath); + if (cchPath >= ((0xffffffff - sizeof(TREE_HASH_NODE<_Record>))/sizeof(WCHAR) - 1)) + { + return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + } + TREE_HASH_NODE<_Record> *pNode = (TREE_HASH_NODE<_Record> *)HeapAlloc( + GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(TREE_HASH_NODE<_Record>) + (cchPath+1)*sizeof(WCHAR)); + if (pNode == NULL) + { + return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + } + + memcpy(pNode+1, pszPath, (cchPath+1)*sizeof(WCHAR)); + pNode->_pszPath = (PCWSTR)(pNode+1); + pNode->_dwHash = dwHash; + pNode->_pNext = pNode->_pNextSibling = pNode->_pFirstChild = NULL; + pNode->_pParentNode = pParentNode; + pNode->_pRecord = pRecord; + + *ppNewNode = pNode; + return S_OK; +} + +template +HRESULT +TREE_HASH_TABLE<_Record>::Initialize( + DWORD nBuckets +) +{ + HRESULT hr = S_OK; + + if ( nBuckets == 0 ) + { + hr = E_INVALIDARG; + goto Failed; + } + + hr = _tableLock.Init(); + if ( FAILED( hr ) ) + { + goto Failed; + } + + if (nBuckets >= 0xffffffff/sizeof(TREE_HASH_NODE<_Record> *)) + { + hr = E_INVALIDARG; + goto Failed; + } + + _ppBuckets = (TREE_HASH_NODE<_Record> **)HeapAlloc( + GetProcessHeap(), + HEAP_ZERO_MEMORY, + nBuckets*sizeof(TREE_HASH_NODE<_Record> *)); + if (_ppBuckets == NULL) + { + hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + goto Failed; + } + _nBuckets = nBuckets; + + return S_OK; + +Failed: + + if (_ppBuckets) + { + HeapFree(GetProcessHeap(), + 0, + _ppBuckets); + _ppBuckets = NULL; + } + + return hr; +} + + +template +TREE_HASH_TABLE<_Record>::~TREE_HASH_TABLE() +{ + if (_ppBuckets == NULL) + { + return; + } + + _ASSERTE(_nItems == 0); + + HeapFree(GetProcessHeap(), + 0, + _ppBuckets); + _ppBuckets = NULL; + _nBuckets = 0; +} + +template +VOID +TREE_HASH_TABLE<_Record>::Clear() +{ + TREE_HASH_NODE<_Record> *pCurrent; + TREE_HASH_NODE<_Record> *pNext; + + _tableLock.ExclusiveAcquire(); + + for (DWORD i=0; i<_nBuckets; i++) + { + pCurrent = _ppBuckets[i]; + _ppBuckets[i] = NULL; + while (pCurrent != NULL) + { + pNext = pCurrent->_pNext; + DeleteNode(pCurrent); + pCurrent = pNext; + } + } + + _nItems = 0; + _tableLock.ExclusiveRelease(); +} + +template +BOOL +TREE_HASH_TABLE<_Record>::FindNodeInternal( + PCWSTR pszKey, + DWORD dwHash, + TREE_HASH_NODE<_Record> ** ppNode, + TREE_HASH_NODE<_Record> *** pppPreviousNodeNextPointer +) +/*++ + Return value indicates whether the item is found + key, dwHash - key and hash for the node to find + ppNode - on successful return, the node found, on failed return, the first + node with hash value greater than the node to be found + pppPreviousNodeNextPointer - the pointer to previous node's _pNext + + This routine may be called under either read or write lock +--*/ +{ + TREE_HASH_NODE<_Record> **ppPreviousNodeNextPointer; + TREE_HASH_NODE<_Record> *pNode; + BOOL fFound = FALSE; + + ppPreviousNodeNextPointer = _ppBuckets + (dwHash % _nBuckets); + pNode = *ppPreviousNodeNextPointer; + while (pNode != NULL) + { + if (pNode->_dwHash == dwHash) + { + if (CompareStringOrdinal(pszKey, + -1, + pNode->_pszPath, + -1, + !_fCaseSensitive) == CSTR_EQUAL) + { + fFound = TRUE; + break; + } + } + else if (pNode->_dwHash > dwHash) + { + break; + } + + ppPreviousNodeNextPointer = &(pNode->_pNext); + pNode = *ppPreviousNodeNextPointer; + } + + *ppNode = pNode; + if (pppPreviousNodeNextPointer != NULL) + { + *pppPreviousNodeNextPointer = ppPreviousNodeNextPointer; + } + return fFound; +} + +template +VOID +TREE_HASH_TABLE<_Record>::FindKey( + PCWSTR pszKey, + _Record ** ppRecord +) +{ + TREE_HASH_NODE<_Record> *pNode; + + *ppRecord = NULL; + + DWORD dwHash = CalcHash(pszKey); + + _tableLock.SharedAcquire(); + + if (FindNodeInternal(pszKey, dwHash, &pNode) && + pNode->_pRecord != NULL) + { + ReferenceRecord(pNode->_pRecord); + *ppRecord = pNode->_pRecord; + } + + _tableLock.SharedRelease(); +} + +template +HRESULT +TREE_HASH_TABLE<_Record>::AddNodeInternal( + PCWSTR pszPath, + DWORD dwHash, + _Record * pRecord, + TREE_HASH_NODE<_Record> * pParentNode, + TREE_HASH_NODE<_Record> ** ppNewNode +) +/*++ + Return value is HRESULT indicating sucess or failure + pszPath, dwHash, pRecord - path, hash value and record to be inserted + pParentNode - this will be the parent of the node being inserted + ppNewNode - on successful return, the new node created and inserted + + This function may be called under a read or write lock +--*/ +{ + TREE_HASH_NODE<_Record> *pNewNode; + TREE_HASH_NODE<_Record> *pNextNode; + TREE_HASH_NODE<_Record> **ppNextPointer; + HRESULT hr; + + // + // Ownership of pRecord is not transferred to pNewNode yet, so remember + // to either set it to null before deleting pNewNode or add an extra + // reference later - this is to make sure we do not do an extra ref/deref + // which users may view as getting flushed out of the hash-table + // + hr = AllocateNode(pszPath, + dwHash, + pRecord, + pParentNode, + &pNewNode); + if (FAILED(hr)) + { + return hr; + } + + do + { + // + // Find the right place to add this node + // + + if (FindNodeInternal(pszPath, dwHash, &pNextNode, &ppNextPointer)) + { + // + // If node already there, record may still need updating + // + if (pRecord != NULL && + InterlockedCompareExchangePointer((PVOID *)&pNextNode->_pRecord, + pRecord, + NULL) == NULL) + { + ReferenceRecord(pRecord); + hr = S_OK; + } + else + { + hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); + } + + // ownership of pRecord has either passed to existing record or + // not to anyone at all + pNewNode->_pRecord = NULL; + DeleteNode(pNewNode); + *ppNewNode = pNextNode; + return hr; + } + + // + // If another node got inserted in betwen, we will have to retry + // + pNewNode->_pNext = pNextNode; + } while (InterlockedCompareExchangePointer((PVOID *)ppNextPointer, + pNewNode, + pNextNode) != pNextNode); + // pass ownership of pRecord now + if (pRecord != NULL) + { + ReferenceRecord(pRecord); + pRecord = NULL; + } + InterlockedIncrement((LONG *)&_nItems); + + // + // update the parent + // + if (pParentNode != NULL) + { + ppNextPointer = &pParentNode->_pFirstChild; + do + { + pNextNode = *ppNextPointer; + pNewNode->_pNextSibling = pNextNode; + } while (InterlockedCompareExchangePointer((PVOID *)ppNextPointer, + pNewNode, + pNextNode) != pNextNode); + } + + *ppNewNode = pNewNode; + return S_OK; +} + +template +HRESULT +TREE_HASH_TABLE<_Record>::InsertRecord( + _Record * pRecord +) +/*++ + This method inserts a node for this record and also empty nodes for paths + in the heirarchy leading upto this path + + The insert is done under only a read-lock - this is possible by keeping + the hashes in a bucket in increasing order and using interlocked operations + to actually insert the item in the hash-bucket lookaside list and the parent + children list + + Returns HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) if the record already exists. + Never leak this error to the end user because "*file* already exists" may be confusing. +--*/ +{ + PCWSTR pszKey = GetKey(pRecord); + STACK_STRU( strPartialPath, 256); + PWSTR pszPartialPath; + DWORD dwHash; + DWORD cchEnd; + HRESULT hr; + TREE_HASH_NODE<_Record> *pParentNode = NULL; + + hr = strPartialPath.Copy(pszKey); + if (FAILED(hr)) + { + goto Finished; + } + pszPartialPath = strPartialPath.QueryStr(); + + _tableLock.SharedAcquire(); + + // + // First find the lowest parent node present + // + for (cchEnd = strPartialPath.QueryCCH() - 1; cchEnd > 0; cchEnd--) + { + if (pszPartialPath[cchEnd] == L'/' || pszPartialPath[cchEnd] == L'\\') + { + pszPartialPath[cchEnd] = L'\0'; + + dwHash = CalcHash(pszPartialPath); + if (FindNodeInternal(pszPartialPath, dwHash, &pParentNode)) + { + pszPartialPath[cchEnd] = pszKey[cchEnd]; + break; + } + pParentNode = NULL; + } + } + + // + // Now go ahead and add the rest of the tree (including our record) + // + for (; cchEnd <= strPartialPath.QueryCCH(); cchEnd++) + { + if (pszPartialPath[cchEnd] == L'\0') + { + dwHash = CalcHash(pszPartialPath); + hr = AddNodeInternal( + pszPartialPath, + dwHash, + (cchEnd == strPartialPath.QueryCCH()) ? pRecord : NULL, + pParentNode, + &pParentNode); + if (FAILED(hr) && + hr != HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) + { + goto Finished; + } + + pszPartialPath[cchEnd] = pszKey[cchEnd]; + } + } + +Finished: + _tableLock.SharedRelease(); + + if (SUCCEEDED(hr)) + { + RehashTableIfNeeded(); + } + + return hr; +} + +template +VOID +TREE_HASH_TABLE<_Record>::DeleteNodeInternal( + TREE_HASH_NODE<_Record> ** ppNextPointer, + TREE_HASH_NODE<_Record> * pNode +) +/*++ + pNode is the node to be deleted + ppNextPointer is the pointer to the previous node's next pointer pointing + to this node + + This function should be called under write-lock +--*/ +{ + // + // First remove this node from hash table + // + *ppNextPointer = pNode->_pNext; + + // + // Now fixup parent + // + if (pNode->_pParentNode != NULL) + { + ppNextPointer = &pNode->_pParentNode->_pFirstChild; + while (*ppNextPointer != pNode) + { + ppNextPointer = &(*ppNextPointer)->_pNextSibling; + } + *ppNextPointer = pNode->_pNextSibling; + } + + // + // Now remove all children recursively + // + TREE_HASH_NODE<_Record> *pChild = pNode->_pFirstChild; + TREE_HASH_NODE<_Record> *pNextChild; + while (pChild != NULL) + { + pNextChild = pChild->_pNextSibling; + + ppNextPointer = _ppBuckets + (pChild->_dwHash % _nBuckets); + while (*ppNextPointer != pChild) + { + ppNextPointer = &(*ppNextPointer)->_pNext; + } + pChild->_pParentNode = NULL; + DeleteNodeInternal(ppNextPointer, pChild); + + pChild = pNextChild; + } + + DeleteNode(pNode); + _nItems--; +} + +template +VOID +TREE_HASH_TABLE<_Record>::DeleteKey( + PCWSTR pszKey +) +{ + TREE_HASH_NODE<_Record> *pNode; + TREE_HASH_NODE<_Record> **ppPreviousNodeNextPointer; + + DWORD dwHash = CalcHash(pszKey); + + _tableLock.ExclusiveAcquire(); + + if (FindNodeInternal(pszKey, dwHash, &pNode, &ppPreviousNodeNextPointer)) + { + DeleteNodeInternal(ppPreviousNodeNextPointer, pNode); + } + + _tableLock.ExclusiveRelease(); +} + +template +VOID +TREE_HASH_TABLE<_Record>::DeleteIf( + PFN_DELETE_IF pfnDeleteIf, + PVOID pvContext +) +{ + TREE_HASH_NODE<_Record> *pNode; + TREE_HASH_NODE<_Record> **ppPreviousNodeNextPointer; + BOOL fDelete; + + _tableLock.ExclusiveAcquire(); + + for (DWORD i=0; i<_nBuckets; i++) + { + ppPreviousNodeNextPointer = _ppBuckets + i; + pNode = *ppPreviousNodeNextPointer; + while (pNode != NULL) + { + // + // Non empty nodes deleted based on DeleteIf, empty nodes deleted + // if they have no children + // + fDelete = FALSE; + if (pNode->_pRecord != NULL) + { + if (pfnDeleteIf(pNode->_pRecord, pvContext)) + { + fDelete = TRUE; + } + } + else if (pNode->_pFirstChild == NULL) + { + fDelete = TRUE; + } + + if (fDelete) + { + if (pNode->_pFirstChild == NULL) + { + DeleteNodeInternal(ppPreviousNodeNextPointer, pNode); + } + else + { + DereferenceRecord(pNode->_pRecord); + pNode->_pRecord = NULL; + } + } + else + { + ppPreviousNodeNextPointer = &pNode->_pNext; + } + + pNode = *ppPreviousNodeNextPointer; + } + } + + _tableLock.ExclusiveRelease(); +} + +template +VOID +TREE_HASH_TABLE<_Record>::Apply( + PFN_APPLY pfnApply, + PVOID pvContext +) +{ + TREE_HASH_NODE<_Record> *pNode; + + _tableLock.SharedAcquire(); + + for (DWORD i=0; i<_nBuckets; i++) + { + pNode = _ppBuckets[i]; + while (pNode != NULL) + { + if (pNode->_pRecord != NULL) + { + pfnApply(pNode->_pRecord, pvContext); + } + + pNode = pNode->_pNext; + } + } + + _tableLock.SharedRelease(); +} + +template +VOID +TREE_HASH_TABLE<_Record>::RehashTableIfNeeded( + VOID +) +{ + TREE_HASH_NODE<_Record> **ppBuckets; + DWORD nBuckets; + TREE_HASH_NODE<_Record> *pNode; + TREE_HASH_NODE<_Record> *pNextNode; + TREE_HASH_NODE<_Record> **ppNextPointer; + TREE_HASH_NODE<_Record> *pNewNextNode; + DWORD nNewBuckets; + + // + // If number of items has become too many, we will double the hash table + // size (we never reduce it however) + // + if (_nItems <= PRIME::GetPrime(2*_nBuckets)) + { + return; + } + + _tableLock.ExclusiveAcquire(); + + nNewBuckets = PRIME::GetPrime(2*_nBuckets); + + if (_nItems <= nNewBuckets) + { + goto Finished; + } + + nBuckets = nNewBuckets; + if (nBuckets >= 0xffffffff/sizeof(TREE_HASH_NODE<_Record> *)) + { + goto Finished; + } + ppBuckets = (TREE_HASH_NODE<_Record> **)HeapAlloc( + GetProcessHeap(), + HEAP_ZERO_MEMORY, + nBuckets*sizeof(TREE_HASH_NODE<_Record> *)); + if (ppBuckets == NULL) + { + goto Finished; + } + + // + // Take out nodes from the old hash table and insert in the new one, make + // sure to keep the hashes in increasing order + // + for (DWORD i=0; i<_nBuckets; i++) + { + pNode = _ppBuckets[i]; + while (pNode != NULL) + { + pNextNode = pNode->_pNext; + + ppNextPointer = ppBuckets + (pNode->_dwHash % nBuckets); + pNewNextNode = *ppNextPointer; + while (pNewNextNode != NULL && + pNewNextNode->_dwHash <= pNode->_dwHash) + { + ppNextPointer = &pNewNextNode->_pNext; + pNewNextNode = pNewNextNode->_pNext; + } + pNode->_pNext = pNewNextNode; + *ppNextPointer = pNode; + + pNode = pNextNode; + } + } + + HeapFree(GetProcessHeap(), 0, _ppBuckets); + _ppBuckets = ppBuckets; + _nBuckets = nBuckets; + ppBuckets = NULL; + +Finished: + + _tableLock.ExclusiveRelease(); +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/LICENSE b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/LICENSE new file mode 100644 index 0000000000..21071075c2 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/MySQL/MySqlConnector.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/MySQL/MySqlConnector.cs new file mode 100644 index 0000000000..ee607e28c7 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/MySQL/MySqlConnector.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; + +namespace Microsoft.Web.Utility +{ + internal static class MySqlConnector + { + public static string[] HardCodedAssemblyVersions + { + get + { + return new string[] + { + "MySql.Data, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d", + "MySql.Data, Version=6.4.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d", + "MySql.Data, Version=6.3.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d", + "MySql.Data, Version=6.2.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d", + "MySql.Data, Version=6.0.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d", + "MySql.Data, Version=6.0.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d", + "MySql.Data, Version=5.2.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d", + "MySql.Data, Version=5.2.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d", + }; + } + } + } +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/AdvApi32.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/AdvApi32.cs new file mode 100644 index 0000000000..9dc6dbfc23 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/AdvApi32.cs @@ -0,0 +1,386 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Text; +using System.Security; +using System.Runtime.Versioning; +using System.Runtime.ConstrainedExecution; +using Microsoft.Win32.SafeHandles; + +namespace Microsoft.Web.Management.PInvoke.AdvApi32 +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct TOKEN_PRIVILEGES + { + public UInt32 PrivilegeCount; + public long Luid; + public UInt32 Attributes; + } + + internal enum TOKEN_INFORMATION_CLASS + { + /// + /// The buffer receives a TOKEN_USER structure that contains the user account of the token. + /// + TokenUser = 1, + + /// + /// The buffer receives a TOKEN_GROUPS structure that contains the group accounts associated with the token. + /// + TokenGroups, + + /// + /// The buffer receives a TOKEN_PRIVILEGES structure that contains the privileges of the token. + /// + TokenPrivileges, + + /// + /// The buffer receives a TOKEN_OWNER structure that contains the default owner security identifier (SID) for newly created objects. + /// + TokenOwner, + + /// + /// The buffer receives a TOKEN_PRIMARY_GROUP structure that contains the default primary group SID for newly created objects. + /// + TokenPrimaryGroup, + + /// + /// The buffer receives a TOKEN_DEFAULT_DACL structure that contains the default DACL for newly created objects. + /// + TokenDefaultDacl, + + /// + /// The buffer receives a TOKEN_SOURCE structure that contains the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information. + /// + TokenSource, + + /// + /// The buffer receives a TOKEN_TYPE value that indicates whether the token is a primary or impersonation token. + /// + TokenType, + + /// + /// The buffer receives a SECURITY_IMPERSONATION_LEVEL value that indicates the impersonation level of the token. If the access token is not an impersonation token, the function fails. + /// + TokenImpersonationLevel, + + /// + /// The buffer receives a TOKEN_STATISTICS structure that contains various token statistics. + /// + TokenStatistics, + + /// + /// The buffer receives a TOKEN_GROUPS structure that contains the list of restricting SIDs in a restricted token. + /// + TokenRestrictedSids, + + /// + /// The buffer receives a DWORD value that indicates the Terminal Services session identifier that is associated with the token. + /// + TokenSessionId, + + /// + /// The buffer receives a TOKEN_GROUPS_AND_PRIVILEGES structure that contains the user SID, the group accounts, the restricted SIDs, and the authentication ID associated with the token. + /// + TokenGroupsAndPrivileges, + + /// + /// Reserved. + /// + TokenSessionReference, + + /// + /// The buffer receives a DWORD value that is nonzero if the token includes the SANDBOX_INERT flag. + /// + TokenSandBoxInert, + + /// + /// Reserved. + /// + TokenAuditPolicy, + + /// + /// The buffer receives a TOKEN_ORIGIN value. + /// + TokenOrigin, + + /// + /// The buffer receives a TOKEN_ELEVATION_TYPE value that specifies the elevation level of the token. + /// + TokenElevationType, + + /// + /// The buffer receives a TOKEN_LINKED_TOKEN structure that contains a handle to another token that is linked to this token. + /// + TokenLinkedToken, + + /// + /// The buffer receives a TOKEN_ELEVATION structure that specifies whether the token is elevated. + /// + TokenElevation, + + /// + /// The buffer receives a DWORD value that is nonzero if the token has ever been filtered. + /// + TokenHasRestrictions, + + /// + /// The buffer receives a TOKEN_ACCESS_INFORMATION structure that specifies security information contained in the token. + /// + TokenAccessInformation, + + /// + /// The buffer receives a DWORD value that is nonzero if virtualization is allowed for the token. + /// + TokenVirtualizationAllowed, + + /// + /// The buffer receives a DWORD value that is nonzero if virtualization is enabled for the token. + /// + TokenVirtualizationEnabled, + + /// + /// The buffer receives a TOKEN_MANDATORY_LABEL structure that specifies the token's integrity level. + /// + TokenIntegrityLevel, + + /// + /// The buffer receives a DWORD value that is nonzero if the token has the UIAccess flag set. + /// + TokenUIAccess, + + /// + /// The buffer receives a TOKEN_MANDATORY_POLICY structure that specifies the token's mandatory integrity policy. + /// + TokenMandatoryPolicy, + + /// + /// The buffer receives the token's logon security identifier (SID). + /// + TokenLogonSid, + + /// + /// The maximum value for this enumeration + /// + MaxTokenInfoClass + } + + internal enum TOKEN_ELEVATION_TYPE + { + TokenElevationTypeDefault = 1, + TokenElevationTypeFull, + TokenElevationTypeLimited + } + + [Flags] + internal enum AccessTokenRights : uint + { + STANDARD_RIGHTS_REQUIRED = 0x000F0000, + STANDARD_RIGHTS_READ = 0x00020000, + TOKEN_ASSIGN_PRIMARY = 0x0001, + TOKEN_DUPLICATE = 0x0002, + TOKEN_IMPERSONATE = 0x0004, + TOKEN_QUERY = 0x0008, + TOKEN_QUERY_SOURCE = 0x0010, + TOKEN_ADJUST_PRIVILEGES = 0x0020, + TOKEN_ADJUST_GROUPS = 0x0040, + TOKEN_ADJUST_DEFAULT = 0x0080, + TOKEN_ADJUST_SESSIONID = 0x0100, + TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY, + TOKEN_ALL_ACCESS = + STANDARD_RIGHTS_REQUIRED | + TOKEN_ASSIGN_PRIMARY | + TOKEN_DUPLICATE | + TOKEN_IMPERSONATE | + TOKEN_QUERY | + TOKEN_QUERY_SOURCE | + TOKEN_ADJUST_PRIVILEGES | + TOKEN_ADJUST_GROUPS | + TOKEN_ADJUST_DEFAULT | + TOKEN_ADJUST_SESSIONID + } + + internal static class NativeMethods + { + private const String ADVAPI32 = "advapi32.dll"; + + // TODO: Should be moved into enums? + internal const int READ_CONTROL = 0x00020000; + internal const int SYNCHRONIZE = 0x00100000; + internal const int STANDARD_RIGHTS_READ = READ_CONTROL; + internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL; + + internal const int KEY_QUERY_VALUE = 0x0001; + internal const int KEY_SET_VALUE = 0x0002; + internal const int KEY_CREATE_SUB_KEY = 0x0004; + internal const int KEY_ENUMERATE_SUB_KEYS = 0x0008; + internal const int KEY_NOTIFY = 0x0010; + + internal const int KEY_READ = ((STANDARD_RIGHTS_READ | + KEY_QUERY_VALUE | + KEY_ENUMERATE_SUB_KEYS | + KEY_NOTIFY) + & + (~SYNCHRONIZE)); + + internal const int KEY_WRITE = ((STANDARD_RIGHTS_WRITE | + KEY_SET_VALUE | + KEY_CREATE_SUB_KEY) + & + (~SYNCHRONIZE)); + + internal const int KEY_WOW64_64KEY = 0x0100; + internal const int KEY_WOW64_32KEY = 0x0200; + + internal const int ERROR_MORE_DATA = 0xEA; + internal const int ERROR_ACCESS_DENIED = 0x5; + + internal const int REG_OPTION_NON_VOLATILE = 0x0000; // (default) keys are persisted beyond reboot/unload + internal const int REG_OPTION_VOLATILE = 0x0001; // All keys created by the function are volatile + internal const int REG_OPTION_CREATE_LINK = 0x0002; // They key is a symbolic link + internal const int REG_OPTION_BACKUP_RESTORE = 0x0004; // Use SE_BACKUP_NAME process special privileges + internal const int REG_NONE = 0; // No value type + internal const int REG_SZ = 1; // Unicode nul terminated string + internal const int REG_EXPAND_SZ = 2; // Unicode nul terminated string + internal const int REG_BINARY = 3; // Free form binary + internal const int REG_DWORD = 4; // 32-bit number + internal const int REG_DWORD_LITTLE_ENDIAN = 4; // 32-bit number (same as REG_DWORD) + internal const int REG_DWORD_BIG_ENDIAN = 5; // 32-bit number + internal const int REG_LINK = 6; // Symbolic Link (unicode) + internal const int REG_MULTI_SZ = 7; // Multiple Unicode strings + internal const int REG_RESOURCE_LIST = 8; // Resource list in the resource map + internal const int REG_FULL_RESOURCE_DESCRIPTOR = 9; // Resource list in the hardware description + internal const int REG_RESOURCE_REQUIREMENTS_LIST = 10; + internal const int REG_QWORD = 11; // 64-bit number + + [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool AdjustTokenPrivileges( + SafeHandleZeroIsInvalid TokenHandle, + [MarshalAs(UnmanagedType.Bool)] + bool DisableAllPrivileges, + ref TOKEN_PRIVILEGES NewState, + int len, + IntPtr prev, + IntPtr relen); + + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); + + [DllImport("advapi32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetTokenInformation( + SafeHandleZeroIsInvalid TokenHandle, + TOKEN_INFORMATION_CLASS TokenInformationClass, + HGlobalBuffer TokenInformation, + int TokenInformationLength, + out int ReturnLength); + + [DllImport("advapi32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool OpenProcessToken( + SafeHandleZeroIsInvalid ProcessHandle, + AccessTokenRights DesiredAccess, + out SafeHandleZeroIsInvalid TokenHandle); + + [DllImport("ADVAPI32.DLL"), + SuppressUnmanagedCodeSecurity, + ResourceExposure(ResourceScope.None), + ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + internal static extern int RegCloseKey(IntPtr hKey); + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] + internal static extern int RegOpenKeyEx(SafeRegistryHandle hKey, String lpSubKey, + int ulOptions, int samDesired, out SafeRegistryHandle hkResult); + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] + internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName, + int[] lpReserved, ref int lpType, [Out] byte[] lpData, + ref int lpcbData); + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] + internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName, + int[] lpReserved, ref int lpType, ref int lpData, + ref int lpcbData); + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] + internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName, + int[] lpReserved, ref int lpType, ref long lpData, + ref int lpcbData); + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] + internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName, + int[] lpReserved, ref int lpType, [Out] char[] lpData, + ref int lpcbData); + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] + internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName, + int[] lpReserved, ref int lpType, StringBuilder lpData, + ref int lpcbData); + + public static void EnableShutdownPrivilege() + { + const int SE_PRIVILEGE_ENABLED = 0x00000002; + const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege"; + + bool retVal; + + using (SafeHandleZeroIsInvalid hproc = Kernel32.NativeMethods.GetCurrentProcess()) + { + TOKEN_PRIVILEGES tp; + SafeHandleZeroIsInvalid htok; + retVal = OpenProcessToken(hproc, AccessTokenRights.TOKEN_ADJUST_PRIVILEGES | AccessTokenRights.TOKEN_QUERY, out htok); + if (!retVal) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + using (htok) + { + tp.PrivilegeCount = 1; + tp.Luid = 0; + tp.Attributes = SE_PRIVILEGE_ENABLED; + retVal = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid); + if (!retVal) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); + if (!retVal) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + } + } + } + } + + [SecurityCritical] + internal sealed class SafeRegistryHandle : SafeHandleZeroOrMinusOneIsInvalid + { + [SecurityCritical] + internal SafeRegistryHandle() + : base(true) + { + } + + [SecurityCritical] + public SafeRegistryHandle(IntPtr preexistingHandle, bool ownsHandle) + : base(ownsHandle) + { + SetHandle(preexistingHandle); + } + + [SecurityCritical] + override protected bool ReleaseHandle() + { + return (Microsoft.Web.Management.PInvoke.AdvApi32.NativeMethods.RegCloseKey(handle) == 0); + } + } +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Common.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Common.cs new file mode 100644 index 0000000000..6d6a3209a7 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Common.cs @@ -0,0 +1,111 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Runtime.InteropServices; + +// Any reference to Common.cs should also include Kernel32.cs because +// SafeHandleZeroIsInvalid (from Common.cs) uses CloseHandle (from Kernel32.cs) +namespace Microsoft.Web.Management.PInvoke +{ + internal enum Win32ErrorCode + { + ERROR_FILE_NOT_FOUND = 2, + ERROR_PATH_NOT_FOUND = 3, + ERROR_ACCESS_DENIED = 5, + ERROR_INVALID_HANDLE = 6, + ERROR_INVALID_DRIVE = 15, + ERROR_NO_MORE_FILES = 18, + ERROR_NOT_READY = 21, + ERROR_SHARING_VIOLATION = 32, + ERROR_FILE_EXISTS = 80, + ERROR_INVALID_PARAMETER = 87, // 0x57 + ERROR_INVALID_NAME = 123, // 0x7b + ERROR_BAD_PATHNAME = 161, + ERROR_ALREADY_EXISTS = 183, + ERROR_FILENAME_EXCED_RANGE = 206, + ERROR_OPERATION_ABORTED = 995, + ELEMENT_NOT_FOUND = 0x490 + } + + internal static class Extension + { + public static int AsHRESULT(Win32ErrorCode errorCode) + { + return (int)((uint)errorCode | 0x80070000); + } + } + + internal class SafeHandleZeroIsInvalid : SafeHandle + { + public SafeHandleZeroIsInvalid() + : base(IntPtr.Zero, true) + { + } + + public SafeHandleZeroIsInvalid(IntPtr newHandle) + : base(IntPtr.Zero, true) + { + this.SetHandle(newHandle); + } + + public override bool IsInvalid + { + get + { + return this.handle == IntPtr.Zero; + } + } + + protected override bool ReleaseHandle() + { + return Kernel32.NativeMethods.CloseHandle(this.handle); + } + } + + internal class HGlobalBuffer : SafeHandle + { + private int _size; + + public HGlobalBuffer(int size) + : base(IntPtr.Zero, true) + { + _size = size; + this.handle = Marshal.AllocHGlobal(size); + } + + protected override bool ReleaseHandle() + { + if (!this.IsInvalid) + { + Marshal.FreeHGlobal(this.handle); + this.handle = IntPtr.Zero; + } + + return true; + } + + public override bool IsInvalid + { + get + { + return this.handle == IntPtr.Zero; + } + } + + public T GetCopyAs() + { + return (T)Marshal.PtrToStructure(this.handle, typeof(T)); + } + + public int Size + { + get + { + return _size; + } + } + + public static readonly HGlobalBuffer NULL = new HGlobalBuffer(0); + } +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Fusion.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Fusion.cs new file mode 100644 index 0000000000..dd3391ff94 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Fusion.cs @@ -0,0 +1,179 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Text; + +namespace Microsoft.Web.Utility.PInvoke.Fusion +{ + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("CD193BC0-B4BC-11d2-9833-00C04FC31D2E")] + internal interface IAssemblyName + { + [PreserveSig()] + int SetProperty( + int PropertyId, + IntPtr pvProperty, + int cbProperty); + + [PreserveSig()] + int GetProperty( + int PropertyId, + IntPtr pvProperty, + ref int pcbProperty); + + [PreserveSig()] + int Finalize(); + + [PreserveSig()] + int GetDisplayName( + StringBuilder pDisplayName, + ref int pccDisplayName, + int displayFlags); + + [PreserveSig()] + int Reserved(ref Guid guid, + Object obj1, + Object obj2, + String string1, + Int64 llFlags, + IntPtr pvReserved, + int cbReserved, + out IntPtr ppv); + + [PreserveSig()] + int GetName( + ref int pccBuffer, + StringBuilder pwzName); + + [PreserveSig()] + int GetVersion( + out int versionHi, + out int versionLow); + [PreserveSig()] + int IsEqual( + IAssemblyName pAsmName, + int cmpFlags); + + [PreserveSig()] + int Clone(out IAssemblyName pAsmName); + }// IAssemblyName + + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")] + internal interface IAssemblyCache + { + [PreserveSig()] + int UninstallAssembly( + int flags, + [MarshalAs(UnmanagedType.LPWStr)] + string assemblyName, + IntPtr refData, + out int disposition); + + [PreserveSig()] + int QueryAssemblyInfo( + int flags, + [MarshalAs(UnmanagedType.LPWStr)] + string assemblyName, + ref AssemblyInfo assemblyInfo); + [PreserveSig()] + int Reserved( + int flags, + IntPtr pvReserved, + out object ppAsmItem, + [MarshalAs(UnmanagedType.LPWStr)] + string assemblyName); + [PreserveSig()] + int Reserved(out object ppAsmScavenger); + + [PreserveSig()] + int InstallAssembly( + int flags, + [MarshalAs(UnmanagedType.LPWStr)] + string assemblyFilePath, + IntPtr refData); + }// IAssemblyCache + + [StructLayout(LayoutKind.Sequential)] + internal struct AssemblyInfo + { + public int cbAssemblyInfo; // size of this structure for future expansion + public int assemblyFlags; + public long assemblySizeInKB; + [MarshalAs(UnmanagedType.LPWStr)] + public string currentAssemblyPath; + public int cchBuf; // size of path buf. + } + + [Flags] + internal enum AssemblyCacheFlags + { + GAC = 2, + } + + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("21b8916c-f28e-11d2-a473-00c04f8ef448")] + internal interface IAssemblyEnum + { + [PreserveSig()] + int GetNextAssembly( + IntPtr pvReserved, + out IAssemblyName ppName, + int flags); + + [PreserveSig()] + int Reset(); + [PreserveSig()] + int Clone(out IAssemblyEnum ppEnum); + } + + [Flags] + internal enum AssemblyNameDisplayFlags + { + VERSION = 0x01, + CULTURE = 0x02, + PUBLIC_KEY_TOKEN = 0x04, + PROCESSORARCHITECTURE = 0x20, + RETARGETABLE = 0x80, + + // This enum might change in the future to include + // more attributes. + ALL = + VERSION + | CULTURE + | PUBLIC_KEY_TOKEN + | PROCESSORARCHITECTURE + | RETARGETABLE + } + + internal enum CreateAssemblyNameObjectFlags + { + CANOF_DEFAULT = 0, + CANOF_PARSE_DISPLAY_NAME = 1, + } + + internal static class NativeMethods + { + [DllImport("fusion.dll")] + public static extern int CreateAssemblyCache( + out IAssemblyCache ppAsmCache, + int reserved); + + [DllImport("fusion.dll")] + public static extern int CreateAssemblyEnum( + out IAssemblyEnum ppEnum, + IntPtr pUnkReserved, + IAssemblyName pName, + AssemblyCacheFlags flags, + IntPtr pvReserved); + + [DllImport("fusion.dll")] + public static extern int CreateAssemblyNameObject( + out IAssemblyName ppAssemblyNameObj, + [MarshalAs(UnmanagedType.LPWStr)] + String szAssemblyName, + CreateAssemblyNameObjectFlags flags, + IntPtr pvReserved); + } +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Kernel32.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Kernel32.cs new file mode 100644 index 0000000000..91265956b5 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Kernel32.cs @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; + +// Any reference to Common.cs should also include Kernel32.cs because +// SafeHandleZeroIsInvalid (from Common.cs) uses CloseHandle (from Kernel32.cs) +namespace Microsoft.Web.Management.PInvoke.Kernel32 +{ + internal enum OSProductType : byte + { + VER_NT_WORKSTATION = 0x0000001, + VER_NT_SERVER = 0x0000003, + VER_NT_DOMAIN_CONTROLLER = 0x0000002, + } + + [StructLayout(LayoutKind.Sequential)] + internal struct OSVERSIONINFOEX + { + public int dwOSVersionInfoSize; + public int dwMajorVersion; + public int dwMinorVersion; + public int dwBuildNumber; + public int dwPlatformId; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + public string szCSDVersion; + public short wServicePackMajor; + public short wServicePackMinor; + public short wSuiteMask; + public OSProductType wProductType; + public byte wReserved; + + public bool IsServer + { + get + { + return + wProductType == OSProductType.VER_NT_SERVER || + wProductType == OSProductType.VER_NT_DOMAIN_CONTROLLER; + } + } + + public bool IsClient + { + get + { + return + wProductType == OSProductType.VER_NT_WORKSTATION; + } + } + } + + internal static class NativeMethods + { + public static OSVERSIONINFOEX GetVersionEx() + { + OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX(); + osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX)); + if (!GetVersionEx(ref osVersionInfo)) + { + throw new Win32Exception(); + } + + return osVersionInfo; + } + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CloseHandle(IntPtr hHandle); + + [DllImport("kernel32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + [SuppressMessage("Microsoft.Usage", "CA2205:UseManagedEquivalentsOfWin32Api", Justification = "GetVersionEx returns more information")] + private static extern bool GetVersionEx(ref OSVERSIONINFOEX osVersionInfo); + + [DllImport("kernel32.dll", ExactSpelling = true)] + internal static extern SafeHandleZeroIsInvalid GetCurrentProcess(); + + // WARNING: Vista+ ONLY + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetProductInfo(uint dwOSMajorVersion, uint dwOSMinorVersion, uint dwSpMajorVersion, uint spMinorVersion, out uint pdwReturnedProductType); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr); + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WritePrivateProfileString(string applicationName, string keyName, string stringValue, string fileName); + } +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Mlang.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Mlang.cs new file mode 100644 index 0000000000..e6e1ff51bd --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/Mlang.cs @@ -0,0 +1,768 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; + +namespace Microsoft.Web.Management.PInvoke.MLang +{ + internal enum HRESULT : uint + { + S_OK = 0x0, + S_FALSE = 0x1, + E_FAIL = 0x80004005, + } + + internal static class NativeMethods + { + [StructLayout(LayoutKind.Explicit, Pack = 4)] + public struct __MIDL_IWinTypes_0009 + { + // Fields + [FieldOffset(0)] + public int hInproc; + [FieldOffset(0)] + public int hRemote; + } + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct _RemotableHandle + { + public int fContext; + public __MIDL_IWinTypes_0009 u; + } + + [ComImport, CoClass(typeof(CMLangConvertCharsetClass)), Guid("D66D6F98-CDAA-11D0-B822-00C04FC9B31F")] + public interface CMLangConvertCharset : IMLangConvertCharset + { + } + + [ComImport, TypeLibType((short)2), Guid("D66D6F99-CDAA-11D0-B822-00C04FC9B31F"), ClassInterface((short)0)] + public class CMLangConvertCharsetClass : IMLangConvertCharset, CMLangConvertCharset + { + // Methods + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void DoConversion([In] ref byte pSrcStr, [In, Out] ref uint pcSrcSize, out byte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void DoConversionFromUnicode([In] ref ushort pSrcStr, [In, Out] ref uint pcSrcSize, out sbyte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void DoConversionToUnicode([In] ref sbyte pSrcStr, [In, Out] ref uint pcSrcSize, out ushort pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetDestinationCodePage(out uint puiDstCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetProperty(out uint pdwProperty); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetSourceCodePage(out uint puiSrcCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void Initialize([In] uint uiSrcCodePage, [In] uint uiDstCodePage, [In] uint dwProperty); + } + + [ComImport, Guid("C04D65CE-B70D-11D0-B188-00AA0038C969"), CoClass(typeof(CMLangStringClass))] + public interface CMLangString : IMLangString + { + } + + [ComImport, TypeLibType((short)2), Guid("C04D65CF-B70D-11D0-B188-00AA0038C969"), ClassInterface((short)0)] + public class CMLangStringClass : IMLangString, CMLangString, IMLangStringWStr, IMLangStringAStr + { + // Methods + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetAStr([In] int lSrcPos, [In] int lSrcLen, [In] uint uCodePageIn, out uint puCodePageOut, [Out, MarshalAs(UnmanagedType.LPStr)] string pszDest, [In] int cchDest, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern int GetLength(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetLocale([In] int lSrcPos, [In] int lSrcMaxLen, out uint plocale, out int plLocalePos, out int plLocaleLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetMLStr([In] int lSrcPos, [In] int lSrcLen, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, [In] uint dwClsContext, [In] ref Guid piid, [MarshalAs(UnmanagedType.IUnknown)] out object ppDestMLStr, out int plDestPos, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetStrBufA([In] int lSrcPos, [In] int lSrcMaxLen, out uint puDestCodePage, [MarshalAs(UnmanagedType.Interface)] out IMLangStringBufA ppDestBuf, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetStrBufW([In] int lSrcPos, [In] int lSrcMaxLen, [MarshalAs(UnmanagedType.Interface)] out IMLangStringBufW ppDestBuf, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetWStr([In] int lSrcPos, [In] int lSrcLen, [Out, MarshalAs(UnmanagedType.LPWStr)] string pszDest, [In] int cchDest, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern int IMLangStringAStr_GetLength(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangStringAStr_GetLocale([In] int lSrcPos, [In] int lSrcMaxLen, out uint plocale, out int plLocalePos, out int plLocaleLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangStringAStr_GetMLStr([In] int lSrcPos, [In] int lSrcLen, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, [In] uint dwClsContext, [In] ref Guid piid, [MarshalAs(UnmanagedType.IUnknown)] out object ppDestMLStr, out int plDestPos, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangStringAStr_SetLocale([In] int lDestPos, [In] int lDestLen, [In] uint locale); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangStringAStr_SetMLStr([In] int lDestPos, [In] int lDestLen, [In, MarshalAs(UnmanagedType.IUnknown)] object pSrcMLStr, [In] int lSrcPos, [In] int lSrcLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangStringAStr_Sync([In] int fNoAccess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern int IMLangStringWStr_GetLength(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangStringWStr_GetMLStr([In] int lSrcPos, [In] int lSrcLen, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, [In] uint dwClsContext, [In] ref Guid piid, [MarshalAs(UnmanagedType.IUnknown)] out object ppDestMLStr, out int plDestPos, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangStringWStr_SetMLStr([In] int lDestPos, [In] int lDestLen, [In, MarshalAs(UnmanagedType.IUnknown)] object pSrcMLStr, [In] int lSrcPos, [In] int lSrcLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangStringWStr_Sync([In] int fNoAccess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void LockAStr([In] int lSrcPos, [In] int lSrcLen, [In] int lFlags, [In] uint uCodePageIn, [In] int cchRequest, out uint puCodePageOut, [MarshalAs(UnmanagedType.LPStr)] out string ppszDest, out int pcchDest, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void LockWStr([In] int lSrcPos, [In] int lSrcLen, [In] int lFlags, [In] int cchRequest, [MarshalAs(UnmanagedType.LPWStr)] out string ppszDest, out int pcchDest, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void SetAStr([In] int lDestPos, [In] int lDestLen, [In] uint uCodePage, [In, MarshalAs(UnmanagedType.LPStr)] string pszSrc, [In] int cchSrc, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void SetLocale([In] int lDestPos, [In] int lDestLen, [In] uint locale); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void SetMLStr([In] int lDestPos, [In] int lDestLen, [In, MarshalAs(UnmanagedType.IUnknown)] object pSrcMLStr, [In] int lSrcPos, [In] int lSrcLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void SetStrBufA([In] int lDestPos, [In] int lDestLen, [In] uint uCodePage, [In, MarshalAs(UnmanagedType.Interface)] IMLangStringBufA pSrcBuf, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void SetStrBufW([In] int lDestPos, [In] int lDestLen, [In, MarshalAs(UnmanagedType.Interface)] IMLangStringBufW pSrcBuf, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void SetWStr([In] int lDestPos, [In] int lDestLen, [In, MarshalAs(UnmanagedType.LPWStr)] string pszSrc, [In] int cchSrc, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void Sync([In] int fNoAccess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void UnlockAStr([In, MarshalAs(UnmanagedType.LPStr)] string pszSrc, [In] int cchSrc, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void UnlockWStr([In, MarshalAs(UnmanagedType.LPWStr)] string pszSrc, [In] int cchSrc, out int pcchActual, out int plActualLen); + } + + [ComImport, Guid("275C23E1-3747-11D0-9FEA-00AA003F8646"), CoClass(typeof(CMultiLanguageClass))] + public interface CMultiLanguage : IMultiLanguage + { + } + + [ComImport, TypeLibType(TypeLibTypeFlags.FCanCreate), ClassInterface(ClassInterfaceType.None), Guid("275C23E2-3747-11D0-9FEA-00AA003F8646")] + public class CMultiLanguageClass : IMultiLanguage, CMultiLanguage, IMLangCodePages, IMLangFontLink, IMLangLineBreakConsole, IMultiLanguage2, IMLangFontLink2, IMultiLanguage3 + { + // Methods + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void BreakLineA([In] uint locale, [In] uint uCodePage, [In] ref sbyte pszSrc, [In] int cchSrc, [In] int cMaxColumns, out int pcchLine, out int pcchSkip); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void BreakLineML([In, MarshalAs(UnmanagedType.Interface)] CMLangString pSrcMLStr, [In] int lSrcPos, [In] int lSrcLen, [In] int cMinColumns, [In] int cMaxColumns, out int plLineLen, out int plSkipLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void BreakLineW([In] uint locale, [In] ref ushort pszSrc, [In] int cchSrc, [In] int cMaxColumns, out int pcchLine, out int pcchSkip); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void CodePagesToCodePage([In] uint dwCodePages, [In] uint uDefaultCodePage, out uint puCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void CodePageToCodePages([In] uint uCodePage, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void CodePageToScriptID([In] uint uiCodePage, out byte pSid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ConvertString([In, Out] ref uint pdwMode, [In] uint dwSrcEncoding, [In] uint dwDstEncoding, [In] ref byte pSrcStr, [In, Out] ref uint pcSrcSize, out byte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ConvertStringFromUnicode([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref ushort pSrcStr, [In, Out] ref uint pcSrcSize, out sbyte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ConvertStringFromUnicodeEx([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref ushort pSrcStr, [In, Out] ref uint pcSrcSize, out sbyte pDstStr, [In, Out] ref uint pcDstSize, [In] uint dwFlag, [In] ref ushort lpFallBack); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ConvertStringInIStream([In, Out] ref uint pdwMode, [In] uint dwFlag, [In] ref ushort lpFallBack, [In] uint dwSrcEncoding, [In] uint dwDstEncoding, [In, MarshalAs(UnmanagedType.Interface)] IStream pstmIn, [In, MarshalAs(UnmanagedType.Interface)] IStream pstmOut); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ConvertStringReset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ConvertStringToUnicode([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref sbyte pSrcStr, [In, Out] ref uint pcSrcSize, out ushort pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ConvertStringToUnicodeEx([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref sbyte pSrcStr, [In, Out] ref uint pcSrcSize, out ushort pDstStr, [In, Out] ref uint pcDstSize, [In] uint dwFlag, [In] ref ushort lpFallBack); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void CreateConvertCharset([In] uint uiSrcCodePage, [In] uint uiDstCodePage, [In] uint dwProperty, [MarshalAs(UnmanagedType.Interface)] out CMLangConvertCharset ppMLangConvertCharset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void DetectCodepageInIStream([In] uint dwFlag, [In] uint dwPrefWinCodePage, [In, MarshalAs(UnmanagedType.Interface)] IStream pstmIn, out DetectEncodingInfo lpEncoding, [In, Out] ref int pnScores); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [PreserveSig] + public virtual extern HRESULT DetectInputCodepage([In] MLDETECTCP dwFlag, [In] uint dwPrefWinCodePage, [In] ref byte pSrcStr, [In, Out] ref int pcSrcSize, ref DetectEncodingInfo lpEncoding, [In, Out] ref int pnScores); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void DetectOutboundCodePage([In] uint dwFlags, [In, MarshalAs(UnmanagedType.LPWStr)] string lpWideCharStr, [In] uint cchWideChar, [In] ref uint puiPreferredCodePages, [In] uint nPreferredCodePages, out uint puiDetectedCodePages, [In, Out] ref uint pnDetectedCodePages, [In, MarshalAs(UnmanagedType.LPWStr)] string lpSpecialChar); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void DetectOutboundCodePageInIStream([In] uint dwFlags, [In, MarshalAs(UnmanagedType.Interface)] IStream pStrIn, [In] ref uint puiPreferredCodePages, [In] uint nPreferredCodePages, out uint puiDetectedCodePages, [In, Out] ref uint pnDetectedCodePages, [In, MarshalAs(UnmanagedType.LPWStr)] string lpSpecialChar); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Interface)] + public virtual extern IEnumCodePage EnumCodePages([In] NativeMethods.MIMECONTF grfFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void EnumCodePages([In] uint grfFlags, [In] ushort LangId, [MarshalAs(UnmanagedType.Interface)] out IEnumCodePage ppEnumCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void EnumRfc1766([MarshalAs(UnmanagedType.Interface)] out IEnumRfc1766 ppEnumRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void EnumRfc1766([In] ushort LangId, [MarshalAs(UnmanagedType.Interface)] out IEnumRfc1766 ppEnumRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void EnumScripts([In] uint dwFlags, [In] ushort LangId, [MarshalAs(UnmanagedType.Interface)] out IEnumScript ppEnumScript); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetCharCodePages([In] ushort chSrc, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetCharsetInfo([In, MarshalAs(UnmanagedType.BStr)] string Charset, out MIMECSETINFO pCharsetInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetCodePageDescription([In] uint uiCodePage, [In] uint lcid, [Out, MarshalAs(UnmanagedType.LPWStr)] string lpWideCharStr, [In] int cchWideChar); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetCodePageInfo([In] uint uiCodePage, out MIMECPINFO pCodePageInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetCodePageInfo([In] uint uiCodePage, [In] ushort LangId, out MIMECPINFO pCodePageInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetFamilyCodePage([In] uint uiCodePage, out uint puiFamilyCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetFontCodePages([In, ComAliasName("MultiLanguage.wireHDC")] ref _RemotableHandle hDC, [In, ComAliasName("MultiLanguage.wireHFONT")] ref _RemotableHandle hFont, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetFontUnicodeRanges([In, ComAliasName("MultiLanguage.wireHDC")] ref _RemotableHandle hDC, [In, Out] ref uint puiRanges, out UNICODERANGE pUranges); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetLcidFromRfc1766(out uint plocale, [In, MarshalAs(UnmanagedType.BStr)] string bstrRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetNumberOfCodePageInfo(out uint pcCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetNumberOfScripts(out uint pnScripts); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetRfc1766FromLcid([In] uint locale, [MarshalAs(UnmanagedType.BStr)] out string pbstrRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetRfc1766Info([In] uint locale, out RFC1766INFO pRfc1766Info); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetRfc1766Info([In] uint locale, [In] ushort LangId, out RFC1766INFO pRfc1766Info); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetScriptFontInfo([In] byte sid, [In] uint dwFlags, [In, Out] ref uint puiFonts, out SCRIPFONTINFO pScriptFont); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void GetStrCodePages([In] ref ushort pszSrc, [In] int cchSrc, [In] uint dwPriorityCodePages, out uint pdwCodePages, out int pcchCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink_CodePagesToCodePage([In] uint dwCodePages, [In] uint uDefaultCodePage, out uint puCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink_CodePageToCodePages([In] uint uCodePage, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink_GetCharCodePages([In] ushort chSrc, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink_GetStrCodePages([In] ref ushort pszSrc, [In] int cchSrc, [In] uint dwPriorityCodePages, out uint pdwCodePages, out int pcchCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink2_CodePagesToCodePage([In] uint dwCodePages, [In] uint uDefaultCodePage, out uint puCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink2_CodePageToCodePages([In] uint uCodePage, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink2_GetCharCodePages([In] ushort chSrc, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink2_GetFontCodePages([In, ComAliasName("MultiLanguage.wireHDC")] ref _RemotableHandle hDC, [In, ComAliasName("MultiLanguage.wireHFONT")] ref _RemotableHandle hFont, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink2_GetStrCodePages([In] ref ushort pszSrc, [In] int cchSrc, [In] uint dwPriorityCodePages, out uint pdwCodePages, out int pcchCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink2_ReleaseFont([In, ComAliasName("MultiLanguage.wireHFONT")] ref _RemotableHandle hFont); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMLangFontLink2_ResetFontMapping(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_ConvertString([In, Out] ref uint pdwMode, [In] uint dwSrcEncoding, [In] uint dwDstEncoding, [In] ref byte pSrcStr, [In, Out] ref uint pcSrcSize, out byte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_ConvertStringFromUnicode([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref ushort pSrcStr, [In, Out] ref uint pcSrcSize, out sbyte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_ConvertStringReset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_ConvertStringToUnicode([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref sbyte pSrcStr, [In, Out] ref uint pcSrcSize, out ushort pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_CreateConvertCharset([In] uint uiSrcCodePage, [In] uint uiDstCodePage, [In] uint dwProperty, [MarshalAs(UnmanagedType.Interface)] out CMLangConvertCharset ppMLangConvertCharset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_GetCharsetInfo([In, MarshalAs(UnmanagedType.BStr)] string Charset, out MIMECSETINFO pCharsetInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_GetFamilyCodePage([In] uint uiCodePage, out uint puiFamilyCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_GetLcidFromRfc1766(out uint plocale, [In, MarshalAs(UnmanagedType.BStr)] string bstrRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_GetNumberOfCodePageInfo(out uint pcCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_GetRfc1766FromLcid([In] uint locale, [MarshalAs(UnmanagedType.BStr)] out string pbstrRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage2_IsConvertible([In] uint dwSrcEncoding, [In] uint dwDstEncoding); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_ConvertString([In, Out] ref uint pdwMode, [In] uint dwSrcEncoding, [In] uint dwDstEncoding, [In] ref byte pSrcStr, [In, Out] ref uint pcSrcSize, out byte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_ConvertStringFromUnicode([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref ushort pSrcStr, [In, Out] ref uint pcSrcSize, out sbyte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_ConvertStringFromUnicodeEx([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref ushort pSrcStr, [In, Out] ref uint pcSrcSize, out sbyte pDstStr, [In, Out] ref uint pcDstSize, [In] uint dwFlag, [In] ref ushort lpFallBack); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_ConvertStringInIStream([In, Out] ref uint pdwMode, [In] uint dwFlag, [In] ref ushort lpFallBack, [In] uint dwSrcEncoding, [In] uint dwDstEncoding, [In, MarshalAs(UnmanagedType.Interface)] IStream pstmIn, [In, MarshalAs(UnmanagedType.Interface)] IStream pstmOut); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_ConvertStringReset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_ConvertStringToUnicode([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref sbyte pSrcStr, [In, Out] ref uint pcSrcSize, out ushort pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_ConvertStringToUnicodeEx([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref sbyte pSrcStr, [In, Out] ref uint pcSrcSize, out ushort pDstStr, [In, Out] ref uint pcDstSize, [In] uint dwFlag, [In] ref ushort lpFallBack); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_CreateConvertCharset([In] uint uiSrcCodePage, [In] uint uiDstCodePage, [In] uint dwProperty, [MarshalAs(UnmanagedType.Interface)] out CMLangConvertCharset ppMLangConvertCharset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_DetectCodepageInIStream([In] uint dwFlag, [In] uint dwPrefWinCodePage, [In, MarshalAs(UnmanagedType.Interface)] IStream pstmIn, out DetectEncodingInfo lpEncoding, [In, Out] ref int pnScores); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_DetectInputCodepage([In] uint dwFlag, [In] uint dwPrefWinCodePage, [In] ref sbyte pSrcStr, [In, Out] ref int pcSrcSize, out DetectEncodingInfo lpEncoding, [In, Out] ref int pnScores); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_EnumCodePages([In] NativeMethods.MIMECONTF grfFlags, [In] ushort LangId, [MarshalAs(UnmanagedType.Interface)] out IEnumCodePage ppEnumCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_EnumRfc1766([In] ushort LangId, [MarshalAs(UnmanagedType.Interface)] out IEnumRfc1766 ppEnumRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_EnumScripts([In] uint dwFlags, [In] ushort LangId, [MarshalAs(UnmanagedType.Interface)] out IEnumScript ppEnumScript); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_GetCharsetInfo([In, MarshalAs(UnmanagedType.BStr)] string Charset, out MIMECSETINFO pCharsetInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_GetCodePageDescription([In] uint uiCodePage, [In] uint lcid, [Out, MarshalAs(UnmanagedType.LPWStr)] string lpWideCharStr, [In] int cchWideChar); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_GetCodePageInfo([In] uint uiCodePage, [In] ushort LangId, out MIMECPINFO pCodePageInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_GetFamilyCodePage([In] uint uiCodePage, out uint puiFamilyCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_GetLcidFromRfc1766(out uint plocale, [In, MarshalAs(UnmanagedType.BStr)] string bstrRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_GetNumberOfCodePageInfo(out uint pcCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_GetNumberOfScripts(out uint pnScripts); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_GetRfc1766FromLcid([In] uint locale, [MarshalAs(UnmanagedType.BStr)] out string pbstrRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_GetRfc1766Info([In] uint locale, [In] ushort LangId, out RFC1766INFO pRfc1766Info); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_IsCodePageInstallable([In] uint uiCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_IsConvertible([In] uint dwSrcEncoding, [In] uint dwDstEncoding); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_SetMimeDBSource([In] MIMECONTF dwSource); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_ValidateCodePage([In] uint uiCodePage, [In, ComAliasName("MultiLanguage.wireHWND")] ref _RemotableHandle hwnd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IMultiLanguage3_ValidateCodePageEx([In] uint uiCodePage, [In, ComAliasName("MultiLanguage.wireHWND")] ref _RemotableHandle hwnd, [In] uint dwfIODControl); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IsCodePageInstallable([In] uint uiCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void IsConvertible([In] uint dwSrcEncoding, [In] uint dwDstEncoding); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void MapFont([In, ComAliasName("MultiLanguage.wireHDC")] ref _RemotableHandle hDC, [In] uint dwCodePages, [In] ushort chSrc, [Out, ComAliasName("MultiLanguage.wireHFONT")] IntPtr pFont); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void MapFont([In, ComAliasName("MultiLanguage.wireHDC")] ref _RemotableHandle hDC, [In] uint dwCodePages, [In, ComAliasName("MultiLanguage.wireHFONT")] ref _RemotableHandle hSrcFont, [Out, ComAliasName("MultiLanguage.wireHFONT")] IntPtr phDestFont); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ReleaseFont([In, ComAliasName("MultiLanguage.wireHFONT")] ref _RemotableHandle hFont); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ResetFontMapping(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void SetMimeDBSource([In] MIMECONTF dwSource); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ValidateCodePage([In] uint uiCodePage, [In, ComAliasName("MultiLanguage.wireHWND")] ref _RemotableHandle hwnd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ValidateCodePageEx([In] uint uiCodePage, [In, ComAliasName("MultiLanguage.wireHWND")] ref _RemotableHandle hwnd, [In] uint dwfIODControl); + } + + [ComImport, Guid("275C23E3-3747-11D0-9FEA-00AA003F8646"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IEnumCodePage + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Clone([MarshalAs(UnmanagedType.Interface)] out IEnumCodePage ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [PreserveSig] + HRESULT Next([In] uint celt, out MIMECPINFO rgelt, out uint pceltFetched); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Skip([In] uint celt); + } + + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("3DC39D1D-C030-11D0-B81B-00C04FC9B31F")] + public interface IEnumRfc1766 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Clone([MarshalAs(UnmanagedType.Interface)] out IEnumRfc1766 ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Next([In] uint celt, out RFC1766INFO rgelt, out uint pceltFetched); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Skip([In] uint celt); + } + + [ComImport, Guid("AE5F1430-388B-11D2-8380-00C04F8F5DA1"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IEnumScript + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Clone([MarshalAs(UnmanagedType.Interface)] out IEnumScript ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Next([In] uint celt, out SCRIPTINFO rgelt, out uint pceltFetched); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Skip([In] uint celt); + } + + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("359F3443-BD4A-11D0-B188-00AA0038C969")] + public interface IMLangCodePages + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetCharCodePages([In] ushort chSrc, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetStrCodePages([In] ref ushort pszSrc, [In] int cchSrc, [In] uint dwPriorityCodePages, out uint pdwCodePages, out int pcchCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void CodePageToCodePages([In] uint uCodePage, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void CodePagesToCodePage([In] uint dwCodePages, [In] uint uDefaultCodePage, out uint puCodePage); + } + + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("D66D6F98-CDAA-11D0-B822-00C04FC9B31F")] + public interface IMLangConvertCharset + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Initialize([In] uint uiSrcCodePage, [In] uint uiDstCodePage, [In] uint dwProperty); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetSourceCodePage(out uint puiSrcCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetDestinationCodePage(out uint puiDstCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetProperty(out uint pdwProperty); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void DoConversion([In] ref byte pSrcStr, [In, Out] ref uint pcSrcSize, out byte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void DoConversionToUnicode([In] ref sbyte pSrcStr, [In, Out] ref uint pcSrcSize, out ushort pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void DoConversionFromUnicode([In] ref ushort pSrcStr, [In, Out] ref uint pcSrcSize, out sbyte pDstStr, [In, Out] ref uint pcDstSize); + } + + [ComImport, Guid("359F3441-BD4A-11D0-B188-00AA0038C969"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComConversionLoss] + public interface IMLangFontLink : IMLangCodePages + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetFontCodePages([In, ComAliasName("MultiLanguage.wireHDC")] ref _RemotableHandle hDC, [In, ComAliasName("MultiLanguage.wireHFONT")] ref _RemotableHandle hFont, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void MapFont([In, ComAliasName("MultiLanguage.wireHDC")] ref _RemotableHandle hDC, [In] uint dwCodePages, [In, ComAliasName("MultiLanguage.wireHFONT")] ref _RemotableHandle hSrcFont, [Out, ComAliasName("MultiLanguage.wireHFONT")] IntPtr phDestFont); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ReleaseFont([In, ComAliasName("MultiLanguage.wireHFONT")] ref _RemotableHandle hFont); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ResetFontMapping(); + } + + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("DCCFC162-2B38-11D2-B7EC-00C04F8F5D9A"), ComConversionLoss] + public interface IMLangFontLink2 : IMLangCodePages + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetFontCodePages([In, ComAliasName("MultiLanguage.wireHDC")] ref _RemotableHandle hDC, [In, ComAliasName("MultiLanguage.wireHFONT")] ref _RemotableHandle hFont, out uint pdwCodePages); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ReleaseFont([In, ComAliasName("MultiLanguage.wireHFONT")] ref _RemotableHandle hFont); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ResetFontMapping(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void MapFont([In, ComAliasName("MultiLanguage.wireHDC")] ref _RemotableHandle hDC, [In] uint dwCodePages, [In] ushort chSrc, [Out, ComAliasName("MultiLanguage.wireHFONT")] IntPtr pFont); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetFontUnicodeRanges([In, ComAliasName("MultiLanguage.wireHDC")] ref _RemotableHandle hDC, [In, Out] ref uint puiRanges, out UNICODERANGE pUranges); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetScriptFontInfo([In] byte sid, [In] uint dwFlags, [In, Out] ref uint puiFonts, out SCRIPFONTINFO pScriptFont); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void CodePageToScriptID([In] uint uiCodePage, out byte pSid); + } + + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("F5BE2EE1-BFD7-11D0-B188-00AA0038C969")] + public interface IMLangLineBreakConsole + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void BreakLineML([In, MarshalAs(UnmanagedType.Interface)] CMLangString pSrcMLStr, [In] int lSrcPos, [In] int lSrcLen, [In] int cMinColumns, [In] int cMaxColumns, out int plLineLen, out int plSkipLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void BreakLineW([In] uint locale, [In] ref ushort pszSrc, [In] int cchSrc, [In] int cMaxColumns, out int pcchLine, out int pcchSkip); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void BreakLineA([In] uint locale, [In] uint uCodePage, [In] ref sbyte pszSrc, [In] int cchSrc, [In] int cMaxColumns, out int pcchLine, out int pcchSkip); + } + + [ComImport, Guid("C04D65CE-B70D-11D0-B188-00AA0038C969"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMLangString + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Sync([In] int fNoAccess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + int GetLength(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetMLStr([In] int lDestPos, [In] int lDestLen, [In, MarshalAs(UnmanagedType.IUnknown)] object pSrcMLStr, [In] int lSrcPos, [In] int lSrcLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetMLStr([In] int lSrcPos, [In] int lSrcLen, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, [In] uint dwClsContext, [In] ref Guid piid, [MarshalAs(UnmanagedType.IUnknown)] out object ppDestMLStr, out int plDestPos, out int plDestLen); + } + + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("C04D65D2-B70D-11D0-B188-00AA0038C969")] + public interface IMLangStringAStr : IMLangString + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetAStr([In] int lDestPos, [In] int lDestLen, [In] uint uCodePage, [In, MarshalAs(UnmanagedType.LPStr)] string pszSrc, [In] int cchSrc, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetStrBufA([In] int lDestPos, [In] int lDestLen, [In] uint uCodePage, [In, MarshalAs(UnmanagedType.Interface)] IMLangStringBufA pSrcBuf, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetAStr([In] int lSrcPos, [In] int lSrcLen, [In] uint uCodePageIn, out uint puCodePageOut, [Out, MarshalAs(UnmanagedType.LPStr)] string pszDest, [In] int cchDest, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetStrBufA([In] int lSrcPos, [In] int lSrcMaxLen, out uint puDestCodePage, [MarshalAs(UnmanagedType.Interface)] out IMLangStringBufA ppDestBuf, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void LockAStr([In] int lSrcPos, [In] int lSrcLen, [In] int lFlags, [In] uint uCodePageIn, [In] int cchRequest, out uint puCodePageOut, [MarshalAs(UnmanagedType.LPStr)] out string ppszDest, out int pcchDest, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void UnlockAStr([In, MarshalAs(UnmanagedType.LPStr)] string pszSrc, [In] int cchSrc, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetLocale([In] int lDestPos, [In] int lDestLen, [In] uint locale); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetLocale([In] int lSrcPos, [In] int lSrcMaxLen, out uint plocale, out int plLocalePos, out int plLocaleLen); + } + + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComConversionLoss, Guid("D24ACD23-BA72-11D0-B188-00AA0038C969")] + public interface IMLangStringBufA + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetStatus(out int plFlags, out int pcchBuf); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void LockBuf([In] int cchOffset, [In] int cchMaxLock, [Out] IntPtr ppszBuf, out int pcchBuf); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void UnlockBuf([In] ref sbyte pszBuf, [In] int cchOffset, [In] int cchWrite); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Insert([In] int cchOffset, [In] int cchMaxInsert, out int pcchActual); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Delete([In] int cchOffset, [In] int cchDelete); + } + + [ComImport, ComConversionLoss, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("D24ACD21-BA72-11D0-B188-00AA0038C969")] + public interface IMLangStringBufW + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetStatus(out int plFlags, out int pcchBuf); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void LockBuf([In] int cchOffset, [In] int cchMaxLock, [Out] IntPtr ppszBuf, out int pcchBuf); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void UnlockBuf([In] ref ushort pszBuf, [In] int cchOffset, [In] int cchWrite); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Insert([In] int cchOffset, [In] int cchMaxInsert, out int pcchActual); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Delete([In] int cchOffset, [In] int cchDelete); + } + + [ComImport, Guid("C04D65D0-B70D-11D0-B188-00AA0038C969"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMLangStringWStr : IMLangString + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetWStr([In] int lDestPos, [In] int lDestLen, [In, MarshalAs(UnmanagedType.LPWStr)] string pszSrc, [In] int cchSrc, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetStrBufW([In] int lDestPos, [In] int lDestLen, [In, MarshalAs(UnmanagedType.Interface)] IMLangStringBufW pSrcBuf, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetWStr([In] int lSrcPos, [In] int lSrcLen, [Out, MarshalAs(UnmanagedType.LPWStr)] string pszDest, [In] int cchDest, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetStrBufW([In] int lSrcPos, [In] int lSrcMaxLen, [MarshalAs(UnmanagedType.Interface)] out IMLangStringBufW ppDestBuf, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void LockWStr([In] int lSrcPos, [In] int lSrcLen, [In] int lFlags, [In] int cchRequest, [MarshalAs(UnmanagedType.LPWStr)] out string ppszDest, out int pcchDest, out int plDestLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void UnlockWStr([In, MarshalAs(UnmanagedType.LPWStr)] string pszSrc, [In] int cchSrc, out int pcchActual, out int plActualLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetLocale([In] int lDestPos, [In] int lDestLen, [In] uint locale); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetLocale([In] int lSrcPos, [In] int lSrcMaxLen, out uint plocale, out int plLocalePos, out int plLocaleLen); + } + + [ComImport, Guid("275C23E1-3747-11D0-9FEA-00AA003F8646"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMultiLanguage + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetNumberOfCodePageInfo(out uint pcCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetCodePageInfo([In] uint uiCodePage, out MIMECPINFO pCodePageInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetFamilyCodePage([In] uint uiCodePage, out uint puiFamilyCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [return: MarshalAs(UnmanagedType.Interface)] + IEnumCodePage EnumCodePages([In] NativeMethods.MIMECONTF grfFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetCharsetInfo([In, MarshalAs(UnmanagedType.BStr)] string Charset, out MIMECSETINFO pCharsetInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void IsConvertible([In] uint dwSrcEncoding, [In] uint dwDstEncoding); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertString([In, Out] ref uint pdwMode, [In] uint dwSrcEncoding, [In] uint dwDstEncoding, [In] ref byte pSrcStr, [In, Out] ref uint pcSrcSize, out byte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertStringToUnicode([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref sbyte pSrcStr, [In, Out] ref uint pcSrcSize, out ushort pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertStringFromUnicode([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref ushort pSrcStr, [In, Out] ref uint pcSrcSize, out sbyte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertStringReset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetRfc1766FromLcid([In] uint locale, [MarshalAs(UnmanagedType.BStr)] out string pbstrRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetLcidFromRfc1766(out uint plocale, [In, MarshalAs(UnmanagedType.BStr)] string bstrRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void EnumRfc1766([MarshalAs(UnmanagedType.Interface)] out IEnumRfc1766 ppEnumRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetRfc1766Info([In] uint locale, out RFC1766INFO pRfc1766Info); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void CreateConvertCharset([In] uint uiSrcCodePage, [In] uint uiDstCodePage, [In] uint dwProperty, [MarshalAs(UnmanagedType.Interface)] out CMLangConvertCharset ppMLangConvertCharset); + } + + [ComImport, Guid("DCCFC164-2B38-11D2-B7EC-00C04F8F5D9A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMultiLanguage2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetNumberOfCodePageInfo(out uint pcCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetCodePageInfo([In] uint uiCodePage, [In] ushort LangId, out MIMECPINFO pCodePageInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetFamilyCodePage([In] uint uiCodePage, out uint puiFamilyCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void EnumCodePages([In] uint grfFlags, [In] ushort LangId, [MarshalAs(UnmanagedType.Interface)] out IEnumCodePage ppEnumCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetCharsetInfo([In, MarshalAs(UnmanagedType.BStr)] string Charset, out MIMECSETINFO pCharsetInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void IsConvertible([In] uint dwSrcEncoding, [In] uint dwDstEncoding); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertString([In, Out] ref uint pdwMode, [In] uint dwSrcEncoding, [In] uint dwDstEncoding, [In] ref byte pSrcStr, [In, Out] ref uint pcSrcSize, out byte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertStringToUnicode([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref sbyte pSrcStr, [In, Out] ref uint pcSrcSize, out ushort pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertStringFromUnicode([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref ushort pSrcStr, [In, Out] ref uint pcSrcSize, out sbyte pDstStr, [In, Out] ref uint pcDstSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertStringReset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetRfc1766FromLcid([In] uint locale, [MarshalAs(UnmanagedType.BStr)] out string pbstrRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetLcidFromRfc1766(out uint plocale, [In, MarshalAs(UnmanagedType.BStr)] string bstrRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void EnumRfc1766([In] ushort LangId, [MarshalAs(UnmanagedType.Interface)] out IEnumRfc1766 ppEnumRfc1766); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetRfc1766Info([In] uint locale, [In] ushort LangId, out RFC1766INFO pRfc1766Info); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void CreateConvertCharset([In] uint uiSrcCodePage, [In] uint uiDstCodePage, [In] uint dwProperty, [MarshalAs(UnmanagedType.Interface)] out CMLangConvertCharset ppMLangConvertCharset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertStringInIStream([In, Out] ref uint pdwMode, [In] uint dwFlag, [In] ref ushort lpFallBack, [In] uint dwSrcEncoding, [In] uint dwDstEncoding, [In, MarshalAs(UnmanagedType.Interface)] IStream pstmIn, [In, MarshalAs(UnmanagedType.Interface)] IStream pstmOut); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertStringToUnicodeEx([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref sbyte pSrcStr, [In, Out] ref uint pcSrcSize, out ushort pDstStr, [In, Out] ref uint pcDstSize, [In] uint dwFlag, [In] ref ushort lpFallBack); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ConvertStringFromUnicodeEx([In, Out] ref uint pdwMode, [In] uint dwEncoding, [In] ref ushort pSrcStr, [In, Out] ref uint pcSrcSize, out sbyte pDstStr, [In, Out] ref uint pcDstSize, [In] uint dwFlag, [In] ref ushort lpFallBack); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void DetectCodepageInIStream([In] uint dwFlag, [In] uint dwPrefWinCodePage, [In, MarshalAs(UnmanagedType.Interface)] IStream pstmIn, out DetectEncodingInfo lpEncoding, [In, Out] ref int pnScores); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [PreserveSig] + HRESULT DetectInputCodepage([In] MLDETECTCP dwFlag, [In] uint dwPrefWinCodePage, [In] ref byte pSrcStr, [In, Out] ref int pcSrcSize, [In, Out] ref DetectEncodingInfo lpEncoding, [In, Out] ref int pnScores); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ValidateCodePage([In] uint uiCodePage, [In, ComAliasName("MultiLanguage.wireHWND")] ref _RemotableHandle hwnd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetCodePageDescription([In] uint uiCodePage, [In] uint lcid, [Out, MarshalAs(UnmanagedType.LPWStr)] string lpWideCharStr, [In] int cchWideChar); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void IsCodePageInstallable([In] uint uiCodePage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetMimeDBSource([In] MIMECONTF dwSource); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetNumberOfScripts(out uint pnScripts); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void EnumScripts([In] uint dwFlags, [In] ushort LangId, [MarshalAs(UnmanagedType.Interface)] out IEnumScript ppEnumScript); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ValidateCodePageEx([In] uint uiCodePage, [In, ComAliasName("MultiLanguage.wireHWND")] ref _RemotableHandle hwnd, [In] uint dwfIODControl); + } + + [ComImport, Guid("4E5868AB-B157-4623-9ACC-6A1D9CAEBE04"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMultiLanguage3 : IMultiLanguage2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void DetectOutboundCodePage([In] uint dwFlags, [In, MarshalAs(UnmanagedType.LPWStr)] string lpWideCharStr, [In] uint cchWideChar, [In] ref uint puiPreferredCodePages, [In] uint nPreferredCodePages, out uint puiDetectedCodePages, [In, Out] ref uint pnDetectedCodePages, [In, MarshalAs(UnmanagedType.LPWStr)] string lpSpecialChar); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void DetectOutboundCodePageInIStream([In] uint dwFlags, [In, MarshalAs(UnmanagedType.Interface)] IStream pStrIn, [In] ref uint puiPreferredCodePages, [In] uint nPreferredCodePages, out uint puiDetectedCodePages, [In, Out] ref uint pnDetectedCodePages, [In, MarshalAs(UnmanagedType.LPWStr)] string lpSpecialChar); + } + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct DetectEncodingInfo + { + public uint nLangID; + public uint nCodePage; + public int nDocPercent; + public int nConfidence; + } + + public enum MIMECONTF + { + MIMECONTF_BROWSER = 2, + MIMECONTF_EXPORT = 0x400, + MIMECONTF_IMPORT = 8, + MIMECONTF_MAILNEWS = 1, + MIMECONTF_MIME_IE4 = 0x10000000, + MIMECONTF_MIME_LATEST = 0x20000000, + MIMECONTF_MIME_REGISTRY = 0x40000000, + MIMECONTF_MINIMAL = 4, + MIMECONTF_PRIVCONVERTER = 0x10000, + MIMECONTF_SAVABLE_BROWSER = 0x200, + MIMECONTF_SAVABLE_MAILNEWS = 0x100, + MIMECONTF_VALID = 0x20000, + MIMECONTF_VALID_NLS = 0x40000 + } + + [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)] + public struct MIMECPINFO + { + public uint dwFlags; + public uint uiCodePage; + public uint uiFamilyCodePage; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x40)] + public string wszDescription; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)] + public string wszWebCharset; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)] + public string wszHeaderCharset; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)] + public string wszBodyCharset; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] + public string wszFixedWidthFont; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] + public string wszProportionalFont; + public byte bGDICharset; + } + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct MIMECSETINFO + { + public uint uiCodePage; + public uint uiInternetEncoding; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)] + public ushort[] wszCharset; + } + + public enum MLSTR_FLAGS + { + MLSTR_READ = 1, + MLSTR_WRITE = 2 + } + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct RFC1766INFO + { + public uint lcid; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public ushort[] wszRfc1766; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public ushort[] wszLocaleName; + } + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct SCRIPFONTINFO + { + public long scripts; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public ushort[] wszFont; + } + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct SCRIPTINFO + { + public byte ScriptId; + public uint uiCodePage; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x30)] + public ushort[] wszDescription; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public ushort[] wszFixedWidthFont; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public ushort[] wszProportionalFont; + } + + public enum MLDETECTCP + { + MLDETECTCP_NONE = 0, + MLDETECTCP_7BIT = 1, + MLDETECTCP_8BIT = 2, + MLDETECTCP_DBCS = 4, + MLDETECTCP_HTML = 8, + MLDETECTCP_NUMBER = 16 + } + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct STATSTG + { + [MarshalAs(UnmanagedType.LPWStr)] + public string pwcsName; + public uint type; + public ulong cbSize; + public System.Runtime.InteropServices.ComTypes.FILETIME mtime; + public System.Runtime.InteropServices.ComTypes.FILETIME ctime; + public System.Runtime.InteropServices.ComTypes.FILETIME atime; + public uint grfMode; + public uint grfLocksSupported; + public Guid clsid; + public uint grfStateBits; + public uint reserved; + } + + [StructLayout(LayoutKind.Sequential, Pack = 2)] + public struct UNICODERANGE + { + public ushort wcFrom; + public ushort wcTo; + } + } +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/User32.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/User32.cs new file mode 100644 index 0000000000..b158632572 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/User32.cs @@ -0,0 +1,88 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Web.Management.PInvoke.User32 +{ + internal enum WindowMessage + { + PBS_SMOOTH = 0x1, + PBS_MARQUEE = 0x8, + WM_SETREDRAW = 0xB, + PBM_SETMARQUEE = 0x400 + 10, + } + + [Flags] + internal enum ExitWindows : uint + { + // + // ONE of the following five: + // + LogOff = 0x00, + ShutDown = 0x01, + Reboot = 0x02, + PowerOff = 0x08, + RestartApps = 0x40, + + // + // plus AT MOST ONE of the following two: + // + Force = 0x04, + ForceIfHung = 0x10, + } + + [Flags] + internal enum ShutdownReason : uint + { + MajorApplication = 0x00040000, + MajorHardware = 0x00010000, + MajorLegacyApi = 0x00070000, + MajorOperatingSystem = 0x00020000, + MajorOther = 0x00000000, + MajorPower = 0x00060000, + MajorSoftware = 0x00030000, + MajorSystem = 0x00050000, + + MinorBlueScreen = 0x0000000F, + MinorCordUnplugged = 0x0000000b, + MinorDisk = 0x00000007, + MinorEnvironment = 0x0000000c, + MinorHardwareDriver = 0x0000000d, + MinorHotfix = 0x00000011, + MinorHung = 0x00000005, + MinorInstallation = 0x00000002, + MinorMaintenance = 0x00000001, + MinorMMC = 0x00000019, + MinorNetworkConnectivity = 0x00000014, + MinorNetworkCard = 0x00000009, + MinorOther = 0x00000000, + MinorOtherDriver = 0x0000000e, + MinorPowerSupply = 0x0000000a, + MinorProcessor = 0x00000008, + MinorReconfig = 0x00000004, + MinorSecurity = 0x00000013, + MinorSecurityFix = 0x00000012, + MinorSecurityFixUninstall = 0x00000018, + MinorServicePack = 0x00000010, + MinorServicePackUninstall = 0x00000016, + MinorTermSrv = 0x00000020, + MinorUnstable = 0x00000006, + MinorUpgrade = 0x00000003, + MinorWMI = 0x00000015, + + FlagUserDefined = 0x40000000, + FlagPlanned = 0x80000000 + } + + internal static class NativeMethods + { + [DllImport("User32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(IntPtr hWnd, WindowMessage msg, int wParam, int lParam); + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ExitWindowsEx(ExitWindows uFlags, ShutdownReason dwReason); + } +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/UxTheme.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/UxTheme.cs new file mode 100644 index 0000000000..520c923505 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/NativeMethods/UxTheme.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Runtime.InteropServices; +using System.Text; +using System.Diagnostics; + +namespace Microsoft.Web.Management.PInvoke.UxTheme +{ + internal static class NativeMethods + { + [DllImport("UxTheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)] + public extern static void SetWindowTheme(IntPtr hWnd, string textSubAppName, string textSubIdList); + + [DllImport("uxtheme.dll", CharSet = CharSet.Unicode, PreserveSig = true)] + private static extern int GetCurrentThemeName(StringBuilder pszThemeFileName, int dwMaxNameChars, StringBuilder pszColorBuff, int dwMaxColorChars, StringBuilder pszSizeBuff, int cchMaxSizeChars); + + public static bool TryGetCurrentThemeName(out string themeName, out string color, out string size) + { + StringBuilder nameBuilder = new StringBuilder(512); + StringBuilder colorBuilder = new StringBuilder(512); + StringBuilder sizeBuilder = new StringBuilder(512); + int hr = GetCurrentThemeName(nameBuilder, nameBuilder.Capacity, colorBuilder, colorBuilder.Capacity, sizeBuilder, sizeBuilder.Capacity); + if (hr == 0) + { + themeName = nameBuilder.ToString(); + color = colorBuilder.ToString(); + size = sizeBuilder.ToString(); + return true; + } + else + { + themeName = null; + color = null; + size = null; + if (hr != Extension.AsHRESULT(Win32ErrorCode.ELEMENT_NOT_FOUND)) + { + Debug.Fail("GetCurrentThemeName returned: " + hr.ToString()); + } + + return false; + } + } + } +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/PseudoLoc/PseudoLoc.targets b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/PseudoLoc/PseudoLoc.targets new file mode 100644 index 0000000000..0222289f2c --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/PseudoLoc/PseudoLoc.targets @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/PseudoLoc/PseudoLocalizer.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/PseudoLoc/PseudoLocalizer.cs new file mode 100644 index 0000000000..fccf038061 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/PseudoLoc/PseudoLocalizer.cs @@ -0,0 +1,456 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Reflection; +using System.Resources; + +namespace Microsoft.Web.Utility +{ +#if PSEUDOLOCALIZER_ENABLED || DEBUG + + /// + /// Class that pseudo-localizes resources from a RESX file by intercepting calls to the managed wrapper class. + /// + internal static class PseudoLocalizer + { + private static bool _shouldPseudoLocalize; + private static double _plocPaddingLengthRatio; + + static PseudoLocalizer() + { + _shouldPseudoLocalize = false; + int plocLengthPaddingPercentage = 50; +#if DEBUG + string plocValue = Environment.GetEnvironmentVariable("PSEUDOLOCALIZE"); + if (!string.IsNullOrEmpty(plocValue)) + { + _shouldPseudoLocalize = true; + int.TryParse(plocValue, out plocLengthPaddingPercentage); + if (plocLengthPaddingPercentage < 10) + { + plocLengthPaddingPercentage = 50; + } + } +#endif // DEBUG + + _plocPaddingLengthRatio = plocLengthPaddingPercentage * 0.01; + if (_plocPaddingLengthRatio < 0.1) + { + DebugTrace("ploc should be at least 10% padded"); + } + +#if PSEUDOLOCALIZER_ENABLED + _shouldPseudoLocalize = true; +#endif // PSEUDOLOCALIZER_ENABLED + } + + public static bool ShouldPseudoLocalize + { + get + { + return _shouldPseudoLocalize; + } + } + + // Need to use this method instead of tracing/debugging directly otherwise + // the application will not be able to disable asserts from the exe.config file. + // this is because this code is run very early on in the app before the + // default trace listener has had a chance to initialize its settings + // correctly + private static void DebugTrace(string format, params object[] args) + { + ////only uncomment these lines when actually debugging something + ////otherwise the application wont be able to toggle the assert ui + ////if (args == null || args.Length == 0) + ////{ + //// Debug.WriteLine(format); + ////} + ////else + ////{ + //// Debug.WriteLine(format, args); + ////} + } + + /// + /// Enables pseudo-localization on any type that is of the form {AssemblyName}.Resources + /// + /// + /// true if succeeded, false if failed. + public static bool TryEnableAssembly(Assembly assembly) + { + bool retVal = false; + if (assembly != null) + { + AssemblyName assemblyName = assembly.GetName(); + string resourceTypeName = assemblyName.Name + ".Resources"; + try + { + Type resourceType = assembly.GetType(resourceTypeName, false); + if (resourceType != null) + { + Enable(resourceType); + retVal = true; + } + else + { + DebugTrace("PLOC: no type {0} found in the assembly {1}", + resourceTypeName, + assembly.FullName); + } + } + catch (Exception ex) + { + DebugTrace(ex.ToString()); + } + } + else + { + DebugTrace("assembly should not be null"); + } + + return retVal; + } + + /// + /// Enables pseudo-localization for the specified RESX managed wrapper class. + /// + /// Type of the RESX managed wrapper class. + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "ResourceManager", Justification = "Name of property.")] + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "resourceMan", Justification = "Name of field.")] + public static void Enable(Type resourcesType) + { + if (null == resourcesType) + { + throw new ArgumentNullException("resourcesType"); + } + + // Get the ResourceManager property + var resourceManagerProperty = resourcesType.GetProperty("ResourceManager", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + if (null == resourceManagerProperty) + { + throw new NotSupportedException("RESX managed wrapper class does not contain the expected internal/public static ResourceManager property."); + } + + // Get the ResourceManager value (ensures the resourceMan field gets initialized) + var resourceManagerValue = resourceManagerProperty.GetValue(null, null) as ResourceManager; + if (null == resourceManagerValue) + { + throw new NotSupportedException("RESX managed wrapper class returned null for the ResourceManager property getter."); + } + + // Get the resourceMan field + var resourceManField = resourcesType.GetField("resourceMan", BindingFlags.Static | BindingFlags.NonPublic); + if (null == resourceManField) + { + throw new NotSupportedException("RESX managed wrapper class does not contain the expected private static resourceMan field."); + } + + // Create a substitute ResourceManager to do the pseudo-localization + var resourceManSubstitute = new PseudoLocalizerResourceManager( + _plocPaddingLengthRatio, + resourceManagerValue.BaseName, + resourcesType.Assembly); + + // Replace the resourceMan field value + resourceManField.SetValue(null, resourceManSubstitute); + } + + /// + /// Enables Pseudo-localization for all assemblies that get loaded from the current + /// host. Within the assemblie, only types that are of the form {AssemblyName}.Resources + /// will get pseudo-localization enabled. + /// + public static void EnableAutoPseudoLocalizationFromHostExecutable() + { + if (ShouldPseudoLocalize) + { + //set up pseudo-localization for ourselves + TryEnableAssembly(Assembly.GetExecutingAssembly()); + + //set up pseudo-localization for anything that gets loaded later + AppDomain.CurrentDomain.AssemblyLoad += + new AssemblyLoadEventHandler(OnCurrentDomainAssemblyLoad); + } + } + + public static string PseudoLocalizeString(string str) + { + return PseudoLocalizerResourceManager.PseudoLocalizeString( + _plocPaddingLengthRatio, + str); + } + + private static void OnCurrentDomainAssemblyLoad(object sender, + AssemblyLoadEventArgs args) + { + Assembly assembly = args.LoadedAssembly; + bool isThisMyAssembly; + if (!assembly.GlobalAssemblyCache) + { + isThisMyAssembly = true; + } + else if (assembly.FullName.StartsWith("Microsoft.Web", + StringComparison.OrdinalIgnoreCase)) + { + isThisMyAssembly = true; + } + else + { + isThisMyAssembly = false; + } + + if (isThisMyAssembly) + { + TryEnableAssembly(assembly); + } + } + + /// + /// Class that overrides default ResourceManager behavior by pseudo-localizing its content. + /// + private class PseudoLocalizerResourceManager : ResourceManager + { + /// + /// Stores a Dictionary for character translations. + /// + private static Dictionary _translations = CreateTranslationsMap(); + + private static Dictionary CreateTranslationsMap() + { + // Map standard "English" characters to similar-looking counterparts from other languages + Dictionary translations = new Dictionary + { + { 'a', 'ä' }, + { 'b', 'ƃ' }, + { 'c', 'č' }, + { 'd', 'ƌ' }, + { 'e', 'ë' }, + { 'f', 'ƒ' }, + { 'g', 'ğ' }, + { 'h', 'ħ' }, + { 'i', 'ï' }, + { 'j', 'ĵ' }, + { 'k', 'ƙ' }, + { 'l', 'ł' }, + { 'm', 'ɱ' }, + { 'n', 'ň' }, + { 'o', 'ö' }, + { 'p', 'þ' }, + { 'q', 'ɋ' }, + { 'r', 'ř' }, + { 's', 'š' }, + { 't', 'ŧ' }, + { 'u', 'ü' }, + { 'v', 'ṽ' }, + { 'w', 'ŵ' }, + { 'x', 'ӿ' }, + { 'y', 'ŷ' }, + { 'z', 'ž' }, + { 'A', 'Ä' }, + { 'B', 'Ɓ' }, + { 'C', 'Č' }, + { 'D', 'Đ' }, + { 'E', 'Ë' }, + { 'F', 'Ƒ' }, + { 'G', 'Ğ' }, + { 'H', 'Ħ' }, + { 'I', 'Ï' }, + { 'J', 'Ĵ' }, + { 'K', 'Ҟ' }, + { 'L', 'Ł' }, + { 'M', 'Ӎ' }, + { 'N', 'Ň' }, + { 'O', 'Ö' }, + { 'P', 'Ҏ' }, + { 'Q', 'Ǫ' }, + { 'R', 'Ř' }, + { 'S', 'Š' }, + { 'T', 'Ŧ' }, + { 'U', 'Ü' }, + { 'V', 'Ṽ' }, + { 'W', 'Ŵ' }, + { 'X', 'Ӿ' }, + { 'Y', 'Ŷ' }, + { 'Z', 'Ž' }, + }; + + return translations; + } + + private double _paddingLengthRatio; + + /// + /// Initializes a new instance of the PseudoLocalizerResourceManager class. + /// + /// The root name of the resource file without its extension but including any fully qualified namespace name. + /// The main assembly for the resources. + public PseudoLocalizerResourceManager(double paddingLengthRatio, + string baseName, + Assembly assembly) + : base(baseName, assembly) + { + _paddingLengthRatio = paddingLengthRatio; + } + + /// + /// Returns the value of the specified String resource. + /// + /// The name of the resource to get. + /// The value of the resource localized for the caller's current culture settings. + public override string GetString(string name) + { + return PseudoLocalizeString(base.GetString(name)); + } + + /// + /// Gets the value of the String resource localized for the specified culture. + /// + /// The name of the resource to get. + /// The CultureInfo object that represents the culture for which the resource is localized. + /// The value of the resource localized for the specified culture. + public override string GetString(string name, CultureInfo culture) + { + return PseudoLocalizeString(base.GetString(name, culture)); + } + + private string PseudoLocalizeString(string str) + { + return PseudoLocalizeString(_paddingLengthRatio, str); + } + + /// + /// Pseudo-localizes a string. + /// + /// Input string. + /// Pseudo-localized string. + internal static string PseudoLocalizeString(double paddingLengthRatio, string str) + { + const string minprefix = "["; + const string minsuffix = "]"; + + // Create a new string with the "translated" values of each character + var translatedChars = new char[str.Length]; + if (IsXamlString(str)) + { + DoCaseTranslation(str, translatedChars); + } + else + { + DoFunkyCharacterTranslation(str, translatedChars); + } + + string mungedString = new string(translatedChars); + + int padLengthPerSide = GetPaddingLengthPerSide( + str.Length, + paddingLengthRatio, + minprefix.Length + minsuffix.Length); + + string extraPadding = new string('=', padLengthPerSide); + string finalString = string.Concat(minprefix, extraPadding, mungedString, extraPadding, minsuffix); + + return finalString; + } + + private static int GetPaddingLengthPerSide(int originalStringLength, double paddingRatio, int minPadLength) + { + int padLengthPerSide; + double exactTotalPadding = (originalStringLength * paddingRatio); + padLengthPerSide = (int)(exactTotalPadding + 1) / 2; + if (padLengthPerSide < 1) + { + padLengthPerSide = 1; + } + + return padLengthPerSide; + } + + private static void DoCaseTranslation(string str, char[] translatedChars) + { + bool inXamlTag = false; + for (var i = 0; i < str.Length; i++) + { + var c = str[i]; + + if (inXamlTag) + { + translatedChars[i] = c; + if (c == '>') + { + inXamlTag = false; + } + } + else + { + translatedChars[i] = (i % 2) == 0 ? char.ToUpper(c) : char.ToLower(c); + if (c == '<' && str.IndexOf('>', i) > -1) + { + inXamlTag = true; + } + } + } + } + + private static void DoFunkyCharacterTranslation(string str, char[] translatedChars) + { + for (var i = 0; i < str.Length; i++) + { + var c = str[i]; + translatedChars[i] = _translations.ContainsKey(c) ? _translations[c] : c; + } + } + + private static bool IsXamlString(string str) + { + // check if this string has a '<' followed by a '>' and assume it's a xaml string if so + int lessThanIndex = str.IndexOf('<'); + if (lessThanIndex > -1) + { + if (str.IndexOf('>', lessThanIndex) > -1) + { + return true; + } + } + + return false; + } + } + } +#else + /// + /// Dummy class needed to keep the public interface be identical in debug and retail builds + /// + internal static class PseudoLocalizer + { + public static bool ShouldPseudoLocalize + { + get + { + return false; + } + } + + public static bool TryEnableAssembly(Assembly assembly) + { + return true; + } + + public static void Enable(Type resourcesType) + { + } + + public static void EnableAutoPseudoLocalizationFromHostExecutable() + { + } + + public static string PseudoLocalizeString(string str) + { + return str; + } + } +#endif +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/References/v7Sp1/Microsoft.Web.administration.dll b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/References/v7Sp1/Microsoft.Web.administration.dll new file mode 100644 index 0000000000..5c786c3d92 Binary files /dev/null and b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/References/v7Sp1/Microsoft.Web.administration.dll differ diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/References/v7Sp1/Microsoft.Web.management.dll b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/References/v7Sp1/Microsoft.Web.management.dll new file mode 100644 index 0000000000..cbae9ccf92 Binary files /dev/null and b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/References/v7Sp1/Microsoft.Web.management.dll differ diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/AuthenticationModule.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/AuthenticationModule.cs new file mode 100644 index 0000000000..f284d02d0e --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/AuthenticationModule.cs @@ -0,0 +1,111 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Net; +using System.Text; + +namespace Microsoft.WebMatrix.Utility +{ + /// + /// This AuthenticationModule implements basic authentication but uses UTF8 Encoding to support international characters. + /// Unfortunately the System.Net implementation uses the Default encoding which breaks with them. + /// + internal class AuthenticationModule : IAuthenticationModule + { + private const string AuthenticationTypeName = "Basic"; + private static AuthenticationModule _module = null; + private static object _lock = new object(); + + public static void InstantiateIfNeeded() + { + lock (_lock) + { + if (_module == null) + { + _module = new AuthenticationModule(); + } + } + } + + private AuthenticationModule() + { + AuthenticationManager.Unregister(AuthenticationTypeName); + AuthenticationManager.Register(this); + } + + string IAuthenticationModule.AuthenticationType + { + get + { + return AuthenticationTypeName; + } + } + + bool IAuthenticationModule.CanPreAuthenticate + { + get + { + return true; + } + } + + Authorization IAuthenticationModule.Authenticate(string challenge, WebRequest request, ICredentials credentials) + { + HttpWebRequest httpWebRequest = request as HttpWebRequest; + if (httpWebRequest == null) + { + return null; + } + + // Verify that the challenge is a Basic Challenge + if (challenge == null || !challenge.StartsWith(AuthenticationTypeName, StringComparison.OrdinalIgnoreCase)) + { + return null; + } + + return Authenticate(httpWebRequest, credentials); + } + + Authorization IAuthenticationModule.PreAuthenticate(WebRequest request, ICredentials credentials) + { + HttpWebRequest httpWebRequest = request as HttpWebRequest; + + if (httpWebRequest == null) + { + return null; + } + + return Authenticate(httpWebRequest, credentials); + } + + private Authorization Authenticate(HttpWebRequest httpWebRequest, ICredentials credentials) + { + if (credentials == null) + { + return null; + } + + // Get the username and password from the credentials + NetworkCredential nc = credentials.GetCredential(httpWebRequest.RequestUri, AuthenticationTypeName); + if (nc == null) + { + return null; + } + + ICredentialPolicy policy = AuthenticationManager.CredentialPolicy; + if (policy != null && !policy.ShouldSendCredential(httpWebRequest.RequestUri, httpWebRequest, nc, this)) + { + return null; + } + + string domain = nc.Domain; + + string basicTicket = (!String.IsNullOrEmpty(domain) ? (domain + "\\") : "") + nc.UserName + ":" + nc.Password; + byte[] bytes = Encoding.UTF8.GetBytes(basicTicket); + + string header = AuthenticationTypeName + " " + Convert.ToBase64String(bytes); + return new Authorization(header, true); + } + } +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/ExceptionHelper.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/ExceptionHelper.cs new file mode 100644 index 0000000000..b3a6c24c2e --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/ExceptionHelper.cs @@ -0,0 +1,122 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; + +namespace Microsoft.WebMatrix.Utility +{ + internal class ExceptionHelper + { + private const int PublicKeyTokenLength = 8; + + /// + /// This will return a list of assemblies that are present in the call stack for + /// the input exception. The list CAN have duplicates. + /// + /// + /// + public static IEnumerable GetAssembliesInCallStack(Exception exception) + { + // an AggregateException might have multiple inner exceptions, so we handle it specially + AggregateException aggregateException = exception as AggregateException; + if (exception == null) + { + return Enumerable.Empty(); + } + else if (aggregateException == null) + { + return GetAssembliesInSingleException(exception).Concat(GetAssembliesInCallStack(exception.InnerException)); + } + else + { + return aggregateException.Flatten().InnerExceptions.SelectMany(ex => GetAssembliesInCallStack(ex)); + } + } + + private static IEnumerable GetAssembliesInSingleException(Exception exception) + { + // some exceptions (like AggregateException) don't have an associated stacktrace + if (exception != null && exception.StackTrace != null) + { + StackTrace stackTrace = new StackTrace(exception, false); + foreach (StackFrame frame in stackTrace.GetFrames()) + { + // DeclaringType can be null for lambdas created by Reflection.Emit + Type declaringType = frame.GetMethod().DeclaringType; + if (declaringType != null) + { + Assembly currentAssembly = declaringType.Assembly; + Debug.Assert(currentAssembly != null, "currentAssembly must not be null"); + if (currentAssembly != null) + { + yield return currentAssembly; + } + } + } + } + } + + public static IEnumerable RemoveAssembliesThatAreIntheGAC(IEnumerable input) + { + foreach (Assembly assembly in input) + { + if (!assembly.GlobalAssemblyCache) + { + yield return assembly; + } + } + } + + public static IEnumerable RemoveAssembliesThatAreSignedWithToken(IEnumerable input, byte[] publicKeyToken) + { + Debug.Assert(publicKeyToken.Length == PublicKeyTokenLength, "public key tokens should be 8 bytes"); + foreach (Assembly assembly in input) + { + byte[] currentToken = assembly.GetName().GetPublicKeyToken(); + bool shouldReturn; + if (currentToken.Length == 0) + { + // unsigned assembly + shouldReturn = true; + } + else if (AreTokensTheSame(currentToken, publicKeyToken)) + { + // tokens are the same skip the assembly + shouldReturn = false; + } + else + { + // didnt match anything, return it + shouldReturn = true; + } + + if (shouldReturn) + { + yield return assembly; + } + } + } + + private static bool AreTokensTheSame(byte[] token1, byte[] token2) + { + Debug.Assert( + token1.Length == PublicKeyTokenLength && + token2.Length == PublicKeyTokenLength, + "public key tokens should be 8 bytes"); + + for (int i = 0; i < PublicKeyTokenLength; i++) + { + if (token1[i] != token2[i]) + { + return false; + } + } + + return true; + } + } +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/GACManagedAccess.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/GACManagedAccess.cs new file mode 100644 index 0000000000..2dbd5c8ff1 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/GACManagedAccess.cs @@ -0,0 +1,192 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using System.Diagnostics; + +namespace Microsoft.Web.Utility +{ + // need to include \common\Managed\NativeMethods\Fusion.cs in your project to use this class + internal static class GACManagedAccess + { + public static List GetAssemblyList(string assemblyName) + { + return GetAssemblyList(assemblyName, true); + } + + public static List GetAssemblyList(string assemblyName, bool getPhysicalPath) + { + if (string.IsNullOrEmpty(assemblyName)) + { + throw new ArgumentNullException("assemblyName"); + } + + List assemblyList = new List(); + using (GacAssembly gacAssembly = new GacAssembly(assemblyName)) + { + while (true) + { + if (gacAssembly.GetNextAssembly()) + { + if (getPhysicalPath) + { + using (GACAssemblyCache gacAssemblyCache = new GACAssemblyCache(assemblyName, gacAssembly.FullAssemblyName)) + { + assemblyList.Add(gacAssemblyCache.AssemblyPath); + } + } + else + { + assemblyList.Add(gacAssembly.FullAssemblyName); + } + } + else + { + break; + } + } + } + + return assemblyList; + } + } + + internal class GacAssembly : IDisposable + { + internal GacAssembly(string assemblyName) + { + _assemblyName = assemblyName; + int hResult = PInvoke.Fusion.NativeMethods.CreateAssemblyNameObject( + out _fusionName, + _assemblyName, + PInvoke.Fusion.CreateAssemblyNameObjectFlags.CANOF_PARSE_DISPLAY_NAME, + IntPtr.Zero); + + if (hResult >= 0) + { + hResult = PInvoke.Fusion.NativeMethods.CreateAssemblyEnum( + out _assemblyEnum, + IntPtr.Zero, + _fusionName, + PInvoke.Fusion.AssemblyCacheFlags.GAC, + IntPtr.Zero); + } + + if (hResult < 0 || _assemblyEnum == null) + { + throw Marshal.GetExceptionForHR(hResult); + } + } + + internal bool GetNextAssembly() + { + int hResult = _assemblyEnum.GetNextAssembly((IntPtr)0, out _fusionName, 0); + + if (hResult < 0 || _fusionName == null) + { + return false; + } + + return true; + } + + internal string FullAssemblyName + { + get + { + StringBuilder sDisplayName = new StringBuilder(1024); + int iLen = 1024; + + int hrLocal = _fusionName.GetDisplayName( + sDisplayName, + ref iLen, + (int)PInvoke.Fusion.AssemblyNameDisplayFlags.ALL); + + if (hrLocal < 0) + { + throw Marshal.GetExceptionForHR(hrLocal); + } + + return sDisplayName.ToString(); + } + } + + internal PInvoke.Fusion.IAssemblyName FusionName + { + get + { + return _fusionName; + } + } + + public void Dispose() + { + PInvoke.Fusion.IAssemblyName tempName = _fusionName; + if (tempName != null) + { + _fusionName = null; + Marshal.ReleaseComObject(tempName); + } + + PInvoke.Fusion.IAssemblyEnum tempEnum = _assemblyEnum; + if (tempEnum != null) + { + _assemblyEnum = null; + Marshal.ReleaseComObject(tempEnum); + } + } + + private string _assemblyName; + private PInvoke.Fusion.IAssemblyEnum _assemblyEnum; + private PInvoke.Fusion.IAssemblyName _fusionName; + } + + internal class GACAssemblyCache : IDisposable + { + internal GACAssemblyCache(string assemblyName, string fullAssemblyName) + { + PInvoke.Fusion.AssemblyInfo aInfo = new PInvoke.Fusion.AssemblyInfo(); + aInfo.cchBuf = 1024; + aInfo.currentAssemblyPath = new string('\0', aInfo.cchBuf); + + int hResult = PInvoke.Fusion.NativeMethods.CreateAssemblyCache(out _assemblyCache, 0); + + if (hResult == 0) + { + hResult = _assemblyCache.QueryAssemblyInfo(0, fullAssemblyName, ref aInfo); + } + + if (hResult != 0) + { + Marshal.GetExceptionForHR(hResult); + } + + _assemblyPath = aInfo.currentAssemblyPath; + } + + internal string AssemblyPath + { + get + { + return _assemblyPath; + } + } + + public void Dispose() + { + PInvoke.Fusion.IAssemblyCache temp = _assemblyCache; + if (temp != null) + { + _assemblyCache = null; + Marshal.ReleaseComObject(temp); + } + } + + private string _assemblyPath; + private PInvoke.Fusion.IAssemblyCache _assemblyCache; + } +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/WebUtility.cs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/WebUtility.cs new file mode 100644 index 0000000000..2f5a9c93c4 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/Managed/Util/WebUtility.cs @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Collections; +using System.Net; + +namespace Microsoft.Web.Utility +{ + internal static class WebUtility + { + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification="We want to count any error as host doesn't exist")] + public static bool IsLocalMachine(string serverName, bool useDns) + { + if (String.Equals(serverName, Environment.MachineName, StringComparison.CurrentCultureIgnoreCase) || + String.Equals(serverName, "localhost", StringComparison.OrdinalIgnoreCase) || + String.Equals(serverName, "127.0.0.1") || + String.Equals(serverName, "::1")) + { + return true; + } + + if (useDns) + { + try + { + ArrayList serverAddressesList = new ArrayList(); + ArrayList currentMachineAddressesList = new ArrayList(); + + IPAddress ownAddress = IPAddress.Parse("127.0.0.1"); + + // All the IP addresses of the hostname specified by the user + IPAddress[] serverAddress = Dns.GetHostAddresses(serverName); + serverAddressesList.AddRange(serverAddress); + + /// All the IP addresses of the current machine + IPAddress[] currentMachineAddress = Dns.GetHostAddresses(Environment.MachineName); + currentMachineAddressesList.AddRange(currentMachineAddress); + + // The address 127.0.0.1 also refers to the current machine + currentMachineAddressesList.Add(ownAddress); + + // If any of the addresses for the current machine is the same + // as the address for the hostname specified by the user + // then use a local connection + foreach (IPAddress address in currentMachineAddressesList) + { + if (serverAddressesList.Contains(address)) + { + return true; + } + } + } + catch + { + // If the Dns class throws an exception the host propbably does not + // exist so we return false + } + } + + return false; + } + } +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/README.md b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/README.md new file mode 100644 index 0000000000..77fc8404c4 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/README.md @@ -0,0 +1,18 @@ +Microsoft IIS Common +-------------------------------- + +The repository contains common resources shared by IIS Out-Of-Band (OOB) products. + +### Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/common_tests.rc b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/common_tests.rc new file mode 100644 index 0000000000..98b1593b3b --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/common_tests.rc @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#define RC_VERSION_INTERNAL_NAME "Common.UnitTests\0" +#define RC_VERSION_ORIGINAL_FILE_NAME "Common.UnitTests.dll\0" +#define RC_VERSION_FILE_DESCRIPTION "Common.UnitTests0" +#include diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/dbgutil_tests.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/dbgutil_tests.cpp new file mode 100644 index 0000000000..2fc97d6f95 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/dbgutil_tests.cpp @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.hxx" +#include "dbgutil.h" +#include + +DECLARE_DEBUG_PRINT_OBJECT( "test" ); + +VOID PrintLevel( DWORD level ) +{ + DWORD old = DEBUG_FLAGS_VAR; + DEBUG_FLAGS_VAR = level; + + DBGPRINTF(( DBG_CONTEXT, "Some Data %d\n", 47 )); + DBGINFO(( DBG_CONTEXT, "Some Info %s\n", "info" )); + DBGWARN(( DBG_CONTEXT, "Some Info %s\n", "warning" )); + DBGERROR(( DBG_CONTEXT, "Some Info %s\n", "error" )); + + DEBUG_FLAGS_VAR = old; +} + + +#pragma managed + +using namespace Microsoft::VisualStudio::TestTools::UnitTesting; + +[TestClass] +public ref class DebugUtilitiesTests +{ +public: + + [ClassInitialize] + static void InitializeDebugObjects(TestContext) + { + CREATE_DEBUG_PRINT_OBJECT; + + _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); + _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR ); + } + + [TestMethod] + void TestDbgError() + { + PrintLevel( DEBUG_FLAGS_ERROR ); + } + + [TestMethod] + void TestPrintAny() + { + PrintLevel( DEBUG_FLAGS_ANY ); + } + + [TestMethod] + void TestPrintError() + { + DBGERROR_HR( E_FAIL ); + DBGERROR_STATUS( 47 ); + } + + [TestMethod] + void TestPrintWarn() + { + PrintLevel( DEBUG_FLAGS_WARN ); + } + + [TestMethod] + void TestPrintInfo() + { + PrintLevel( DEBUG_FLAGS_INFO ); + } +}; \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/hash_tests.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/hash_tests.cpp new file mode 100644 index 0000000000..c0fb29f5a2 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/hash_tests.cpp @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.hxx" +#include "hashtable.h" +#include "hashfn.h" +#include "my_hash.h" + +VOID +CountHash( + MY_OBJ * , //pRecord, + PVOID pVoid +) +{ + DWORD * pActualCount = (DWORD*) pVoid; + ++(*pActualCount); +} + + +#pragma managed + +using namespace Microsoft::VisualStudio::TestTools::UnitTesting; + +[TestClass] +public ref class HashTableTests +{ +public: + + [TestMethod] + void AddTwoRecordsTest() + { + MY_HASH hash; + HRESULT hr; + hr = hash.Initialize(32); + + Assert::AreEqual(S_OK, hr, L"Invalid hash table initialization"); + + MY_OBJ one(L"one"); + hr = hash.InsertRecord(&one); + Assert::AreEqual(S_OK, hr, L"Cannot add element 'one'"); + + MY_OBJ two(L"two"); + hr = hash.InsertRecord(&two); + Assert::AreEqual(S_OK, hr, L"Cannot add element 'two'"); + + DWORD ActualCount = 0; + hash.Apply(CountHash, &ActualCount); + Assert::AreEqual((DWORD)2, ActualCount, L"ActualCount != 2"); + + hash.Clear(); + } +}; diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/hybrid_array_tests.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/hybrid_array_tests.cpp new file mode 100644 index 0000000000..9f54467e77 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/hybrid_array_tests.cpp @@ -0,0 +1,95 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.hxx" +#include "hybrid_array.h" + +// +// Cannot support mixed native/managed code for BUFFER class +// because of alignment. We need to run the test as native. +// +#include + + +void HybridArrayTest() +{ + HRESULT hr; + + { + HYBRID_ARRAY arrPointers; + Assert::AreEqual(32, arrPointers.QueryCapacity(), L"Invalid initial length"); + } + + { + HYBRID_ARRAY arrIntegers; + int SourceArray[] = {1, 2, 3, 4}; + hr = arrIntegers.Copy( SourceArray ); + Assert::AreEqual(S_OK, hr, L"Copy failed."); + Assert::AreEqual(_countof(SourceArray), arrIntegers.QueryCapacity()); + } + + { + HYBRID_ARRAY arrIntegers; + int* pOriginal = arrIntegers.QueryArray(); + int SourceArray[] = {1, 2, 3, 4}; + hr = arrIntegers.Copy( SourceArray ); + int* pNew = arrIntegers.QueryArray(); + Assert::AreEqual(S_OK, hr, L"Copy failed."); + Assert::AreEqual(_countof(SourceArray), arrIntegers.QueryCapacity(), L"Size should be like source"); + Assert::AreNotEqual((__int64)pNew, (__int64)pOriginal, L"Pointer should be different"); + + Assert::AreEqual(1, arrIntegers[0], L"Index 0 failed."); + Assert::AreEqual(2, arrIntegers.QueryItem(1), L"Index 1 failed."); + Assert::AreEqual(3, arrIntegers.QueryItem(2), L"Index 2 failed."); + Assert::AreEqual(4, arrIntegers[3], L"Index 3 failed."); + } + + { + HYBRID_ARRAY arrIntegers; + hr = arrIntegers.EnsureCapacity(100, false); + Assert::AreEqual(S_OK, hr, L"Copy failed."); + Assert::AreEqual(100, arrIntegers.QueryCapacity()); + } + + { + HYBRID_ARRAY arrIntegers; + arrIntegers[0] = 123; + arrIntegers[1] = 999; + hr = arrIntegers.EnsureCapacity(100, true /*copy previous*/); + Assert::AreEqual(S_OK, hr, L"Copy failed."); + Assert::AreEqual(100, arrIntegers.QueryCapacity()); + Assert::AreEqual(123, arrIntegers[0], L"Index resize 0 failed."); + Assert::AreEqual(999, arrIntegers[1], L"Index resize 1 failed."); + + } + + { + HYBRID_ARRAY arrIntegers; + arrIntegers[0] = 123; + arrIntegers[1] = 999; + hr = arrIntegers.EnsureCapacity(100, true /*copy previous*/, true /*trivial assign*/); + Assert::AreEqual(S_OK, hr, L"Copy failed."); + Assert::AreEqual(100, arrIntegers.QueryCapacity()); + Assert::AreEqual(123, arrIntegers[0], L"Index resize trivial 0 failed."); + Assert::AreEqual(999, arrIntegers[1], L"Index resize trivial 1 failed."); + + } +} + + +#pragma managed + +using namespace Microsoft::VisualStudio::TestTools::UnitTesting; + +[TestClass] +public ref class ArrayTests +{ +public: + + [TestMethod] + void HybridArrayTest() + { + ::HybridArrayTest(); + } + +}; diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/my_hash.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/my_hash.h new file mode 100644 index 0000000000..71417dc77b --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/my_hash.h @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +class MY_OBJ +{ + public: + MY_OBJ(PCWSTR pstr) + : _pstr(pstr) + {} + + PCWSTR GetString() + { + return _pstr; + } + + private: + PCWSTR _pstr; +}; + +class MY_HASH : public HASH_TABLE +{ + public: + VOID + ReferenceRecord( + MY_OBJ * //pRecord + ) + {} + + VOID + DereferenceRecord( + MY_OBJ * //pRecord + ) + {} + + PCWSTR + ExtractKey( + MY_OBJ * pRecord + ) + { + return pRecord->GetString(); + } + + DWORD + CalcKeyHash( + PCWSTR key + ) + { + return HashString(key); + } + + BOOL + EqualKeys( + PCWSTR key1, + PCWSTR key2 + ) + { + return (wcscmp(key1, key2) == 0); + } +}; + +void TestHash(); \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/precomp.hxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/precomp.hxx new file mode 100644 index 0000000000..16c76d9540 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/precomp.hxx @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once +// Native-only by default +#pragma unmanaged +#include diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/string_tests.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/string_tests.cpp new file mode 100644 index 0000000000..0b987e9b58 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/UnitTests/string_tests.cpp @@ -0,0 +1,680 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.hxx" +#include "buffer.h" +#include "stringu.h" +#include "stringa.h" + +// +// Cannot support mixed native/managed code for BUFFER class +// because of alignment. We need to run the test as native. +// +#include + +void TestBuffer() +{ + // + // 104 == 8 byte size rounded, why is this needed? + // + STACK_BUFFER( bufStack, 104 ); + BUFFER bufReg; + BUFFER* pBuf = new BUFFER; + + // + // QueryPtr + // + Assert::IsNotNull( bufStack.QueryPtr( ) ); + Assert::IsNotNull( bufReg.QueryPtr( ) ); + Assert::IsNotNull( pBuf->QueryPtr( ) ); + + // + // QuerySize + // + Assert::IsTrue( 104 == bufStack.QuerySize( ) ); + Assert::IsTrue( INLINED_BUFFER_LEN == bufReg.QuerySize( ) ); + Assert::IsTrue( INLINED_BUFFER_LEN == pBuf->QuerySize( ) ); + + // + // Resize + // + Assert::IsTrue( bufStack.Resize( 64 ) ); + Assert::IsTrue( bufReg.Resize( 128) ); + Assert::IsTrue( pBuf->Resize( 256 ) ); + + // + // Resize again + // + Assert::IsTrue( bufStack.Resize( 512, true ) ); + Assert::IsTrue( bufReg.Resize( 512, true ) ); + Assert::IsTrue( pBuf->Resize( 512, true ) ); + + // + // Resize again + // + Assert::IsTrue( bufStack.Resize( 1024, false ) ); + Assert::IsTrue( bufReg.Resize( 1024, false ) ); + Assert::IsTrue( pBuf->Resize( 1024, false ) ); + + // + // write to mem + // + ZeroMemory( bufStack.QueryPtr( ), bufStack.QuerySize( ) ); + ZeroMemory( bufReg.QueryPtr( ), bufReg.QuerySize( ) ); + ZeroMemory( pBuf->QueryPtr( ), pBuf->QuerySize( ) ); + + delete pBuf; +} + +void TestStraOverrun() +{ + STACK_STRA( straStack, 3 ); + wchar_t Input[] = {0x65f6, 0x0}; + HRESULT hr; + + hr = straStack.CopyW(Input); + Assert::IsTrue( SUCCEEDED(hr) ); + Assert::AreEqual( 3, straStack.QueryCCH(), L"Invalid string length." ); + Assert::AreEqual( 4, straStack.QuerySizeCCH(), L"Invalid buffer length." ); +} + +#define LOWER_A_THING L"ä" +#define UPPER_A_THING L"Ä" + +void TestStru() +{ + STACK_STRU( struStack, 104 ); + STRU struReg; + wchar_t buf[100]; + DWORD cbBuf = sizeof( buf ); + + // + // IsEmpty + // + Assert::IsTrue( struStack.IsEmpty( ) ); + Assert::IsTrue( L'\0' == struStack.QueryStr()[0] ); + Assert::IsTrue( struReg.IsEmpty( ) ); + + // + // Copy psz + // CopyA psz + // + Assert::IsTrue( SUCCEEDED( struStack.Copy( L"hello" ) ) ); + Assert::IsTrue( SUCCEEDED( struReg.CopyA( "hello" ) ) ); + + // + // Equal + // + Assert::IsTrue( struStack.Equals( L"hello" ) ); + Assert::IsTrue( !struStack.Equals( L"goodbye" ) ); + Assert::IsTrue( !struStack.Equals( L"" ) ); + + STRU strHELLO; + Assert::IsTrue( SUCCEEDED( strHELLO.Copy( L"HELLO" ) ) ); + + Assert::IsTrue( struStack.Equals( &struReg ) ); + Assert::IsTrue( struStack.Equals( struReg ) ); + + Assert::IsTrue( !struStack.Equals( &strHELLO ) ); + Assert::IsTrue( !struStack.Equals( strHELLO ) ); + + Assert::IsTrue( struStack.Equals( &strHELLO, TRUE ) ); + Assert::IsTrue( struStack.Equals( strHELLO, TRUE ) ); + + Assert::IsTrue( struStack.Equals( L"helLO", TRUE ) ); + + + Assert::IsTrue( STRU::Equals( L"Hello", L"Hello" ) ); + Assert::IsTrue( STRU::Equals( L"Hello", L"Hello", FALSE ) ); + Assert::IsTrue( STRU::Equals( L"Hello", L"Hello", TRUE ) ); + + Assert::IsFalse( STRU::Equals( L"hello", L"Hello" ) ); + Assert::IsFalse( STRU::Equals( L"hello", L"Hello", FALSE ) ); + Assert::IsTrue( STRU::Equals( L"hello", L"Hello", TRUE ) ); + + Assert::IsFalse( STRU::Equals( L"hello", L"goodbye" ) ); + Assert::IsFalse( STRU::Equals( L"hello", L"goodbye", FALSE ) ); + Assert::IsFalse( STRU::Equals( L"hello", L"goodbye", TRUE ) ); + + Assert::IsFalse( STRU::Equals( (PCWSTR)NULL, (PCWSTR)NULL ) ); + Assert::IsFalse( STRU::Equals( L"hello", (PCWSTR)NULL ) ); + Assert::IsFalse( STRU::Equals( (PCWSTR)NULL, L"hello" ) ); + + + + // + // Query* + // + Assert::IsTrue( 5 * sizeof( wchar_t ) == struStack.QueryCB( ) ); + Assert::IsTrue( 5 == struStack.QueryCCH( ) ); + Assert::IsTrue( 6 <= struStack.QuerySizeCCH( ) ); + Assert::IsTrue( L'h' == *( struStack.QueryStr( ) ) ); + + // + // Resize + // + Assert::IsTrue( SUCCEEDED( struReg.Resize( 7 ) ) ); + Assert::IsTrue( 7 == struReg.QuerySizeCCH( ) ); + + // + // SyncWithBuffer + // + *(struStack.QueryStr() + 5) = L'\0'; + Assert::AreEqual(S_OK, struStack.SyncWithBuffer( )); + Assert::IsTrue( 5 == struStack.QueryCCH( ) ); + + // + // Reset + // + struStack.Reset( ); + Assert::IsTrue( 0 == wcslen( struStack.QueryStr( ) ) ); + + // + // Append* + // + Assert::IsTrue( SUCCEEDED( struStack.Append( L"hell" ) ) ); + Assert::IsTrue( SUCCEEDED( struStack.Append( L"o", 1 ) ) ); + Assert::IsTrue( SUCCEEDED( struStack.Append( &struReg ) ) ); + Assert::IsTrue( SUCCEEDED( struStack.AppendA( "hell" ) ) ); + Assert::IsTrue( SUCCEEDED( struStack.AppendA( "0", 1, CP_ACP ) ) ); + Assert::IsTrue( 15 == wcslen( struStack.QueryStr( ) ) ); + + // + // CopyToBuffer + // + Assert::IsTrue( SUCCEEDED( struStack.CopyToBuffer( buf, &cbBuf ) ) ); + Assert::IsTrue( 15 == wcslen( buf ) ); + Assert::IsTrue( 16 * sizeof( wchar_t ) == cbBuf ); + + // + // Trim + // + Assert::IsTrue( SUCCEEDED( struStack.Copy(L" \n\tHello World! \n\t ") ) ); + struStack.Trim(); + Assert::IsTrue( struStack.Equals(L"Hello World!")); + + Assert::IsTrue( SUCCEEDED( struStack.Copy(L" Test test") ) ); + struStack.Trim(); + Assert::IsTrue( struStack.Equals(L"Test test")); + + Assert::IsTrue( SUCCEEDED( struStack.Copy(L"Test test ") ) ); + struStack.Trim(); + Assert::IsTrue( struStack.Equals(L"Test test")); + + Assert::IsTrue( SUCCEEDED( struStack.Copy(L" Test test ") ) ); + struStack.Trim(); + Assert::IsTrue( struStack.Equals(L"Test test")); + + Assert::IsTrue( SUCCEEDED( struStack.Copy(L" ") ) ); + struStack.Trim(); + Assert::IsTrue( struStack.Equals(L"")); + + Assert::IsTrue( SUCCEEDED( struStack.Copy(L" ") ) ); + struStack.Trim(); + Assert::IsTrue( struStack.Equals(L"")); + + Assert::IsTrue( SUCCEEDED( struStack.Copy(L"") ) ); + struStack.Trim(); + Assert::IsTrue( struStack.Equals(L"")); + + // + // StartsWith + // + Assert::IsTrue( SUCCEEDED( struStack.Copy(L"Just the facts, please.") ) ); + Assert::IsTrue( struStack.StartsWith(L"Just the facts, please.") ); + Assert::IsTrue( struStack.StartsWith(L"Just") ); + Assert::IsTrue( struStack.StartsWith(L"Just the") ); + Assert::IsTrue( !struStack.StartsWith(L"just the") ); + Assert::IsTrue( struStack.StartsWith(L"just The", TRUE) ); + Assert::IsTrue( !struStack.StartsWith((LPCWSTR) NULL, TRUE) ); + Assert::IsTrue( !struStack.StartsWith(L"Just the facts, please...") ); + + // + // EndsWith + // + Assert::IsTrue( SUCCEEDED( struStack.Copy(L"The beginning of the end of the beginning.") ) ); + Assert::IsTrue( struStack.EndsWith(L"The beginning of the end of the beginning.") ); + Assert::IsTrue( struStack.EndsWith(L".") ); + Assert::IsTrue( struStack.EndsWith(L"of the beginning.") ); + Assert::IsTrue( !struStack.EndsWith(L"Beginning.") ); + Assert::IsTrue( struStack.EndsWith(L"Beginning.", TRUE) ); + Assert::IsTrue( struStack.EndsWith(L"tHe BeGiNnIng.", TRUE) ); + Assert::IsTrue( !struStack.EndsWith((LPCWSTR) NULL, TRUE) ); + Assert::IsTrue( !struStack.EndsWith(L" The beginning of the end of the beginning.") ); + + // + // IndexOf + // + Assert::IsTrue( SUCCEEDED( struStack.Copy(L"01234567890") ) ); + Assert::IsTrue( 0 == struStack.IndexOf( L'0' ) ); + Assert::IsTrue( 1 == struStack.IndexOf( L'1' ) ); + Assert::IsTrue( 2 == struStack.IndexOf( L'2', 1 ) ); + Assert::IsTrue( 10 == struStack.IndexOf( L'0', 1 ) ); + Assert::IsTrue( -1 == struStack.IndexOf( L'A' ) ); + Assert::IsTrue( -1 == struStack.IndexOf( L'0', 20 ) ); + + Assert::IsTrue( 0 == struStack.IndexOf( L"0123" ) ); + Assert::IsTrue( -1 == struStack.IndexOf( L"0123", 1 ) ); + Assert::IsTrue( 0 == struStack.IndexOf( L"01234567890" ) ); + Assert::IsTrue( -1 == struStack.IndexOf( L"012345678901" ) ); + Assert::IsTrue( 1 == struStack.IndexOf( L"1234" ) ); + Assert::IsTrue( 1 == struStack.IndexOf( L"1234", 1 ) ); + Assert::IsTrue( -1 == struStack.IndexOf( (PCWSTR)NULL ) ); + Assert::IsTrue( 0 == struStack.IndexOf( L"" ) ); + Assert::IsTrue( -1 == struStack.IndexOf( L"", 20 ) ); + + // + // LastIndexOf + // + Assert::IsTrue( 10 == struStack.LastIndexOf( L'0' ) ); + Assert::IsTrue( 1 == struStack.LastIndexOf( L'1' ) ); + Assert::IsTrue( 2 == struStack.LastIndexOf( L'2', 1 ) ); + Assert::IsTrue( 10 == struStack.LastIndexOf( L'0', 1 ) ); + Assert::IsTrue( -1 == struStack.LastIndexOf( L'A' ) ); + Assert::IsTrue( -1 == struStack.LastIndexOf( L'0', 20 ) ); + + // + // SetLen + // + Assert::IsTrue( SUCCEEDED( struStack.SetLen( 2 ) ) ); + Assert::IsTrue( 2 == struStack.QueryCCH( ) ); + +#if defined( NTDDI_VERSION ) && NTDDI_VERSION >= NTDDI_LONGHORN + + // + // OS-locale case-insensitive compare + // Note how the two case-insensitive comparisons have different expected results + // + Assert::IsTrue( SUCCEEDED( struStack.Copy( LOWER_A_THING ) ) ); + Assert::IsTrue( SUCCEEDED( struReg.Copy( UPPER_A_THING ) ) ); + Assert::IsTrue( !struStack.Equals( &struReg ) ); + Assert::IsTrue( struStack.Equals( &struReg, TRUE ) ); + Assert::IsTrue( 0 != _wcsicmp( LOWER_A_THING, UPPER_A_THING ) ); + +#endif + + Assert::IsTrue( SUCCEEDED( struReg.SafeSnwprintf( L"%s%d", L"Hello", 10 ) ) ); + + // + // Fail since there is no null-terminating char. + // + struStack.Reset(); + struStack.Resize(200); + memset(struStack.QueryStr(), 'x', 200 * sizeof(WCHAR)); + Assert::AreNotEqual(S_OK, struStack.SyncWithBuffer()); +} + +void TestStra() +{ + STACK_STRA( straStack, 104 ); + STRA straReg; + char buf[100]; + DWORD cbBuf = sizeof( buf ); + + // + // IsEmpty + // + Assert::IsTrue( straStack.IsEmpty( ) ); + Assert::IsTrue( '\0' == straStack.QueryStr()[0] ); + Assert::IsTrue( straReg.IsEmpty( ) ); + + // + // Copy psz + // CopyW psz + // + Assert::IsTrue( SUCCEEDED( straStack.Copy( "hello" ) ) ); + Assert::IsTrue( SUCCEEDED( straReg.CopyW( L"hello" ) ) ); + + // + // Equal + // + Assert::IsTrue( straStack.Equals( "hello" ) ); + Assert::IsTrue( straStack.Equals( &straReg ) ); + Assert::IsTrue( straStack.Equals( "helLO", TRUE ) ); + + + Assert::IsTrue( STRA::Equals( "Hello", "Hello" ) ); + Assert::IsTrue( STRA::Equals( "Hello", "Hello", FALSE ) ); + Assert::IsTrue( STRA::Equals( "Hello", "Hello", TRUE ) ); + + Assert::IsFalse( STRA::Equals( "hello", "Hello" ) ); + Assert::IsFalse( STRA::Equals( "hello", "Hello", FALSE ) ); + Assert::IsTrue( STRA::Equals( "hello", "Hello", TRUE ) ); + + Assert::IsFalse( STRA::Equals( "hello", "goodbye" ) ); + Assert::IsFalse( STRA::Equals( "hello", "goodbye", FALSE ) ); + Assert::IsFalse( STRA::Equals( "hello", "goodbye", TRUE ) ); + + Assert::IsFalse( STRA::Equals( (PCSTR)NULL, (PCSTR)NULL ) ); + Assert::IsFalse( STRA::Equals( "hello", (PCSTR)NULL ) ); + Assert::IsFalse( STRA::Equals( (PCSTR)NULL, "hello" ) ); + + // + // Query* + // + Assert::IsTrue( 5 * sizeof( char ) == straStack.QueryCB( ) ); + Assert::IsTrue( 5 == straStack.QueryCCH( ) ); + Assert::IsTrue( 6 <= straStack.QuerySizeCCH( ) ); + Assert::IsTrue( 'h' == *( straStack.QueryStr( ) ) ); + + // + // Resize + // + Assert::IsTrue( SUCCEEDED( straReg.Resize( 7 ) ) ); + Assert::IsTrue( 7 == straReg.QuerySizeCCH( ) ); + + // + // SyncWithBuffer + // + *(straStack.QueryStr() + 5) = L'\0'; + Assert::AreEqual(S_OK, straStack.SyncWithBuffer( )); + Assert::IsTrue( 5 == straStack.QueryCCH( ) ); + + // + // Reset + // + straStack.Reset( ); + Assert::IsTrue( 0 == strlen( straStack.QueryStr( ) ) ); + + // + // Append* + // + Assert::IsTrue( SUCCEEDED( straStack.Append( "hell" ) ) ); + Assert::IsTrue( SUCCEEDED( straStack.Append( "o", 1 ) ) ); + Assert::IsTrue( SUCCEEDED( straStack.Append( &straReg ) ) ); + Assert::IsTrue( SUCCEEDED( straStack.AppendW( L"hell" ) ) ); + Assert::IsTrue( SUCCEEDED( straStack.AppendW( L"0", 1, CP_ACP ) ) ); + Assert::IsTrue( 15 == strlen( straStack.QueryStr( ) ) ); + + // + // CopyToBuffer + // + Assert::IsTrue( SUCCEEDED( straStack.CopyToBuffer( buf, &cbBuf ) ) ); + Assert::IsTrue( 15 == strlen( buf ) ); + Assert::IsTrue( 16 * sizeof( char ) == cbBuf ); + + // + // Trim + // + Assert::IsTrue( SUCCEEDED( straStack.Copy(" \n\tHello World! \n\t ") ) ); + straStack.Trim(); + Assert::IsTrue( straStack.Equals("Hello World!")); + + Assert::IsTrue( SUCCEEDED( straStack.Copy(" Test test") ) ); + straStack.Trim(); + Assert::IsTrue( straStack.Equals("Test test")); + + Assert::IsTrue( SUCCEEDED( straStack.Copy("Test test ") ) ); + straStack.Trim(); + Assert::IsTrue( straStack.Equals("Test test")); + + Assert::IsTrue( SUCCEEDED( straStack.Copy(" Test test ") ) ); + straStack.Trim(); + Assert::IsTrue( straStack.Equals("Test test")); + + Assert::IsTrue( SUCCEEDED( straStack.Copy(" ") ) ); + straStack.Trim(); + Assert::IsTrue( straStack.Equals("")); + + Assert::IsTrue( SUCCEEDED( straStack.Copy(" ") ) ); + straStack.Trim(); + Assert::IsTrue( straStack.Equals("")); + + Assert::IsTrue( SUCCEEDED( straStack.Copy("") ) ); + straStack.Trim(); + Assert::IsTrue( straStack.Equals("")); + + // + // StartsWith + // + Assert::IsTrue( SUCCEEDED( straStack.Copy("Just the facts, please.") ) ); + Assert::IsTrue( straStack.StartsWith("Just the facts, please.") ); + Assert::IsTrue( straStack.StartsWith("Just") ); + Assert::IsTrue( straStack.StartsWith("Just the") ); + Assert::IsTrue( !straStack.StartsWith("just the") ); + Assert::IsTrue( straStack.StartsWith("just The", TRUE) ); + Assert::IsTrue( !straStack.StartsWith((LPCSTR) NULL, TRUE) ); + Assert::IsTrue( !straStack.StartsWith("Just the facts, please...") ); + + // + // EndsWith + // + Assert::IsTrue( SUCCEEDED( straStack.Copy("The beginning of the end of the beginning.") ) ); + Assert::IsTrue( straStack.EndsWith("The beginning of the end of the beginning.") ); + Assert::IsTrue( straStack.EndsWith(".") ); + Assert::IsTrue( straStack.EndsWith("of the beginning.") ); + Assert::IsTrue( !straStack.EndsWith("Beginning.") ); + Assert::IsTrue( straStack.EndsWith("Beginning.", TRUE) ); + Assert::IsTrue( straStack.EndsWith("tHe BeGiNnIng.", TRUE) ); + Assert::IsTrue( !straStack.EndsWith((LPCSTR) NULL, TRUE) ); + Assert::IsTrue( !straStack.EndsWith(" The beginning of the end of the beginning.") ); + + // + // IndexOf + // + Assert::IsTrue( SUCCEEDED( straStack.Copy("01234567890") ) ); + Assert::IsTrue( 0 == straStack.IndexOf( '0' ) ); + Assert::IsTrue( 1 == straStack.IndexOf( '1' ) ); + Assert::IsTrue( 2 == straStack.IndexOf( '2', 1 ) ); + Assert::IsTrue( 10 == straStack.IndexOf( '0', 1 ) ); + Assert::IsTrue( -1 == straStack.IndexOf( 'A' ) ); + Assert::IsTrue( -1 == straStack.IndexOf( '0', 20 ) ); + + Assert::IsTrue( 0 == straStack.IndexOf( "0123" ) ); + Assert::IsTrue( -1 == straStack.IndexOf( "0123", 1 ) ); + Assert::IsTrue( 0 == straStack.IndexOf( "01234567890" ) ); + Assert::IsTrue( -1 == straStack.IndexOf( "012345678901" ) ); + Assert::IsTrue( 1 == straStack.IndexOf( "1234" ) ); + Assert::IsTrue( 1 == straStack.IndexOf( "1234", 1 ) ); + Assert::IsTrue( -1 == straStack.IndexOf( (PCSTR)NULL ) ); + Assert::IsTrue( 0 == straStack.IndexOf( "" ) ); + Assert::IsTrue( -1 == straStack.IndexOf( "", 20 ) ); + + // + // LastIndexOf + // + Assert::IsTrue( 10 == straStack.LastIndexOf( '0' ) ); + Assert::IsTrue( 1 == straStack.LastIndexOf( '1' ) ); + Assert::IsTrue( 2 == straStack.LastIndexOf( '2', 1 ) ); + Assert::IsTrue( 10 == straStack.LastIndexOf( '0', 1 ) ); + Assert::IsTrue( -1 == straStack.LastIndexOf( 'A' ) ); + Assert::IsTrue( -1 == straStack.LastIndexOf( '0', 20 ) ); + + // + // SetLen + // + Assert::IsTrue( SUCCEEDED( straStack.SetLen( 2 ) ) ); + Assert::IsTrue( 2 == straStack.QueryCCH( ) ); + + + // + // Convert. + // + { + STRA str; + wchar_t psz[] = {0x41, L'Ã', 0x0}; + char pszA[] = {0x41, 'Ã', 0x0}; + Assert::IsTrue( SUCCEEDED(str.CopyW((LPCWSTR)psz, 2, CP_ACP )) ); + Assert::IsTrue( 0 == strcmp( pszA, str.QueryStr() ) ); + } + // + // Empty + // + { + STRA str; + wchar_t psz[] = {0x0}; + char pszA[] = {0x0}; + Assert::IsTrue( SUCCEEDED(str.CopyW((LPCWSTR)psz, 0, CP_ACP )) ); + Assert::IsTrue( 0 == strcmp( pszA, str.QueryStr() ) ); + } + + // + // Fail since there is no null-terminating char. + // + straStack.Reset(); + straStack.Resize(200); + memset(straStack.QueryStr(), 'x', 200); + Assert::AreNotEqual(S_OK, straStack.SyncWithBuffer()); +} + +VOID +AsciiAssert(char * str1, char * str2, size_t length) +{ + for ( size_t index = 0; index < length; ++index ) + { + Assert::AreEqual(str1[index], str2[index]); + } +} + +void +TestStraUnicode() +{ + STRA str; + HRESULT hr = S_OK; + + // + // Tool used to convert unicode to UTF-8 code points and hexadecimal code points: + // http://rishida.net/scripts/uniview/conversion.php + // + + // + // Input values to play with. + // + + // Real unicode string. + LPCWSTR InputRealUnicode = L"?q=世加"; + + // This is the same value than InputRealUnicode, but represented as an array. + wchar_t InputRealUnicodeArray[] = + { + 0x3F, // ? + 0x71, // q + 0x3D, // = + 0x4E16, // 世 + 0x52A0, // 加 + 0x00 // L'\0' + }; + + wchar_t InputAscii[] = + { + 0x3F, // ? + 0x71, // q + 0x3D, // = + 0x7F, // 127 + 0x00 // L'\0' + }; + + // Fake unicode + // UTF-8 code units in 'wchar_t' chars instead of 'char' chars. + // This is how WinHttp returns the query string. + wchar_t InputFakeUnicode[] = + { + 0x3F, // ? + 0x71, // q + 0x3D, // = + 0xE4, // 1st code unit for '世' + 0xB8, // 2nd code unit for '世' + 0x96, // 3rd code unit for '世' + 0xE5, // 1st code unit for '加' + 0x8A, // 2nd code unit for '加' + 0xA0, // 3rd code unit for '加' + 0x00 // L'\0' + }; + + // + // Expected values after translation. + // + + unsigned char ExpectedAsciiCodeUnits[] = + { + 0x3F, // ? + 0x71, // q + 0x3D, // = + 0xE4, // 1st code unit for '世' + 0xB8, // 2nd code unit for '世' + 0x96, // 3rd code unit for '世' + 0xE5, // 1st code unit for '加' + 0x8A, // 2nd code unit for '加' + 0xA0, // 3rd code unit for '加' + 0x00 // L'\0' + }; + + char ExpectedAscii[] = + { + 0x3F, // ? + 0x71, // q + 0x3D, // = + 0x7F, // 127 + 0x00 // L'\0' + }; + + // + // Act and Assert. + // + + hr = str.CopyW(InputRealUnicode); + Assert::AreEqual(S_OK, hr); + Assert::AreEqual(9UL, str.QueryCCH(), L"Invalid real unicode query string length."); + AsciiAssert( (char*)ExpectedAsciiCodeUnits, str.QueryStr(), str.QueryCCH() ); + + hr = str.CopyW(InputRealUnicodeArray); + Assert::AreEqual(S_OK, hr); + Assert::AreEqual(9UL, str.QueryCCH(), L"Invalid real unicode query string length."); + AsciiAssert( (char*)ExpectedAsciiCodeUnits, str.QueryStr(), str.QueryCCH() ); + + hr = str.CopyWTruncate(InputFakeUnicode); + Assert::AreEqual(S_OK, hr); + Assert::AreEqual(9UL, str.QueryCCH(), L"Invalid truncated fake unicode query string length."); + AsciiAssert( (char*)ExpectedAsciiCodeUnits, str.QueryStr(), str.QueryCCH() ); + + hr = str.CopyWTruncate(InputAscii); + Assert::AreEqual(S_OK, hr); + Assert::AreEqual(4UL, str.QueryCCH(), L"Invalid truncated ASCII query string length."); + AsciiAssert( ExpectedAscii, str.QueryStr(), str.QueryCCH() ); + + hr = str.CopyW(InputAscii); + Assert::AreEqual(S_OK, hr); + Assert::AreEqual(4UL, str.QueryCCH(), L"Invalid CopyW ASCII query string length."); + AsciiAssert( ExpectedAscii, str.QueryStr(), str.QueryCCH() ); + +} + +#pragma managed + +using namespace Microsoft::VisualStudio::TestTools::UnitTesting; + +[TestClass] +public ref class StringTests +{ +public: + + [TestMethod] + void BufferTest() + { + ::TestBuffer(); + } + + [TestMethod] + void StruTest() + { + ::TestStru(); + } + + [TestMethod] + void StraTest() + { + ::TestStra(); + } + + [TestMethod] + void TestStraOverrun() + { + ::TestStraOverrun(); + } + + [TestMethod] + void StraUnicodeTest() + { + ::TestStraUnicode(); + } +}; diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/compiler.props b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/compiler.props new file mode 100644 index 0000000000..7394db4ad1 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/compiler.props @@ -0,0 +1,17 @@ + + + + 14.11.25547 + $(UserProfile)\.nuget\packages\visualcpptools.community.vs2017layout\$(CppNugetVersion)\build\native\VisualCppTools.Community.VS2017Layout.props + $(UserProfile)\.nuget\GlobalPackages\visualcpptools.community.vs2017layout.$(CppNugetVersion)\build\native\VisualCppTools.Community.VS2017Layout.props + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/copy-outputs.targets b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/copy-outputs.targets new file mode 100644 index 0000000000..bdc59f4f6d --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/copy-outputs.targets @@ -0,0 +1,18 @@ + + + + + + + + $(Configuration)\$(PlatformShortname)\ + + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/exports.props b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/exports.props new file mode 100644 index 0000000000..fb90d74264 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/exports.props @@ -0,0 +1,9 @@ + + + + + + $(MSBuildThisFileDirectory)..\ + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings.props b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings.props new file mode 100644 index 0000000000..bd51e2d1af --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings.props @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings/common.props b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings/common.props new file mode 100644 index 0000000000..0130b6e5ab --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings/common.props @@ -0,0 +1,53 @@ + + + + + + + x64 + x86 + + + + + + 10.0.15063.0 + $(IisOobWinSdkVersion) + Unicode + bin\$(Configuration)\$(PlatformShortname)\ + obj\$(Configuration)\$(PlatformShortname)\ + + + + + + + Level3 + + + + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + + + WIN32;%(PreprocessorDefinitions) + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings/debug.props b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings/debug.props new file mode 100644 index 0000000000..710f5553d0 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings/debug.props @@ -0,0 +1,29 @@ + + + + + + true + true + false + + + + + + + true + Disabled + true + EnableFastChecks + MultiThreadedDebug + + + false + false + true + /JMC- + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings/release.props b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings/release.props new file mode 100644 index 0000000000..d7eb8ffa35 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/settings/release.props @@ -0,0 +1,51 @@ + + + + + + + true + true + + + + + + + false + false + true + + + + + + + Full + Speed + false + MultiThreaded + true + + + true + true + UseLinkTimeCodeGeneration + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/submodule.props b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/submodule.props new file mode 100644 index 0000000000..00046cf191 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/submodule.props @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/versions.props b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/versions.props new file mode 100644 index 0000000000..3be2245e72 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/build/versions.props @@ -0,0 +1,38 @@ + + + + + 7 + 1 + + + $([MSBuild]::Multiply(12,$([MSBuild]::Subtract($([System.DateTime]::Now.Year), 2016)))) + $([MSBuild]::Add( $([MSBuild]::Subtract($([System.DateTime]::Now.Month), 10)), $(VersionDateMonths))) + $([System.DateTime]::Now.ToString("dd")) + $([System.String]::Concat($([System.Int32]::Parse('$(VersionDateTotalMonths)').ToString("D3")), $(VersionDateDays))) + $(VersionBuildMajor) + $([System.DateTime]::Now.ToString("HHmm")) + + + + + /DPRODUCT_MAJOR=$(PRODUCT_MAJOR) %(AdditionalOptions) + + + /DPRODUCT_MINOR=$(PRODUCT_MINOR) %(AdditionalOptions) + + + /DBUILD_MAJOR=$(BUILD_MAJOR) %(AdditionalOptions) + + + /DBUILD_MINOR=$(BUILD_MINOR) %(AdditionalOptions) + + + + + PRODUCT_MAJOR=$(PRODUCT_MAJOR);$(ResourceCompilePreprocessorDefinitions) + PRODUCT_MINOR=$(PRODUCT_MINOR);$(ResourceCompilePreprocessorDefinitions) + BUILD_MAJOR=$(BUILD_MAJOR);$(ResourceCompilePreprocessorDefinitions) + BUILD_MINOR=$(BUILD_MINOR);$(ResourceCompilePreprocessorDefinitions) + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/CommonLib.vcxproj b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/CommonLib.vcxproj new file mode 100644 index 0000000000..1e32646e9a --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/CommonLib.vcxproj @@ -0,0 +1,78 @@ + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {B54A8F61-60DE-4AD9-87CA-D102F230678E} + Win32Proj + Lib + CommonLib + + + + StaticLibrary + v141 + + + false + + + + $(ProjectDir)..\include;$(IncludePath) + iiscommon + + + + true + precomp.h + _LIB;%(PreprocessorDefinitions) + + + Windows + + + + + + + + + + + + + + + + + + + + + + This project is trying to import a missing file: {0}. + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/acache.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/acache.cxx new file mode 100644 index 0000000000..262c010a2a --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/acache.cxx @@ -0,0 +1,443 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +LONG ALLOC_CACHE_HANDLER::sm_nFillPattern = 0xACA50000; +HANDLE ALLOC_CACHE_HANDLER::sm_hHeap; + +// +// This class is used to implement the free list. We cast the free'd +// memory block to a FREE_LIST_HEADER*. The signature is used to guard against +// double deletion. We also fill memory with a pattern. +// +class FREE_LIST_HEADER +{ +public: + SLIST_ENTRY ListEntry; + DWORD dwSignature; + + enum + { + FREE_SIGNATURE = (('A') | ('C' << 8) | ('a' << 16) | (('$' << 24) | 0x80)), + }; +}; + +ALLOC_CACHE_HANDLER::ALLOC_CACHE_HANDLER( + VOID +) : m_nThreshold(0), + m_cbSize(0), + m_pFreeLists(NULL), + m_nTotal(0) +{ +} + +ALLOC_CACHE_HANDLER::~ALLOC_CACHE_HANDLER( + VOID +) +{ + if (m_pFreeLists != NULL) + { + CleanupLookaside(); + m_pFreeLists->Dispose(); + m_pFreeLists = NULL; + } +} + +HRESULT +ALLOC_CACHE_HANDLER::Initialize( + DWORD cbSize, + LONG nThreshold +) +{ + HRESULT hr = S_OK; + + m_nThreshold = nThreshold; + if ( m_nThreshold > 0xffff) + { + // + // This will be compared against QueryDepthSList return value (USHORT). + // + m_nThreshold = 0xffff; + } + + if ( IsPageheapEnabled() ) + { + // + // Disable acache. + // + m_nThreshold = 0; + } + + // + // Make sure the block is big enough to hold a FREE_LIST_HEADER. + // + m_cbSize = cbSize; + m_cbSize = max(m_cbSize, sizeof(FREE_LIST_HEADER)); + + // + // Round up the block size to a multiple of the size of a LONG (for + // the fill pattern in Free()). + // + m_cbSize = (m_cbSize + sizeof(LONG) - 1) & ~(sizeof(LONG) - 1); + +#if defined(_MSC_VER) && _MSC_VER >= 1600 // VC10 + auto Init = [] (SLIST_HEADER* pHead) + { + InitializeSListHead(pHead); + }; +#else + class Functor + { + public: + void operator()(SLIST_HEADER* pHead) + { + InitializeSListHead(pHead); + } + } Init; +#endif + + hr = PER_CPU::Create(Init, + &m_pFreeLists ); + if (FAILED(hr)) + { + goto Finished; + } + + m_nFillPattern = InterlockedIncrement(&sm_nFillPattern); + +Finished: + + return hr; +} + +// static +HRESULT +ALLOC_CACHE_HANDLER::StaticInitialize( + VOID +) +{ + // + // Since the memory allocated is fixed size, + // a heap is not really needed, allocations can be done + // using VirtualAllocEx[Numa]. For now use Windows Heap. + // + // Be aware that creating one private heap consumes more + // virtual address space for the worker process. + // + sm_hHeap = GetProcessHeap(); + return S_OK; +} + + +// static +VOID +ALLOC_CACHE_HANDLER::StaticTerminate( + VOID +) +{ + sm_hHeap = NULL; +} + +VOID +ALLOC_CACHE_HANDLER::CleanupLookaside( + VOID +) +/*++ + Description: + This function cleans up the lookaside list by removing storage space. + + Arguments: + None. + + Returns: + None +--*/ +{ + // + // Free up all the entries in the list. + // Don't use InterlockedFlushSList, in order to work + // memory must be 16 bytes aligned and currently it is 64. + // + +#if defined(_MSC_VER) && _MSC_VER >= 1600 // VC10 + auto Predicate = [=] (SLIST_HEADER * pListHeader) + { + PSLIST_ENTRY pl; + LONG NodesToDelete = QueryDepthSList( pListHeader ); + + pl = InterlockedPopEntrySList( pListHeader ); + while ( pl != NULL && --NodesToDelete >= 0 ) + { + InterlockedDecrement( &m_nTotal); + + ::HeapFree( sm_hHeap, 0, pl ); + + pl = InterlockedPopEntrySList(pListHeader); + } + }; +#else + class Functor + { + public: + explicit Functor(ALLOC_CACHE_HANDLER * pThis) : _pThis(pThis) + { + } + void operator()(SLIST_HEADER * pListHeader) + { + PSLIST_ENTRY pl; + LONG NodesToDelete = QueryDepthSList( pListHeader ); + + pl = InterlockedPopEntrySList( pListHeader ); + while ( pl != NULL && --NodesToDelete >= 0 ) + { + InterlockedDecrement( &_pThis->m_nTotal); + + ::HeapFree( sm_hHeap, 0, pl ); + + pl = InterlockedPopEntrySList(pListHeader); + } + } + private: + ALLOC_CACHE_HANDLER * _pThis; + } Predicate(this); +#endif + + m_pFreeLists ->ForEach(Predicate); +} + +LPVOID +ALLOC_CACHE_HANDLER::Alloc( + VOID +) +{ + LPVOID pMemory = NULL; + + if ( m_nThreshold > 0 ) + { + SLIST_HEADER * pListHeader = m_pFreeLists ->GetLocal(); + pMemory = (LPVOID) InterlockedPopEntrySList(pListHeader); // get the real object + + if (pMemory != NULL) + { + FREE_LIST_HEADER* pfl = (FREE_LIST_HEADER*) pMemory; + // + // If the signature is wrong then somebody's been scribbling + // on memory that they've freed. + // + DBG_ASSERT(pfl->dwSignature == FREE_LIST_HEADER::FREE_SIGNATURE); + } + } + + if ( pMemory == NULL ) + { + // + // No free entry. Need to alloc a new object. + // + pMemory = (LPVOID) ::HeapAlloc( sm_hHeap, + 0, + m_cbSize ); + + if ( pMemory != NULL ) + { + // + // Update counters. + // + m_nTotal++; + } + } + + if ( pMemory == NULL ) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + } + else + { + FREE_LIST_HEADER* pfl = (FREE_LIST_HEADER*) pMemory; + pfl->dwSignature = 0; // clear; just in case caller never overwrites + } + + return pMemory; +} + +VOID +ALLOC_CACHE_HANDLER::Free( + __in LPVOID pMemory +) +{ + // + // Assume that this is allocated using the Alloc() function. + // + DBG_ASSERT(NULL != pMemory); + + // + // Use a signature to check against double deletions. + // + FREE_LIST_HEADER* pfl = (FREE_LIST_HEADER*) pMemory; + DBG_ASSERT(pfl->dwSignature != FREE_LIST_HEADER::FREE_SIGNATURE); + + // + // Start filling the space beyond the portion overlaid by the initial + // FREE_LIST_HEADER. Fill at most 6 DWORDS. + // + LONG* pl = (LONG*) (pfl+1); + + for (LONG cb = (LONG)min(6 * sizeof(LONG),m_cbSize) - sizeof(FREE_LIST_HEADER); + cb > 0; + cb -= sizeof(LONG)) + { + *pl++ = m_nFillPattern; + } + + // + // Now, set the signature. + // + pfl->dwSignature = FREE_LIST_HEADER::FREE_SIGNATURE; + + // + // Store the items in the alloc cache. + // + SLIST_HEADER * pListHeader = m_pFreeLists ->GetLocal(); + + if ( QueryDepthSList(pListHeader) >= m_nThreshold ) + { + // + // Threshold for free entries is exceeded. Free the object to + // process pool. + // + ::HeapFree( sm_hHeap, 0, pMemory ); + } + else + { + // + // Store the given pointer in the single linear list + // + InterlockedPushEntrySList(pListHeader, &pfl->ListEntry); + } +} + +DWORD +ALLOC_CACHE_HANDLER::QueryDepthForAllSLists( + VOID +) +/*++ + +Description: + + Aggregates the total count of elements in all lists. + +Arguments: + + None. + +Return Value: + + Total count (snapshot). + +--*/ +{ + DWORD Count = 0; + + if (m_pFreeLists != NULL) + { +#if defined(_MSC_VER) && _MSC_VER >= 1600 // VC10 + auto Predicate = [&Count] (SLIST_HEADER * pListHeader) + { + Count += QueryDepthSList(pListHeader); + }; +#else + class Functor + { + public: + explicit Functor(DWORD& Count) : _Count(Count) + { + } + void operator()(SLIST_HEADER * pListHeader) + { + _Count += QueryDepthSList(pListHeader); + } + private: + DWORD& _Count; + } Predicate(Count); +#endif + // + // [&Count] means that the method can modify local variable Count. + // + m_pFreeLists ->ForEach(Predicate); + } + + return Count; +} + +// static +BOOL +ALLOC_CACHE_HANDLER::IsPageheapEnabled( + VOID +) +{ + BOOL fRet = FALSE; + BOOL fLockedHeap = FALSE; + HMODULE hModule = NULL; + HANDLE hHeap = NULL; + PROCESS_HEAP_ENTRY heapEntry = {0}; + + // + // If verifier.dll is loaded - we are running under app verifier == pageheap is enabled + // + hModule = GetModuleHandle( L"verifier.dll" ); + if ( hModule != NULL ) + { + hModule = NULL; + fRet = TRUE; + goto Finished; + } + + // + // Create a heap for calling heapwalk + // otherwise HeapWalk turns off lookasides for a useful heap + // + hHeap = ::HeapCreate( 0, 0, 0 ); + if ( hHeap == NULL ) + { + fRet = FALSE; + goto Finished; + } + + fRet = ::HeapLock( hHeap ); + if ( !fRet ) + { + goto Finished; + } + fLockedHeap = TRUE; + + // + // If HeapWalk is unsupported -> then running page heap + // + fRet = ::HeapWalk( hHeap, &heapEntry ); + if ( !fRet ) + { + if ( GetLastError() == ERROR_INVALID_FUNCTION ) + { + fRet = TRUE; + goto Finished; + } + } + + fRet = FALSE; + +Finished: + + if ( fLockedHeap ) + { + fLockedHeap = FALSE; + DBG_REQUIRE( ::HeapUnlock( hHeap ) ); + } + + if ( hHeap ) + { + DBG_REQUIRE( ::HeapDestroy( hHeap ) ); + hHeap = NULL; + } + + return fRet; +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/ahutil.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/ahutil.cpp new file mode 100644 index 0000000000..9685b233c8 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/ahutil.cpp @@ -0,0 +1,1734 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +HRESULT +SetElementProperty( + IN IAppHostElement * pElement, + IN CONST WCHAR * szPropName, + IN CONST VARIANT * varPropValue + ) +{ + HRESULT hr = NOERROR; + + CComPtr pPropElement; + + BSTR bstrPropName = SysAllocString( szPropName ); + + if( !bstrPropName ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto exit; + } + + hr = pElement->GetPropertyByName( bstrPropName, + &pPropElement ); + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = pPropElement->put_Value( *varPropValue ); + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + +exit: + + if( bstrPropName ) + { + SysFreeString( bstrPropName ); + bstrPropName = NULL; + } + + return hr; +} + +HRESULT +SetElementStringProperty( + IN IAppHostElement * pElement, + IN CONST WCHAR * szPropName, + IN CONST WCHAR * szPropValue + ) +{ + HRESULT hr; + VARIANT varPropValue; + VariantInit(&varPropValue); + + hr = VariantAssign(&varPropValue, szPropValue); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = SetElementProperty(pElement, szPropName, &varPropValue); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + VariantClear(&varPropValue); + return hr; +} + +HRESULT +GetElementStringProperty( + IN IAppHostElement * pElement, + IN CONST WCHAR * szPropName, + OUT BSTR * pbstrPropValue + ) +{ + HRESULT hr = S_OK; + BSTR bstrPropName = SysAllocString( szPropName ); + IAppHostProperty* pProperty = NULL; + + *pbstrPropValue = NULL; + + if (!bstrPropName) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto exit; + } + + hr = pElement->GetPropertyByName( bstrPropName, &pProperty ); + if (FAILED(hr)) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = pProperty->get_StringValue( pbstrPropValue ); + if (FAILED(hr)) + { + DBGERROR_HR( hr ); + goto exit; + } + +exit: + + if (pProperty) + { + pProperty->Release(); + } + + if (bstrPropName) + { + SysFreeString( bstrPropName ); + } + + return hr; +} + + +HRESULT +GetElementStringProperty( + IN IAppHostElement * pElement, + IN CONST WCHAR * szPropName, + OUT STRU * pstrPropValue + ) +{ + HRESULT hr = S_OK; + BSTR bstrPropName = SysAllocString( szPropName ); + IAppHostProperty* pProperty = NULL; + BSTR bstrPropValue = NULL; + + if (!bstrPropName) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto exit; + } + + hr = pElement->GetPropertyByName( bstrPropName, &pProperty ); + if (FAILED(hr)) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = pProperty->get_StringValue( &bstrPropValue ); + if (FAILED(hr)) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = pstrPropValue->Copy(bstrPropValue); + if (FAILED(hr)) + { + DBGERROR_HR( hr ); + goto exit; + } + +exit: + + if (pProperty) + { + pProperty->Release(); + } + + if (bstrPropValue) + { + SysFreeString( bstrPropValue ); + } + + if (bstrPropName) + { + SysFreeString( bstrPropName ); + } + + return hr; +} + +HRESULT +GetElementChildByName( + IN IAppHostElement * pElement, + IN LPCWSTR pszElementName, + OUT IAppHostElement ** ppChildElement +) +{ + BSTR bstrElementName = SysAllocString(pszElementName); + if (bstrElementName == NULL) + { + return E_OUTOFMEMORY; + } + HRESULT hr = pElement->GetElementByName(bstrElementName, + ppChildElement); + SysFreeString(bstrElementName); + return hr; +} + +HRESULT +GetElementBoolProperty( + IN IAppHostElement * pElement, + IN LPCWSTR pszPropertyName, + OUT bool * pBool +) +{ + BOOL fValue; + HRESULT hr = GetElementBoolProperty(pElement, + pszPropertyName, + &fValue); + if (SUCCEEDED(hr)) + { + *pBool = !!fValue; + } + return hr; +} + +HRESULT +GetElementBoolProperty( + IN IAppHostElement * pElement, + IN LPCWSTR pszPropertyName, + OUT BOOL * pBool +) +{ + HRESULT hr = S_OK; + BSTR bstrPropertyName = NULL; + IAppHostProperty * pProperty = NULL; + VARIANT varValue; + + VariantInit( &varValue ); + + bstrPropertyName = SysAllocString( pszPropertyName ); + if ( bstrPropertyName == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + // Now ask for the property and if it succeeds it is returned directly back. + hr = pElement->GetPropertyByName( bstrPropertyName, &pProperty ); + if ( FAILED ( hr ) ) + { + goto exit; + } + + // Now let's get the property and then extract it from the Variant. + hr = pProperty->get_Value( &varValue ); + if ( FAILED ( hr ) ) + { + goto exit; + } + + hr = VariantChangeType( &varValue, &varValue, 0, VT_BOOL ); + if ( FAILED ( hr ) ) + { + goto exit; + } + + // extract the value + *pBool = ( V_BOOL( &varValue ) == VARIANT_TRUE ); + +exit: + + VariantClear( &varValue ); + + if ( bstrPropertyName != NULL ) + { + SysFreeString( bstrPropertyName ); + bstrPropertyName = NULL; + } + + if ( pProperty != NULL ) + { + pProperty->Release(); + pProperty = NULL; + } + + return hr; + +} + +HRESULT +GetElementDWORDProperty( + IN IAppHostElement * pSitesCollectionEntry, + IN LPCWSTR pwszName, + OUT DWORD * pdwValue +) +{ + HRESULT hr = S_OK; + IAppHostProperty * pProperty = NULL; + BSTR bstrName = NULL; + VARIANT varValue; + + VariantInit( &varValue ); + + bstrName = SysAllocString( pwszName ); + if ( bstrName == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto error; + } + + hr = pSitesCollectionEntry->GetPropertyByName( bstrName, + &pProperty ); + if ( FAILED ( hr ) ) + { + goto error; + } + + hr = pProperty->get_Value( &varValue ); + if ( FAILED ( hr ) ) + { + goto error; + } + + hr = VariantChangeType( &varValue, &varValue, 0, VT_UI4 ); + if ( FAILED ( hr ) ) + { + goto error; + } + + // extract the value + *pdwValue = varValue.ulVal; + +error: + + VariantClear( &varValue ); + + if ( pProperty != NULL ) + { + pProperty->Release(); + pProperty = NULL; + } + + if ( bstrName != NULL ) + { + SysFreeString( bstrName ); + bstrName = NULL; + } + + return hr; +} + +HRESULT +GetElementINTProperty( + IN IAppHostElement * pElement, + IN LPCWSTR pszPropertyName, + OUT INT * pintValue +) +{ + HRESULT hr = S_OK; + IAppHostProperty * pProperty = NULL; + BSTR bstrName = NULL; + VARIANT varValue; + + VariantInit( &varValue ); + + bstrName = SysAllocString( pszPropertyName ); + if ( bstrName == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto error; + } + + hr = pElement->GetPropertyByName( bstrName, + &pProperty ); + if ( FAILED( hr ) ) + { + goto error; + } + + hr = pProperty->get_Value( &varValue ); + if ( FAILED( hr ) ) + { + goto error; + } + + hr = VariantChangeType( &varValue, &varValue, 0, VT_I4 ); + if ( FAILED( hr ) ) + { + goto error; + } + + // extract the value + *pintValue = varValue.intVal; + +error: + + VariantClear( &varValue ); + + if ( pProperty != NULL ) + { + pProperty->Release(); + pProperty = NULL; + } + + if ( bstrName != NULL ) + { + SysFreeString( bstrName ); + bstrName = NULL; + } + + return hr; +} + +HRESULT +GetElementLONGLONGProperty( + IN IAppHostElement * pSitesCollectionEntry, + IN LPCWSTR pwszName, + OUT LONGLONG * pllValue +) +{ + HRESULT hr = S_OK; + IAppHostProperty * pProperty = NULL; + BSTR bstrName = NULL; + VARIANT varValue; + + VariantInit( &varValue ); + + bstrName = SysAllocString( pwszName ); + if ( bstrName == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto error; + } + + hr = pSitesCollectionEntry->GetPropertyByName( bstrName, + &pProperty ); + if ( FAILED ( hr ) ) + { + goto error; + } + + hr = pProperty->get_Value( &varValue ); + if ( FAILED ( hr ) ) + { + goto error; + } + + hr = VariantChangeType( &varValue, &varValue, 0, VT_I8 ); + if ( FAILED ( hr ) ) + { + goto error; + } + + // extract the value + *pllValue = varValue.ulVal; + +error: + + VariantClear( &varValue ); + + if ( pProperty != NULL ) + { + pProperty->Release(); + pProperty = NULL; + } + + if ( bstrName != NULL ) + { + SysFreeString( bstrName ); + bstrName = NULL; + } + + return hr; +} + +HRESULT +GetElementRawTimeSpanProperty( + IN IAppHostElement * pElement, + IN LPCWSTR pszPropertyName, + OUT ULONGLONG * pulonglong +) +{ + HRESULT hr = S_OK; + BSTR bstrPropertyName = NULL; + IAppHostProperty * pProperty = NULL; + VARIANT varValue; + + VariantInit( &varValue ); + + bstrPropertyName = SysAllocString( pszPropertyName ); + if ( bstrPropertyName == NULL ) + { + hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY ); + goto Finished; + } + + // Now ask for the property and if it succeeds it is returned directly back + hr = pElement->GetPropertyByName( bstrPropertyName, &pProperty ); + if ( FAILED ( hr ) ) + { + goto Finished; + } + + // Now let's get the property and then extract it from the Variant. + hr = pProperty->get_Value( &varValue ); + if ( FAILED ( hr ) ) + { + goto Finished; + } + + hr = VariantChangeType( &varValue, &varValue, 0, VT_UI8 ); + if ( FAILED ( hr ) ) + { + goto Finished; + } + + // extract the value + *pulonglong = varValue.ullVal; + + +Finished: + + VariantClear( &varValue ); + + if ( bstrPropertyName != NULL ) + { + SysFreeString( bstrPropertyName ); + bstrPropertyName = NULL; + } + + if ( pProperty != NULL ) + { + pProperty->Release(); + pProperty = NULL; + } + + return hr; + +} // end of Config_GetRawTimeSpanProperty + +HRESULT +DeleteElementFromCollection( + IAppHostElementCollection *pCollection, + CONST WCHAR * szKeyName, + CONST WCHAR * szKeyValue, + ULONG BehaviorFlags, + BOOL * pfDeleted + ) +{ + HRESULT hr = NOERROR; + ULONG index; + + VARIANT varIndex; + VariantInit( &varIndex ); + + *pfDeleted = FALSE; + + hr = FindElementInCollection( + pCollection, + szKeyName, + szKeyValue, + BehaviorFlags, + &index + ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + if (hr == S_FALSE) + { + // + // Not found. + // + + goto exit; + } + + varIndex.vt = VT_UI4; + varIndex.ulVal = index; + + hr = pCollection->DeleteElement( varIndex ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + *pfDeleted = TRUE; + +exit: + + return hr; +} + +HRESULT +DeleteAllElementsFromCollection( + IAppHostElementCollection *pCollection, + CONST WCHAR * szKeyName, + CONST WCHAR * szKeyValue, + ULONG BehaviorFlags, + UINT * pNumDeleted + ) +{ + HRESULT hr = S_OK; + UINT numDeleted = 0; + BOOL fDeleted = TRUE; + + while (fDeleted) + { + hr = DeleteElementFromCollection( + pCollection, + szKeyName, + szKeyValue, + BehaviorFlags, + &fDeleted + ); + + if (hr == S_FALSE) + { + hr = S_OK; + break; + } + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + break; + } + + if (fDeleted) + { + numDeleted++; + } + } + + *pNumDeleted = numDeleted; + return hr; +} + +BOOL +FindCompareCaseSensitive( + CONST WCHAR * szLookupValue, + CONST WCHAR * szKeyValue + ) +{ + return !wcscmp(szLookupValue, szKeyValue); +} + +BOOL +FindCompareCaseInsensitive( + CONST WCHAR * szLookupValue, + CONST WCHAR * szKeyValue + ) +{ + return !_wcsicmp(szLookupValue, szKeyValue); +} + +typedef +BOOL +(*PFN_FIND_COMPARE_PROC)( + CONST WCHAR *szLookupValue, + CONST WCHAR *szKeyValue + ); + +HRESULT +FindElementInCollection( + IAppHostElementCollection *pCollection, + CONST WCHAR * szKeyName, + CONST WCHAR * szKeyValue, + ULONG BehaviorFlags, + OUT ULONG * pIndex + ) +{ + HRESULT hr = NOERROR; + + CComPtr pElement; + CComPtr pKeyProperty; + + VARIANT varIndex; + VariantInit( &varIndex ); + + VARIANT varKeyValue; + VariantInit( &varKeyValue ); + + DWORD count; + DWORD i; + + BSTR bstrKeyName = NULL; + PFN_FIND_COMPARE_PROC compareProc; + + compareProc = (BehaviorFlags & FIND_ELEMENT_CASE_INSENSITIVE) + ? &FindCompareCaseInsensitive + : &FindCompareCaseSensitive; + + bstrKeyName = SysAllocString( szKeyName ); + if( !bstrKeyName ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pCollection->get_Count( &count ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + for( i = 0; i < count; i++ ) + { + varIndex.vt = VT_UI4; + varIndex.ulVal = i; + + hr = pCollection->get_Item( varIndex, + &pElement ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto tryNext; + } + + hr = pElement->GetPropertyByName( bstrKeyName, + &pKeyProperty ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto tryNext; + } + + hr = pKeyProperty->get_Value( &varKeyValue ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto tryNext; + } + + if ((compareProc)(szKeyValue, varKeyValue.bstrVal)) + { + *pIndex = i; + break; + } + +tryNext: + + pElement.Release(); + pKeyProperty.Release(); + + VariantClear( &varKeyValue ); + } + + if (i >= count) + { + hr = S_FALSE; + } + +exit: + + SysFreeString( bstrKeyName ); + VariantClear( &varKeyValue ); + + return hr; +} + +HRESULT +VariantAssign( + IN OUT VARIANT * pv, + IN CONST WCHAR * sz + ) +{ + if( !pv || !sz ) + { + return E_INVALIDARG; + } + + HRESULT hr = NOERROR; + + BSTR bstr = SysAllocString( sz ); + if( !bstr ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto exit; + } + + hr = VariantClear( pv ); + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + pv->vt = VT_BSTR; + pv->bstrVal = bstr; + bstr = NULL; + +exit: + + SysFreeString( bstr ); + + return hr; +} + +HRESULT +GetLocationFromFile( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szLocationPath, + OUT IAppHostConfigLocation ** ppLocation, + OUT BOOL * pFound + ) +{ + HRESULT hr = NOERROR; + + CComPtr pLocationCollection; + CComPtr pLocation; + + BSTR bstrLocationPath = NULL; + + *ppLocation = NULL; + *pFound = FALSE; + + hr = GetLocationCollection( pAdminMgr, + szConfigPath, + &pLocationCollection ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + DWORD count; + DWORD i; + VARIANT varIndex; + VariantInit( &varIndex ); + + hr = pLocationCollection->get_Count( &count ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + for( i = 0; i < count; i++ ) + { + varIndex.vt = VT_UI4; + varIndex.ulVal = i; + + hr = pLocationCollection->get_Item( varIndex, + &pLocation ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pLocation->get_Path( &bstrLocationPath ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if( 0 == wcscmp ( szLocationPath, bstrLocationPath ) ) + { + *pFound = TRUE; + *ppLocation = pLocation.Detach(); + break; + } + + + pLocation.Release(); + + SysFreeString( bstrLocationPath ); + bstrLocationPath = NULL; + } + +exit: + + SysFreeString( bstrLocationPath ); + + return hr; +} + +HRESULT +GetSectionFromLocation( + IN IAppHostConfigLocation * pLocation, + IN CONST WCHAR * szSectionName, + OUT IAppHostElement ** ppSectionElement, + OUT BOOL * pFound + ) +{ + HRESULT hr = NOERROR; + + CComPtr pSectionElement; + + DWORD count; + DWORD i; + + VARIANT varIndex; + VariantInit( &varIndex ); + + BSTR bstrSectionName = NULL; + + *pFound = FALSE; + *ppSectionElement = NULL; + + hr = pLocation->get_Count( &count ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + for( i = 0; i < count; i++ ) + { + varIndex.vt = VT_UI4; + varIndex.ulVal = i; + + + hr = pLocation->get_Item( varIndex, + &pSectionElement ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pSectionElement->get_Name( &bstrSectionName ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if( 0 == wcscmp ( szSectionName, bstrSectionName ) ) + { + *pFound = TRUE; + *ppSectionElement = pSectionElement.Detach(); + break; + } + + pSectionElement.Release(); + + SysFreeString( bstrSectionName ); + bstrSectionName = NULL; + } + +exit: + + SysFreeString( bstrSectionName ); + + return hr; +} + + +HRESULT +GetAdminElement( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szElementName, + OUT IAppHostElement ** pElement +) +{ + HRESULT hr = S_OK; + BSTR bstrConfigPath = NULL; + BSTR bstrElementName = NULL; + + bstrConfigPath = SysAllocString(szConfigPath); + bstrElementName = SysAllocString(szElementName); + + if (bstrConfigPath == NULL || bstrElementName == NULL) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->GetAdminSection( bstrElementName, + bstrConfigPath, + pElement ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + if ( bstrElementName != NULL ) + { + SysFreeString(bstrElementName); + bstrElementName = NULL; + } + if ( bstrConfigPath != NULL ) + { + SysFreeString(bstrConfigPath); + bstrConfigPath = NULL; + } + + return hr; +} + + +HRESULT +ClearAdminElement( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szElementName + ) +{ + HRESULT hr; + CComPtr pElement; + + hr = GetAdminElement( + pAdminMgr, + szConfigPath, + szElementName, + &pElement + ); + + if (FAILED(hr)) + { + if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) + { + hr = S_OK; + } + else + { + DBGERROR_HR(hr); + } + + goto exit; + } + + hr = pElement->Clear(); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return hr; +} + + +HRESULT +ClearElementFromAllSites( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szElementName + ) +{ + HRESULT hr; + CComPtr pSitesCollection; + CComPtr pSiteElement; + CComPtr pChildCollection; + ENUM_INDEX index; + BOOL found; + + // + // Enumerate the sites, remove the specified elements. + // + + hr = GetSitesCollection( + pAdminMgr, + szConfigPath, + &pSitesCollection + ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + for (hr = FindFirstElement(pSitesCollection, &index, &pSiteElement) ; + SUCCEEDED(hr) ; + hr = FindNextElement(pSitesCollection, &index, &pSiteElement)) + { + if (hr == S_FALSE) + { + hr = S_OK; + break; + } + + hr = pSiteElement->get_ChildElements(&pChildCollection); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + if (pChildCollection) + { + hr = ClearChildElementsByName( + pChildCollection, + szElementName, + &found + ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + } + + pSiteElement.Release(); + } + +exit: + + return hr; + +} + + +HRESULT +ClearElementFromAllLocations( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szElementName + ) +{ + HRESULT hr; + CComPtr pLocationCollection; + CComPtr pLocation; + CComPtr pChildCollection; + ENUM_INDEX index; + + // + // Enum the tags, remove the specified elements. + // + + hr = GetLocationCollection( + pAdminMgr, + szConfigPath, + &pLocationCollection + ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + for (hr = FindFirstLocation(pLocationCollection, &index, &pLocation) ; + SUCCEEDED(hr) ; + hr = FindNextLocation(pLocationCollection, &index, &pLocation)) + { + if (hr == S_FALSE) + { + hr = S_OK; + break; + } + + hr = ClearLocationElements(pLocation, szElementName); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + pLocation.Release(); + } + +exit: + + return hr; + +} + +HRESULT +ClearLocationElements( + IN IAppHostConfigLocation * pLocation, + IN CONST WCHAR * szElementName + ) +{ + HRESULT hr; + CComPtr pElement; + ENUM_INDEX index; + BOOL matched; + + for (hr = FindFirstLocationElement(pLocation, &index, &pElement) ; + SUCCEEDED(hr) ; + hr = FindNextLocationElement(pLocation, &index, &pElement)) + { + if (hr == S_FALSE) + { + hr = S_OK; + break; + } + + hr = CompareElementName(pElement, szElementName, &matched); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + if (matched) + { + pElement->Clear(); + } + + pElement.Release(); + } + +exit: + + return hr; +} + +HRESULT +CompareElementName( + IN IAppHostElement * pElement, + IN CONST WCHAR * szNameToMatch, + OUT BOOL * pMatched + ) +{ + HRESULT hr; + BSTR bstrElementName = NULL; + + *pMatched = FALSE; // until proven otherwise + + hr = pElement->get_Name(&bstrElementName); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + if( 0 == wcscmp ( szNameToMatch, bstrElementName ) ) + { + *pMatched = TRUE; + } + +exit: + + SysFreeString(bstrElementName); + return hr; +} + + +HRESULT +ClearChildElementsByName( + IN IAppHostChildElementCollection * pCollection, + IN CONST WCHAR * szElementName, + OUT BOOL * pFound + ) +{ + HRESULT hr; + CComPtr pElement; + ENUM_INDEX index; + BOOL matched; + + *pFound = FALSE; + + for (hr = FindFirstChildElement(pCollection, &index, &pElement) ; + SUCCEEDED(hr) ; + hr = FindNextChildElement(pCollection, &index, &pElement)) + { + if (hr == S_FALSE) + { + hr = S_OK; + break; + } + + hr = CompareElementName(pElement, szElementName, &matched); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + if (matched) + { + hr = pElement->Clear(); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + *pFound = TRUE; + } + + pElement.Release(); + } + +exit: + + return hr; +} + + +HRESULT +GetSitesCollection( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + OUT IAppHostElementCollection ** pSitesCollection + ) +{ + HRESULT hr; + CComPtr pSitesElement; + BSTR bstrConfigPath; + BSTR bstrSitesSectionName; + + bstrConfigPath = SysAllocString(szConfigPath); + bstrSitesSectionName = SysAllocString(L"system.applicationHost/sites"); + *pSitesCollection = NULL; + + if (bstrConfigPath == NULL || bstrSitesSectionName == NULL) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + // + // Chase down the sites collection. + // + + hr = pAdminMgr->GetAdminSection( bstrSitesSectionName, + bstrConfigPath, + &pSitesElement ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pSitesElement->get_Collection(pSitesCollection); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + SysFreeString(bstrSitesSectionName); + SysFreeString(bstrConfigPath); + return hr; +} + + +HRESULT +GetLocationCollection( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + OUT IAppHostConfigLocationCollection ** pLocationCollection + ) +{ + HRESULT hr; + BSTR bstrConfigPath; + CComPtr pConfigMgr; + CComPtr pConfigFile; + + bstrConfigPath = SysAllocString(szConfigPath); + *pLocationCollection = NULL; + + if (bstrConfigPath == NULL) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->get_ConfigManager(&pConfigMgr); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pConfigMgr->GetConfigFile(bstrConfigPath, &pConfigFile); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pConfigFile->get_Locations(pLocationCollection); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + SysFreeString(bstrConfigPath); + return hr; +} + + +HRESULT +FindFirstElement( + IN IAppHostElementCollection * pCollection, + OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ) +{ + HRESULT hr; + + hr = pCollection->get_Count(&pIndex->Count); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + return hr; + } + + VariantInit(&pIndex->Index); + pIndex->Index.vt = VT_UI4; + pIndex->Index.ulVal = 0; + + return FindNextElement(pCollection, pIndex, pElement); +} + +HRESULT +FindNextElement( + IN IAppHostElementCollection * pCollection, + IN OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ) +{ + HRESULT hr; + + *pElement = NULL; + + if (pIndex->Index.ulVal >= pIndex->Count) + { + return S_FALSE; + } + + hr = pCollection->get_Item(pIndex->Index, pElement); + + if (SUCCEEDED(hr)) + { + pIndex->Index.ulVal++; + } + + return hr; +} + +HRESULT +FindFirstChildElement( + IN IAppHostChildElementCollection * pCollection, + OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ) +{ + HRESULT hr; + + hr = pCollection->get_Count(&pIndex->Count); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + return hr; + } + + VariantInit(&pIndex->Index); + pIndex->Index.vt = VT_UI4; + pIndex->Index.ulVal = 0; + + return FindNextChildElement(pCollection, pIndex, pElement); +} + +HRESULT +FindNextChildElement( + IN IAppHostChildElementCollection * pCollection, + IN OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ) +{ + HRESULT hr; + + *pElement = NULL; + + if (pIndex->Index.ulVal >= pIndex->Count) + { + return S_FALSE; + } + + hr = pCollection->get_Item(pIndex->Index, pElement); + + if (SUCCEEDED(hr)) + { + pIndex->Index.ulVal++; + } + + return hr; +} + +HRESULT +FindFirstLocation( + IN IAppHostConfigLocationCollection * pCollection, + OUT ENUM_INDEX * pIndex, + OUT IAppHostConfigLocation ** pLocation + ) +{ + HRESULT hr; + + hr = pCollection->get_Count(&pIndex->Count); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + return hr; + } + + VariantInit(&pIndex->Index); + pIndex->Index.vt = VT_UI4; + pIndex->Index.ulVal = 0; + + return FindNextLocation(pCollection, pIndex, pLocation); +} + +HRESULT +FindNextLocation( + IN IAppHostConfigLocationCollection * pCollection, + IN OUT ENUM_INDEX * pIndex, + OUT IAppHostConfigLocation ** pLocation + ) +{ + HRESULT hr; + + *pLocation = NULL; + + if (pIndex->Index.ulVal >= pIndex->Count) + { + return S_FALSE; + } + + hr = pCollection->get_Item(pIndex->Index, pLocation); + + if (SUCCEEDED(hr)) + { + pIndex->Index.ulVal++; + } + + return hr; +} + +HRESULT +FindFirstLocationElement( + IN IAppHostConfigLocation * pLocation, + OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ) +{ + HRESULT hr; + + hr = pLocation->get_Count(&pIndex->Count); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + return hr; + } + + VariantInit(&pIndex->Index); + pIndex->Index.vt = VT_UI4; + pIndex->Index.ulVal = 0; + + return FindNextLocationElement(pLocation, pIndex, pElement); +} + +HRESULT +FindNextLocationElement( + IN IAppHostConfigLocation * pLocation, + IN OUT ENUM_INDEX * pIndex, + OUT IAppHostElement ** pElement + ) +{ + HRESULT hr; + + *pElement = NULL; + + if (pIndex->Index.ulVal >= pIndex->Count) + { + return S_FALSE; + } + + hr = pLocation->get_Item(pIndex->Index, pElement); + + if (SUCCEEDED(hr)) + { + pIndex->Index.ulVal++; + } + + return hr; +} + +HRESULT +GetSharedConfigEnabled( + BOOL * pfIsSharedConfig +) +/*++ + +Routine Description: + Search the configuration for the shared configuration property. + +Arguments: + + pfIsSharedConfig - true if shared configuration is enabled + +Return Value: + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + IAppHostAdminManager *pAdminManager = NULL; + + BSTR bstrSectionName = NULL; + BSTR bstrConfigPath = NULL; + + IAppHostElement * pConfigRedirSection = NULL; + + + bstrSectionName = SysAllocString( L"configurationRedirection" ); + + if ( bstrSectionName == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + bstrConfigPath = SysAllocString( L"MACHINE/REDIRECTION" ); + if ( bstrConfigPath == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = CoCreateInstance( CLSID_AppHostAdminManager, + NULL, + CLSCTX_INPROC_SERVER, + IID_IAppHostAdminManager, + (VOID **)&pAdminManager ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminManager->GetAdminSection( bstrSectionName, + bstrConfigPath, + &pConfigRedirSection ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = GetElementBoolProperty( pConfigRedirSection, + L"enabled", + pfIsSharedConfig ); + + if ( FAILED( hr ) ) + { + DBGERROR_HR(hr); + goto exit; + } + + pConfigRedirSection->Release(); + pConfigRedirSection = NULL; + + +exit: + + // + // dump config exception to setup log file (if available) + // + + if ( pConfigRedirSection != NULL ) + { + pConfigRedirSection->Release(); + } + + if ( pAdminManager != NULL ) + { + pAdminManager->Release(); + } + + if ( bstrConfigPath != NULL ) + { + SysFreeString( bstrConfigPath ); + } + + if ( bstrSectionName != NULL ) + { + SysFreeString( bstrSectionName ); + } + + return hr; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/base64.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/base64.cxx new file mode 100644 index 0000000000..26e601fac4 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/base64.cxx @@ -0,0 +1,482 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +DWORD +Base64Encode( + __in_bcount(cbDecodedBufferSize) VOID * pDecodedBuffer, + IN DWORD cbDecodedBufferSize, + __out_ecount_opt(cchEncodedStringSize) PWSTR pszEncodedString, + IN DWORD cchEncodedStringSize, + __out_opt DWORD * pcchEncoded + ) +/*++ + +Routine Description: + + Decode a base64-encoded string. + +Arguments: + + pDecodedBuffer (IN) - buffer to encode. + cbDecodedBufferSize (IN) - size of buffer to encode. + cchEncodedStringSize (IN) - size of the buffer for the encoded string. + pszEncodedString (OUT) = the encoded string. + pcchEncoded (OUT) - size in characters of the encoded string. + +Return Values: + + 0 - success. + E_OUTOFMEMORY + +--*/ +{ + static WCHAR rgchEncodeTable[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' + }; + + DWORD ib; + DWORD ich; + DWORD cchEncoded; + BYTE b0, b1, b2; + BYTE * pbDecodedBuffer = (BYTE *) pDecodedBuffer; + + // Calculate encoded string size. + cchEncoded = 1 + (cbDecodedBufferSize + 2) / 3 * 4; + + if (NULL != pcchEncoded) { + *pcchEncoded = cchEncoded; + } + + if (cchEncodedStringSize == 0 && pszEncodedString == NULL) { + return ERROR_SUCCESS; + } + + if (cchEncodedStringSize < cchEncoded) { + // Given buffer is too small to hold encoded string. + return ERROR_INSUFFICIENT_BUFFER; + } + + // Encode data byte triplets into four-byte clusters. + ib = ich = 0; + while (ib < cbDecodedBufferSize) { + b0 = pbDecodedBuffer[ib++]; + b1 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0; + b2 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0; + + // + // The checks below for buffer overflow seems redundant to me. + // But it's the only way I can find to keep OACR quiet so it + // will have to do. + // + + pszEncodedString[ich++] = rgchEncodeTable[b0 >> 2]; + if ( ich >= cchEncodedStringSize ) + { + DBG_ASSERT( FALSE ); + return ERROR_BUFFER_OVERFLOW; + } + + pszEncodedString[ich++] = rgchEncodeTable[((b0 << 4) & 0x30) | ((b1 >> 4) & 0x0f)]; + if ( ich >= cchEncodedStringSize ) + { + DBG_ASSERT( FALSE ); + return ERROR_BUFFER_OVERFLOW; + } + + pszEncodedString[ich++] = rgchEncodeTable[((b1 << 2) & 0x3c) | ((b2 >> 6) & 0x03)]; + if ( ich >= cchEncodedStringSize ) + { + DBG_ASSERT( FALSE ); + return ERROR_BUFFER_OVERFLOW; + } + + pszEncodedString[ich++] = rgchEncodeTable[b2 & 0x3f]; + if ( ich >= cchEncodedStringSize ) + { + DBG_ASSERT( FALSE ); + return ERROR_BUFFER_OVERFLOW; + } + } + + // Pad the last cluster as necessary to indicate the number of data bytes + // it represents. + switch (cbDecodedBufferSize % 3) { + case 0: + break; + case 1: + pszEncodedString[ich - 2] = '='; + __fallthrough; + case 2: + pszEncodedString[ich - 1] = '='; + break; + } + + // Null-terminate the encoded string. + pszEncodedString[ich++] = '\0'; + + DBG_ASSERT(ich == cchEncoded); + + return ERROR_SUCCESS; +} + + +DWORD +Base64Decode( + __in PCWSTR pszEncodedString, + __out_opt VOID * pDecodeBuffer, + __in DWORD cbDecodeBufferSize, + __out_opt DWORD * pcbDecoded + ) +/*++ + +Routine Description: + + Decode a base64-encoded string. + +Arguments: + + pszEncodedString (IN) - base64-encoded string to decode. + cbDecodeBufferSize (IN) - size in bytes of the decode buffer. + pbDecodeBuffer (OUT) - holds the decoded data. + pcbDecoded (OUT) - number of data bytes in the decoded data (if success or + STATUS_BUFFER_TOO_SMALL). + +Return Values: + + 0 - success. + E_OUTOFMEMORY + E_INVALIDARG + +--*/ +{ +#define NA (255) +#define DECODE(x) (((ULONG)(x) < sizeof(rgbDecodeTable)) ? rgbDecodeTable[x] : NA) + + static BYTE rgbDecodeTable[128] = { + NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 0-15 + NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 16-31 + NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 62, NA, NA, NA, 63, // 32-47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NA, NA, NA, 0, NA, NA, // 48-63 + NA, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NA, NA, NA, NA, NA, // 80-95 + NA, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111 + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, NA, NA, NA, NA, NA, // 112-127 + }; + + DWORD cbDecoded; + DWORD cchEncodedSize; + DWORD ich; + DWORD ib; + BYTE b0, b1, b2, b3; + BYTE * pbDecodeBuffer = (BYTE *) pDecodeBuffer; + + cchEncodedSize = (DWORD)wcslen(pszEncodedString); + if (NULL != pcbDecoded) { + *pcbDecoded = 0; + } + + if ((0 == cchEncodedSize) || (0 != (cchEncodedSize % 4))) { + // Input string is not sized correctly to be base64. + return ERROR_INVALID_PARAMETER; + } + + // Calculate decoded buffer size. + cbDecoded = (cchEncodedSize + 3) / 4 * 3; + if (pszEncodedString[cchEncodedSize-1] == '=') { + if (pszEncodedString[cchEncodedSize-2] == '=') { + // Only one data byte is encoded in the last cluster. + cbDecoded -= 2; + } + else { + // Only two data bytes are encoded in the last cluster. + cbDecoded -= 1; + } + } + + if (NULL != pcbDecoded) { + *pcbDecoded = cbDecoded; + } + + if (cbDecodeBufferSize == 0 && pDecodeBuffer == NULL) { + return ERROR_SUCCESS; + } + + if (cbDecoded > cbDecodeBufferSize) { + // Supplied buffer is too small. + return ERROR_INSUFFICIENT_BUFFER; + } + + // Decode each four-byte cluster into the corresponding three data bytes. + ich = ib = 0; + while (ich < cchEncodedSize) { + b0 = DECODE(pszEncodedString[ich]); ich++; + b1 = DECODE(pszEncodedString[ich]); ich++; + b2 = DECODE(pszEncodedString[ich]); ich++; + b3 = DECODE(pszEncodedString[ich]); ich++; + + if ((NA == b0) || (NA == b1) || (NA == b2) || (NA == b3)) { + // Contents of input string are not base64. + return ERROR_INVALID_PARAMETER; + } + + pbDecodeBuffer[ib++] = (b0 << 2) | (b1 >> 4); + + if (ib < cbDecoded) { + pbDecodeBuffer[ib++] = (b1 << 4) | (b2 >> 2); + + if (ib < cbDecoded) { + pbDecodeBuffer[ib++] = (b2 << 6) | b3; + } + } + } + + DBG_ASSERT(ib == cbDecoded); + + return ERROR_SUCCESS; +} + + +DWORD +Base64Encode( + __in_bcount(cbDecodedBufferSize) VOID * pDecodedBuffer, + IN DWORD cbDecodedBufferSize, + __out_ecount_opt(cchEncodedStringSize) PSTR pszEncodedString, + IN DWORD cchEncodedStringSize, + __out_opt DWORD * pcchEncoded + ) +/*++ + +Routine Description: + + Decode a base64-encoded string. + +Arguments: + + pDecodedBuffer (IN) - buffer to encode. + cbDecodedBufferSize (IN) - size of buffer to encode. + cchEncodedStringSize (IN) - size of the buffer for the encoded string. + pszEncodedString (OUT) = the encoded string. + pcchEncoded (OUT) - size in characters of the encoded string. + +Return Values: + + 0 - success. + E_OUTOFMEMORY + +--*/ +{ + static CHAR rgchEncodeTable[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' + }; + + DWORD ib; + DWORD ich; + DWORD cchEncoded; + BYTE b0, b1, b2; + BYTE * pbDecodedBuffer = (BYTE *) pDecodedBuffer; + + // Calculate encoded string size. + cchEncoded = 1 + (cbDecodedBufferSize + 2) / 3 * 4; + + if (NULL != pcchEncoded) { + *pcchEncoded = cchEncoded; + } + + if (cchEncodedStringSize == 0 && pszEncodedString == NULL) { + return ERROR_SUCCESS; + } + + if (cchEncodedStringSize < cchEncoded) { + // Given buffer is too small to hold encoded string. + return ERROR_INSUFFICIENT_BUFFER; + } + + // Encode data byte triplets into four-byte clusters. + ib = ich = 0; + while (ib < cbDecodedBufferSize) { + b0 = pbDecodedBuffer[ib++]; + b1 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0; + b2 = (ib < cbDecodedBufferSize) ? pbDecodedBuffer[ib++] : 0; + + // + // The checks below for buffer overflow seems redundant to me. + // But it's the only way I can find to keep OACR quiet so it + // will have to do. + // + + pszEncodedString[ich++] = rgchEncodeTable[b0 >> 2]; + if ( ich >= cchEncodedStringSize ) + { + DBG_ASSERT( FALSE ); + return ERROR_BUFFER_OVERFLOW; + } + + pszEncodedString[ich++] = rgchEncodeTable[((b0 << 4) & 0x30) | ((b1 >> 4) & 0x0f)]; + if ( ich >= cchEncodedStringSize ) + { + DBG_ASSERT( FALSE ); + return ERROR_BUFFER_OVERFLOW; + } + + pszEncodedString[ich++] = rgchEncodeTable[((b1 << 2) & 0x3c) | ((b2 >> 6) & 0x03)]; + if ( ich >= cchEncodedStringSize ) + { + DBG_ASSERT( FALSE ); + return ERROR_BUFFER_OVERFLOW; + } + + pszEncodedString[ich++] = rgchEncodeTable[b2 & 0x3f]; + if ( ich >= cchEncodedStringSize ) + { + DBG_ASSERT( FALSE ); + return ERROR_BUFFER_OVERFLOW; + } + } + + // Pad the last cluster as necessary to indicate the number of data bytes + // it represents. + switch (cbDecodedBufferSize % 3) { + case 0: + break; + case 1: + pszEncodedString[ich - 2] = '='; + __fallthrough; + case 2: + pszEncodedString[ich - 1] = '='; + break; + } + + // Null-terminate the encoded string. + pszEncodedString[ich++] = '\0'; + + DBG_ASSERT(ich == cchEncoded); + + return ERROR_SUCCESS; +} + + +DWORD +Base64Decode( + __in PCSTR pszEncodedString, + __out_opt VOID * pDecodeBuffer, + __in DWORD cbDecodeBufferSize, + __out_opt DWORD * pcbDecoded + ) +/*++ + +Routine Description: + + Decode a base64-encoded string. + +Arguments: + + pszEncodedString (IN) - base64-encoded string to decode. + cbDecodeBufferSize (IN) - size in bytes of the decode buffer. + pbDecodeBuffer (OUT) - holds the decoded data. + pcbDecoded (OUT) - number of data bytes in the decoded data (if success or + STATUS_BUFFER_TOO_SMALL). + +Return Values: + + 0 - success. + E_OUTOFMEMORY + E_INVALIDARG + +--*/ +{ +#define NA (255) +#define DECODE(x) (((ULONG)(x) < sizeof(rgbDecodeTable)) ? rgbDecodeTable[x] : NA) + + static BYTE rgbDecodeTable[128] = { + NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 0-15 + NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, // 16-31 + NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 62, NA, NA, NA, 63, // 32-47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NA, NA, NA, 0, NA, NA, // 48-63 + NA, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NA, NA, NA, NA, NA, // 80-95 + NA, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111 + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, NA, NA, NA, NA, NA, // 112-127 + }; + + DWORD cbDecoded; + DWORD cchEncodedSize; + DWORD ich; + DWORD ib; + BYTE b0, b1, b2, b3; + BYTE * pbDecodeBuffer = (BYTE *) pDecodeBuffer; + + cchEncodedSize = (DWORD)strlen(pszEncodedString); + if (NULL != pcbDecoded) { + *pcbDecoded = 0; + } + + if ((0 == cchEncodedSize) || (0 != (cchEncodedSize % 4))) { + // Input string is not sized correctly to be base64. + return ERROR_INVALID_PARAMETER; + } + + // Calculate decoded buffer size. + cbDecoded = (cchEncodedSize + 3) / 4 * 3; + if (pszEncodedString[cchEncodedSize-1] == '=') { + if (pszEncodedString[cchEncodedSize-2] == '=') { + // Only one data byte is encoded in the last cluster. + cbDecoded -= 2; + } + else { + // Only two data bytes are encoded in the last cluster. + cbDecoded -= 1; + } + } + + if (NULL != pcbDecoded) { + *pcbDecoded = cbDecoded; + } + + if (cbDecodeBufferSize == 0 && pDecodeBuffer == NULL) { + return ERROR_SUCCESS; + } + + if (cbDecoded > cbDecodeBufferSize) { + // Supplied buffer is too small. + return ERROR_INSUFFICIENT_BUFFER; + } + + // Decode each four-byte cluster into the corresponding three data bytes. + ich = ib = 0; + while (ich < cchEncodedSize) { + b0 = DECODE(pszEncodedString[ich]); ich++; + b1 = DECODE(pszEncodedString[ich]); ich++; + b2 = DECODE(pszEncodedString[ich]); ich++; + b3 = DECODE(pszEncodedString[ich]); ich++; + + if ((NA == b0) || (NA == b1) || (NA == b2) || (NA == b3)) { + // Contents of input string are not base64. + return ERROR_INVALID_PARAMETER; + } + + pbDecodeBuffer[ib++] = (b0 << 2) | (b1 >> 4); + + if (ib < cbDecoded) { + pbDecodeBuffer[ib++] = (b1 << 4) | (b2 >> 2); + + if (ib < cbDecoded) { + pbDecodeBuffer[ib++] = (b2 << 6) | b3; + } + } + } + + DBG_ASSERT(ib == cbDecoded); + + return ERROR_SUCCESS; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/datetime.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/datetime.cxx new file mode 100644 index 0000000000..a856b997f1 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/datetime.cxx @@ -0,0 +1,247 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +static const CHAR* s_rgchMonths[] = { + "Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", + "Sep", "Oct", "Nov", "Dec" +}; + +// Custom hash table for make_month() for mapping "Apr" to 4 +static const CHAR MonthIndexTable[64] = { + -1,'A', 2, 12, -1, -1, -1, 8, // A to G + -1, -1, -1, -1, 7, -1,'N', -1, // F to O + 9, -1,'R', -1, 10, -1, 11, -1, // P to W + -1, 5, -1, -1, -1, -1, -1, -1, // X to Z + -1,'A', 2, 12, -1, -1, -1, 8, // a to g + -1, -1, -1, -1, 7, -1,'N', -1, // f to o + 9, -1,'R', -1, 10, -1, 11, -1, // p to w + -1, 5, -1, -1, -1, -1, -1, -1 // x to z +}; + +static const BYTE TensDigit[10] = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90 }; + +WORD +iis_2atoi( + __in_ecount(2) PCHAR s + ) +/*++ + + Converts a 2 character string to integer + + Arguments: + s String to convert + + Returns: + numeric equivalent, 0 on failure. +--*/ +{ + + DWORD tens = s[0] - '0'; + DWORD ones = s[1] - '0'; + + if ( (tens <= 9) && (ones <= 9) ) { + return((WORD)(TensDigit[tens] + ones)); + } + return(0); +} + +WORD +make_month( + __in_ecount(3) PCHAR s + ) +{ + UCHAR monthIndex; + UCHAR c; + LPCSTR monthString; + + // + // use the third character as the index + // + + c = (s[2] - 0x40) & 0x3F; + + monthIndex = MonthIndexTable[c]; + + if ( monthIndex < 13 ) { + goto verify; + } + + // + // ok, we need to look at the second character + // + + if ( monthIndex == 'N' ) { + + // + // we got an N which we need to resolve further + // + + // + // if s[1] is 'u' then Jun, if 'a' then Jan + // + + if ( MonthIndexTable[(s[1]-0x40) & 0x3f] == 'A' ) { + monthIndex = 1; + } else { + monthIndex = 6; + } + + } else if ( monthIndex == 'R' ) { + + // + // if s[1] is 'a' then March, if 'p' then April + // + + if ( MonthIndexTable[(s[1]-0x40) & 0x3f] == 'A' ) { + monthIndex = 3; + } else { + monthIndex = 4; + } + } else { + goto error_exit; + } + +verify: + + monthString = s_rgchMonths[monthIndex-1]; + + if ( (s[0] == monthString[0]) && + (s[1] == monthString[1]) && + (s[2] == monthString[2]) ) { + + return(monthIndex); + + } else if ( (toupper(s[0]) == monthString[0]) && + (tolower(s[1]) == monthString[1]) && + (tolower(s[2]) == monthString[2]) ) { + + return monthIndex; + } + +error_exit: + return(0); + +} // make_month + +BOOL +StringTimeToFileTime( + IN const CHAR * pszTime, + OUT ULONGLONG * pulTime + ) +/*++ + + Converts a string representation of a GMT time (three different + varieties) to an NT representation of a file time. + + We handle the following variations: + + Sun, 06 Nov 1994 08:49:37 GMT (RFC 822 updated by RFC 1123) + Sunday, 06-Nov-94 08:49:37 GMT (RFC 850) + Sun Nov 6 08:49:37 1994 (ANSI C's asctime() format + + Arguments: + pszTime String representation of time field + pliTime large integer containing the time in NT format. + + Returns: + TRUE on success and FALSE on failure. + + History: + + Johnl 24-Jan-1995 Modified from WWW library + +--*/ +{ + + CHAR * s; + SYSTEMTIME st; + + if (pszTime == NULL) { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + st.wMilliseconds = 0; + + if ((s = (CHAR*) strchr(pszTime, ','))) { + + DWORD len; + + // + // Thursday, 10-Jun-93 01:29:59 GMT + // or: Thu, 10 Jan 1993 01:29:59 GMT */ + // + + s++; + + while (*s && *s==' ') s++; + len = (DWORD)strlen(s); + + if (len < 18) { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if ( *(s+2) == '-' ) { /* First format */ + + st.wDay = (WORD) atoi(s); + st.wMonth = (WORD) make_month(s+3); + st.wYear = (WORD) atoi(s+7); + st.wHour = (WORD) atoi(s+10); + st.wMinute = (WORD) atoi(s+13); + st.wSecond = (WORD) atoi(s+16); + + } else { /* Second format */ + + if (len < 20) { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + st.wDay = iis_2atoi(s); + st.wMonth = make_month(s+3); + st.wYear = iis_2atoi(s+7) * 100 + iis_2atoi(s+9); + st.wHour = iis_2atoi(s+12); + st.wMinute = iis_2atoi(s+15); + st.wSecond = iis_2atoi(s+18); + + } + } else { /* Try the other format: Wed Jun 9 01:29:59 1993 GMT */ + + s = (CHAR *) pszTime; + while (*s && *s==' ') s++; + + if ((int)strlen(s) < 24) { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + st.wDay = (WORD) atoi(s+8); + st.wMonth = (WORD) make_month(s+4); + st.wYear = (WORD) atoi(s+20); + st.wHour = (WORD) atoi(s+11); + st.wMinute = (WORD) atoi(s+14); + st.wSecond = (WORD) atoi(s+17); + } + + // + // Adjust for dates with only two digits + // + + if ( st.wYear < 1000 ) { + if ( st.wYear < 50 ) { + st.wYear += 2000; + } else { + st.wYear += 1900; + } + } + + if (!SystemTimeToFileTime(&st, (FILETIME *)pulTime)) { + return FALSE; + } + return(TRUE); +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/multisz.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/multisz.cxx new file mode 100644 index 0000000000..26eacdb244 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/multisz.cxx @@ -0,0 +1,480 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + + +//#include +#include +//# include + +#include + +// +// Private Definitions +// + +#define MAXULONG 4294967295 +#define ISWHITE( ch ) ((ch) == L' ' || (ch) == L'\t' || (ch) == L'\r') + +// +// When appending data, this is the extra amount we request to avoid +// reallocations +// +#define STR_SLOP 128 + + +DWORD +MULTISZ::CalcLength( const WCHAR * str, + LPDWORD pcStrings ) +{ + DWORD count = 0; + DWORD total = 1; + DWORD len; + + while( *str ) { + len = (DWORD)(::wcslen( str ) + 1); + total += len; + str += len; + count++; + } + + if( pcStrings != NULL ) { + *pcStrings = count; + } + + return total; + +} // MULTISZ::CalcLength + + +BOOL +MULTISZ::FindString( const WCHAR * str ) +{ + + WCHAR * multisz; + + // + // Sanity check. + // + + DBG_ASSERT( QueryStr() != NULL ); + DBG_ASSERT( str != NULL ); + DBG_ASSERT( *str != '\0' ); + + // + // Scan it. + // + + multisz = QueryStr(); + + while( *multisz != '\0' ) { + + if( !::wcscmp( multisz, str ) ) { + + return TRUE; + + } + + multisz += ::wcslen( multisz ) + 1; + + } + + return FALSE; + +} // MULTISZ::FindString + + +BOOL +MULTISZ::FindStringNoCase( const WCHAR * str ) +{ + + WCHAR * multisz; + + // + // Sanity check. + // + + DBG_ASSERT( QueryStr() != NULL ); + DBG_ASSERT( str != NULL ); + DBG_ASSERT( *str != '\0' ); + + // + // Scan it. + // + + multisz = QueryStr(); + + while( *multisz != '\0' ) { + + if( !_wcsicmp( multisz, str ) ) { + + return TRUE; + + } + + multisz += wcslen( multisz ) + 1; + + } + + return FALSE; + +} // MULTISZ::FindStringNoCase + + +VOID +MULTISZ::AuxInit( const WCHAR * pInit ) +{ + BOOL fRet; + + if ( pInit ) + { + DWORD cStrings; + int cbCopy = CalcLength( pInit, &cStrings ) * sizeof(WCHAR); + fRet = Resize( cbCopy ); + + if ( fRet ) { + CopyMemory( QueryPtr(), pInit, cbCopy ); + m_cchLen = (cbCopy)/sizeof(WCHAR); + m_cStrings = cStrings; + } else { +// BUFFER::SetValid( FALSE); + } + + } else { + + Reset(); + + } + +} // MULTISZ::AuxInit() + + +/******************************************************************* + + NAME: MULTISZ::AuxAppend + + SYNOPSIS: Appends the string onto the multisz. + + ENTRY: Object to append +********************************************************************/ + +BOOL MULTISZ::AuxAppend( const WCHAR * pStr, UINT cbStr, BOOL fAddSlop ) +{ + DBG_ASSERT( pStr != NULL ); + + UINT cbThis = QueryCB(); + + DBG_ASSERT( cbThis >= 2 ); + + if( cbThis == 4 ) { + + // + // It's empty, so start at the beginning. + // + + cbThis = 0; + + } else { + + // + // It's not empty, so back up over the final terminating NULL. + // + + cbThis -= sizeof(WCHAR); + + } + + // + // Only resize when we have to. When we do resize, we tack on + // some extra space to avoid extra reallocations. + // + // Note: QuerySize returns the requested size of the string buffer, + // *not* the strlen of the buffer + // + + //AcIncrement( CacMultiszAppend); + + // + // Check for the arithmetic overflow + // + // ( 2 * sizeof( WCHAR ) ) is for the double terminator + // + ULONGLONG cb64Required = (ULONGLONG)cbThis + cbStr + 2 * sizeof(WCHAR); + if ( cb64Required > MAXULONG ) + { + SetLastError( ERROR_ARITHMETIC_OVERFLOW ); + return FALSE; + } + if ( QuerySize() < (DWORD) cb64Required ) + { + ULONGLONG cb64AllocSize = cb64Required + (fAddSlop ? STR_SLOP : 0 ); + // + // Check for the arithmetic overflow + // + if ( cb64AllocSize > MAXULONG ) + { + SetLastError( ERROR_ARITHMETIC_OVERFLOW ); + return FALSE; + } + if ( !Resize( (DWORD) cb64AllocSize ) ) + return FALSE; + } + + // copy the exact string and tack on the double terminator + memcpy( (BYTE *) QueryPtr() + cbThis, + pStr, + cbStr); + *(WCHAR *)((BYTE *)QueryPtr() + cbThis + cbStr) = L'\0'; + *(WCHAR *)((BYTE *)QueryPtr() + cbThis + cbStr + sizeof(WCHAR) ) = L'\0'; + + m_cchLen = CalcLength( (const WCHAR *)QueryPtr(), &m_cStrings ); + return TRUE; + +} // MULTISZ::AuxAppend() + + +#if 0 + +BOOL +MULTISZ::CopyToBuffer( WCHAR * lpszBuffer, LPDWORD lpcch) const +/*++ + Description: + Copies the string into the WCHAR buffer passed in if the buffer + is sufficient to hold the translated string. + If the buffer is small, the function returns small and sets *lpcch + to contain the required number of characters. + + Arguments: + lpszBuffer pointer to WCHAR buffer which on return contains + the UNICODE version of string on success. + lpcch pointer to DWORD containing the length of the buffer. + If *lpcch == 0 then the function returns TRUE with + the count of characters required stored in *lpcch. + Also in this case lpszBuffer is not affected. + Returns: + TRUE on success. + FALSE on failure. Use GetLastError() for further details. + + History: + MuraliK 11-30-94 +--*/ +{ + BOOL fReturn = TRUE; + + if ( lpcch == NULL) { + SetLastError( ERROR_INVALID_PARAMETER); + return ( FALSE); + } + + if ( *lpcch == 0) { + + // + // Inquiring the size of buffer alone + // + *lpcch = QueryCCH() + 1; // add one character for terminating null + } else { + + // + // Copy after conversion from ANSI to Unicode + // + int iRet; + iRet = MultiByteToWideChar( CP_ACP, + MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, + QueryStrA(), QueryCCH() + 1, + lpszBuffer, (int )*lpcch); + + if ( iRet == 0 || iRet != (int ) *lpcch) { + + // + // Error in conversion. + // + fReturn = FALSE; + } + } + + return ( fReturn); +} // MULTISZ::CopyToBuffer() +#endif + +BOOL +MULTISZ::CopyToBuffer( __out_ecount_opt(*lpcch) WCHAR * lpszBuffer, LPDWORD lpcch) const +/*++ + Description: + Copies the string into the WCHAR buffer passed in if the buffer + is sufficient to hold the translated string. + If the buffer is small, the function returns small and sets *lpcch + to contain the required number of characters. + + Arguments: + lpszBuffer pointer to WCHAR buffer which on return contains + the string on success. + lpcch pointer to DWORD containing the length of the buffer. + If *lpcch == 0 then the function returns TRUE with + the count of characters required stored in lpcch. + Also in this case lpszBuffer is not affected. + Returns: + TRUE on success. + FALSE on failure. Use GetLastError() for further details. + + History: + MuraliK 20-Nov-1996 +--*/ +{ + BOOL fReturn = TRUE; + + if ( lpcch == NULL) { + SetLastError( ERROR_INVALID_PARAMETER); + return ( FALSE); + } + + register DWORD cch = QueryCCH(); + + if ( *lpcch >= cch) { + + DBG_ASSERT( lpszBuffer); + memcpy( lpszBuffer, QueryStr(), cch * sizeof(WCHAR)); + } else { + DBG_ASSERT( *lpcch < cch); + SetLastError( ERROR_INSUFFICIENT_BUFFER); + fReturn = FALSE; + } + + *lpcch = cch; + + return ( fReturn); +} // MULTISZ::CopyToBuffer() + +BOOL +MULTISZ::Equals( + MULTISZ* pmszRhs +) +// +// Compares this to pmszRhs, returns TRUE if equal +// +{ + DBG_ASSERT( NULL != pmszRhs ); + + PCWSTR pszLhs = First( ); + PCWSTR pszRhs = pmszRhs->First( ); + + if( m_cStrings != pmszRhs->m_cStrings ) + { + return FALSE; + } + + while( NULL != pszLhs ) + { + DBG_ASSERT( NULL != pszRhs ); + + if( 0 != wcscmp( pszLhs, pszRhs ) ) + { + return FALSE; + } + + pszLhs = Next( pszLhs ); + pszRhs = pmszRhs->Next( pszRhs ); + } + + return TRUE; +} + +HRESULT +SplitCommaDelimitedString( + PCWSTR pszList, + BOOL fTrimEntries, + BOOL fRemoveEmptyEntries, + MULTISZ * pmszList +) +/*++ + +Routine Description: + + Split comma delimited string into a multisz. Additional leading empty + entries after the first are discarded. + +Arguments: + + pszList - List to split up + fTrimEntries - Whether each entry should be trimmed before added to multisz + fRemoveEmptyEntries - Whether empty entires should be discarded + pmszList - Filled with MULTISZ list + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + + if ( pszList == NULL || + pmszList == NULL ) + { + DBG_ASSERT( FALSE ); + hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + goto Finished; + } + + pmszList->Reset(); + + /* + pszCurrent: start of the current entry which may be the comma that + precedes the next entry if the entry is empty + + pszNext: the comma that precedes the next entry. If + pszCurrent == pszNext, then the entry is empty + + pszEnd: just past the end of the current entry + */ + + for ( PCWSTR pszCurrent = pszList, + pszNext = wcschr( pszCurrent, L',' ) + ; + ; + pszCurrent = pszNext + 1, + pszNext = wcschr( pszCurrent, L',' ) ) + { + PCWSTR pszEnd = NULL; + + if ( pszNext != NULL ) + { + pszEnd = pszNext; + } + else + { + pszEnd = pszCurrent + wcslen( pszCurrent ); + } + + if ( fTrimEntries ) + { + while ( pszCurrent < pszEnd && ISWHITE( pszCurrent[ 0 ] ) ) + { + pszCurrent++; + } + + while ( pszEnd > pszCurrent && ISWHITE( pszEnd[ -1 ] ) ) + { + pszEnd--; + } + } + + if ( pszCurrent != pszEnd || !fRemoveEmptyEntries ) + { + if ( !pmszList->Append( pszCurrent, (DWORD) ( pszEnd - pszCurrent ) ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Finished; + } + } + + if ( pszNext == NULL ) + { + break; + } + } + +Finished: + + return hr; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/multisza.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/multisza.cxx new file mode 100644 index 0000000000..e6972534bb --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/multisza.cxx @@ -0,0 +1,414 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + + +//#include +#include +//# include + +#include + +// +// Private Definitions +// + +#define MAXULONG 4294967295 +#define ISWHITE( ch ) ((ch) == L' ' || (ch) == L'\t' || (ch) == L'\r') + +// +// When appending data, this is the extra amount we request to avoid +// reallocations +// +#define STR_SLOP 128 + + +DWORD +MULTISZA::CalcLength( const CHAR * str, + LPDWORD pcStrings ) +{ + DWORD count = 0; + DWORD total = 1; + DWORD len; + + while( *str ) { + len = (DWORD)(::strlen( str ) + 1); + total += len; + str += len; + count++; + } + + if( pcStrings != NULL ) { + *pcStrings = count; + } + + return total; + +} // MULTISZA::CalcLength + + +BOOL +MULTISZA::FindString( const CHAR * str ) +{ + + CHAR * multisz; + + // + // Sanity check. + // + + DBG_ASSERT( QueryStr() != NULL ); + DBG_ASSERT( str != NULL ); + DBG_ASSERT( *str != '\0' ); + + // + // Scan it. + // + + multisz = QueryStr(); + + while( *multisz != '\0' ) { + + if( !::strcmp( multisz, str ) ) { + + return TRUE; + + } + + multisz += ::strlen( multisz ) + 1; + + } + + return FALSE; + +} // MULTISZA::FindString + + +BOOL +MULTISZA::FindStringNoCase( const CHAR * str ) +{ + + CHAR * multisz; + + // + // Sanity check. + // + + DBG_ASSERT( QueryStr() != NULL ); + DBG_ASSERT( str != NULL ); + DBG_ASSERT( *str != '\0' ); + + // + // Scan it. + // + + multisz = QueryStr(); + + while( *multisz != '\0' ) { + + if( !_stricmp( multisz, str ) ) { + + return TRUE; + + } + + multisz += strlen( multisz ) + 1; + + } + + return FALSE; + +} // MULTISZA::FindStringNoCase + + +VOID +MULTISZA::AuxInit( const CHAR * pInit ) +{ + BOOL fRet; + + if ( pInit ) + { + DWORD cStrings; + int cbCopy = CalcLength( pInit, &cStrings ) * sizeof(CHAR); + fRet = Resize( cbCopy ); + + if ( fRet ) { + CopyMemory( QueryPtr(), pInit, cbCopy ); + m_cchLen = (cbCopy)/sizeof(CHAR); + m_cStrings = cStrings; + } else { +// BUFFER::SetValid( FALSE); + } + + } else { + + Reset(); + + } + +} // MULTISZA::AuxInit() + + +/******************************************************************* + + NAME: MULTISZA::AuxAppend + + SYNOPSIS: Appends the string onto the MULTISZA. + + ENTRY: Object to append +********************************************************************/ + +BOOL MULTISZA::AuxAppend( const CHAR * pStr, UINT cbStr, BOOL fAddSlop ) +{ + DBG_ASSERT( pStr != NULL ); + + UINT cbThis = QueryCB(); + + if( cbThis == 2 ) { + + // + // It's empty, so start at the beginning. + // + + cbThis = 0; + + } else { + + // + // It's not empty, so back up over the final terminating NULL. + // + + cbThis -= sizeof(CHAR); + + } + + // + // Only resize when we have to. When we do resize, we tack on + // some extra space to avoid extra reallocations. + // + // Note: QuerySize returns the requested size of the string buffer, + // *not* the strlen of the buffer + // + + //AcIncrement( CacMultiszAppend); + + // + // Check for the arithmetic overflow + // + // ( 2 * sizeof( CHAR ) ) is for the double terminator + // + ULONGLONG cb64Required = (ULONGLONG)cbThis + cbStr + 2 * sizeof(CHAR); + if ( cb64Required > MAXULONG ) + { + SetLastError( ERROR_ARITHMETIC_OVERFLOW ); + return FALSE; + } + if ( QuerySize() < (DWORD) cb64Required ) + { + ULONGLONG cb64AllocSize = cb64Required + (fAddSlop ? STR_SLOP : 0 ); + // + // Check for the arithmetic overflow + // + if ( cb64AllocSize > MAXULONG ) + { + SetLastError( ERROR_ARITHMETIC_OVERFLOW ); + return FALSE; + } + if ( !Resize( (DWORD) cb64AllocSize ) ) + return FALSE; + } + + // copy the exact string and tack on the double terminator + memcpy( (BYTE *) QueryPtr() + cbThis, + pStr, + cbStr); + *(CHAR *)((BYTE *)QueryPtr() + cbThis + cbStr) = L'\0'; + *(CHAR *)((BYTE *)QueryPtr() + cbThis + cbStr + sizeof(CHAR) ) = L'\0'; + + m_cchLen = CalcLength( (const CHAR *)QueryPtr(), &m_cStrings ); + return TRUE; + +} // MULTISZA::AuxAppend() + +BOOL +MULTISZA::CopyToBuffer( __out_ecount_opt(*lpcch) CHAR * lpszBuffer, LPDWORD lpcch) const +/*++ + Description: + Copies the string into the CHAR buffer passed in if the buffer + is sufficient to hold the translated string. + If the buffer is small, the function returns small and sets *lpcch + to contain the required number of characters. + + Arguments: + lpszBuffer pointer to CHAR buffer which on return contains + the string on success. + lpcch pointer to DWORD containing the length of the buffer. + If *lpcch == 0 then the function returns TRUE with + the count of characters required stored in lpcch. + Also in this case lpszBuffer is not affected. + Returns: + TRUE on success. + FALSE on failure. Use GetLastError() for further details. + + History: + MuraliK 20-Nov-1996 +--*/ +{ + BOOL fReturn = TRUE; + + if ( lpcch == NULL) { + SetLastError( ERROR_INVALID_PARAMETER); + return ( FALSE); + } + + register DWORD cch = QueryCCH(); + + if ( *lpcch >= cch) { + + DBG_ASSERT( lpszBuffer); + memcpy( lpszBuffer, QueryStr(), cch * sizeof(CHAR)); + } else { + DBG_ASSERT( *lpcch < cch); + SetLastError( ERROR_INSUFFICIENT_BUFFER); + fReturn = FALSE; + } + + *lpcch = cch; + + return ( fReturn); +} // MULTISZA::CopyToBuffer() + +BOOL +MULTISZA::Equals( + MULTISZA* pmszRhs +) +// +// Compares this to pmszRhs, returns TRUE if equal +// +{ + DBG_ASSERT( NULL != pmszRhs ); + + PCSTR pszLhs = First( ); + PCSTR pszRhs = pmszRhs->First( ); + + if( m_cStrings != pmszRhs->m_cStrings ) + { + return FALSE; + } + + while( NULL != pszLhs ) + { + DBG_ASSERT( NULL != pszRhs ); + + if( 0 != strcmp( pszLhs, pszRhs ) ) + { + return FALSE; + } + + pszLhs = Next( pszLhs ); + pszRhs = pmszRhs->Next( pszRhs ); + } + + return TRUE; +} + +HRESULT +SplitCommaDelimitedString( + PCSTR pszList, + BOOL fTrimEntries, + BOOL fRemoveEmptyEntries, + MULTISZA * pmszList +) +/*++ + +Routine Description: + + Split comma delimited string into a MULTISZA. Additional leading empty + entries after the first are discarded. + +Arguments: + + pszList - List to split up + fTrimEntries - Whether each entry should be trimmed before added to MULTISZA + fRemoveEmptyEntries - Whether empty entires should be discarded + pmszList - Filled with MULTISZA list + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + + if ( pszList == NULL || + pmszList == NULL ) + { + DBG_ASSERT( FALSE ); + hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + goto Finished; + } + + pmszList->Reset(); + + /* + pszCurrent: start of the current entry which may be the comma that + precedes the next entry if the entry is empty + + pszNext: the comma that precedes the next entry. If + pszCurrent == pszNext, then the entry is empty + + pszEnd: just past the end of the current entry + */ + + for ( PCSTR pszCurrent = pszList, + pszNext = strchr( pszCurrent, L',' ) + ; + ; + pszCurrent = pszNext + 1, + pszNext = strchr( pszCurrent, L',' ) ) + { + PCSTR pszEnd = NULL; + + if ( pszNext != NULL ) + { + pszEnd = pszNext; + } + else + { + pszEnd = pszCurrent + strlen( pszCurrent ); + } + + if ( fTrimEntries ) + { + while ( pszCurrent < pszEnd && ISWHITE( pszCurrent[ 0 ] ) ) + { + pszCurrent++; + } + + while ( pszEnd > pszCurrent && ISWHITE( pszEnd[ -1 ] ) ) + { + pszEnd--; + } + } + + if ( pszCurrent != pszEnd || !fRemoveEmptyEntries ) + { + if ( !pmszList->Append( pszCurrent, (DWORD) ( pszEnd - pszCurrent ) ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Finished; + } + } + + if ( pszNext == NULL ) + { + break; + } + } + +Finished: + + return hr; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/normalize.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/normalize.cxx new file mode 100644 index 0000000000..48b41fdd1c --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/normalize.cxx @@ -0,0 +1,890 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" +#include "normalize.h" +#include "stringa.h" + +BOOL g_fEnableNonUTF8; +BOOL g_fEnableDBCS; +BOOL g_fIsSystemDBCS; +static BOOL g_fFavorDBCS; + +#ifndef STACK_STRA +#define STACK_STRA(name, size) CHAR __ach##name[size]; \ + STRA name(__ach##name, sizeof(__ach##name) / sizeof(CHAR)) +#endif + +HRESULT +InitializeNormalizeUrl( + VOID +) +{ + HKEY hKey; + DWORD dwType; + DWORD dwData; + DWORD cbData; + WORD wPrimaryLangID; + + // + // Read the registry settings on how to handle URLs + // + + g_fEnableNonUTF8 = TRUE; + g_fEnableDBCS = FALSE; + g_fFavorDBCS = FALSE; + + if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, + L"System\\CurrentControlSet\\Services\\http\\Parameters", + 0, + KEY_READ, + &hKey ) == ERROR_SUCCESS ) + { + cbData = sizeof( dwData ); + if ( RegQueryValueEx( hKey, + L"EnableNonUTF8", + NULL, + &dwType, + (LPBYTE) &dwData, + &cbData ) == ERROR_SUCCESS && + dwType == REG_DWORD ) + { + g_fEnableNonUTF8 = !!dwData; + } + + if ( g_fEnableNonUTF8 ) + { + cbData = sizeof( dwData ); + + if ( RegQueryValueEx( hKey, + L"EnableDBCS", + NULL, + &dwType, + (LPBYTE) &dwData, + &cbData ) == ERROR_SUCCESS && + dwType == REG_DWORD ) + { + g_fEnableDBCS = !!dwData; + } + } + else + { + g_fEnableDBCS = FALSE; + } + + if ( g_fEnableDBCS ) + { + cbData = sizeof( dwData ); + + if ( RegQueryValueEx( hKey, + L"FavorDBCS", + NULL, + &dwType, + (LPBYTE) &dwData, + &cbData ) == ERROR_SUCCESS && + dwType == REG_DWORD ) + { + g_fFavorDBCS = !!dwData; + } + } + else + { + g_fFavorDBCS = FALSE; + } + + RegCloseKey( hKey ); + } + + + wPrimaryLangID = PRIMARYLANGID( GetSystemDefaultLangID() ); + + g_fIsSystemDBCS = ( wPrimaryLangID == LANG_JAPANESE || + wPrimaryLangID == LANG_CHINESE || + wPrimaryLangID == LANG_KOREAN ); + + return NO_ERROR; +} + +// +// Private constants. +// + +#define ACTION_NOTHING 0x00000000 +#define ACTION_EMIT_CH 0x00010000 +#define ACTION_EMIT_DOT_CH 0x00020000 +#define ACTION_EMIT_DOT_DOT_CH 0x00030000 +#define ACTION_BACKUP 0x00040000 +#define ACTION_MASK 0xFFFF0000 + + +// +// Private globals. +// + +INT p_StateTable[16] = + { + // state 0 + 0 , // other + 0 , // "." + 4 , // EOS + 1 , // "\" + + // state 1 + 0 , // other + 2 , // "." + 4 , // EOS + 1 , // "\" + + // state 2 + 0 , // other + 3 , // "." + 4 , // EOS + 1 , // "\" + + // state 3 + 0 , // other + 0 , // "." + 4 , // EOS + 1 // "\" + }; + + + +INT p_ActionTable[16] = + { + // state 0 + ACTION_EMIT_CH, // other + ACTION_EMIT_CH, // "." + ACTION_EMIT_CH, // EOS + ACTION_EMIT_CH, // "\" + + // state 1 + ACTION_EMIT_CH, // other + ACTION_NOTHING, // "." + ACTION_EMIT_CH, // EOS + ACTION_NOTHING, // "\" + + // state 2 + ACTION_EMIT_DOT_CH, // other + ACTION_NOTHING, // "." + ACTION_EMIT_CH, // EOS + ACTION_NOTHING, // "\" + + // state 3 + ACTION_EMIT_DOT_DOT_CH, // other + ACTION_EMIT_DOT_DOT_CH, // "." + ACTION_BACKUP, // EOS + ACTION_BACKUP // "\" + }; + +// since max states = 4, we calculat the index by multiplying with 4. +# define IndexFromState( st) ( (st) * 4) + + +// the following table provides the index for various ISA Latin1 characters +// in the incoming URL. +// It assumes that the URL is ISO Latin1 == ASCII +INT p_rgIndexForChar[] = { + + 2, // null char + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 thru 10 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 11 thru 20 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 21 thru 30 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 31 thru 40 + 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, // 41 thru 50 46 = '.' 47 = '/' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 51 thru 60 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 61 thru 70 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 71 thru 80 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 81 thru 90 + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, // 91 thru 100 92 = '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 101 thru 110 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 111 thru 120 + 0, 0, 0, 0, 0, 0, 0, 0 // 121 thru 128 +}; + +#define IS_UTF8_TRAILBYTE(ch) (((ch) & 0xc0) == 0x80) + + +/******************************************************************* + + NAME: IsUTF8URL + + ENTRY: pszPath - The path to sanitize. + + HISTORY: + atsusk 06-Jan-1998 Created. + +********************************************************************/ + +BOOL IsUTF8URL(__in LPSTR pszPath) +{ + CHAR ch; + + if ( g_fFavorDBCS ) + { + return ( MultiByteToWideChar( CP_ACP, + MB_ERR_INVALID_CHARS, + pszPath, + -1, + NULL, + 0) == 0); + } + + while (ch = *pszPath++) { + + if (ch & 0x80) { + wchar_t wch; + int iLen; + BOOL bDefault = FALSE; + char chTrail1; + char chTrail2; + + chTrail1 = *pszPath++; + if (chTrail1) { + chTrail2 = *pszPath; + } else { + chTrail2 = 0; + } + + if ( ((ch & 0xF0) == 0xE0) && + IS_UTF8_TRAILBYTE(chTrail1) && + IS_UTF8_TRAILBYTE(chTrail2) ) { + + // handle three byte case + // 1110xxxx 10xxxxxx 10xxxxxx + wch = (wchar_t) (((ch & 0x0f) << 12) | + ((chTrail1 & 0x3f) << 6) | + (chTrail2 & 0x3f)); + pszPath++; + + } else + if ( ((ch & 0xE0) == 0xC0) && + IS_UTF8_TRAILBYTE(chTrail1) ) { + + // handle two byte case + // 110xxxxx 10xxxxxx + + wch = (wchar_t) (((ch & 0x1f) << 6) | (chTrail1 & 0x3f)); + + } else + return FALSE; + + iLen = WideCharToMultiByte( CP_ACP, + WC_NO_BEST_FIT_CHARS, + &wch, + 1, + NULL, + 0, + NULL, + &bDefault ); + + if (bDefault == TRUE || iLen == 0 || iLen > 2) + return FALSE; + } + } + + return TRUE; +} // IsUTF8URL() + + +/******************************************************************* + + NAME: CanonURL + + SYNOPSIS: Sanitizes a path by removing bogus path elements. + + As expected, "/./" entries are simply removed, and + "/../" entries are removed along with the previous + path element. + + To maintain compatibility with URL path semantics + additional transformations are required. All backward + slashes "\\" are converted to forward slashes. Any + repeated forward slashes (such as "///") are mapped to + single backslashes. + + A state table (see the p_StateTable global at the + beginning of this file) is used to perform most of + the transformations. The table's rows are indexed + by current state, and the columns are indexed by + the current character's "class" (either slash, dot, + NULL, or other). Each entry in the table consists + of the new state tagged with an action to perform. + See the ACTION_* constants for the valid action + codes. + + ENTRY: pszPath - The path to sanitize. + fIsDBCSLocale - Indicates the server is in a + locale that uses DBCS. + + HISTORY: + KeithMo 07-Sep-1994 Created. + MuraliK 28-Apr-1995 Adopted this for symbolic paths + +********************************************************************/ +INT +CanonURL( + __inout LPSTR pszPath, + BOOL fIsDBCSLocale + ) +{ + UCHAR * pszSrc; + UCHAR * pszDest; + DWORD ch; + INT index; + BOOL fDBCS = FALSE; + DWORD cchMultiByte = 0; + + DBG_ASSERT( pszPath != NULL ); + + // + // Always look for UTF8 except when DBCS characters are detected + // + BOOL fScanForUTF8 = IsUTF8URL(pszPath); + + // If fScanForUTF8 is true, this URL is UTF8. don't recognize DBCS. + if (fIsDBCSLocale && fScanForUTF8) { + fIsDBCSLocale = FALSE; + } + + // + // Start our scan at the first character + // + + pszSrc = pszDest = (UCHAR *) pszPath; + + // + // State 0 is the initial state. + // + index = 0; // State = 0 + + // + // Loop until we enter state 4 (the final, accepting state). + // + + do { + + // + // Grab the next character from the path and compute its + // next state. While we're at it, map any forward + // slashes to backward slashes. + // + + index = IndexFromState( p_StateTable[index]); // 4 = # states + ch = (DWORD ) *pszSrc++; + + // + // If this is a DBCS trailing byte - skip it + // + + if ( !fIsDBCSLocale ) + { + index += (( ch >= 0x80) ? 0 : p_rgIndexForChar[ch]); + } + else + { + if ( fDBCS ) + { + // + // If this is a 0 terminator, we need to set next + // state accordingly + // + + if ( ch == 0 ) + { + index += p_rgIndexForChar[ ch ]; + } + + // + // fDBCS == TRUE means this byte was a trail byte. + // index is implicitly set to zero. + // + fDBCS = FALSE; + } + else + { + index += (( ch >= 0x80) ? 0 : p_rgIndexForChar[ch]); + + if ( IsDBCSLeadByte( (UCHAR)ch ) ) + { + // + // This is a lead byte, so the next is a trail. + // + fDBCS = TRUE; + } + } + } + + // + // Interesting UTF8 characters always have the top bit set + // + + if ( (ch & 0x80) && fScanForUTF8 ) + { + wchar_t wch; + UCHAR mbstr[2]; + + // + // This is a UTF8 character, convert it here. + // index is implicitly set to zero. + // + if ( cchMultiByte < 2 ) + { + char chTrail1; + char chTrail2; + + chTrail1 = *pszSrc; + if (chTrail1) { + chTrail2 = *(pszSrc+1); + } else { + chTrail2 = 0; + } + wch = 0; + + if ((ch & 0xf0) == 0xe0) + { + // handle three byte case + // 1110xxxx 10xxxxxx 10xxxxxx + + wch = (wchar_t) (((ch & 0x0f) << 12) | + ((chTrail1 & 0x3f) << 6) | + (chTrail2 & 0x3f)); + + cchMultiByte = WideCharToMultiByte( CP_ACP, + WC_NO_BEST_FIT_CHARS, + &wch, + 1, + (LPSTR) mbstr, + 2, + NULL, + NULL ); + + ch = mbstr[0]; + pszSrc += (3 - cchMultiByte); + + // WinSE 12843: Security Fix, Index should be updated for this character + index += (( ch >= 0x80) ? 0 : p_rgIndexForChar[ch]); + + } else if ((ch & 0xe0) == 0xc0) + { + // handle two byte case + // 110xxxxx 10xxxxxx + + wch = (wchar_t) (((ch & 0x1f) << 6) | (chTrail1 & 0x3f)); + + cchMultiByte = WideCharToMultiByte( CP_ACP, + WC_NO_BEST_FIT_CHARS, + &wch, + 1, + (LPSTR) mbstr, + 2, + NULL, + NULL ); + + ch = mbstr[0]; + pszSrc += (2 - cchMultiByte); + + // WinSE 12843: Security Fix, Index should be updated for this character + index += (( ch >= 0x80) ? 0 : p_rgIndexForChar[ch]); + } + + } else { + // + // get ready to emit 2nd byte of converted character + // + ch = mbstr[1]; + cchMultiByte = 0; + } + } + + + // + // Perform the action associated with the state. + // + + switch( p_ActionTable[index] ) + { + case ACTION_EMIT_DOT_DOT_CH : + *pszDest++ = '.'; + /* fall through */ + + case ACTION_EMIT_DOT_CH : + *pszDest++ = '.'; + /* fall through */ + + case ACTION_EMIT_CH : + *pszDest++ = (CHAR ) ch; + /* fall through */ + + case ACTION_NOTHING : + break; + + case ACTION_BACKUP : + if( (pszDest > ( (UCHAR *) pszPath + 1 ) ) && (*pszPath == '/')) + { + pszDest--; + DBG_ASSERT( *pszDest == '/' ); + + *pszDest = '\0'; + pszDest = (UCHAR *) strrchr( pszPath, '/') + 1; + } + + *pszDest = '\0'; + break; + + default : + DBG_ASSERT( !"Invalid action code in state table!" ); + index = IndexFromState(0) + 2; // move to invalid state + DBG_ASSERT( p_StateTable[index] == 4); + *pszDest++ = '\0'; + break; + } + + } while( p_StateTable[index] != 4 ); + + // + // point to terminating nul + // only do the check if we aren't about to go outside of the number + // of elements in the table. + // + if ( ( index < ( sizeof(p_ActionTable) / sizeof(p_ActionTable[0]) ) ) + && p_ActionTable[index] == ACTION_EMIT_CH ) + { + pszDest--; + } + + DBG_ASSERT(*pszDest == '\0' && pszDest > (UCHAR*) pszPath); + + return (INT)DIFF(pszDest - (UCHAR*)pszPath); +} // CanonURL() + + + +HRESULT +NormalizeUrl( + __inout LPSTR pszStart + ) +/*++ + +Routine Description: + + Normalize URL + +Arguments: + + strUrl - URL to be updated to a canonical URI + +Return value: + + TRUE if no error, otherwise FALSE + +--*/ +{ + CHAR * pchParams; + LPSTR pszSlash; + LPSTR pszURL; + LPSTR pszValue; + STACK_STRA( strChgUrl, MAX_PATH ); + HRESULT hr; + DWORD cchInput; + + if ( pszStart == NULL ) + { + return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + } + + cchInput = (DWORD)strlen( pszStart ); + + if ( *pszStart != '/' ) + { + // + // assume HTTP URL, skip protocol & host name by + // searching for 1st '/' following "//" + // + // We handle this information as a "Host:" header. + // It will be overwritten by the real header if it is + // present. + // + // We do not check for a match in this case. + // + + if ( (pszSlash = strchr( pszStart, '/' )) && pszSlash[1] == '/' ) + { + pszSlash += 2; + if ( pszURL = strchr( pszSlash, '/' ) ) + { + // + // update pointer to URL to point to the 1st slash + // following host name + // + + pszValue = pszURL; + } + else + { + // + // if no single slash following host name + // consider the URL to be empty. + // + + pszValue = pszSlash + strlen( pszSlash ); + } + + memmove( pszStart, pszValue, strlen(pszValue)+1 ); + } + + // + // if no double slash, this is not a fully qualified URL + // and we leave it alone. + // + } + + // + // Check for a question mark which indicates this URL contains some + // parameters and break the two apart if found + // + + if ( (pchParams = strchr( pszStart, '?' )) ) + { + *pchParams = '\0'; + } + + // + // Unescape wants a STR ( sigh ) + // + + hr = strChgUrl.Copy( (CHAR*)pszStart ); + + if ( FAILED( hr ) ) + { + return hr; + } + + strChgUrl.Unescape(); + + hr = StringCchCopyNA( pszStart, cchInput + 1, strChgUrl.QueryStr(), cchInput ); + if ( FAILED( hr ) ) + { + return hr; + } + + // + // Canonicalize the URL + // + + CanonURL( pszStart, g_fIsSystemDBCS ); + + return NO_ERROR; +} + + + + +HRESULT +NormalizeUrlOld( + __inout LPSTR pszUrl +) +/*++ + +Routine Description: + + NormalizeUrl wrapper (used by ISAPI filter and extension support functions) + +Parameters: + + pszUrl - On entry, the URL to be normalized + On return, the normalized URL + (size of normalized URL is always <= not normalized URL) + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = NO_ERROR; + + if ( pszUrl ) + { + STACK_BUFFER( buffUrlOutput, MAX_PATH ); + STACK_STRA( strUrlA, MAX_PATH ); + LPWSTR szQueryString; + DWORD cchData; + DWORD cbOutput; + + cchData = (DWORD)strlen( pszUrl ); + + // + // Prepare the Output string + // + + if ( !buffUrlOutput.Resize( ( cchData + 1 ) *sizeof( WCHAR ) ) ) + { + return HRESULT_FROM_WIN32( GetLastError() ); + } + + // + // Normalize it + // + + hr = UlCleanAndCopyUrl( + pszUrl, + cchData, + &cbOutput, + (WCHAR *) buffUrlOutput.QueryPtr(), + &szQueryString + ); + + if ( FAILED( hr ) ) + { + return hr; + } + + // + // Terminate the string at the query so that the + // query string doesn't appear in the output. IIS 5 + // truncated in this way. + // + + if ( szQueryString != NULL ) + { + ((WCHAR *) buffUrlOutput.QueryPtr())[ cbOutput - wcslen( szQueryString )] = 0; + } + + // + // Write the normalized URL over the input data + // + + hr = strUrlA.CopyW( (WCHAR *) buffUrlOutput.QueryPtr() ); + + if ( FAILED( hr ) ) + { + return hr; + } + + // + // Normalized string will never be longer than the original one + // + + DBG_ASSERT( strUrlA.QueryCCH() <= cchData ); + + hr = StringCchCopyA( pszUrl, cchData + 1, strUrlA.QueryStr() ); + if ( FAILED( hr ) ) + { + return hr; + } + + hr = NO_ERROR; + } + else + { + hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + } + return hr; +} + + +HRESULT +NormalizeUrlW( + __inout LPWSTR pszUrl +) +/*++ + +Routine Description: + + unicode version of NormalizeUrl wrapper (used by ISAPI filter and extension support functions) + +Parameters: + + pszUrl - On entry, the URL to be normalized + On return, the normalized URL + (size of normalized URL is always <= not normalized URL) + +Return Value: + + HRESULT + +--*/ +{ + + HRESULT hr = NO_ERROR; + + if ( pszUrl ) + { + STACK_BUFFER( buffUrlOutput, MAX_PATH ); + STACK_STRA( strUrlA, MAX_PATH ); + LPWSTR szQueryString; + DWORD cchData; + DWORD cbOutput; + + cchData = (DWORD)wcslen( pszUrl ); + + hr = strUrlA.CopyWToUTF8Escaped( pszUrl ); + + if ( FAILED( hr ) ) + { + return hr; + } + + // + // Prepare Output string + // + + if ( !buffUrlOutput.Resize( ( cchData + 1 ) *sizeof( WCHAR ) ) ) + { + return HRESULT_FROM_WIN32( GetLastError() ); + } + + // + // Normalize it + // + + hr = UlCleanAndCopyUrl( + strUrlA.QueryStr(), + strUrlA.QueryCB(), + &cbOutput, + (WCHAR *) buffUrlOutput.QueryPtr(), + &szQueryString + ); + + if ( FAILED( hr ) ) + { + return hr; + } + + + // + // Terminate the string at the query so that the + // query string doesn't appear in the output. IIS 5 + // truncated in this way. + // + + if ( szQueryString != NULL ) + { + ((WCHAR *) buffUrlOutput.QueryPtr())[ cbOutput - wcslen( szQueryString )] = 0; + } + + // + // normalized string will never be longer than the original one + // + + DBG_ASSERT( cbOutput <= cchData * sizeof( WCHAR ) ); + + // + // Write the normalized URL over the input data + // + + hr = StringCchCopyW( pszUrl, cchData+1, (WCHAR *) buffUrlOutput.QueryPtr() ); + if ( FAILED( hr ) ) + { + return hr; + } + + hr = NO_ERROR; + } + else + { + hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + } + return hr; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/packages.config b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/packages.config new file mode 100644 index 0000000000..21d9344493 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/packages.config @@ -0,0 +1,4 @@ + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/precomp.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/precomp.h new file mode 100644 index 0000000000..8f578b2ad3 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/precomp.h @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include +#include +#pragma warning( disable:4127 ) +#include +#include +#include + +#include "macros.h" +#include "stringu.h" +#include "stringa.h" +#include "dbgutil.h" +#include "ntassert.h" +#include "ahutil.h" +#include "acache.h" +#include "base64.hxx" diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/stringa.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/stringa.cpp new file mode 100644 index 0000000000..6380535473 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/stringa.cpp @@ -0,0 +1,1767 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +STRA::STRA( + VOID +) : m_cchLen( 0 ) +{ + *( QueryStr() ) = '\0'; +} + +STRA::STRA( + __inout_ecount(cchInit) CHAR* pbInit, + __in DWORD cchInit +) : m_Buff( pbInit, cchInit * sizeof( CHAR ) ), + m_cchLen(0) +/*++ + Description: + + Used by STACK_STRA. Initially populates underlying buffer with pbInit. + + pbInit is not freed. + + Arguments: + + pbInit - initial memory to use + cchInit - count, in characters, of pbInit + + Returns: + + None. + +--*/ +{ + _ASSERTE( NULL != pbInit ); + _ASSERTE( cchInit > 0 ); + _ASSERTE( pbInit[0] == '\0' ); +} + +BOOL +STRA::IsEmpty( + VOID +) const +{ + return ( m_cchLen == 0 ); +} + +BOOL +STRA::Equals( + __in PCSTR pszRhs, + __in BOOL fIgnoreCase /*= FALSE*/ +) const +{ + _ASSERTE( NULL != pszRhs ); + + if( fIgnoreCase ) + { + return ( 0 == _stricmp( QueryStr(), pszRhs ) ); + } + + return ( 0 == strcmp( QueryStr(), pszRhs ) ); +} + +BOOL +STRA::Equals( + __in const STRA * pstrRhs, + __in BOOL fIgnoreCase /*= FALSE*/ +) const +{ + _ASSERTE( NULL != pstrRhs ); + return Equals( pstrRhs->QueryStr(), fIgnoreCase ); +} + +BOOL +STRA::Equals( + __in const STRA & strRhs, + __in BOOL fIgnoreCase /*= FALSE*/ +) const +{ + return Equals( strRhs.QueryStr(), fIgnoreCase ); +} + +DWORD +STRA::QueryCB( + VOID +) const +// +// Returns the number of bytes in the string excluding the terminating NULL +// +{ + return m_cchLen * sizeof( CHAR ); +} + +DWORD +STRA::QueryCCH( + VOID +) const +// +// Returns the number of characters in the string excluding the terminating NULL +// +{ + return m_cchLen; +} + +DWORD +STRA::QuerySizeCCH( + VOID +) const +// +// Returns size of the underlying storage buffer, in characters +// +{ + return m_Buff.QuerySize() / sizeof( CHAR ); +} + +DWORD +STRA::QuerySize( + VOID +) const +// +// Returns the size of the storage buffer in bytes +// +{ + return m_Buff.QuerySize(); +} + +__nullterminated +__bcount(this->m_cchLen) +CHAR * +STRA::QueryStr( + VOID +) const +// +// Return the string buffer +// +{ + return m_Buff.QueryPtr(); +} + +VOID +STRA::Reset( + VOID +) +// +// Resets the internal string to be NULL string. Buffer remains cached. +// +{ + _ASSERTE( QueryStr() != NULL ); + *(QueryStr()) = '\0'; + m_cchLen = 0; +} + +HRESULT +STRA::Resize( + __in DWORD cchSize +) +{ + if( !m_Buff.Resize( cchSize * sizeof( CHAR ) ) ) + { + return E_OUTOFMEMORY; + } + + return S_OK; +} + +HRESULT +STRA::SyncWithBuffer( + VOID +) +// +// Recalculate the length of the string, etc. because we've modified +// the buffer directly. +// +{ + HRESULT hr; + size_t size; + hr = StringCchLengthA( QueryStr(), + QuerySizeCCH(), + &size ); + if ( SUCCEEDED( hr ) ) + { + m_cchLen = static_cast(size); + } + return hr; +} + +HRESULT +STRA::Copy( + __in PCSTR pszCopy +) +{ + HRESULT hr; + size_t cbLen; + hr = StringCbLengthA( pszCopy, + STRSAFE_MAX_CCH, + &cbLen ); + if ( FAILED( hr ) ) + { + return hr; + } + return Copy( pszCopy, cbLen ); +} + + +HRESULT +STRA::Copy( + __in_ecount(cchLen) + PCSTR pszCopy, + __in SIZE_T cbLen +) +// +// Copy the contents of another string to this one +// +{ + _ASSERTE( cbLen <= MAXDWORD ); + + return AuxAppend( + pszCopy, + static_cast(cbLen), + 0 + ); +} + +HRESULT +STRA::Copy( + __in const STRA * pstrRhs +) +{ + _ASSERTE( pstrRhs != NULL ); + return Copy( pstrRhs->QueryStr(), pstrRhs->QueryCCH() ); +} + +HRESULT +STRA::Copy( + __in const STRA & strRhs +) +{ + return Copy( strRhs.QueryStr(), strRhs.QueryCCH() ); +} + +HRESULT +STRA::CopyW( + __in PCWSTR pszCopyW +) +{ + HRESULT hr; + size_t cchLen; + hr = StringCchLengthW( pszCopyW, + STRSAFE_MAX_CCH, + &cchLen ); + if ( FAILED( hr ) ) + { + return hr; + } + return CopyW( pszCopyW, cchLen ); +} + +HRESULT +STRA::CopyWTruncate( + __in PCWSTR pszCopyWTruncate +) +{ + HRESULT hr; + size_t cchLen; + hr = StringCchLengthW( pszCopyWTruncate, + STRSAFE_MAX_CCH, + &cchLen ); + if ( FAILED( hr ) ) + { + return hr; + } + return CopyWTruncate( pszCopyWTruncate, cchLen ); +} + +HRESULT +STRA::CopyWTruncate( + __in_ecount(cchLen) + PCWSTR pszCopyWTruncate, + __in SIZE_T cchLen +) +// +// The "Truncate" methods do not do proper conversion. They do a (CHAR) caste +// +{ + _ASSERTE( cchLen <= MAXDWORD ); + + return AuxAppendWTruncate( + pszCopyWTruncate, + static_cast(cchLen), + 0 + ); +} + +HRESULT +STRA::Append( + __in PCSTR pszAppend +) +{ + HRESULT hr; + size_t cbLen; + hr = StringCbLengthA( pszAppend, + STRSAFE_MAX_CCH, + &cbLen ); + if ( FAILED( hr ) ) + { + return hr; + } + return Append( pszAppend, cbLen ); +} + +HRESULT +STRA::Append( + __in_ecount(cchLen) + PCSTR pszAppend, + __in SIZE_T cbLen +) +{ + _ASSERTE( cbLen <= MAXDWORD ); + if ( cbLen == 0 ) + { + return S_OK; + } + return AuxAppend( + pszAppend, + static_cast(cbLen), + QueryCB() + ); +} + +HRESULT +STRA::Append( + __in const STRA * pstrRhs +) +{ + _ASSERTE( pstrRhs != NULL ); + return Append( pstrRhs->QueryStr(), pstrRhs->QueryCCH() ); +} + +HRESULT +STRA::Append( + __in const STRA & strRhs +) +{ + return Append( strRhs.QueryStr(), strRhs.QueryCCH() ); +} + +HRESULT +STRA::AppendWTruncate( + __in PCWSTR pszAppendWTruncate +) +{ + HRESULT hr; + size_t cchLen; + hr = StringCchLengthW( pszAppendWTruncate, + STRSAFE_MAX_CCH, + &cchLen ); + if ( FAILED( hr ) ) + { + return hr; + } + return AppendWTruncate( pszAppendWTruncate, cchLen ); +} + +HRESULT +STRA::AppendWTruncate( + __in_ecount(cchLen) + PCWSTR pszAppendWTruncate, + __in SIZE_T cchLen +) +// +// The "Truncate" methods do not do proper conversion. They do a (CHAR) caste +// +{ + _ASSERTE( cchLen <= MAXDWORD ); + if ( cchLen == 0 ) + { + return S_OK; + } + return AuxAppendWTruncate( + pszAppendWTruncate, + static_cast(cchLen), + QueryCB() + ); +} + +HRESULT +STRA::CopyToBuffer( + __out_bcount(*pcb) CHAR* pszBuffer, + __inout DWORD * pcb +) const +// +// Makes a copy of the stored string into the given buffer +// +{ + _ASSERTE( NULL != pszBuffer ); + _ASSERTE( NULL != pcb ); + + HRESULT hr = S_OK; + DWORD cbNeeded = QueryCB() + sizeof( CHAR ); + + if( *pcb < cbNeeded ) + { + hr = HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ); + goto Finished; + } + + memcpy( pszBuffer, QueryStr(), cbNeeded ); + +Finished: + + *pcb = cbNeeded; + + return hr; +} + +HRESULT +STRA::SetLen( + __in DWORD cchLen +) +/*++ + * +Routine Description: + + Set the length of the string and null terminate, if there + is sufficient buffer already allocated. Will not reallocate. + +Arguments: + + cchLen - The number of characters in the new string. + +Return Value: + + HRESULT + +--*/ +{ + if( cchLen >= QuerySizeCCH() ) + { + return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + } + + *( QueryStr() + cchLen ) = '\0'; + m_cchLen = cchLen; + + return S_OK; +} + + +HRESULT +STRA::SafeSnprintf( + __in __format_string + PCSTR pszFormatString, + ... +) +/*++ + +Routine Description: + + Writes to a STRA, growing it as needed. It arbitrarily caps growth at 64k chars. + +Arguments: + + pszFormatString - printf format + ... - printf args + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + va_list argsList; + va_start( argsList, pszFormatString ); + + hr = SafeVsnprintf(pszFormatString, argsList); + + va_end( argsList ); + return hr; +} + +HRESULT +STRA::SafeVsnprintf( + __in __format_string + PCSTR pszFormatString, + va_list argsList +) +/*++ + +Routine Description: + + Writes to a STRA, growing it as needed. It arbitrarily caps growth at 64k chars. + +Arguments: + + pszFormatString - printf format + argsList - printf va_list + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + int cchOutput; + int cchNeeded; + + // + // Format the incoming message using vsnprintf() + // so that the overflows are captured + // + cchOutput = _vsnprintf_s( + QueryStr(), + QuerySizeCCH(), + QuerySizeCCH() - 1, + pszFormatString, + argsList + ); + + if( cchOutput == -1 ) + { + // + // Couldn't fit this in the original STRU size. + // + cchNeeded = _vscprintf( pszFormatString, argsList ); + if( cchNeeded > 64 * 1024 ) + { + // + // If we're trying to produce a string > 64k chars, then + // there is probably a problem + // + hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + goto Finished; + } + + // + // _vscprintf doesn't include terminating null character + // + cchNeeded++; + + hr = Resize( cchNeeded ); + if( FAILED( hr ) ) + { + goto Finished; + } + + cchOutput = _vsnprintf_s( + QueryStr(), + QuerySizeCCH(), + QuerySizeCCH() - 1, + pszFormatString, + argsList + ); + if( -1 == cchOutput ) + { + // + // This should never happen, cause we should already have correctly sized memory + // + _ASSERTE( FALSE ); + + hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + goto Finished; + } + } + + // + // always null terminate at the last WCHAR + // + QueryStr()[ QuerySizeCCH() - 1 ] = L'\0'; + + // + // we directly touched the buffer - therefore: + // + hr = SyncWithBuffer(); + if( FAILED( hr ) ) + { + goto Finished; + } + +Finished: + + if( FAILED( hr ) ) + { + Reset(); + } + + return hr; +} + +bool +FShouldEscapeUtf8( + BYTE ch + ) +{ + if ( ( ch >= 128 ) ) + { + return true; + } + + return false; +} + +bool +FShouldEscapeUrl( + BYTE ch + ) +{ + if ( ( ch >= 128 || + ch <= 32 || + ch == '<' || + ch == '>' || + ch == '%' || + ch == '?' || + ch == '#' ) && + !( ch == '\n' || ch == '\r' ) ) + { + return true; + } + + return false; +} + +HRESULT +STRA::Escape( + VOID +) +/*++ + +Routine Description: + + Escapes a STRA + +Arguments: + + None + +Return Value: + + None + +--*/ +{ + return EscapeInternal( FShouldEscapeUrl ); +} + +HRESULT +STRA::EscapeUtf8( + VOID +) +/*++ + +Routine Description: + + Escapes the high-bit chars in a STRA. LWS, CR, LF & controls are untouched. + +Arguments: + + None + +Return Value: + + None + +--*/ +{ + return EscapeInternal( FShouldEscapeUtf8 ); +} + + +HRESULT +STRA::EscapeInternal( + PFN_F_SHOULD_ESCAPE pfnFShouldEscape +) +/*++ + +Routine Description: + + Escapes a STRA according to the predicate function passed in + +Arguments: + + None + +Return Value: + + None + +--*/ +{ + LPCSTR pch = QueryStr(); + __analysis_assume( pch != NULL ); + int i = 0; + BYTE ch; + HRESULT hr = S_OK; + BOOL fRet = FALSE; + SIZE_T NewSize = 0; + + // Set to true if any % escaping occurs + BOOL fEscapingDone = FALSE; + + // + // If there are any characters that need to be escaped we copy the entire string + // character by character into straTemp, escaping as we go, then at the end + // copy all of straTemp over. Don't modify InlineBuffer directly. + // + CHAR InlineBuffer[512]; + InlineBuffer[0] = '\0'; + STRA straTemp(InlineBuffer, sizeof(InlineBuffer)/sizeof(*InlineBuffer)); + + _ASSERTE( pch ); + + while (ch = pch[i]) + { + // + // Escape characters that are in the non-printable range + // but ignore CR and LF + // + + if ( pfnFShouldEscape( ch ) ) + { + if (FALSE == fEscapingDone) + { + // first character in the string that needed escaping + fEscapingDone = TRUE; + + // guess that the size needs to be larger than + // what we used to have times two + NewSize = QueryCCH() * 2; + if ( NewSize > MAXDWORD ) + { + hr = HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW ); + return hr; + } + + hr = straTemp.Resize( static_cast(NewSize) ); + + if (FAILED(hr)) + { + return hr; + } + + // Copy all of the previous buffer into buffTemp, only if it is not the first character: + + if ( i > 0) + { + hr = straTemp.Copy(QueryStr(), + i * sizeof(CHAR)); + if (FAILED(hr)) + { + return hr; + } + } + } + + // resize the temporary (if needed) with the slop of the entire buffer length + // this fixes constant reallocation if the entire string needs to be escaped + NewSize = QueryCCH() + 2 * sizeof(CHAR) + 1 * sizeof(CHAR); + if ( NewSize > MAXDWORD ) + { + hr = HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW ); + return hr; + } + + fRet = straTemp.m_Buff.Resize( NewSize ); + if ( !fRet ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + return hr; + } + + // + // Create the string to append for the current character + // + + CHAR chHex[3]; + chHex[0] = '%'; + + // + // Convert the low then the high character to hex + // + + UINT nLowDigit = (UINT)(ch % 16); + chHex[2] = TODIGIT( nLowDigit ); + + ch /= 16; + + UINT nHighDigit = (UINT)(ch % 16); + + chHex[1] = TODIGIT( nHighDigit ); + + // + // Actually append the converted character to the end of the temporary + // + hr = straTemp.Append(chHex, 3); + if (FAILED(hr)) + { + return hr; + } + } + else + { + // if no escaping done, no need to copy + if (fEscapingDone) + { + // if ANY escaping done, copy current character into new buffer + straTemp.Append(&pch[i], 1); + } + } + + // inspect the next character in the string + i++; + } + + if (fEscapingDone) + { + // the escaped string is now in straTemp + hr = Copy(straTemp); + } + + return hr; + +} // EscapeInternal() + +VOID +STRA::Unescape( + VOID +) +/*++ + +Routine Description: + + Unescapes a STRA + + Supported escape sequences are: + %uxxxx unescapes Unicode character xxxx into system codepage + %xx unescapes character xx + % without following hex digits is ignored + +Arguments: + + None + +Return Value: + + None + +--*/ +{ + CHAR *pScan; + CHAR *pDest; + CHAR *pNextScan; + WCHAR wch; + DWORD dwLen; + BOOL fChanged = FALSE; + + // + // Now take care of any escape characters + // + pDest = pScan = strchr(QueryStr(), '%'); + + while (pScan) + { + if ((pScan[1] == 'u' || pScan[1] == 'U') && + SAFEIsXDigit(pScan[2]) && + SAFEIsXDigit(pScan[3]) && + SAFEIsXDigit(pScan[4]) && + SAFEIsXDigit(pScan[5])) + { + wch = TOHEX(pScan[2]) * 4096 + TOHEX(pScan[3]) * 256 + + TOHEX(pScan[4]) * 16 + TOHEX(pScan[5]); + + dwLen = WideCharToMultiByte(CP_ACP, + WC_NO_BEST_FIT_CHARS, + &wch, + 1, + (LPSTR) pDest, + 6, + NULL, + NULL); + + pDest += dwLen; + pScan += 6; + fChanged = TRUE; + } + else if (SAFEIsXDigit(pScan[1]) && SAFEIsXDigit(pScan[2])) + { + *pDest = TOHEX(pScan[1]) * 16 + TOHEX(pScan[2]); + + pDest ++; + pScan += 3; + fChanged = TRUE; + } + else // Not an escaped char, just a '%' + { + if (fChanged) + { + *pDest = *pScan; + } + + pDest++; + pScan++; + } + + // + // Copy all the information between this and the next escaped char + // + pNextScan = strchr(pScan, '%'); + + if (fChanged) // pScan!=pDest, so we have to copy the char's + { + if (!pNextScan) // That was the last '%' in the string + { + memmove(pDest, + pScan, + QueryCCH() - DIFF(pScan - QueryStr()) + 1); + } + else + { + // There is another '%', move intermediate chars + if ((dwLen = (DWORD)DIFF(pNextScan - pScan)) != 0) + { + memmove(pDest, + pScan, + dwLen); + pDest += dwLen; + } + } + } + + pScan = pNextScan; + } + + if (fChanged) + { + m_cchLen = (DWORD)strlen(QueryStr()); // for safety recalc the length + } + + return; +} + +HRESULT +STRA::CopyWToUTF8Unescaped( + __in LPCWSTR cpchStr +) +{ + return STRA::CopyWToUTF8Unescaped(cpchStr, (DWORD) wcslen(cpchStr)); +} + +HRESULT +STRA::CopyWToUTF8Unescaped( + __in_ecount(cch) + LPCWSTR cpchStr, + __in DWORD cch +) +{ + HRESULT hr = S_OK; + int iRet; + + if (cch == 0) + { + Reset(); + return S_OK; + } + + iRet = ConvertUnicodeToUTF8(cpchStr, + &m_Buff, + cch); + if (-1 == iRet) + { + // could not convert + hr = HRESULT_FROM_WIN32(GetLastError()); + goto Finished; + } + + m_cchLen = iRet; + + _ASSERTE(strlen(m_Buff.QueryPtr()) == m_cchLen); +Finished: + return hr; +} + +HRESULT +STRA::CopyWToUTF8Escaped( + __in LPCWSTR cpchStr +) +{ + return STRA::CopyWToUTF8Escaped(cpchStr, (DWORD) wcslen(cpchStr)); +} + +HRESULT +STRA::CopyWToUTF8Escaped( + __in_ecount(cch) + LPCWSTR cpchStr, + __in DWORD cch +) +{ + HRESULT hr = S_OK; + + hr = CopyWToUTF8Unescaped(cpchStr, cch); + if (FAILED(hr)) + { + goto Finished; + } + + hr = Escape(); + if (FAILED(hr)) + { + goto Finished; + } + + hr = S_OK; +Finished: + return hr; +} + +HRESULT +STRA::AuxAppend( + __in_ecount(cbLen) + LPCSTR pStr, + __in DWORD cbLen, + __in DWORD cbOffset +) +{ + _ASSERTE( NULL != pStr ); + _ASSERTE( cbOffset <= QueryCB() ); + + ULONGLONG cb64NewSize = (ULONGLONG)cbOffset + cbLen + sizeof( CHAR ); + if( cb64NewSize > MAXDWORD ) + { + return HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW ); + } + + if( m_Buff.QuerySize() < cb64NewSize ) + { + if( !m_Buff.Resize( static_cast(cb64NewSize) ) ) + { + return E_OUTOFMEMORY; + } + } + + memcpy( reinterpret_cast(m_Buff.QueryPtr()) + cbOffset, pStr, cbLen ); + + m_cchLen = cbLen + cbOffset; + + *( QueryStr() + m_cchLen ) = '\0'; + + return S_OK; +} + +HRESULT +STRA::AuxAppendW( + __in_ecount(cchAppendW) + PCWSTR pszAppendW, + __in DWORD cchAppendW, + __in DWORD cbOffset, + __in UINT CodePage, + __in BOOL fFailIfNoTranslation, + __in DWORD dwFlags +) +{ + HRESULT hr = S_OK; + DWORD cbAvailable = 0; + DWORD cbRet = 0; + + // + // There are only two expect places to append + // + _ASSERTE( 0 == cbOffset || QueryCB() == cbOffset ); + + if ( cchAppendW == 0 ) + { + goto Finished; + } + + // + // start by assuming 1 char to 1 char will be enough space + // + if( !m_Buff.Resize( cbOffset + cchAppendW + sizeof( CHAR ) ) ) + { + hr = E_OUTOFMEMORY; + goto Finished; + } + + cbAvailable = m_Buff.QuerySize() - cbOffset; + + cbRet = WideCharToMultiByte( + CodePage, + dwFlags, + pszAppendW, + cchAppendW, + QueryStr() + cbOffset, + cbAvailable, + NULL, + NULL + ); + if( 0 != cbRet ) + { + if(!m_Buff.Resize(cbOffset + cbRet + 1)) + { + hr = E_OUTOFMEMORY; + } + + // + // not zero --> success, so we're done + // + goto Finished; + } + + // + // We only know how to handle ERROR_INSUFFICIENT_BUFFER + // + hr = HRESULT_FROM_WIN32( GetLastError() ); + if( hr != HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) ) + { + goto Finished; + } + + // + // Reset HResult because we need to get the number of bytes needed + // + hr = S_OK; + cbRet = WideCharToMultiByte( + CodePage, + dwFlags, + pszAppendW, + cchAppendW, + NULL, + 0, + NULL, + NULL + ); + if( 0 == cbRet ) + { + // + // no idea how we could ever reach here + // + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Finished; + } + + if( !m_Buff.Resize( cbOffset + cbRet + 1) ) + { + hr = E_OUTOFMEMORY; + goto Finished; + } + + cbAvailable = m_Buff.QuerySize() - cbOffset; + + cbRet = WideCharToMultiByte( + CodePage, + dwFlags, + pszAppendW, + cchAppendW, + QueryStr() + cbOffset, + cbAvailable, + NULL, + NULL + ); + if( 0 == cbRet ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Finished; + } + +Finished: + + if( SUCCEEDED( hr ) && 0 != cbRet ) + { + m_cchLen = cbRet + cbOffset; + } + + // + // ensure we're still NULL terminated in the right spot + // (regardless of success or failure) + // + QueryStr()[m_cchLen] = '\0'; + + return hr; +} + +HRESULT +STRA::AuxAppendWTruncate( + __in_ecount(cchAppendW) + __in PCWSTR pszAppendW, + __in DWORD cchAppendW, + __in DWORD cbOffset +) +// +// Cheesey WCHAR --> CHAR conversion +// +{ + HRESULT hr = S_OK; + CHAR* pszBuffer; + + _ASSERTE( NULL != pszAppendW ); + _ASSERTE( 0 == cbOffset || cbOffset == QueryCB() ); + + if( !pszAppendW ) + { + hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + goto Finished; + } + + ULONGLONG cbNeeded = (ULONGLONG)cbOffset + cchAppendW + sizeof( CHAR ); + if( cbNeeded > MAXDWORD ) + { + hr = HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW ); + goto Finished; + } + + if( !m_Buff.Resize( static_cast(cbNeeded) ) ) + { + hr = E_OUTOFMEMORY; + goto Finished; + } + + // + // Copy/convert the UNICODE string over (by making two bytes into one) + // + pszBuffer = QueryStr() + cbOffset; + for( DWORD i = 0; i < cchAppendW; i++ ) + { + pszBuffer[i] = static_cast(pszAppendW[i]); + } + + m_cchLen = cchAppendW + cbOffset; + *( QueryStr() + m_cchLen ) = '\0'; + +Finished: + + return hr; +} + +// static +int +STRA::ConvertUnicodeToCodePage( + __in_ecount(dwStringLen) + LPCWSTR pszSrcUnicodeString, + __inout BUFFER_T * pbufDstAnsiString, + __in DWORD dwStringLen, + __in UINT uCodePage +) +{ + _ASSERTE(NULL != pszSrcUnicodeString); + _ASSERTE(NULL != pbufDstAnsiString); + + BOOL bTemp; + int iStrLen = 0; + DWORD dwFlags; + + if (uCodePage == CP_ACP) + { + dwFlags = WC_NO_BEST_FIT_CHARS; + } + else + { + dwFlags = 0; + } + + iStrLen = WideCharToMultiByte(uCodePage, + dwFlags, + pszSrcUnicodeString, + dwStringLen, + (LPSTR)pbufDstAnsiString->QueryPtr(), + (int)pbufDstAnsiString->QuerySize(), + NULL, + NULL); + if ((iStrLen == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { + iStrLen = WideCharToMultiByte(uCodePage, + dwFlags, + pszSrcUnicodeString, + dwStringLen, + NULL, + 0, + NULL, + NULL); + if (iStrLen != 0) { + // add one just for the extra NULL + bTemp = pbufDstAnsiString->Resize(iStrLen + 1); + if (!bTemp) + { + iStrLen = 0; + } + else + { + iStrLen = WideCharToMultiByte(uCodePage, + dwFlags, + pszSrcUnicodeString, + dwStringLen, + (LPSTR)pbufDstAnsiString->QueryPtr(), + (int)pbufDstAnsiString->QuerySize(), + NULL, + NULL); + } + + } + } + + if (0 != iStrLen && + pbufDstAnsiString->Resize(iStrLen + 1)) + { + // insert a terminating NULL into buffer for the dwStringLen+1 in the case that the dwStringLen+1 was not a NULL. + ((CHAR*)pbufDstAnsiString->QueryPtr())[iStrLen] = '\0'; + } + else + { + iStrLen = -1; + } + + return iStrLen; +} + +// static +HRESULT +STRA::ConvertUnicodeToMultiByte( + __in_ecount(dwStringLen) + LPCWSTR pszSrcUnicodeString, + __in BUFFER_T * pbufDstAnsiString, + __in DWORD dwStringLen +) +{ + return ConvertUnicodeToCodePage( pszSrcUnicodeString, + pbufDstAnsiString, + dwStringLen, + CP_ACP ); +} + +// static +HRESULT +STRA::ConvertUnicodeToUTF8( + __in_ecount(dwStringLen) + LPCWSTR pszSrcUnicodeString, + __in BUFFER_T * pbufDstAnsiString, + __in DWORD dwStringLen +) +{ + return ConvertUnicodeToCodePage( pszSrcUnicodeString, + pbufDstAnsiString, + dwStringLen, + CP_UTF8 ); +} + +/*++ + +Routine Description: + + Removes leading and trailing whitespace + +--*/ + +VOID +STRA::Trim() +{ + PSTR pszString = QueryStr(); + DWORD cchNewLength = m_cchLen; + DWORD cchLeadingWhitespace = 0; + DWORD cchTempLength = 0; + + for (LONG ixString = m_cchLen - 1; ixString >= 0; ixString--) + { + if (isspace((unsigned char) pszString[ixString]) != 0) + { + pszString[ixString] = '\0'; + cchNewLength--; + } + else + { + break; + } + } + + cchTempLength = cchNewLength; + for (DWORD ixString = 0; ixString < cchTempLength; ixString++) + { + if (isspace((unsigned char) pszString[ixString]) != 0) + { + cchLeadingWhitespace++; + cchNewLength--; + } + else + { + break; + } + } + + if (cchNewLength == 0) + { + + Reset(); + } + else if (cchLeadingWhitespace > 0) + { + memmove(pszString, pszString + cchLeadingWhitespace, cchNewLength * sizeof(CHAR)); + pszString[cchNewLength] = '\0'; + } + + SyncWithBuffer(); +} + +/*++ + +Routine Description: + + Compares the string to the provided prefix to check for equality + +Arguments: + + pStraPrefix - string to compare with + fIgnoreCase - indicates whether the string comparison should be case-sensitive + +Return Value: + + TRUE if prefix string matches with internal string, FALSE otherwise + +--*/ +BOOL +STRA::StartsWith( + __in const STRA * pStraPrefix, + __in bool fIgnoreCase) const +{ + _ASSERTE( pStraPrefix != NULL ); + return StartsWith(pStraPrefix->QueryStr(), fIgnoreCase); +} + +/*++ + +Routine Description: + + Compares the string to the provided prefix to check for equality + +Arguments: + + straPrefix - string to compare with + fIgnoreCase - indicates whether the string comparison should be case-sensitive + +Return Value: + + TRUE if prefix string matches with internal string, FALSE otherwise + +--*/ +BOOL +STRA::StartsWith( + __in const STRA & straPrefix, + __in bool fIgnoreCase) const +{ + return StartsWith(straPrefix.QueryStr(), fIgnoreCase); +} + +/*++ + +Routine Description: + + Compares the string to the provided prefix to check for equality + +Arguments: + + pszPrefix - string to compare with + fIgnoreCase - indicates whether the string comparison should be case-sensitive + +Return Value: + + TRUE if prefix string matches with internal string, FALSE otherwise + +--*/ +BOOL +STRA::StartsWith( + __in PCSTR pszPrefix, + __in bool fIgnoreCase) const +{ + HRESULT hr = S_OK; + BOOL fMatch = FALSE; + size_t cchPrefix = 0; + + if (pszPrefix == NULL) + { + goto Finished; + } + + hr = StringCchLengthA( pszPrefix, + STRSAFE_MAX_CCH, + &cchPrefix ); + if (FAILED(hr)) + { + goto Finished; + } + + _ASSERTE( cchPrefix <= MAXDWORD ); + + if (cchPrefix > m_cchLen) + { + goto Finished; + } + + if( fIgnoreCase ) + { + fMatch = ( 0 == _strnicmp( QueryStr(), pszPrefix, cchPrefix ) ); + } + else + { + fMatch = ( 0 == strncmp( QueryStr(), pszPrefix, cchPrefix ) ); + } + + +Finished: + + return fMatch; +} + +/*++ + +Routine Description: + + Compares the string to the provided suffix to check for equality + +Arguments: + + pStraSuffix - string to compare with + fIgnoreCase - indicates whether the string comparison should be case-sensitive + +Return Value: + + TRUE if suffix string matches with internal string, FALSE otherwise + +--*/ +BOOL +STRA::EndsWith( + __in const STRA * pStraSuffix, + __in bool fIgnoreCase) const +{ + _ASSERTE( pStraSuffix != NULL ); + return EndsWith(pStraSuffix->QueryStr(), fIgnoreCase); +} + + +/*++ + +Routine Description: + + Compares the string to the provided suffix to check for equality + +Arguments: + + straSuffix - string to compare with + fIgnoreCase - indicates whether the string comparison should be case-sensitive + +Return Value: + + TRUE if suffix string matches with internal string, FALSE otherwise + +--*/ +BOOL +STRA::EndsWith( + __in const STRA & straSuffix, + __in bool fIgnoreCase) const +{ + return EndsWith(straSuffix.QueryStr(), fIgnoreCase); +} + + +/*++ + +Routine Description: + + Compares the string to the provided suffix to check for equality + +Arguments: + + pszSuffix - string to compare with + fIgnoreCase - indicates whether the string comparison should be case-sensitive + +Return Value: + + TRUE if suffix string matches with internal string, FALSE otherwise + +--*/ +BOOL +STRA::EndsWith( + __in PCSTR pszSuffix, + __in bool fIgnoreCase) const +{ + HRESULT hr = S_OK; + PSTR pszString = QueryStr(); + BOOL fMatch = FALSE; + size_t cchSuffix = 0; + ptrdiff_t ixOffset = 0; + + if (pszSuffix == NULL) + { + goto Finished; + } + + hr = StringCchLengthA( pszSuffix, + STRSAFE_MAX_CCH, + &cchSuffix ); + if (FAILED(hr)) + { + goto Finished; + } + + _ASSERTE( cchSuffix <= MAXDWORD ); + + if (cchSuffix > m_cchLen) + { + goto Finished; + } + + ixOffset = m_cchLen - cchSuffix; + _ASSERTE(ixOffset >= 0 && ixOffset <= MAXDWORD); + + if( fIgnoreCase ) + { + fMatch = ( 0 == _strnicmp( pszString + ixOffset, pszSuffix, cchSuffix ) ); + } + else + { + fMatch = ( 0 == strncmp( pszString + ixOffset, pszSuffix, cchSuffix ) ); + } + +Finished: + + return fMatch; +} + + +/*++ + +Routine Description: + + Searches the string for the first occurrence of the specified character. + +Arguments: + + charValue - character to find + dwStartIndex - the initial index. + +Return Value: + + The index for the first character occurence in the string. + + -1 if not found. + +--*/ +INT +STRA::IndexOf( + __in CHAR charValue, + __in DWORD dwStartIndex + ) const +{ + INT nIndex = -1; + + // Make sure that there are no buffer overruns. + if( dwStartIndex >= QueryCCH() ) + { + goto Finished; + } + + const CHAR* pChar = strchr( QueryStr() + dwStartIndex, charValue ); + + // Determine the index if found + if( pChar ) + { + // nIndex will be set to -1 on failure. + (VOID)SizeTToInt( pChar - QueryStr(), &nIndex ); + } + +Finished: + + return nIndex; +} + + +/*++ + +Routine Description: + + Searches the string for the first occurrence of the specified substring. + +Arguments: + + pszValue - substring to find + dwStartIndex - initial index. + +Return Value: + + The index for the first character occurence in the string. + + -1 if not found. + +--*/ +INT +STRA::IndexOf( + __in PCSTR pszValue, + __in DWORD dwStartIndex + ) const +{ + HRESULT hr = S_OK; + INT nIndex = -1; + SIZE_T cchValue = 0; + + // Validate input parameters + if( dwStartIndex >= QueryCCH() || !pszValue ) + { + goto Finished; + } + + const CHAR* pChar = strstr( QueryStr() + dwStartIndex, pszValue ); + + // Determine the index if found + if( pChar ) + { + // nIndex will be set to -1 on failure. + (VOID)SizeTToInt( pChar - QueryStr(), &nIndex ); + } + +Finished: + + return nIndex; +} + + +/*++ + +Routine Description: + + Searches the string for the last occurrence of the specified character. + +Arguments: + + charValue - character to find + dwStartIndex - initial index. + +Return Value: + + The index for the last character occurence in the string. + + -1 if not found. + +--*/ +INT +STRA::LastIndexOf( + __in CHAR charValue, + __in DWORD dwStartIndex + ) const +{ + INT nIndex = -1; + + // Make sure that there are no buffer overruns. + if( dwStartIndex >= QueryCCH() ) + { + goto Finished; + } + + const CHAR* pChar = strrchr( QueryStr() + dwStartIndex, charValue ); + + // Determine the index if found + if( pChar ) + { + // nIndex will be set to -1 on failure. + (VOID)SizeTToInt( pChar - QueryStr(), &nIndex ); + } + +Finished: + + return nIndex; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/stringu.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/stringu.cpp new file mode 100644 index 0000000000..4fd2a052f2 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/stringu.cpp @@ -0,0 +1,1289 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +STRU::STRU( + VOID +) : m_cchLen( 0 ) +{ + *(QueryStr()) = L'\0'; +} + +STRU::STRU( + __inout_ecount(cchInit) WCHAR* pbInit, + __in DWORD cchInit +) : m_Buff( pbInit, cchInit * sizeof( WCHAR ) ), + m_cchLen( 0 ) +/*++ + Description: + + Used by STACK_STRU. Initially populates underlying buffer with pbInit. + + pbInit is not freed. + + Arguments: + + pbInit - initial memory to use + cchInit - count, in characters, of pbInit + + Returns: + + None. + +--*/ +{ + _ASSERTE( cchInit <= (MAXDWORD / sizeof( WCHAR )) ); + _ASSERTE( NULL != pbInit ); + _ASSERTE(cchInit > 0 ); + _ASSERTE(pbInit[0] == L'\0'); +} + +BOOL +STRU::IsEmpty( + VOID +) const +{ + return ( m_cchLen == 0 ); +} + +DWORD +STRU::QueryCB( + VOID +) const +// +// Returns the number of bytes in the string excluding the terminating NULL +// +{ + return m_cchLen * sizeof( WCHAR ); +} + +DWORD +STRU::QueryCCH( + VOID +) const +// +// Returns the number of characters in the string excluding the terminating NULL +// +{ + return m_cchLen; +} + +DWORD +STRU::QuerySizeCCH( + VOID +) const +// +// Returns size of the underlying storage buffer, in characters +// +{ + return m_Buff.QuerySize() / sizeof( WCHAR ); +} + +__nullterminated +__ecount(this->m_cchLen) +WCHAR* +STRU::QueryStr( + VOID +) const +// +// Return the string buffer +// +{ + return m_Buff.QueryPtr(); +} + +VOID +STRU::Reset( + VOID +) +// +// Resets the internal string to be NULL string. Buffer remains cached. +// +{ + _ASSERTE( QueryStr() != NULL ); + *(QueryStr()) = L'\0'; + m_cchLen = 0; +} + +HRESULT +STRU::Resize( + DWORD cchSize +) +{ + SIZE_T cbSize = cchSize * sizeof( WCHAR ); + if ( cbSize > MAXDWORD ) + { + return HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW ); + } + if( !m_Buff.Resize( cbSize ) ) + { + return E_OUTOFMEMORY; + } + + return S_OK; +} + +HRESULT +STRU::SyncWithBuffer( + VOID +) +// +// Recalculate the length of the string, etc. because we've modified +// the buffer directly. +// +{ + HRESULT hr; + size_t size; + hr = StringCchLengthW( QueryStr(), + QuerySizeCCH(), + &size ); + if ( SUCCEEDED( hr ) ) + { + m_cchLen = static_cast(size); + } + return hr; +} + +HRESULT +STRU::Copy( + __in PCWSTR pszCopy +) +{ + HRESULT hr; + size_t cbStr; + + hr = StringCchLengthW( pszCopy, + STRSAFE_MAX_CCH, + &cbStr ); + if ( FAILED( hr ) ) + { + return hr; + } + + _ASSERTE( cbStr <= MAXDWORD ); + return Copy( pszCopy, + cbStr ); +} + +HRESULT +STRU::Copy( + __in_ecount(cchLen) + PCWSTR pszCopy, + SIZE_T cchLen +) +// +// Copy the contents of another string to this one +// +{ + return AuxAppend( pszCopy, + cchLen * sizeof(WCHAR), + 0); +} + +HRESULT +STRU::Copy( + __in const STRU * pstrRhs +) +{ + _ASSERTE( NULL != pstrRhs ); + return Copy( pstrRhs->QueryStr(), pstrRhs->QueryCCH() ); +} + +HRESULT +STRU::Copy( + __in const STRU & str +) +{ + return Copy( str.QueryStr(), str.QueryCCH() ); +} + +HRESULT +STRU::CopyAndExpandEnvironmentStrings( + __in PCWSTR pszSource +) +{ + HRESULT hr = S_OK; + DWORD cchDestReqBuff = 0; + + Reset(); + + cchDestReqBuff = ExpandEnvironmentStringsW( pszSource, + QueryStr(), + QuerySizeCCH() ); + if ( cchDestReqBuff == 0 ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Finished; + } + else if ( cchDestReqBuff > QuerySizeCCH() ) + { + hr = Resize( cchDestReqBuff ); + if ( FAILED( hr ) ) + { + goto Finished; + } + + cchDestReqBuff = ExpandEnvironmentStringsW( pszSource, + QueryStr(), + QuerySizeCCH() ); + + if ( cchDestReqBuff == 0 || cchDestReqBuff > QuerySizeCCH() ) + { + _ASSERTE( FALSE ); + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Finished; + } + } + + hr = SyncWithBuffer(); + if ( FAILED( hr ) ) + { + goto Finished; + } + +Finished: + + return hr; + +} + +HRESULT +STRU::CopyA( + __in PCSTR pszCopyA +) +{ + HRESULT hr; + size_t cbStr; + + hr = StringCbLengthA( pszCopyA, + STRSAFE_MAX_CCH, + &cbStr ); + if ( FAILED( hr ) ) + { + return hr; + } + + _ASSERTE( cbStr <= MAXDWORD ); + return CopyA( pszCopyA, + cbStr ); +} + +HRESULT +STRU::CopyA( + __in_bcount(cchLen) + PCSTR pszCopyA, + SIZE_T cchLen, + UINT CodePage /*= CP_UTF8*/ +) +{ + return AuxAppendA( + pszCopyA, + cchLen, + 0, + CodePage + ); +} + +HRESULT +STRU::Append( + __in PCWSTR pszAppend +) +{ + HRESULT hr; + size_t cbStr; + + hr = StringCchLengthW( pszAppend, + STRSAFE_MAX_CCH, + &cbStr ); + if ( FAILED( hr ) ) + { + return hr; + } + + _ASSERTE( cbStr <= MAXDWORD ); + return Append( pszAppend, + cbStr ); +} + +HRESULT +STRU::Append( + __in_ecount(cchLen) + PCWSTR pszAppend, + SIZE_T cchLen +) +// +// Append something to the end of the string +// +{ + if ( cchLen == 0 ) + { + return S_OK; + } + return AuxAppend( pszAppend, + cchLen * sizeof(WCHAR), + QueryCB() ); +} + +HRESULT +STRU::Append( + __in const STRU * pstrRhs +) +{ + _ASSERTE( NULL != pstrRhs ); + return Append( pstrRhs->QueryStr(), pstrRhs->QueryCCH() ); +} + +HRESULT +STRU::Append( + __in const STRU & strRhs +) +{ + return Append( strRhs.QueryStr(), strRhs.QueryCCH() ); +} + +HRESULT +STRU::AppendA( + __in PCSTR pszAppendA +) +{ + HRESULT hr; + size_t cbStr; + + hr = StringCbLengthA( pszAppendA, + STRSAFE_MAX_CCH, + &cbStr ); + if ( FAILED( hr ) ) + { + return hr; + } + + _ASSERTE( cbStr <= MAXDWORD ); + return AppendA( pszAppendA, + cbStr ); +} + +HRESULT +STRU::AppendA( + __in_bcount(cchLen) + PCSTR pszAppendA, + SIZE_T cchLen, + UINT CodePage /*= CP_UTF8*/ +) +{ + if ( cchLen == 0 ) + { + return S_OK; + } + return AuxAppendA( + pszAppendA, + cchLen, + QueryCB(), + CodePage + ); +} + +HRESULT +STRU::CopyToBuffer( + __out_bcount(*pcb) WCHAR* pszBuffer, + PDWORD pcb +) const +// +// Makes a copy of the stored string into the given buffer +// +{ + _ASSERTE( NULL != pszBuffer ); + _ASSERTE( NULL != pcb ); + + HRESULT hr = S_OK; + DWORD cbNeeded = QueryCB() + sizeof( WCHAR ); + + if( *pcb < cbNeeded ) + { + hr = HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ); + goto Finished; + } + + // + // BUGBUG: StringCchCopy? + // + memcpy( pszBuffer, QueryStr(), cbNeeded ); + +Finished: + + *pcb = cbNeeded; + + return hr; +} + +HRESULT +STRU::CopyToBufferA( + __out_bcount(*pcb) CHAR* pszBuffer, + __inout PDWORD pcb +) const +{ + HRESULT hr = S_OK; + STACK_STRA( straBuffer, 256 ); + hr = straBuffer.CopyW( QueryStr() ); + if ( FAILED( hr ) ) + { + goto Finished; + } + hr = straBuffer.CopyToBuffer( pszBuffer, pcb ); + if ( FAILED( hr ) ) + { + goto Finished; + } +Finished: + return hr; +} + +HRESULT +STRU::SetLen( + __in DWORD cchLen +) +/*++ + * +Routine Description: + + Set the length of the string and null terminate, if there + is sufficient buffer already allocated. Will not reallocate. + +Arguments: + + cchLen - The number of characters in the new string. + +Return Value: + + HRESULT + +--*/ +{ + if( cchLen >= QuerySizeCCH() ) + { + return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + } + + *( QueryStr() + cchLen ) = L'\0'; + m_cchLen = cchLen; + + return S_OK; +} + +HRESULT +STRU::SafeSnwprintf( + __in PCWSTR pwszFormatString, + ... +) +/*++ + +Routine Description: + + Writes to a STRU, growing it as needed. It arbitrarily caps growth at 64k chars. + +Arguments: + + pwszFormatString - printf format + ... - printf args + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + va_list argsList; + va_start( argsList, pwszFormatString ); + + hr = SafeVsnwprintf(pwszFormatString, argsList); + + va_end( argsList ); + return hr; +} + +HRESULT +STRU::SafeVsnwprintf( + __in PCWSTR pwszFormatString, + va_list argsList +) +/*++ + +Routine Description: + + Writes to a STRU, growing it as needed. It arbitrarily caps growth at 64k chars. + +Arguments: + + pwszFormatString - printf format + argsList - printf va_list + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + int cchOutput; + int cchNeeded; + + // + // Format the incoming message using vsnprintf() + // so that the overflows are captured + // + cchOutput = _vsnwprintf_s( + QueryStr(), + QuerySizeCCH(), + QuerySizeCCH() - 1, + pwszFormatString, + argsList + ); + + if( cchOutput == -1 ) + { + // + // Couldn't fit this in the original STRU size. + // + cchNeeded = _vscwprintf( pwszFormatString, argsList ); + if( cchNeeded > 64 * 1024 ) + { + // + // If we're trying to produce a string > 64k chars, then + // there is probably a problem + // + hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + goto Finished; + } + + // + // _vscprintf doesn't include terminating null character + // + cchNeeded++; + + hr = Resize( cchNeeded ); + if( FAILED( hr ) ) + { + goto Finished; + } + + cchOutput = _vsnwprintf_s( + QueryStr(), + QuerySizeCCH(), + QuerySizeCCH() - 1, + pwszFormatString, + argsList + ); + if( -1 == cchOutput ) + { + // + // This should never happen, cause we should already have correctly sized memory + // + _ASSERTE( FALSE ); + + hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + goto Finished; + } + } + + // + // always null terminate at the last WCHAR + // + QueryStr()[ QuerySizeCCH() - 1 ] = L'\0'; + + // + // we directly touched the buffer - therefore: + // + hr = SyncWithBuffer(); + if ( FAILED( hr ) ) + { + goto Finished; + } + +Finished: + + if( FAILED( hr ) ) + { + Reset(); + } + + return hr; +} + +HRESULT +STRU::AuxAppend( + __in_ecount(cNumStrings) + PCWSTR const rgpszStrings[], + SIZE_T cNumStrings +) +/*++ + +Routine Description: + + Appends an array of strings of length cNumStrings + +Arguments: + + rgStrings - The array of strings to be appened + cNumStrings - The count of String + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + size_t cbStringsTotal = sizeof( WCHAR ); // Account for null-terminator + + // + // Compute total size of the string. + // Resize internal buffer + // Copy each array element one by one to backing buffer + // Update backing buffer string length + // + for ( SIZE_T i = 0; i < cNumStrings; i++ ) + { + _ASSERTE( rgpszStrings[ i ] != NULL ); + if ( NULL == rgpszStrings[ i ] ) + { + return E_INVALIDARG; + } + + size_t cbString = 0; + + hr = StringCbLengthW( rgpszStrings[ i ], + STRSAFE_MAX_CCH * sizeof( WCHAR ), + &cbString ); + if ( FAILED( hr ) ) + { + return hr; + } + + cbStringsTotal += cbString; + + if ( cbStringsTotal > MAXDWORD ) + { + return HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW ); + } + } + + size_t cbBufSizeRequired = QueryCB() + cbStringsTotal; + if ( cbBufSizeRequired > MAXDWORD ) + { + return HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW ); + } + + if( m_Buff.QuerySize() < cbBufSizeRequired ) + { + if( !m_Buff.Resize( cbBufSizeRequired ) ) + { + return E_OUTOFMEMORY; + } + } + + STRSAFE_LPWSTR pszStringEnd = QueryStr() + QueryCCH(); + size_t cchRemaining = QuerySizeCCH() - QueryCCH(); + for ( SIZE_T i = 0; i < cNumStrings; i++ ) + { + hr = StringCchCopyExW( pszStringEnd, // pszDest + cchRemaining, // cchDest + rgpszStrings[ i ], // pszSrc + &pszStringEnd, // ppszDestEnd + &cchRemaining, // pcchRemaining + 0 ); // dwFlags + if ( FAILED( hr ) ) + { + _ASSERTE( FALSE ); + HRESULT hr2 = SyncWithBuffer(); + if ( FAILED( hr2 ) ) + { + return hr2; + } + return hr; + } + } + + m_cchLen = static_cast< DWORD >( cbBufSizeRequired ) / sizeof( WCHAR ) - 1; + + return S_OK; +} + +HRESULT +STRU::AuxAppend( + __in_bcount(cbStr) + const WCHAR* pStr, + SIZE_T cbStr, + DWORD cbOffset +) +/*++ + +Routine Description: + + Appends to the string starting at the (byte) offset cbOffset. + +Arguments: + + pStr - A unicode string to be appended + cbStr - Length, in bytes, of pStr + cbOffset - Offset, in bytes, at which to begin the append + +Return Value: + + HRESULT + +--*/ +{ + _ASSERTE( NULL != pStr ); + _ASSERTE( 0 == cbStr % sizeof( WCHAR ) ); + _ASSERTE( cbOffset <= QueryCB() ); + _ASSERTE( 0 == cbOffset % sizeof( WCHAR ) ); + + ULONGLONG cb64NewSize = (ULONGLONG)cbOffset + cbStr + sizeof( WCHAR ); + if( cb64NewSize > MAXDWORD ) + { + return HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW ); + } + + if( m_Buff.QuerySize() < cb64NewSize ) + { + if( !m_Buff.Resize( static_cast(cb64NewSize) ) ) + { + return E_OUTOFMEMORY; + } + } + + memcpy( reinterpret_cast(m_Buff.QueryPtr()) + cbOffset, pStr, cbStr ); + + m_cchLen = (static_cast(cbStr) + cbOffset) / sizeof(WCHAR); + + *( QueryStr() + m_cchLen ) = L'\0'; + + return S_OK; +} + +HRESULT +STRU::AuxAppendA( + __in_bcount(cbStr) + const CHAR* pStr, + SIZE_T cbStr, + DWORD cbOffset, + UINT CodePage +) +/*++ + +Routine Description: + + Convert and append an ANSI string to the string starting at + the (byte) offset cbOffset + +Arguments: + + pStr - An ANSI string to be appended + cbStr - Length, in bytes, of pStr + cbOffset - Offset, in bytes, at which to begin the append + CodePage - code page to use for conversion + +Return Value: + + HRESULT + +--*/ +{ + WCHAR* pszBuffer; + DWORD cchBuffer; + DWORD cchCharsCopied = 0; + + _ASSERTE( NULL != pStr ); + _ASSERTE( cbOffset <= QueryCB() ); + _ASSERTE( 0 == cbOffset % sizeof( WCHAR ) ); + + if ( NULL == pStr ) + { + return E_INVALIDARG; + } + + if( 0 == cbStr ) + { + return S_OK; + } + + // + // Only resize when we have to. When we do resize, we tack on + // some extra space to avoid extra reallocations. + // + if( m_Buff.QuerySize() < (ULONGLONG)cbOffset + (cbStr * sizeof( WCHAR )) + sizeof(WCHAR) ) + { + ULONGLONG cb64NewSize = (ULONGLONG)( cbOffset + cbStr * sizeof(WCHAR) + sizeof( WCHAR ) ); + + // + // Check for the arithmetic overflow + // + if( cb64NewSize > MAXDWORD ) + { + return HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW ); + } + + if( !m_Buff.Resize( static_cast(cb64NewSize) ) ) + { + return E_OUTOFMEMORY; + } + } + + pszBuffer = reinterpret_cast(reinterpret_cast(m_Buff.QueryPtr()) + cbOffset); + cchBuffer = ( m_Buff.QuerySize() - cbOffset - sizeof( WCHAR ) ) / sizeof( WCHAR ); + + cchCharsCopied = MultiByteToWideChar( + CodePage, + MB_ERR_INVALID_CHARS, + pStr, + static_cast(cbStr), + pszBuffer, + cchBuffer + ); + if( 0 == cchCharsCopied ) + { + return HRESULT_FROM_WIN32( GetLastError() ); + } + + // + // set the new length + // + m_cchLen = cchCharsCopied + cbOffset/sizeof(WCHAR); + + // + // Must be less than, cause still need to add NULL + // + _ASSERTE( m_cchLen < QuerySizeCCH() ); + + // + // append NULL character + // + *(QueryStr() + m_cchLen) = L'\0'; + + return S_OK; +} + + +/*++ + +Routine Description: + + Removes leading and trailing whitespace + +--*/ + +VOID +STRU::Trim() +{ + PWSTR pwszString = QueryStr(); + DWORD cchNewLength = m_cchLen; + DWORD cchLeadingWhitespace = 0; + DWORD cchTempLength = 0; + + for (LONG ixString = m_cchLen - 1; ixString >= 0; ixString--) + { + if (iswspace(pwszString[ixString]) != 0) + { + pwszString[ixString] = L'\0'; + cchNewLength--; + } + else + { + break; + } + } + + cchTempLength = cchNewLength; + for (DWORD ixString = 0; ixString < cchTempLength; ixString++) + { + if (iswspace(pwszString[ixString]) != 0) + { + cchLeadingWhitespace++; + cchNewLength--; + } + else + { + break; + } + } + + if (cchNewLength == 0) + { + + Reset(); + } + else if (cchLeadingWhitespace > 0) + { + memmove(pwszString, pwszString + cchLeadingWhitespace, cchNewLength * sizeof(WCHAR)); + pwszString[cchNewLength] = L'\0'; + } + + SyncWithBuffer(); +} + +/*++ + +Routine Description: + + Compares the string to the provided prefix to check for equality + +Arguments: + + pwszPrefix - wide char string to compare with + fIgnoreCase - indicates whether the string comparison should be case-sensitive + +Return Value: + + TRUE if prefix string matches with internal string, FALSE otherwise + +--*/ + +BOOL +STRU::StartsWith( + __in PCWSTR pwszPrefix, + __in bool fIgnoreCase) const +{ + HRESULT hr = S_OK; + BOOL fMatch = FALSE; + size_t cchPrefix = 0; + + if (pwszPrefix == NULL) + { + goto Finished; + } + + hr = StringCchLengthW( pwszPrefix, + STRSAFE_MAX_CCH, + &cchPrefix ); + if (FAILED(hr)) + { + goto Finished; + } + + _ASSERTE( cchPrefix <= MAXLONG ); + + if (cchPrefix > m_cchLen) + { + goto Finished; + } + + #if defined( NTDDI_VERSION ) && NTDDI_VERSION >= NTDDI_LONGHORN + + fMatch = ( CSTR_EQUAL == CompareStringOrdinal( QueryStr(), + (int)cchPrefix, + pwszPrefix, + (int)cchPrefix, + fIgnoreCase ) ); + #else + + if( fIgnoreCase ) + { + fMatch = ( 0 == _wcsnicmp( QueryStr(), pwszPrefix, cchPrefix ) ); + } + else + { + fMatch = ( 0 == wcsncmp( QueryStr(), pwszPrefix, cchPrefix ) ); + } + + #endif + +Finished: + + return fMatch; +} + +/*++ + +Routine Description: + + Compares the string to the provided suffix to check for equality + +Arguments: + + pwszSuffix - wide char string to compare with + fIgnoreCase - indicates whether the string comparison should be case-sensitive + +Return Value: + + TRUE if suffix string matches with internal string, FALSE otherwise + +--*/ + + +BOOL +STRU::EndsWith( + __in PCWSTR pwszSuffix, + __in bool fIgnoreCase) const +{ + HRESULT hr = S_OK; + PWSTR pwszString = QueryStr(); + BOOL fMatch = FALSE; + size_t cchSuffix = 0; + ptrdiff_t ixOffset = 0; + + if (pwszSuffix == NULL) + { + goto Finished; + } + + hr = StringCchLengthW( pwszSuffix, + STRSAFE_MAX_CCH, + &cchSuffix ); + if (FAILED(hr)) + { + goto Finished; + } + + _ASSERTE( cchSuffix <= MAXLONG ); + + if (cchSuffix > m_cchLen) + { + goto Finished; + } + + ixOffset = m_cchLen - cchSuffix; + _ASSERTE(ixOffset >= 0 && ixOffset <= MAXDWORD); + + #if defined( NTDDI_VERSION ) && NTDDI_VERSION >= NTDDI_LONGHORN + + fMatch = ( CSTR_EQUAL == CompareStringOrdinal( pwszString + ixOffset, + (int)cchSuffix, + pwszSuffix, + (int)cchSuffix, + fIgnoreCase ) ); + #else + + if( fIgnoreCase ) + { + fMatch = ( 0 == _wcsnicmp( pwszString + ixOffset, pwszSuffix, cchSuffix ) ); + } + else + { + fMatch = ( 0 == wcsncmp( pwszString + ixOffset, pwszSuffix, cchSuffix ) ); + } + + #endif + +Finished: + + return fMatch; +} + +/*++ + +Routine Description: + + Searches the string for the first occurrence of the specified character. + +Arguments: + + charValue - character to find + dwStartIndex - the initial index. + +Return Value: + + The index for the first character occurence in the string. + + -1 if not found. + +--*/ +INT +STRU::IndexOf( + __in WCHAR charValue, + __in DWORD dwStartIndex + ) const +{ + INT nIndex = -1; + + // Make sure that there are no buffer overruns. + if( dwStartIndex >= QueryCCH() ) + { + goto Finished; + } + + const WCHAR* pwChar = wcschr( QueryStr() + dwStartIndex, charValue ); + + // Determine the index if found + if( pwChar ) + { + // nIndex will be set to -1 on failure. + (VOID)SizeTToInt( pwChar - QueryStr(), &nIndex ); + } + +Finished: + + return nIndex; +} + + +/*++ + +Routine Description: + + Searches the string for the first occurrence of the specified substring. + +Arguments: + + pwszValue - substring to find + dwStartIndex - initial index. + +Return Value: + + The index for the first character occurence in the string. + + -1 if not found. + +--*/ +INT +STRU::IndexOf( + __in PCWSTR pwszValue, + __in DWORD dwStartIndex + ) const +{ + HRESULT hr = S_OK; + INT nIndex = -1; + SIZE_T cchValue = 0; + + // Validate input parameters + if( dwStartIndex >= QueryCCH() || !pwszValue ) + { + goto Finished; + } + + const WCHAR* pwChar = wcsstr( QueryStr() + dwStartIndex, pwszValue ); + + // Determine the index if found + if( pwChar ) + { + // nIndex will be set to -1 on failure. + (VOID)SizeTToInt( pwChar - QueryStr(), &nIndex ); + } + +Finished: + + return nIndex; +} + + +/*++ + +Routine Description: + + Searches the string for the last occurrence of the specified character. + +Arguments: + + charValue - character to find + dwStartIndex - initial index. + +Return Value: + + The index for the last character occurence in the string. + + -1 if not found. + +--*/ +INT +STRU::LastIndexOf( + __in WCHAR charValue, + __in DWORD dwStartIndex + ) const +{ + INT nIndex = -1; + + // Make sure that there are no buffer overruns. + if( dwStartIndex >= QueryCCH() ) + { + goto Finished; + } + + const WCHAR* pwChar = wcsrchr( QueryStr() + dwStartIndex, charValue ); + + // Determine the index if found + if( pwChar ) + { + // nIndex will be set to -1 on failure. + (VOID)SizeTToInt( pwChar - QueryStr(), &nIndex ); + } + +Finished: + + return nIndex; +} + +//static +HRESULT +STRU::ExpandEnvironmentVariables( + __in PCWSTR pszString, + __out STRU * pstrExpandedString + ) +/*++ + +Routine Description: + + Expand the environment variables in a string + +Arguments: + + pszString - String with environment variables to expand + pstrExpandedString - Receives expanded string on success + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + DWORD cchNewSize = 0; + + if ( pszString == NULL || + pstrExpandedString == NULL ) + { + DBG_ASSERT( FALSE ); + hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + goto Exit; + } + + cchNewSize = ExpandEnvironmentStrings( pszString, + pstrExpandedString->QueryStr(), + pstrExpandedString->QuerySizeCCH() ); + if ( cchNewSize == 0 ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Exit; + } + + if ( cchNewSize > pstrExpandedString->QuerySizeCCH() ) + { + hr = pstrExpandedString->Resize( + ( cchNewSize + 1 ) * sizeof( WCHAR ) + ); + if ( FAILED( hr ) ) + { + goto Exit; + } + + cchNewSize = ExpandEnvironmentStrings( + pszString, + pstrExpandedString->QueryStr(), + pstrExpandedString->QuerySizeCCH() + ); + + if ( cchNewSize == 0 || + cchNewSize > pstrExpandedString->QuerySizeCCH() ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Exit; + } + } + + pstrExpandedString->SyncWithBuffer(); + + hr = S_OK; + +Exit: + + return hr; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/ulparse.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/ulparse.cxx new file mode 100644 index 0000000000..69b42e6250 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/ulparse.cxx @@ -0,0 +1,1416 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +// +// BUGBUG: Turn off optimization on ia64 builds due to a compiler bug +// +#if (defined(_M_IA64) && (_MSC_FULL_VER == 13009286)) +#pragma optimize("",off) +#endif + +#define LF 0x0A +#define SP 0x20 +#define HT 0x09 + +#define HTTP_CHAR 0x001 +#define HTTP_UPCASE 0x002 +#define HTTP_LOCASE 0x004 +#define HTTP_ALPHA (HTTP_UPCASE | HTTP_LOCASE) +#define HTTP_DIGIT 0x008 +#define HTTP_CTL 0x010 +#define HTTP_LWS 0x020 +#define HTTP_HEX 0x040 +#define HTTP_SEPERATOR 0x080 +#define HTTP_TOKEN 0x100 + +#define URL_LEGAL 0x200 +#define URL_TOKEN (HTTP_ALPHA | HTTP_DIGIT | URL_LEGAL) + +#define IS_HTTP_UPCASE(c) (HttpChars[(UCHAR)(c)] & HTTP_UPCASE) +#define IS_HTTP_LOCASE(c) (HttpChars[(UCHAR)(c)] & HTTP_UPCASE) +#define IS_HTTP_ALPHA(c) (HttpChars[(UCHAR)(c)] & HTTP_ALPHA) +#define IS_HTTP_DIGIT(c) (HttpChars[(UCHAR)(c)] & HTTP_DIGIT) +#define IS_HTTP_HEX(c) (HttpChars[(UCHAR)(c)] & HTTP_HEX) +#define IS_HTTP_CTL(c) (HttpChars[(UCHAR)(c)] & HTTP_CTL) +#define IS_HTTP_LWS(c) (HttpChars[(UCHAR)(c)] & HTTP_LWS) +#define IS_HTTP_SEPERATOR(c) (HttpChars[(UCHAR)(c)] & HTTP_SEPERATOR) +#define IS_HTTP_TOKEN(c) (HttpChars[(UCHAR)(c)] & HTTP_TOKEN) +#define IS_URL_TOKEN(c) (HttpChars[(UCHAR)(c)] & URL_TOKEN) + +// Some stuff not defined in VS SDK +#ifndef NT_SUCCESS +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif + +// Copied from ntstatus.h, otherwise we will have double definition for +// number of macros that are both in ntstatus.h and winnt.h +#ifndef STATUS_SUCCESS +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth +#endif +#ifndef STATUS_OBJECT_PATH_SYNTAX_BAD +#define STATUS_OBJECT_PATH_SYNTAX_BAD ((NTSTATUS)0xC000003BL) +#endif +#ifndef STATUS_OBJECT_PATH_INVALID +#define STATUS_OBJECT_PATH_INVALID ((NTSTATUS)0xC0000039L) +#endif +// +// Constant Declarations for UTF8 Encoding +// + +#define ASCII 0x007f + +#define UTF8_2_MAX 0x07ff // max UTF8 2-byte sequence (32 * 64 =2048) +#define UTF8_1ST_OF_2 0xc0 // 110x xxxx +#define UTF8_1ST_OF_3 0xe0 // 1110 xxxx +#define UTF8_1ST_OF_4 0xf0 // 1111 xxxx +#define UTF8_TRAIL 0x80 // 10xx xxxx + +#define HIGHER_6_BIT(u) ((u) >> 12) +#define MIDDLE_6_BIT(u) (((u) & 0x0fc0) >> 6) +#define LOWER_6_BIT(u) ((u) & 0x003f) + +#define BIT7(a) ((a) & 0x80) +#define BIT6(a) ((a) & 0x40) + +#define HIGH_SURROGATE_START 0xd800 +#define HIGH_SURROGATE_END 0xdbff +#define LOW_SURROGATE_START 0xdc00 +#define LOW_SURROGATE_END 0xdfff + +#define EMIT_CHAR(ch) \ + do { \ + pDest[0] = (ch); \ + pDest += 1; \ + BytesCopied += 2; \ + } while (0) + +typedef enum _URL_TYPE +{ + UrlTypeUtf8, + UrlTypeAnsi, + UrlTypeDbcs +} URL_TYPE; + +typedef enum _URL_PART +{ + Scheme, + HostName, + AbsPath, + QueryString + +} URL_PART; + +#define IS_UTF8_TRAILBYTE(ch) (((ch) & 0xc0) == 0x80) + +// +// These are copied from RTL NLS routines. +// + +#define DBCS_TABLE_SIZE 256 +extern PUSHORT NlsLeadByteInfo; + +#define LeadByteTable (*(PUSHORT *)NlsLeadByteInfo) +#define IS_LEAD_BYTE(c) (IsDBCSLeadByte(c)) + +ULONG HttpChars[256]; +USHORT FastPopChars[256]; +USHORT DummyPopChars[256]; +WCHAR FastUpcaseChars[256]; +BOOL g_UlEnableNonUTF8; +BOOL g_UlEnableDBCS; +BOOL g_UlFavorDBCS; + +// RtlNtStatusToDosError is nowhere defined, should be used through +// native code "reflection" +typedef ULONG (RTL_NT_STATUS_TO_DOS_ERROR_PROC)(NTSTATUS); +static RTL_NT_STATUS_TO_DOS_ERROR_PROC* rtlNtStatusToDosErrorProc = NULL; +static HMODULE lib = NULL; + +HRESULT +WIN32_FROM_NTSTATUS( + __in NTSTATUS status, + __out DWORD * pResult + ) +{ + HRESULT hr = S_OK; + if (pResult == NULL) + { + hr = E_INVALIDARG; + goto Finished; + } + if (lib == NULL) + { + lib = GetModuleHandle(L"Ntdll.dll"); + if (lib == NULL) + { + hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + goto Finished; + } + } + if (rtlNtStatusToDosErrorProc == NULL) + { + rtlNtStatusToDosErrorProc = + (RTL_NT_STATUS_TO_DOS_ERROR_PROC*)GetProcAddress( + lib, "RtlNtStatusToDosError"); + if (rtlNtStatusToDosErrorProc == NULL) + { + hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + goto Finished; + } + } + *pResult = rtlNtStatusToDosErrorProc(status); + +Finished: + return hr; +} + +NTSTATUS +Unescape( + IN PUCHAR pChar, + OUT PUCHAR pOutChar + ) + +{ + UCHAR Result, Digit; + + if (pChar[0] != '%' || + SAFEIsXDigit(pChar[1]) == FALSE || + SAFEIsXDigit(pChar[2]) == FALSE) + { + return STATUS_OBJECT_PATH_SYNTAX_BAD; + } + + // + // HexToChar() inlined + // + + // uppercase #1 + // + if (SAFEIsAlpha(pChar[1])) + Digit = (UCHAR) toupper(pChar[1]); + else + Digit = pChar[1]; + + Result = ((Digit >= 'A') ? (Digit - 'A' + 0xA) : (Digit - '0')) << 4; + + // uppercase #2 + // + if (SAFEIsAlpha(pChar[2])) + Digit = (UCHAR) toupper(pChar[2]); + else + Digit = pChar[2]; + + Result |= (Digit >= 'A') ? (Digit - 'A' + 0xA) : (Digit - '0'); + + *pOutChar = Result; + + return STATUS_SUCCESS; + +} // Unescape + +// +// PopChar is used only if the string is not UTF-8, or UrlPart != QueryString, +// or the current character is '%' or its high bit is set. In all other cases, +// the FastPopChars table is used for fast conversion. +// + +__inline +NTSTATUS +PopChar( + IN URL_TYPE UrlType, + IN URL_PART UrlPart, + __in LPSTR pChar, + __out WCHAR * pUnicodeChar, + __out WCHAR * pUnicodeChar2, + OUT PULONG pCharToSkip + ) +{ + NTSTATUS Status; + WCHAR UnicodeChar = L'\0'; + WCHAR UnicodeChar2 = L'\0'; + UCHAR Char; + UCHAR Trail1; + UCHAR Trail2; + UCHAR Trail3; + ULONG CharToSkip; + + // + // validate it as a valid url character + // + + if (UrlPart != QueryString) + { + if (IS_URL_TOKEN((UCHAR)pChar[0]) == FALSE) + { + Status = STATUS_OBJECT_PATH_SYNTAX_BAD; + goto end; + } + } + else + { + // + // Allow anything but linefeed in the query string. + // + + if (pChar[0] == LF) + { + Status = STATUS_OBJECT_PATH_SYNTAX_BAD; + goto end; + } + + UnicodeChar = (USHORT) (UCHAR)pChar[0]; + CharToSkip = 1; + + // skip all the decoding stuff + goto slash; + } + + // + // need to unescape ? + // + // can't decode the query string. that would be lossy decodeing + // as '=' and '&' characters might be encoded, but have meaning + // to the usermode parser. + // + + if (pChar[0] == '%') + { + Status = Unescape((PUCHAR)pChar, &Char); + if (NT_SUCCESS(Status) == FALSE) + goto end; + CharToSkip = 3; + } + else + { + Char = pChar[0]; + CharToSkip = 1; + } + + if (UrlType == UrlTypeUtf8) + { + // + // convert to unicode, checking for utf8 . + // + // 3 byte runs are the largest we can have. 16 bits in UCS-2 = + // 3 bytes of (4+4,2+6,2+6) where it's code + char. + // for a total of 6+6+4 char bits = 16 bits. + // + + // + // NOTE: we'll only bother to decode utf if it was escaped + // thus the (CharToSkip == 3) + // + if ((CharToSkip == 3) && ((Char & 0xf8) == 0xf0)) + { + // 4 byte run + // + + // Unescape the next 3 trail bytes + // + + Status = Unescape((PUCHAR)pChar+CharToSkip, &Trail1); + if (NT_SUCCESS(Status) == FALSE) + goto end; + + CharToSkip += 3; // %xx + + Status = Unescape((PUCHAR)pChar+CharToSkip, &Trail2); + if (NT_SUCCESS(Status) == FALSE) + goto end; + + CharToSkip += 3; // %xx + + Status = Unescape((PUCHAR)pChar+CharToSkip, &Trail3); + if (NT_SUCCESS(Status) == FALSE) + goto end; + + CharToSkip += 3; // %xx + + if (IS_UTF8_TRAILBYTE(Trail1) == FALSE || + IS_UTF8_TRAILBYTE(Trail2) == FALSE || + IS_UTF8_TRAILBYTE(Trail3) == FALSE) + { + // bad utf! + // + Status = STATUS_OBJECT_PATH_SYNTAX_BAD; + goto end; + } + + // handle four byte case - convert to utf-16 + // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + + UnicodeChar = ((USHORT) ((Char & 0x07) << 8) | + ((Trail1 & 0x3f) << 2) | + ((Trail2 & 0x30) >> 4)) + 0xD7C0; + UnicodeChar2 = ((USHORT) ((Trail2 & 0x0f) << 6) | + (Trail3 & 0x3f)) | 0xDC00; + } + else if ((CharToSkip == 3) && ((Char & 0xf0) == 0xe0)) + { + // 3 byte run + // + + // Unescape the next 2 trail bytes + // + + Status = Unescape((PUCHAR)pChar+CharToSkip, &Trail1); + if (NT_SUCCESS(Status) == FALSE) + goto end; + + CharToSkip += 3; // %xx + + Status = Unescape((PUCHAR)pChar+CharToSkip, &Trail2); + if (NT_SUCCESS(Status) == FALSE) + goto end; + + CharToSkip += 3; // %xx + + if (IS_UTF8_TRAILBYTE(Trail1) == FALSE || + IS_UTF8_TRAILBYTE(Trail2) == FALSE) + { + // bad utf! + // + Status = STATUS_OBJECT_PATH_SYNTAX_BAD; + goto end; + } + + // handle three byte case + // 1110xxxx 10xxxxxx 10xxxxxx + + UnicodeChar = (USHORT) (((Char & 0x0f) << 12) | + ((Trail1 & 0x3f) << 6) | + (Trail2 & 0x3f)); + + } + else if ((CharToSkip == 3) && ((Char & 0xe0) == 0xc0)) + { + // 2 byte run + // + + // Unescape the next 1 trail byte + // + + Status = Unescape((PUCHAR)pChar+CharToSkip, &Trail1); + if (NT_SUCCESS(Status) == FALSE) + goto end; + + CharToSkip += 3; // %xx + + if (IS_UTF8_TRAILBYTE(Trail1) == FALSE) + { + // bad utf! + // + Status = STATUS_OBJECT_PATH_SYNTAX_BAD; + goto end; + } + + // handle two byte case + // 110xxxxx 10xxxxxx + + UnicodeChar = (USHORT) (((Char & 0x1f) << 6) | + (Trail1 & 0x3f)); + + } + + // now this can either be unescaped high-bit (bad) + // or escaped high-bit. (also bad) + // + // thus not checking CharToSkip + // + + else if ((Char & 0x80) == 0x80) + { + // high bit set ! bad utf! + // + Status = STATUS_OBJECT_PATH_SYNTAX_BAD; + goto end; + + } + // + // Normal character (again either escaped or unescaped) + // + else + { + // + // Simple conversion to unicode, it's 7-bit ascii. + // + + UnicodeChar = (USHORT)Char; + } + + } + else // UrlType != UrlTypeUtf8 + { + UCHAR AnsiChar[2]; + ULONG AnsiCharSize; + + // + // Convert ANSI character to Unicode. + // If the UrlType is UrlTypeDbcs, then we may have + // a DBCS lead/trail pair. + // + + if (UrlType == UrlTypeDbcs && IS_LEAD_BYTE(Char)) + { + UCHAR SecondByte; + + // + // This is a double-byte character. + // + + SecondByte = *(pChar+CharToSkip); + + AnsiCharSize = 2; + AnsiChar[0] = Char; + + if (SecondByte == '%') + { + Status = Unescape((PUCHAR)pChar+CharToSkip, &AnsiChar[1]); + if (!NT_SUCCESS(Status)) + { + goto end; + } + + CharToSkip += 3; // %xx + } + else + { + AnsiChar[1] = SecondByte; + CharToSkip += 1; + } + + } + else + { + // + // This is a single-byte character. + // + + AnsiCharSize = 1; + AnsiChar[0] = Char; + + } + /* + Status = RtlMultiByteToUnicodeN( + &UnicodeChar, + sizeof(WCHAR), + NULL, + (PCHAR) &AnsiChar[0], + AnsiCharSize + ); + */ + Status = MultiByteToWideChar( + CP_ACP, + 0, + (PCHAR) &AnsiChar[0], + AnsiCharSize, + &UnicodeChar, + sizeof(WCHAR) + ); + + if (!NT_SUCCESS(Status)) + { + goto end; + } + } + + +slash: + // + // turn backslashes into forward slashes + // + + if (UrlPart != QueryString && UnicodeChar == L'\\') + { + UnicodeChar = L'/'; + } + else if (UnicodeChar == UNICODE_NULL) + { + // + // we pop'd a NULL. bad! + // + Status = STATUS_OBJECT_PATH_SYNTAX_BAD; + goto end; + } + + *pCharToSkip = CharToSkip; + *pUnicodeChar = UnicodeChar; + *pUnicodeChar2 = UnicodeChar2; + + Status = STATUS_SUCCESS; + +end: + return Status; + +} // PopChar + + +// +// Private constants. +// + +#define ACTION_NOTHING 0x00000000 +#define ACTION_EMIT_CH 0x00010000 +#define ACTION_EMIT_DOT_CH 0x00020000 +#define ACTION_EMIT_DOT_DOT_CH 0x00030000 +#define ACTION_BACKUP 0x00040000 +#define ACTION_MASK 0xFFFF0000 + +// +// Private globals +// + +// +// this table says what to do based on the current state and the current +// character +// +ULONG pActionTable[16] = +{ + // + // state 0 = fresh, seen nothing exciting yet + // + ACTION_EMIT_CH, // other = emit it state = 0 + ACTION_EMIT_CH, // "." = emit it state = 0 + ACTION_NOTHING, // EOS = normal finish state = 4 + ACTION_EMIT_CH, // "/" = we saw the "/", emit it state = 1 + + // + // state 1 = we saw a "/" ! + // + ACTION_EMIT_CH, // other = emit it, state = 0 + ACTION_NOTHING, // "." = eat it, state = 2 + ACTION_NOTHING, // EOS = normal finish state = 4 + ACTION_NOTHING, // "/" = extra slash, eat it, state = 1 + + // + // state 2 = we saw a "/" and ate a "." ! + // + ACTION_EMIT_DOT_CH, // other = emit the dot we ate. state = 0 + ACTION_NOTHING, // "." = eat it, a .. state = 3 + ACTION_NOTHING, // EOS = normal finish state = 4 + ACTION_NOTHING, // "/" = we ate a "/./", swallow it state = 1 + + // + // state 3 = we saw a "/" and ate a ".." ! + // + ACTION_EMIT_DOT_DOT_CH, // other = emit the "..". state = 0 + ACTION_EMIT_DOT_DOT_CH, // "." = 3 dots, emit the ".." state = 0 + ACTION_BACKUP, // EOS = we have a "/..\0", backup! state = 4 + ACTION_BACKUP // "/" = we have a "/../", backup! state = 1 +}; + +// +// this table says which newstate to be in given the current state and the +// character we saw +// +ULONG pNextStateTable[16] = +{ + // state 0 + 0 , // other + 0 , // "." + 4 , // EOS + 1 , // "\" + + // state 1 + 0 , // other + 2 , // "." + 4 , // EOS + 1 , // "\" + + // state 2 + 0 , // other + 3 , // "." + 4 , // EOS + 1 , // "\" + + // state 3 + 0 , // other + 0 , // "." + 4 , // EOS + 1 // "\" +}; + +// +// this says how to index into pNextStateTable given our current state. +// +// since max states = 4, we calculate the index by multiplying with 4. +// +#define IndexFromState( st) ( (st) * 4) + + +/***************************************************************************++ + +Routine Description: + + This function can be told to clean up UTF-8, ANSI, or DBCS URLs. + + Unescape + Convert backslash to forward slash + Remove double slashes (empty directiories names) - e.g. // or \\ + Handle /./ + Handle /../ + Convert to unicode + computes the case insensitive hash + +Arguments: + + +Return Value: + + NTSTATUS - Completion status. + + +--***************************************************************************/ +NTSTATUS +UlpCleanAndCopyUrlByType( + IN URL_TYPE UrlType, + IN URL_PART UrlPart, + __inout PWSTR pDestination, + __in_ecount(SourceLength) LPSTR pSource, + IN ULONG SourceLength, + OUT PULONG pBytesCopied, + __deref_opt_out_opt PWSTR * ppQueryString + ) +{ + NTSTATUS Status; + PWSTR pDest; + PUCHAR pChar; + ULONG CharToSkip; + ULONG BytesCopied; + PWSTR pQueryString; + ULONG StateIndex; + WCHAR UnicodeChar; + WCHAR UnicodeChar2 = L'\0'; + BOOLEAN MakeCanonical; + PUSHORT pFastPopChar; + + pDest = pDestination; + pQueryString = NULL; + BytesCopied = 0; + + pChar = (PUCHAR)pSource; + CharToSkip = 0; + + StateIndex = 0; + + MakeCanonical = (UrlPart == AbsPath) ? TRUE : FALSE; + + if (UrlType == UrlTypeUtf8 && UrlPart != QueryString) + { + pFastPopChar = FastPopChars; + } + else + { + pFastPopChar = DummyPopChars; + } + + while (SourceLength > 0) + { + // + // advance ! it's at the top of the loop to enable ANSI_NULL to + // come through ONCE + // + + pChar += CharToSkip; + SourceLength -= CharToSkip; + + // + // well? have we hit the end? + // + + if (SourceLength == 0) + { + UnicodeChar = UNICODE_NULL; + UnicodeChar2 = UNICODE_NULL; + } + else + { + // + // Nope. Peek briefly to see if we hit the query string + // + + if (UrlPart == AbsPath && pChar[0] == '?') + { + DBG_ASSERT(pQueryString == NULL); + + // + // remember it's location + // + + pQueryString = pDest; + + // + // let it fall through ONCE to the canonical + // in order to handle a trailing "/.." like + // "http://hostname:80/a/b/..?v=1&v2" + // + + UnicodeChar = L'?'; + UnicodeChar2 = UNICODE_NULL; + CharToSkip = 1; + + // + // now we are cleaning the query string + // + + UrlPart = QueryString; + + // + // cannot use fast path for PopChar anymore + // + + pFastPopChar = DummyPopChars; + } + else + { + USHORT NextUnicodeChar = pFastPopChar[*pChar]; + + // + // Grab the next character. Try to be fast for the + // normal character case. Otherwise call PopChar. + // + + if (NextUnicodeChar == 0) + { + Status = PopChar( + UrlType, + UrlPart, + (LPSTR)pChar, + &UnicodeChar, + &UnicodeChar2, + &CharToSkip + ); + + if (NT_SUCCESS(Status) == FALSE) + goto end; + } + else + { +#if DBG + Status = PopChar( + UrlType, + UrlPart, + (LPSTR)pChar, + &UnicodeChar, + &UnicodeChar2, + &CharToSkip + ); + + DBG_ASSERT(NT_SUCCESS(Status)); + DBG_ASSERT(UnicodeChar == NextUnicodeChar); + DBG_ASSERT(CharToSkip == 1); +#endif + UnicodeChar = NextUnicodeChar; + UnicodeChar2 = UNICODE_NULL; + CharToSkip = 1; + } + } + } + + if (MakeCanonical) + { + // + // now use the state machine to make it canonical . + // + + // + // from the old value of StateIndex, figure out our new base StateIndex + // + StateIndex = IndexFromState(pNextStateTable[StateIndex]); + + // + // did we just hit the query string? this will only happen once + // that we take this branch after hitting it, as we stop + // processing after hitting it. + // + + if (UrlPart == QueryString) + { + // + // treat this just like we hit a NULL, EOS. + // + + StateIndex += 2; + } + else + { + // + // otherwise based the new state off of the char we + // just popped. + // + + switch (UnicodeChar) + { + case UNICODE_NULL: StateIndex += 2; break; + case L'.': StateIndex += 1; break; + case L'/': StateIndex += 3; break; + default: StateIndex += 0; break; + } + } + + } + else + { + StateIndex = (UnicodeChar == UNICODE_NULL) ? 2 : 0; + } + + // + // Perform the action associated with the state. + // + + switch (pActionTable[StateIndex]) + { + case ACTION_EMIT_DOT_DOT_CH: + + EMIT_CHAR(L'.'); + + // fall through + + case ACTION_EMIT_DOT_CH: + + EMIT_CHAR(L'.'); + + // fall through + + case ACTION_EMIT_CH: + + EMIT_CHAR(UnicodeChar); + if (UnicodeChar2 != UNICODE_NULL) + { + EMIT_CHAR(UnicodeChar2); + } + + // fall through + + case ACTION_NOTHING: + break; + + case ACTION_BACKUP: + + // + // pDest currently points 1 past the last '/'. backup over it and + // find the preceding '/', set pDest to 1 past that one. + // + + // + // backup to the '/' + // + + pDest -= 1; + BytesCopied -= 2; + + DBG_ASSERT(pDest[0] == L'/'); + + // + // are we at the start of the string? that's bad, can't go back! + // + + if (pDest == pDestination) + { + DBG_ASSERT(BytesCopied == 0); + Status = STATUS_OBJECT_PATH_INVALID; + goto end; + } + + // + // back up over the '/' + // + + pDest -= 1; + BytesCopied -= 2; + + DBG_ASSERT(pDest > pDestination); + + // + // now find the previous slash + // + + while (pDest > pDestination && pDest[0] != L'/') + { + pDest -= 1; + BytesCopied -= 2; + } + + // + // we already have a slash, so don't have to store 1. + // + + DBG_ASSERT(pDest[0] == L'/'); + + // + // simply skip it, as if we had emitted it just now + // + + pDest += 1; + BytesCopied += 2; + + break; + + default: + DBG_ASSERT(!"http!UlpCleanAndCopyUrl: Invalid action code in state table!"); + Status = STATUS_OBJECT_PATH_SYNTAX_BAD; + goto end; + } + + // + // Just hit the query string ? + // + + if (MakeCanonical && UrlPart == QueryString) + { + // + // Stop canonical processing + // + + MakeCanonical = FALSE; + + // + // Need to emit the '?', it wasn't emitted above + // + + DBG_ASSERT(pActionTable[StateIndex] != ACTION_EMIT_CH); + + EMIT_CHAR(L'?'); + + } + + } + + // + // terminate the string, it hasn't been done in the loop + // + + DBG_ASSERT((pDest-1)[0] != UNICODE_NULL); + + pDest[0] = UNICODE_NULL; + *pBytesCopied = BytesCopied; + + if (ppQueryString != NULL) + { + *ppQueryString = pQueryString; + } + + Status = STATUS_SUCCESS; + + +end: + return Status; + +} // UlpCleanAndCopyUrlByType + + +/***************************************************************************++ + +Routine Description: + + + Unescape + Convert backslash to forward slash + Remove double slashes (empty directiories names) - e.g. // or \\ + Handle /./ + Handle /../ + Convert to unicode + +Arguments: + +Return Value: + + HRESULT + + +--***************************************************************************/ +HRESULT +UlCleanAndCopyUrl( + __in LPSTR pSource, + IN ULONG SourceLength, + OUT PULONG pBytesCopied, + __inout PWSTR pDestination, + __deref_opt_out_opt PWSTR * ppQueryString OPTIONAL + ) +{ + NTSTATUS Status; + URL_TYPE AnsiUrlType = g_UlEnableDBCS ? UrlTypeDbcs : UrlTypeAnsi; + + if (!g_UlEnableNonUTF8) + { + // + // Only accept UTF-8 URLs. + // + + Status = UlpCleanAndCopyUrlByType( + UrlTypeUtf8, + AbsPath, + pDestination, + pSource, + SourceLength, + pBytesCopied, + ppQueryString + ); + + } + else if (!g_UlFavorDBCS) + { + // + // The URL may be either UTF-8 or ANSI. First + // try UTF-8, and if that fails go for ANSI. + // + + Status = UlpCleanAndCopyUrlByType( + UrlTypeUtf8, + AbsPath, + pDestination, + pSource, + SourceLength, + pBytesCopied, + ppQueryString + ); + + if (!NT_SUCCESS(Status)) + { + Status = UlpCleanAndCopyUrlByType( + AnsiUrlType, + AbsPath, + pDestination, + pSource, + SourceLength, + pBytesCopied, + ppQueryString + ); + + } + + } + else + { + // + // The URL may be either ANSI or UTF-8. First + // try the ANSI interpretation, and if that fails + // go for UTF-8. + // + Status = UlpCleanAndCopyUrlByType( + AnsiUrlType, + AbsPath, + pDestination, + pSource, + SourceLength, + pBytesCopied, + ppQueryString + ); + + if (!NT_SUCCESS(Status)) + { + Status = UlpCleanAndCopyUrlByType( + UrlTypeUtf8, + AbsPath, + pDestination, + pSource, + SourceLength, + pBytesCopied, + ppQueryString + ); + + } + } + + // + // Convert NTSTATUS to HRESULT + // + + if ( Status == STATUS_SUCCESS ) + { + return S_OK; + } + else + { + DWORD dwErr = 0; + if (SUCCEEDED(WIN32_FROM_NTSTATUS( Status, &dwErr ))) + { + return HRESULT_FROM_WIN32( dwErr ); + } + else + { + return Status; + } + } +} + +HRESULT +UlInitializeParsing( + VOID +) +{ + ULONG i; + UCHAR c; + HKEY hKey; + DWORD dwType; + DWORD dwData; + DWORD cbData; + + // + // First read the HTTP registry settings on how to handle URLs + // + + g_UlEnableNonUTF8 = TRUE; + g_UlEnableDBCS = FALSE; + g_UlFavorDBCS = FALSE; + + if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, + L"System\\CurrentControlSet\\Services\\http\\Parameters", + 0, + KEY_READ, + &hKey ) == ERROR_SUCCESS ) + { + cbData = sizeof( dwData ); + + if ( RegQueryValueEx( hKey, + L"EnableNonUTF8", + NULL, + &dwType, + (LPBYTE) &dwData, + &cbData ) == ERROR_SUCCESS && + dwType == REG_DWORD ) + { + g_UlEnableNonUTF8 = !!dwData; + } + + cbData = sizeof( dwData ); + + if ( g_UlEnableNonUTF8 ) + { + if ( RegQueryValueEx( hKey, + L"EnableDBCS", + NULL, + &dwType, + (LPBYTE) &dwData, + &cbData ) == ERROR_SUCCESS && + dwType == REG_DWORD ) + { + g_UlEnableDBCS = !!dwData; + } + } + else + { + g_UlEnableDBCS = FALSE; + } + + cbData = sizeof( dwData ); + + if ( g_UlEnableDBCS ) + { + if ( RegQueryValueEx( hKey, + L"FavorDBCS", + NULL, + &dwType, + (LPBYTE) &dwData, + &cbData ) == ERROR_SUCCESS && + dwType == REG_DWORD ) + { + g_UlFavorDBCS = !!dwData; + } + } + else + { + g_UlFavorDBCS = FALSE; + } + + RegCloseKey( hKey ); + } + + + // Initialize the HttpChars array appropriately. + + for (i = 0; i < 128; i++) + { + HttpChars[i] = HTTP_CHAR; + } + + for (i = 'A'; i <= 'Z'; i++) + { + HttpChars[i] |= HTTP_UPCASE; + } + + for (i = 'a'; i <= 'z'; i++) + { + HttpChars[i] |= HTTP_LOCASE; + } + + for (i = '0'; i <= '9'; i++) + { + HttpChars[i] |= (HTTP_DIGIT | HTTP_HEX); + } + + + for (i = 0; i <= 31; i++) + { + HttpChars[i] |= HTTP_CTL; + } + + HttpChars[127] |= HTTP_CTL; + + HttpChars[SP] |= HTTP_LWS; + HttpChars[HT] |= HTTP_LWS; + + + for (i = 'A'; i <= 'F'; i++) + { + HttpChars[i] |= HTTP_HEX; + } + + for (i = 'a'; i <= 'f'; i++) + { + HttpChars[i] |= HTTP_HEX; + } + + HttpChars['('] |= HTTP_SEPERATOR; + HttpChars[')'] |= HTTP_SEPERATOR; + HttpChars['<'] |= HTTP_SEPERATOR; + HttpChars['>'] |= HTTP_SEPERATOR; + HttpChars['@'] |= HTTP_SEPERATOR; + HttpChars[','] |= HTTP_SEPERATOR; + HttpChars[';'] |= HTTP_SEPERATOR; + HttpChars[':'] |= HTTP_SEPERATOR; + HttpChars['\\'] |= HTTP_SEPERATOR; + HttpChars['"'] |= HTTP_SEPERATOR; + HttpChars['/'] |= HTTP_SEPERATOR; + HttpChars['['] |= HTTP_SEPERATOR; + HttpChars[']'] |= HTTP_SEPERATOR; + HttpChars['?'] |= HTTP_SEPERATOR; + HttpChars['='] |= HTTP_SEPERATOR; + HttpChars['{'] |= HTTP_SEPERATOR; + HttpChars['}'] |= HTTP_SEPERATOR; + HttpChars[SP] |= HTTP_SEPERATOR; + HttpChars[HT] |= HTTP_SEPERATOR; + + + // + // URL "reserved" characters (rfc2396) + // + + HttpChars[';'] |= URL_LEGAL; + HttpChars['/'] |= URL_LEGAL; + HttpChars['\\'] |= URL_LEGAL; + HttpChars['?'] |= URL_LEGAL; + HttpChars[':'] |= URL_LEGAL; + HttpChars['@'] |= URL_LEGAL; + HttpChars['&'] |= URL_LEGAL; + HttpChars['='] |= URL_LEGAL; + HttpChars['+'] |= URL_LEGAL; + HttpChars['$'] |= URL_LEGAL; + HttpChars[','] |= URL_LEGAL; + + + // + // URL escape character + // + + HttpChars['%'] |= URL_LEGAL; + + // + // URL "mark" characters (rfc2396) + // + + HttpChars['-'] |= URL_LEGAL; + HttpChars['_'] |= URL_LEGAL; + HttpChars['.'] |= URL_LEGAL; + HttpChars['!'] |= URL_LEGAL; + HttpChars['~'] |= URL_LEGAL; + HttpChars['*'] |= URL_LEGAL; + HttpChars['\''] |= URL_LEGAL; + HttpChars['('] |= URL_LEGAL; + HttpChars[')'] |= URL_LEGAL; + + + // + // RFC2396 describes these characters as `unwise' "because gateways and + // other transport agents are known to sometimes modify such characters, + // or they are used as delimiters". However, for compatibility with + // IIS 5.0 and DAV, we must allow these unwise characters in URLs. + // + + HttpChars['{'] |= URL_LEGAL; + HttpChars['}'] |= URL_LEGAL; + HttpChars['|'] |= URL_LEGAL; + HttpChars['^'] |= URL_LEGAL; + HttpChars['['] |= URL_LEGAL; + HttpChars[']'] |= URL_LEGAL; + HttpChars['`'] |= URL_LEGAL; + + // + // '#', '%', and '"' are not considered URL_LEGAL, according to the RFC. + // However, IIS 5.0 allowed them, so we should too. + // + + HttpChars['#'] |= URL_LEGAL; + HttpChars['%'] |= URL_LEGAL; + HttpChars['"'] |= URL_LEGAL; + + // + // In DBCS locales we need to explicitly accept lead bytes which + // we would normally reject. + // + + if (0) // BUGBUG + { + for (i = 0; i < DBCS_TABLE_SIZE; i++) + { + if (IS_LEAD_BYTE((BYTE)i)) + { + HttpChars[i] |= URL_LEGAL; + } + } + } + + // + // These US-ASCII characters are "excluded"; i.e. not URL_LEGAL (see RFC): + // '<' | '>' | ' ' (0x20) + // In addition, control characters (0x00-0x1F and 0x7F) and + // non US-ASCII characters (0x80-0xFF) are not URL_LEGAL. + // + + for (i = 0; i < 128; i++) + { + if (!IS_HTTP_SEPERATOR(i) && !IS_HTTP_CTL(i)) + { + HttpChars[i] |= HTTP_TOKEN; + } + } + + + // + // Fast path for PopChar + // + + RtlZeroMemory(FastPopChars, 256 * sizeof(USHORT)); + RtlZeroMemory(DummyPopChars, 256 * sizeof(USHORT)); + + for (i = 0; i < 256; i++) + { + c = (UCHAR)i; + + if (IS_URL_TOKEN(c) && c != '%' && (c & 0x80) != 0x80) + { + FastPopChars[i] = (USHORT)c; + } + } + + // + // Turn backslashes into forward slashes + // + + FastPopChars['\\'] = L'/'; + + + // + // Fast path for UpcaseUnicodeChar + // + + for (i = 0; i < 256; i++) + { + FastUpcaseChars[i] = towupper((WCHAR)i); + } + + + return S_OK; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/util.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/util.cxx new file mode 100644 index 0000000000..22c31a0ed2 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/lib/util.cxx @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +HRESULT +MakePathCanonicalizationProof( + IN PCWSTR pszName, + OUT STRU * pstrPath +) +/*++ + +Routine Description: + + This functions adds a prefix + to the string, which is "\\?\UNC\" for a UNC path, and "\\?\" for + other paths. This prefix tells Windows not to parse the path. + +Arguments: + + IN pszName - The path to be converted + OUT pstrPath - Output path created + +Return Values: + + HRESULT + +--*/ +{ + HRESULT hr; + + if (pszName[0] == L'\\' && pszName[1] == L'\\') + { + // + // If the path is already canonicalized, just return + // + + if ((pszName[2] == '?' || pszName[2] == '.') && + pszName[3] == '\\') + { + hr = pstrPath->Copy(pszName); + + if (SUCCEEDED(hr)) + { + // + // If the path was in DOS form ("\\.\"), + // we need to change it to Win32 from ("\\?\") + // + + pstrPath->QueryStr()[2] = L'?'; + } + + return hr; + } + + pszName += 2; + + + if (FAILED(hr = pstrPath->Copy(L"\\\\?\\UNC\\"))) + { + return hr; + } + } + else + { + if (FAILED(hr = pstrPath->Copy(L"\\\\?\\"))) + { + return hr; + } + } + + return pstrPath->Append(pszName); +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/stbuff.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/stbuff.h new file mode 100644 index 0000000000..04e13789f0 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/stbuff.h @@ -0,0 +1,1013 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _STBUFF_H +#define _STBUFF_H + +#include +#include + +#define STB_INLINE_SIZE 64 +#define STB_MAX_ALLOC 16*1024 + +#define TO_UPPER(ch) (isupper(ch) ? ch : toupper(ch)) + +class STBUFF +{ +public: + + STBUFF( + BOOL fZeroInit = TRUE + ) : _pData( _Inline ), + _cbData( 0 ), + _cbBuffer( STB_INLINE_SIZE ), + _cbMaxAlloc( STB_MAX_ALLOC ) + { + if ( fZeroInit ) + { + ZeroInit(); + } + + _Inline[STB_INLINE_SIZE] = 0; + _Inline[STB_INLINE_SIZE+1] = 0; + } + + virtual + ~STBUFF() + { + Reset( TRUE ); + } + + VOID + Reset( + BOOL fFreeAlloc = FALSE + ) + { + // + // If we are supposed to free any heap + // allocations, do so now. + // + + if ( fFreeAlloc && + _pData != _Inline ) + { + LocalFree( _pData ); + _pData = _Inline; + _cbBuffer = STB_INLINE_SIZE; + } + + // + // Reset the data size + // + + _cbData = 0; + } + + HRESULT + Resize( + DWORD cbSize + ) + { + HRESULT hr = S_OK; + BYTE * pTemp; + + // + // If the buffer is large enough, just return + // + + if ( cbSize < _cbBuffer ) + { + goto Finished; + } + + // + // If the requested size exceeds our maximum + // allocation, then fail this call. + // + + if ( cbSize > _cbMaxAlloc ) + { + hr = E_OUTOFMEMORY; + goto Finished; + } + + // + // Adjust the allocation size so that we allocate + // in chunks of MINITOOLS_INLINE_SIZE. Don't + // exeed _cbMaxAlloc. + // + + if ( cbSize % STB_INLINE_SIZE ) + { + cbSize = ( cbSize / STB_INLINE_SIZE + 1 ) * + STB_INLINE_SIZE; + } + + if ( cbSize > _cbMaxAlloc ) + { + cbSize = _cbMaxAlloc; + } + + // + // Allocate the new storage and copy any existing + // data into it. + // + // Allocate two extra bytes so that we can guarantee + // NULL termination when someone queries the data + // pointer as a string. + // + + pTemp = (BYTE*)LocalAlloc( LPTR, cbSize + 2 ); + + if ( !pTemp ) + { + hr = E_OUTOFMEMORY; + goto Finished; + } + + if ( _cbData ) + { + CopyMemory( pTemp, _pData, _cbData ); + } + + // + // If the original buffer is not the inline + // storage, then free it. + // + + if ( _pData != _Inline ) + { + LocalFree( _pData ); + } + + // + // Save the new storage pointer + // + + _pData = pTemp; + _cbBuffer = cbSize; + + // + // Set the extra two bytes as 0 + // + + _pData[_cbBuffer] = 0; + _pData[_cbBuffer+1] = 0; + +Finished: + return hr; + } + + HRESULT + AppendData( + VOID * pData, + DWORD cbData, + DWORD Offset = 0xffffffff + ) + { + DWORD cbNeeded; + HRESULT hr = S_OK; + + // + // Resize the buffer if necessary + // + + cbNeeded = Offset + cbData; + + hr = Resize( cbNeeded ); + + if ( FAILED( hr ) ) + { + goto Finished; + } + + // + // Copy the new data + // + + if ( cbData ) + { + CopyMemory( _pData + Offset, pData, cbData ); + } + + _cbData = cbNeeded; + + // + // NULL terminate the data + // + + GuaranteeNullTermination(); + +Finished: + + return hr; + } + + + HRESULT + AppendData( + LPCSTR szData, + DWORD cchData = 0xffffffff, + DWORD Offset = 0xffffffff + ) + { + // + // If cchData is 0xffffffff, then calculate size + // + + if ( cchData == 0xffffffff ) + { + cchData = (DWORD)strlen( szData ); + } + + // + // If offset is 0xffffffff, then assume + // that we are appending to the end of the + // string. + // + + if ( Offset == 0xffffffff ) + { + Offset = _cbData; + } + + return AppendData( (VOID*)szData, + cchData, + Offset ); + } + + HRESULT + AppendData( + LPCWSTR szData, + DWORD cchData = 0xffffffff, + DWORD cchOffset = 0xffffffff + ) + { + DWORD cbData; + DWORD cbOffset; + // + // If cchData is 0xffffffff, then calculate size + // + + if ( cchData == 0xffffffff ) + { + cchData = (DWORD)wcslen( szData ); + } + + cbData = cchData * sizeof(WCHAR); + + // + // If offset is 0xffffffff, then assume + // that we are appending to the end of the + // string. + // + + if ( cchOffset == 0xffffffff ) + { + cchOffset = _cbData; + } + + cbOffset = cchOffset * sizeof(WCHAR); + + return AppendData( (VOID*)szData, + cbData, + cbOffset ); + } + + HRESULT + AppendData( + STBUFF *pbuff + ) + { + return AppendData( pbuff->QueryPtr(), + pbuff->QueryDataSize() ); + } + + HRESULT + SetData( + VOID * pData, + DWORD cbData + ) + { + // + // Set data is just an append to offset zero + // + + return AppendData( pData, + cbData, + 0 ); + } + + HRESULT + SetData( + LPCSTR pData, + DWORD cchData = 0xffffffff + ) + { + // + // If cbData is 0xffffffff, then assume that + // pData is a NULL terminated string. + // + + if ( cchData == 0xffffffff ) + { + cchData = (DWORD)strlen( (LPSTR)pData ); + } + + return SetData( (VOID*)pData, cchData ); + } + + HRESULT + SetData( + LPCWSTR pData, + DWORD cchData = 0xffffffff + ) + { + // + // If cbData is 0xffffffff, then assume that + // pData is a NULL terminated string. + // + + if ( cchData == 0xffffffff ) + { + cchData = (DWORD)wcslen( (LPWSTR)pData ); + } + + return SetData( (VOID*)pData, cchData * sizeof(WCHAR) ); + } + + + HRESULT + SetData( + STBUFF *pbuff + ) + { + return AppendData( pbuff->QueryPtr(), + pbuff->QueryDataSize(), + 0 ); + } + + HRESULT + AnsiToUnicode( + LPCSTR szString, + UINT codepage = CP_UTF8 + ) + { + DWORD cchString = (DWORD)strlen( szString ); + HRESULT hr = S_OK; + + hr = Resize( cchString * sizeof(WCHAR) ); + + if ( FAILED( hr ) ) + { + goto Finished; + } + + if ( !MultiByteToWideChar( codepage, + MB_ERR_INVALID_CHARS, + szString, + cchString, + (LPWSTR)_pData, + cchString ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Finished; + } + + _cbData = cchString * sizeof(WCHAR); + +Finished: + + return hr; + } + + HRESULT + UnicodeToAnsi( + LPCWSTR szStringW, + UINT codepage = CP_UTF8 + ) + { + DWORD cchString = (DWORD)wcslen( szStringW ); + HRESULT hr = S_OK; + + hr = Resize( cchString ); + + if ( FAILED( hr ) ) + { + goto Finished; + } + + if ( !WideCharToMultiByte( codepage, + 0, + szStringW, + cchString, + (LPSTR)_pData, + cchString, + NULL, + NULL ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Finished; + } + + _cbData = cchString; + +Finished: + + return hr; + } + + HRESULT + ExpandEnvironmentStrings( + VOID + ) + { + STBUFF Temp; + DWORD cbNeeded; + HRESULT hr = S_OK; + + cbNeeded = ::ExpandEnvironmentStringsA( QueryStr(), + Temp.QueryStr(), + Temp.QueryBufferSize() ); + + if ( cbNeeded > Temp.QueryBufferSize() ) + { + hr = Temp.Resize ( cbNeeded ); + if ( FAILED (hr) ) + { + goto Finished; + } + + cbNeeded = ::ExpandEnvironmentStringsA( QueryStr(), + Temp.QueryStr(), + Temp.QueryBufferSize() ); + + } + + Temp.CalcDataSize(); + + hr = SetData( &Temp ); + if ( FAILED (hr) ) + { + goto Finished; + } + + Finished: + + return hr; + } + + HRESULT + Vsprintf( + LPCSTR szFormat, + va_list args + ) + { + DWORD cchWritten; + HRESULT hr = S_OK; + + DWORD cbNeeded = _vscprintf( szFormat, args ); + + hr = Resize( cbNeeded + 1 ); + + if ( FAILED( hr ) ) + { + goto Finished; + } + + cchWritten = _vsnprintf_s( QueryStr(), + QueryBufferSize(), + QueryBufferSize(), + szFormat, + args ); + + _cbData = cchWritten; + +Finished: + + return hr; + } + + HRESULT + Vsprintf( + LPCWSTR szFormat, + va_list args + ) + { + DWORD cchWritten; + HRESULT hr = S_OK; + + DWORD cbNeeded = _vscwprintf( szFormat, args ) * sizeof(WCHAR); + + hr = Resize( cbNeeded + 1 ); + + if ( FAILED( hr ) ) + { + goto Finished; + } + + cchWritten = _vsnwprintf_s( QueryStrW(), + QueryBufferSize() / sizeof(WCHAR), + _TRUNCATE, + szFormat, + args ); + + _cbData = cchWritten * sizeof(WCHAR); + +Finished: + + return hr; + } + + HRESULT + Printf( + LPCSTR szFormat, + ... + ) + { + HRESULT hr; + + // + // Let Vsprintf do the work + // + + va_list args; + + va_start( args, szFormat ); + + hr = Vsprintf( szFormat, + args ); + + va_end( args ); + + return hr; + } + + HRESULT + Printf( + LPCWSTR szFormat, + ... + ) + { + HRESULT hr; + + // + // Let Vsprintf do the work + // + + va_list args; + + va_start( args, szFormat ); + + hr = Vsprintf( szFormat, + args ); + + va_end( args ); + + return hr; + } + + VOID * + QueryPtr() + { + return (VOID*)_pData; + } + + LPSTR + QueryStr() + { + GuaranteeNullTermination(); + + return (LPSTR)_pData; + } + + LPWSTR + QueryStrW() + { + GuaranteeNullTermination(); + + return (LPWSTR)_pData; + } + + DWORD + QueryDataSize() + { + return _cbData; + } + + HRESULT + SetDataSize( + DWORD cbData + ) + { + HRESULT hr = S_OK; + + if ( cbData > _cbBuffer ) + { + hr = HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ); + goto Finished; + } + + _cbData = cbData; + + Finished: + return hr; + } + + VOID + CalcDataSize() + { + _cbData = (DWORD)strlen( (LPSTR)_pData ); + } + + VOID + CalcDataSizeW() + { + _cbData = (DWORD)wcslen( (LPWSTR)_pData ); + } + + DWORD + QueryBufferSize() + { + return _cbBuffer; + } + + DWORD + QueryMaxAlloc() + { + return _cbMaxAlloc; + } + + VOID + SetMaxAlloc( + DWORD cbMaxAlloc + ) + { + _cbMaxAlloc = cbMaxAlloc; + } + + VOID + ZeroInit( + VOID + ) + { + FillMemory( _Inline, STB_INLINE_SIZE, 0x00 ); + + if ( _pData != _Inline ) + { + FillMemory( _pData, _cbBuffer, 0x00 ); + } + } + + HRESULT + Escape( + BOOL fAllowDoubleEscaping = FALSE + ) + { + STBUFF Temp; + DWORD dwNumEscapes = 0; + CHAR szHex[3] = {0}; + BYTE * pRead; + BYTE * pWrite; + HRESULT hr = S_OK; + + // + // Walk through the string once. If there + // are no escapes, then we can just return. + // + + GuaranteeNullTermination(); + + pRead = (BYTE*)_pData; + + while ( *pRead != '\0' ) + { + if ( ( fAllowDoubleEscaping || + !IsEscapeSequence( (CHAR*)pRead ) ) && + ShouldEscape( *pRead ) ) + { + dwNumEscapes++; + } + + pRead++; + } + + if ( dwNumEscapes == 0 ) + { + goto Finished; + } + + // + // Make sure that our cooked string buffer is big enough, so + // we can manipulate its pointer directly. + // + + hr = Temp.Resize( _cbData + dwNumEscapes * 2 ); + if ( FAILED (hr) ) + { + goto Finished; + } + + pRead = (BYTE*)_pData; + pWrite = (BYTE*)Temp.QueryStr(); + + while ( *pRead != '\0' ) + { + if ( ( fAllowDoubleEscaping || + !IsEscapeSequence( (CHAR*)pRead ) ) && + ShouldEscape( *pRead ) ) + { + _snprintf_s( szHex, 3, 2, "%02x", *pRead ); + + *pWrite = '%'; + *(pWrite+1) = szHex[0]; + *(pWrite+2) = szHex[1]; + + pRead++; + pWrite += 3; + + continue; + } + + *pWrite = *pRead; + + pRead++; + pWrite++; + } + + *pWrite = '\0'; + + Temp.CalcDataSize(); + + hr = SetData( Temp.QueryStr() ); + if ( FAILED (hr) ) + { + goto Finished; + } + + Finished: + + return hr; + } + + VOID + Unescape( + VOID + ) + { + CHAR * pRead; + CHAR * pWrite; + CHAR szHex[3] = {0}; + BYTE c; + + pRead = (CHAR*)_pData; + pWrite = pRead; + + while ( *pRead ) + { + if ( IsEscapeSequence( pRead ) ) + { + szHex[0] = *(pRead+1); + szHex[1] = *(pRead+2); + + c = (BYTE)strtoul( szHex, NULL, 16 ); + + *pWrite = c; + + pRead += 3; + pWrite++; + + continue; + } + + *pWrite = *pRead; + + pRead++; + pWrite++; + } + + *pWrite = '\0'; + + CalcDataSize(); + + return; + } + + VOID + MoveToFront( + DWORD cbOffset + ) + { + if ( cbOffset >= _cbData ) + { + Reset(); + + return; + } + + MoveMemory( _pData, _pData + cbOffset, _cbData - cbOffset ); + + _cbData -= cbOffset; + } + + BOOL + IsWildcardMatch( + LPCSTR szExpr + ) + { + LPCSTR pExpr = szExpr; + LPCSTR pString = QueryStr(); + LPCSTR pSubMatch; + DWORD cchSubMatch; + + if ( !pExpr ) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + while ( *pExpr ) + { + switch ( *pExpr ) + { + case '*': + + // + // Eat '*' characters + // + + while ( *pExpr == '*' ) + { + pExpr++; + } + + // + // Find the next wildcard + // + + pSubMatch = strchr( pExpr, '*' ); + + cchSubMatch = (DWORD)(pSubMatch ? + pSubMatch - pExpr : + strlen( pExpr )); + + if ( cchSubMatch == 0 ) + { + // + // No submatch. The rest of + // pString automatically matches + // + + return TRUE; + } + + // + // Ensure that the current submatch exists + // + + while ( _strnicmp( pString, pExpr, cchSubMatch ) ) + { + pString++; + + if ( *pString == '\0' ) + { + // + // Not found + // + + return FALSE; + } + } + + pExpr += cchSubMatch; + pString += cchSubMatch; + + break; + + default: + + if ( TO_UPPER( *pExpr ) != TO_UPPER( *pString ) ) + { + return FALSE; + } + + pExpr++; + pString++; + } + } + + if ( *pString != '\0' ) + { + return FALSE; + } + + return TRUE; + } + +private: + + LPBYTE _pData; + DWORD _cbData; + DWORD _cbBuffer; + DWORD _cbMaxAlloc; + BYTE _Inline[STB_INLINE_SIZE+2]; + + VOID + GuaranteeNullTermination() + { + _pData[_cbData] = 0; + _pData[_cbData+1] = 0; + } + + BOOL + IsEscapeSequence( + CHAR * str + ) + { + if ( *str == '%' && + isxdigit( *(str+1) ) && + isxdigit( *(str+2) ) ) + { + return TRUE; + } + + return FALSE; + } + + BOOL + ShouldEscape( + BYTE c + ) + { + // + // If the character is listed in RFC2396, section + // 2.4.3 as control, space, delims or unwise, we + // should escape it. Also, we should escape characters + // with the high bit set. + // + + if ( c <= 0x1f || + c == 0x7f ) + { + // + // Control character + // + + goto ReturnTrue; + } + + if ( c >= 0x80 ) + { + // + // High bit set + // + + goto ReturnTrue; + } + + switch ( c ) + { + + // + // space + // + case ' ': + + // + // delims + // + case '<': + case '>': + case '#': + case '%': + case '\"': + + // + // unwise + // + case '{': + case '}': + case '|': + case '\\': + case '^': + case '[': + case ']': + case '`': + + goto ReturnTrue; + } + + // + // If we get here, then the character should not be + // escaped + // + + return FALSE; + + ReturnTrue: + + return TRUE; + } +}; + +#endif // _STBUFF_H diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/stlist.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/stlist.h new file mode 100644 index 0000000000..916c8576a8 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/stlist.h @@ -0,0 +1,87 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _STLIST_H +#define _STLIST_H + +#ifndef IsListEmpty + +#include + +#define IsListEmpty(ListHead) ((ListHead)->Flink == (ListHead)) + +VOID +inline +InitializeListHead( + LIST_ENTRY * ListHead + ) +{ + ListHead->Flink = ListHead->Blink = ListHead; +} + +BOOL +inline +RemoveEntryList( + LIST_ENTRY * Entry + ) +{ + LIST_ENTRY * Blink; + LIST_ENTRY * Flink; + + Flink = Entry->Flink; + Blink = Entry->Blink; + Blink->Flink = Flink; + Flink->Blink = Blink; + return (Flink == Blink); +} + +PLIST_ENTRY +inline +RemoveHeadList( + LIST_ENTRY * ListHead + ) +{ + LIST_ENTRY * Flink; + LIST_ENTRY * Entry; + + Entry = ListHead->Flink; + Flink = Entry->Flink; + ListHead->Flink = Flink; + Flink->Blink = ListHead; + return Entry; +} + +VOID +inline +InsertHeadList( + LIST_ENTRY * ListHead, + LIST_ENTRY * Entry + ) +{ + LIST_ENTRY * Flink; + + Flink = ListHead->Flink; + Entry->Flink = Flink; + Entry->Blink = ListHead; + Flink->Blink = Entry; + ListHead->Flink = Entry; +} + +VOID +inline +InsertTailList( + LIST_ENTRY * ListHead, + LIST_ENTRY * Entry + ) +{ + LIST_ENTRY * Blink; + + Blink = ListHead->Blink; + Entry->Flink = ListHead; + Entry->Blink = Blink; + Blink->Flink = Entry; + ListHead->Blink = Entry; +} + +#endif // IsListEmpty +#endif // _STLIST_H diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/stlock.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/stlock.h new file mode 100644 index 0000000000..6571489187 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/stlock.h @@ -0,0 +1,149 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _STLOCK_H +#define _STLOCK_H + +class STLOCK +{ +public: + + STLOCK() + : _fInitialized( FALSE ) + { + } + + ~STLOCK() + { + if ( _fInitialized ) + { + DeleteCriticalSection( &_cs ); + CloseHandle( _hReadersDone ); + } + } + + HRESULT + Initialize( + VOID + ) + { + HRESULT hr = S_OK; + BOOL fResult = FALSE; + + if ( !_fInitialized ) + { + _fWriterWaiting = FALSE; + _cReaders = 0; + + fResult = InitializeCriticalSectionAndSpinCount( &_cs, 100 ); + + if ( !fResult ) + { + hr = E_FAIL; + goto Finished; + } + + _hReadersDone = CreateEvent( NULL, + FALSE, + FALSE, + NULL ); + + if ( !_hReadersDone ) + { + DeleteCriticalSection( &_cs ); + hr = E_FAIL; + goto Finished; + } + + _fInitialized = TRUE; + } + +Finished: + return hr; + } + + BOOL + QueryInitialized() const + { + return _fInitialized; + } + + void SharedAcquire() + { + EnterCriticalSection( &_cs ); + InterlockedIncrement( &_cReaders ); + LeaveCriticalSection( &_cs ); + } + + void SharedRelease() + { + ReleaseInternal(); + } + + void ExclusiveAcquire() + { + EnterCriticalSection( &_cs ); + + _fWriterWaiting = TRUE; + + // + // If there are any readers, wait for them + // to release + // + + if ( InterlockedExchangeAdd( &_cReaders, 0 ) > 0 ) + { + WaitForSingleObject( _hReadersDone, INFINITE ); + } + + // + // Reader count -1 indicates that a writer has the lock + // + + _cReaders = -1; + } + + void ExclusiveRelease() + { + ReleaseInternal(); + } + +private: + + BOOL _fInitialized; + BOOL _fWriterWaiting; + LONG _cReaders; + CRITICAL_SECTION _cs; + HANDLE _hReadersDone; + + void ReleaseInternal() + { + LONG cReaders = InterlockedDecrement( &_cReaders ); + + if ( cReaders >= 0 ) + { + // + // Released a read lock. If this was the last + // reader and writers are waiting, set the + // readers done event + // + + if ( ( _fWriterWaiting ) && ( cReaders == 0 ) ) + { + SetEvent( _hReadersDone ); + } + } + else + { + // + // Released a write lock + // + + _cReaders = 0; + _fWriterWaiting = FALSE; + LeaveCriticalSection( &_cs ); + } + } +}; + +#endif // _STLOCK_H \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/sttable.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/sttable.h new file mode 100644 index 0000000000..0fd629af3d --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/sttable.h @@ -0,0 +1,599 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _STTABLE_H +#define _STTABLE_H + +#include +#include +#include "stbuff.h" +#include "stlock.h" +#include "stlist.h" + +#define DEFAULT_BUCKETS 97 // largest prime under 100 + +class ITEM; +class STTABLE_ITEM; + +typedef DWORD (WINAPI * PFN_HASH)(STBUFF*); +typedef BOOL (WINAPI * PFN_COMPARE_KEYS)(STBUFF*,STBUFF*); +typedef VOID (WINAPI * PFN_ITER)(STTABLE_ITEM*, BOOL*); + +class STTABLE_ITEM +{ +public: + + STTABLE_ITEM() + : _cRefs( 1 ) + { + InitializeListHead( &le ); + } + + VOID + Reference() + { + InterlockedIncrement( &_cRefs ); + } + + VOID + Dereference() + { + LONG cRefs = InterlockedDecrement( &_cRefs ); + + if ( cRefs == 0 ) + { + delete this; + } + } + + HRESULT + Initialize( + STBUFF * pKey + ) + { + return _buffKey.SetData( pKey->QueryPtr(), + pKey->QueryDataSize() ); + } + + STBUFF * + QueryKey() + { + return &_buffKey; + } + + virtual + ~STTABLE_ITEM() + {} + + LIST_ENTRY le; + +private: + + LONG _cRefs; + STBUFF _buffKey; +}; + +class STTABLE_BUCKET +{ +public: + + STTABLE_BUCKET() + : _pfnCompareKeys( NULL ) + {} + + virtual + ~STTABLE_BUCKET() + { + LIST_ENTRY * pEntry; + STTABLE_ITEM * pItem; + + while ( !IsListEmpty( &_Head ) ) + { + pEntry = RemoveHeadList( &_Head ); + + pItem = CONTAINING_RECORD( pEntry, + STTABLE_ITEM, + le ); + + pItem->Dereference(); + pItem = NULL; + } + } + + HRESULT + Initialize( + PFN_COMPARE_KEYS pfnCompareKeys = NULL + ) + { + InitializeListHead( &_Head ); + + _pfnCompareKeys = pfnCompareKeys; + + return _BucketLock.Initialize(); + } + + HRESULT + Insert( + STTABLE_ITEM * pNewItem + ) + { + LIST_ENTRY * pEntry; + STTABLE_ITEM * pItem; + HRESULT hr = S_OK; + + _BucketLock.ExclusiveAcquire(); + + // + // Check to see if the item is already in the list + // + + pEntry = _Head.Flink; + + while ( pEntry != &_Head ) + { + pItem = CONTAINING_RECORD( pEntry, + STTABLE_ITEM, + le ); + + if ( CompareKeys( pNewItem->QueryKey(), + pItem->QueryKey() ) ) + { + hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); + goto Finished; + } + + pEntry = pEntry->Flink; + } + + // + // It's not in the list. Add it now + // + + pNewItem->Reference(); + InsertTailList( &_Head, &pNewItem->le ); + +Finished: + + _BucketLock.ExclusiveRelease(); + + return hr; + } + + HRESULT + Remove( + STTABLE_ITEM * pItemToRemove + ) + { + LIST_ENTRY * pEntry; + STTABLE_ITEM * pItem; + + _BucketLock.ExclusiveAcquire(); + + // + // Find the item in the list + // + + pEntry = _Head.Flink; + + while ( pEntry != &_Head ) + { + pItem = CONTAINING_RECORD( pEntry, + STTABLE_ITEM, + le ); + + if ( CompareKeys( pItemToRemove->QueryKey(), + pItem->QueryKey() ) ) + { + RemoveEntryList( &pItemToRemove->le ); + pItemToRemove->Dereference(); + pItemToRemove = NULL; + + goto Finished; + } + + pEntry = pEntry->Flink; + } + + // + // Item was not found. Set error code, but + // don't fail function. + // + + SetLastError (ERROR_FILE_NOT_FOUND); + +Finished: + + _BucketLock.ExclusiveRelease(); + + return S_OK; + } + + HRESULT + GetItem( + STBUFF * pKey, + STTABLE_ITEM **ppItem + ) + { + LIST_ENTRY * pEntry; + STTABLE_ITEM * pItem; + HRESULT hr = S_OK; + + _BucketLock.SharedAcquire(); + + // + // Find the item in the list + // + + pEntry = _Head.Flink; + + while ( pEntry != &_Head ) + { + pItem = CONTAINING_RECORD( pEntry, + STTABLE_ITEM, + le ); + + if ( CompareKeys( pKey, + pItem->QueryKey() ) ) + { + pItem->Reference(); + goto Finished; + } + + pEntry = pEntry->Flink; + } + + // + // Item was not found. + // + + pItem = NULL; + + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + +Finished: + + _BucketLock.SharedRelease(); + + *ppItem = pItem; + + return hr; + } + + VOID + Iterate( + PFN_ITER pIterFunction + ) + { + LIST_ENTRY * pEntry; + STTABLE_ITEM * pItem; + BOOL fRemoveItem; + + //////////////////////////////////////// + // + // It is assumed that this function will + // be called under a write lock + // + //////////////////////////////////////// + + // + // Walk the list and call the provided + // function on each item + // + + pEntry = _Head.Flink; + + while ( pEntry != &_Head ) + { + pItem = CONTAINING_RECORD( pEntry, + STTABLE_ITEM, + le ); + + // + // The iterator function might remove + // the item from the list, so we need + // to get the next link first + // + + pEntry = pEntry->Flink; + + pItem->Reference(); + pIterFunction( pItem, &fRemoveItem ); + + if ( fRemoveItem ) + { + RemoveEntryList( &pItem->le ); + pItem->Dereference(); + pItem = NULL; + } + } + + } + +private: + + LIST_ENTRY _Head; + STLOCK _BucketLock; + PFN_COMPARE_KEYS _pfnCompareKeys; + + BOOL + CompareKeys( + STBUFF * pKey1, + STBUFF * pKey2 + ) + { + if ( _pfnCompareKeys ) + { + return _pfnCompareKeys( pKey1, + pKey2 ); + } + + return ( strcmp( pKey1->QueryStr(), + pKey2->QueryStr() ) == 0 ); + } +}; + + +class STTABLE +{ +public: + + STTABLE() + : _cBuckets( 0 ), + _pfnHash( NULL ) + {} + + virtual + ~STTABLE() + { + STTABLE_BUCKET ** rgBuckets; + STTABLE_BUCKET * pBucket; + DWORD n; + + rgBuckets = (STTABLE_BUCKET**)_buffBucketPtrs.QueryPtr(); + + for( n = 0; n < _cBuckets; n++ ) + { + pBucket = rgBuckets[n]; + + delete pBucket; + pBucket = NULL; + } + } + + HRESULT + Initialize( + DWORD cBuckets = DEFAULT_BUCKETS, + PFN_HASH pfnHash = NULL, + PFN_COMPARE_KEYS pfnCompareKeys = NULL + ) + { + STTABLE_BUCKET ** rgBuckets; + DWORD n; + HRESULT hr = S_OK; + + // + // Create a buffer for the bucket array + // + + hr = _buffBucketPtrs.Resize( cBuckets * sizeof(STTABLE_BUCKET*) ); + + if ( FAILED (hr) ) + { + goto Finished; + } + + rgBuckets = (STTABLE_BUCKET**)_buffBucketPtrs.QueryPtr(); + + // + // Create the buckets + // + + for ( n = 0; n < cBuckets; n++ ) + { + STTABLE_BUCKET * pNewBucket = new STTABLE_BUCKET; + + if ( !pNewBucket ) + { + hr = E_OUTOFMEMORY; + goto Finished; + } + + hr = pNewBucket->Initialize( pfnCompareKeys ); + + if ( FAILED (hr) ) + { + delete pNewBucket; + pNewBucket = NULL; + + goto Finished; + } + + rgBuckets[n] = pNewBucket; + pNewBucket = NULL; + + _cBuckets++; + } + + // + // Initialize the table lock + // + + _TableLock.Initialize(); + + // + // Set the hash function + // + + _pfnHash = pfnHash; + +Finished: + return hr; + } + + HRESULT + Insert( + STTABLE_ITEM * pNewItem + ) + { + + DWORD dwHash; + STTABLE_BUCKET * pBucket; + HRESULT hr = S_OK; + + dwHash = ComputeHash( pNewItem->QueryKey() ); + + pBucket = GetBucket( dwHash ); + + _TableLock.SharedAcquire(); + + hr = pBucket->Insert( pNewItem ); + + _TableLock.SharedRelease(); + + return hr; + } + + HRESULT + Remove( + STTABLE_ITEM * pItemToRemove + ) + { + DWORD dwHash; + STTABLE_BUCKET * pBucket; + HRESULT hr = S_OK; + + dwHash = ComputeHash( pItemToRemove->QueryKey() ); + + pBucket = GetBucket( dwHash ); + + _TableLock.SharedAcquire(); + + hr = pBucket->Remove( pItemToRemove ); + + _TableLock.SharedRelease(); + + return hr; + } + + HRESULT + GetItem( + STBUFF * pKey, + STTABLE_ITEM **ppItem + ) + { + DWORD dwHash; + STTABLE_BUCKET * pBucket; + STTABLE_ITEM * pRet; + HRESULT hr = S_OK; + + dwHash = ComputeHash( pKey ); + + pBucket = GetBucket( dwHash ); + + _TableLock.SharedAcquire(); + + hr = pBucket->GetItem( pKey, &pRet ); + if(FAILED( hr)) + { + pRet = NULL; + goto Finished; + } + + Finished: + + _TableLock.SharedRelease(); + + *ppItem = pRet; + + return hr; + } + + VOID + Iterate( + PFN_ITER pIterFunction + ) + { + STTABLE_BUCKET ** rgBuckets; + DWORD n; + + _TableLock.ExclusiveAcquire(); + + rgBuckets = (STTABLE_BUCKET**)_buffBucketPtrs.QueryPtr(); + + // + // Iterate each bucket + // + + for ( n = 0; n < _cBuckets; n++ ) + { + STTABLE_BUCKET * pBucket; + + pBucket = rgBuckets[n]; + + pBucket->Iterate( pIterFunction ); + + pBucket = NULL; + } + + _TableLock.ExclusiveRelease(); + } + +private: + + STBUFF _buffBucketPtrs; + DWORD _cBuckets; + STLOCK _TableLock; + PFN_HASH _pfnHash; + + DWORD + ComputeHash( + STBUFF * pKey + ) + { + if ( _pfnHash ) + { + return _pfnHash( pKey ); + } + + return HashString( pKey->QueryStr() ); + } + + STTABLE_BUCKET * + GetBucket( + DWORD dwHash + ) + { + STTABLE_BUCKET ** rgBuckets; + + rgBuckets = (STTABLE_BUCKET**)_buffBucketPtrs.QueryPtr(); + + return rgBuckets[dwHash % _cBuckets]; + } + + DWORD + WINAPI + HashString( + LPCSTR szString + ) + { + DWORD dwRet = 0; + + // + // Create a hash by adding up the ascii values + // of each character in a case-insensitive manner + // + + if ( szString ) + { + while ( *szString ) + { + dwRet += ( (*szString) | 0x20 ); + szString++; + } + } + + return dwRet; + } +}; + +#endif // _STTABLE_H diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/sttimer.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/sttimer.h new file mode 100644 index 0000000000..f5a10817a5 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/open-inc/sttimer.h @@ -0,0 +1,232 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _STTIMER_H +#define _STTIMER_H + +class STTIMER +{ +public: + + STTIMER() + : _pTimer( NULL ) + { + } + + virtual + ~STTIMER() + { + if ( _pTimer ) + { + CancelTimer(); + + CloseThreadpoolTimer( _pTimer ); + + _pTimer = NULL; + } + } + + HRESULT + InitializeTimer( + PTP_TIMER_CALLBACK pfnCallback, + VOID * pContext, + DWORD dwInitialWait = 0, + DWORD dwPeriod = 0 + ) + { + _pTimer = CreateThreadpoolTimer( pfnCallback, + pContext, + NULL ); + + if ( !_pTimer ) + { + return HRESULT_FROM_WIN32( GetLastError() ); + } + + if ( dwInitialWait ) + { + SetTimer( dwInitialWait, + dwPeriod ); + } + + return S_OK; + } + + VOID + SetTimer( + DWORD dwInitialWait, + DWORD dwPeriod = 0 + ) + { + FILETIME ftInitialWait; + + if ( dwInitialWait == 0 && dwPeriod == 0 ) + { + // + // Special case. We are preventing new callbacks + // from being queued. Any existing callbacks in the + // queue will still run. + // + // This effectively disables the timer. It can be + // re-enabled by setting non-zero initial wait or + // period values. + // + + SetThreadpoolTimer( _pTimer, NULL, 0, 0 ); + return; + } + + InitializeRelativeFileTime( &ftInitialWait, dwInitialWait ); + + SetThreadpoolTimer( _pTimer, + &ftInitialWait, + dwPeriod, + 0 ); + } + + VOID + CancelTimer() + { + // + // Disable the timer + // + + SetTimer( 0 ); + + // + // Wait until any callbacks queued prior to disabling + // have completed. + // + + WaitForThreadpoolTimerCallbacks( _pTimer, TRUE ); + } + +private: + + VOID + InitializeRelativeFileTime( + FILETIME * pft, + DWORD dwMilliseconds + ) + { + LARGE_INTEGER li; + + // + // The pftDueTime parameter expects the time to be + // expressed as the number of 100 nanosecond intervals + // times -1. + // + // To convert from milliseconds, we'll multiply by + // -10000 + // + + li.QuadPart = (LONGLONG)dwMilliseconds * -10000; + + pft->dwHighDateTime = li.HighPart; + pft->dwLowDateTime = li.LowPart; + }; + + TP_TIMER * _pTimer; +}; + +class STELAPSED +{ +public: + + STELAPSED() + : _dwInitTime( 0 ), + _dwInitTickCount( 0 ), + _dwPerfCountsPerMillisecond( 0 ), + _fUsingHighResolution( FALSE ) + { + LARGE_INTEGER li; + BOOL fResult; + + _dwInitTickCount = GetTickCount64(); + + fResult = QueryPerformanceFrequency( &li ); + + if ( !fResult ) + { + goto Finished; + } + + _dwPerfCountsPerMillisecond = li.QuadPart / 1000; + + fResult = QueryPerformanceCounter( &li ); + + if ( !fResult ) + { + goto Finished; + } + + _dwInitTime = li.QuadPart / _dwPerfCountsPerMillisecond; + + _fUsingHighResolution = TRUE; + +Finished: + + return; + } + + virtual + ~STELAPSED() + { + } + + LONGLONG + QueryElapsedTime() + { + LARGE_INTEGER li; + + if ( _fUsingHighResolution && QueryPerformanceCounter( &li ) ) + { + DWORD64 dwCurrentTime = li.QuadPart / _dwPerfCountsPerMillisecond; + + if ( dwCurrentTime < _dwInitTime ) + { + // + // It's theoretically possible that QueryPerformanceCounter + // may return slightly different values on different CPUs. + // In this case, we don't want to return an unexpected value + // so we'll return zero. This is acceptable because + // presumably such a case would only happen for a very short + // time window. + // + // It would be possible to prevent this by ensuring processor + // affinity for all calls to QueryPerformanceCounter, but that + // would be undesirable in the general case because it could + // introduce unnecessary context switches and potentially a + // CPU bottleneck. + // + // Note that this issue also applies to callers doing rapid + // calls to this function. If a caller wants to mitigate + // that, they could enforce the affinitization, or they + // could implement a similar sanity check when comparing + // returned values from this function. + // + + return 0; + } + + return dwCurrentTime - _dwInitTime; + } + + return GetTickCount64() - _dwInitTickCount; + } + + BOOL + QueryUsingHighResolution() + { + return _fUsingHighResolution; + } + +private: + + DWORD64 _dwInitTime; + DWORD64 _dwInitTickCount; + DWORD64 _dwPerfCountsPerMillisecond; + BOOL _fUsingHighResolution; +}; + +#endif // _STTIMER_H \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/dbgutil2.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/dbgutil2.h new file mode 100644 index 0000000000..1c4d2d4381 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/dbgutil2.h @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +# ifndef _DBGUTIL_H_ +# define _DBGUTIL_H_ + + +// begin_user_modifiable + +// +// define DEBUG_FLAGS_VAR to assure that DebugFlags will stay private to +// iisutil. This is important in the case when iisutil is linked as static library +// +#define DEBUG_FLAGS_VAR g_dwDebugFlagsIISUtil + +// +// Modify the following flags if necessary +// + +# define DEFAULT_OUTPUT_FLAGS ( DbgOutputKdb ) + + +// end_user_modifiable +// begin_user_unmodifiable + + + +/************************************************************ + * Include Headers + ************************************************************/ + +# include + + +// +// Define the debugging constants +// + +# define DEBUG_ALLOC_CACHE 0x01000000 +# define DEBUG_SCHED 0x02000000 +# define DEBUG_RESOURCE 0x04000000 +# define DEBUG_INET_MONITOR 0x08000000 +# define DEBUG_PIPEDATA 0x10000000 + +// Use the default constants from pudebug.h + +# endif /* _DBGUTIL_H_ */ + +/************************ End of File ***********************/ diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/irtldbg.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/irtldbg.h new file mode 100644 index 0000000000..3c6c48e7b1 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/irtldbg.h @@ -0,0 +1,154 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef __IRTLDBG_H__ +#define __IRTLDBG_H__ + +#ifndef __IRTLMISC_H__ +# include +#endif + +/* Ensure that MessageBoxes can popup */ +# define RUNNING_AS_SERVICE 1 + + +#ifdef _AFX + /* Assure compatiblity with MFC */ + +# define IRTLASSERT(x) ASSERT(x) +# define IRTLVERIFY(x) VERIFY(x) + +#else /* !_AFX */ + +# if DBG || defined(_DEBUG) +# define IRTLDEBUG +# endif + +# if defined(IRTLDEBUG) +# ifndef USE_DEBUG_CRTS + /* IIS (and NT) do not ship msvcrtD.dll, per the VC license, + * so we can't use the assertion code from . Use similar + * macros from instead. */ +# include + + /* workaround for /W4 warnings about 'constant expressions' */ +# define IRTLASSERT(f) \ + ((void) ((f) || (PuDbgAssertFailed(DBG_CONTEXT, #f, ""), 0) )) + +# elif defined(_MSC_VER) && (_MSC_VER >= 1000) + /* Use the new debugging tools in Visual C++ 4.x */ +# include + /* _ASSERTE will give a more meaningful message, but the string takes + * space. Use _ASSERT if this is an issue. */ +# define IRTLASSERT(f) _ASSERTE(f) +# else +# include +# define IRTLASSERT(f) assert(f) +# endif + +# ifdef _PREFAST_ +# undef IRTLASSERT +# define IRTLASSERT(f) ((void)0) +# endif + +# define IRTLVERIFY(f) IRTLASSERT(f) +# define DEBUG_ONLY(f) (f) +# define TRACE IrtlTrace +# define TRACE0(psz) IrtlTrace(_T("%s"), _T(psz)) +# define TRACE1(psz, p1) IrtlTrace(_T(psz), p1) +# define TRACE2(psz, p1, p2) IrtlTrace(_T(psz), p1, p2) +# define TRACE3(psz, p1, p2, p3) IrtlTrace(_T(psz), p1, p2, p3) +# define ASSERT_VALID(pObj) \ + do {IRTLASSERT((pObj) != NULL); (pObj)->AssertValid();} while (0) +# define DUMP(pObj) \ + do {IRTLASSERT((pObj) != NULL); (pObj)->Dump();} while (0) + +# else /* !_DEBUG */ + + /* These macros should all compile away to nothing */ +# define IRTLASSERT(f) ((void)0) +# define IRTLVERIFY(f) ((void)(f)) +# define DEBUG_ONLY(f) ((void)0) +# define TRACE 1 ? (void)0 : IrtlTrace +# define TRACE0(psz) +# define TRACE1(psz, p1) +# define TRACE2(psz, p1, p2) +# define TRACE3(psz, p1, p2, p3) +# define ASSERT_VALID(pObj) ((void)0) +# define DUMP(pObj) ((void)0) + +# endif /* !_DEBUG */ + + +# define ASSERT_POINTER(p, type) \ + IRTLASSERT((p) != NULL) + +#define ASSERT_STRING(s) \ + IRTLASSERT(((s) != NULL)) + +/* Declarations for non-Windows apps */ + +# ifndef _WINDEF_ +typedef void* LPVOID; +typedef const void* LPCVOID; +typedef unsigned int UINT; +typedef int BOOL; +typedef const char* LPCTSTR; +# endif /* _WINDEF_ */ + +# ifndef TRUE +# define FALSE 0 +# define TRUE 1 +# endif + +#endif /* !_AFX */ + + +#ifdef __cplusplus + +// Compile-time (not run-time) assertion. Code will not compile if +// expr is false. Note: there is no non-debug version of this; we +// want this for all builds. The compiler optimizes the code away. +template struct static_checker; +template <> struct static_checker {}; // specialize only for `true' +#define STATIC_ASSERT(expr) static_checker< (expr) >() + +#endif /* !__cplusplus */ + +/* Writes trace messages to debug stream */ +extern +#ifdef __cplusplus +"C" +#endif /* !__cplusplus */ +IRTL_DLLEXP +void __cdecl +IrtlTrace( + LPCTSTR pszFormat, + ...); + + +#ifdef _DEBUG +# define IRTL_DEBUG_INIT() IrtlDebugInit() +# define IRTL_DEBUG_TERM() IrtlDebugTerm() +#else /* !_DEBUG */ +# define IRTL_DEBUG_INIT() ((void)0) +# define IRTL_DEBUG_TERM() ((void)0) +#endif /* !_DEBUG */ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* should be called from main(), WinMain(), or DllMain() */ +IRTL_DLLEXP void +IrtlDebugInit(); + +IRTL_DLLEXP void +IrtlDebugTerm(); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __IRTLDBG_H__ */ diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/irtlmisc.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/irtlmisc.h new file mode 100644 index 0000000000..02bfa2d065 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/irtlmisc.h @@ -0,0 +1,131 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef __IRTLMISC_H__ +#define __IRTLMISC_H__ + +#include + +//-------------------------------------------------------------------- +// These declarations are needed to export the template classes from +// IisRtl.DLL and import them into other modules. + +// DEBGUDEBUG +/** +#ifndef IRTL_DLLEXP +# ifdef DLL_IMPLEMENTATION +# define IRTL_DLLEXP __declspec(dllexport) +# ifdef IMPLEMENTATION_EXPORT +# define IRTL_EXPIMP +# else +# undef IRTL_EXPIMP +# endif +# elif defined LIB_IMPLEMENTATION +# define IRTL_DLLEXP +# define IRTL_EXPIMP extern +# else +# define IRTL_DLLEXP __declspec(dllimport) +# define IRTL_EXPIMP extern +# endif // !DLL_IMPLEMENTATION +#endif // !IRTL_DLLEXP +*/ + +#define IRTL_DLLEXP +#define IRTL_EXPIMP + + + + + +//-------------------------------------------------------------------- +// Miscellaneous functions + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + + +// Heap routines + +// Private IIS heap +HANDLE +WINAPI +IisHeap(); + +// Allocate dwBytes +LPVOID +WINAPI +IisMalloc( + IN SIZE_T dwBytes); + +// Allocate dwBytes. Memory is zeroed +LPVOID +WINAPI +IisCalloc( + IN SIZE_T dwBytes); + +// Reallocate lpMem to dwBytes +LPVOID +WINAPI +IisReAlloc( + IN LPVOID lpMem, + IN SIZE_T dwBytes); + +// Free lpMem +BOOL +WINAPI +IisFree( + IN LPVOID lpMem); + +// additional IISRTL initialization +BOOL +WINAPI +InitializeIISRTL(); + +// call before unloading IISRTL +void +WINAPI +TerminateIISRTL(); + +// case-insensitive strstr +IRTL_DLLEXP const char* stristr(const char* pszString, const char* pszSubString); + +// how many CPUs on this machine? +inline int NumProcessors() +{ + static int s_nCPUs = 0; + + if (s_nCPUs == 0) + { + SYSTEM_INFO si; + GetSystemInfo(&si); + s_nCPUs = si.dwNumberOfProcessors; + } + return s_nCPUs; +} + + +// how many CPUs on this machine? +inline int ProcessorType() +{ + static int s_nProcessorType = 0; + + if (s_nProcessorType == 0) + { + SYSTEM_INFO si; + GetSystemInfo(&si); + s_nProcessorType = si.dwProcessorType; + } + return s_nProcessorType; +} + + +#ifdef __cplusplus +} +#endif // __cplusplus + +#define HRESULT_FROM_GLE() ( GetLastError() != NO_ERROR ) \ + ? HRESULT_FROM_WIN32( GetLastError() ) \ + : E_FAIL + +#endif // __IRTLMISC_H__ diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/memorylog.hxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/memorylog.hxx new file mode 100644 index 0000000000..effa543259 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/memorylog.hxx @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _MEMORYLOG_HXX_ +#define _MEMORYLOG_HXX_ + +//#include "buffer.hxx" + +class CMemoryLog +{ +public: + CMemoryLog(DWORD dwMaxByteSize); + ~CMemoryLog(); + + // + // Override the new and delete operator to make them + // use LocalAlloc so that CMemoryLog + // can be safely constructed and deleted + // in the DllMain() + // + + VOID * + operator new( + size_t size + ) + { + return LocalAlloc( LPTR, size ); + } + + VOID + operator delete( + VOID * pMemoryLog + ) + { + DBG_ASSERT( pMemoryLog != NULL ); + LocalFree( pMemoryLog ); + } + + // appends to memory log + DWORD Append(LPCSTR pszOutput, + DWORD cchLen + ); +private: + CMemoryLog(); + + // pointer to the beginning of the memory buffer + CHAR *m_pBufferBegin; + // pointer to the byte 1 beyond the end of the last message + CHAR *m_pLastMessageEnd; + // pointer to the end of the memory buffer + CHAR *m_pBufferEnd; + + // Used for storage + BUFFER m_buf; + + // TRUE if storage could be allocated, otherwise FALSE + BOOL m_fValid; + + CRITICAL_SECTION m_cs; + + // to be able to tell if the critsec was initialized successfully + BOOL m_fCritSecInitialized; + +}; + +#endif // _MEMORYLOG_HXX_ + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/precomp.hxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/precomp.hxx new file mode 100644 index 0000000000..d012c7ee29 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/precomp.hxx @@ -0,0 +1,9 @@ +#include +#include "tchar.h" +#include "dbgutil.h" +#include "ntassert.h" +#include "buffer.h" +#include "stringa.h" +#include "stringu.h" +#include "stdlib.h" +#include "stdio.h" diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/pudebug.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/pudebug.h new file mode 100644 index 0000000000..d42153d457 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/include/pudebug.h @@ -0,0 +1,748 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#if !defined(BUILD_PUDEBUG) +// +// if we are not using this header for building the pudebug library +// then better this be used with dbgutil.h +// + # ifndef _DBGUTIL_H_ + // error Please make sure you included dbgutil.h! + // error Do not include pudebug.h directly + #include + # endif // _DBGUTIL_H_ +#endif + +# ifndef _PUDEBUG_H_ +# define _PUDEBUG_H_ + +#ifndef _NO_TRACING_ +# define _NO_TRACING_ +#endif // _NO_TRACING_ + +/************************************************************ + * Include Headers + ************************************************************/ + +# ifdef __cplusplus +extern "C" { +# endif // __cplusplus + +# include + +# ifndef dllexp +# define dllexp __declspec( dllexport) +# endif // dllexp + +#include + +#ifndef IN_OUT +#define IN_OUT __inout +#endif + +/*********************************************************** + * Macros + ************************************************************/ + +enum PRINT_REASONS { + PrintNone = 0x0, // Nothing to be printed + PrintError = 0x1, // An error message + PrintWarning = 0x2, // A warning message + PrintLog = 0x3, // Just logging. Indicates a trace of where ... + PrintMsg = 0x4, // Echo input message + PrintCritical = 0x5, // Print and Exit + PrintAssertion= 0x6 // Printing for an assertion failure + }; + + +enum DEBUG_OUTPUT_FLAGS { + DbgOutputNone = 0x0, // None + DbgOutputKdb = 0x1, // Output to Kernel Debugger + DbgOutputLogFile = 0x2, // Output to LogFile + DbgOutputTruncate = 0x4, // Truncate Log File if necessary + DbgOutputStderr = 0x8, // Send output to std error + DbgOutputBackup = 0x10, // Make backup of debug file ? + DbgOutputMemory = 0x20, // Dump to memory buffer + DbgOutputAll = 0xFFFFFFFF // All the bits set. + }; + + +# define MAX_LABEL_LENGTH ( 100) + + +// The following flags are used internally to track what level of tracing we +// are currently using. Bitmapped for extensibility. +#define DEBUG_FLAG_ODS 0x00000001 +//#define DEBUG_FLAG_INFO 0x00000002 +//#define DEBUG_FLAG_WARN 0x00000004 +//#define DEBUG_FLAG_ERROR 0x00000008 +// The following are used internally to determine whether to log or not based +// on what the current state is +//#define DEBUG_FLAGS_INFO (DEBUG_FLAG_ODS | DEBUG_FLAG_INFO) +//#define DEBUG_FLAGS_WARN (DEBUG_FLAG_ODS | DEBUG_FLAG_INFO | DEBUG_FLAG_WARN) +//#define DEBUG_FLAGS_ERROR (DEBUG_FLAG_ODS | DEBUG_FLAG_INFO | DEBUG_FLAG_WARN | DEBUG_FLAG_ERROR) + +#define DEBUG_FLAGS_ANY (DEBUG_FLAG_INFO | DEBUG_FLAG_WARN | DEBUG_FLAG_ERROR) + +// +// user of DEBUG infrastructure may choose unique variable name for DEBUG_FLAGS +// that's specially useful for cases where DEBUG infrastructure is used within +// static library (static library may prefer to maintain it's own DebugFlags independent +// on the main program it links to +// +#ifndef DEBUG_FLAGS_VAR +#define DEBUG_FLAGS_VAR g_dwDebugFlags +#endif + +extern +#ifdef __cplusplus +"C" +# endif // _cplusplus + DWORD DEBUG_FLAGS_VAR ; // Debugging Flags + +# define DECLARE_DEBUG_VARIABLE() + +# define SET_DEBUG_FLAGS( dwFlags) DEBUG_FLAGS_VAR = dwFlags +# define GET_DEBUG_FLAGS() ( DEBUG_FLAGS_VAR ) + +# define LOAD_DEBUG_FLAGS_FROM_REG(hkey, dwDefault) \ + DEBUG_FLAGS_VAR = PuLoadDebugFlagsFromReg((hkey), (dwDefault)) + +# define LOAD_DEBUG_FLAGS_FROM_REG_STR(pszRegKey, dwDefault) \ + DEBUG_FLAGS_VAR = PuLoadDebugFlagsFromRegStr((pszRegKey), (dwDefault)) + +# define SAVE_DEBUG_FLAGS_IN_REG(hkey, dwDbg) \ + PuSaveDebugFlagsInReg((hkey), (dwDbg)) + +# define DEBUG_IF( arg, s) if ( DEBUG_ ## arg & GET_DEBUG_FLAGS()) { \ + s \ + } else {} + +# define IF_DEBUG( arg) if ( DEBUG_## arg & GET_DEBUG_FLAGS()) + + +/*++ + class DEBUG_PRINTS + + This class is responsible for printing messages to log file / kernel debugger + + Currently the class supports only member functions for char. + ( not unicode-strings). + +--*/ + + +typedef struct _DEBUG_PRINTS { + + CHAR m_rgchLabel[MAX_LABEL_LENGTH]; + CHAR m_rgchLogFilePath[MAX_PATH]; + CHAR m_rgchLogFileName[MAX_PATH]; + HANDLE m_LogFileHandle; + HANDLE m_StdErrHandle; + BOOL m_fInitialized; + BOOL m_fBreakOnAssert; + DWORD m_dwOutputFlags; + VOID *m_pMemoryLog; +} DEBUG_PRINTS, FAR * LPDEBUG_PRINTS; + + +LPDEBUG_PRINTS +PuCreateDebugPrintsObject( + IN const char * pszPrintLabel, + IN DWORD dwOutputFlags); + +// +// frees the debug prints object and closes any file if necessary. +// Returns NULL on success or returns pDebugPrints on failure. +// +LPDEBUG_PRINTS +PuDeleteDebugPrintsObject( + IN_OUT LPDEBUG_PRINTS pDebugPrints); + + +VOID +PuDbgPrint( + IN_OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN const char * pszFormat, + ...); + // arglist +VOID +PuDbgPrintW( + IN_OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN const WCHAR * pszFormat, + ...); // arglist + +// PuDbgPrintError is similar to PuDbgPrint() but allows +// one to print error code in friendly manner +VOID +PuDbgPrintError( + IN_OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN DWORD dwError, + IN const char * pszFormat, + ...); // arglist + +/*++ + PuDbgDump() does not do any formatting of output. + It just dumps the given message onto the debug destinations. +--*/ +VOID +PuDbgDump( + IN_OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN const char * pszDump + ); + +// +// PuDbgAssertFailed() *must* be __cdecl to properly capture the +// thread context at the time of the failure. +// + +INT +__cdecl +PuDbgAssertFailed( + IN_OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN const char * pszExpression, + IN const char * pszMessage); + +INT +WINAPI +PuDbgPrintAssertFailed( + IN_OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN const char * pszExpression, + IN const char * pszMessage); + +VOID +PuDbgCaptureContext ( + OUT PCONTEXT ContextRecord + ); + +VOID +PuDbgPrintCurrentTime( + IN_OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName + ); + +VOID +PuSetDbgOutputFlags( + IN_OUT LPDEBUG_PRINTS pDebugPrints, + IN DWORD dwFlags); + +DWORD +PuGetDbgOutputFlags( + IN const LPDEBUG_PRINTS pDebugPrints); + + +// +// Following functions return Win32 error codes. +// NO_ERROR if success +// + +DWORD +PuOpenDbgPrintFile( + IN_OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFileName, + IN const char * pszPathForFile); + +DWORD +PuReOpenDbgPrintFile( + IN_OUT LPDEBUG_PRINTS pDebugPrints); + +DWORD +PuCloseDbgPrintFile( + IN_OUT LPDEBUG_PRINTS pDebugPrints); + +DWORD +PuOpenDbgMemoryLog( + IN_OUT LPDEBUG_PRINTS pDebugPrints); + +DWORD +PuCloseDbgMemoryLog( + IN_OUT LPDEBUG_PRINTS pDebugPrints); + +DWORD +PuLoadDebugFlagsFromReg(IN HKEY hkey, IN DWORD dwDefault); + +DWORD +PuLoadDebugFlagsFromRegStr(IN LPCSTR pszRegKey, IN DWORD dwDefault); + +DWORD +PuSaveDebugFlagsInReg(IN HKEY hkey, IN DWORD dwDbg); + + +# define PuPrintToKdb( pszOutput) \ + if ( pszOutput != NULL) { \ + OutputDebugString( pszOutput); \ + } else {} + + + +# ifdef __cplusplus +}; +# endif // __cplusplus + +// begin_user_unmodifiable + + + +/*********************************************************** + * Macros + ************************************************************/ + + +extern +#ifdef __cplusplus +"C" +# endif // _cplusplus +DEBUG_PRINTS * g_pDebug; // define a global debug variable + +# if DBG + +// For the CHK build we want ODS enabled. For an explanation of these flags see +// the comment just after the definition of DBG_CONTEXT +# define DECLARE_DEBUG_PRINTS_OBJECT() \ + DEBUG_PRINTS * g_pDebug = NULL; \ + DWORD DEBUG_FLAGS_VAR = DEBUG_FLAG_ERROR; + +#else // !DBG + +# define DECLARE_DEBUG_PRINTS_OBJECT() \ + DEBUG_PRINTS * g_pDebug = NULL; \ + DWORD DEBUG_FLAGS_VAR = 0; + +#endif // !DBG + + +// +// Call the following macro as part of your initialization for program +// planning to use the debugging class. +// +/** DEBUGDEBUG +# define CREATE_DEBUG_PRINT_OBJECT( pszLabel) \ + g_pDebug = PuCreateDebugPrintsObject( pszLabel, DEFAULT_OUTPUT_FLAGS);\ + if ( g_pDebug == NULL) { \ + OutputDebugStringA( "Unable to Create Debug Print Object \n"); \ + } +*/ + +// +// Call the following macro once as part of the termination of program +// which uses the debugging class. +// +# define DELETE_DEBUG_PRINT_OBJECT( ) \ + g_pDebug = PuDeleteDebugPrintsObject( g_pDebug); + + +# define VALID_DEBUG_PRINT_OBJECT() \ + ( ( g_pDebug != NULL) && g_pDebug->m_fInitialized) + + +// +// Use the DBG_CONTEXT without any surrounding braces. +// This is used to pass the values for global DebugPrintObject +// and File/Line information +// +//# define DBG_CONTEXT g_pDebug, __FILE__, __LINE__, __FUNCTION__ + +// The 3 main tracing macros, each one corresponds to a different level of +// tracing + +// The 3 main tracing macros, each one corresponds to a different level of +// tracing +//# define DBGINFO(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_INFO) { PuDbgPrint args; }} +//# define DBGWARN(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_WARN) { PuDbgPrint args; }} +//# define DBGERROR(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_ERROR) { PuDbgPrint args; }} + +# define DBGINFOW(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_INFO) { PuDbgPrintW args; }} +# define DBGWARNW(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_WARN) { PuDbgPrintW args; }} +# define DBGERRORW(args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_ERROR) { PuDbgPrintW args; }} + + +// +// DBGPRINTF() is printing function ( much like printf) but always called +// with the DBG_CONTEXT as follows +// DBGPRINTF( ( DBG_CONTEXT, format-string, arguments for format list)); +// +# define DBGPRINTF DBGINFO + +// +// DPERROR() is printing function ( much like printf) but always called +// with the DBG_CONTEXT as follows +// DPERROR( ( DBG_CONTEXT, error, format-string, +// arguments for format list)); +// +# define DPERROR( args) {if (DEBUG_FLAGS_VAR & DEBUG_FLAGS_ERROR) { PuDbgPrintError args; }} + +# if DBG + +# define DBG_CODE(s) s /* echoes code in debugging mode */ + +// The same 3 main tracing macros however in this case the macros are only compiled +// into the CHK build. This is necessary because some tracing info used functions or +// variables which are not compiled into the FRE build. +# define CHKINFO(args) { PuDbgPrint args; } +# define CHKWARN(args) { PuDbgPrint args; } +# define CHKERROR(args) { PuDbgPrint args; } + +# define CHKINFOW(args) { PuDbgPrintW args; } +# define CHKWARNW(args) { PuDbgPrintW args; } +# define CHKERRORW(args) { PuDbgPrintW args; } + + +#ifndef DBG_ASSERT +# ifdef _PREFAST_ +# define DBG_ASSERT(exp) ((void)0) /* Do Nothing */ +# define DBG_ASSERT_MSG(exp, pszMsg) ((void)0) /* Do Nothing */ +# define DBG_REQUIRE( exp) ((void) (exp)) +# else // !_PREFAST_ +# define DBG_ASSERT( exp ) \ + ( (VOID)( ( exp ) || ( DebugBreak(), \ + PuDbgPrintAssertFailed( DBG_CONTEXT, #exp, "" ) ) ) ) + +# define DBG_ASSERT_MSG( exp, pszMsg) \ + ( (VOID)( ( exp ) || ( DebugBreak(), \ + PuDbgPrintAssertFailed( DBG_CONTEXT, #exp, pszMsg ) ) ) ) + +# define DBG_REQUIRE( exp ) \ + DBG_ASSERT( exp ) +# endif // !_PREFAST_ +#endif + + +# define DBG_LOG() PuDbgPrint( DBG_CONTEXT, "\n" ) + +# define DBG_OPEN_LOG_FILE( pszFile, pszPath ) \ + PuOpenDbgPrintFile( g_pDebug, (pszFile), (pszPath) ) + +# define DBG_CLOSE_LOG_FILE( ) \ + PuCloseDbgPrintFile( g_pDebug ) + +# define DBG_OPEN_MEMORY_LOG( ) \ + PuOpenDbgMemoryLog( g_pDebug ) + + +# define DBGDUMP( args ) PuDbgDump args + +# define DBGPRINT_CURRENT_TIME() PuDbgPrintCurrentTime( DBG_CONTEXT ) + +# else // !DBG + +# define DBG_CODE(s) ((void)0) /* Do Nothing */ + +# define CHKINFO(args) ((void)0) /* Do Nothing */ +# define CHKWARN(args) ((void)0) /* Do Nothing */ +# define CHKERROR(args) ((void)0) /* Do Nothing */ + +# define CHKINFOW(args) ((void)0) /* Do Nothing */ +# define CHKWARNW(args) ((void)0) /* Do Nothing */ +# define CHKERRORW(args) ((void)0) /* Do Nothing */ + +#ifndef DBG_ASSERT +# define DBG_ASSERT(exp) ((void)0) /* Do Nothing */ + +# define DBG_ASSERT_MSG(exp, pszMsg) ((void)0) /* Do Nothing */ + +# define DBG_REQUIRE( exp) ((void) (exp)) +#endif // !DBG_ASSERT + +# define DBGDUMP( args) ((void)0) /* Do nothing */ + +# define DBG_LOG() ((void)0) /* Do Nothing */ + +# define DBG_OPEN_LOG_FILE( pszFile, pszPath) ((void)0) /* Do Nothing */ + +# define DBG_OPEN_MEMORY_LOG() ((void)0) /* Do Nothing */ + +# define DBG_CLOSE_LOG_FILE() ((void)0) /* Do Nothing */ + +# define DBGPRINT_CURRENT_TIME() ((void)0) /* Do Nothing */ + +# endif // !DBG + + +// end_user_unmodifiable + +// begin_user_unmodifiable + + +#ifdef ASSERT +# undef ASSERT +#endif + + +# define ASSERT( exp) DBG_ASSERT( exp) + + +// end_user_unmodifiable + +// begin_user_modifiable + +// +// Debugging constants consist of two pieces. +// All constants in the range 0x0 to 0x8000 are reserved +// User extensions may include additional constants (bit flags) +// + +# define DEBUG_API_ENTRY 0x00000001L +# define DEBUG_API_EXIT 0x00000002L +# define DEBUG_INIT_CLEAN 0x00000004L +# define DEBUG_ERROR 0x00000008L + + // End of Reserved Range +# define DEBUG_RESERVED 0x00000FFFL + +// end_user_modifiable + + + +/*********************************************************** + * Platform Type related variables and macros + ************************************************************/ + +// +// Enum for product types +// + +typedef enum _PLATFORM_TYPE { + + PtInvalid = 0, // Invalid + PtNtWorkstation = 1, // NT Workstation + PtNtServer = 2, // NT Server + +} PLATFORM_TYPE; + +// +// IISGetPlatformType is the function used to the platform type +// + +extern +#ifdef __cplusplus +"C" +# endif // _cplusplus +PLATFORM_TYPE +IISGetPlatformType( + VOID + ); + +// +// External Macros +// + +#define InetIsNtServer( _pt ) ((_pt) == PtNtServer) +#define InetIsNtWksta( _pt ) ((_pt) == PtNtWorkstation) +#define InetIsValidPT(_pt) ((_pt) != PtInvalid) + +extern +#ifdef __cplusplus +"C" +# endif // _cplusplus +PLATFORM_TYPE g_PlatformType; + + +// Use the DECLARE_PLATFORM_TYPE macro to declare the platform type +#define DECLARE_PLATFORM_TYPE() \ + PLATFORM_TYPE g_PlatformType = PtInvalid; + +// Use the INITIALIZE_PLATFORM_TYPE to init the platform type +// This should typically go inside the DLLInit or equivalent place. +#define INITIALIZE_PLATFORM_TYPE() \ + g_PlatformType = IISGetPlatformType(); + +// +// Additional Macros to use the Platform Type +// + +#define TsIsNtServer( ) InetIsNtServer(g_PlatformType) +#define TsIsNtWksta( ) InetIsNtWksta(g_PlatformType) +#define IISIsValidPlatform() InetIsValidPT(g_PlatformType) +#define IISPlatformType() (g_PlatformType) + + +/*********************************************************** + * Some utility functions for Critical Sections + ************************************************************/ + +// +// IISSetCriticalSectionSpinCount() provides a thunk for the +// original NT4.0sp3 API SetCriticalSectionSpinCount() for CS with Spin counts +// Users of this function should definitely dynlink with kernel32.dll, +// Otherwise errors will surface to a large extent +// +extern +# ifdef __cplusplus +"C" +# endif // _cplusplus +DWORD +IISSetCriticalSectionSpinCount( + LPCRITICAL_SECTION lpCriticalSection, + DWORD dwSpinCount +); + + +// +// Macro for the calls to SetCriticalSectionSpinCount() +// +# define SET_CRITICAL_SECTION_SPIN_COUNT( lpCS, dwSpins) \ + IISSetCriticalSectionSpinCount( (lpCS), (dwSpins)) + +// +// IIS_DEFAULT_CS_SPIN_COUNT is the default value of spins used by +// Critical sections defined within IIS. +// NYI: We should have to switch the individual values based on experiments! +// Current value is an arbitrary choice +// +# define IIS_DEFAULT_CS_SPIN_COUNT (1000) + +// +// Initializes a critical section and sets its spin count +// to IIS_DEFAULT_CS_SPIN_COUNT. Equivalent to +// InitializeCriticalSectionAndSpinCount(lpCS, IIS_DEFAULT_CS_SPIN_COUNT), +// but provides a safe thunking layer for older systems that don't provide +// this API. +// +extern +# ifdef __cplusplus +"C" +# endif // _cplusplus +BOOL +IISInitializeCriticalSection( + LPCRITICAL_SECTION lpCriticalSection +); + +// +// Macro for the calls to InitializeCriticalSection() +// +# define INITIALIZE_CRITICAL_SECTION(lpCS) IISInitializeCriticalSection(lpCS) + +# endif /* _DEBUG_HXX_ */ + +// +// The following macros allow the automatic naming of certain Win32 objects. +// See IIS\SVCS\IISRTL\WIN32OBJ.C for details on the naming convention. +// +// Set IIS_NAMED_WIN32_OBJECTS to a non-zero value to enable named events, +// semaphores, and mutexes. +// + +#if DBG +#define IIS_NAMED_WIN32_OBJECTS 1 +#else +#define IIS_NAMED_WIN32_OBJECTS 0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +HANDLE +PuDbgCreateEvent( + __in LPSTR FileName, + IN ULONG LineNumber, + __in LPSTR MemberName, + IN PVOID Address, + IN BOOL ManualReset, + IN BOOL InitialState + ); + +HANDLE +PuDbgCreateSemaphore( + __in LPSTR FileName, + IN ULONG LineNumber, + __in LPSTR MemberName, + IN PVOID Address, + IN LONG InitialCount, + IN LONG MaximumCount + ); + +HANDLE +PuDbgCreateMutex( + __in LPSTR FileName, + IN ULONG LineNumber, + __in LPSTR MemberName, + IN PVOID Address, + IN BOOL InitialOwner + ); + +#ifdef __cplusplus +} // extern "C" +#endif + +#if IIS_NAMED_WIN32_OBJECTS + +#define IIS_CREATE_EVENT( membername, address, manual, state ) \ + PuDbgCreateEvent( \ + (LPSTR)__FILE__, \ + (ULONG)__LINE__, \ + (membername), \ + (PVOID)(address), \ + (manual), \ + (state) \ + ) + +#define IIS_CREATE_SEMAPHORE( membername, address, initial, maximum ) \ + PuDbgCreateSemaphore( \ + (LPSTR)__FILE__, \ + (ULONG)__LINE__, \ + (membername), \ + (PVOID)(address), \ + (initial), \ + (maximum) \ + ) + +#define IIS_CREATE_MUTEX( membername, address, initial ) \ + PuDbgCreateMutex( \ + (LPSTR)__FILE__, \ + (ULONG)__LINE__, \ + (membername), \ + (PVOID)(address), \ + (initial) \ + ) + +#else // !IIS_NAMED_WIN32_OBJECTS + +#define IIS_CREATE_EVENT( membername, address, manual, state ) \ + CreateEventA( \ + NULL, \ + (manual), \ + (state), \ + NULL \ + ) + +#define IIS_CREATE_SEMAPHORE( membername, address, initial, maximum ) \ + CreateSemaphoreA( \ + NULL, \ + (initial), \ + (maximum), \ + NULL \ + ) + +#define IIS_CREATE_MUTEX( membername, address, initial ) \ + CreateMutexA( \ + NULL, \ + (initial), \ + NULL \ + ) + +#endif // IIS_NAMED_WIN32_OBJECTS + + +/************************ End of File ***********************/ + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/reftrace.vcxproj b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/reftrace.vcxproj new file mode 100644 index 0000000000..257df53c47 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/reftrace.vcxproj @@ -0,0 +1,78 @@ + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + 15.0 + {A2599642-CBE5-4230-8511-3DC2D81874BE} + Win32Proj + reftrace + + + + StaticLibrary + v141 + + + true + + + + $(ProjectDir)include;$(IIS-Common)Include;$(IncludePath) + + + + true + precomp.hxx + _LIB;%(PreprocessorDefinitions) + + + Windows + + + + + + This project is trying to import a missing file: {0}. + + + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/reftrace.vcxproj.filters b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/reftrace.vcxproj.filters new file mode 100644 index 0000000000..b77ab9c7c1 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/reftrace.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {aaa5bb99-ba5c-4b8d-9ef9-a406282e05a6} + + + {85a83b74-9536-44d0-a7f7-96e1475f21e9} + + + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + + + include + + + include + + + include + + + include + + + include + + + include + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/irtldbg.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/irtldbg.cpp new file mode 100644 index 0000000000..06ce025bbe --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/irtldbg.cpp @@ -0,0 +1,150 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.hxx" + +#include +#include +#include +#include +#include + +#define IMPLEMENTATION_EXPORT +#include + + +void __cdecl +IrtlTrace( + LPCTSTR ptszFormat, + ...) +{ + TCHAR tszBuff[2048]; + va_list args; + + va_start(args, ptszFormat); + _vsntprintf_s(tszBuff, sizeof(tszBuff) / sizeof(tszBuff[0]), _TRUNCATE, ptszFormat, args); + va_end(args); + + DBGPRINTF(( DBG_CONTEXT, "%ls", tszBuff )); +} + + + +#ifdef IRTLDEBUG + +# if defined(USE_DEBUG_CRTS) && defined(_MSC_VER) && (_MSC_VER >= 1000) + + +# ifdef IRTLDBG_RUNNING_AS_SERVICE + +// The default assertion mechanism set up by Visual C++ 4 will not +// work with Active Server Pages because it's running inside a service +// and there is no desktop to interact with. + +// Note: for this to work properly, #define _WIN32_WINNT 0x400 before +// including or MB_SERVICE_NOTIFICATION won't be #define'd. + +int __cdecl +AspAssertHandler( + int nReportType, + char* pszErrorText, + int* pnReturn) +{ + const char szInfo[] = " (Press ABORT to terminate IIS," + " RETRY to debug this failure," + " or IGNORE to continue.)"; + char* pszMessageTitle = NULL; + int nResult = FALSE; + + *pnReturn = 0; // nothing for _CrtDbgReport to do + + // These flags enable message boxes to show up on the user's console + switch (nReportType) + { + case _CRT_WARN: + // If using MFC's TRACE macro (AfxTrace), the report hook + // (AspAssertHandler) will get called with _CRT_WARN. Ignore. + pszMessageTitle = "Warning"; + *pnReturn = 0; + return FALSE; + + case _CRT_ERROR: + pszMessageTitle = "Fatal Error"; + break; + + case _CRT_ASSERT: + pszMessageTitle = "Assertion Failed"; + break; + } + + char* pszMessageText = + static_cast(malloc(strlen(pszErrorText) + strlen(szInfo) + 1)); + + if (NULL == pszMessageText) + return FALSE; + + strcpy(pszMessageText, pszErrorText); + strcat(pszMessageText, szInfo); + + const int n = MessageBoxA(NULL, pszMessageText, pszMessageTitle, + (MB_SERVICE_NOTIFICATION | MB_TOPMOST + | MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION)); + + if (n == IDABORT) + { + exit(1); + } + else if (n == IDRETRY) + { + *pnReturn = 1; // tell _CrtDbgReport to start the debugger + nResult = TRUE; // tell _CrtDbgReport to run + } + + free(pszMessageText); + + return nResult; +} +# endif // IRTLDBG_RUNNING_AS_SERVICE +# endif // _MSC_VER >= 1000 + + + +void +IrtlDebugInit() +{ +# if defined(USE_DEBUG_CRTS) && defined(_MSC_VER) && (_MSC_VER >= 1000) +# ifdef IRTLDBG_RUNNING_AS_SERVICE + // If we end up in _CrtDbgReport, don't put up a message box + // _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); + _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); + + // Use AspAssertHandler to put up a message box instead + _CrtSetReportHook(AspAssertHandler); +# endif // IRTLDBG_RUNNING_AS_SERVICE + + + // Enable debug heap allocations & check for memory leaks at program exit + // The memory leak check will not be performed if inetinfo.exe is + // run directly under a debugger, only if it is run as a service. + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF + | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)); +# endif // _MSC_VER >= 1000 +} + + + +void +IrtlDebugTerm() +{ +# if defined(USE_DEBUG_CRTS) && defined(_MSC_VER) && (_MSC_VER >= 1000) +# ifdef IRTLDBG_RUNNING_AS_SERVICE + // Turn off AspAssertHandler, so that we don't get numerous message boxes + // if there are memory leaks on shutdown + _CrtSetReportHook(NULL); +# endif // IRTLDBG_RUNNING_AS_SERVICE +# endif // _MSC_VER >= 1000 +} + +#endif //IRTLDEBUG + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/isplat.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/isplat.cxx new file mode 100644 index 0000000000..eb13b3edde --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/isplat.cxx @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.hxx" +#include "pudebug.h" + +#define IMPLEMENTATION_EXPORT + +extern "C" +PLATFORM_TYPE +IISGetPlatformType( + VOID +) +/*++ + + This function consults the registry and determines the platform type + for this machine. + + Arguments: + + None + + Returns: + Platform type + +--*/ +{ + OSVERSIONINFOEX osVersionInfoEx = { 0 }; + DWORDLONG dwlConditionMask = 0; + BOOL fReturn = FALSE; + + osVersionInfoEx.dwOSVersionInfoSize = sizeof( osVersionInfoEx ); + + // + // If we are not workstation (Client) + // that means that we are a server or domain controller (Server) + // + osVersionInfoEx.wProductType = VER_NT_WORKSTATION; + VER_SET_CONDITION( dwlConditionMask, VER_PRODUCT_TYPE, VER_EQUAL ); + + fReturn = VerifyVersionInfo( + &osVersionInfoEx, + VER_PRODUCT_TYPE, + dwlConditionMask ); + + // + // VerifyVersionInfo fails if the return value is zero + // and GetLastError returns an error code other than ERROR_OLD_WIN_VERSION + // + if ( !fReturn && GetLastError() != ERROR_OLD_WIN_VERSION ) + { + DPERROR(( DBG_CONTEXT, + HRESULT_FROM_WIN32 ( GetLastError() ), + "VerifyVersionInfo failed\n" )); + + return PtInvalid; + } + + return ( fReturn ) ? PtNtWorkstation : PtNtServer; +} + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/memorylog.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/memorylog.cxx new file mode 100644 index 0000000000..6f303f94e0 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/memorylog.cxx @@ -0,0 +1,123 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.hxx" +#include "memorylog.hxx" +#include "pudebug.h" + +CMemoryLog::CMemoryLog(DWORD dwMaxByteSize) : + m_fValid(FALSE), + m_fCritSecInitialized(FALSE) +{ + BOOL fRet; + + fRet = m_buf.Resize(dwMaxByteSize); + if (fRet) + { + m_fValid = TRUE; + } + + m_pBufferBegin = (CHAR*) m_buf.QueryPtr(); + m_pLastMessageEnd = (CHAR*) m_buf.QueryPtr(); + m_pBufferEnd = ((CHAR*) m_buf.QueryPtr()) + m_buf.QuerySize(); + + fRet = InitializeCriticalSectionAndSpinCount(&m_cs, + 0x80000000 /* precreate event */ | + IIS_DEFAULT_CS_SPIN_COUNT ); + if (FALSE != fRet) + { + m_fCritSecInitialized = TRUE; + } + +} + +CMemoryLog::~CMemoryLog() +{ + m_pBufferBegin = NULL; + m_pLastMessageEnd = NULL; + m_pBufferEnd = NULL; + m_fValid = FALSE; + + if (m_fCritSecInitialized) + { + DeleteCriticalSection(&m_cs); + m_fCritSecInitialized = FALSE; + } +} + +// +// Appends to end of the circular memory log. +// +DWORD +CMemoryLog::Append(LPCSTR pszOutput, + DWORD cchLen + ) +{ + // make sure internal state can accept this request + if (FALSE == m_fValid || + FALSE == m_fCritSecInitialized ) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + + // make sure that we won't think we need less + // memory than we do. We are going to add 1 to + // this value next, so if it is MAX_UINT then + // we will wrap on the add. Don't allow strings + // that are that long. + if ( (ULONGLONG)cchLen + 1 > MAXDWORD ) + { + return ERROR_ARITHMETIC_OVERFLOW; + } + + // make sure the string length will fit inside the buffer + if ( cchLen + 1 > m_buf.QuerySize()) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + + CHAR * pWhereToWriteMessage = NULL; + + // need to synchronize access to m_pLastMessageEnd + EnterCriticalSection(&m_cs); + + // check if the new message will fit into the remaining space in the buffer + // previous end (+1) + new length + 1 for NULL + if (m_pLastMessageEnd + cchLen + 1 < m_pBufferEnd) + { + // it will fit in remaining space + pWhereToWriteMessage = m_pLastMessageEnd; + } + else + { + // start over at the beginning + pWhereToWriteMessage = (CHAR*)m_buf.QueryPtr(); + + // don't leave extra old goo sitting around in the buffer + ZeroMemory(m_pLastMessageEnd, m_pBufferEnd - m_pLastMessageEnd); + } + + // set end of message to pWhere + length + 1 for NULL + m_pLastMessageEnd = pWhereToWriteMessage + cchLen + 1; + + LeaveCriticalSection(&m_cs); + + // the following memcpy is outside of the criticalsection - + // this introduces a race between leaving the criticalsection and + // looping back through the buffer before we finish writing. + // how likely is this? Not very. + // + // In addition - moving the memcpy inside of the critsec makes the time spent + // quite a bit larger than some simple load/stores that are currently there. + // + // Plus this is a debugging aid - life isn't fair. + + // actually do the copy + memcpy(pWhereToWriteMessage, pszOutput, cchLen); + + // write out a NULL to indicate end of message + *(pWhereToWriteMessage + cchLen) = NULL; + + return NO_ERROR; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/pudebug.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/pudebug.cxx new file mode 100644 index 0000000000..44e42a21b1 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/pudebug.cxx @@ -0,0 +1,1164 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +/************************************************************ + * Include Headers + ************************************************************/ +# include "precomp.hxx" + + +# include +# include +# include +# include +# include + + +# include "pudebug.h" +# include "memorylog.hxx" + + +/************************************************************* + * Global Variables and Default Values + *************************************************************/ + +// +// TRUE if we're in a test process. +// There are a few noisy assertions that fire frequently cause of test code issues. These noisy asserts are masking +// real ones, drastically reducing the value of CHK bits. +// +BOOL g_fTestProcess = FALSE; + +// +// HACK HACK +// suppress shutdown asserts under some hosts +// +BOOL g_fAvoidShutdownAsserts = FALSE; + +# define MAX_PRINTF_OUTPUT ( 10240) + +# define DEFAULT_DEBUG_FLAGS_VALUE ( 0) +# define DEBUG_FLAGS_REGISTRY_LOCATION_A "DebugFlags" +# define DEBUG_BREAK_ENABLED_REGKEYNAME_A "BreakOnAssert" + +/************************************************************* + * Functions + *************************************************************/ + +/********************************************************************++ + +Routine Description: + This function creates a new DEBUG_PRINTS object for the required + program. + +Arguments: + pszPrintLabel pointer to null-terminated string containing + the label for program's debugging output + dwOutputFlags DWORD containing the output flags to be used. + +Returns: + pointer to a new DEBUG_PRINTS object on success. + Returns NULL on failure. +--*********************************************************************/ +LPDEBUG_PRINTS +PuCreateDebugPrintsObject( + IN const char * pszPrintLabel, + IN DWORD dwOutputFlags) +{ + + LPDEBUG_PRINTS pDebugPrints; + + pDebugPrints = (LPDEBUG_PRINTS ) GlobalAlloc( GPTR, sizeof( DEBUG_PRINTS)); + + if ( pDebugPrints != NULL) { + + if ( strlen( pszPrintLabel) < MAX_LABEL_LENGTH) { + + strcpy_s( pDebugPrints->m_rgchLabel, + sizeof( pDebugPrints->m_rgchLabel ) / sizeof( pDebugPrints->m_rgchLabel[0]), + pszPrintLabel); + } else { + strncpy_s( pDebugPrints->m_rgchLabel, + sizeof( pDebugPrints->m_rgchLabel ) / sizeof( pDebugPrints->m_rgchLabel[0]), + pszPrintLabel, + MAX_LABEL_LENGTH - 1); + } + + memset( pDebugPrints->m_rgchLogFilePath, 0, MAX_PATH); + memset( pDebugPrints->m_rgchLogFileName, 0, MAX_PATH); + + pDebugPrints->m_LogFileHandle = INVALID_HANDLE_VALUE; + + pDebugPrints->m_dwOutputFlags = dwOutputFlags; + pDebugPrints->m_StdErrHandle = GetStdHandle( STD_ERROR_HANDLE); + + if ( pDebugPrints->m_StdErrHandle == NULL ) + { + pDebugPrints->m_StdErrHandle = INVALID_HANDLE_VALUE; + } + + pDebugPrints->m_fInitialized = TRUE; + pDebugPrints->m_fBreakOnAssert= TRUE; + pDebugPrints->m_pMemoryLog = NULL; + } + + + return ( pDebugPrints); +} // PuCreateDebugPrintsObject() + + + + +/********************************************************************++ + +Routine Description: + This function cleans up the pDebugPrints object and + frees the allocated memory. + + Arguments: + pDebugPrints poitner to the DEBUG_PRINTS object. + + Returns: + NULL on success. + pDebugPrints() if the deallocation failed. + +--*********************************************************************/ +LPDEBUG_PRINTS +PuDeleteDebugPrintsObject( + IN OUT LPDEBUG_PRINTS pDebugPrints) +{ + if ( pDebugPrints != NULL) { + + PuCloseDbgMemoryLog(pDebugPrints); + DWORD dwError = PuCloseDbgPrintFile( pDebugPrints); + + if ( dwError != NO_ERROR) { + + SetLastError( dwError); + } else { + + // returns NULL on success + pDebugPrints = + (LPDEBUG_PRINTS ) GlobalFree( pDebugPrints); + } + } + + return ( pDebugPrints); + +} // PuDeleteDebugPrintsObject() + + + + +VOID +PuSetDbgOutputFlags( + IN OUT LPDEBUG_PRINTS pDebugPrints, + IN DWORD dwFlags) +{ + + if ( pDebugPrints == NULL) { + + SetLastError( ERROR_INVALID_PARAMETER); + } else { + + pDebugPrints->m_dwOutputFlags = dwFlags; + } + + return; +} // PuSetDbgOutputFlags() + + + +DWORD +PuGetDbgOutputFlags( + IN const LPDEBUG_PRINTS pDebugPrints) +{ + return ( pDebugPrints != NULL) ? pDebugPrints->m_dwOutputFlags : 0; + +} // PuGetDbgOutputFlags() + + +static DWORD +PuOpenDbgFileLocal( + IN OUT LPDEBUG_PRINTS pDebugPrints) +{ + if ( pDebugPrints == NULL) + return ERROR_INVALID_PARAMETER; + + if ( pDebugPrints->m_LogFileHandle != INVALID_HANDLE_VALUE) { + + // + // Silently return as a file handle exists. + // + return ( NO_ERROR); + } + + pDebugPrints->m_LogFileHandle = + CreateFileA( pDebugPrints->m_rgchLogFileName, + GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if ( pDebugPrints->m_LogFileHandle == INVALID_HANDLE_VALUE) { + + CHAR pchBuffer[1024]; + DWORD dwError = GetLastError(); + + sprintf_s( pchBuffer, + sizeof( pchBuffer ) / sizeof( pchBuffer[0] ), + " Critical Error: Unable to Open File %s. Error = %d\n", + pDebugPrints->m_rgchLogFileName, dwError); + OutputDebugStringA( pchBuffer); + + return ( dwError); + } + + return ( NO_ERROR); +} // PuOpenDbgFileLocal() + + + + + +DWORD +PuOpenDbgPrintFile( + IN OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFileName, + IN const char * pszPathForFile) +/********************************************************************++ + + Opens a Debugging log file. This function can be called to set path + and name of the debugging file. + + Arguments: + pszFileName pointer to null-terminated string containing + the name of the file. + + pszPathForFile pointer to null-terminated string containing the + path for the given file. + If NULL, then the old place where dbg files were + stored is used or if none, + default windows directory will be used. + + Returns: + Win32 error codes. NO_ERROR on success. + +--*********************************************************************/ + +{ + if ( pszFileName == NULL || pDebugPrints == NULL) { + + return ( ERROR_INVALID_PARAMETER); + } + + // + // Setup the Path information. if necessary. + // + + if ( pszPathForFile != NULL) { + + // Path is being changed. + + if ( strlen( pszPathForFile) < MAX_PATH) { + + strcpy_s( pDebugPrints->m_rgchLogFilePath, + sizeof( pDebugPrints->m_rgchLogFilePath ) / sizeof( pDebugPrints->m_rgchLogFilePath[0] ), + pszPathForFile); + } else { + + return ( ERROR_INVALID_PARAMETER); + } + } else { + + if ( pDebugPrints->m_rgchLogFilePath[0] == '\0' && // no old path + !GetWindowsDirectoryA( pDebugPrints->m_rgchLogFilePath, MAX_PATH)) { + + // + // Unable to get the windows default directory. Use current dir + // + + strcpy_s( pDebugPrints->m_rgchLogFilePath, + sizeof( pDebugPrints->m_rgchLogFilePath ) / sizeof( pDebugPrints->m_rgchLogFilePath[0] ), + "."); + } + } + + // + // Should need be, we need to create this directory for storing file + // + + + // + // Form the complete Log File name and open the file. + // + if ( (strlen( pszFileName) + strlen( pDebugPrints->m_rgchLogFilePath)) + >= MAX_PATH) { + + return ( ERROR_NOT_ENOUGH_MEMORY); + } + + // form the complete path + strcpy_s( pDebugPrints->m_rgchLogFileName, + sizeof( pDebugPrints->m_rgchLogFileName ) / sizeof( pDebugPrints->m_rgchLogFileName[0] ), + pDebugPrints->m_rgchLogFilePath); + + if ( pDebugPrints->m_rgchLogFileName[ strlen(pDebugPrints->m_rgchLogFileName) - 1] + != '\\') { + // Append a \ if necessary + strcat_s( pDebugPrints->m_rgchLogFileName, + sizeof( pDebugPrints->m_rgchLogFileName ) / sizeof( pDebugPrints->m_rgchLogFileName[0] ), + "\\"); + }; + strcat_s( pDebugPrints->m_rgchLogFileName, + sizeof( pDebugPrints->m_rgchLogFileName ) / sizeof( pDebugPrints->m_rgchLogFileName[0] ), + pszFileName); + + return PuOpenDbgFileLocal( pDebugPrints); + +} // PuOpenDbgPrintFile() + + + + +DWORD +PuReOpenDbgPrintFile( + IN OUT LPDEBUG_PRINTS pDebugPrints) +/********************************************************************++ + + This function closes any open log file and reopens a new copy. + If necessary. It makes a backup copy of the file. + +--*********************************************************************/ + +{ + if ( pDebugPrints == NULL) { + return ( ERROR_INVALID_PARAMETER); + } + + PuCloseDbgPrintFile( pDebugPrints); // close any existing file. + + if ( pDebugPrints->m_dwOutputFlags & DbgOutputBackup) { + + // MakeBkupCopy(); + + OutputDebugStringA( " Error: MakeBkupCopy() Not Yet Implemented\n"); + } + + return PuOpenDbgFileLocal( pDebugPrints); + +} // PuReOpenDbgPrintFile() + + + + +DWORD +PuCloseDbgPrintFile( + IN OUT LPDEBUG_PRINTS pDebugPrints) +{ + DWORD dwError = NO_ERROR; + + if ( pDebugPrints == NULL ) { + dwError = ERROR_INVALID_PARAMETER; + } else { + + if ( pDebugPrints->m_LogFileHandle != INVALID_HANDLE_VALUE) { + + FlushFileBuffers( pDebugPrints->m_LogFileHandle); + + if ( !CloseHandle( pDebugPrints->m_LogFileHandle)) { + + CHAR pchBuffer[1024]; + + dwError = GetLastError(); + + sprintf_s( pchBuffer, + sizeof( pchBuffer ) / sizeof( pchBuffer[0] ), + "CloseDbgPrintFile() : CloseHandle( %p) failed." + " Error = %d\n", + pDebugPrints->m_LogFileHandle, + dwError); + OutputDebugStringA( pchBuffer); + } + + pDebugPrints->m_LogFileHandle = INVALID_HANDLE_VALUE; + } + } + + return ( dwError); +} // DEBUG_PRINTS::CloseDbgPrintFile() + +DWORD +PuOpenDbgMemoryLog(IN OUT LPDEBUG_PRINTS pDebugPrints) +{ + DWORD dwError; + CMemoryLog * pLog = NULL; + + if (NULL == pDebugPrints) + { + dwError = ERROR_INVALID_PARAMETER; + goto done; + } + + if (NULL != pDebugPrints->m_pMemoryLog) + { + dwError = ERROR_SUCCESS; + goto done; + } + + pLog = new CMemoryLog(1024 * 512); // max size of 512 K + if (NULL == pLog) + { + dwError = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + + // save away the pointer + pDebugPrints->m_pMemoryLog = pLog; + + // make sure output gets to the log + pDebugPrints->m_dwOutputFlags |= DbgOutputMemory; + + dwError = NO_ERROR; +done: + return dwError; +} + +DWORD +PuCloseDbgMemoryLog(IN OUT LPDEBUG_PRINTS pDebugPrints) +{ + DWORD dwError; + + if (NULL == pDebugPrints) + { + dwError = ERROR_INVALID_PARAMETER; + goto done; + } + if (NULL != pDebugPrints->m_pMemoryLog) + { + CMemoryLog * pLog = (CMemoryLog*) (pDebugPrints->m_pMemoryLog); + delete pLog; + pDebugPrints->m_pMemoryLog = NULL; + } + + dwError = NO_ERROR; +done: + return dwError; +} + +VOID +PupOutputMessage( + IN LPDEBUG_PRINTS pDebugPrints, + IN STRA *straOutput + ) +{ + if ( pDebugPrints != NULL) + { + if ( ( pDebugPrints->m_dwOutputFlags & DbgOutputStderr) && + ( pDebugPrints->m_StdErrHandle != INVALID_HANDLE_VALUE ) ) { + + DWORD nBytesWritten; + + ( VOID) WriteFile( pDebugPrints->m_StdErrHandle, + straOutput->QueryStr(), + straOutput->QueryCCH(), + &nBytesWritten, + NULL); + } + + if ( pDebugPrints->m_dwOutputFlags & DbgOutputLogFile && + pDebugPrints->m_LogFileHandle != INVALID_HANDLE_VALUE) { + + DWORD nBytesWritten; + + // + // Truncation of log files. Not yet implemented. + + ( VOID) WriteFile( pDebugPrints->m_LogFileHandle, + straOutput->QueryStr(), + straOutput->QueryCCH(), + &nBytesWritten, + NULL); + + } + + if ( (pDebugPrints->m_dwOutputFlags & DbgOutputMemory) && + (NULL != pDebugPrints->m_pMemoryLog) ) + { + CMemoryLog* pLog = (CMemoryLog*) (pDebugPrints->m_pMemoryLog); + pLog->Append(straOutput->QueryStr(), straOutput->QueryCCH()); + } + + } + + + if ( pDebugPrints == NULL || + pDebugPrints->m_dwOutputFlags & DbgOutputKdb) + { + OutputDebugStringA( straOutput->QueryStr() ); + } + + return; +} + +void +FormatMsgToBuffer( IN OUT STRA * pSTRAOutput, + IN LPDEBUG_PRINTS pDebugPrints, + IN LPCSTR pszFilePath, + IN DWORD nLineNum, + IN LPCSTR pszFunctionName, + IN LPCSTR pszFormat, + IN va_list * pargsList) +{ + LPCSTR pszFileName = strrchr( pszFilePath, '\\'); + int cchPrologue = 0; + HRESULT hr = S_OK; + DWORD cchOutput = 0; + + // + // Skip the complete path name and retain file name in pszName + // + + if ( pszFileName== NULL) { + + // if skipping \\ yields nothing use whole path. + pszFileName = pszFilePath; + } + else + { + // skip past the '\' + ++pszFileName; + } + + // Format the message header as: tid label!function [file @ line number]:message + cchPrologue = sprintf_s( pSTRAOutput->QueryStr(), + pSTRAOutput->QuerySize(), + "%lu %hs!%hs [%hs @ %d]:", + GetCurrentThreadId(), + pDebugPrints ? pDebugPrints->m_rgchLabel : "??", + pszFunctionName, + pszFileName, + nLineNum); + + // we directly touched the buffer - however, wait to SyncWithBuffer + // until the rest of the operations are done. Do NOT call QueryCCH() it will be WRONG. + + + // Format the incoming message using vsnprintf() so that the overflows are + // captured + + cchOutput = _vsnprintf_s( pSTRAOutput->QueryStr() + cchPrologue, + pSTRAOutput->QuerySize() - cchPrologue, + pSTRAOutput->QuerySize() - cchPrologue - 1, + pszFormat, *pargsList); + + if ( cchOutput == -1 ) + { + // couldn't fit this in the original STRA size. Try a heap allocation. + hr = pSTRAOutput->Resize(MAX_PRINTF_OUTPUT); + if (FAILED(hr)) + { + // Can't allocate, therefore don't give back half done results + pSTRAOutput->Reset(); + return; + } + + cchOutput = _vsnprintf_s( pSTRAOutput->QueryStr() + cchPrologue, + pSTRAOutput->QuerySize() - cchPrologue, + pSTRAOutput->QuerySize() - cchPrologue - 1, + pszFormat, *pargsList); + if (cchOutput == -1) + { + // we need to NULL terminate, as _vsnprintf failed to do that for us. + pSTRAOutput->QueryStr()[pSTRAOutput->QuerySize() - 1] = '\0'; + } + } + + // we directly touched the buffer - therefore: + pSTRAOutput->SyncWithBuffer(); + + return; +} // FormatMsgToBuffer() + + +/********************************************************************++ +Routine Description: + Main function that examines the incoming message and prints out a header + and the message. + +Arguments: + pDebugPrints - pointer to the debug print object + pszFilePaht - pointer to the file from where this function is called + nLineNum - Line number within the file + pszFormat - formatting string to use. + +Returns: + None +--*********************************************************************/ + +VOID +PuDbgPrint( + IN OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN const char * pszFormat, + ...) +{ + STACK_STRA(straOutput, 256); + va_list argsList; + DWORD dwErr; + + // get a local copy of the error code so that it is not lost + dwErr = GetLastError(); + + va_start( argsList, pszFormat); + FormatMsgToBuffer( &straOutput, + pDebugPrints, + pszFilePath, + nLineNum, + pszFunctionName, + pszFormat, + &argsList); + + va_end( argsList); + + // + // Send the outputs to respective files. + // + PupOutputMessage( pDebugPrints, &straOutput); + + + SetLastError( dwErr ); + + return; +} // PuDbgPrint() + +void +FormatMsgToBufferW( IN OUT STRU * pSTRUOutput, + IN LPDEBUG_PRINTS pDebugPrints, + IN LPCSTR pszFilePath, + IN DWORD nLineNum, + IN LPCSTR pszFunctionName, + IN LPCWSTR pszFormat, + IN va_list * pargsList) +{ + LPCSTR pszFileName = strrchr( pszFilePath, '\\'); + int cchPrologue = 0; + HRESULT hr = S_OK; + DWORD cchOutput = 0; + + // + // Skip the complete path name and retain file name in pszName + // + + if ( pszFileName== NULL) { + + // if skipping \\ yields nothing use whole path. + pszFileName = pszFilePath; + } + else + { + // skip past the '\' + ++pszFileName; + } + + // Format the message header as: tid label!function [file @ line number]:message + cchPrologue = swprintf_s( pSTRUOutput->QueryStr(), + pSTRUOutput->QuerySizeCCH(), + L"%lu %hs!%hs [%hs @ %d]:", + GetCurrentThreadId(), + pDebugPrints ? pDebugPrints->m_rgchLabel : "??", + pszFunctionName, + pszFileName, + nLineNum); + + // we directly touched the buffer - however, wait to SyncWithBuffer + // until the rest of the operations are done. Do NOT call QueryCCH() it will be WRONG. + + // Format the incoming message using vsnprintf() so that the overflows are + // captured + + cchOutput = _vsnwprintf_s( pSTRUOutput->QueryStr() + cchPrologue, + pSTRUOutput->QuerySizeCCH() - cchPrologue, + // DEBUGDEBUG + //pSTRUOutput->QueryBuffer()->QuerySize() / sizeof(WCHAR) - cchPrologue - 1, // this is a count of characters + pSTRUOutput->QuerySizeCCH() - cchPrologue - 1, + pszFormat, *pargsList); + + if ( cchOutput == -1 ) + { + // couldn't fit this in the original STRA size. Try a heap allocation. + hr = pSTRUOutput->Resize(MAX_PRINTF_OUTPUT); + if (FAILED(hr)) + { + // Can't allocate, therefore don't give back half done results + pSTRUOutput->Reset(); + return; + } + + cchOutput = _vsnwprintf_s( pSTRUOutput->QueryStr() + cchPrologue, + pSTRUOutput->QuerySizeCCH() - cchPrologue, + //DEBUGDEBUG + //pSTRUOutput->QueryBuffer()->QuerySize() / sizeof(WCHAR) - cchPrologue - 1, // this is a count of characters + pSTRUOutput->QuerySizeCCH() - cchPrologue - 1, + pszFormat, *pargsList); + if (cchOutput == -1) + { + // we need to NULL terminate, as _vsnprintf failed to do that for us. + //DEBUGDEBUG + pSTRUOutput->QueryStr()[pSTRUOutput->QuerySizeCCH() - 1] = L'\0'; + + } + } + + // we directly touched the buffer - therefore: + pSTRUOutput->SyncWithBuffer(); + + return; +} // FormatMsgToBuffer() + +extern "C" +VOID +PuDbgPrintW( + IN OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN const WCHAR * pszFormat, + ... +) +{ + STACK_STRU(struOutput, 256); + va_list argsList; + DWORD dwErr; + HRESULT hr; + // get a local copy of the error code so that it is not lost + dwErr = GetLastError(); + + va_start( argsList, pszFormat); + FormatMsgToBufferW( &struOutput, + pDebugPrints, + pszFilePath, + nLineNum, + pszFunctionName, + pszFormat, + &argsList); + + va_end( argsList); + + // + // Send the outputs to respective files. + // + STACK_STRA(straOutput, 256); + hr = straOutput.CopyWTruncate(struOutput.QueryStr(), struOutput.QueryCCH()); + if (FAILED(hr)) + { + goto done; + } + + PupOutputMessage( pDebugPrints, &straOutput); + +done: + + SetLastError( dwErr ); + + return; +} + +/********************************************************************++ +Routine Description: + This function behaves like PuDbgPrint() but also prints out formatted + Error message indicating what failed. + +Arguments: + pDebugPrints - pointer to the debug print object + pszFilePaht - pointer to the file from where this function is called + nLineNum - Line number within the file + dwError - Error code for which the formatted error message should + be printed + pszFormat - formatting string to use. + +Returns: + None +--*********************************************************************/ +VOID +PuDbgPrintError( + IN OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN DWORD dwError, + IN const char * pszFormat, + ...) // argsList +{ + STACK_STRA(straOutput, 256); + va_list argsList; + DWORD dwErr; + + // get a local copy of the error code so that it is not lost + dwErr = GetLastError(); + + va_start( argsList, pszFormat); + FormatMsgToBuffer( &straOutput, + pDebugPrints, + pszFilePath, + nLineNum, + pszFunctionName, + pszFormat, + &argsList); + + va_end( argsList); + + + // + // obtain the formatted error message for error code + // + + LPSTR lpErrorBuffer = NULL; + DWORD nRet; +#pragma prefast(suppress: __WARNING_ANSI_APICALL,"debug spew is ansi") + nRet = + FormatMessageA((FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM), + NULL, // lpSource + dwError, + LANG_NEUTRAL, + (LPSTR ) &lpErrorBuffer, // pointer to store buffer allocated + 0, // size of buffer + NULL // lpArguments + ); + + if (lpErrorBuffer) + { + CHAR pszErrorOut[64]; // 64 from: (/t=)4 + (Error(=)7 + (%x=)18 (0x + 16hex on 64 bit systems) + (): =)3 == 32 + some more slop + _snprintf_s( pszErrorOut, + sizeof( pszErrorOut ) / sizeof( pszErrorOut[0] ), + sizeof(pszErrorOut) / sizeof(CHAR) - 1, // leave space for NULL. + "\tError(%x): ", + dwError); + pszErrorOut[63] = '\0'; + + // if these appends fail, nothing to be done about it therefore just ignore the return values + straOutput.Append(pszErrorOut); + + straOutput.Append(lpErrorBuffer); + straOutput.Append("\n"); + } + + // + // Send the outputs to respective files. + // + PupOutputMessage( pDebugPrints, &straOutput); + + // free the buffer if any was allocated + if ( lpErrorBuffer != NULL) { + LocalFree (lpErrorBuffer); + } + + SetLastError( dwErr ); + + return; +} // PuDbgPrintError() + + + +VOID +PuDbgDump( + IN OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN const char * pszDump + ) +{ + UNREFERENCED_PARAMETER( pszFunctionName ); + UNREFERENCED_PARAMETER( nLineNum ); + + LPCSTR pszFileName = strrchr( pszFilePath, '\\'); + DWORD dwErr; + DWORD cbDump; + + + // + // Skip the complete path name and retain file name in pszName + // + + if ( pszFileName== NULL) { + + pszFileName = pszFilePath; + } + + dwErr = GetLastError(); + + // No message header for this dump + cbDump = (DWORD)strlen( pszDump); + + // + // Send the outputs to respective files. + // + + if ( pDebugPrints != NULL) + { + if ( ( pDebugPrints->m_dwOutputFlags & DbgOutputStderr) && + ( pDebugPrints->m_StdErrHandle != INVALID_HANDLE_VALUE ) ) { + + DWORD nBytesWritten; + + ( VOID) WriteFile( pDebugPrints->m_StdErrHandle, + pszDump, + cbDump, + &nBytesWritten, + NULL); + } + + if ( pDebugPrints->m_dwOutputFlags & DbgOutputLogFile && + pDebugPrints->m_LogFileHandle != INVALID_HANDLE_VALUE) { + + DWORD nBytesWritten; + + // + // Truncation of log files. Not yet implemented. + + ( VOID) WriteFile( pDebugPrints->m_LogFileHandle, + pszDump, + cbDump, + &nBytesWritten, + NULL); + + } + + if ( (pDebugPrints->m_dwOutputFlags & DbgOutputMemory) && + (NULL != pDebugPrints->m_pMemoryLog) ) + { + CMemoryLog * pLog = (CMemoryLog*)(pDebugPrints->m_pMemoryLog); + pLog->Append(pszDump, cbDump); + } + } + + if ( pDebugPrints == NULL + || pDebugPrints->m_dwOutputFlags & DbgOutputKdb) + { + OutputDebugStringA( pszDump); + } + + SetLastError( dwErr ); + + return; +} // PuDbgDump() + +// +// N.B. For PuDbgCaptureContext() to work properly, the calling function +// *must* be __cdecl, and must have a "normal" stack frame. So, we decorate +// PuDbgAssertFailed() with the __cdecl modifier and disable the frame pointer +// omission (FPO) optimization. +// + +// DEBUGDEBUG +//#pragma optimize( "y", off ) // disable frame pointer omission (FPO) +#pragma optimize( "", off ) + +INT +__cdecl +PuDbgAssertFailed( + IN OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN const char * pszExpression, + IN const char * pszMessage) +/********************************************************************++ + This function calls assertion failure and records assertion failure + in log file. + +--*********************************************************************/ + +{ + PuDbgPrintAssertFailed( pDebugPrints, pszFilePath, nLineNum, pszFunctionName, + pszExpression, + pszMessage ); + if ( !g_fAvoidShutdownAsserts ) + { + DebugBreak(); + } + + return 0; +} // PuDbgAssertFailed() + +#pragma optimize( "", on ) // restore frame pointer omission (FPO) + +INT +WINAPI +PuDbgPrintAssertFailed( + IN OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName, + IN const char * pszExpression, + IN const char * pszMessage) +/********************************************************************++ + This function calls assertion failure and records assertion failure + in log file. + +--*********************************************************************/ + +{ + PuDbgPrint( pDebugPrints, pszFilePath, nLineNum, pszFunctionName, + " Assertion (%s) Failed: %s\n", + pszExpression, + pszMessage ); + return 0; +} // PuDbgPrintAssertFailed() + + + +VOID +PuDbgPrintCurrentTime( + IN OUT LPDEBUG_PRINTS pDebugPrints, + IN const char * pszFilePath, + IN int nLineNum, + IN const char * pszFunctionName + ) +/********************************************************************++ + This function generates the current time and prints it out to debugger + for tracing out the path traversed, if need be. + + Arguments: + pszFile pointer to string containing the name of the file + lineNum line number within the file where this function is called. + + Returns: + NO_ERROR always. +--*********************************************************************/ + +{ + PuDbgPrint( pDebugPrints, pszFilePath, nLineNum, pszFunctionName, + " TickCount = %u\n", + GetTickCount() + ); + + return; +} // PrintOutCurrentTime() + + + + +DWORD +PuLoadDebugFlagsFromReg(IN HKEY hkey, IN DWORD dwDefault) +/********************************************************************++ + This function reads the debug flags assumed to be stored in + the location "DebugFlags" under given key. + If there is any error the default value is returned. +--*********************************************************************/ + +{ + DWORD err; + DWORD dwDebug = dwDefault; + DWORD dwBuffer; + DWORD cbBuffer = sizeof(dwBuffer); + DWORD dwType; + + if( hkey != NULL ) + { + err = RegQueryValueExA( hkey, + DEBUG_FLAGS_REGISTRY_LOCATION_A, + NULL, + &dwType, + (LPBYTE)&dwBuffer, + &cbBuffer ); + + if( ( err == NO_ERROR ) && ( dwType == REG_DWORD ) ) + { + dwDebug = dwBuffer; + } + } + + return dwDebug; +} // PuLoadDebugFlagsFromReg() + + + + +DWORD +PuLoadDebugFlagsFromRegStr(IN LPCSTR pszRegKey, IN DWORD dwDefault) +/********************************************************************++ +Description: + This function reads the debug flags assumed to be stored in + the location "DebugFlags" under given key location in registry. + If there is any error the default value is returned. + +Arguments: + pszRegKey - pointer to registry key location from where to read the key from + dwDefault - default values in case the read from registry fails + +Returns: + Newly read value on success + If there is any error the dwDefault is returned. +--*********************************************************************/ + +{ + HKEY hkey = NULL; + + DWORD dwVal = dwDefault; + + DWORD dwError = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + pszRegKey, + 0, + KEY_READ, + &hkey); + if ( dwError == NO_ERROR) { + dwVal = PuLoadDebugFlagsFromReg( hkey, dwDefault); + RegCloseKey( hkey); + hkey = NULL; + } + + return ( dwVal); +} // PuLoadDebugFlagsFromRegStr() + + + + + +DWORD +PuSaveDebugFlagsInReg(IN HKEY hkey, IN DWORD dwDbg) +/********************************************************************++ + Saves the debug flags in registry. On failure returns the error code for + the operation that failed. + +--*********************************************************************/ +{ + DWORD err; + + if( hkey == NULL ) { + + err = ERROR_INVALID_PARAMETER; + } else { + + err = RegSetValueExA(hkey, + DEBUG_FLAGS_REGISTRY_LOCATION_A, + 0, + REG_DWORD, + (LPBYTE)&dwDbg, + sizeof(dwDbg) ); + } + + return (err); +} // PuSaveDebugFlagsInReg() + + +VOID +PuDbgCaptureContext ( + OUT PCONTEXT ContextRecord + ) +{ + // + // This space intentionally left blank. + // + UNREFERENCED_PARAMETER( ContextRecord ); +} // PuDbgCaptureContext + + +/****************************** End of File ******************************/ + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/reftrace.c b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/reftrace.c new file mode 100644 index 0000000000..bfb78aa717 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/reftrace.c @@ -0,0 +1,232 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +//#include +//#include +//#include +#include +#include +#include +#include + + +PTRACE_LOG +CreateRefTraceLog( + IN LONG LogSize, + IN LONG ExtraBytesInHeader + ) +/*++ + +Routine Description: + + Creates a new (empty) ref count trace log buffer. + +Arguments: + + LogSize - The number of entries in the log. + + ExtraBytesInHeader - The number of extra bytes to include in the + log header. This is useful for adding application-specific + data to the log. + +Return Value: + + PTRACE_LOG - Pointer to the newly created log if successful, + NULL otherwise. + +--*/ +{ + + return CreateTraceLog( + LogSize, + ExtraBytesInHeader, + sizeof(REF_TRACE_LOG_ENTRY) + ); + +} // CreateRefTraceLog + + +VOID +DestroyRefTraceLog( + IN PTRACE_LOG Log + ) +/*++ + +Routine Description: + + Destroys a ref count trace log buffer created with CreateRefTraceLog(). + +Arguments: + + Log - The ref count trace log buffer to destroy. + +Return Value: + + None. + +--*/ +{ + + DestroyTraceLog( Log ); + +} // DestroyRefTraceLog + + +// +// N.B. For RtlCaptureBacktrace() to work properly, the calling function +// *must* be __cdecl, and must have a "normal" stack frame. So, we decorate +// WriteRefTraceLog[Ex]() with the __cdecl modifier and disable the frame +// pointer omission (FPO) optimization. +// + +//#pragma optimize( "y", off ) // disable frame pointer omission (FPO) +#pragma optimize( "", off ) // disable frame pointer omission (FPO) + +LONG +__cdecl +WriteRefTraceLog( + IN PTRACE_LOG Log, + IN LONG NewRefCount, + IN CONST VOID * Context + ) +/*++ + +Routine Description: + + Writes a new entry to the specified ref count trace log. The entry + written contains the updated reference count and a stack backtrace + leading up to the current caller. + +Arguments: + + Log - The log to write to. + + NewRefCount - The updated reference count. + + Context - An uninterpreted context to associate with the log entry. + +Return Value: + + Index of entry in log. + +--*/ +{ + + return WriteRefTraceLogEx( + Log, + NewRefCount, + Context, + REF_TRACE_EMPTY_CONTEXT, // suppress use of optional extra contexts + REF_TRACE_EMPTY_CONTEXT, + REF_TRACE_EMPTY_CONTEXT + ); + +} // WriteRefTraceLog + + + + +LONG +__cdecl +WriteRefTraceLogEx( + IN PTRACE_LOG Log, + IN LONG NewRefCount, + IN CONST VOID * Context, + IN CONST VOID * Context1, // optional extra context + IN CONST VOID * Context2, // optional extra context + IN CONST VOID * Context3 // optional extra context + ) +/*++ + +Routine Description: + + Writes a new "extended" entry to the specified ref count trace log. + The entry written contains the updated reference count, stack backtrace + leading up to the current caller and extra context information. + +Arguments: + + Log - The log to write to. + + NewRefCount - The updated reference count. + + Context - An uninterpreted context to associate with the log entry. + Context1 - An uninterpreted context to associate with the log entry. + Context2 - An uninterpreted context to associate with the log entry. + Context3 - An uninterpreted context to associate with the log entry. + + NOTE Context1/2/3 are "optional" in that the caller may suppress + debug display of these values by passing REF_TRACE_EMPTY_CONTEXT + for each of them. + +Return Value: + + Index of entry in log. + +--*/ +{ + + REF_TRACE_LOG_ENTRY entry; + ULONG hash; + DWORD cStackFramesSkipped; + + // + // Initialize the entry. + // + + RtlZeroMemory( + &entry, + sizeof(entry) + ); + + // + // Set log entry members. + // + + entry.NewRefCount = NewRefCount; + entry.Context = Context; + entry.Thread = GetCurrentThreadId(); + entry.Context1 = Context1; + entry.Context2 = Context2; + entry.Context3 = Context3; + + // + // Capture the stack backtrace. Normally, we skip two stack frames: + // one for this routine, and one for RtlCaptureBacktrace() itself. + // For non-Ex callers who come in via WriteRefTraceLog, + // we skip three stack frames. + // + + if ( entry.Context1 == REF_TRACE_EMPTY_CONTEXT + && entry.Context2 == REF_TRACE_EMPTY_CONTEXT + && entry.Context3 == REF_TRACE_EMPTY_CONTEXT + ) { + + cStackFramesSkipped = 2; + + } else { + + cStackFramesSkipped = 1; + + } + + RtlCaptureStackBackTrace( + cStackFramesSkipped, + REF_TRACE_LOG_STACK_DEPTH, + entry.Stack, + &hash + ); + + // + // Write it to the log. + // + + return WriteTraceLog( + Log, + &entry + ); + +} // WriteRefTraceLogEx + +#pragma optimize( "", on ) // restore frame pointer omission (FPO) + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/tracelog.c b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/tracelog.c new file mode 100644 index 0000000000..58eeb4863f --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/tracelog.c @@ -0,0 +1,239 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +//#include +//#include +//#include +#include +#include +#include +#include +#include + + +#define ALLOC_MEM(cb) (PVOID)LocalAlloc( LPTR, (cb) ) +#define FREE_MEM(ptr) (VOID)LocalFree( (HLOCAL)(ptr) ) + + + +PTRACE_LOG +CreateTraceLog( + IN LONG LogSize, + IN LONG ExtraBytesInHeader, + IN LONG EntrySize + ) +/*++ + +Routine Description: + + Creates a new (empty) trace log buffer. + +Arguments: + + LogSize - The number of entries in the log. + + ExtraBytesInHeader - The number of extra bytes to include in the + log header. This is useful for adding application-specific + data to the log. + + EntrySize - The size (in bytes) of each entry. + +Return Value: + + PTRACE_LOG - Pointer to the newly created log if successful, + NULL otherwise. + +--*/ +{ + + ULONG ulTotalSize = 0; + ULONG ulLogSize = 0; + ULONG ulEntrySize = 0; + ULONG ulTmpResult = 0; + ULONG ulExtraBytesInHeader = 0; + PTRACE_LOG log = NULL; + HRESULT hr = S_OK; + + // + // Sanity check the parameters. + // + + //DBG_ASSERT( LogSize > 0 ); + //DBG_ASSERT( EntrySize > 0 ); + //DBG_ASSERT( ExtraBytesInHeader >= 0 ); + //DBG_ASSERT( ( EntrySize & 3 ) == 0 ); + + // + // converting to unsigned long. Since all these values are positive + // so its safe to cast them to their unsigned equivalent directly. + // + ulLogSize = (ULONG) LogSize; + ulEntrySize = (ULONG) EntrySize; + ulExtraBytesInHeader = (ULONG) ExtraBytesInHeader; + + // + // Check if the multiplication operation will overflow a LONG + // ulTotalSize = LogSize * EntrySize; + // + hr = ULongMult( ulLogSize, ulEntrySize, &ulTotalSize ); + if ( FAILED(hr) ) + { + SetLastError( ERROR_ARITHMETIC_OVERFLOW ); + return NULL; + } + + // + // check for overflow in addition operation. + // ulTmpResult = sizeof(TRACE_LOG) + ulExtraBytesInHeader + // + hr = ULongAdd( (ULONG) sizeof(TRACE_LOG), ulExtraBytesInHeader, &ulTmpResult ); + if ( FAILED(hr) ) + { + SetLastError( ERROR_ARITHMETIC_OVERFLOW ); + return NULL; + } + + // + // check for overflow in addition operation. + // ulTotalSize = ulTotalSize + ulTmpResult; + // + hr = ULongAdd( ulTmpResult, ulTotalSize, &ulTotalSize ); + if ( FAILED(hr) ) + { + SetLastError( ERROR_ARITHMETIC_OVERFLOW ); + return NULL; + } + + if ( ulTotalSize > (ULONG) 0x7FFFFFFF ) + { + SetLastError( ERROR_ARITHMETIC_OVERFLOW ); + return NULL; + } + + // + // Allocate & initialize the log structure. + // + + log = (PTRACE_LOG)ALLOC_MEM( ulTotalSize ); + + // + // Initialize it. + // + + if( log != NULL ) { + + RtlZeroMemory( log, ulTotalSize ); + + log->Signature = TRACE_LOG_SIGNATURE; + log->LogSize = LogSize; + log->NextEntry = -1; + log->EntrySize = EntrySize; + log->LogBuffer = (PUCHAR)( log + 1 ) + ExtraBytesInHeader; + } + + return log; + +} // CreateTraceLog + + +VOID +DestroyTraceLog( + IN PTRACE_LOG Log + ) +/*++ + +Routine Description: + + Destroys a trace log buffer created with CreateTraceLog(). + +Arguments: + + Log - The trace log buffer to destroy. + +Return Value: + + None. + +--*/ +{ + if ( Log != NULL ) { + //DBG_ASSERT( Log->Signature == TRACE_LOG_SIGNATURE ); + + Log->Signature = TRACE_LOG_SIGNATURE_X; + FREE_MEM( Log ); + } + +} // DestroyTraceLog + + +LONG +WriteTraceLog( + IN PTRACE_LOG Log, + IN PVOID Entry + ) +/*++ + +Routine Description: + + Writes a new entry to the specified trace log. + +Arguments: + + Log - The log to write to. + + Entry - Pointer to the data to write. This buffer is assumed to be + Log->EntrySize bytes long. + +Return Value: + + Index of entry in log. This is useful for correlating the output + of !inetdbg.ref to a particular point in the output debug stream + +--*/ +{ + + PUCHAR target; + ULONG index; + + //DBG_ASSERT( Log != NULL ); + //DBG_ASSERT( Log->Signature == TRACE_LOG_SIGNATURE ); + //DBG_ASSERT( Entry != NULL ); + + // + // Find the next slot, copy the entry to the slot. + // + + index = ( (ULONG) InterlockedIncrement( &Log->NextEntry ) ) % (ULONG) Log->LogSize; + + //DBG_ASSERT( index < (ULONG) Log->LogSize ); + + target = Log->LogBuffer + ( index * Log->EntrySize ); + + RtlCopyMemory( + target, + Entry, + Log->EntrySize + ); + + return index; +} // WriteTraceLog + + +VOID +ResetTraceLog( + IN PTRACE_LOG Log + ) +{ + + //DBG_ASSERT( Log != NULL ); + //DBG_ASSERT( Log->Signature == TRACE_LOG_SIGNATURE ); + + RtlZeroMemory( + ( Log + 1 ), + Log->LogSize * Log->EntrySize + ); + + Log->NextEntry = -1; + +} // ResetTraceLog + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/win32obj.cxx b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/win32obj.cxx new file mode 100644 index 0000000000..cd6987d860 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/reftrace/src/win32obj.cxx @@ -0,0 +1,348 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.hxx" +#include "pudebug.h" + +#define MAX_OBJECT_NAME 256 // chars + + +LONG g_PuDbgEventsCreated = 0; +LONG g_PuDbgSemaphoresCreated = 0; +LONG g_PuDbgMutexesCreated = 0; + + + +LPSTR +PuDbgpBuildObjectName( + __in LPSTR ObjectNameBuffer, + IN ULONG ObjectNameBufferCch, + __in LPSTR FileName, + IN ULONG LineNumber, + __in LPSTR MemberName, + IN PVOID Address + ) + +/*++ + +Routine Description: + + Internal routine that builds an appropriate object name based on + the file name, line number, member name, address, and process ID. + +Arguments: + + ObjectNameBuffer - Pointer to the target buffer for the name. + + FileName - The filename of the source creating the object. This + is __FILE__ of the caller. + + LineNumber - The line number within the source. This is __LINE__ + of the caller. + + MemberName - The member/global variable name where the object handle + is to be stored. + + Address - The address of the containing structure/class or of the + global itself. + +Return Value: + + LPSTR - Pointer to ObjectNameBuffer if successful, NULL otherwise. + + N.B. This routine always returns NULL when running under Win9x. + +--*/ + +{ + + PLATFORM_TYPE platformType; + LPSTR fileNamePart; + LPSTR result; + + // + // We have no convenient way to dump objects w/ names from + // Win9x, so we'll only enable this functionality under NT. + // + + // platformType = IISGetPlatformType(); + + // + // By default IIS-Duct-tape will only run on NT platforms. So + // do not worry about getting the platform types yet. + // + platformType = PtNtServer; + result = NULL; + + if( platformType == PtNtServer || + platformType == PtNtWorkstation ) { + + // + // Find the filename part of the incoming source file name. + // + + fileNamePart = strrchr( FileName, '\\' ); + + if( fileNamePart == NULL ) { + fileNamePart = strrchr( FileName, '/' ); + } + + if( fileNamePart == NULL ) { + fileNamePart = strrchr( FileName, ':' ); + } + + if( fileNamePart == NULL ) { + fileNamePart = FileName; + } else { + fileNamePart++; + } + + // + // Ensure we don't overwrite our object name buffer. + // + + if( ( sizeof(":1234567890 :12345678 PID:1234567890") + + strlen( fileNamePart ) + + strlen( MemberName ) ) < MAX_OBJECT_NAME ) { + + sprintf_s( + ObjectNameBuffer, + ObjectNameBufferCch, + "%s:%lu %s:%08p PID:%lu", + fileNamePart, + LineNumber, + MemberName, + Address, + GetCurrentProcessId() + ); + + result = ObjectNameBuffer; + + } + + } + + return result; + +} // PuDbgpBuildObjectName + + +HANDLE +PuDbgCreateEvent( + __in LPSTR FileName, + IN ULONG LineNumber, + __in LPSTR MemberName, + IN PVOID Address, + IN BOOL ManualReset, + IN BOOL InitialState + ) + +/*++ + +Routine Description: + + Creates a new event object. + +Arguments: + + FileName - The filename of the source creating the object. This + is __FILE__ of the caller. + + LineNumber - The line number within the source. This is __LINE__ + of the caller. + + MemberName - The member/global variable name where the object handle + is to be stored. + + Address - The address of the containing structure/class or of the + global itself. + + ManualReset - TRUE to create a manual reset event, FALSE to create + an automatic reset event. + + InitialState - The intitial state of the event object. + +Return Value: + + HANDLE - Handle to the object if successful, NULL otherwise. + +--*/ + +{ + UNREFERENCED_PARAMETER( Address ); + UNREFERENCED_PARAMETER( MemberName ); + UNREFERENCED_PARAMETER( LineNumber ); + UNREFERENCED_PARAMETER( FileName ); + + LPSTR objName = NULL; + HANDLE objHandle; + //CHAR objNameBuffer[MAX_OBJECT_NAME]; + +/* + disable passing names to event creation + Longhorn forces some security checks that + prevent hostable webcore to work on checked builds + (at least ASP requests are failing when + trying to create event) + + objName = PuDbgpBuildObjectName( + objNameBuffer, + FileName, + LineNumber, + MemberName, + Address + ); +*/ + objHandle = CreateEventA( + NULL, // lpEventAttributes + ManualReset, // bManualReset + InitialState, // bInitialState + objName // lpName + ); + + if( objHandle != NULL ) { + InterlockedIncrement( &g_PuDbgEventsCreated ); + } + + return objHandle; + +} // PuDbgCreateEvent + + +HANDLE +PuDbgCreateSemaphore( + __in LPSTR FileName, + IN ULONG LineNumber, + __in LPSTR MemberName, + IN PVOID Address, + IN LONG InitialCount, + IN LONG MaximumCount + ) + +/*++ + +Routine Description: + + Creates a new semaphore object. + +Arguments: + + FileName - The filename of the source creating the object. This + is __FILE__ of the caller. + + LineNumber - The line number within the source. This is __LINE__ + of the caller. + + MemberName - The member/global variable name where the object handle + is to be stored. + + Address - The address of the containing structure/class or of the + global itself. + + InitialCount - The initial count of the semaphore. + + MaximumCount - The maximum count of the semaphore. + +Return Value: + + HANDLE - Handle to the object if successful, NULL otherwise. + +--*/ + +{ + + LPSTR objName; + HANDLE objHandle; + CHAR objNameBuffer[MAX_OBJECT_NAME]; + + objName = PuDbgpBuildObjectName( + objNameBuffer, + sizeof( objNameBuffer) / sizeof( objNameBuffer[0] ), + FileName, + LineNumber, + MemberName, + Address + ); + + objHandle = CreateSemaphoreA( + NULL, // lpSemaphoreAttributes + InitialCount, // lInitialCount + MaximumCount, // lMaximumCount + objName // lpName + ); + + if( objHandle != NULL ) { + InterlockedIncrement( &g_PuDbgSemaphoresCreated ); + } + + return objHandle; + +} // PuDbgCreateSemaphore + + +HANDLE +PuDbgCreateMutex( + __in LPSTR FileName, + IN ULONG LineNumber, + __in LPSTR MemberName, + IN PVOID Address, + IN BOOL InitialOwner + ) + +/*++ + +Routine Description: + + Creates a new mutex object. + +Arguments: + + FileName - The filename of the source creating the object. This + is __FILE__ of the caller. + + LineNumber - The line number within the source. This is __LINE__ + of the caller. + + MemberName - The member/global variable name where the object handle + is to be stored. + + Address - The address of the containing structure/class or of the + global itself. + + InitialOwner - TRUE if the mutex should be created "owned". + +Return Value: + + HANDLE - Handle to the object if successful, NULL otherwise. + +--*/ + +{ + + LPSTR objName; + HANDLE objHandle; + CHAR objNameBuffer[MAX_OBJECT_NAME]; + + objName = PuDbgpBuildObjectName( + objNameBuffer, + sizeof( objNameBuffer) / sizeof( objNameBuffer[0] ), + FileName, + LineNumber, + MemberName, + Address + ); + + objHandle = CreateMutexA( + NULL, // lpMutexAttributes + InitialOwner, // bInitialOwner, + objName // lpName + ); + + if( objHandle != NULL ) { + InterlockedIncrement( &g_PuDbgMutexesCreated ); + } + + return objHandle; + +} // PuDbgCreateMutex + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/version/bldver.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/version/bldver.h new file mode 100644 index 0000000000..63a67d68f4 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/version/bldver.h @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _BLDVER_H_ +#define _BLDVER_H_ + +#define STR_HELPER(x) #x +#define WSTR_HELPER(x) L#x +#define NUM_TO_STR(x) STR_HELPER(x) +#define NUM_TO_WSTR(x) WSTR_HELPER(x) + +// +// Build versions are properties of the build system but can be overwritten below +// +// #define PRODUCT_MAJOR 7 +// #define PRODUCT_MINOR 1 +// #define BUILD_MAJOR 1972 +// #define BUILD_MINOR 0 + +#define PRODUCT_MAJOR_STRING NUM_TO_STR(PRODUCT_MAJOR) +#define PRODUCT_MAJOR_STRING_L NUM_TO_WSTR(PRODUCT_MAJOR) +#define PRODUCT_MAJOR_NUMBER PRODUCT_MAJOR + +#define PRODUCT_MINOR_STRING NUM_TO_STR(PRODUCT_MINOR) +#define PRODUCT_MINOR_STRING_L NUM_TO_WSTR(PRODUCT_MINOR) +#define PRODUCT_MINOR_NUMBER PRODUCT_MINOR + +#define BUILD_MAJOR_STRING NUM_TO_STR(BUILD_MAJOR) +#define BUILD_MAJOR_STRING_L NUM_TO_WSTR(BUILD_MAJOR) +#define BUILD_MAJOR_NUMBER BUILD_MAJOR + +#define BUILD_MINOR_STRING NUM_TO_STR(BUILD_MINOR) +#define BUILD_MINOR_STRING_L NUM_TO_WSTR(BUILD_MINOR) +#define BUILD_MINOR_NUMBER BUILD_MINOR + +#define BUILD_NUMBER BUILD_MAJOR_STRING "." BUILD_MINOR_STRING +#define BUILD_NUM BUILD_MAJOR , BUILD_MINOR +#define PRODUCT_NUMBER PRODUCT_MAJOR_STRING "." PRODUCT_MINOR_STRING +#define PRODUCT_NUM PRODUCT_MAJOR , PRODUCT_MINOR +#define INET_VERSION PRODUCT_MAJOR_STRING "." PRODUCT_MINOR_STRING "." BUILD_MAJOR_STRING "." BUILD_MINOR_STRING +#define INET_VERSION_L PRODUCT_MAJOR_STRING_L L"." PRODUCT_MINOR_STRING_L L"." BUILD_MAJOR_STRING_L L"." BUILD_MINOR_STRING_L +#define INET_VER PRODUCT_MAJOR , PRODUCT_MINOR , BUILD_MAJOR , BUILD_MINOR + +#define BUILD_PRIVATE "Built by IISBLD on IISBLD.\0" + +#undef VER_PRODUCTVERSION +#undef VER_PRODUCTVERSION_STR +#undef VER_PRODUCTMAJORVERSION +#undef VER_PRODUCTMINORVERSION +#undef VER_PRODUCTBUILD +#undef VER_PRODUCTBUILD_QFE +#undef VER_PRODUCTNAME_STR +#undef VER_COMPANYNAME_STR + +#define VER_PRODUCTVERSION PRODUCT_MAJOR,PRODUCT_MINOR,BUILD_MAJOR,BUILD_MINOR +#define VER_PRODUCTVERSION_STR PRODUCT_MAJOR_STRING "." PRODUCT_MINOR_STRING "." BUILD_MAJOR_STRING "." BUILD_MINOR_STRING +#define VER_PRODUCTMAJORVERSION PRODUCT_MAJOR +#define VER_PRODUCTMINORVERSION PRODUCT_MINOR +#define VER_PRODUCTBUILD BUILD_MAJOR +#define VER_PRODUCTBUILD_QFE BUILD_MINOR +#define VER_PRODUCTNAME_STR "Microsoft Web Platform Extensions" +#define VER_COMPANYNAME_STR "Microsoft Corporation" + +#endif diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/version/bldver.rc b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/version/bldver.rc new file mode 100644 index 0000000000..30a96499ec --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Common/version/bldver.rc @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +// BLDVER.RC - Standard version resource for CoreXT applications. + +// Before including this file into your .rc, define the following +// macros for your application (don't forget the \0's): +// #define RC_VERSION_FILE_DESCRIPTION "Test DLL\0" +// #define RC_VERSION_INTERNAL_NAME "Test\0" +// #define RC_VERSION_ORIGINAL_FILE_NAME "Test.DLL\0" + +#include +#include + +VS_VERSION_INFO VERSIONINFO + +FILEVERSION INET_VER +PRODUCTVERSION INET_VER + +FILEFLAGSMASK 0x3fL +#ifdef DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + +// +// Global definitions +// +#ifndef RC_VERSION_COMPANY_NAME + #define RC_VERSION_COMPANY_NAME "Microsoft Corporation\0" +#endif + +#ifndef RC_VERSION_PRODUCT_NAME + #define RC_VERSION_PRODUCT_NAME "Microsoft\256 Web Platform Extensions\0" +#endif + +#ifndef RC_VERSION_LEGAL_COPYRIGHT + #define RC_VERSION_LEGAL_COPYRIGHT "Copyright \251 Microsoft Corporation\0" +#endif + +#ifndef RC_VERSION_LEGAL_TRADEMARKS + #define RC_VERSION_LEGAL_TRADEMARKS "Microsoft\256 is a registered trademark of Microsoft Corporation.\0" +#endif + +FILEOS 0x4L +FILETYPE 0x1L +FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RC_VERSION_COMPANY_NAME + VALUE "FileDescription", RC_VERSION_FILE_DESCRIPTION + VALUE "InternalName", RC_VERSION_INTERNAL_NAME + VALUE "LegalCopyright", RC_VERSION_LEGAL_COPYRIGHT + VALUE "LegalTrademarks", RC_VERSION_LEGAL_TRADEMARKS + VALUE "OriginalFilename", RC_VERSION_ORIGINAL_FILE_NAME + VALUE "ProductName", RC_VERSION_PRODUCT_NAME + VALUE "FileVersion", INET_VERSION + VALUE "ProductVersion", INET_VERSION + VALUE "PrivateBuild", BUILD_PRIVATE +#ifdef OLEREGISTER + VALUE "OLESelfRegister","\0" +#endif + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Setup.sln b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Setup.sln new file mode 100644 index 0000000000..4ec3c19636 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/IIS-Setup.sln @@ -0,0 +1,41 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iisca", "iisca\lib\iisca.vcxproj", "{7324770C-0871-4D73-BE3D-5E2F3E9E1B1E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonLib", "IIS-Common\lib\CommonLib.vcxproj", "{B54A8F61-60DE-4AD9-87CA-D102F230678E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7324770C-0871-4D73-BE3D-5E2F3E9E1B1E}.Debug|x64.ActiveCfg = Debug|x64 + {7324770C-0871-4D73-BE3D-5E2F3E9E1B1E}.Debug|x64.Build.0 = Debug|x64 + {7324770C-0871-4D73-BE3D-5E2F3E9E1B1E}.Debug|x86.ActiveCfg = Debug|Win32 + {7324770C-0871-4D73-BE3D-5E2F3E9E1B1E}.Debug|x86.Build.0 = Debug|Win32 + {7324770C-0871-4D73-BE3D-5E2F3E9E1B1E}.Release|x64.ActiveCfg = Release|x64 + {7324770C-0871-4D73-BE3D-5E2F3E9E1B1E}.Release|x64.Build.0 = Release|x64 + {7324770C-0871-4D73-BE3D-5E2F3E9E1B1E}.Release|x86.ActiveCfg = Release|Win32 + {7324770C-0871-4D73-BE3D-5E2F3E9E1B1E}.Release|x86.Build.0 = Release|Win32 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Debug|x64.ActiveCfg = Debug|x64 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Debug|x64.Build.0 = Debug|x64 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Debug|x86.ActiveCfg = Debug|Win32 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Debug|x86.Build.0 = Debug|Win32 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Release|x64.ActiveCfg = Release|x64 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Release|x64.Build.0 = Release|x64 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Release|x86.ActiveCfg = Release|Win32 + {B54A8F61-60DE-4AD9-87CA-D102F230678E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3DC22D38-F38B-420A-9AD1-77F2512B35FF} + EndGlobalSection +EndGlobal diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/LICENSE b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/LICENSE new file mode 100644 index 0000000000..21071075c2 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/README.md b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/README.md new file mode 100644 index 0000000000..22e594aa6c --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/README.md @@ -0,0 +1,18 @@ +Microsoft IIS Setup +-------------------------------- + +The repository contains setup resources shared by IIS Out-Of-Band (OOB) products. + +### Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/appsearch/appsearch.wxi b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/appsearch/appsearch.wxi new file mode 100644 index 0000000000..820cc86f4e --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/appsearch/appsearch.wxi @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/build/exports.props b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/build/exports.props new file mode 100644 index 0000000000..94f411d056 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/build/exports.props @@ -0,0 +1,23 @@ + + + + + + $(MSBuildThisFileDirectory)..\ + + + + + + <_IIS-CommonExportsPath>$(IIS-Setup)\IIS-Common\build\exports.props + + + + + + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/build/submodule.props b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/build/submodule.props new file mode 100644 index 0000000000..d51d7f8d8e --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/build/submodule.props @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/ConfigShared.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/ConfigShared.cpp new file mode 100644 index 0000000000..883a228a33 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/ConfigShared.cpp @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + + +HRESULT +CheckInstallToSharedConfig( + IN MSIHANDLE hInstall, + BOOL * pbShouldInstall + ) +{ + HRESULT hr = S_OK; + STRU strShared; + STRU strWriteToShared; + + *pbShouldInstall = FALSE; + + //Check if config is shared + hr = MsiUtilGetProperty( hInstall, L"IISCONFIGISSHARED", &strShared ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + if( 0 != wcscmp( strShared.QueryStr(), L"1" ) ) + { + //config is not shared, tell caller to schedule executeCA for config + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"IIS Configuration is NOT shared. Setup will schedule the deferred custom action."); + *pbShouldInstall = TRUE; + goto exit; + } + + // + //config is shared lets check IIUSESHAREDCONFIG Property + // + hr = MsiUtilGetProperty( hInstall, L"IIUSESHAREDCONFIG", &strWriteToShared ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + if( 0 == wcscmp( strWriteToShared.QueryStr(), L"1" ) ) + { + //Config is shared but property is set + //tell caller to schedule executeCA for config + // + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"IIS Configuration IS shared. IIUSESHAREDCONFIG property indicated that setup SHOULD schedule the deferred custom action.."); + *pbShouldInstall = TRUE; + } + else + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"IIS Configuration IS shared. IIUSESHAREDCONFIG property indicated that setup should NOT schedule the deferred custom action."); + } + +exit: + return hr; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/ConfigShared.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/ConfigShared.h new file mode 100644 index 0000000000..0ac0ea9852 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/ConfigShared.h @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +HRESULT +CheckInstallToSharedConfig( + IN MSIHANDLE hInstall, + BOOL * pbShouldInstall + ); diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/CustomAction.def b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/CustomAction.def new file mode 100644 index 0000000000..8ba47da929 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/CustomAction.def @@ -0,0 +1,15 @@ +; Copyright (c) Microsoft Corporation. All rights reserved. +; Licensed under the MIT license. + +LIBRARY iisca + +EXPORTS + + ; IIS Common Config custom actions + + IISScheduleInstallCA + IISScheduleUninstallCA + IISExecuteCA + IISBeginTransactionCA + IISRollbackTransactionCA + IISCommitTransactionCA diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/cgi_restrictions.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/cgi_restrictions.cpp new file mode 100644 index 0000000000..b57a5d3037 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/cgi_restrictions.cpp @@ -0,0 +1,271 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +// +// Public functions +// + +HRESULT +RegisterCgiRestriction( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szPath, + IN BOOL fAllowed, + IN OPTIONAL CONST WCHAR * szGroupId, + IN OPTIONAL CONST WCHAR * szDescription + ) +{ + HRESULT hr = NOERROR; + + CComPtr pCgiRestrictionSection; + CComPtr pCgiRestrictionCollection; + CComPtr pNewCgiRestrictionElement; + + BSTR bstrAppHostConfigPath = SysAllocString(szConfigPath); + BSTR bstrCgiRestriction = SysAllocString( L"system.webServer/security/isapiCgiRestriction" ); + BSTR bstrAdd = SysAllocString( L"add" ); + + if( !bstrAppHostConfigPath || + !bstrCgiRestriction || + !bstrAdd ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto exit; + } + + // + // Remove any existing web service first, + // ignore any resulting errors. + // + + hr = UnRegisterCgiRestriction( + pAdminMgr, + szConfigPath, + szPath, + FALSE // do NOT expand environment strings + ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + // press on regardless + } + + hr = UnRegisterCgiRestriction( + pAdminMgr, + szConfigPath, + szPath, + TRUE // DO expand environment strings + ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + // press on regardless + } + + // + // Get the ISAPI CGI Restriction collection + // + + hr = pAdminMgr->GetAdminSection( bstrCgiRestriction, + bstrAppHostConfigPath, + &pCgiRestrictionSection ); + + + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = pCgiRestrictionSection->get_Collection( &pCgiRestrictionCollection ); + + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + // + // Create a new element + // + + hr = pCgiRestrictionCollection->CreateNewElement( bstrAdd, + &pNewCgiRestrictionElement ); + + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = SetElementStringProperty( + pNewCgiRestrictionElement, + L"path", + szPath + ); + + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = SetElementStringProperty( + pNewCgiRestrictionElement, + L"allowed", + fAllowed ? L"true" : L"false" + ); + + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + if( szGroupId && *szGroupId ) + { + hr = SetElementStringProperty( + pNewCgiRestrictionElement, + L"groupId", + szGroupId + ); + + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + } + + if( szDescription && *szDescription ) + { + hr = SetElementStringProperty( + pNewCgiRestrictionElement, + L"description", + szDescription + ); + + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + } + + // + // Add the new element + // + + hr = pCgiRestrictionCollection->AddElement( pNewCgiRestrictionElement ); + + if( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + +exit: + + SysFreeString( bstrAppHostConfigPath ); + SysFreeString( bstrCgiRestriction ); + SysFreeString( bstrAdd ); + + return hr; +} + +HRESULT +UnRegisterCgiRestriction( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szPath, + IN BOOL fExpandPath + ) +{ + HRESULT hr = NOERROR; + + CComPtr pCgiRestrictionSection; + CComPtr pCgiRestrictionCollection; + + BSTR bstrAppHostConfigPath = SysAllocString(szConfigPath); + BSTR bstrCgiRestriction = SysAllocString( L"system.webServer/security/isapiCgiRestriction" ); + + UINT numDeleted; + + STRU expandedPath; + + if( !bstrAppHostConfigPath || + !bstrCgiRestriction ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto exit; + } + + if (fExpandPath) + { + hr = expandedPath.CopyAndExpandEnvironmentStrings(szPath); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + szPath = expandedPath.QueryStr(); + } + + // + // Remove from the ISAPI CGI Restriction collection + // + + hr = pAdminMgr->GetAdminSection( bstrCgiRestriction, + bstrAppHostConfigPath, + &pCgiRestrictionSection ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pCgiRestrictionSection->get_Collection( &pCgiRestrictionCollection ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = DeleteAllElementsFromCollection( pCgiRestrictionCollection, + L"path", + szPath, + FIND_ELEMENT_CASE_INSENSITIVE, + &numDeleted + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if( numDeleted == 0 ) + { + DBGWARN(( DBG_CONTEXT, + "Expected to find %S in ISAPI CGI Restriction collection\n", + szPath )); + } + +exit: + + SysFreeString( bstrAppHostConfigPath ); + SysFreeString( bstrCgiRestriction ); + + return hr; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/cgi_restrictions.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/cgi_restrictions.h new file mode 100644 index 0000000000..68ae838d07 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/cgi_restrictions.h @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + + +#ifndef _CGI_RESTRICTIONS_H_ +#define _CGI_RESTRICTIONS_H_ + + +HRESULT +RegisterCgiRestriction( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szPath, + IN BOOL fAllowed, + IN OPTIONAL CONST WCHAR * szGroupId, + IN OPTIONAL CONST WCHAR * szDescription + ); + + +HRESULT +UnRegisterCgiRestriction( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szPath, + IN BOOL fExpandPath = FALSE + ); + + +#endif + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/config_custom.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/config_custom.cpp new file mode 100644 index 0000000000..8d44a69506 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/config_custom.cpp @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +UINT +__stdcall +CheckForSharedConfigurationCA( + MSIHANDLE hInstall +) +{ + HRESULT hr = S_OK; + UINT status = ERROR_SUCCESS; + BOOL fIsSharedConfig = FALSE; + STRU strWriteToShared; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + hr = GetSharedConfigEnabled( &fIsSharedConfig ); + if ( FAILED( hr ) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Unable to detect whether shared configuration is in use."); + status = LogMsiCustomActionError( hInstall, 30001 ); + goto exit; + } + if ( fIsSharedConfig ) + { + //set config shared property. + //will be used by other CAs via CheckInstallToSharedConfig + hr = MsiSetProperty( hInstall, L"IISCONFIGISSHARED", L"1" ); + if ( FAILED( hr ) ) + { + goto exit; + } + // + //config is shared lets check if user + //set public property IIUSESHAREDCONFIG + // + hr = MsiUtilGetProperty( hInstall, L"IIUSESHAREDCONFIG", &strWriteToShared ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + if( 0 == wcscmp( strWriteToShared.QueryStr(), L"1" ) ) + { + //Config is shared but property is set + //tell caller to schedule executeCA for config + // + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"IIS Configuration IS shared. IIUSESHAREDCONFIG property indicated that setup SHOULD schedule the deferred custom action.."); + } + else + { + // + //public property not set error-out install + // + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Shared Configuration detected."); + status = LogMsiCustomActionError( hInstall, 30002 ); + goto exit; + } + } + else + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"No Shared Configuration detected."); + } + +exit: + + IISLogClose(); + return status; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/config_custom.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/config_custom.h new file mode 100644 index 0000000000..f69b0101c4 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/config_custom.h @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + + +#ifndef _CONFIG_CUSTOM_H_ +#define _CONFIG_CUSTOM_H_ + + +UINT +__stdcall +CheckForSharedConfigurationCA( + MSIHANDLE hInstall +); + +#endif + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/consoleprops.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/consoleprops.cpp new file mode 100644 index 0000000000..ed39ca6af6 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/consoleprops.cpp @@ -0,0 +1,594 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +#define CheckAndGoToExit(hr,sev,msg,prop) if (FAILED(hr)) { DBGERROR_HR(hr); IISLogWrite(sev, msg, prop, hr);goto exit;} +#define CheckAndReturnHr(hr,sev,msg,prop) if (FAILED(hr)) { DBGERROR_HR(hr); IISLogWrite(sev, msg, prop, hr);return hr;} + + +HRESULT +GetConsoleIntProperty( + IN MSIHANDLE hRecord, + IN UINT field, + __inout CA_DATA_WRITER * cadata) +{ + HRESULT hr = S_OK; + + UINT dwValue = 0; + hr = MsiUtilRecordGetInteger( hRecord, + field, + &dwValue ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting column %d from record, hr=0x%x", field, hr); + return hr; + } + + hr = cadata->Write(dwValue); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error writing custom action data, hr=0x%x", hr); + return hr; + } + + return hr; +} + +HRESULT +GetConsoleProperties( + IN MSIHANDLE hRecord, + __inout CA_DATA_WRITER * cadata) +{ + HRESULT hr = S_OK; + + /*STACK_STRU( strTextColour, 128 ); + STACK_STRU( strBackgroundColour, 128 );*/ + + enum { + CA_CONSOLEPROPS_QUCIKEDIT = 5, + CA_CONSOLEPROPS_INSERTMODE, + CA_CONSOLEPROPS_WINDOWWIDTH, + CA_CONSOLEPROPS_WINDOWHEIGHT, + CA_CONSOLEPROPS_BUFFERWIDTH, + CA_CONSOLEPROPS_BUFFERHEIGHT, + /* CA_CONSOLEPROPS_TEXTCOLOUR, + CA_CONSOLEPROPS_BACKGROUNDCOLOUR*/ + }; + + // GET QuickEdit int + hr = GetConsoleIntProperty( hRecord, + CA_CONSOLEPROPS_QUCIKEDIT, + cadata ); + if ( FAILED(hr) ) { return hr;} + + // GET InsertMode + hr = GetConsoleIntProperty( hRecord, + CA_CONSOLEPROPS_INSERTMODE, + cadata ); + if ( FAILED(hr) ) { return hr;} + + + // GET WindowWidth + hr = GetConsoleIntProperty( hRecord, + CA_CONSOLEPROPS_WINDOWWIDTH, + cadata ); + if ( FAILED(hr) ) { return hr;} + + + // GET WindowHeight + hr = GetConsoleIntProperty( hRecord, + CA_CONSOLEPROPS_WINDOWHEIGHT, + cadata ); + if ( FAILED(hr) ) { return hr;} + + + // GET BufferWidth + hr = GetConsoleIntProperty( hRecord, + CA_CONSOLEPROPS_BUFFERWIDTH, + cadata ); + if ( FAILED(hr) ) { return hr;} + + + // GET BufferHeight + hr = GetConsoleIntProperty( hRecord, + CA_CONSOLEPROPS_BUFFERHEIGHT, + cadata ); + if ( FAILED(hr) ) { return hr;} + + //// Get Text colours + //hr = MsiUtilRecordGetString( hRecord, + // CA_CONSOLEPROPS_TEXTCOLOUR, + // &strTextColour ); + + //CheckAndReturnHr(hr, SETUP_LOG_SEVERITY_ERROR, L"Error getting column %d from record, hr=0x%x", CA_CONSOLEPROPS_TEXTCOLOUR); + + //hr = cadata->Write( strTextColour.QueryStr(), strTextColour.QueryCCH() ); + //if ( FAILED(hr) ) + //{ + // DBGERROR_HR(hr); + // IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error writing custom action data, hr=0x%x", hr); + // return hr; + //} + + //// Get Background colours + //hr = MsiUtilRecordGetString( hRecord, + // CA_CONSOLEPROPS_BACKGROUNDCOLOUR, + // &strBackgroundColour ); + + //CheckAndReturnHr(hr, SETUP_LOG_SEVERITY_ERROR, L"Error getting column %d from record, hr=0x%x", CA_CONSOLEPROPS_TEXTCOLOUR); + + //hr = cadata->Write( strBackgroundColour.QueryStr(), strBackgroundColour.QueryCCH() ); + //if ( FAILED(hr) ) + //{ + // DBGERROR_HR(hr); + // IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error writing custom action data, hr=0x%x", hr); + // return hr; + //} + + return hr; +} + +UINT +WINAPI +ScheduleSetConsolePropertiesCA( + IN MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strShortcut, 128 ); + STACK_STRU( strDirectoryId, 256 ); // Directory Identifier + STACK_STRU( strDirectoryName, 256 ); + STACK_STRU( strComponent, 128 ); + STACK_STRU( strShortcutName, 256 ); + STACK_STRU( strData, 256); + + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISShortcutConsoleProperties`.`Shortcut_`, " + L"`Shortcut`.`Component_`, " + L"`Shortcut`.`Name`, " + L"`Directory`.`Directory`, " + L"`IISShortcutConsoleProperties`.`QuickEdit`, " + L"`IISShortcutConsoleProperties`.`InsertMode`, " + L"`IISShortcutConsoleProperties`.`WindowWidth`, " + L"`IISShortcutConsoleProperties`.`WindowHeight`, " + L"`IISShortcutConsoleProperties`.`BufferWidth`, " + L"`IISShortcutConsoleProperties`.`BufferHeight` " + /*L"`IISShortcutConsoleProperties`.`TextColor`, " + L"`IISShortcutConsoleProperties`.`BackgroundColor` "*/ + L"FROM `IISShortcutConsoleProperties`, `Shortcut`, `Directory` " + L"WHERE `IISShortcutConsoleProperties`.`Shortcut_`=`Shortcut`.`Shortcut` " + L"AND `Shortcut`.`Directory_`=`Directory`.`Directory`"; + + + CA_DATA_WRITER cadata; + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + BOOL scheduleDefferedCA = FALSE; + + enum { + CA_CONSOLEPROPS_SHORTCUT = 1, + CA_CONSOLEPROPS_COMPONENT, + CA_CONSOLEPROPS_SHORTCUTNAME, + CA_CONSOLEPROPS_DIRECTORY, + }; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting MSI database, hr=0x%x", hr); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error opening View, hr=0x%x", hr); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error executing view, hr=0x%x", hr); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_CONSOLEPROPS_COMPONENT, + &strComponent ); + CheckAndGoToExit(hr, SETUP_LOG_SEVERITY_ERROR, L"Error getting column %d from record, hr=0x%x", CA_CONSOLEPROPS_COMPONENT); + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting state for component %s, hr=0x%x", strComponent.QueryStr(), hr); + goto exit; + } + + // Only run if the comonent is installing or reinstalling + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + // Get Shortcut location + { + // GET: directory where shortcut is + // Get the directory id for the shortcut + hr = MsiUtilRecordGetString( hRecord, + CA_CONSOLEPROPS_DIRECTORY, + &strDirectoryId ); + + CheckAndGoToExit(hr, SETUP_LOG_SEVERITY_ERROR, L"Error getting column %d from record, hr=0x%x", CA_CONSOLEPROPS_DIRECTORY); + + // Get directory path + hr = MsiUtilGetProperty(hInstall, strDirectoryId.QueryStr(), &strDirectoryName ); + + CheckAndGoToExit(hr, SETUP_LOG_SEVERITY_ERROR, L"Error getting value for directory record %s, hr=0x%x", strDirectoryId.QueryStr()); + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Shortcut Directory: '%s'.", + strDirectoryName.QueryStr()); + // ENDGET: directory where shortcut is + + + // GET: Short and Long names of shortcuts + hr = MsiUtilRecordGetString( hRecord, + CA_CONSOLEPROPS_SHORTCUTNAME, + &strShortcutName ); + + CheckAndGoToExit(hr, SETUP_LOG_SEVERITY_ERROR, L"Error getting column %d from record, hr=0x%x", CA_CONSOLEPROPS_SHORTCUTNAME); + + + // strShortcutName contains the short and long file names of the shortcut + PCWSTR pszPrevious = strShortcutName.QueryStr(); + // Append the shortcut name to the directory and write to cadata + // Write the short and long shortcut paths + for ( DWORD i = 0; i < strShortcutName.QueryCCH() + 1; i++ ) + { + if ( strShortcutName.QueryStr()[ i ] == L'|' || + strShortcutName.QueryStr()[ i ] == L'\0' ) + { + strShortcutName.QueryStr()[ i ] = L'\0'; + + strData.Copy( strDirectoryName ); + strData.Append(L"\\"); + strData.Append(pszPrevious); + strData.Append(L".lnk"); + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Potential shortcut path: %s", + strData.QueryStr()); + + hr = cadata.Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error writing custom action data, hr=0x%x", hr); + goto exit; + } + + pszPrevious = strShortcutName.QueryStr() + i + 1; + + // Get the console properties + hr = GetConsoleProperties(hRecord, &cadata); + if( FAILED(hr)) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting console properties, hr=0x%x", hr); + goto exit; + } + + // Only schedule custom action if needed + scheduleDefferedCA = TRUE; + } + } + // ENDGET: Short and Long names of shortcuts + } + // End OF getting shortcut location + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + } + + if ( scheduleDefferedCA ) + { + hr = MsiUtilScheduleDeferredAction( hInstall, + L"ExecuteSetConsoleProperties", + cadata.QueryData() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error scheduling custom action, hr=0x%x", hr); + goto exit; + } + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Custom action ExecuteSetConsoleProperties scheduled"); + } + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogClose(); + + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_SUCCESS; +} + +void IntializeConsoleProps( + IN NT_CONSOLE_PROPS* pConsoleProps + ) +{ + if (!pConsoleProps) + { + return; + } + + pConsoleProps->dbh.cbSize = sizeof(NT_CONSOLE_PROPS); + pConsoleProps->dbh.dwSignature = NT_CONSOLE_PROPS_SIG; + pConsoleProps->bFullScreen = false; + pConsoleProps->uHistoryBufferSize = 50; + pConsoleProps->uNumberOfHistoryBuffers = 4; + pConsoleProps->uCursorSize = 25; + + pConsoleProps->ColorTable[0] = RGB(0,0,0); + pConsoleProps->ColorTable[1] = RGB(0,0,128); + pConsoleProps->ColorTable[2] = RGB(0,128,0); + pConsoleProps->ColorTable[3] = RGB(0,128,128); + pConsoleProps->ColorTable[4] = RGB(128,0,0); + pConsoleProps->ColorTable[5] = RGB(128,0,128); + pConsoleProps->ColorTable[6] = RGB(128,128,0); + pConsoleProps->ColorTable[7] = RGB(192,192,192); + pConsoleProps->ColorTable[8] = RGB(128,128,128); + pConsoleProps->ColorTable[9] = RGB(0,0,255); + pConsoleProps->ColorTable[10] = RGB(0,255,0); + pConsoleProps->ColorTable[11] = RGB(0,255,255); + pConsoleProps->ColorTable[12] = RGB(255,0,0); + pConsoleProps->ColorTable[13] = RGB(255,0,255); + pConsoleProps->ColorTable[14] = RGB(255,255,0); + pConsoleProps->ColorTable[15] = RGB(255,255,255); + + pConsoleProps->wPopupFillAttribute = ((15 << 4) | 3); +} + + +UINT +WINAPI +ExecuteSetConsolePropertiesCA( + IN MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + + BOOL fCoInit = FALSE; + + WCHAR * szShortcutFile = NULL; + /*WCHAR * szTextColour = NULL; + WCHAR * szBackgroundColour = NULL;*/ + INT dwQuickEdit = 0; + INT dwInsertMode = 0; + INT dwWindowWidth = 120; + INT dwWindowHeight = 50; + INT dwBufferWidth = 120; + INT dwBufferHeight = 3000; + + + CA_DATA_READER cadata; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + // + // Retrieve parameters from ca data + // + + hr = cadata.LoadDeferredCAData( hInstall ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error retrieving custom action data, hr=0x%x", hr); + goto exit; + } + + if ( SUCCEEDED( hr = CoInitialize(NULL) ) ) + { + fCoInit = TRUE; + } + + while ( SUCCEEDED(hr = cadata.Read( &szShortcutFile )) ) + { + hr = cadata.Read( &dwQuickEdit); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata.Read( &dwInsertMode); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata.Read( &dwWindowWidth); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata.Read( &dwWindowHeight); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata.Read( &dwBufferWidth); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata.Read( &dwBufferHeight); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + /*hr = cadata.Read( &szTextColour); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata.Read( &szBackgroundColour); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + }*/ + + // Check to see if file exists + if(GetFileAttributes(szShortcutFile) != 0xFFFFFFFF) + { + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Shortcut %s exists", szShortcutFile); + + // Get shell + CComPtr sppf; + + if (FAILED(hr = sppf.CoCreateInstance(L"lnkfile")) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error get ShellLink com object, hr=0x%x", hr); + goto exit; + } + + // Load shortcut file + if (FAILED(hr = sppf->Load(szShortcutFile, STGM_READWRITE))) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error loading shortcut file %s, hr=0x%x", szShortcutFile, hr); + goto exit; + } + + CComQIPtr spdl(sppf); + if (!spdl) + { + DBGERROR_HR(hr); + goto exit; + } + + NT_CONSOLE_PROPS* pConsoleProps = NULL; + + hr = spdl->CopyDataBlock(NT_CONSOLE_PROPS_SIG, (LPVOID*) &pConsoleProps); + if ( FAILED(hr) || (NULL == pConsoleProps) ) + { + // Create new console properties and set defaults + pConsoleProps = (NT_CONSOLE_PROPS *)malloc(sizeof(NT_CONSOLE_PROPS)); + memset(pConsoleProps,0,sizeof(NT_CONSOLE_PROPS)); + IntializeConsoleProps(pConsoleProps); + } + + pConsoleProps->bQuickEdit = dwQuickEdit > 0; + pConsoleProps->bInsertMode = dwInsertMode > 0; + pConsoleProps->dwWindowSize.X = (short) dwWindowWidth; + pConsoleProps->dwWindowSize.Y = (short) dwWindowHeight; + pConsoleProps->dwScreenBufferSize.X = (short) dwBufferWidth; + pConsoleProps->dwScreenBufferSize.Y = (short) dwBufferHeight; + + pConsoleProps->ColorTable[6] = RGB(238, 237, 240); // text color + pConsoleProps->ColorTable[5] = RGB(1, 36, 86); // backgroud color + pConsoleProps->wFillAttribute = ((5 << 4) | 6 ); + + + spdl->RemoveDataBlock(NT_CONSOLE_PROPS_SIG); + if (FAILED(hr = spdl->AddDataBlock((void *)pConsoleProps))) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error setting NT_CONSOLE_PROPS on shortcut file %s, hr=0x%x", szShortcutFile, hr); + goto exit; + } + + if (FAILED(hr = sppf->Save(NULL, TRUE))) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error saving changes to shortcut, hr=0x%x", hr); + goto exit; + } + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Successfully added properties to shortcut %s", + szShortcutFile); + + } + } + + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + if ( fCoInit ) + { + CoUninitialize(); + } + + IISLogClose(); + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_SUCCESS; +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/consoleprops.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/consoleprops.h new file mode 100644 index 0000000000..11692e14b3 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/consoleprops.h @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +UINT +WINAPI +ScheduleSetConsolePropertiesCA( + IN MSIHANDLE hInstall + ); + +UINT +WINAPI +ExecuteSetConsolePropertiesCA( + IN MSIHANDLE hInstall + ); \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/defaults.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/defaults.cpp new file mode 100644 index 0000000000..51a9831cf7 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/defaults.cpp @@ -0,0 +1,716 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + + +HRESULT +SetElementMetadata( + IAppHostElement * pElement, + CONST WCHAR * szMetaType, + CONST VARIANT * pVarValue + ) +{ + HRESULT hr = NOERROR; + + BSTR bstrMetaType = SysAllocString( szMetaType ); + if( !bstrMetaType ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pElement->SetMetadata( bstrMetaType, + *pVarValue ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + SysFreeString( bstrMetaType ); + + return hr; +} + +HRESULT +ProcessAttributes( + IAppHostElement * pElement, + IXmlReader * pReader + ) +{ + HRESULT hr = NOERROR; + + VARIANT varPropValue; + VariantInit( &varPropValue ); + + CONST WCHAR * pszName; + CONST WCHAR * pszValue; + + for( hr = pReader->MoveToFirstAttribute(); + ; + hr = pReader->MoveToNextAttribute() ) + { + if (hr == S_FALSE) + { + hr = S_OK; + break; + } + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pReader->GetLocalName( &pszName, NULL ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pReader->GetValue( &pszValue, NULL ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = VariantAssign( &varPropValue, pszValue ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = SetElementProperty( pElement, pszName, &varPropValue ); + + if( HRESULT_FROM_WIN32( ERROR_INVALID_INDEX ) == hr ) + { + // + // Possibly this is a metadata attribute not a property + // + + hr = SetElementMetadata( pElement, pszName, &varPropValue ); + } + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + VariantClear( &varPropValue ); + } + +exit: + + VariantClear( &varPropValue ); + + return hr; +} + +HRESULT +ProcessSection( + IAppHostWritableAdminManager * pAdminMgr, + CONST WCHAR * szSectionName, + IXmlReader * pReader, + IAppHostElement * pParent, + BOOL fClearSection + ) +{ + HRESULT hr = NOERROR; + + CComPtr pChildElement; + CComPtr pParentElement = pParent; + + CONST WCHAR * pwszLocalName; + + BSTR bstrName = NULL; + BSTR bstrSectionName = NULL; + BSTR bstrRoot = NULL; + BSTR bstrAddElementName = NULL; + + BOOL isEmpty = FALSE; + + bstrSectionName = SysAllocString( szSectionName ); + bstrRoot = SysAllocString( L"MACHINE/WEBROOT/APPHOST" ); + + if( !bstrSectionName || !bstrRoot ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + XmlNodeType nodeType; + + for (;;) + { + hr = pReader->Read(&nodeType); + + if (hr == S_FALSE) + { + hr = S_OK; + break; + } + + if (FAILED(hr)) + { + break; + } + + if( nodeType == XmlNodeType_Element ) + { + hr = pReader->GetLocalName( &pwszLocalName, NULL ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + SysFreeString( bstrName ); + bstrName = NULL; + + bstrName = SysAllocString( pwszLocalName ); + if( !bstrName ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + isEmpty = pReader->IsEmptyElement(); + + if( !pParent ) + { + // + // This is the entry point to resetting the section. Begin by + // clearing. + // + + hr = pAdminMgr->GetAdminSection( bstrSectionName, + bstrRoot, + &pChildElement ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if (fClearSection) + { + hr = pChildElement->Clear(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // Need to commit change after clear + + hr = pAdminMgr->CommitChanges(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // Need to reload after commit + + pChildElement.Release(); + + hr = pAdminMgr->GetAdminSection( bstrSectionName, + bstrRoot, + &pChildElement ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + } + else + { + // Test the parent of this node for a collection + + CComPtr pCollection; + hr = pParentElement->get_Collection( &pCollection ); + + if ( SUCCEEDED ( hr ) && ( pCollection != NULL ) ) + { + // Get the schema for the collection + CComPtr pCollectionSchema; + hr = pCollection->get_Schema( &pCollectionSchema ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + SysFreeString( bstrAddElementName ); + bstrAddElementName = NULL; + + // Parent element has a collection. Get the addElement token. + pCollectionSchema->get_AddElementNames(&bstrAddElementName); + + if( 0 == wcscmp( pwszLocalName, bstrAddElementName ) ) + { + hr = pCollection->CreateNewElement( bstrName, &pChildElement ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = ProcessAttributes( pChildElement, pReader ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pCollection->AddElement( pChildElement ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + pCollection.Release(); + } + else + { + // Parent has collection, but this isn't an 'addElement' + hr = pParentElement->GetElementByName( bstrName, + &pChildElement ); + if( FAILED(hr) ) + { + DBGERROR(( DBG_CONTEXT, "Failed to get child element %S, %08x\n", bstrName, hr )); + goto exit; + } + } + + pCollectionSchema.Release(); + } + else + { + // Parent is not a collection. + hr = pParentElement->GetElementByName( bstrName, + &pChildElement ); + if( FAILED(hr) ) + { + DBGERROR(( DBG_CONTEXT, "Failed to get child element %S, %08x\n", bstrName, hr )); + goto exit; + } + } + } + + hr = ProcessAttributes( pChildElement, pReader ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if( !isEmpty ) + { + hr = ProcessSection( pAdminMgr, + szSectionName, + pReader, + pChildElement, + fClearSection); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + pChildElement.Release(); + } + else if( nodeType == XmlNodeType_EndElement ) + { + break; + } + } + +exit: + + SysFreeString( bstrAddElementName ); + SysFreeString( bstrName ); + SysFreeString( bstrSectionName ); + SysFreeString( bstrRoot ); + + return hr; +} + +HRESULT +ResetConfigSection( + IN IAppHostWritableAdminManager * pAdminMgr, + IN CONST WCHAR * szSectionName, + IN OUT IStream * pStreamDefaults + ) +{ + HRESULT hr = NOERROR; + + CComPtr pReader; + + + hr = CreateXmlReader(__uuidof(IXmlReader), (void**) &pReader, NULL); + if( FAILED(hr) ) + { + DBGERROR(( DBG_CONTEXT, "Error creating xml reader, error is %08.8lx", hr)); + goto exit; + } + + hr = pReader->SetProperty( XmlReaderProperty_DtdProcessing, + DtdProcessing_Prohibit ); + if( FAILED(hr) ) + { + DBGERROR(( DBG_CONTEXT, "Error setting XmlReaderProperty_DtdProcessing, %08x", hr)); + goto exit; + } + + hr = pReader->SetInput( pStreamDefaults ); + if( FAILED(hr) ) + { + DBGERROR(( DBG_CONTEXT, "Error setting input for reader, %08x", hr)); + goto exit; + } + + hr = ProcessSection( pAdminMgr, + szSectionName, + pReader, + NULL, + TRUE); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return hr; +} + +HRESULT +CreateStreamFromTextResource( + IN HINSTANCE hInstance, + IN CONST WCHAR * szResourceName, + OUT IStream ** ppStream + ) +{ + HRESULT hr = NOERROR; + + HRSRC hResDefaults = NULL; + HGLOBAL hGlobDefaults = NULL; + LPCVOID pDefaults = NULL; + DWORD cbDefaults; + HGLOBAL hDefaultsData = NULL; + LPVOID pDefaultsData = NULL; + + hResDefaults = FindResourceW( g_hinst, + szResourceName, + L"TEXT" ); + if( !hResDefaults ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto exit; + } + + hGlobDefaults = LoadResource( hInstance, hResDefaults ); + if( !hGlobDefaults ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto exit; + } + + pDefaults = LockResource( hGlobDefaults ); + if( !pDefaults ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto exit; + } + + cbDefaults = SizeofResource( g_hinst, hResDefaults ); + if( !cbDefaults ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto exit; + } + + hDefaultsData = GlobalAlloc( GMEM_MOVEABLE, cbDefaults ); + if( !hDefaultsData ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto exit; + } + + pDefaultsData = GlobalLock( hDefaultsData ); + if( !pDefaultsData ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto exit; + } + + #pragma prefast( suppress:26010, "cbDefaults is allocated size for pDefaultsData" ) + CopyMemory( pDefaultsData, pDefaults, cbDefaults ); + + GlobalUnlock( hDefaultsData ); + + hr = CreateStreamOnHGlobal( hDefaultsData, TRUE, ppStream ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hDefaultsData = NULL; + +exit: + + if( hDefaultsData ) + { + GlobalFree( hDefaultsData ); + } + + return hr; +} + + +HRESULT +ResetConfigSectionFromResource( + IN CONST WCHAR * szResourceName, + IN CONST WCHAR * szSectionName + ) +{ + HRESULT hr = NOERROR; + + CComPtr pAdminMgr; + CComPtr pStream; + + hr = CreateStreamFromTextResource( g_hinst, + szResourceName, + &pStream ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( IAppHostWritableAdminManager ), + (VOID **)&pAdminMgr ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = ResetConfigSection( pAdminMgr, + szSectionName, + pStream ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Save + // + + hr = pAdminMgr->CommitChanges(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return ( hr ); +} + +HRESULT +ResetConfigSectionFromFile( + IN CONST WCHAR * szFileName, + IN CONST WCHAR * szSectionName + ) +{ + HRESULT hr = NOERROR; + + CComPtr pAdminMgr; + CComPtr pStream; + + hr = SHCreateStreamOnFileEx( szFileName, + STGM_READ, + FILE_ATTRIBUTE_NORMAL, + FALSE, + NULL, + &pStream); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( IAppHostWritableAdminManager ), + (VOID **)&pAdminMgr ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = ResetConfigSection( pAdminMgr, + szSectionName, + pStream ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Save + // + + hr = pAdminMgr->CommitChanges(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return ( hr ); +} + +HRESULT +AppendConfigSectionFromFile( + IN CONST WCHAR * szFileName, + IN CONST WCHAR * szSectionName + ) +{ + HRESULT hr = NOERROR; + + CComPtr pAdminMgr; + CComPtr pStream; + + hr = SHCreateStreamOnFileEx( szFileName, + STGM_READ, + FILE_ATTRIBUTE_NORMAL, + FALSE, + NULL, + &pStream); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( IAppHostWritableAdminManager ), + (VOID **)&pAdminMgr ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = AppendConfigSection( pAdminMgr, + szSectionName, + pStream ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Save + // + + hr = pAdminMgr->CommitChanges(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return ( hr ); +} + + +HRESULT +AppendConfigSection( + IN IAppHostWritableAdminManager * pAdminMgr, + IN CONST WCHAR * szSectionName, + IN OUT IStream * pStreamDefaults + ) +{ + HRESULT hr = NOERROR; + + CComPtr pReader; + + + hr = CreateXmlReader(__uuidof(IXmlReader), (void**) &pReader, NULL); + if( FAILED(hr) ) + { + DBGERROR(( DBG_CONTEXT, "Error creating xml reader, error is %08.8lx", hr)); + goto exit; + } + + hr = pReader->SetProperty( XmlReaderProperty_DtdProcessing, + DtdProcessing_Prohibit ); + if( FAILED(hr) ) + { + DBGERROR(( DBG_CONTEXT, "Error setting XmlReaderProperty_DtdProcessing, %08x", hr)); + goto exit; + } + + hr = pReader->SetInput( pStreamDefaults ); + if( FAILED(hr) ) + { + DBGERROR(( DBG_CONTEXT, "Error setting input for reader, %08x", hr)); + goto exit; + } + + hr = ProcessSection( pAdminMgr, + szSectionName, + pReader, + NULL, + FALSE); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return hr; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/defaults.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/defaults.h new file mode 100644 index 0000000000..491938dfc9 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/defaults.h @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _DEFAULTS_H_ +#define _DEFAULTS_H_ + + +// +// Helper routines for setting-up default module config. +// + +HRESULT +CreateStreamFromTextResource( + IN HINSTANCE hInstance, + IN CONST WCHAR * szResourceName, + OUT IStream ** ppStream + ); + +HRESULT +ResetConfigSection( + IN IAppHostWritableAdminManager * pAdminMgr, + IN CONST WCHAR * szSectionName, + IN OUT IStream * pStreamDefaults + ); + +HRESULT +ResetConfigSectionFromResource( + IN CONST WCHAR * szResourceName, + IN CONST WCHAR * szSectionName + ); + +HRESULT +ResetConfigSectionFromFile( + IN CONST WCHAR * szFileName, + IN CONST WCHAR * szSectionName + ); + +HRESULT +AppendConfigSectionFromFile( + IN CONST WCHAR * szFileName, + IN CONST WCHAR * szSectionName + ); + +HRESULT +AppendConfigSection( + IN IAppHostWritableAdminManager * pAdminMgr, + IN CONST WCHAR * szSectionName, + IN OUT IStream * pStreamDefaults + ); + +#endif + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/elevatedsc.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/elevatedsc.cpp new file mode 100644 index 0000000000..bc9abda798 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/elevatedsc.cpp @@ -0,0 +1,346 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +UINT +WINAPI +ScheduleMakeShortcutElevatedCA( + IN MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strShortcut, 128 ); + STACK_STRU( strDirectoryId, 256 ); // Directory Identifier + STACK_STRU( strDirectoryName, 256 ); + STACK_STRU( strComponent, 128 ); + STACK_STRU( strShortcutName, 256 ); + STACK_STRU( strData, 256); + + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISElevatedShortcut`.`Shortcut_`, " + L"`Shortcut`.`Component_`, " + L"`Shortcut`.`Name`, " + L"`Directory`.`Directory` " + L"FROM `IISElevatedShortcut`, `Shortcut`, `Directory` " + L"WHERE `IISElevatedShortcut`.`Shortcut_`=`Shortcut`.`Shortcut` " + L"AND `Shortcut`.`Directory_`=`Directory`.`Directory`"; + + + CA_DATA_WRITER cadata; + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + BOOL scheduleDefferedCA = FALSE; + + enum { + CA_ELEVATESC_SHORTCUT = 1, + CA_ELEVATESC_COMPONENT, + CA_ELEVATESC_SHORTCUTNAME, + CA_ELEVATESC_DIRECTORY, + }; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting MSI database, hr=0x%x", hr); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error opening View, hr=0x%x", hr); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error executing view, hr=0x%x", hr); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_ELEVATESC_COMPONENT, + &strComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting column %d from record, hr=0x%x", CA_ELEVATESC_COMPONENT, hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting state for component %s, hr=0x%x", strComponent.QueryStr(), hr); + goto exit; + } + + // Only run if the comonent is installing or reinstalling + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + // GET: directory where shortcut is + // Get the directory id for the shortcut + hr = MsiUtilRecordGetString( hRecord, + CA_ELEVATESC_DIRECTORY, + &strDirectoryId ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting column %d from record, hr=0x%x", CA_ELEVATESC_DIRECTORY, hr); + goto exit; + } + + // Get directory path + hr = MsiUtilGetProperty(hInstall, strDirectoryId.QueryStr(), &strDirectoryName ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting value for directory record %s, hr=0x%x", strDirectoryId.QueryStr(), hr); + goto exit; + } + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Shortcut Directory: '%s'.", + strDirectoryName.QueryStr()); + // ENDGET: directory where shortcut is + + + // GET: Short and Long names of shortcuts + hr = MsiUtilRecordGetString( hRecord, + CA_ELEVATESC_SHORTCUTNAME, + &strShortcutName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting column %d from record, hr=0x%x", CA_ELEVATESC_SHORTCUTNAME, hr); + goto exit; + } + + // strShortcutName contains the short and long file names of the shortcut + + PCWSTR pszPrevious = strShortcutName.QueryStr(); + // Append the shortcut name to the directory and write to cadata + // Write the short and long shortcut paths + for ( DWORD i = 0; i < strShortcutName.QueryCCH() + 1; i++ ) + { + if ( strShortcutName.QueryStr()[ i ] == L'|' || + strShortcutName.QueryStr()[ i ] == L'\0' ) + { + strShortcutName.QueryStr()[ i ] = L'\0'; + + strData.Copy( strDirectoryName ); + strData.Append(L"\\"); + strData.Append(pszPrevious); + strData.Append(L".lnk"); + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Potential shortcut path: %s", + strData.QueryStr()); + + hr = cadata.Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error writing custom action data, hr=0x%x", hr); + goto exit; + } + + pszPrevious = strShortcutName.QueryStr() + i + 1; + + // Only schedule custom action if needed + scheduleDefferedCA = TRUE; + } + } + + // ENDGET: Short and Long names of shortcuts + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + } + + if ( scheduleDefferedCA ) + { + hr = MsiUtilScheduleDeferredAction( hInstall, + L"ExecuteMakeShortcutElevated", + cadata.QueryData() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error scheduling custom action, hr=0x%x", hr); + goto exit; + } + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Custom action ExecuteMakeShortcutElevated scheduled"); + } + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogClose(); + + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_SUCCESS; +} + +UINT +WINAPI +ExecuteMakeShortcutElevatedCA( + IN MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + + BOOL fCoInit = FALSE; + + WCHAR * szShortcutFile = NULL; + + CA_DATA_READER cadata; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + // + // Retrieve parameters from ca data + // + + hr = cadata.LoadDeferredCAData( hInstall ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error retrieving custom action data, hr=0x%x", hr); + goto exit; + } + + if ( SUCCEEDED( hr = CoInitialize(NULL) ) ) + { + fCoInit = TRUE; + } + + while ( SUCCEEDED(hr = cadata.Read( &szShortcutFile )) ) + { + if(GetFileAttributes(szShortcutFile) != 0xFFFFFFFF) + { + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Shortcut %s exists", szShortcutFile); + + // Get shell + CComPtr sppf; + + if (FAILED(hr = sppf.CoCreateInstance(L"lnkfile")) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error get ShellLink com object, hr=0x%x", hr); + goto exit; + } + + // Load shortcut file + if (FAILED(hr = sppf->Load(szShortcutFile, STGM_READWRITE))) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error loading shortcut file %s, hr=0x%x", szShortcutFile, hr); + goto exit; + } + + CComQIPtr spdl(sppf); + if (!spdl) + { + DBGERROR_HR(hr); + goto exit; + } + + DWORD dwFlags; + if (FAILED(hr = spdl->GetFlags(&dwFlags))) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting shortcut flags, hr=0x%x", hr); + goto exit; + } + + // Add "run as ..." flag + dwFlags |= SLDF_RUNAS_USER; + if (FAILED(hr = spdl->SetFlags(dwFlags))) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error setting SLDF_RUNAS_USER flag, hr=0x%x", hr); + goto exit; + } + + // Save file. + if (FAILED(hr = sppf->Save(NULL, TRUE))) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error saving changes to shortcut, hr=0x%x", hr); + goto exit; + } + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Successfully added SLDF_RUNAS_USER flag to shortcut %s", + szShortcutFile); + + } + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + if ( fCoInit ) + { + CoUninitialize(); + } + + IISLogClose(); + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_SUCCESS; +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/elevatedsc.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/elevatedsc.h new file mode 100644 index 0000000000..c5f5428510 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/elevatedsc.h @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +UINT +WINAPI +ScheduleMakeShortcutElevatedCA( + IN MSIHANDLE hInstall + ); + +UINT +WINAPI +ExecuteMakeShortcutElevatedCA( + IN MSIHANDLE hInstall + ); \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/handlers.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/handlers.cpp new file mode 100644 index 0000000000..1e824ae72e --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/handlers.cpp @@ -0,0 +1,472 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +// +// Local function declarations +// + +// +// Public functions +// + +HRESULT +RegisterHandler( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN ULONG Index, + IN CONST WCHAR * szName, + IN CONST WCHAR * szPath, + IN CONST WCHAR * szVerbs, + IN OPTIONAL CONST WCHAR * szType, + IN OPTIONAL CONST WCHAR * szModules, + IN OPTIONAL CONST WCHAR * szScriptProcessor, + IN OPTIONAL CONST WCHAR * szResourceType, + IN OPTIONAL CONST WCHAR * szRequiredAccess, + IN OPTIONAL CONST WCHAR * szPreCondition + ) +{ + HRESULT hr; + CComPtr pHandlersCollection; + CComPtr pNewElement; + UINT numDeleted; + BSTR bstrAdd; + + bstrAdd = SysAllocString(L"add"); + + if (bstrAdd == NULL) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = GetHandlersCollection( + pAdminMgr, + szConfigPath, + &pHandlersCollection + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Just in case... delete if it's already there. + // + + hr = DeleteAllElementsFromCollection( + pHandlersCollection, + L"name", + szName, + FIND_ELEMENT_CASE_SENSITIVE, + &numDeleted + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if (Index == HANDLER_INDEX_BEFORE_STATICFILE) + { + // + // If the StaticFile handler is installed (and it probably is) + // then install just before it. + // + + hr = FindHandlerByName( + pAdminMgr, + szConfigPath, + HANDLER_STATICFILE_NAME, + &Index + ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + if (hr == S_FALSE) + { + // + // Not found. Install at end of list. + // + + Index = HANDLER_INDEX_LAST; + } + } + + // + // If the caller wants this to be the last handler, then + // chase down the current entry count. + // + + if (Index == HANDLER_INDEX_LAST) + { + hr = pHandlersCollection->get_Count(&Index); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + hr = pHandlersCollection->CreateNewElement(bstrAdd, &pNewElement); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Required properties. + // + + hr = SetElementStringProperty( + pNewElement, + L"name", + szName + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = SetElementStringProperty( + pNewElement, + L"path", + szPath + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = SetElementStringProperty( + pNewElement, + L"verb", + szVerbs + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Optional properties. + // + + if (szType != NULL && szType[0] != L'\0') + { + hr = SetElementStringProperty( + pNewElement, + L"type", + szType + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if (szModules != NULL && szModules[0] != L'\0') + { + hr = SetElementStringProperty( + pNewElement, + L"modules", + szModules + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if (szScriptProcessor != NULL && szScriptProcessor[0] != L'\0') + { + hr = SetElementStringProperty( + pNewElement, + L"scriptProcessor", + szScriptProcessor + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if (szResourceType != NULL && szResourceType[0] != L'\0') + { + hr = SetElementStringProperty( + pNewElement, + L"resourceType", + szResourceType + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if (szRequiredAccess != NULL && szRequiredAccess[0] != L'\0') + { + hr = SetElementStringProperty( + pNewElement, + L"requireAccess", + szRequiredAccess + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if (szPreCondition != NULL && szPreCondition[0] != L'\0') + { + hr = SetElementStringProperty( + pNewElement, + L"preCondition", + szPreCondition + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + hr = pHandlersCollection->AddElement(pNewElement, Index); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + SysFreeString(bstrAdd); + return hr; +} + +HRESULT +UnRegisterHandler( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szName + ) +{ + HRESULT hr; + CComPtr pHandlersCollection; + CComPtr pLocationCollection; + CComPtr pLocation; + CComPtr pElement; + ENUM_INDEX locationIndex; + BOOL found; + UINT numDeleted; + + // + // Enum the tags, look for any sections, + // and if found, remove the specified handler from each. + // + + hr = GetLocationCollection( + pAdminMgr, + szConfigPath, + &pLocationCollection + ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + for (hr = FindFirstLocation(pLocationCollection, &locationIndex, &pLocation) ; + SUCCEEDED(hr) ; + hr = FindNextLocation(pLocationCollection, &locationIndex, &pLocation)) + { + if (hr == S_FALSE) + { + hr = S_OK; + break; + } + + hr = GetSectionFromLocation( + pLocation, + L"system.webServer/handlers", + &pElement, + &found + ); + + if (SUCCEEDED(hr)) + { + if (found) + { + hr = pElement->get_Collection(&pHandlersCollection); + + if (SUCCEEDED(hr)) + { + hr = DeleteAllElementsFromCollection( + pHandlersCollection, + L"name", + szName, + FIND_ELEMENT_CASE_SENSITIVE, + &numDeleted + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + } + + pHandlersCollection.Release(); + } + else + { + DBGERROR_HR(hr); + } + + pElement.Release(); + } + } + else + { + DBGERROR_HR(hr); + } + + pLocation.Release(); + } + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return hr; +} + +HRESULT +FindHandlerByName( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szName, + OUT ULONG * pIndex + ) +{ + HRESULT hr; + CComPtr pHandlersCollection; + + *pIndex = 0; + + hr = GetHandlersCollection( + pAdminMgr, + szConfigPath, + &pHandlersCollection + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = FindElementInCollection( + pHandlersCollection, + L"name", + szName, + FIND_ELEMENT_CASE_SENSITIVE, + pIndex + ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return hr; +} + +HRESULT +GetHandlersCollection( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + OUT IAppHostElementCollection ** pHandlersCollection + ) +{ + HRESULT hr; + CComPtr pHandlersElement; + BSTR bstrConfigPath; + BSTR bstrHandlersSectionName; + + bstrConfigPath = SysAllocString(szConfigPath); + bstrHandlersSectionName = SysAllocString(L"system.webServer/handlers"); + *pHandlersCollection = NULL; + + if (bstrConfigPath == NULL || bstrHandlersSectionName == NULL) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + // + // Chase down the handlers collection. + // + + hr = pAdminMgr->GetAdminSection( bstrHandlersSectionName, + bstrConfigPath, + &pHandlersElement ); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pHandlersElement->get_Collection(pHandlersCollection); + + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + SysFreeString(bstrHandlersSectionName); + SysFreeString(bstrConfigPath); + return hr; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/handlers.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/handlers.h new file mode 100644 index 0000000000..3024acf8fd --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/handlers.h @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _HANDLERS_H_ +#define _HANDLERS_H_ + + +#define HANDLER_INDEX_FIRST 0 +#define HANDLER_INDEX_LAST ((ULONG)(-1L)) +#define HANDLER_INDEX_BEFORE_STATICFILE ((ULONG)(-2L)) + +#define HANDLER_STATICFILE_NAME L"StaticFile" + +HRESULT +RegisterHandler( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN ULONG Index, + IN CONST WCHAR * szName, + IN CONST WCHAR * szPath, + IN CONST WCHAR * szVerbs, + IN OPTIONAL CONST WCHAR * szType, + IN OPTIONAL CONST WCHAR * szModules, + IN OPTIONAL CONST WCHAR * szScriptProcessor, + IN OPTIONAL CONST WCHAR * szResourceType, + IN OPTIONAL CONST WCHAR * szRequiredAccess, + IN OPTIONAL CONST WCHAR * szPreCondition = NULL + ); + +HRESULT +UnRegisterHandler( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szName + ); + +HRESULT +FindHandlerByName( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + IN CONST WCHAR * szName, + OUT ULONG * pIndex + ); + +HRESULT +GetHandlersCollection( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + OUT IAppHostElementCollection ** pHandlersCollection + ); + + +#endif + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/hotfix.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/hotfix.cpp new file mode 100644 index 0000000000..a800948b13 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/hotfix.cpp @@ -0,0 +1,766 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" +#include "wuerror.h" + +#define REBOOT_REQUIRED_REGKEY L"Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce" +#define REBOOT_REGVALUE L"IIS Extensions Reboot Required" + +HRESULT ExecuteCommandLine( + IN PCWSTR szCommandLine, + IN DWORD dwTimeout, + __out LPDWORD pExitCode + + ) +{ + HRESULT hr = NOERROR; + UINT status = 0; + PROCESS_INFORMATION oProcInfo = {0}; + STARTUPINFOW oStartInfo = {0}; + DWORD dwExitCode = ERROR_SUCCESS; + STACK_STRU( strModifiableCommandLine, MAX_PATH); + + oStartInfo.cb = sizeof ( STARTUPINFOW ); + oProcInfo.hThread = INVALID_HANDLE_VALUE; + oProcInfo.hProcess = INVALID_HANDLE_VALUE; + + _ASSERTE ( szCommandLine ); + _ASSERTE ( pExitCode ); + + hr = strModifiableCommandLine.Copy ( szCommandLine ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error copying command line, hr=0x%x", hr); + goto exit; + } + + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Launching process with command line %s", strModifiableCommandLine.QueryStr()); + + status = CreateProcessW(NULL, + strModifiableCommandLine.QueryStr(), // command line + NULL, // security info + NULL, // thread info + TRUE, // inherit handles + GetPriorityClass(GetCurrentProcess()), // creation flags + NULL, // environment + NULL, // cur dir + &oStartInfo, + &oProcInfo); + + if ( 0 == status ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error creating process, hr=0x%x", hr); + goto exit; + } + + status = WaitForSingleObject( oProcInfo.hProcess, dwTimeout ); + if ( status == WAIT_FAILED ) + { + IISLogWrite(SETUP_LOG_SEVERITY_WARNING, L"Process wait failed, hr=0x%x", HRESULT_FROM_WIN32 ( GetLastError() ) ); + // but we can still continue + } + + status = GetExitCodeProcess ( oProcInfo.hProcess, &dwExitCode ); + if ( 0 == status ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting exit code for process, hr=0x%x", hr); + goto exit; + } + + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Process returned with exit code %d", dwExitCode); + *pExitCode = dwExitCode; + +exit: + if ( INVALID_HANDLE_VALUE != oProcInfo.hThread ) + { + CloseHandle ( oProcInfo.hThread ); + oProcInfo.hThread = INVALID_HANDLE_VALUE; + } + + if ( INVALID_HANDLE_VALUE != oProcInfo.hProcess ) + { + CloseHandle ( oProcInfo.hProcess ); + oProcInfo.hProcess = INVALID_HANDLE_VALUE; + } + + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error in function %s, hr=0x%x", UNITEXT(__FUNCTION__), hr); + } + + return hr; +} + + +HRESULT +InstallWindowsHotfixQuietly( + IN PCWSTR szHotFixPath, + __out BOOL * pbRebootRequired +) +{ + HRESULT hr = NOERROR; + UINT status = 0; + STACK_STRU( strCommandLine, MAX_PATH); + DWORD cch = 0; + DWORD exitCode = 0; + + _ASSERTE(szHotFixPath); + _ASSERTE(pbRebootRequired); + + *pbRebootRequired = FALSE; + cch = strCommandLine.QuerySizeCCH(); + + status = GetSystemDirectoryW(strCommandLine.QueryStr(), cch); + if ( status > cch) + { + cch = status; + hr = strCommandLine.Resize( ++cch ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error resizing buffer, hr=0x%x", hr); + goto exit; + } + + status = GetSystemDirectoryW(strCommandLine.QueryStr(), cch); + } + + if ( 0 == status ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting system folder path, hr=0x%x", hr); + goto exit; + } + + strCommandLine.SyncWithBuffer(); + + hr = strCommandLine.Append(L"\\wusa.exe /quiet /norestart \""); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error apppending wusa, hr=0x%x", hr); + goto exit; + } + + hr = strCommandLine.Append(szHotFixPath); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error apppending hotfixpath, hr=0x%x", hr); + goto exit; + } + + hr = strCommandLine.Append(L"\""); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error apppending end quote, hr=0x%x", hr); + goto exit; + } + + hr = ExecuteCommandLine ( strCommandLine.QueryStr(), INFINITE, &exitCode); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error running the hotfix installer, hr=0x%x", hr); + goto exit; + } + + // + // handle return codes based on WinSE team info regarding WUSA.exe + // + switch ( exitCode ) + { + case ERROR_SUCCESS: + // install succeeded, continue. + hr = S_OK; + break; + case ERROR_SUCCESS_REBOOT_INITIATED: + case ERROR_SUCCESS_REBOOT_REQUIRED: + case WU_S_REBOOT_REQUIRED: + *pbRebootRequired = TRUE; + hr = S_OK; + break; + case WU_S_ALREADY_INSTALLED: + // WUSA.exe can return the above codes if this DWORD registry value is set: + // HKLM\Software\Microsoft\Windows\CurrentVersion\WUSA\ExtendedReturnCode + hr = S_OK; + break; + case S_FALSE: + // WUSA.exe returns this when the MSU is already installed, or when its not applicable, continue. + hr = S_OK; + break; + + // + // need cases to handle new WU_S_ALREADY_INSTALLED and WU_E_NOT_APPLICABLE error codes + // + + default: + // the installation failed, abort + hr = HRESULT_FROM_WIN32 ( ERROR_INSTALL_FAILURE ); + goto exit; + } + +exit: + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error in function %s, hr=0x%x", UNITEXT(__FUNCTION__), hr); + } + + return hr; +} +UINT +__stdcall +ExecuteCleanUpWindowsHotfixCA( + IN MSIHANDLE hInstall +) +{ + HRESULT hr = NOERROR; + UINT status = 0; + CA_DATA_READER cadata; + WCHAR * szHotFixName = NULL; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + hr = cadata.LoadDeferredCAData( hInstall ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error retrieving custom action data, hr=0x%x", hr); + goto exit; + } + + while ( SUCCEEDED(hr = cadata.Read( &szHotFixName )) ) + { + status = 0; + status = DeleteFileW( szHotFixName ); + + if( FAILED(status) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error deleting hotfix temp file '%s', hr=0x%x", szHotFixName, hr); + //eat this error and try and delete other temp files + hr = NOERROR; + } + else + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Success deleting hotfix temp file '%s'", szHotFixName ); + } + } + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error in function %s, hr=0x%x", UNITEXT(__FUNCTION__), hr); + } + + IISLogClose(); + //do not fail commit or rollback transaction for this + return ERROR_SUCCESS; +} + +UINT +__stdcall +ScheduleInstallWindowsHotfixCA( + IN MSIHANDLE hInstall +) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + OSVERSIONINFOEXW osVersionInfo = {0}; + + PMSIHANDLE hDatabase; + PMSIHANDLE hView; + PMSIHANDLE hRecord; + BOOL bDeferredRequired = FALSE; + + CA_DATA_WRITER cadata; + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISWindowsHotfix`.`Name`, " + L"`IISWindowsHotfix`.`OSMajorVersion`, " + L"`IISWindowsHotfix`.`OSMinorVersion`, " + L"`IISWindowsHotfix`.`SPMajorVersion`, " + L"`IISWindowsHotfix`.`Condition`, " + L"`Binary`.`Data` " + L"FROM `IISWindowsHotfix`, `Binary` " + L"WHERE `IISWindowsHotfix`.`BinaryName_`=`Binary`.`Name`"; + + enum { CA_HOTFIX_NAME = 1, + CA_HOTFIX_OSMAJORVERSION, + CA_HOTFIX_OSMINORVERSION, + CA_HOTFIX_SPMAJORVERSION, + CA_HOTFIX_CONDITION, + CA_HOTFIX_BINARYDATA + }; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + osVersionInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEXW ); +#pragma warning( push ) +#pragma warning( disable : 4996) + status = GetVersionEx( (LPOSVERSIONINFOW) &osVersionInfo ); +#pragma warning( pop ) + + if ( !status ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting Windows version, hr=0x%x", hr); + DBGERROR_HR(hr); + goto exit; + } + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting MSI database, hr=0x%x", hr); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error opening View, hr=0x%x", hr); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error executing view, hr=0x%x", hr); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + UINT dwTargetOSMajorVersion = 0; + UINT dwTargetOSMinorVersion = 0; + UINT dwTargetSPMajorVersion = 0; + STACK_STRU( strHotFixName, 128 ); + BOOL isApplicable = TRUE; // Applicable by default + + hr = MsiUtilRecordGetString( hRecord, + CA_HOTFIX_NAME, + &strHotFixName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting column %d from record, hr=0x%x", CA_HOTFIX_NAME, hr); + goto exit; + } + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Checking applicability of Hotfix '%s'.", + strHotFixName.QueryStr()); + + hr = MsiUtilRecordGetInteger( hRecord, + CA_HOTFIX_OSMAJORVERSION, + &dwTargetOSMajorVersion); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"No OS Major Version available.", CA_HOTFIX_OSMAJORVERSION, hr); + // This column may be NULL + hr = S_FALSE; + } + + hr = MsiUtilRecordGetInteger( hRecord, + CA_HOTFIX_OSMINORVERSION, + &dwTargetOSMinorVersion); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"No OS Minor Version available."); + // This column may be NULL + hr = S_FALSE; + } + + hr = MsiUtilRecordGetInteger( hRecord, + CA_HOTFIX_SPMAJORVERSION, + &dwTargetSPMajorVersion); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"No OS SP Major Version available."); + // This column may be NULL + hr = S_FALSE; + } + + if ( hr == S_FALSE ) + { + // No OS Version information available + hr = S_OK; + } + else + { + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"OS Version: Actual '%d.%d'. Hotfix Target '%d.%d'.", + osVersionInfo.dwMajorVersion, + osVersionInfo.dwMinorVersion, + dwTargetOSMajorVersion, + dwTargetOSMinorVersion); + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"OS Service Pack Level: Actual '%d'. Hotfix Target '%d'.", + osVersionInfo.wServicePackMajor, + dwTargetSPMajorVersion); + + if ( osVersionInfo.dwMajorVersion != dwTargetOSMajorVersion || + osVersionInfo.dwMinorVersion != dwTargetOSMinorVersion) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"OS Version Mismatch! Will not apply the hotfix."); + isApplicable = FALSE; + } + else if(osVersionInfo.wServicePackMajor != dwTargetSPMajorVersion) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"OS SP Level Mismatch! Will not apply the hotfix."); + isApplicable = FALSE; + } + else + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"OS Versions match! Will try to apply the hotfix."); + isApplicable = TRUE; + } + } + + if ( isApplicable ) + { + STACK_STRU( strCondition, 128 ); + MSICONDITION Condition; + + hr = MsiUtilRecordGetString( hRecord, + CA_HOTFIX_CONDITION, + &strCondition ); + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"Error gettting column %d from record, hr=0x%x", + CA_HOTFIX_CONDITION, + hr); + goto exit; + } + + Condition = MsiEvaluateCondition( hInstall, strCondition.QueryStr() ); + + switch( Condition ) + { + case MSICONDITION_ERROR: + hr = E_UNEXPECTED; + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"Cannot evaluate hotfix install condition \"%s\", hr=0x%x", + strCondition.QueryStr(), + hr ); + goto exit; + + case MSICONDITION_FALSE: + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Condition evaluation returned false! Will not apply the hotfix."); + isApplicable = FALSE; + break; + + case MSICONDITION_TRUE: + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Condition evaluation returned true! Will try to apply the hotfix."); + isApplicable = TRUE; + break; + + case MSICONDITION_NONE: + + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"No condition available to evaluate."); + + break; + } + } + + if ( isApplicable ) + { + //apply the hotfix + STACK_STRU( hotFixFilePath, MAX_PATH * 2 ); + + hr = GenerateTempFileName ( strHotFixName.QueryStr(), + L"msu", + &hotFixFilePath); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error generating temp file name for the hotfix, hr=0x%x", hr); + goto exit; + } + + hr = MsiUtilRecordReadStreamIntoFile ( hRecord, + CA_HOTFIX_BINARYDATA, + hotFixFilePath.QueryStr()); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error streaming binary data into file, hr=0x%x", hr); + goto exit; + } + else + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Streamed hotfix '%s' into file '%s'.", strHotFixName.QueryStr(), hotFixFilePath.QueryStr()); + } + + bDeferredRequired = TRUE; + hr = cadata.Write( hotFixFilePath.QueryStr(), hotFixFilePath.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error writing custom action data, hr=0x%x", hr); + goto exit; + } + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + if( bDeferredRequired ) + { + //schedule CA to install the msu files + hr = MsiUtilScheduleDeferredAction( hInstall, + L"ExecuteInstallWindowsHotfix", + cadata.QueryData() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error scheduling custom action ExecuteInstallWindowsHotfix, hr=0x%x", hr); + goto exit; + } + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Custom action ExecuteInstallWindowsHotfix scheduled"); + + + //schedule CA to delete the msu files if rollback transaction initiated + hr = MsiUtilScheduleDeferredAction( hInstall, + L"RollbackCleanUpWindowsHotfix", + cadata.QueryData() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error scheduling custom action RollbackCleanUpWindowsHotfix, hr=0x%x", hr); + goto exit; + } + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Custom action RollbackCleanUpWindowsHotfix scheduled"); + + //schedule CA to delete the msu files if commit transaction initiated + hr = MsiUtilScheduleDeferredAction( hInstall, + L"CommitCleanUpWindowsHotfix", + cadata.QueryData() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error scheduling custom action CommitCleanUpWindowsHotfix, hr=0x%x", hr); + goto exit; + } + + IISLogWrite ( SETUP_LOG_SEVERITY_INFORMATION, + L"Custom action CommitCleanUpWindowsHotfix scheduled"); + + } + +exit: + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error in function %s, hr=0x%x", UNITEXT(__FUNCTION__), hr); + } + + IISLogClose(); + + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; +} + + +UINT +__stdcall +ExecuteInstallWindowsHotfixCA( + IN MSIHANDLE hInstall +) +{ + HRESULT hr = NOERROR; + CA_DATA_READER cadata; + WCHAR * szHotFixName = NULL; + BOOL rebootRequired = FALSE; + HKEY regKey = NULL; + LONG status = ERROR_SUCCESS; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + hr = cadata.LoadDeferredCAData( hInstall ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error retrieving custom action data, hr=0x%x", hr); + goto exit; + } + + while ( SUCCEEDED(hr = cadata.Read( &szHotFixName )) ) + { + BOOL requiresReboot = FALSE; + hr = InstallWindowsHotfixQuietly ( szHotFixName , &requiresReboot ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error installing hotfix '%s', hr=0x%x", szHotFixName, hr); + goto exit; + } + if ( requiresReboot ) + { + rebootRequired = TRUE; + } + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + + if ( rebootRequired ) + { + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + REBOOT_REQUIRED_REGKEY, + 0, + KEY_SET_VALUE, + ®Key); + if(status != ERROR_SUCCESS) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error opening the reboot registry key, hr=0x%x", hr); + goto exit; + } + + status = RegSetValueEx(regKey, + REBOOT_REGVALUE, + 0, + REG_SZ, + (PBYTE)L"", + 4); + if(status != ERROR_SUCCESS) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error creating the reboot registry value, hr=0x%x", hr); + goto exit; + } + + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Created a registry key to signal reboot is required"); + } + +exit: + if(regKey != NULL) + { + RegCloseKey(regKey); + regKey = NULL; + } + + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error in function %s, hr=0x%x", UNITEXT(__FUNCTION__), hr); + } + + IISLogClose(); + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; +} + +UINT +__stdcall +ScheduleRebootIfRequiredCA( + IN MSIHANDLE hInstall +) +{ + HRESULT hr = NOERROR; + HKEY regKey = NULL; + LONG status = ERROR_SUCCESS; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + REBOOT_REQUIRED_REGKEY, + 0, + KEY_QUERY_VALUE, + ®Key); + if(status != ERROR_SUCCESS) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error opening the reboot registry key, hr=0x%x", hr); + goto exit; + } + + status = RegQueryValueEx(regKey, + REBOOT_REGVALUE, + 0, + NULL, + NULL, + NULL); + switch(status) + { + case ERROR_SUCCESS: + status = MsiSetMode(hInstall, + MSIRUNMODE_REBOOTATEND, + TRUE); + if( status != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error setting reboot required for the installation, hr=0x%x", hr); + goto exit; + } + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Signalled the installer to reboot at the end of the installation."); + break; + + case ERROR_FILE_NOT_FOUND: + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"No reboot is required by the IIS custom actions."); + hr = S_OK; + break; + + default: + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting the IIS registry key reboot value, hr=0x%x", hr); + goto exit; + } + +exit: + if(regKey != NULL) + { + RegCloseKey(regKey); + regKey = NULL; + } + + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error in function %s, hr=0x%x", UNITEXT(__FUNCTION__), hr); + } + + IISLogClose(); + + //dont report an error here. the install has completed so its too late to report a failure + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_SUCCESS; + +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/httpapi.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/httpapi.cpp new file mode 100644 index 0000000000..c3b5d059ba --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/httpapi.cpp @@ -0,0 +1,518 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + + +HRESULT GetSidStringForAccount( + const WCHAR * szAccount, + __inout STRU * pstr + ) +{ + HRESULT hr = NOERROR; + BOOL success = TRUE; + DWORD sidSize = 0; + DWORD domainSize = 0; + PSID psid = NULL; + SID_NAME_USE sidKind; + LPWSTR pszSid = NULL; + LPWSTR pszDomain = NULL; + + LookupAccountNameW(NULL, + szAccount, + NULL, + &sidSize, + NULL, + &domainSize, + &sidKind); + + _ASSERT ( sidSize > 0 ); + + psid = new BYTE[sidSize]; + if( psid == NULL ) + { + hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY ); + DBGERROR_HR(hr); + goto exit; + } + + pszDomain = new WCHAR[domainSize]; + if( pszDomain == NULL ) + { + hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY ); + DBGERROR_HR(hr); + goto exit; + } + + success = LookupAccountNameW(NULL, + szAccount, + psid, + &sidSize, + pszDomain, + &domainSize, + &sidKind); + if( !success ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto exit; + } + + success = ConvertSidToStringSidW( psid, &pszSid ); + if( !success ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto exit; + } + + _ASSERT(pszSid); + + hr = pstr->Copy(pszSid); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error in function %s, hr=0x%x", UNITEXT(__FUNCTION__), hr); + } + + if (pszSid) + { + LocalFree( pszSid ); + pszSid = NULL; + } + + delete [] psid; + psid = NULL; + delete [] pszDomain; + pszDomain = NULL; + + return hr; +} + +UINT +WINAPI +ScheduleHttpListenerCA( + IN MSIHANDLE hInstall, + IN const WCHAR * pszCAName, + IIS_HTTP_LISTENER_CA_TYPE caType + ) +{ + HRESULT hr = S_OK; + UINT status = ERROR_SUCCESS; + BOOL scheduleDefferedCA = FALSE; + + PMSIHANDLE hDatabase; + PMSIHANDLE hView; + PMSIHANDLE hRecord; + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISHttpListener`.`Name`, " + L"`IISHttpListener`.`Component_`, " + L"`IISHttpListener`.`Account`, " + L"`IISHttpListener`.`Prefix` " + L"FROM `IISHttpListener`"; + + enum { CA_HTTP_NAME = 1, + CA_HTTP_COMPONENT, + CA_HTTP_ACCOUNT, + CA_HTTP_PREFIX}; + + CA_DATA_WRITER cadata; + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + STACK_STRU( strName, 128 ); + STACK_STRU( strComponent, 128 ); + STACK_STRU( strAccount, 128 ); + STACK_STRU( strPrefix, 128 ); + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + BOOL scheduleThisComponent = FALSE; + + hr = MsiUtilRecordGetString( hRecord, + CA_HTTP_NAME, + &strName ); + if ( FAILED( hr ) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_HTTP_COMPONENT, + &strComponent ); + if ( FAILED( hr ) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if (MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + if (caType == IIS_HTTP_LISTENER_CA_INSTALL) + { + scheduleThisComponent = TRUE; + scheduleDefferedCA = TRUE; + } + } + else if (MsiUtilIsUnInstalling( installStateCurrent, installStateAction)) + { + if (caType == IIS_HTTP_LISTENER_CA_UNINSTALL) + { + scheduleThisComponent = TRUE; + scheduleDefferedCA = TRUE; + } + + } + + if (scheduleThisComponent) + { + hr = MsiUtilRecordGetString( hRecord, + CA_HTTP_ACCOUNT, + &strAccount ); + if ( FAILED( hr ) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_HTTP_PREFIX, + &strPrefix ); + if ( FAILED( hr ) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata.Write( strName.QueryStr(), strName.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilFormatString( hInstall, &strAccount); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata.Write( strAccount.QueryStr(), strAccount.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilFormatString( hInstall, &strPrefix); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata.Write( strPrefix.QueryStr(), strPrefix.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + } + + if ( scheduleDefferedCA ) + { + hr = MsiUtilScheduleDeferredAction( hInstall, + pszCAName, + cadata.QueryData() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + +exit: + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error in function %s, hr=0x%x", UNITEXT(__FUNCTION__), hr); + } + + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; +} + +UINT +__stdcall +ExecuteHttpListenerCA( + IN MSIHANDLE hInstall, + IIS_HTTP_LISTENER_CA_TYPE caType + ) +{ + HRESULT hr = NOERROR; + ULONG status = NO_ERROR; + BOOL bHttpInitialized = FALSE; + CA_DATA_READER cadata; + WCHAR * szName = NULL; + WCHAR * szAccount = NULL; + WCHAR * szPrefix = NULL; + HTTPAPI_VERSION httpVersion1 = HTTPAPI_VERSION_1; + + hr = cadata.LoadDeferredCAData( hInstall ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + status = HttpInitialize( httpVersion1, HTTP_INITIALIZE_CONFIG, NULL ); + if ( status != NO_ERROR ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error calling HttpInitialize, hr=0x%x", hr); + goto exit; + } + bHttpInitialized = TRUE; + + while ( SUCCEEDED(hr = cadata.Read( &szName)) ) + { + const WCHAR * securityDescriptorFormat = L"D:(A;;GX;;;%s)"; + HTTP_SERVICE_CONFIG_URLACL_SET inputConfigInfo; + STACK_STRU( strSid, 128 ); + STACK_STRU( strSecurityString, 128 ); + + hr = cadata.Read( &szAccount); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata.Read( &szPrefix); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = GetSidStringForAccount(szAccount, &strSid); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = strSecurityString.SafeSnwprintf(securityDescriptorFormat, strSid.QueryStr()); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + inputConfigInfo.KeyDesc.pUrlPrefix = szPrefix; + inputConfigInfo.ParamDesc.pStringSecurityDescriptor = strSecurityString.QueryStr(); + + status = HttpDeleteServiceConfiguration(NULL, + HttpServiceConfigUrlAclInfo, + &inputConfigInfo, + sizeof(inputConfigInfo), + NULL); + + if (status == E_INVALIDARG) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error calling Http API. Please make sure that the URL and Account information specified is correct."); + } + + if ( (status != NO_ERROR) && (status != ERROR_FILE_NOT_FOUND) ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error calling HttpDeleteServiceConfiguration for account '%s', prefix '%s', securityDescriptor '%s', hr=0x%x", + szAccount, + szPrefix, + strSecurityString.QueryStr(), + hr); + goto exit; + } + + if ( caType == IIS_HTTP_LISTENER_CA_INSTALL) + { + status = HttpSetServiceConfiguration(NULL, + HttpServiceConfigUrlAclInfo, + &inputConfigInfo, + sizeof(inputConfigInfo), + NULL); + if (status == E_INVALIDARG) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error calling Http API. Please make sure that the URL and Account information specified is correct."); + } + if ( status != NO_ERROR ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error calling HttpSetServiceConfiguration for account '%s', prefix '%s', securityDescriptor '%s', hr=0x%x", + szAccount, + szPrefix, + strSecurityString.QueryStr(), + hr); + goto exit; + } + } + } + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + if (bHttpInitialized) + { + HttpTerminate ( HTTP_INITIALIZE_CONFIG , NULL); + } + + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error in function %s, hr=0x%x", UNITEXT(__FUNCTION__), hr); + } + + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; +} + + //for(inputConfigInfo.dwToken = 0; /* condition inside */ ; inputConfigInfo.dwToken++) + //{ + // HTTP_SERVICE_CONFIG_URLACL_SET * pOutputConfigInfo = NULL; + // ULONG outputConfigInfoSize = 0; + + // while (status == ERROR_INSUFFICIENT_BUFFER) + // { + // delete pOutputConfigInfo; + // pOutputConfigInfo = NULL; + // pOutputConfigInfo = new BYTE[outputConfigInfoSize]; + // if (pOutputConfigInfo == NULL) + // { + // hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY ); + // DBGERROR_HR(hr); + // goto exit; + // } + + // status = HttpQueryServiceConfiguration ( NULL, + // HttpServiceConfigUrlAclInfo, + // &inputConfigInfo, + // sizeof(inputConfigInfo), + // pOutputConfigInfo, + // outputConfigInfoSize, + // &outputConfigInfoSize, + // NULL); + // } //end while + + // _ASSERT (status != ERROR_INSUFFICIENT_BUFFER) + // + // if (status == NO_ERROR) + // { + // //lookup output info + + // } + // else if (status == ERROR_NO_MORE_ITEMS) + // { + // //we're done + // break; + // } + // else + // { + // hr = HRESULT_FROM_WIN32( status ); + // DBGERROR_HR(hr); + // IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error calling HttpQueryServiceConfiguration, hr=0x%x", hr); + // goto exit; + // } + //} //end for + +UINT +WINAPI +ScheduleInstallHttpListenerCA( + IN MSIHANDLE hInstall + ) +{ + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + UINT retVal = ScheduleHttpListenerCA(hInstall, L"ExecuteInstallHttpListener", IIS_HTTP_LISTENER_CA_INSTALL); + IISLogClose(); + return retVal; +} + +UINT +WINAPI +ScheduleUnInstallHttpListenerCA( + IN MSIHANDLE hInstall + ) +{ + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + UINT retVal = ScheduleHttpListenerCA(hInstall, L"ExecuteUnInstallHttpListener", IIS_HTTP_LISTENER_CA_UNINSTALL); + IISLogClose(); + return retVal; +} +UINT +__stdcall +ExecuteInstallHttpListenerCA( + IN MSIHANDLE hInstall + ) +{ + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + UINT retVal = ExecuteHttpListenerCA(hInstall, IIS_HTTP_LISTENER_CA_INSTALL); + IISLogClose(); + return retVal; +} + +UINT +__stdcall +ExecuteUnInstallHttpListenerCA( + IN MSIHANDLE hInstall + ) +{ + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + UINT retVal = ExecuteHttpListenerCA(hInstall, IIS_HTTP_LISTENER_CA_UNINSTALL); + IISLogClose(); + return retVal; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/httpapi.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/httpapi.h new file mode 100644 index 0000000000..1783e4ddf8 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/httpapi.h @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + + +enum IIS_HTTP_LISTENER_CA_TYPE +{ + IIS_HTTP_LISTENER_CA_INSTALL, + IIS_HTTP_LISTENER_CA_UNINSTALL +}; + +HRESULT GetSidStringForAccount( + const WCHAR * szAccount, + __inout STRU * pstr + ); + +UINT +WINAPI +ScheduleHttpListenerCA( + IN MSIHANDLE hInstall, + IN const WCHAR * pszCAName, + IIS_HTTP_LISTENER_CA_TYPE caType + ); + +UINT +__stdcall +ExecuteHttpListenerCA( + IN MSIHANDLE hInstall, + IIS_HTTP_LISTENER_CA_TYPE caType + ); + +UINT +WINAPI +ScheduleInstallHttpListenerCA( + IN MSIHANDLE hInstall + ); + +UINT +__stdcall +ExecuteInstallHttpListenerCA( + IN MSIHANDLE hInstall + ); + +UINT +WINAPI +ScheduleUnInstallHttpListenerCA( + IN MSIHANDLE hInstall + ); + +UINT +__stdcall +ExecuteUnInstallHttpListenerCA( + IN MSIHANDLE hInstall + ); \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iisca.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iisca.cpp new file mode 100644 index 0000000000..06631ce964 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iisca.cpp @@ -0,0 +1,4302 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +#define ROOT_CONFIG_PATH L"MACHINE/WEBROOT/APPHOST" + +#define MAX_NAME 256 +#define _UNITEXT(quote) L##quote +#define UNITEXT(quote) _UNITEXT(quote) + +HRESULT +GetFullTypeFromAssemblyTable( + IN MSIHANDLE hDatabase, + IN CONST WCHAR * szComponent, + IN CONST WCHAR * szTypeName, + IN OUT STRU * pstrFullType + ); + +BOOL IsSectionInAdminConfig( + IN CONST WCHAR * szIsInAdminConfig + ) +{ + if( 0 == _wcsicmp(szIsInAdminConfig, L"yes") ) + { + return TRUE; + } + else + { + return FALSE; + } +} + +HRESULT +ScheduleInstallModuleCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + // + // If the module being installed includes the optional TypeName, + // then the we'll test the component to insure that the module + // is a .Net module. If so, then we will not install the module + // in and we'll include the TypeName and strong + // name info when we install in the . + // + + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + STACK_STRU( strTemp, 128 ); + STACK_STRU( strComponent, 128 ); + STACK_STRU( strTypeName, 128 ); + STACK_STRU( strFullType, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISGlobalModule`.`Name`, " + L"`IISGlobalModule`.`File_`, " + L"`IISGlobalModule`.`PreCondition`, " + L"`File`.`Component_`, " + L"`IISGlobalModule`.`TypeName` " + L"FROM `IISGlobalModule`, `File` " + L"WHERE `File`.`File`=`IISGlobalModule`.`File_`"; + + enum { CA_MODULE_NAME = 1, + CA_MODULE_IMAGE, + CA_MODULE_PRECONDITION, + CA_MODULE_COMPONENT, + CA_MODULE_TYPENAME }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + // does table exists + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISGlobalModule"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_MODULE_COMPONENT, + &strComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + + cadata->Write( IIS_INSTALL_MODULE ); + + // Get the module name + hr = MsiUtilRecordGetString( hRecord, + CA_MODULE_NAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // CA_MODULE_IMAGE is the name of the File element, need to + // resolve it to the full path by formatting it as [#ModuleDll] + // + + hr = MsiUtilRecordGetString( hRecord, + CA_MODULE_IMAGE, + &strTemp ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = strData.SafeSnwprintf( L"[#%s]", strTemp.QueryStr() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilFormatString( hInstall, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_MODULE_PRECONDITION, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Get the type name (optional) + // If the type name is present, then this is a .Net and does not have + // to be registered in the + // + hr = MsiUtilRecordGetString( hRecord, + CA_MODULE_TYPENAME, + &strTypeName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( strTypeName.QueryCCH() > 0 ) + { + // TypeName is present. Get the assembly info + hr = GetFullTypeFromAssemblyTable( hDatabase, + strComponent.QueryStr(), + strTypeName.QueryStr(), + &strFullType ); + + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + else + { + strFullType.Reset(); + } + + hr = cadata->Write( strFullType.QueryStr(), strFullType.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + + +HRESULT +ScheduleUnInstallModuleCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISGlobalModule`.`Name`, " + L"`File`.`Component_`, " + L"`IISGlobalModule`.`TypeName` " + L"FROM `IISGlobalModule`, `File` " + L"WHERE `File`.`File`=`IISGlobalModule`.`File_`"; + + enum { CA_MODULE_NAME = 1, + CA_MODULE_COMPONENT, + CA_MODULE_TYPENAME }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + //Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISGlobalModule"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_MODULE_COMPONENT, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strData.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsUnInstalling( installStateCurrent, installStateAction ) ) + { + + cadata->Write( IIS_UNINSTALL_MODULE ); + + + hr = MsiUtilRecordGetString( hRecord, + CA_MODULE_NAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_MODULE_TYPENAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + + +HRESULT +ExecuteInstallModuleCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szName = NULL; + WCHAR * szImage = NULL; + WCHAR * szPreCondition = NULL; + WCHAR * szType = NULL; + + + hr = cadata->Read( &szName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szImage ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szPreCondition ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szType ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Install the module + // + + hr = InstallModule( szName, + szImage, + szPreCondition, + szType ); + + if ( hr == HRESULT_FROM_WIN32( ERROR_ALREADY_EXISTS ) ) + { + // + // We'll quietly accept a module already exists. + // This will happen if a component has multiple features + // that each have a module. + // If a feature is omitted on the initial install, + // and added later using Change, the features that + // were initially installed will show up in the + // ScheduleInstallModuleCA with install + // INSTALLSTATE_UNKNOWN, which will trigger a reinstall. + // Reinstall will result in ERROR_ALREADY_EXISTS. + // + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, + L"Module: '%s' already installed.", + szName); + + hr = S_OK; + } + + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + + +HRESULT +ExecuteUnInstallModuleCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szName = NULL; + WCHAR * szType = NULL; + + + + hr = cadata->Read( &szName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szType ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = UnInstallModule( szName, szType ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + + +HRESULT +ScheduleRegisterSectionSchemaCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISConfigSections`.`Name`, " + L"`IISConfigSections`.`File_`, " + L"`IISConfigSections`.`OverrideModeDefault`, " + L"`IISConfigSections`.`AllowDefinition`, " + L"`IISConfigSections`.`Type`, " + L"`IISConfigSections`.`InAdminConfig`, " + L"`File`.`Component_` " + L"FROM `IISConfigSections`, `File` " + L"WHERE `File`.`File`=`IISConfigSections`.`File_`"; + + enum + { + CA_SECTION_NAME = 1, + CA_SCHEMA_FILE, + CA_SECTION_OVERRIDEMODE, + CA_SECTION_ALLOWDEF, + CA_SECTION_TYPE, + CA_SECTION_INADMINCONFIG, + CA_SCHEMA_COMPONENT + }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + //Does table exists + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISConfigSections"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_SCHEMA_COMPONENT, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strData.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + + cadata->Write( IIS_INSTALL_SECTIONSCHEMA ); + + hr = MsiUtilRecordGetString( hRecord, + CA_SECTION_NAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_SECTION_OVERRIDEMODE, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_SECTION_ALLOWDEF, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_SECTION_TYPE, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_SECTION_INADMINCONFIG, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; +} + + +HRESULT +ScheduleUnRegisterSectionSchemaCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISConfigSections`.`Name`, " + L"`IISConfigSections`.`InAdminConfig`, " + L"`File`.`Component_` " + L"FROM `IISConfigSections`, `File` " + L"WHERE `File`.`File`=`IISConfigSections`.`File_`"; + + enum { + CA_SECTION_NAME = 1, + CA_SECTION_INADMINCONFIG, + CA_SCHEMA_COMPONENT }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + //Does table exists + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISConfigSections"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_SCHEMA_COMPONENT, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strData.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsUnInstalling( installStateCurrent, installStateAction ) ) + { + cadata->Write( IIS_UNINSTALL_SECTIONSCHEMA ); + + hr = MsiUtilRecordGetString( hRecord, + CA_SECTION_NAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_SECTION_INADMINCONFIG, + &strData ); + + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + + +HRESULT +ExecuteRegisterSectionSchemaCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szSectionName = NULL; + WCHAR * szOverrideMode = NULL; + WCHAR * szAllowDefinition = NULL; + WCHAR * szType = NULL; + WCHAR * szIsInAdminConfig = NULL; + + + // + // Retrieve parameters from ca data + // + hr = cadata->Read( &szSectionName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szOverrideMode ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szAllowDefinition ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szType ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szIsInAdminConfig ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Register the section + // + + hr = RegisterSectionSchema( IsSectionInAdminConfig(szIsInAdminConfig), + szSectionName, + szOverrideMode, + szAllowDefinition, + szType ); + + if ( hr == HRESULT_FROM_WIN32( ERROR_ALREADY_EXISTS ) ) + { + // + // We'll quietly accept a section name already exists. + // This will happen if a package has multiple features + // that each have a section. + // If a feature is omitted on the initial install, + // and added later using Change, the features that + // were initially installed will show up in the + // ScheduleRegisterSectionSchemaCA with install + // INSTALLSTATE_UNKNOWN, which will trigger a reinstall. + // Reinstall will result in ERROR_ALREADY_EXISTS. + // + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, + L"Section name: '%s' already exists.", + szSectionName); + + hr = S_OK; + } + + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; +} + + +HRESULT +ExecuteUnRegisterSectionSchemaCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szSectionName = NULL; + WCHAR * szIsInAdminConfig = NULL; + + + hr = cadata->Read( &szSectionName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szIsInAdminConfig ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = UnRegisterSectionSchema( IsSectionInAdminConfig(szIsInAdminConfig), + szSectionName ); + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"Failed to unregister section schema for section: '%s', hr=0x%x .", + szSectionName, + hr ); + DBGERROR_HR(hr); + + // + // We need to keep going because this is an uninstall action + // and should be resilient to missing elements. + // + hr = S_OK; + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; +} + +HRESULT +CanonicalizeAssemblyVersion( + STRU & strValue +) +{ + // + // Converts 7.1.2.000 to 7.1.2.0 + // + + HRESULT hr = S_OK; + LPCWSTR psz = wcschr( strValue.QueryStr(), L'.' ); + DWORD dwDotCount = 0; + + // + // Find the 3rd '.' + // + while ( psz != NULL ) + { + dwDotCount++; + LPCWSTR psz2 = wcschr( psz + 1, L'.' ); + if ( psz2 == NULL ) + { + break; + } + psz = psz2; + } + + if ( dwDotCount == 3 && psz != NULL ) + { + // + // Convert "000" to integer and then back to string. + // + + psz ++; + DWORD dw = _wtoi( psz ); + STACK_STRU( strTemp, 16 ); + + hr = strTemp.SafeSnwprintf( L"%u", dw ); + if ( SUCCEEDED( hr ) ) + { + ptrdiff_t diff = psz - strValue.QueryStr(); + + _ASSERTE( diff >= 0 ); + + hr = strValue.SetLen( (DWORD) diff ); + if ( FAILED( hr ) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = strValue.Append(strTemp); + if ( FAILED( hr ) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + } + +exit: + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + +HRESULT +GetFullTypeFromAssemblyTable( + IN MSIHANDLE hDatabase, + IN CONST WCHAR * szComponent, + IN CONST WCHAR * szTypeName, + IN OUT STRU * pstrFullType + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + BOOL fRecordFound = FALSE; + BOOL fVersion = FALSE; + + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strQuery, 128 ); + STACK_STRU( strPropName, 64 ); + STACK_STRU( strPropValueName, 64 ); + STACK_STRU( strPropVersion, 64 ); + STACK_STRU( strPropCulture, 64 ); + STACK_STRU( strPropKeyToken, 64 ); + + CONST WCHAR * szQueryTemplate = + L"SELECT `Name`, `Value` " + L"FROM `MsiAssemblyName` " + L"WHERE `Component_`='%s'"; + + CONST WCHAR * szFullTypeTempl = L"%s, %s, Version=%s, Culture=%s, PublicKeyToken=%s"; + // szTypeName, name, version, culture, publicKeyToken + + enum { CA_ASSEMBLY_PROP_NAME = 1, CA_ASSEMBLY_PROP_VALUE }; + + hr = strQuery.SafeSnwprintf( szQueryTemplate, szComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, strQuery.QueryStr(), &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + STRU * pstr; + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + fRecordFound = TRUE; + hr = MsiUtilRecordGetString( hRecord, + CA_ASSEMBLY_PROP_NAME, + &strPropName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + pstr = NULL; + + if ( 0 == wcscmp( strPropName.QueryStr(), L"name" ) ) + { + pstr = &strPropValueName; + } + else if ( 0 == wcscmp( strPropName.QueryStr(), L"version" ) ) + { + fVersion = TRUE; + pstr = &strPropVersion; + } + else if ( 0 == wcscmp( strPropName.QueryStr(), L"culture" ) ) + { + pstr = &strPropCulture; + } + else if ( 0 == wcscmp( strPropName.QueryStr(), L"publicKeyToken" ) ) + { + pstr = &strPropKeyToken; + } + + if ( pstr ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_ASSEMBLY_PROP_VALUE, + pstr ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( fVersion ) + { + hr = CanonicalizeAssemblyVersion( *pstr ); + if ( FAILED( hr ) ) + { + DBGERROR_HR(hr); + goto exit; + } + fVersion = FALSE; + } + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + hr = pstrFullType->SafeSnwprintf( szFullTypeTempl, + szTypeName, + strPropValueName.QueryStr(), + strPropVersion.QueryStr(), + strPropCulture.QueryStr(), + strPropKeyToken.QueryStr() + ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + _ASSERTE( fRecordFound ); + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + + +HRESULT +ScheduleRegisterUIModuleCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strComponent, 128 ); + STACK_STRU( strAssemblyInfoComponent, 128 ); + STACK_STRU( strData, 128 ); + STACK_STRU( strFullType, 128 ); + + const STRU * pstrComponentName = NULL; + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISUIModule`.`Name`, " + L"`IISUIModule`.`TypeName`, " + L"`IISUIModule`.`Component_` ," + L"`IISUIModule`.`AssemblyInfoComponent_` ," + L"`IISUIModule`.`RegisterInModulesSection` ," + L"`IISUIModule`.`PrependToList` " + L"FROM `IISUIModule` "; + + enum { + CA_UIMODULE_NAME = 1, + CA_UIMODULE_TYPE, + CA_UIMODULE_COMPONENT, + CA_UIMODULE_ASSEMBLYINFOCOMPONENT, + CA_UIMODULE_REGISTER, + CA_UIMODULE_PREPEND + }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + //Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISUIModule"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_UIMODULE_COMPONENT, + &strComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + + cadata->Write( IIS_INSTALL_UIMODULE ); + + hr = MsiUtilRecordGetString( hRecord, + CA_UIMODULE_NAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_UIMODULE_ASSEMBLYINFOCOMPONENT, + &strAssemblyInfoComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // use the AssemblyInfoComponent_ to get the module assembly information + // fall back to using the component if the value is null. + if ( strAssemblyInfoComponent.QueryCCH() > 0 ) + { + pstrComponentName = &strAssemblyInfoComponent; + } + else + { + pstrComponentName = &strComponent; + } + _ASSERTE( pstrComponentName != NULL ); + + hr = MsiUtilRecordGetString( hRecord, + CA_UIMODULE_TYPE, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = GetFullTypeFromAssemblyTable( hDatabase, + pstrComponentName->QueryStr(), + strData.QueryStr(), + &strFullType ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strFullType.QueryStr(), strFullType.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_UIMODULE_REGISTER, + &strData ); + if (FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_UIMODULE_PREPEND, + &strData ); + if (FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; +} + + +HRESULT +ScheduleUnRegisterUIModuleCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strComponent, 128 ); + STACK_STRU( strAssemblyInfoComponent, 128 ); + STACK_STRU( strData, 128 ); + STACK_STRU( strFullType, 128 ); + + const STRU * pstrComponentName = NULL; + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISUIModule`.`Name`, " + L"`IISUIModule`.`TypeName`, " + L"`IISUIModule`.`Component_` ," + L"`IISUIModule`.`AssemblyInfoComponent_` " + L"FROM `IISUIModule` "; + + enum { + CA_UIMODULE_NAME = 1, + CA_UIMODULE_TYPE, + CA_UIMODULE_COMPONENT, + CA_UIMODULE_ASSEMBLYINFOCOMPONENT, + }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + //Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISUIModule"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_UIMODULE_COMPONENT, + &strComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsUnInstalling( installStateCurrent, installStateAction ) ) + { + + cadata->Write( IIS_UNINSTALL_UIMODULE ); + + hr = MsiUtilRecordGetString( hRecord, + CA_UIMODULE_NAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordGetString( hRecord, + CA_UIMODULE_ASSEMBLYINFOCOMPONENT, + &strAssemblyInfoComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // use the AssemblyInfoComponent_ to get the module assembly information + // fall back to using the component if the value is null. + if ( strAssemblyInfoComponent.QueryCCH() > 0 ) + { + pstrComponentName = &strAssemblyInfoComponent; + } + else + { + pstrComponentName = &strComponent; + } + _ASSERTE( pstrComponentName != NULL ); + + hr = MsiUtilRecordGetString( hRecord, + CA_UIMODULE_TYPE, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = GetFullTypeFromAssemblyTable( hDatabase, + pstrComponentName->QueryStr(), + strData.QueryStr(), + &strFullType ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strFullType.QueryStr(), strFullType.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; +} + + +HRESULT +ExecuteRegisterUIModuleCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szUIModuleName = NULL; + WCHAR * szUIModuleTypeInfo = NULL; + WCHAR * szUIModuleRegister = NULL; + WCHAR * szUIModulePrepend = NULL; + + hr = cadata->Read( &szUIModuleName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szUIModuleTypeInfo ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szUIModuleRegister ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szUIModulePrepend ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Register the section + // + + hr = RegisterUIModule( szUIModuleName, + szUIModuleTypeInfo, + szUIModuleRegister, + szUIModulePrepend ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + + +HRESULT +ExecuteUnRegisterUIModuleCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szUIModuleName = NULL; + WCHAR * szUIModuleTypeInfo = NULL; + + hr = cadata->Read( &szUIModuleName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szUIModuleTypeInfo ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = UnRegisterUIModule( szUIModuleName, szUIModuleTypeInfo ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + +HRESULT +ScheduleRegisterTraceAreaCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + STACK_STRU( strComponent, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISTraceArea`.`Component_`, " + L"`IISTraceArea`.`ProviderName`, " + L"`IISTraceArea`.`ProviderGuid`, " + L"`IISTraceArea`.`AreaName`, " + L"`IISTraceArea`.`AreaValue` " + L"FROM `IISTraceArea` "; + + enum { CA_COMPONENT = 1, + CA_PROVIDER_NAME, + CA_PROVIDER_GUID, + CA_AREA_NAME, + CA_AREA_VALUE }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + //Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISTraceArea"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_COMPONENT, + &strComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + cadata->Write( IIS_INSTALL_TRACEAREA ); + + // Get the values + for ( DWORD Index = CA_PROVIDER_NAME; Index <= CA_AREA_VALUE; Index++ ) + { + hr = MsiUtilRecordGetString( hRecord, + Index, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + + +HRESULT +ExecuteRegisterTraceAreaCA( + IN CA_DATA_READER * cadata +) +{ + HRESULT hr = NOERROR; + + WCHAR * szTraceProviderName = NULL; + WCHAR * szTraceProviderGuid = NULL; + WCHAR * szAreaName = NULL; + WCHAR * szAreaValue = NULL; + + + hr = cadata->Read( &szTraceProviderName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szTraceProviderGuid ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szAreaName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szAreaValue ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Register the section + // + hr = RegisterTraceArea( szTraceProviderName, + szTraceProviderGuid, + szAreaName, + szAreaValue ); + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"Failed to register trace area (Provider: '%s'; " + L"Guid: '%s'; AreaName: '%s'; AreaValue: '%s') hr=0x%x", + szTraceProviderName, + szTraceProviderGuid, + szAreaName, + szAreaValue, + hr ); + DBGERROR_HR(hr); + goto exit; + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_SUCCESS; +} + +/// The error messages are from setstrings.wxl. +/// The integer parameter is used to to get the string. +UINT +LogMsiCustomActionError( + IN MSIHANDLE hInstall, + UINT messageId + ) +{ + PMSIHANDLE pLogger = MsiCreateRecord(1); + if ( pLogger == NULL ) + { + return ERROR_INSTALL_FAILURE; + } + + MsiRecordSetInteger( pLogger, 1, messageId ); + MsiProcessMessage( hInstall, INSTALLMESSAGE_ERROR, pLogger ); + + if ( pLogger != NULL ) + { + MsiCloseHandle( pLogger ); + pLogger = NULL; + } + + return ERROR_INSTALL_FAILURE; +} + + +HRESULT +ScheduleRegisterMofFileCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISTraceArea`.`BinaryName_`, " + L"`Binary`.`Data`, " + L"`IISTraceArea`.`Component_` " + L"FROM `IISTraceArea`, `Binary` " + L"WHERE `Binary`.`Name`=`IISTraceArea`.`BinaryName_`"; + + enum { CA_BINARY_NAME = 1, + CA_FILE_DATA, + CA_MOF_COMPONENT }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + + // + //Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISTraceArea"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_MOF_COMPONENT, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strData.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + + cadata->Write( IIS_INSTALL_MOFFILE ); + + STACK_STRU( strBinaryName, 128 ); + STACK_STRU( strMofFilePath, MAX_PATH ); + + hr = MsiUtilRecordGetString( hRecord, + CA_BINARY_NAME, + &strBinaryName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = GenerateTempFileName( strBinaryName.QueryStr(), + L"mof", + &strMofFilePath); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = MsiUtilRecordReadStreamIntoFile( hRecord, + CA_FILE_DATA, + strMofFilePath.QueryStr()); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strMofFilePath.QueryStr(), strMofFilePath.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + } + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + +HRESULT +ExecuteRegisterMofFileCA( + IN CA_DATA_READER * cadata +) +{ + HRESULT hr = NOERROR; + + WCHAR * szMofFileName = NULL; + + hr = cadata->Read( &szMofFileName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + // Register the section + // + hr = RegisterMofFile( szMofFileName ); + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"Failed to register MOF file (File name: '%s') hr=0x%x", + szMofFileName, + hr ); + DBGERROR_HR(hr); + + // + // Continue setup, this is not a fatal error. + // + hr = S_OK; + + goto exit; + } + else + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, + L"MOF file '%s' registered.", + szMofFileName ); + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; +} + +HRESULT +ScheduleInstallHandlerCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + STACK_STRU( strComponent, 128 ); + + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISGlobalHandler`.`Name`, " + L"`IISGlobalHandler`.`Component_`, " + L"`IISGlobalHandler`.`Path`, " + L"`IISGlobalHandler`.`Verb`, " + L"`IISGlobalHandler`.`Type`, " + L"`IISGlobalHandler`.`Index`, " + L"`IISGlobalHandler`.`Modules`, " + L"`IISGlobalHandler`.`ScriptProcessor`, " + L"`IISGlobalHandler`.`ResourceType`, " + L"`IISGlobalHandler`.`RequiredAccess`, " + L"`IISGlobalHandler`.`PreCondition` " + L"FROM `IISGlobalHandler` "; + + enum { CA_HANDLER_NAME = 1, + CA_HANDLER_COMPONENT, + CA_HANDLER_PATH, + CA_HANDLER_VERB, + CA_HANDLER_TYPE, + CA_HANDLER_INDEX, + CA_HANDLER_MODULES, + CA_HANDLER_SCRIPTPROCESSOR, + CA_HANDLER_RESOURCETYPE, + CA_HANDLER_REQUIREDACCESS, + CA_HANDLER_PRECONDITION + }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + + // + //Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISGlobalHandler"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_COMPONENT, + &strComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + + cadata->Write( IIS_INSTALL_HANDLER ); + + // Get the Handler name + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_NAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Get handler Path + // + + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_PATH, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + //Get handler Verb + // + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_VERB, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + // Get handler Type + // + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_TYPE, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + // Get handler Index + // + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_INDEX, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + // Get handler Modules + // + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_MODULES, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + // Get handler Script Processor + // + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_SCRIPTPROCESSOR, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + // Get handler ResourceType + // + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_RESOURCETYPE, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + // Get handler RequiredAccess + // + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_REQUIREDACCESS, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + // Get handler PreCondition + // + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_PRECONDITION, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + + +HRESULT +ScheduleUnInstallHandlerCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISGlobalHandler`.`Name`, " + L"`IISGlobalHandler`.`Component_` " + L"FROM `IISGlobalHandler` "; + + enum { CA_HANDLER_NAME = 1, + CA_HANDLER_COMPONENT + }; + + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + //Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISGlobalHandler"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_COMPONENT, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strData.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsUnInstalling( installStateCurrent, installStateAction ) ) + { + + cadata->Write( IIS_UNINSTALL_HANDLER ); + + hr = MsiUtilRecordGetString( hRecord, + CA_HANDLER_NAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; +} + + +HRESULT +ExecuteInstallHandlerCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szName = NULL; + WCHAR * szPath = NULL; + WCHAR * szVerb = NULL; + WCHAR * szType = NULL; + WCHAR * szIndex = NULL; + WCHAR * szModules = NULL; + WCHAR * szScriptProcessor = NULL; + WCHAR * szResourceType = NULL; + WCHAR * szRequiredAccess = NULL; + WCHAR * szPreCondition = NULL; + + ULONG ulIndex = HANDLER_INDEX_FIRST; + + CComPtr pAdminMgr; + + + hr = CoCreateInstance(__uuidof(AppHostWritableAdminManager), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(IAppHostWritableAdminManager), + (VOID **)&pAdminMgr); + if (FAILED(hr)) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"CoCreateInstance failed 0x%08x", hr); + DBGERROR_HR(hr); + goto exit; + } + + + hr = cadata->Read( &szName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szPath ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szVerb ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szType ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szIndex ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + if( 0 == _wcsicmp( szIndex, L"FIRST" ) ) + { + ulIndex = HANDLER_INDEX_FIRST; + } + else if ( 0 == _wcsicmp( szIndex, L"LAST" ) ) + { + ulIndex = HANDLER_INDEX_FIRST; + } + else if ( 0 == _wcsicmp( szIndex, L"BEFORE_STATICFILE" ) ) + { + ulIndex = HANDLER_INDEX_BEFORE_STATICFILE; + } + + hr = cadata->Read( &szModules ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szScriptProcessor ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szResourceType ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szRequiredAccess ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Read( &szPreCondition ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Install the Handler + // + hr = RegisterHandler( pAdminMgr, + ROOT_CONFIG_PATH, + ulIndex, + szName, + szPath, + szVerb, + szType, + szModules, + szScriptProcessor, + szResourceType, + szRequiredAccess, + szPreCondition + ); + + if ( hr == HRESULT_FROM_WIN32( ERROR_ALREADY_EXISTS ) ) + { + // + // We'll quietly accept a handler already exists. + // + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, + L"Handler: '%s' already installed.", + szName); + + hr = S_OK; + } + + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + + // + // Update config + // + hr = pAdminMgr->CommitChanges(); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; +} + + +HRESULT +ExecuteUnInstallHandlerCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szName = NULL; + + CComPtr pAdminMgr; + + + hr = CoCreateInstance(__uuidof(AppHostWritableAdminManager), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(IAppHostWritableAdminManager), + (VOID **)&pAdminMgr); + if (FAILED(hr)) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"CoCreateInstance failed 0x%08x", hr); + DBGERROR_HR(hr); + goto exit; + } + + + hr = cadata->Read( &szName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = UnRegisterHandler( pAdminMgr, ROOT_CONFIG_PATH, szName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + + // + // Update config + // + hr = pAdminMgr->CommitChanges(); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; +} + +HRESULT +ScheduleInstallSectionDefaultsCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + STACK_STRU( strComponent, 128 ); + STACK_STRU( strName, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISConfigSectionDefaults`.`Name`, " + L"`IISConfigSectionDefaults`.`SectionName`, " + L"`IISConfigSectionDefaults`.`Component_`, " + L"`Binary`.`Data` " + L"FROM `IISConfigSectionDefaults`, `Binary` " + L"WHERE `IISConfigSectionDefaults`.`BinaryName_`=`Binary`.`Name`"; + + + enum { CA_DEFAULTS_NAME = 1, + CA_DEFAULTS_SECTIONNAME, + CA_DEFAULTS_COMPONENT, + CA_DEFAULTS_BINARYDATA + }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + //Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISConfigSectionDefaults"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_DEFAULTS_COMPONENT, + &strComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + + cadata->Write( IIS_INSTALL_DEFAULTS ); + + // Get the record name + hr = MsiUtilRecordGetString( hRecord, + CA_DEFAULTS_NAME, + &strName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // Get the Section name + hr = MsiUtilRecordGetString( hRecord, + CA_DEFAULTS_SECTIONNAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Get File from binary, write to temp file + // + STACK_STRU( strFilePath, MAX_PATH * 2 ); + + hr = GenerateTempFileName ( strName.QueryStr(), + L"def", + &strFilePath); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error generating temp file name for the hotfix, hr=0x%x", hr); + goto exit; + } + + hr = MsiUtilRecordReadStreamIntoFile ( hRecord, + CA_DEFAULTS_BINARYDATA, + strFilePath.QueryStr()); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error streaming binary data into file, hr=0x%x", hr); + goto exit; + } + + hr = cadata->Write( strFilePath.QueryStr(), strFilePath.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error writing custom action data, hr=0x%x", hr); + goto exit; + } + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; + +} +HRESULT +ExecuteInstallSectionDefaultsCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szSectionName = NULL; + WCHAR * szTempFileName = NULL; + + CComPtr pAdminMgr; + + + hr = CoCreateInstance(__uuidof(AppHostWritableAdminManager), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(IAppHostWritableAdminManager), + (VOID **)&pAdminMgr); + if (FAILED(hr)) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"CoCreateInstance failed 0x%08x", hr); + DBGERROR_HR(hr); + goto exit; + } + + + hr = cadata->Read( &szSectionName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szTempFileName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Set Section Defaults from temp file created during schedule + // + hr = ResetConfigSectionFromFile( szTempFileName, szSectionName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + // delete temp file. No error checking. + // + ::DeleteFileW( szTempFileName ); + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + + // + // Update config + // + hr = pAdminMgr->CommitChanges(); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; + +} + +HRESULT +ScheduleInstallSectionAdditionsCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + STACK_STRU( strComponent, 128 ); + STACK_STRU( strName, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISConfigSectionAdditions`.`Name`, " + L"`IISConfigSectionAdditions`.`SectionName`, " + L"`IISConfigSectionAdditions`.`Component_`, " + L"`Binary`.`Data` " + L"FROM `IISConfigSectionAdditions`, `Binary` " + L"WHERE `IISConfigSectionAdditions`.`BinaryName_`=`Binary`.`Name`"; + + + enum { CA_SECTION_ADDITION_NAME = 1, + CA_SECTION_ADDITION_SECTIONNAME, + CA_SECTION_ADDITION_COMPONENT, + CA_SECTION_ADDITION_BINARYDATA + }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + + // + // Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISConfigSectionAdditions"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_SECTION_ADDITION_COMPONENT, + &strComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + + cadata->Write( IIS_INSTALL_SECTION_ADDITIONS); + + // Get the record name + hr = MsiUtilRecordGetString( hRecord, + CA_SECTION_ADDITION_NAME, + &strName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // Get the Section name + hr = MsiUtilRecordGetString( hRecord, + CA_SECTION_ADDITION_SECTIONNAME, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Get File from binary, write to temp file + // + STACK_STRU( strFilePath, MAX_PATH * 2 ); + + hr = GenerateTempFileName ( strName.QueryStr(), + L"def", + &strFilePath); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error generating temp file name for the hotfix, hr=0x%x", hr); + goto exit; + } + + hr = MsiUtilRecordReadStreamIntoFile ( hRecord, + CA_SECTION_ADDITION_BINARYDATA, + strFilePath.QueryStr()); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error streaming binary data into file, hr=0x%x", hr); + goto exit; + } + + hr = cadata->Write( strFilePath.QueryStr(), strFilePath.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error writing custom action data, hr=0x%x", hr); + goto exit; + } + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; + +} +HRESULT +ExecuteInstallSectionAdditionsCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szSectionName = NULL; + WCHAR * szTempFileName = NULL; + + CComPtr pAdminMgr; + + + hr = CoCreateInstance(__uuidof(AppHostWritableAdminManager), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(IAppHostWritableAdminManager), + (VOID **)&pAdminMgr); + if (FAILED(hr)) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"CoCreateInstance failed 0x%08x", hr); + DBGERROR_HR(hr); + goto exit; + } + + + hr = cadata->Read( &szSectionName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szTempFileName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Set Section Defaults from temp file created during schedule + // + hr = AppendConfigSectionFromFile( szTempFileName, szSectionName ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // + // delete temp file. No error checking. + // + ::DeleteFileW( szTempFileName ); + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + + // + // Update config + // + hr = pAdminMgr->CommitChanges(); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; + +} + +HRESULT +ScheduleInstallCgiRestrictionsCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + STACK_STRU( strComponent, 128 ); + STACK_STRU( strName, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISCgiRestriction`.`Name`, " + L"`IISCgiRestriction`.`Component_`, " + L"`IISCgiRestriction`.`Path`, " + L"`IISCgiRestriction`.`Allowed`, " + L"`IISCgiRestriction`.`GroupId`, " + L"`IISCgiRestriction`.`Description` " + L"FROM `IISCgiRestriction` "; + + enum { CA_CGI_NAME = 1, + CA_CGI_COMPONENT, + CA_CGI_PATH, + CA_CGI_ALLOWED, + CA_CGI_GROUPID, + CA_CGI_DESC + }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + //Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISCgiRestriction"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + cadata->Write( IIS_INSTALL_CGIRESTRICTIONS ); + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_CGI_COMPONENT, + &strComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsInstalling( installStateCurrent, installStateAction ) || + MsiUtilIsReInstalling( installStateCurrent, installStateAction ) ) + { + + // Get the Path + hr = MsiUtilRecordGetString( hRecord, + CA_CGI_PATH, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // Get the Allowed + hr = MsiUtilRecordGetString( hRecord, + CA_CGI_ALLOWED, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // Get the GroupId + hr = MsiUtilRecordGetString( hRecord, + CA_CGI_GROUPID, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + // Get the Description + hr = MsiUtilRecordGetString( hRecord, + CA_CGI_DESC, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; + +} + +HRESULT +ScheduleUnInstallCgiRestrictionsCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ) +{ + + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + MSIHANDLE hDatabase = NULL; + MSIHANDLE hView = NULL; + MSIHANDLE hRecord = NULL; + + STACK_STRU( strData, 128 ); + STACK_STRU( strComponent, 128 ); + STACK_STRU( strName, 128 ); + + CONST WCHAR * szQuery = + L"SELECT " + L"`IISCgiRestriction`.`Name`, " + L"`IISCgiRestriction`.`Component_`, " + L"`IISCgiRestriction`.`Path`, " + L"FROM `IISCgiRestriction` "; + + enum { CA_CGI_NAME = 1, + CA_CGI_COMPONENT, + CA_CGI_PATH, + CA_CGI_ALLOWED, + CA_CGI_GROUPID, + CA_CGI_DESC + }; + + INSTALLSTATE installStateCurrent; + INSTALLSTATE installStateAction; + + hDatabase = MsiGetActiveDatabase( hInstall ); + if ( !hDatabase ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + // + //Does table exist + // + UINT er = ERROR_SUCCESS; + er = ::MsiDatabaseIsTablePersistentW(hDatabase, L"IISCgiRestriction"); + if (MSICONDITION_TRUE != er) + { + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' Table not found, exiting", + UNITEXT(__FUNCTION__) + ); + goto exit; + } + + + cadata->Write( IIS_UNINSTALL_CGIRESTRICTIONS ); + + status = MsiDatabaseOpenViewW( hDatabase, szQuery, &hView ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiViewExecute( hView, NULL ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto exit; + } + + while ( ERROR_SUCCESS == MsiViewFetch( hView, &hRecord ) ) + { + hr = MsiUtilRecordGetString( hRecord, + CA_CGI_COMPONENT, + &strComponent ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetComponentStateW( hInstall, + strComponent.QueryStr(), + &installStateCurrent, + &installStateAction ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + if ( MsiUtilIsUnInstalling( installStateCurrent, installStateAction ) ) + { + + // Get the Path + hr = MsiUtilRecordGetString( hRecord, + CA_CGI_PATH, + &strData ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Write( strData.QueryStr(), strData.QueryCCH() ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + } + + +exit: + + if ( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + if ( hView ) + { + MsiCloseHandle( hView ); + hView = NULL; + } + + if ( hDatabase ) + { + MsiCloseHandle( hDatabase ); + hDatabase = NULL; + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + + return hr; + +} + + +HRESULT +ExecuteInstallCgiRestrictionsCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szPath = NULL; + WCHAR * szAllowed = NULL; + WCHAR * szGroupId = NULL; + WCHAR * szDescription = NULL; + BOOL fAllowed = FALSE; + + CComPtr pAdminMgr; + + + hr = CoCreateInstance(__uuidof(AppHostWritableAdminManager), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(IAppHostWritableAdminManager), + (VOID **)&pAdminMgr); + if (FAILED(hr)) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"CoCreateInstance failed 0x%08x", hr); + DBGERROR_HR(hr); + goto exit; + } + + + while ( SUCCEEDED(hr = cadata->Read( &szPath )) ) + { + + hr = cadata->Read( &szAllowed ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szGroupId ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + hr = cadata->Read( &szDescription ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( 0 == wcscmp( szAllowed, L"true" ) ) + { + fAllowed = TRUE; + } + else if ( 0 == wcscmp( szAllowed, L"false" ) ) + { + fAllowed = FALSE; + } + + hr = RegisterCgiRestriction( + pAdminMgr, + ROOT_CONFIG_PATH, + szPath, + fAllowed, + szGroupId, + szDescription + ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + + // + // Update config + // + hr = pAdminMgr->CommitChanges(); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; + +} + + +HRESULT +ExecuteUnInstallCgiRestrictionsCA( + IN CA_DATA_READER * cadata + ) +{ + HRESULT hr = NOERROR; + + WCHAR * szPath = NULL; + + CComPtr pAdminMgr; + + + hr = CoCreateInstance(__uuidof(AppHostWritableAdminManager), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(IAppHostWritableAdminManager), + (VOID **)&pAdminMgr); + if (FAILED(hr)) + { + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, + L"CoCreateInstance failed 0x%08x", hr); + DBGERROR_HR(hr); + goto exit; + } + + + while ( SUCCEEDED(hr = cadata->Read( &szPath )) ) + { + hr = UnRegisterCgiRestriction( + pAdminMgr, + ROOT_CONFIG_PATH, + szPath, + FALSE + ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + hr = S_OK; + } + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + + // + // Update config + // + hr = pAdminMgr->CommitChanges(); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + return hr; +} + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iisca.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iisca.h new file mode 100644 index 0000000000..40f7097845 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iisca.h @@ -0,0 +1,255 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#define _UNITEXT(quote) L##quote +#define UNITEXT(quote) _UNITEXT(quote) + + +// IIS Custom action Types +enum IIS_COSTOM_ACTION_TYPE +{ + IIS_INSTALL_MODULE = 1, + IIS_UNINSTALL_MODULE, + IIS_INSTALL_UIMODULE, + IIS_UNINSTALL_UIMODULE, + IIS_INSTALL_HANDLER, + IIS_UNINSTALL_HANDLER, + IIS_INSTALL_SECTIONSCHEMA, + IIS_UNINSTALL_SECTIONSCHEMA, + IIS_INSTALL_TRACEAREA, + IIS_INSTALL_MOFFILE, + IIS_INSTALL_DEFAULTS, + IIS_INSTALL_SECTION_ADDITIONS, + IIS_INSTALL_CGIRESTRICTIONS, + IIS_UNINSTALL_CGIRESTRICTIONS, + IIS_INSTALL_, + IIS_UNINSTALL_, + IIS_END +}; + + +HRESULT +InstallModule( + IN CONST WCHAR * szName, + IN CONST WCHAR * szImage, + IN OPTIONAL CONST WCHAR * szPreCondition, + IN OPTIONAL CONST WCHAR * szTYpe + ); + + +HRESULT +UnInstallModule( + IN CONST WCHAR * szName, + IN OPTIONAL CONST WCHAR * szPreCondition + ); + +HRESULT +RegisterSectionSchema( + IN CONST BOOL isSectionInAdminSchema, + IN CONST WCHAR * szSectionName, + IN CONST WCHAR * szOverideModeDefault, + IN OPTIONAL CONST WCHAR * szAllowDefinition, + IN OPTIONAL CONST WCHAR * szType + ); + +HRESULT +UnRegisterSectionSchema( + IN CONST BOOL isSectionInAdminSchema, + IN CONST WCHAR * szSectionName + ); + +HRESULT +RegisterUIModule( + IN CONST WCHAR * szModuleName, + IN CONST WCHAR * szModuleTypeInfo, + IN OPTIONAL CONST WCHAR * szRegisterInModulesSection, + IN OPTIONAL CONST WCHAR * szPrependToList + ); + +HRESULT +UnRegisterUIModule( + IN CONST WCHAR * szModuleName, + IN CONST WCHAR * szModuleTypeInfo + ); + +UINT +WINAPI +CheckForAdminSIDCA( + MSIHANDLE hInstall + ); + +UINT +LogMsiCustomActionError( + IN MSIHANDLE hInstall, + UINT messageId + ); + +HRESULT +InitAdminMgrForAdminConfig( + IN IAppHostWritableAdminManager * pAdminMgr, + IN CONST WCHAR * szCommitPath +); + +HRESULT +RegisterMofFile( + IN PWSTR pszFileName +); + +HRESULT +ScheduleInstallModuleCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + +HRESULT +ScheduleUnInstallModuleCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + +HRESULT +ExecuteInstallModuleCA( + IN CA_DATA_READER * cadata +); + +HRESULT +ExecuteUnInstallModuleCA( + IN CA_DATA_READER * cadata +); + + +HRESULT +ExecuteUnRegisterUIModuleCA( + IN CA_DATA_READER * cadata +); + + +HRESULT +ScheduleRegisterUIModuleCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); +HRESULT +ExecuteRegisterUIModuleCA( + IN CA_DATA_READER * cadata +); + +HRESULT +ScheduleUnRegisterUIModuleCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + + +HRESULT +ScheduleInstallHandlerCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ); + +HRESULT +ScheduleUnInstallHandlerCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata + ); + +HRESULT +ExecuteInstallHandlerCA( + IN CA_DATA_READER * cadata + ); + +HRESULT +ExecuteUnInstallHandlerCA( + IN CA_DATA_READER * cadata + ); + +HRESULT +ExecuteUnRegisterSectionSchemaCA( + IN CA_DATA_READER * cadata +); + + +HRESULT +ScheduleRegisterSectionSchemaCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + +HRESULT +ExecuteRegisterSectionSchemaCA( + IN CA_DATA_READER * cadata +); + +HRESULT +ScheduleUnRegisterSectionSchemaCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + +HRESULT +ScheduleRegisterTraceAreaCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + +HRESULT +ExecuteRegisterTraceAreaCA( + IN CA_DATA_READER * cadata +); + +HRESULT +ScheduleRegisterMofFileCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + +HRESULT +ExecuteRegisterMofFileCA( + IN CA_DATA_READER * cadata +); + +HRESULT +ScheduleInstallSectionDefaultsCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + +HRESULT +ExecuteInstallSectionDefaultsCA( + IN CA_DATA_READER * cadata +); + +HRESULT +ScheduleInstallSectionAdditionsCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + +HRESULT +ExecuteInstallSectionAdditionsCA( + IN CA_DATA_READER * cadata +); + +HRESULT +ScheduleInstallCgiRestrictionsCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + +HRESULT +ScheduleUnInstallCgiRestrictionsCA( + IN MSIHANDLE hInstall, + IN CA_DATA_WRITER * cadata +); + +HRESULT +ExecuteInstallCgiRestrictionsCA( + IN CA_DATA_READER * cadata +); + +HRESULT +ExecuteUnInstallCgiRestrictionsCA( + IN CA_DATA_READER * cadata +); diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iisca.vcxproj b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iisca.vcxproj new file mode 100644 index 0000000000..a05a121110 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iisca.vcxproj @@ -0,0 +1,131 @@ + + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {b54a8f61-60de-4ad9-87ca-d102f230678e} + + + + {7324770c-0871-4d73-be3d-5e2f3e9e1b1e} + Win32Proj + iisca + + + + StaticLibrary + Unicode + v141 + + + + $(IIS-Common)version;$(IIS-Common)Include;$(AdditionalIncludeDirectories) + Create + precomp.h + $(IntDir)precomp.pch + + + + $(WIX)sdk\$(WixPlatformToolset)\inc;$(AdditionalIncludeDirectories) + Level4 + + + nothrownew.obj;httpapi.lib;shlwapi.lib;ahadmin.lib;xmllite.lib;msi.lib;dutil.lib;wcautil.lib;Version.lib;%(AdditionalDependencies) + CustomAction.def + Windows + + + + + _DEBUG;_WINDOWS;_USRDLL;CUSTOMACTIONTEST_EXPORTS;%(PreprocessorDefinitions) + + + + + MaxSpeed + + + true + + + + + $(VC_ReferencesPath_x86);$(WindowsSDK_LibraryPath)\$(PlatformTarget);$(WIX)sdk\$(WixPlatformToolset)\lib\x86;%(AdditionalLibraryDirectories) + MachineX86 + + + + + $(VC_ReferencesPath_x64);$(WindowsSDK_LibraryPath)\$(PlatformTarget);$(WIX)sdk\$(WixPlatformToolset)\lib\x64;%(AdditionalLibraryDirectories) + Machinex64 + + + + + + This project is trying to import a missing file: {0}. + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iiscaexp.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iiscaexp.cpp new file mode 100644 index 0000000000..e407497402 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iiscaexp.cpp @@ -0,0 +1,791 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + + + +#define IIS_CONFIG_BACKUP_EXT L"IISOOBBACK" + + +typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + +LPFN_ISWOW64PROCESS fnIsWow64Process; + +BOOL IsWow64() +{ + BOOL bIsWow64 = FALSE; + + //IsWow64Process is not available on all supported versions of Windows. + //Use GetModuleHandle to get a handle to the DLL that contains the function + //and GetProcAddress to get a pointer to the function if available. + + fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress( + GetModuleHandle(TEXT("kernel32")),"IsWow64Process"); + + if(NULL != fnIsWow64Process) + { + if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) + { + //handle error + } + } + return bIsWow64; +} + +/******************************************************************** +IISScheduleInstall CA - CUSTOM ACTION ENTRY POINT for reading IIS custom +table settings into CA Data + +********************************************************************/ +UINT +WINAPI +IISScheduleInstallCA( + IN MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + CA_DATA_WRITER cadata; + BOOL bWriteToShared = FALSE; + BOOL fCoInit = FALSE; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + if ( SUCCEEDED( CoInitializeEx( NULL, COINIT_MULTITHREADED ) ) ) + { + fCoInit = TRUE; + } + + // + //See if we are going to update shared config + // + hr = CheckInstallToSharedConfig( hInstall, &bWriteToShared ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + if ( !bWriteToShared ) + { + //do not update config for this module + //ExecuteCA will not be scheduled. + } + // + // Schedule transactions + // + hr = MsiUtilScheduleDeferredAction( hInstall, + L"IISBeginTransactionCA", + cadata.QueryData() ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = MsiUtilScheduleDeferredAction( hInstall, + L"IISRollbackTransactionCA", + cadata.QueryData() ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = MsiUtilScheduleDeferredAction( hInstall, + L"IISCommitTransactionCA", + cadata.QueryData() ); + if ( FAILED(hr) ) + { + goto exit; + } + if( bWriteToShared ) + { + // + // Do the Config Install actions + // + hr = ScheduleInstallModuleCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleRegisterUIModuleCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleInstallHandlerCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleRegisterSectionSchemaCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleRegisterTraceAreaCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleInstallSectionDefaultsCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleInstallSectionAdditionsCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleInstallCgiRestrictionsCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + } + + // + // Do the Non-Config Install actions + // + hr = ScheduleRegisterMofFileCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + + + // + // Schedule deferred execute CA + // + + hr = MsiUtilScheduleDeferredAction( hInstall, + L"IISExecuteCA", + cadata.QueryData() ); + if ( FAILED(hr) ) + { + goto exit; + } + + hr = NOERROR; + + +exit: + if ( fCoInit ) + { + CoUninitialize(); + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + IISLogClose(); + + return hr; +} +/******************************************************************** +IISScheduleUninstall CA - CUSTOM ACTION ENTRY POINT for reading IIS custom +table settings into CA Data + +********************************************************************/ +UINT +WINAPI +IISScheduleUninstallCA( + IN MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + CA_DATA_WRITER cadata; + BOOL bWriteToShared = FALSE; + BOOL fCoInit = FALSE; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + if ( SUCCEEDED( CoInitializeEx( NULL, COINIT_MULTITHREADED ) ) ) + { + fCoInit = TRUE; + } + + // + //See if we are going to update shared config + // + hr = CheckInstallToSharedConfig( hInstall, &bWriteToShared ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + if ( !bWriteToShared ) + { + //do not update config for this module + //ExecuteCA will not be scheduled. + } + + if( bWriteToShared ) + { + // + // Do the Config Uninstall actions + // + hr = ScheduleUnInstallModuleCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleUnRegisterUIModuleCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleUnInstallHandlerCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleUnRegisterSectionSchemaCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + hr = ScheduleUnInstallCgiRestrictionsCA( hInstall, &cadata ); + if ( FAILED(hr) ) + { + goto exit; + } + } + // + // Do the Non-Config Uninstall actions + // + + + // + // Schedule deferred execute CA + // + + hr = MsiUtilScheduleDeferredAction( hInstall, + L"IISExecuteCA", + cadata.QueryData() ); + if ( FAILED(hr) ) + { + goto exit; + } + + hr = NOERROR; + + +exit: + if ( fCoInit ) + { + CoUninitialize(); + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + IISLogClose(); + + // + // Don't fail while uninstalling. + // + return NOERROR; +} +/******************************************************************** +IISExecuteCA - CUSTOM ACTION ENTRY POINT for writing IIS custom +table settings to iis config + +********************************************************************/ +UINT +WINAPI +IISExecuteCA( + IN MSIHANDLE hInstall + ) +{ + HRESULT hr = NOERROR; + CA_DATA_READER cadata; + INT icaType = 0; + BOOL fCoInit = FALSE; + + IISLogInitialize(hInstall, UNITEXT(__FUNCTION__)); + + if ( SUCCEEDED( CoInitializeEx( NULL, COINIT_MULTITHREADED ) ) ) + { + fCoInit = TRUE; + } + // + // Retrieve parameters from ca data + // + + hr = cadata.LoadDeferredCAData( hInstall ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + while ( SUCCEEDED(hr = cadata.Read( &icaType )) ) + { + switch (icaType ) + { + case IIS_INSTALL_MODULE: + { + hr = ExecuteInstallModuleCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_UNINSTALL_MODULE: + { + hr = ExecuteUnInstallModuleCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_INSTALL_UIMODULE: + { + hr = ExecuteRegisterUIModuleCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_UNINSTALL_UIMODULE: + { + hr = ExecuteUnRegisterUIModuleCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_INSTALL_HANDLER: + { + hr = ExecuteInstallHandlerCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_UNINSTALL_HANDLER: + { + hr = ExecuteUnInstallHandlerCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_INSTALL_SECTIONSCHEMA: + { + hr = ExecuteRegisterSectionSchemaCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_UNINSTALL_SECTIONSCHEMA: + { + hr = ExecuteUnRegisterSectionSchemaCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_INSTALL_TRACEAREA: + { + hr = ExecuteRegisterTraceAreaCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_INSTALL_MOFFILE: + { + hr = ExecuteRegisterMofFileCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_INSTALL_DEFAULTS: + { + hr = ExecuteInstallSectionDefaultsCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_INSTALL_SECTION_ADDITIONS: + { + hr = ExecuteInstallSectionAdditionsCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_INSTALL_CGIRESTRICTIONS: + { + hr = ExecuteInstallCgiRestrictionsCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + case IIS_UNINSTALL_CGIRESTRICTIONS: + { + hr = ExecuteInstallCgiRestrictionsCA( &cadata ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + break; + } + default: + { + //unknown execute CA action type + hr = E_UNEXPECTED; + goto exit; + } + } + } + + if ( HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ) + { + hr = S_OK; + } + +exit: + + if ( fCoInit ) + { + CoUninitialize(); + } + + IISLogWrite( + SETUP_LOG_SEVERITY_INFORMATION, + L"CA '%s' completed with return code hr=0x%x", + UNITEXT(__FUNCTION__), + hr ); + + IISLogClose(); + + return hr; +} + +/******************************************************************** + BeginTransaction - CUSTOM ACTION ENTRY POINT for backing up + config + + Input: deferred CustomActionData - BackupName +********************************************************************/ +UINT +WINAPI +IISBeginTransactionCA( + IN MSIHANDLE + ) + +{ + HRESULT hr = S_OK; + STACK_STRU( wzConfigSource, MAX_PATH ); + STACK_STRU( wzConfigCopy, MAX_PATH ); + DWORD dwSize = 0; + + if( IsWow64() ) + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\Sysnative\\inetsrv\\config\\applicationHost.config", + wzConfigSource.QueryStr(), + MAX_PATH + ); + } + else + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\applicationHost.config", + wzConfigSource.QueryStr(), + MAX_PATH + ); + } + if ( dwSize == 0 ) + { + //ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); + goto exit; + } + wzConfigSource.SyncWithBuffer(); + hr = wzConfigCopy.Copy( wzConfigSource ); + + //add ca action as extension + + hr = wzConfigCopy.Append( L"."); + + hr = wzConfigCopy.Append( IIS_CONFIG_BACKUP_EXT); + + if ( !::CopyFileW(wzConfigSource.QueryStr(), wzConfigCopy.QueryStr(), FALSE) ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + //ExitOnFailure2(hr, "Failed to copy config backup %S -> %S", wzConfigSource, wzConfigCopy); + } + + if( IsWow64() ) + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\Sysnative\\inetsrv\\config\\administration.config", + wzConfigSource.QueryStr(), + MAX_PATH + ); + } + else + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\administration.config", + wzConfigSource.QueryStr(), + MAX_PATH + ); + } + + if ( dwSize == 0 ) + { + //ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); + goto exit; + } + wzConfigSource.SyncWithBuffer(); + hr = wzConfigCopy.Copy( wzConfigSource ); + + //add ca action as extension + + hr = wzConfigCopy.Append( L"."); + + hr = wzConfigCopy.Append( IIS_CONFIG_BACKUP_EXT); + + if ( !::CopyFileW(wzConfigSource.QueryStr(), wzConfigCopy.QueryStr(), FALSE) ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + //ExitOnFailure2(hr, "Failed to copy config backup %S -> %S", wzConfigSource, wzConfigCopy); + } + + +exit: + + return S_OK; + +} + + +/******************************************************************** + RollbackTransaction - CUSTOM ACTION ENTRY POINT for unbacking up + config + + Input: deferred CustomActionData - BackupName +********************************************************************/ +UINT +WINAPI +IISRollbackTransactionCA( + IN MSIHANDLE + ) +{ + + HRESULT hr = S_OK; + STACK_STRU( wzConfigSource, MAX_PATH ); + STACK_STRU( wzConfigCopy, MAX_PATH ); + DWORD dwSize = 0; + + + if( IsWow64() ) + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\Sysnative\\inetsrv\\config\\applicationHost.config", + wzConfigSource.QueryStr(), + MAX_PATH + ); + } + else + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\applicationHost.config", + wzConfigSource.QueryStr(), + MAX_PATH + ); + } + if ( dwSize == 0 ) + { + //ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); + goto exit; + } + wzConfigSource.SyncWithBuffer(); + hr = wzConfigCopy.Copy( wzConfigSource ); + + //add ca action as extension + + hr = wzConfigCopy.Append( L"." ); + + hr = wzConfigCopy.Append( IIS_CONFIG_BACKUP_EXT ); + + //rollback copy is reverse of start transaction + if( !::CopyFileW( wzConfigCopy.QueryStr(), wzConfigSource.QueryStr(), FALSE) ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + //ExitOnFailure(hr, "failed to restore config backup"); + } + + if ( !::DeleteFileW( wzConfigCopy.QueryStr() ) ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + //ExitOnFailure(hr, "failed to delete config backup"); + } + + if( IsWow64() ) + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\Sysnative\\inetsrv\\config\\administration.config", + wzConfigSource.QueryStr(), + MAX_PATH + ); + } + else + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\administration.config", + wzConfigSource.QueryStr(), + MAX_PATH + ); + } + if ( dwSize == 0 ) + { + //ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); + goto exit; + } + wzConfigSource.SyncWithBuffer(); + hr = wzConfigCopy.Copy( wzConfigSource ); + + //add ca action as extension + + hr = wzConfigCopy.Append( L"." ); + + hr = wzConfigCopy.Append( IIS_CONFIG_BACKUP_EXT ); + + //rollback copy is reverse of start transaction + if( !::CopyFileW( wzConfigCopy.QueryStr(), wzConfigSource.QueryStr(), FALSE) ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + //ExitOnFailure(hr, "failed to restore config backup"); + } + + if ( !::DeleteFileW( wzConfigCopy.QueryStr() ) ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + //ExitOnFailure(hr, "failed to delete config backup"); + } + + +exit: + + return S_OK; + +} +/******************************************************************** + CommitTransaction - CUSTOM ACTION ENTRY POINT for unbacking up + config + + Input: deferred CustomActionData - BackupName +********************************************************************/ +UINT +WINAPI +IISCommitTransactionCA( + IN MSIHANDLE + ) +{ + HRESULT hr = S_OK; + STACK_STRU( wzConfigCopy, MAX_PATH ); + DWORD dwSize = 0; + + + + // Config AdminMgr changes already committed, just + // delete backup config file. + + if( IsWow64() ) + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\Sysnative\\inetsrv\\config\\applicationHost.config", + wzConfigCopy.QueryStr(), + MAX_PATH + ); + } + else + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\applicationHost.config", + wzConfigCopy.QueryStr(), + MAX_PATH + ); + } + if ( dwSize == 0 ) + { + //ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); + goto exit; + } + wzConfigCopy.SyncWithBuffer(); + + hr = wzConfigCopy.Append( L"." ); + + hr = wzConfigCopy.Append( IIS_CONFIG_BACKUP_EXT); + + if( !::DeleteFileW(wzConfigCopy.QueryStr() ) ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + //ExitOnFailure(hr, "failed to delete config backup"); + } + + if( IsWow64() ) + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\Sysnative\\inetsrv\\config\\administration.config", + wzConfigCopy.QueryStr(), + MAX_PATH + ); + } + else + { + dwSize = ExpandEnvironmentStringsW(L"%windir%\\system32\\inetsrv\\config\\administration.config", + wzConfigCopy.QueryStr(), + MAX_PATH + ); + } + if ( dwSize == 0 ) + { + //ExitWithLastError(hr, "failed to get ExpandEnvironmentStrings"); + goto exit; + } + wzConfigCopy.SyncWithBuffer(); + + hr = wzConfigCopy.Append( L"." ); + + hr = wzConfigCopy.Append( IIS_CONFIG_BACKUP_EXT); + + if( !::DeleteFileW(wzConfigCopy.QueryStr() ) ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + //ExitOnFailure(hr, "failed to delete config backup"); + } + + +exit: + + return S_OK; + +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iiscaexp.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iiscaexp.h new file mode 100644 index 0000000000..184df8aff8 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/iiscaexp.h @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +UINT +WINAPI +IISScheduleInstallCA( + IN MSIHANDLE hInstall + ); + +UINT +WINAPI +IISScheduleUninstallCA( + IN MSIHANDLE hInstall + ); + +UINT +WINAPI +IISExecuteCA( + IN MSIHANDLE hInstall + ); + +UINT +WINAPI +IISBeginTransactionCA( + IN MSIHANDLE hInstall + ); + +UINT +WINAPI +IISRollbackTransactionCA( + IN MSIHANDLE hInstall + ); + +UINT +WINAPI +IISCommitTransactionCA( + IN MSIHANDLE hInstall + ); + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/modules.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/modules.cpp new file mode 100644 index 0000000000..341306461d --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/modules.cpp @@ -0,0 +1,655 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +// +// Local function declarations +// + +HRESULT +AddModuleToGlobalModules( + IN IAppHostWritableAdminManager * pAdminMgr, + IN CONST WCHAR * szName, + IN CONST WCHAR * szImage, + IN OPTIONAL CONST WCHAR * szPreCondition + ); + +HRESULT +AddModuleToRootModules( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szName, + IN CONST WCHAR * szPreCondition, + IN OPTIONAL CONST WCHAR * szType + ); + +HRESULT +DeleteModuleFromRootModules( + IAppHostAdminManager * pAdminMgr, + CONST WCHAR * szName, + BOOL * pfDeleted + ); + +// +// Public functions +// + +HRESULT +InstallModule( + IN CONST WCHAR * szName, + IN CONST WCHAR * szImage, + IN OPTIONAL CONST WCHAR * szPreCondition, + IN OPTIONAL CONST WCHAR * szType + ) +{ + HRESULT hr = NOERROR; + + CComPtr pAdminMgr; + + hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( IAppHostWritableAdminManager ), + (VOID **)&pAdminMgr ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // If the type is present, this is a .Net module and + // should not be added to the globalModules + if ( ( szType == NULL ) || ( *szType == L'\0' ) ) + { + STRU strFinalImage; + WCHAR ProgFiles[64]; + WCHAR SysRoot[64]; + WCHAR SysDrive[16]; + PCWSTR szSubstFrom = NULL; + PCWSTR szSubstTo = NULL; + + if (GetEnvironmentVariable(L"ProgramFiles", + ProgFiles, + _countof(ProgFiles)) > _countof(ProgFiles) || + GetEnvironmentVariable(L"SystemRoot", + SysRoot, + _countof(SysRoot)) > _countof(SysRoot) || + GetEnvironmentVariable(L"SystemDrive", + SysDrive, + _countof(SysDrive)) > _countof(SysDrive)) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + + if (_wcsnicmp(szImage, ProgFiles, wcslen(ProgFiles)) == 0) + { + szSubstFrom = ProgFiles; + szSubstTo = L"%ProgramFiles%"; + } + else if (_wcsnicmp(szImage, SysRoot, wcslen(SysRoot)) == 0) + { + szSubstFrom = SysRoot; + szSubstTo = L"%SystemRoot%"; + } + else if (_wcsnicmp(szImage, SysDrive, wcslen(SysDrive)) == 0) + { + szSubstFrom = SysDrive; + szSubstTo = L"%SystemDrive%"; + } + + if (szSubstFrom != NULL) + { + if (FAILED(hr = strFinalImage.Copy(szSubstTo)) || + FAILED(hr = strFinalImage.Append(szImage + wcslen(szSubstFrom)))) + { + goto exit; + } + szImage = strFinalImage.QueryStr(); + } + + hr = AddModuleToGlobalModules( pAdminMgr, + szName, + szImage, + szPreCondition ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + hr = AddModuleToRootModules( pAdminMgr, + szName, + szPreCondition, + szType ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->CommitChanges(); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return hr; +} + +HRESULT +UnInstallModule( + IN CONST WCHAR * szName, + IN OPTIONAL CONST WCHAR * szType + ) +{ + HRESULT hr = NOERROR; + + CComPtr pAdminMgr; + CComPtr pGlobalModulesSection; + CComPtr pGlobalModulesCollection; + + BSTR bstrAppHostConfigPath = SysAllocString( L"MACHINE/WEBROOT/APPHOST" ); + BSTR bstrGlobalModules = SysAllocString( L"system.webServer/globalModules" ); + + BOOL fChanged = FALSE; + BOOL fDeleted = FALSE; + UINT numDeleted; + + if ( !bstrAppHostConfigPath || + !bstrGlobalModules ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto exit; + } + + hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( IAppHostWritableAdminManager ), + (VOID **)&pAdminMgr ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Remove from root modules + // + + hr = DeleteModuleFromRootModules( pAdminMgr, + szName, + &fDeleted ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( !fDeleted ) + { + DBGWARN(( DBG_CONTEXT, + "Expected to find %S in root modules collection\n" , + szName )); + } + + fChanged = fDeleted; + + if ( ( szType == NULL ) || ( *szType == L'\0' ) ) + { + // + // Remove from globalModules + // + + hr = pAdminMgr->GetAdminSection( bstrGlobalModules, + bstrAppHostConfigPath, + &pGlobalModulesSection ); + + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pGlobalModulesSection->get_Collection( &pGlobalModulesCollection ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + + hr = DeleteAllElementsFromCollection( pGlobalModulesCollection, + L"name", + szName, + FIND_ELEMENT_CASE_SENSITIVE, + &numDeleted ); + + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( numDeleted == 0 ) + { + DBGWARN(( DBG_CONTEXT, + "Expected to find %S in globalModules list.\n", + szName )); + } + else + { + fChanged = TRUE; + } + } + + if ( fChanged ) + { + hr = pAdminMgr->CommitChanges(); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + +exit: + + SysFreeString( bstrAppHostConfigPath ); + SysFreeString( bstrGlobalModules ); + + return hr; +} + +// +// Local functions +// + +HRESULT +AddModuleToGlobalModules( + IN IAppHostWritableAdminManager * pAdminMgr, + IN CONST WCHAR * szName, + IN CONST WCHAR * szImage, + IN OPTIONAL CONST WCHAR * szPreCondition + ) +{ + HRESULT hr = NOERROR; + + CComPtr pGlobalModulesSection; + CComPtr pGlobalModulesCollection; + CComPtr pNewGlobalModuleElement; + + VARIANT varPropValue; + VariantInit( &varPropValue ); + + BSTR bstrAppHostConfigPath = SysAllocString( L"MACHINE/WEBROOT/APPHOST" ); + BSTR bstrGlobalModules = SysAllocString( L"system.webServer/globalModules" ); + BSTR bstrAdd = SysAllocString( L"add" ); + + if ( !bstrAppHostConfigPath || + !bstrGlobalModules || + !bstrAdd ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto exit; + } + + // + // Get the global modules collection + // + + hr = pAdminMgr->GetAdminSection( bstrGlobalModules, + bstrAppHostConfigPath, + &pGlobalModulesSection ); + + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = pGlobalModulesSection->get_Collection( &pGlobalModulesCollection ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + // + // Create a new module element + // + + hr = pGlobalModulesCollection->CreateNewElement( bstrAdd, + &pNewGlobalModuleElement ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = VariantAssign( &varPropValue, szName ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = SetElementProperty( pNewGlobalModuleElement, + L"name", + &varPropValue ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = VariantAssign( &varPropValue, szImage ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = SetElementProperty( pNewGlobalModuleElement, + L"image", + &varPropValue ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + if ( szPreCondition && *szPreCondition ) + { + hr = VariantAssign( &varPropValue, szPreCondition ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = SetElementProperty( pNewGlobalModuleElement, + L"preCondition", + &varPropValue ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + } + + // + // Add the new element + // + + hr = pGlobalModulesCollection->AddElement( pNewGlobalModuleElement ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + +exit: + + VariantClear( &varPropValue ); + + SysFreeString( bstrAppHostConfigPath ); + SysFreeString( bstrGlobalModules ); + SysFreeString( bstrAdd ); + + return hr; +} + +HRESULT +AddModuleToRootModules( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szName, + IN CONST WCHAR * szPreCondition, + IN OPTIONAL CONST WCHAR * szType + ) +{ + HRESULT hr = NOERROR; + + BOOL found = FALSE; + + CComPtr pLocation; + CComPtr pModulesSection; + CComPtr pModuleCollection; + CComPtr pNewModuleElement; + + VARIANT varPropValue; + VariantInit( &varPropValue ); + + BSTR bstrAdd = SysAllocString( L"add" ); + + if ( !bstrAdd ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = GetLocationFromFile( pAdminMgr, + L"MACHINE/WEBROOT/APPHOST", + L"", + &pLocation, + &found ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( !found ) + { + hr = HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND ); + DBGERROR(( DBG_CONTEXT, + "Failed to find root location path\n" )); + goto exit; + } + + hr = GetSectionFromLocation( pLocation, + L"system.webServer/modules", + &pModulesSection, + &found ); + + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( !found ) + { + hr = HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND ); + DBGERROR(( DBG_CONTEXT, + "Failed to find modules section\n" )); + goto exit; + } + + // + // Create a new module element + // + + hr = pModulesSection->get_Collection( &pModuleCollection ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pModuleCollection->CreateNewElement( bstrAdd, + &pNewModuleElement ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = VariantAssign( &varPropValue, szName ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = SetElementProperty( pNewModuleElement, + L"name", + &varPropValue ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + if ( szPreCondition && *szPreCondition ) + { + hr = VariantAssign( &varPropValue, szPreCondition ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = SetElementProperty( pNewModuleElement, + L"preCondition", + &varPropValue ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + } + + if ( szType && *szType ) + { + hr = VariantAssign( &varPropValue, szType ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + + hr = SetElementProperty( pNewModuleElement, + L"type", + &varPropValue ); + if ( FAILED(hr) ) + { + DBGERROR_HR( hr ); + goto exit; + } + } + + hr = pModuleCollection->AddElement( pNewModuleElement, + -1 ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + SysFreeString( bstrAdd ); + VariantClear( &varPropValue ); + + return hr; +} + +HRESULT +DeleteModuleFromRootModules( + IAppHostAdminManager * pAdminMgr, + CONST WCHAR * szName, + BOOL * pfDeleted + ) +{ + HRESULT hr = NOERROR; + + CComPtr pLocation; + CComPtr pModulesSection; + CComPtr pModulesCollection; + + UINT numDeleted; + BOOL found = FALSE; + + *pfDeleted = FALSE; + + hr = GetLocationFromFile( pAdminMgr, + L"MACHINE/WEBROOT/APPHOST", + L"", + &pLocation, + &found ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( !found ) + { + DBGWARN(( DBG_CONTEXT, + "Failed to find root location path\n" )); + goto exit; + } + + hr = GetSectionFromLocation( pLocation, + L"system.webServer/modules", + &pModulesSection, + &found ); + + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( !found ) + { + DBGWARN(( DBG_CONTEXT, + "Failed to find modules section in root\n" )); + goto exit; + } + + hr = pModulesSection->get_Collection( &pModulesCollection ); + + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = DeleteAllElementsFromCollection( pModulesCollection, + L"name", + szName, + FIND_ELEMENT_CASE_SENSITIVE, + &numDeleted ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( numDeleted == 0 ) + { + DBGWARN(( DBG_CONTEXT, + "Failed to find %S in root modules\n", + szName )); + } + else + { + *pfDeleted = TRUE; + } + +exit: + + return hr; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/mof.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/mof.cpp new file mode 100644 index 0000000000..2f13ab1dfc --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/mof.cpp @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" +#include + +HRESULT +RegisterMofFile( + __in PWSTR pszFileName +) +{ + HRESULT hr = S_OK; + WBEM_COMPILE_STATUS_INFO CompileStatusInfo; + CComPtr pCompiler; + + hr = CoCreateInstance( _uuidof(MofCompiler), + 0, + CLSCTX_INPROC_SERVER, + _uuidof(IMofCompiler), + (LPVOID *) &pCompiler); + if ( FAILED( hr ) ) + { + // + // Register the COM object if is not registered. + // + WCHAR * pszDllPath = new WCHAR[ MAX_PATH ]; + if ( pszDllPath != NULL ) + { + if ( GetSystemDirectory( pszDllPath, MAX_PATH ) != 0 ) + { + HRESULT (STDAPICALLTYPE *pfDllRegisterServer)(VOID); + + (VOID) StringCchCat( pszDllPath, MAX_PATH, L"\\wbem\\mofd.dll" ); + + HINSTANCE hLib = LoadLibraryEx( pszDllPath, + NULL, + LOAD_WITH_ALTERED_SEARCH_PATH ); + if ( hLib != NULL ) + { + pfDllRegisterServer = (HRESULT (STDAPICALLTYPE *)(VOID))GetProcAddress(hLib, "DllRegisterServer"); + if ( pfDllRegisterServer != NULL ) + { + pfDllRegisterServer(); + hr = CoCreateInstance( _uuidof(MofCompiler), + 0, + CLSCTX_INPROC_SERVER, + _uuidof(IMofCompiler), + (LPVOID *) &pCompiler); + } + FreeLibrary( hLib ); + } + } + delete [] pszDllPath; + } + if ( FAILED( hr ) ) + { + goto Finished; + } + } + + hr = pCompiler->CompileFile( pszFileName, + NULL, // namespace + NULL, // username + NULL, // authoroty + NULL, // password + 0, // option flags + 0, // class flags + 0, // instance + &CompileStatusInfo ); + if ( hr != S_OK ) + { + // + // Means failure. + // + goto Finished; + } + +Finished: + + return hr; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/msiutil.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/msiutil.cpp new file mode 100644 index 0000000000..2a9b65ab37 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/msiutil.cpp @@ -0,0 +1,581 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +HRESULT +MsiUtilGetProperty( + IN MSIHANDLE hInstall, + __in PCWSTR szName, + __inout STRU * pstrProperty + ) +{ + HRESULT hr = NOERROR; + DWORD cch = 0; + WCHAR dummy = L'\0'; + DWORD status; + + pstrProperty->Reset(); + + // + // Get the length. + // + + status = MsiGetPropertyW( hInstall, + szName, + &dummy, + &cch ); + + if( status != ERROR_MORE_DATA ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + // + // Return is count of characters w/o NULL + // + + cch++; + + hr = pstrProperty->Resize( cch ); + if( FAILED( hr ) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiGetPropertyW( hInstall, + szName, + pstrProperty->QueryStr(), + &cch ); + + if( status != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + pstrProperty->SyncWithBuffer(); + +exit: + + return hr; +} + + +HRESULT +MsiUtilScheduleDeferredAction( + IN MSIHANDLE hInstall, + __in PCWSTR szAction, + __in PCWSTR szData + ) +{ + HRESULT hr = NOERROR; + UINT status; + + status = MsiSetPropertyW( hInstall, + szAction, + szData ); + if( status != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + status = MsiDoActionW( hInstall, + szAction ); + + if( status != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32(status ); + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return hr; +} + +HRESULT +MsiUtilRecordGetInteger( + IN MSIHANDLE hRecord, + IN UINT field, + __inout UINT * pInt + ) +{ + HRESULT hr = NOERROR; + UINT tempValue = 0; + + _ASSERTE(pInt); + + tempValue = MsiRecordGetInteger(hRecord, field); + + if( MSI_NULL_INTEGER == tempValue ) + { + hr = E_UNEXPECTED; + DBGERROR(( DBG_CONTEXT, "Non-integer value encountered in Integer field, %08x\n", hr )); + goto exit; + } + + *pInt = tempValue; + +exit: + return hr; +} + +HRESULT +MsiUtilRecordGetString( + IN MSIHANDLE hRecord, + IN UINT field, + __inout STRU * pstr + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + + DWORD cch = pstr->QuerySizeCCH(); + + status = MsiRecordGetStringW( hRecord, + field, + pstr->QueryStr(), + &cch ); + + if( ERROR_MORE_DATA == status ) + { + hr = pstr->Resize( ++cch ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiRecordGetStringW( hRecord, + field, + pstr->QueryStr(), + &cch ); + } + + if( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + hr = pstr->SetLen( cch ); + if( FAILED(hr) ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return hr; +} + +HRESULT +MsiUtilRecordReadStreamIntoFile( + IN MSIHANDLE hRecord, + IN UINT field, + IN PCWSTR szFileName + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + HANDLE hOutputFile = INVALID_HANDLE_VALUE; + + _ASSERTE(szFileName); + + hOutputFile = CreateFileW( szFileName, + GENERIC_WRITE, + 0, + NULL, + CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, + NULL); + if ( INVALID_HANDLE_VALUE == hOutputFile ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + goto exit; + } + + do + { + DWORD bytesWritten = 0; + BOOL fRet = FALSE; + CHAR szBuffer[4096]; + DWORD cbBuf = sizeof(szBuffer); + + status = MsiRecordReadStream(hRecord, field, szBuffer, &cbBuf); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + else if ( 0 == cbBuf ) + { + //we've reached the end of the stream + break; + } + + fRet = WriteFile(hOutputFile, szBuffer, cbBuf, &bytesWritten, NULL); + if( !fRet ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + } while (1); + + +exit: + + if( INVALID_HANDLE_VALUE != hOutputFile) + { + CloseHandle( hOutputFile ); + hOutputFile = INVALID_HANDLE_VALUE; + } + + return hr; +} + +HRESULT +MsiUtilFormatString( + IN MSIHANDLE hInstall, + __inout STRU * pstrData + ) +{ + HRESULT hr = NOERROR; + UINT status = ERROR_SUCCESS; + MSIHANDLE hRecord = NULL; + + hRecord = MsiCreateRecord( 1 ); + if( !hRecord ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto exit; + } + + status = MsiRecordSetStringW( hRecord, + 0, + pstrData->QueryStr() ); + if( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + DWORD cch = pstrData->QuerySizeCCH(); + + status = MsiFormatRecordW( hInstall, + hRecord, + pstrData->QueryStr(), + &cch ); + if( ERROR_MORE_DATA == status ) + { + hr = pstrData->Resize( ++cch ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + status = MsiFormatRecordW( hInstall, + hRecord, + pstrData->QueryStr(), + &cch ); + } + + if( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32(status); + DBGERROR_HR(hr); + goto exit; + } + + hr = pstrData->SetLen( cch ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + if( hRecord ) + { + MsiCloseHandle( hRecord ); + hRecord = NULL; + } + + return hr; +} + +WCHAR CA_DATA_DELIM[] = { '^', 0 }; + +// +// BUGBUG - Prefix will barf on this +// Can I really trust this data hasn't been tampered with? +// +WCHAR * +CA_DATA_READER::ExtractString() +{ + if( !_current || *_current == 0 ) + { + return NULL; + } + + // + // String format is: + // (len - delim - data - delim) (xN) \0 + // "3^cat^4^fish^\0" + // + + // + // extract length of data + // + + WCHAR * psz = wcsstr( _current, CA_DATA_DELIM ); + + _ASSERTE( psz ); + if( psz ) + { + *psz = 0; + INT cch = wcstol( _current, NULL, 0 ); + + // + // advance to data + // + + psz++; + + // + // terminate and advance to next block + // + + _current = psz + cch; + *_current = 0; + + _current++; + } + + return psz; +} + +HRESULT +CA_DATA_WRITER::WriteInternal( + CONST WCHAR * sz, + INT n +) +{ + HRESULT hr = NOERROR; + + // + // Write out the data length + // + + WCHAR buffer[20]; + StringCchPrintfW( buffer, sizeof(buffer)/sizeof(buffer[0]), L"%d", n ); + + hr = _data.Append( buffer ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = _data.Append( CA_DATA_DELIM ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Write out the data + // + + hr = _data.Append( sz ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = _data.Append( CA_DATA_DELIM ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + return hr; +} + + + +BOOL +MsiUtilIsInstalling( + INSTALLSTATE isInstalled, + INSTALLSTATE isAction + ) +{ + return (INSTALLSTATE_LOCAL == isAction || + INSTALLSTATE_SOURCE == isAction || + (INSTALLSTATE_DEFAULT == isAction && + (INSTALLSTATE_LOCAL == isInstalled || + INSTALLSTATE_SOURCE == isInstalled))); +} + + +BOOL +MsiUtilIsReInstalling( + INSTALLSTATE isInstalled, + INSTALLSTATE isAction + ) +{ + return ((INSTALLSTATE_LOCAL == isAction || + INSTALLSTATE_SOURCE == isAction || + INSTALLSTATE_DEFAULT == isAction || + INSTALLSTATE_UNKNOWN == isAction) && + (INSTALLSTATE_LOCAL == isInstalled || + INSTALLSTATE_SOURCE == isInstalled)); +} + + +BOOL +MsiUtilIsUnInstalling( + INSTALLSTATE isInstalled, + INSTALLSTATE isAction + ) +{ + return ((INSTALLSTATE_ABSENT == isAction || + INSTALLSTATE_REMOVED == isAction) && + (INSTALLSTATE_LOCAL == isInstalled || + INSTALLSTATE_SOURCE == isInstalled)); +} + +HRESULT +GenerateTempFileName( + __in PCWSTR szPrefix, + __in PCWSTR szExtension, + __inout STRU * pstr +) +{ + HRESULT hr = NOERROR; + UINT status = 0; + STACK_STRU( guidName, 128 ); + GUID guid = {0}; + DWORD cch = 0; + + _ASSERTE(szPrefix); + _ASSERTE(szExtension); + _ASSERTE(pstr); + + cch = pstr->QuerySizeCCH(); + + status = GetTempPathW(cch, pstr->QueryStr()); + if ( status > cch) + { + cch = status; + hr = pstr->Resize( ++cch ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error resizing buffer, hr=0x%x", hr); + goto exit; + } + + status = GetTempPathW(cch, pstr->QueryStr()); + } + + if ( 0 == status ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting temp path, hr=0x%x", hr); + goto exit; + } + + pstr->SyncWithBuffer(); + + hr = pstr->Append(L"\\"); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error apppending \\, hr=0x%x", hr); + goto exit; + } + + hr = pstr->Append(szPrefix); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error appending file prefix, hr=0x%x", hr); + goto exit; + } + + cch = guidName.QuerySizeCCH(); + hr = CoCreateGuid ( &guid ); + if ( FAILED (hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error generating the GUID, hr=0x%x", hr); + goto exit; + } + + if ( !StringFromGUID2( guid, guidName.QueryStr(), cch ) ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error getting string from GUID, hr=0x%x", hr); + goto exit; + } + + guidName.SyncWithBuffer(); + + hr = pstr->Append(guidName.QueryStr()); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error appending GUID, hr=0x%x", hr); + goto exit; + } + + hr = pstr->Append(L"."); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error appending ., hr=0x%x", hr); + goto exit; + } + + hr = pstr->Append(szExtension); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + IISLogWrite(SETUP_LOG_SEVERITY_ERROR, L"Error appending extension, hr=0x%x", hr); + goto exit; + } + +exit: + if ( FAILED(hr) ) + { + IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Error in function %s, hr=0x%x", UNITEXT(__FUNCTION__), hr); + } + return hr; +} \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/msiutil.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/msiutil.h new file mode 100644 index 0000000000..e7c770c534 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/msiutil.h @@ -0,0 +1,192 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +HRESULT +MsiUtilGetProperty( + IN MSIHANDLE hInstall, + __in PCWSTR szName, + __inout STRU * pstrProperty + ); + +HRESULT +MsiUtilScheduleDeferredAction( + IN MSIHANDLE hInstall, + __in PCWSTR szAction, + __in PCWSTR szData + ); + +HRESULT +MsiUtilRecordGetInteger( + IN MSIHANDLE hRecord, + IN UINT field, + __inout UINT * pInt + ); + +HRESULT +MsiUtilRecordGetString( + IN MSIHANDLE hRecord, + IN UINT field, + __inout STRU * pstr + ); + +HRESULT +MsiUtilRecordReadStreamIntoFile( + IN MSIHANDLE hRecord, + IN UINT field, + IN PCWSTR szFileName + ); + +HRESULT +MsiUtilFormatString( + IN MSIHANDLE hInstall, + __inout STRU * pstrData + ); + +class CA_DATA_WRITER +{ +public: + + CA_DATA_WRITER() + { + } + + HRESULT + Write( + CONST WCHAR * sz + ) + { + return WriteInternal( sz, (INT)wcslen(sz) ); + } + + HRESULT + Write( + CONST WCHAR * sz, + INT cch + ) + { + return WriteInternal( sz, cch ); + } + + HRESULT + Write( + INT n + ) + { + HRESULT hr; + + WCHAR buffer[20]; + hr = StringCchPrintfW( buffer, + sizeof(buffer)/sizeof(buffer[0]), + L"%d", + n ); + if( FAILED(hr) ) + { + return hr; + } + + return WriteInternal( buffer, (INT)wcslen(buffer) ); + } + + CONST WCHAR * + QueryData() const + { + return _data.QueryStr(); + } + +protected: + + HRESULT + WriteInternal( + CONST WCHAR * sz, + INT n + ); + + STRU _data; +}; + +class CA_DATA_READER +{ +public: + + CA_DATA_READER() : + _current( NULL ) + { + } + + ~CA_DATA_READER() + { + } + + HRESULT + LoadDeferredCAData( + MSIHANDLE hInstall + ) + { + HRESULT hr = MsiUtilGetProperty( hInstall, L"CustomActionData", &_strCustomActionData ); + _current = _strCustomActionData.QueryStr(); + return hr; + } + + HRESULT + Read( + __deref_out_z WCHAR ** psz + ) + { + *psz = ExtractString(); + if( !*psz ) + { + return HRESULT_FROM_WIN32( ERROR_NO_MORE_ITEMS ); + } + return S_OK; + } + + HRESULT + Read( + INT * pi + ) + { + CONST WCHAR * sz = ExtractString(); + if( !sz ) + { + return HRESULT_FROM_WIN32( ERROR_NO_MORE_ITEMS ); + } + *pi = wcstol( sz, NULL, 10 ); + return S_OK; + } + +private: + + WCHAR * + ExtractString(); + + STRU _strCustomActionData; + WCHAR * _current; +}; + + +BOOL +MsiUtilIsReInstalling( + INSTALLSTATE isInstalled, + INSTALLSTATE isAction + ); + +BOOL +MsiUtilIsInstalling( + INSTALLSTATE isInstalled, + INSTALLSTATE isAction + ); + +BOOL +MsiUtilIsUnInstalling( + INSTALLSTATE isInstalled, + INSTALLSTATE isAction + ); + +HRESULT +GenerateTempFileName( + __in PCWSTR szPrefix, + __in PCWSTR szExtension, + __inout STRU * pstr +); \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/packages.config b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/packages.config new file mode 100644 index 0000000000..21d9344493 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/packages.config @@ -0,0 +1,4 @@ + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/precomp.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/precomp.h new file mode 100644 index 0000000000..5f32044523 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/precomp.h @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +// Don't throw exceptions for CComVariant failures. +// Check for VT_ERROR instead. +#define _ATL_NO_VARIANT_THROW +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include +#pragma warning( disable:4127 ) +#include +#include "dbgutil.h" +#include +#define IRTL_DLLEXP +#include +#include +#include +#include +#include +#include +#include + +// +// Security APIs. +// +#include +#include +#include +#include + + +#include "ahutil.h" +#include "msiutil.h" +#include "defaults.h" +#include "cgi_restrictions.h" +#include "handlers.h" +#include "tracing.h" +#include "config_custom.h" +#include "setup_log.h" +#include "httpapi.h" +#include "secutils.h" +#include "ConfigShared.h" +#include "iisca.h" +#include "iiscaexp.h" +extern HINSTANCE g_hinst; + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/schema.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/schema.cpp new file mode 100644 index 0000000000..fe39b356f0 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/schema.cpp @@ -0,0 +1,741 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +HRESULT +GetChildSectionGroup( + IN IAppHostSectionGroup * pParentSectionGroup, + IN CONST WCHAR * szChildGroupName, + OUT IAppHostSectionGroup ** ppChildSectionGroup + ) +{ + HRESULT hr = NOERROR; + + CComPtr pChildSectionGroup; + + VARIANT varChildGroupName; + VariantInit( &varChildGroupName ); + + *ppChildSectionGroup = NULL; + + hr = VariantAssign( &varChildGroupName, + szChildGroupName ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pParentSectionGroup->get_Item( varChildGroupName, + &pChildSectionGroup ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + *ppChildSectionGroup = pChildSectionGroup.Detach(); + +exit: + + VariantClear( &varChildGroupName ); + + return hr; +} + +HRESULT +GetRootSectionGroup( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szConfigPath, + OUT IAppHostSectionGroup ** ppRootSectionGroup + ) +{ + HRESULT hr = NOERROR; + + CComPtr pRootSectionGroup; + CComPtr pConfigMgr; + CComPtr pConfigFile; + + BSTR bstrConfigPath = NULL; + + *ppRootSectionGroup = NULL; + + bstrConfigPath = SysAllocString( szConfigPath ); + + if( !bstrConfigPath ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->get_ConfigManager( &pConfigMgr ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pConfigMgr->GetConfigFile( bstrConfigPath, + &pConfigFile ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pConfigFile->get_RootSectionGroup( &pRootSectionGroup ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + *ppRootSectionGroup = pRootSectionGroup.Detach(); + +exit: + + SysFreeString( bstrConfigPath ); + + return hr; +} + +HRESULT +InitializeAdminManager( + IN CONST BOOL isSectionInAdminSchema, + IN IAppHostWritableAdminManager * pAdminMgr, + OUT CONST WCHAR ** pszCommitPath +) +{ + HRESULT hr = NOERROR; + CONST WCHAR * szAdminCommitPath = L"MACHINE/WEBROOT"; + CONST WCHAR * szAppHostCommitPath = L"MACHINE/WEBROOT/APPHOST"; + + CONST WCHAR * szCommitPath = NULL; + + *pszCommitPath = NULL; + + if(isSectionInAdminSchema) + { + szCommitPath = szAdminCommitPath; + hr = InitAdminMgrForAdminConfig( pAdminMgr, + szCommitPath ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + else + { + szCommitPath = szAppHostCommitPath; + } + + *pszCommitPath = szCommitPath; + +exit: + return hr; +} + +HRESULT +RegisterSectionSchema( + IN CONST BOOL isSectionInAdminSchema, + IN CONST WCHAR * szSectionName, + IN CONST WCHAR * szOverrideModeDefault, + IN OPTIONAL CONST WCHAR * szAllowDefinition, + IN OPTIONAL CONST WCHAR * szType + ) +{ + HRESULT hr = NOERROR; + + CComPtr pAdminMgr; + CComPtr pRootSectionGroup; + CComPtr pParentSectionGroup; + CComPtr pChildSectionGroup; + CComPtr pSections; + CComPtr pNewSection; + + + BSTR bstrSectionGroupName = NULL; + BSTR bstrSectionName = NULL; + BSTR bstrOverrideModeDefault = NULL; + BSTR bstrAllowDefinition = NULL; + BSTR bstrType = NULL; + + CONST WCHAR * szCommitPath = NULL; + + WCHAR * szSectionNameCopy = _wcsdup( szSectionName ); + if( !szSectionNameCopy ) + { + hr = E_OUTOFMEMORY; + goto exit; + } + szSectionName = NULL; + + // + // szSectionNameCopy is the full name of the section. The last + // segment szShortName will be registered as the name of the + // section and the other segments are section groups + // + // eg. "system.webServer/foo/bar/mysection" + // + + WCHAR * szShortName = wcsrchr( szSectionNameCopy, L'/' ); + if( szShortName == NULL ) + { + szShortName = szSectionNameCopy; + } + else + { + *szShortName++ = L'\0'; + } + + hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( IAppHostWritableAdminManager ), + (VOID **)&pAdminMgr ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = InitializeAdminManager( isSectionInAdminSchema, + pAdminMgr, + &szCommitPath); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = GetRootSectionGroup( pAdminMgr, + szCommitPath, + &pRootSectionGroup); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // For each section group referenced in szSectionNameCopy retrieve or + // create it. + // + + WCHAR * pszGroupName = szSectionNameCopy; + WCHAR * pszNext = NULL; + + pParentSectionGroup = pRootSectionGroup; + + if (szShortName == szSectionNameCopy) + { + goto SkipAddingGroups; + } + + while( pszGroupName ) + { + pszNext = wcschr( pszGroupName, L'/' ); + if( pszNext ) + { + *pszNext++ = 0; + } + + hr = GetChildSectionGroup( pParentSectionGroup, + pszGroupName, + &pChildSectionGroup ); + + if( hr == HRESULT_FROM_WIN32( ERROR_INVALID_INDEX ) ) + { + // + // Create the group if it does not exist + // + bstrSectionGroupName = SysAllocString( pszGroupName ); + if( !bstrSectionGroupName ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pParentSectionGroup->AddSectionGroup( bstrSectionGroupName, + &pChildSectionGroup ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + else if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + pParentSectionGroup = pChildSectionGroup; + pChildSectionGroup.Release(); + + SysFreeString( bstrSectionGroupName ); + bstrSectionGroupName = NULL; + + pszGroupName = pszNext; + } + + SkipAddingGroups: + // + // Add the new section + // + + hr = pParentSectionGroup->get_Sections( &pSections ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + bstrSectionName = SysAllocString( szShortName ); + if( !bstrSectionName ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pSections->AddSection( bstrSectionName, + &pNewSection ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + bstrOverrideModeDefault = SysAllocString( szOverrideModeDefault ); + if( !bstrOverrideModeDefault ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pNewSection->put_OverrideModeDefault( bstrOverrideModeDefault ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if( szAllowDefinition && *szAllowDefinition ) + { + bstrAllowDefinition = SysAllocString( szAllowDefinition ); + if( !bstrAllowDefinition ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pNewSection->put_AllowDefinition( bstrAllowDefinition ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if( szType && *szType ) + { + bstrType = SysAllocString( szType ); + if( !bstrType ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pNewSection->put_Type( bstrType ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + // + // Persist changes + // + + hr = pAdminMgr->CommitChanges(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + SysFreeString( bstrSectionGroupName ); + SysFreeString( bstrSectionName ); + SysFreeString( bstrOverrideModeDefault ); + SysFreeString( bstrType ); + SysFreeString( bstrAllowDefinition ); + + free( szSectionNameCopy ); + + return hr; +} + +HRESULT +RemoveSectionDefinition( + IN IAppHostSectionGroup * pParentSection, + __in_z WCHAR * szSectionPath, + __in_z WCHAR * szSectionName + ) +{ + HRESULT hr = NOERROR; + + CComPtr pChildSectionGroup; + CComPtr pSections; + + WCHAR * pszNextPath = NULL; + + VARIANT varIndex; + VariantInit( &varIndex ); + + // + // If there are no more path segments, remove the section + // + + if( !szSectionPath ) + { + hr = pParentSection->get_Sections( &pSections ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = VariantAssign( &varIndex, szSectionName ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pSections->DeleteSection( varIndex ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // End recursion + goto exit; + } + + // + // We have more path segments, so move to the next segment + // and call RemoveSectionDefinition recursively + // + + pszNextPath = wcschr( szSectionPath, L'/' ); + if( pszNextPath ) + { + *pszNextPath++ = 0; + } + + hr = GetChildSectionGroup( pParentSection, + szSectionPath, + &pChildSectionGroup ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = RemoveSectionDefinition( pChildSectionGroup, + pszNextPath, + szSectionName ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // The section has been removed, check to see if the + // child section group is empty and clean up if it is. + // + + ULONG childCount = 0; + hr = pChildSectionGroup->get_Count( &childCount ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if( childCount == 0 ) + { + hr = pChildSectionGroup->get_Sections( &pSections ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pSections->get_Count( &childCount ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if( childCount == 0 ) + { + hr = VariantAssign( &varIndex, szSectionPath ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pParentSection->DeleteSectionGroup( varIndex ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + } + } + +exit: + + VariantClear( &varIndex ); + + return hr; +} + +HRESULT +RemoveSectionData( + IN IAppHostAdminManager * pAdminMgr, + IN CONST WCHAR * szSectionName, + IN CONST WCHAR * szConfigPath + ) +{ + HRESULT hr = NOERROR; + + CComPtr pSectionElement; + CComPtr pConfigMgr; + CComPtr pConfigFile; + CComPtr pLocations; + CComPtr pLocation; + + BSTR bstrSectionName = SysAllocString( szSectionName ); + BSTR bstrPath = SysAllocString( szConfigPath ); + + VARIANT varSectionName; + VariantInit( &varSectionName ); + + if( !bstrSectionName || + !bstrPath ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = VariantAssign( &varSectionName, szSectionName ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->GetAdminSection( bstrSectionName, + bstrPath, + &pSectionElement ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pSectionElement->Clear(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Go through the location tags and delete the section + // + + hr = pAdminMgr->get_ConfigManager( &pConfigMgr ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pConfigMgr->GetConfigFile( bstrPath, + &pConfigFile ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pConfigFile->get_Locations( &pLocations ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + DWORD count; + VARIANT varIndex; + VariantInit( &varIndex ); + + hr = pLocations->get_Count( &count ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + for( DWORD i = 0; i < count; i++ ) + { + varIndex.vt = VT_UI4; + varIndex.ulVal = i; + + hr = pLocations->get_Item( varIndex, &pLocation ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pLocation->DeleteConfigSection( varSectionName ); + if( HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) == hr ) + { + hr = S_OK; + } + else if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + pLocation.Release(); + } + +exit: + + SysFreeString( bstrSectionName ); + SysFreeString( bstrPath ); + + return hr; +} + +HRESULT +UnRegisterSectionSchema( + IN CONST BOOL isSectionInAdminSchema, + IN CONST WCHAR * szSectionName + ) +{ + HRESULT hr = NOERROR; + + CComPtr pAdminMgr; + CComPtr pRootSectionGroup; + + CONST WCHAR * szCommitPath = NULL; + + WCHAR * szSectionNameCopy = _wcsdup( szSectionName ); + if( !szSectionNameCopy ) + { + hr = E_OUTOFMEMORY; + goto exit; + } + + // + // szSectionNameCopy is the full name of the section. The last + // segment szShortName will be registered as the name of the + // section and the other segments are section groups + // + // eg. "system.webServer/foo/bar/mysection" + // + + WCHAR * szShortName = wcsrchr( szSectionNameCopy, L'/' ); + if( szShortName == NULL ) + { + szShortName = szSectionNameCopy; + } + else + { + *szShortName++ = 0; + } + + hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( IAppHostWritableAdminManager ), + (VOID **)&pAdminMgr ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = InitializeAdminManager( isSectionInAdminSchema, + pAdminMgr, + &szCommitPath); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = RemoveSectionData( pAdminMgr, + szSectionName, + szCommitPath); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = GetRootSectionGroup( pAdminMgr, + szCommitPath, + &pRootSectionGroup ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = RemoveSectionDefinition( pRootSectionGroup, + (szShortName == szSectionNameCopy) ? NULL : szSectionNameCopy, + szShortName ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->CommitChanges(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + free( szSectionNameCopy ); + + return hr; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/secutils.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/secutils.cpp new file mode 100644 index 0000000000..8806cd667e --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/secutils.cpp @@ -0,0 +1,1125 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +#ifndef NT_SUCCESS +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif + +#ifndef STATUS_SOME_NOT_MAPPED +// +// MessageId: STATUS_SOME_NOT_MAPPED +// +// MessageText: +// +// Some of the information to be translated has not been translated. +// +#define STATUS_SOME_NOT_MAPPED ((NTSTATUS)0x00000107L) +#endif + +#ifndef STATUS_NONE_MAPPED +#define STATUS_NONE_MAPPED ((NTSTATUS)0xc0000073L) +#endif + + +HRESULT +IsVistaOrGreater( + __out BOOL & fIsVistaOrGreater +) +/*++ + +Routine Description: + + Return TRUE if we are running in a Server SKU, + otherwise return FALSE. + +Arguments: + + pfIsServer - The return value. + +Return Value: + + BOOL + +--*/ +{ + HRESULT hr = S_OK; + OSVERSIONINFOEX osVersionInfoEx = { 0 }; + DWORDLONG dwlConditionMask = 0; + BOOL fReturn = FALSE; + + fIsVistaOrGreater = FALSE; + osVersionInfoEx.dwOSVersionInfoSize = sizeof( osVersionInfoEx ); + osVersionInfoEx.dwMajorVersion = 6; + + VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL ); + + fReturn = VerifyVersionInfo( + &osVersionInfoEx, + VER_MAJORVERSION, + dwlConditionMask ); + + // + // If the function fails, the return value is zero + // and GetLastError returns an error code other than ERROR_OLD_WIN_VERSION + // + if ( fReturn == FALSE && GetLastError() != ERROR_OLD_WIN_VERSION ) + { + hr = HRESULT_FROM_WIN32 ( GetLastError() ); + DBGERROR_HR( hr ); + goto Finished; + } + + fIsVistaOrGreater = ( fReturn ); + +Finished: + + return hr; + +} + +HRESULT +CreateDirectory( + __in LPCWSTR pszFileName +) +{ + HRESULT hr = S_OK; + DWORD dwFileAttributes = 0; + + dwFileAttributes = GetFileAttributes( pszFileName ); + if ( dwFileAttributes == INVALID_FILE_ATTRIBUTES ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + + if ( hr == HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) || + hr == HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND ) ) + { + hr = S_OK; + + // + // Create the folder. + // + if ( !CreateDirectory( pszFileName, NULL ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR( hr ); + goto Finished; + } + } + else + { + DBGERROR_HR( hr ); + } + } + +Finished: + + return hr; +} + +HRESULT +AddExplicitAccessToFileDacl( + __in LPWSTR pszFilePath, + DWORD cExplicitAccess, + EXPLICIT_ACCESS rgExplicitAccess[] +) +/*++ + +Routine Description: + + Add EXPLICIT_ACCESS entries to a file DACL + +Arguments: + + pszFilePath - The path to the file where the DACL will be modified + cExplicitAccess - The count of EXPLICIT_ACCESS entires to add + rgExplicitAccess - The EXPLICIT_ACCESS entries + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + DWORD dwError = ERROR_SUCCESS; + PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; + PACL pOldFileDacl = NULL; + PACL pNewFileDacl = NULL; + + if ( pszFilePath == NULL || + cExplicitAccess == 0 || + rgExplicitAccess == NULL ) + { + hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + goto Finished; + } + + // + // Get the current file DACL + // + dwError = GetNamedSecurityInfo( pszFilePath, + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION, + NULL, // ppsidOwner + NULL, // ppsidGroup + &pOldFileDacl, + NULL, // ppSacl + &pSecurityDescriptor ); + if ( dwError != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32( dwError ); + goto Finished; + } + + // + // Create a new DACL with the EXPLICIT_ACCESS entries + // + + dwError = SetEntriesInAcl( cExplicitAccess, + rgExplicitAccess, + pOldFileDacl, + &pNewFileDacl ); + if ( dwError != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32( dwError ); + goto Finished; + } + + // + // Write the new DACL + // + + dwError = SetNamedSecurityInfo( pszFilePath, + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION, + NULL, // psidOwner + NULL, // psidGroup + pNewFileDacl, + NULL ); // pSacl + if ( dwError != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32( dwError ); + goto Finished; + } + +Finished: + + if ( pNewFileDacl != NULL ) + { + LocalFree( pNewFileDacl ); + pNewFileDacl = NULL; + } + + if ( pSecurityDescriptor != NULL ) + { + LocalFree( pSecurityDescriptor ); + pSecurityDescriptor = NULL; + } + + return hr; +} + +HRESULT +GrantFileAccessToIisIusrs( + __in LPWSTR pszFilePath, + DWORD dwAccessMask, + DWORD dwInheritance +) +/*++ + +Routine Description: + + This method gives the IIS_IUSRS group access to a specified file + path. In the case that this is executed on a domain controller, + this method will grant access explicitly to Local Service and + Network Service instead. + +Arguments: + + pszFilePath - The path where access is granted + dwAccessMask - Desired access to grant + dwInhertiance - Inheritance for access mask + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + DWORD cExplicitAccess = 1; + PSID pSidUserAccount = NULL; + DWORD cbUserAccount = 0; + EXPLICIT_ACCESS rgExplicitAccess[ 1 ]; + + if ( pszFilePath == NULL ) + { + hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + goto Finished; + } + + // Zero out the struct + ZeroMemory( &(rgExplicitAccess[0]), sizeof( EXPLICIT_ACCESS ) ); + + // Get the SID for IIS_IUSRS + if ( CreateWellKnownSid( WinBuiltinIUsersSid, + NULL, // DomainSid + pSidUserAccount, + &cbUserAccount ) ) + { + // + // We are expecing a FALSE return value since we + // are obtaining required buffer sizes. + // + hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + goto Finished; + } + + hr = HRESULT_FROM_WIN32( GetLastError() ); + if ( hr != HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) ) + { + goto Finished; + } + hr = S_OK; + + pSidUserAccount = (PSID) LocalAlloc( LPTR, cbUserAccount ); + if ( pSidUserAccount == NULL ) + { + hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY ); + goto Finished; + } + + if ( !CreateWellKnownSid( WinBuiltinIUsersSid, + NULL, // DomainSid + pSidUserAccount, + &cbUserAccount ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + goto Finished; + } + + // Build TRUSTEE with the IIS_IUSRS SID + BuildTrusteeWithSid( &(rgExplicitAccess[0].Trustee), pSidUserAccount ); + rgExplicitAccess[0].grfAccessPermissions = dwAccessMask; + rgExplicitAccess[0].grfAccessMode = GRANT_ACCESS; + rgExplicitAccess[0].grfInheritance = dwInheritance; + + // Add access to file DACL + hr = AddExplicitAccessToFileDacl( pszFilePath, + cExplicitAccess, + rgExplicitAccess ); + if ( FAILED( hr ) ) + { + goto Finished; + } + +Finished: + + return hr; +} + +HRESULT +GetStringSddlFromFile( + __in LPWSTR pszFileName, + __out STRU & strFileSddl, + __in BOOL fCreateIfDoesNotExist +) +/*++ + +Routine Description: + + Returns the DACL in the format SDDL for the + specified file or directory. + +Arguments: + + pszFileName - The file or directory path from to get the DACL. + strFileSddl - The file's security descriptor as string. + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + DWORD dwResult = ERROR_SUCCESS; + PACL pFileObjectAcl = NULL; + PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; + LPWSTR pszSddl = NULL; + ULONG cchSddlLen = 0; + + if ( fCreateIfDoesNotExist ) + { + hr = CreateDirectory( pszFileName ); + if ( FAILED( hr ) ) + { + DBGERROR_HR( hr ); + goto Finished; + } + } + + dwResult = GetNamedSecurityInfo( + pszFileName, + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION, + NULL, + NULL, + &pFileObjectAcl, + NULL, + &pSecurityDescriptor ); + if ( dwResult != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32( dwResult ); + DBGERROR_HR( hr ); + goto Finished; + } + + if ( ! ConvertSecurityDescriptorToStringSecurityDescriptor( + pSecurityDescriptor, + SDDL_REVISION_1, + DACL_SECURITY_INFORMATION, + &pszSddl, + &cchSddlLen ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR( hr ); + goto Finished; + } + + hr = strFileSddl.Copy( pszSddl ); + if ( FAILED( hr ) ) + { + goto Finished; + } + +Finished: + + if ( pSecurityDescriptor != NULL ) + { + LocalFree( pSecurityDescriptor ); + pSecurityDescriptor = NULL; + } + + if ( pszSddl != NULL ) + { + LocalFree( pszSddl ); + pszSddl = NULL; + } + + return hr; +} + +VOID +FreeStringSids( + __in DWORD cStringSids, + __in_bcount(cStringSids) LPWSTR rgszStringSids[] +) +/*++ + +Routine Description: + + Frees the memory allocated by ConvertAccountNamesToStringSids. + +Arguments: + + cStringSids - The number of string in the array rgszStringSids. + rgszStringSids - An array of SIDs represented as string. + +Return Value: + + HRESULT + +--*/ +{ + if ( rgszStringSids == NULL ) + { + return; + } + + for ( DWORD dwIndex = 0; dwIndex < cStringSids; dwIndex ++ ) + { + LocalFree( rgszStringSids [ dwIndex ] ); + } + + LocalFree ( rgszStringSids ); +} + +HRESULT +ConvertAccountNamesToStringSids ( + __in DWORD dwNameCount, + __in_ecount(dwNameCount) LPWSTR rgszNames[], + __deref_out_ecount(*pcStringSids) LPWSTR** StringSids, + __out DWORD* pcStringSids +) +/*++ + +Routine Description: + + Converts a list of local users or groups to string SIDs. + The StringSids array must be freed via the FreeStringSids function + +Arguments: + + dwNameCount - Number of names to convert. + + rgszNames - Array of pointers to Domain\Member strings + + StringSids - Returns a pointer to an array of pointers to String SIDs. + The array should be freed via FreeStringSids. + + pcStringSids - The number of String SIDs translated. + +Return Value: + + HRESULT + +--*/ +{ + HRESULT hr = S_OK; + NTSTATUS ntStatus = ERROR_SUCCESS; + LSA_HANDLE hPolicy = NULL; + LSA_OBJECT_ATTRIBUTES ObjectAttributes = {0}; + PUNICODE_STRING pUnicodeNames = NULL; + PLSA_REFERENCED_DOMAIN_LIST pReferencedDomainList = NULL; + PLSA_TRANSLATED_SID2 pTranslatedSid = NULL; + SIZE_T cchLength = 0; + LPWSTR * rgszStringSids = NULL; + DWORD cStringSids = 0; + DWORD dwStringIndex = 0; + + HMODULE hModule = NULL; + + typedef NTSTATUS + (NTAPI * PFN_LSALOOKUPNAMES2) ( + __in LSA_HANDLE PolicyHandle, + __in ULONG Flags, // Reserved + __in ULONG Count, + __in PLSA_UNICODE_STRING Names, + __out PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, + __out PLSA_TRANSLATED_SID2 *Sids + ); + + PFN_LSALOOKUPNAMES2 pfn = NULL; + + hModule = LoadLibrary( L"Advapi32.dll" ); + if ( hModule == NULL ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR( hr ); + goto Finished; + } + + pfn = ( PFN_LSALOOKUPNAMES2 ) GetProcAddress( hModule, "LsaLookupNames2" ); + if ( pfn == NULL ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR( hr ); + if ( hr == HRESULT_FROM_WIN32( ERROR_PROC_NOT_FOUND ) ) + { + // + // This must be an OS before Windows 2003. + // + hr = S_OK; + } + goto Finished; + } + + // + // Open the local LSA database + // + ntStatus = LsaOpenPolicy( NULL, // Open the local policy + &ObjectAttributes, + POLICY_LOOKUP_NAMES, + &hPolicy ) ; + + if ( !NT_SUCCESS( ntStatus ) ) + { + hr = HRESULT_FROM_NT( ntStatus ); + DBGERROR_HR( hr ); + goto Finished; + } + + // + // Convert the names to unicode strings + // + pUnicodeNames = (PUNICODE_STRING) LocalAlloc( + LMEM_FIXED, + sizeof(UNICODE_STRING) * dwNameCount ); + + if ( pUnicodeNames == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto Finished; + } + + for ( DWORD dwIndex = 0; dwIndex < dwNameCount; dwIndex++ ) + { + cchLength = wcslen( rgszNames[dwIndex] ) * sizeof( *rgszNames[dwIndex] ); + if ( ( cchLength + sizeof( UNICODE_NULL ) ) > USHRT_MAX ) + { + hr = HRESULT_FROM_WIN32 ( ERROR_ARITHMETIC_OVERFLOW ); + goto Finished; + } + + pUnicodeNames[dwIndex].Buffer = rgszNames[dwIndex]; + pUnicodeNames[dwIndex].Length = ( USHORT ) cchLength; + pUnicodeNames[dwIndex].MaximumLength = ( USHORT ) ( cchLength + sizeof( UNICODE_NULL ) ); + } + + // + // Convert the names to sids + // + ntStatus = (*pfn) ( hPolicy, + 0, // Flags + dwNameCount, + pUnicodeNames, + &pReferencedDomainList, + &pTranslatedSid ); + + if ( !NT_SUCCESS( ntStatus ) ) + { + hr = HRESULT_FROM_WIN32( ntStatus ); + DBGERROR_HR( hr ); + goto Finished; + } + + // + // Some of the names could not be translated. + // This is an informational-level return value. + // + if ( ntStatus == STATUS_SOME_NOT_MAPPED ) + { + hr = HRESULT_FROM_WIN32( ntStatus ); + DBGERROR_HR( hr ); + hr = S_OK; + } + + // + // Count the number of SIDs retrieved + // + for ( DWORD dwIndex = 0; dwIndex < dwNameCount; dwIndex++ ) + { + if ( pTranslatedSid[dwIndex].Sid != NULL ) + { + cStringSids ++; + } + } + + // + // Allocate the SID list to return + // + rgszStringSids = (LPWSTR *) LocalAlloc( + LMEM_FIXED, + sizeof( LPWSTR ) * cStringSids ); + + if ( rgszStringSids == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR( hr ); + goto Finished; + } + + // + // Construct a string SID for each name + // + dwStringIndex = 0; + for ( DWORD dwIndex = 0; dwIndex < dwNameCount; dwIndex++ ) + { + if ( pTranslatedSid[dwIndex].Sid != NULL ) + { + if ( ! ConvertSidToStringSid( + pTranslatedSid [dwIndex].Sid, + &rgszStringSids [dwStringIndex] ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR( hr ); + goto Finished; + } + dwStringIndex ++; + } + } + +Finished: + + if ( pUnicodeNames != NULL ) + { + LocalFree( pUnicodeNames ); + pUnicodeNames = NULL; + } + + if ( pReferencedDomainList != NULL ) + { + LsaFreeMemory( pReferencedDomainList ); + pReferencedDomainList = NULL; + } + + if ( pTranslatedSid != NULL ) + { + LsaFreeMemory( pTranslatedSid ); + pTranslatedSid = NULL; + } + + if ( hPolicy != NULL ) + { + LsaClose( hPolicy ); + hPolicy = NULL; + } + + // + // If the translation wasn't successful, + // free any partial translation. + // + + if ( FAILED( hr ) ) + { + if ( rgszStringSids != NULL ) + { + FreeStringSids( cStringSids, rgszStringSids ); + rgszStringSids = NULL; + } + } + + // + // Assign the output parameters + // + (*StringSids) = rgszStringSids; + (*pcStringSids) = cStringSids; + + if ( hModule != NULL ) + { + FreeLibrary( hModule ); + hModule = NULL; + } + + return hr; +} + +HRESULT +SetFileSddl( + __in LPCWSTR pszSddl, + __in LPWSTR pszPath +) +{ + HRESULT hr = S_OK; + SECURITY_ATTRIBUTES sa = { 0 }; + DWORD status = 0; + BOOL fIsVistaOrGreater = FALSE; + + sa.nLength = sizeof( sa ); + sa.bInheritHandle = FALSE; + if ( ! ConvertStringSecurityDescriptorToSecurityDescriptor( + pszSddl, + SDDL_REVISION_1, + &sa.lpSecurityDescriptor, + NULL)) + { + hr = HRESULT_FROM_WIN32 ( GetLastError() ); + DBGERROR_HR( hr ); + goto Finished; + } + + hr = IsVistaOrGreater ( fIsVistaOrGreater ); + if ( FAILED(hr) ) + { + fIsVistaOrGreater = FALSE; + hr = S_OK; + } + + if ( fIsVistaOrGreater ) + { + status = SetNamedSecurityInfo( pszPath, + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION, + NULL, + NULL, + (PACL) sa.lpSecurityDescriptor, + NULL ); + if ( status != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32 (status ); + DBGERROR_HR( hr ); + goto Finished; + } + } + else + { + if ( ! SetFileSecurity( pszPath, + DACL_SECURITY_INFORMATION, + (PSECURITY_DESCRIPTOR) sa.lpSecurityDescriptor ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR( hr ); + goto Finished; + } + } + + +Finished: + + if ( sa.lpSecurityDescriptor != NULL ) + { + LocalFree( sa.lpSecurityDescriptor ); + sa.lpSecurityDescriptor = NULL; + } + + return hr; +} + +HRESULT +GetIISWPGSid( + __out STRU & strIISWPGSid +) +{ + HRESULT hr = S_OK; + LPWSTR* ppszStringSids = NULL; + DWORD cStringSids = 0; + + LPWSTR rgszIisAccountsToResolve [] = { L"IIS_WPG" }; + + hr = ConvertAccountNamesToStringSids( _countof( rgszIisAccountsToResolve ), + rgszIisAccountsToResolve, + &ppszStringSids, + &cStringSids ); + if ( FAILED( hr ) ) + { + DBGERROR_HR( hr ); + goto Finished; + } + + if ( cStringSids < 1 ) + { + hr = E_INVALIDARG; + goto Finished; + } + + hr = strIISWPGSid.Copy( ppszStringSids[0] ); + if ( FAILED( hr ) ) + { + goto Finished; + } + +Finished: + + if ( ppszStringSids != NULL ) + { + FreeStringSids( cStringSids, ppszStringSids ); + ppszStringSids = NULL; + } + + return hr; +} + +ULONG +GetRealAclSize( + __in PACL Acl + ) +/*++ + +Routine Description: + + Walks the sids in an ACL to determine it's minimum size + +Arguments: + + Acl - Acl to scan + +Return Value: + + Byte count + +--*/ +{ + PACE_HEADER Ace = FirstAce( Acl ); + int i = 0; + while (i < Acl->AceCount ) { + i++; + Ace = NextAce( Ace ); + } + + return (ULONG) ((PBYTE) Ace - (PBYTE) Acl); + +} + +HRESULT +MakeAutoInheritFromParent( + __in LPWSTR pszPath +) +{ + HRESULT hr = S_OK; + DWORD dwError; + PACL Acl; + PACE_HEADER Ace; + PSECURITY_DESCRIPTOR pSecurityDescriptor; + SECURITY_INFORMATION SecurityInfo = DACL_SECURITY_INFORMATION; + + // + // Get the current file DACL + // + dwError = GetNamedSecurityInfo( pszPath, + SE_FILE_OBJECT, + SecurityInfo, + NULL, + NULL, + &Acl, + NULL, + &pSecurityDescriptor ); + if ( dwError != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32( dwError ); + DBGERROR_HR( hr ); + goto Finished; + } + + // + // Remove all the ACEs + // + Ace = FirstAce( Acl ); + int i = 0; + while ( i < Acl->AceCount ) + { + // + // The Ace was not inherited + // + if( (Ace->AceFlags & INHERITED_ACE) == 0 ) + { + if (!DeleteAce( Acl, i )) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR( hr ); + goto Finished; + } + } + else + { + i++; + Ace = NextAce( Ace ); + } + } + Acl->AclSize = (WORD) GetRealAclSize( Acl ); + + // + // Auto-inherit + // + SecurityInfo |= UNPROTECTED_DACL_SECURITY_INFORMATION; + + dwError = SetNamedSecurityInfo( pszPath, + SE_FILE_OBJECT, + SecurityInfo, + NULL, + NULL, + Acl, + NULL ); + if ( dwError != ERROR_SUCCESS ) + { + hr = HRESULT_FROM_WIN32( dwError ); + DBGERROR_HR( hr ); + goto Finished; + } + +Finished: + + if ( pSecurityDescriptor != NULL ) + { + LocalFree( pSecurityDescriptor ); + pSecurityDescriptor = NULL; + } + + return hr; +} + +HRESULT +GrantIISWPGReadWritePermissions( + __in LPWSTR pszPath +) +{ + HRESULT hr = S_OK; + STACK_STRU( strAces, 128 ); + STACK_STRU( strFileSddl, 128 ); + STACK_STRU( strFileSddlTemp, 128 ); + STACK_STRU( strIISWPGSid, 32 ); + + hr = GetStringSddlFromFile( pszPath, + strFileSddlTemp ); + if ( FAILED( hr ) ) + { + DBGERROR_HR( hr ); + goto Finished; + } + + hr = GetIISWPGSid( strIISWPGSid ); + if ( FAILED( hr ) ) + { + DBGERROR_HR( hr ); + if ( hr == STATUS_NONE_MAPPED ) + { + // + // No maps found. + // + hr = S_OK; + } + goto Finished; + } + + // + // Add Read/Write permissions. + // + hr = strAces.Copy( L"(A;OICI;0x12019f;;;" ); + if ( FAILED( hr ) ) + { + goto Finished; + } + + hr = strAces.Append( strIISWPGSid ); + if ( FAILED( hr ) ) + { + goto Finished; + } + + hr = strAces.Append( L")", 1 ); + if ( FAILED( hr ) ) + { + goto Finished; + } + + // + // Insert the ACE before any other ACE. + // + + // + // Search for the first ACE '(' + // + LPCWSTR psz = wcschr( strFileSddlTemp.QueryStr(), SDDL_ACE_BEGINC ); + + // + // Copy the first part before the first '(' + // + hr = strFileSddl.Append( strFileSddlTemp.QueryStr(), + (DWORD)(psz - strFileSddlTemp.QueryStr()) ); + if ( FAILED( hr ) ) + { + DBGERROR_HR( hr ); + goto Finished; + } + + // + // Copy the new ACE + // + hr = strFileSddl.Append( strAces ); + if ( FAILED( hr ) ) + { + DBGERROR_HR( hr ); + goto Finished; + } + + // + // Copy the other ACEs. + // + hr = strFileSddl.Append( psz ); + if ( FAILED( hr ) ) + { + DBGERROR_HR( hr ); + goto Finished; + } + + hr = SetFileSddl( strFileSddl.QueryStr(), + pszPath ); + if ( FAILED( hr ) ) + { + DBGERROR_HR( hr ); + goto Finished; + } + +Finished: + + return hr; +} + +HRESULT +SetupAclsWow64( + LPCWSTR pwszPath +) +{ + HRESULT hr = S_OK; + HMODULE hModule = NULL; + STACK_STRU( strPath, MAX_PATH ); + + typedef UINT + (WINAPI *PFN_GETSYSTEMWOW64DIRECTORY) + ( + __out LPTSTR lpBuffer, + __in UINT uSize + ); + + PFN_GETSYSTEMWOW64DIRECTORY pfn; + + hModule = LoadLibrary( L"kernel32.dll" ); + if ( hModule == NULL ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR( hr ); + goto Finished; + } + pfn = ( PFN_GETSYSTEMWOW64DIRECTORY ) GetProcAddress( hModule, "GetSystemWow64DirectoryW" ); + if ( pfn == NULL ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + DBGERROR_HR( hr ); + if ( hr == HRESULT_FROM_WIN32( ERROR_PROC_NOT_FOUND ) ) + { + // + // This must be an OS before Windows 2003. + // + hr = S_OK; + } + goto Finished; + } + + if ( ! (*pfn)( strPath.QueryStr(), + strPath.QuerySizeCCH() ) ) + { + hr = HRESULT_FROM_WIN32( GetLastError() ); + if ( hr == HRESULT_FROM_WIN32( ERROR_CALL_NOT_IMPLEMENTED ) ) + { + // + // This is not Win64. + // + hr = S_OK; + } + else + { + DBGERROR_HR( hr ); + } + goto Finished; + } + strPath.SyncWithBuffer(); + + if (pwszPath != NULL) + { + hr = strPath.Append( pwszPath ); + if ( FAILED( hr ) ) + { + goto Finished; + } + } + + hr = MakeAutoInheritFromParent( strPath.QueryStr() ); + if ( FAILED( hr ) ) + { + DBGERROR_HR( hr ); + goto Finished; + } + +Finished: + + if ( hModule != NULL ) + { + FreeLibrary( hModule ); + hModule = NULL; + } + + return hr; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/secutils.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/secutils.h new file mode 100644 index 0000000000..416ffd369c --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/secutils.h @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +HRESULT +IsVistaOrGreater( + __out BOOL & fIsVistaOrGreater +); + +HRESULT +CreateDirectory( + __in LPCWSTR pszFileName +); + +HRESULT +AddExplicitAccessToFileDacl( + __in LPWSTR pszFilePath, + DWORD cExplicitAccess, + EXPLICIT_ACCESS rgExplicitAccess[] +); + +HRESULT +GrantFileAccessToIisIusrs( + __in LPWSTR pszFilePath, + DWORD dwAccessMask, + DWORD dwInheritance +); + +HRESULT +GetStringSddlFromFile( + __in LPWSTR pszFileName, + __out STRU & strFileSddl, + __in BOOL fCreateIfDoesNotExist = TRUE +); + +VOID +FreeStringSids( + __in DWORD cStringSids, + __in_bcount(cStringSids) LPWSTR rgszStringSids[] +); + +HRESULT +ConvertAccountNamesToStringSids ( + __in DWORD dwNameCount, + __in_ecount(dwNameCount) LPWSTR rgszNames[], + __deref_out_ecount(*pcStringSids) LPWSTR** StringSids, + __out DWORD* pcStringSids +); + +HRESULT +SetFileSddl( + __in LPCWSTR pszSddl, + __in LPWSTR pszPath +); + +HRESULT +GetIISWPGSid( + __out STRU & strIISWPGSid +); + +inline PACE_HEADER +FirstAce( __in PACL Acl ) +{ + return (PACE_HEADER)(((PBYTE)Acl) + sizeof( ACL )); +} + +inline PACE_HEADER +NextAce( __in PACE_HEADER Ace ) +{ + return (PACE_HEADER)(((PBYTE)Ace) + Ace->AceSize ); +} + +inline PSID +SidFromAce( __in PACE_HEADER Ace ) +{ + return (PSID)&((PACCESS_ALLOWED_ACE)Ace)->SidStart; +} + +ULONG +GetRealAclSize( + __in PACL Acl +); + + +HRESULT +MakeAutoInheritFromParent( + __in LPWSTR pszPath +); + +HRESULT +GrantIISWPGReadWritePermissions( + __in LPWSTR pszPath +); + +HRESULT +SetupAclsWow64( + LPCWSTR pwszPath +); + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/setup_log.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/setup_log.cpp new file mode 100644 index 0000000000..86a8857096 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/setup_log.cpp @@ -0,0 +1,423 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" +#include "ntassert.h" +// +// SETUP_LOG class, used only by MsiLogXXX functions not used directly by CA code +// +class SETUP_LOG +{ + +public: + + SETUP_LOG( + VOID + ) + { + _severityThreshold = SETUP_LOG_SEVERITY_INFORMATION; + } + + ~SETUP_LOG( + VOID + ) + { + } + + VOID + Initialize( + IN MSIHANDLE hInstall, + IN LPCWSTR pszCAName + ); + + VOID + Close( + VOID + ); + + VOID + Write( + IN CONST SETUP_LOG_SEVERITY setupLogSeverity, + IN LPCWSTR pszLogMessageFormat + ); + +private: + + MSIHANDLE _hInstall; + SETUP_LOG_SEVERITY _severityThreshold; + STRU _strSCANamePrefix; + +private: + HRESULT + WriteMSIMessage( + IN STRU * pstrLogMessage + ); + + HRESULT + SETUP_LOG::FmtCAName( + IN STRU * pstrFmtCAName + ); +}; + + +VOID +SETUP_LOG::Initialize( + IN MSIHANDLE hInstall, + IN LPCWSTR pszCAName + ) +/*++ + +Routine Description: + + Initialization. Opens handle to the log file and writes a message. + +Return Value: + + HRESULT + +--*/ +{ + STACK_STRU ( strMsiRegKey, 64 ); + STACK_STRU ( strStartLogMessage, MAX_PATH ); + STACK_STRU ( strMsiLoggingValue, 32 ); + DWORD dwBufLen = strMsiRegKey.QuerySizeCCH(); + DWORD status = ERROR_SUCCESS; + HKEY hKey = NULL; + + //for checking logging level + WORD i; + + // + //Set MSI handle & CA name + // + + _hInstall = hInstall; + + // + //Prefix message with CAname + // + _strSCANamePrefix.Copy( L"IISCA " ); + _strSCANamePrefix.Append( pszCAName ); + _strSCANamePrefix.Append( L" : " ); + + // + //test MsiLogging property MSI 4.0+ + // + + (VOID) MsiUtilGetProperty( hInstall, L"MsiLogging", &strMsiLoggingValue ); + + if( !strMsiLoggingValue.IsEmpty() ) + { + WCHAR * szValueBuf = strMsiLoggingValue.QueryStr(); + if( wcschr( szValueBuf, L'v' ) || wcschr( szValueBuf, L'V' ) ) + { + _severityThreshold = SETUP_LOG_SEVERITY_DEBUG ; + } + } + + if ( _severityThreshold != SETUP_LOG_SEVERITY_DEBUG ) + { + // + // Last chance - check Logging Registry Key/value + // + + status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Policies\\Microsoft\\Windows\\Installer", + 0, + KEY_QUERY_VALUE, + &hKey ); + + if ( status == ERROR_SUCCESS ) + { + status = RegQueryValueEx( hKey, + L"Logging", + NULL, + NULL, + (LPBYTE) strMsiRegKey.QueryStr(), + &dwBufLen); + + strMsiRegKey.SyncWithBuffer( ); + } + + if ( !( status != ERROR_SUCCESS ) || ( dwBufLen > strMsiRegKey.QuerySizeCCH() ) ) + { + // + //Have Logging key Value.. we will log something + // + // Check logging flags for verbosity 'v' + // + for ( i = 0; i < strMsiRegKey.QueryCCH() ; i++ ) + { + if ( strMsiRegKey.QueryStr()[ i ] == L'V' || strMsiRegKey.QueryStr()[ i ] == L'v' ) + { + _severityThreshold = SETUP_LOG_SEVERITY_DEBUG ; + break; + } + } + } + } + + // + // write the start message, prifix message with CAname + // + strStartLogMessage.Append( _strSCANamePrefix.QueryStr() ); + + strStartLogMessage.Append( L"Begin CA Setup" ); + + // + // write the message + // + + WriteMSIMessage( &strStartLogMessage ); + + + if ( hKey != NULL ) + { + RegCloseKey( hKey ); + hKey = NULL; + } + + return; +} + +VOID +SETUP_LOG::Close( + VOID + ) + +{ + STACK_STRU ( strEndLogMessage, MAX_PATH ); + + strEndLogMessage.Append( _strSCANamePrefix.QueryStr() ); + strEndLogMessage.Append( L"End CA Setup" ); + + // + // write the message + // + + WriteMSIMessage( &strEndLogMessage); + + return; +} + +VOID +SETUP_LOG::Write( + IN SETUP_LOG_SEVERITY setupLogSeverity, + IN LPCWSTR pszLogMessage + ) +/*++ + +Routine Description: + + Write a formatted message to the log file. Note that the message + will not be written to the log file if the severity is below that + of the current threshold. + +Arguments: + + setupLogSeverity - Severity of the message + pszLogMessageFormat - Format of the log message + +--*/ +{ + STACK_STRU ( struLogMessage, MAX_PATH ); + + DBG_ASSERT( pszLogMessage); + + if ( pszLogMessage == NULL ) + { + goto Exit; + } + + // + // If this message does not have high enough severity, we are done. + // + if ( setupLogSeverity < _severityThreshold ) + { + goto Exit; + } + + // + //Prefix message with CAname + // + + struLogMessage.Append( _strSCANamePrefix.QueryStr() ); + + // + // Prefix the high severity messages so we can easily spot errors. + // + + if ( setupLogSeverity == SETUP_LOG_SEVERITY_WARNING ) + { + struLogMessage.Append( L"< WARNING! > " ); + } + else if ( setupLogSeverity == SETUP_LOG_SEVERITY_ERROR ) + { + struLogMessage.Append( L"< !!ERROR!! > " ); + } + + struLogMessage.Append( pszLogMessage ); + + // + // Write to the log file + // + + WriteMSIMessage( &struLogMessage ); + +Exit: + + return; +} + +HRESULT +SETUP_LOG::WriteMSIMessage( + STRU * pstrLogMessage + ) + +{ + HRESULT hr = S_OK; + PMSIHANDLE msiRow; + UINT status = 0; + // + // get an MSI record + // + + //consider passing a parameterized string here + msiRow = MsiCreateRecord( 1 ); + if ( msiRow == NULL ) + { + hr = E_UNEXPECTED; + DBGERROR_HR(hr); + goto Exit; + } + + // + // put message in msi record + // + + status = MsiRecordSetStringW( msiRow, 1, (LPCWSTR)pstrLogMessage->QueryStr() ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto Exit; + } + + // + // send message to MSI log file + // + + status = MsiProcessMessage( _hInstall, INSTALLMESSAGE_INFO, msiRow ); + if ( ERROR_SUCCESS != status ) + { + hr = HRESULT_FROM_WIN32( status ); + DBGERROR_HR(hr); + goto Exit; + } + +Exit: + + return hr; +} + +// +//Use static global instance of SETUP_LOG class +// +static SETUP_LOG * g_pSetupLog = NULL; + +// +//MSI Log safe functions, used directly by CA code +// +VOID +IISLogInitialize( + IN MSIHANDLE hInstall, + IN LPCWSTR pszCAName + ) +{ + HRESULT hr = S_OK; + + //debug assert that it is always null. becaues previous custom action should have cleaned it up + DBG_ASSERT( g_pSetupLog == NULL ); + + if ( g_pSetupLog == NULL ) + { + g_pSetupLog = new SETUP_LOG(); + if ( g_pSetupLog == NULL ) + { + hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY ); + DBGERROR_HR(hr); + goto Exit; + } + } + + // + // init + // + + g_pSetupLog->Initialize( hInstall, pszCAName ); + +Exit: + return; +} + + +VOID +IISLogClose( + VOID + ) +{ + if ( !g_pSetupLog ) + { + goto Exit; + } + + // + // do the call + // + + g_pSetupLog->Close(); + + // + //Done with SETUP_LOG instance + // + + delete g_pSetupLog; + g_pSetupLog = NULL; + +Exit: + + return ; +} + + +VOID +IISLogWrite( + IN SETUP_LOG_SEVERITY setupLogSeverity, + IN LPCWSTR pszLogMessageFormat, + ... + ) +{ + va_list argsList; + va_start ( argsList, pszLogMessageFormat ); + + STACK_STRU ( struLogMessage, 128 ); + //debug assert that it is not null + DBG_ASSERT( g_pSetupLog ); + + if ( !g_pSetupLog ) + { + goto Exit; + } + + // + // Form struLogMessage so that we can write a single string + // + + struLogMessage.SafeVsnwprintf( pszLogMessageFormat, argsList ); + + g_pSetupLog->Write( setupLogSeverity, struLogMessage.QueryStr() ); + +Exit: + va_end ( argsList ); + return; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/setup_log.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/setup_log.h new file mode 100644 index 0000000000..848fe4d0a3 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/setup_log.h @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#ifndef _SETUP_LOG_H_ +#define _SETUP_LOG_H_ + + +// +// Severity levels for setup log information. This is arranged in the +// order of increasing severity. +// +enum SETUP_LOG_SEVERITY +{ + SETUP_LOG_SEVERITY_DEBUG, + SETUP_LOG_SEVERITY_INFORMATION, + SETUP_LOG_SEVERITY_WARNING, + SETUP_LOG_SEVERITY_ERROR +}; + +//consider using an IIS prefix for Msi* methods - they conflict with MSI apis + +// +// Initalize logging once at begining of CA +// + +VOID +IISLogInitialize( + IN MSIHANDLE hInstall, + IN LPCWSTR pszCAName + ); + +// +// Close logging at end / exit of CA +// + +VOID +IISLogClose( + VOID + ); + +// +// Writes a message to msi log file +// +VOID +IISLogWrite( + IN SETUP_LOG_SEVERITY setupLogSeverity, + IN LPCWSTR pszLogMessageFormat, + ... + ); + +#endif + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/tracing.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/tracing.cpp new file mode 100644 index 0000000000..a7e051b92e --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/tracing.cpp @@ -0,0 +1,343 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +HRESULT +RegisterTraceArea( + IN CONST WCHAR * szTraceProviderName, + IN CONST WCHAR * szTraceProviderGuid, + IN CONST WCHAR * szAreaName, + IN CONST WCHAR * szAreaValue +) +{ + HRESULT hr = NOERROR; + CComPtr pAdminMgr; + CComPtr pTraceProviderSection; + CComPtr pTraceProvidersCollection; + CComPtr pTraceProvider; + CComPtr pAreasElement; + CComPtr pAreasCollection; + CComPtr pAreaElement; + + BSTR bstrAppHostConfigPath = SysAllocString( L"MACHINE/WEBROOT/APPHOST" ); + BSTR bstrTracingSection = SysAllocString( L"system.webServer/tracing/traceProviderDefinitions" ); + BSTR bstrAreas = SysAllocString( L"areas" ); + + NAME_VALUE_PAIR ProviderProperties[] = + { + { L"name", CComVariant( szTraceProviderName )}, + { L"guid", CComVariant( szTraceProviderGuid )} + }; + + NAME_VALUE_PAIR AreaProperties[] = + { + { L"name", CComVariant( szAreaName )}, + { L"value", CComVariant( szAreaValue )} + }; + + if ( bstrAppHostConfigPath == NULL || + bstrTracingSection == NULL || + bstrAreas == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( IAppHostWritableAdminManager ), + (VOID **)&pAdminMgr ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->GetAdminSection( bstrTracingSection, + bstrAppHostConfigPath, + &pTraceProviderSection ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pTraceProviderSection->get_Collection( &pTraceProvidersCollection ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = GetElementFromCollection( pTraceProvidersCollection, + L"name", + szTraceProviderName, + &pTraceProvider ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Create the trace provider if it doesn't exist. + // + if ( hr == S_FALSE ) + { + hr = AddElementToCollection( pTraceProvidersCollection, + L"add", + ProviderProperties, + _countof( ProviderProperties ), + &pTraceProvider ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + hr = pTraceProvider->GetElementByName( bstrAreas, + &pAreasElement ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pAreasElement->get_Collection( &pAreasCollection ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = GetElementFromCollection( pAreasCollection, + L"name", + szAreaName, + &pAreaElement ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + // + // Add the trace area if it doesn't exist. + // + if ( hr != S_FALSE ) + { + hr = S_OK; + goto exit; + } + + hr = AddElementToCollection( pAreasCollection, + L"add", + AreaProperties, + _countof( AreaProperties ), + NULL ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->CommitChanges(); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + SysFreeString( bstrAppHostConfigPath ); + SysFreeString( bstrTracingSection ); + SysFreeString( bstrAreas ); + + return hr; +} + +HRESULT +AddElementToCollection( + IN IAppHostElementCollection * pCollection, + IN CONST WCHAR * pElementName, + IN NAME_VALUE_PAIR rgProperties[], + IN DWORD cProperties, + OUT IAppHostElement ** ppElement +) +{ + HRESULT hr = NOERROR; + CComPtr pElement; + CComPtr pProperty; + + BSTR bstrName = NULL; + BSTR bstrElementName = SysAllocString( pElementName ); + + if ( bstrElementName == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pCollection->CreateNewElement( bstrElementName, + &pElement ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + for ( DWORD Index = 0; Index < cProperties; Index ++ ) + { + bstrName = SysAllocString( rgProperties[Index].Name ); + if ( bstrName == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pElement->GetPropertyByName( bstrName, + &pProperty ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( rgProperties[Index].Value.vt == VT_ERROR ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pProperty->put_Value( rgProperties[Index].Value ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + SysFreeString( bstrName ); + pProperty.Detach()->Release(); + } + + hr = pCollection->AddElement( pElement ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if ( ppElement != NULL ) + { + *ppElement = pElement.Detach(); + } + +exit: + + SysFreeString( bstrElementName ); + SysFreeString( bstrName ); + + return hr; +} + +HRESULT +GetElementFromCollection( + IN IAppHostElementCollection * pCollection, + IN CONST WCHAR * szIndex, + IN CONST WCHAR * szExpectedPropertyValue, + OUT IAppHostElement ** ppElement, + OUT DWORD * pIndex +) +{ + HRESULT hr = NOERROR; + DWORD dwElementCount = 0; + CComPtr pElement; + CComPtr pProperty; + + BSTR bstrPropertyName = SysAllocString( szIndex ); + + if ( bstrPropertyName == NULL ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pCollection->get_Count( &dwElementCount ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + for ( DWORD Index = 0; Index < dwElementCount; Index ++ ) + { + CComVariant value; + + hr = pCollection->get_Item( CComVariant( Index ), + &pElement ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pElement->GetPropertyByName( bstrPropertyName, + &pProperty ); + if ( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pProperty->get_Value( &value ); + if ( value.vt == VT_ERROR ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + if ( value.vt != VT_BSTR ) + { + hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA ); + DBGERROR_HR(hr); + goto exit; + } + + if ( _wcsicmp( value.bstrVal, szExpectedPropertyValue ) == 0 ) + { + // + // Element found. + // + *ppElement = pElement.Detach(); + if ( pIndex != NULL ) + { + *pIndex = Index; + } + hr = S_OK; + goto exit; + } + + pProperty.Detach()->Release(); + pElement.Detach()->Release(); + } + + // + // Element not found. + // + hr = S_FALSE; + +exit: + + SysFreeString( bstrPropertyName ); + + return hr; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/tracing.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/tracing.h new file mode 100644 index 0000000000..087e8ded74 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/tracing.h @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +HRESULT +RegisterTraceArea( + IN CONST WCHAR * szTraceProviderName, + IN CONST WCHAR * szTraceProviderGuid, + IN CONST WCHAR * szAreaName, + IN CONST WCHAR * szAreaValue +); + +HRESULT +GetElementFromCollection( + IN IAppHostElementCollection * pCollection, + IN CONST WCHAR * szPropertyName, + IN CONST WCHAR * szExpectedPropertyValue, + OUT IAppHostElement ** ppElement, + OUT DWORD * pIndex = NULL +); + +struct NAME_VALUE_PAIR +{ + LPCWSTR Name; + CComVariant Value; +}; + +HRESULT +AddElementToCollection( + IN IAppHostElementCollection * pCollection, + IN CONST WCHAR * pElementName, + IN NAME_VALUE_PAIR rgProperties[], + IN DWORD cProperties, + OUT IAppHostElement ** ppElement +); diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/uimodule.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/uimodule.cpp new file mode 100644 index 0000000000..76adb89ca6 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/uimodule.cpp @@ -0,0 +1,637 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#include "precomp.h" + +class ADMINISTRATION_CONFIG_PATH_MAPPER : public IAppHostPathMapper +{ + +public: + + ADMINISTRATION_CONFIG_PATH_MAPPER( + VOID + ) : _cRefs( 1 ) + { + } + + ~ADMINISTRATION_CONFIG_PATH_MAPPER( + VOID + ) + { + } + + HRESULT + Initialize() + { + // TODO this could be more reliable. + HRESULT hr = NOERROR; + DWORD cch; + + cch = ExpandEnvironmentStringsW( + L"%windir%\\system32\\inetsrv\\config\\administration.config", + _strMappedPath.QueryStr(), + _strMappedPath.QuerySizeCCH() + ); + if( !cch ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto exit; + } + + if( cch > _strMappedPath.QuerySizeCCH() ) + { + hr = _strMappedPath.Resize( cch ); + if( FAILED(hr) ) + { + goto exit; + } + + cch = ExpandEnvironmentStringsW( + L"%windir%\\system32\\inetsrv\\config\\administration.config", + _strMappedPath.QueryStr(), + _strMappedPath.QuerySizeCCH() + ); + if( !cch || + cch > _strMappedPath.QuerySizeCCH() ) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto exit; + } + } + + _strMappedPath.SyncWithBuffer(); + + exit: + + return hr; + + } + + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return InterlockedIncrement( &_cRefs ); + } + + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + ULONG ulRet = 0; + + ulRet = InterlockedDecrement( &_cRefs ); + + if ( ulRet == 0 ) + { + delete this; + } + return ulRet; + } + + HRESULT + STDMETHODCALLTYPE + QueryInterface( + REFIID riid, + void ** ppObject + ) + { + if ( riid == __uuidof(IUnknown) || + riid == __uuidof(IAppHostPathMapper) ) + { + AddRef(); + *ppObject = (IAppHostPathMapper*) this; + return S_OK; + } + else + { + *ppObject = NULL; + return E_NOINTERFACE; + } + } + + HRESULT + STDMETHODCALLTYPE + MapPath( + BSTR bstrConfigPath, + BSTR bstrMappedPhysicalPath, + BSTR * pbstrNewPhysicalPath + ) + { + BSTR bstrNewPhysicalPath = NULL; + + if ( wcscmp( bstrConfigPath, L"MACHINE/WEBROOT" ) == 0 ) + { + bstrNewPhysicalPath = SysAllocString( _strMappedPath.QueryStr() ); + } + else + { + bstrNewPhysicalPath = SysAllocString( bstrMappedPhysicalPath ); + } + + if ( bstrNewPhysicalPath == NULL ) + { + return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY ); + } + + *pbstrNewPhysicalPath = bstrNewPhysicalPath; + return S_OK; + } + +private: + + LONG _cRefs; + STRU _strMappedPath; +}; + +HRESULT +InitAdminMgrForAdminConfig( + IN IAppHostWritableAdminManager * pAdminMgr, + IN CONST WCHAR * szCommitPath + ) +{ + HRESULT hr = NOERROR; + + VARIANT varPathMapper; + VariantInit( &varPathMapper ); + + BSTR bstrPathMapperName = SysAllocString( L"pathMapper" ); + BSTR bstrCommitPath = SysAllocString( szCommitPath ); + + ADMINISTRATION_CONFIG_PATH_MAPPER * pPathMapper = NULL; + + if( !bstrPathMapperName || !bstrCommitPath) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->put_CommitPath( bstrCommitPath ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + pPathMapper = new ADMINISTRATION_CONFIG_PATH_MAPPER(); + if( !pPathMapper ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = pPathMapper->Initialize(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + varPathMapper.vt = VT_UNKNOWN; + varPathMapper.punkVal = pPathMapper; + pPathMapper = NULL; + + hr = pAdminMgr->SetMetadata( bstrPathMapperName, varPathMapper ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + SysFreeString( bstrPathMapperName ); + SysFreeString( bstrCommitPath ); + + VariantClear( &varPathMapper ); + + if( pPathMapper ) + { + pPathMapper->Release(); + pPathMapper = NULL; + } + + return hr; +} + + +HRESULT +RegisterUIModule( + IN CONST WCHAR * szModuleName, + IN CONST WCHAR * szModuleTypeInfo, + IN OPTIONAL CONST WCHAR * szRegisterInModulesSection, + IN OPTIONAL CONST WCHAR * szPrependToList + ) +{ + HRESULT hr = NOERROR; + + CComPtr pAdminMgr; + CComPtr pProvidersSection; + CComPtr pProvidersCollection; + CComPtr pNewModuleElement; + CComPtr pModulesSection; + CComPtr pModulesCollection; + CComPtr pModulesCollectionElement; + + VARIANT varValue; + VariantInit( &varValue ); + DWORD dwIndex; + BOOL fAddElement = FALSE; + INT cIndex; + + BSTR bstrCommitPath = SysAllocString( L"MACHINE/WEBROOT" ); + BSTR bstrModuleProvidersName = SysAllocString( L"moduleProviders" ); + BSTR bstrAdd = SysAllocString( L"add" ); + BSTR bstrModulesSectionName = SysAllocString( L"modules" ); + + if( !bstrCommitPath || + !bstrModuleProvidersName || + !bstrAdd || + !bstrModulesSectionName ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( IAppHostWritableAdminManager ), + (VOID **)&pAdminMgr ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = InitAdminMgrForAdminConfig( pAdminMgr, + bstrCommitPath ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->GetAdminSection( bstrModuleProvidersName, + bstrCommitPath, + &pProvidersSection ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pProvidersSection->get_Collection( &pProvidersCollection ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = FindElementInCollection( + pProvidersCollection, + L"name", + szModuleName, + FIND_ELEMENT_CASE_SENSITIVE, + &dwIndex); + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + if (hr == S_OK) + { + VARIANT vtIndex; + vtIndex.vt = VT_UI4; + vtIndex.ulVal = dwIndex; + + hr = pProvidersCollection->get_Item( + vtIndex, + &pNewModuleElement); + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + } + else + { + hr = pProvidersCollection->CreateNewElement( bstrAdd, + &pNewModuleElement ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + fAddElement = TRUE; + } + + hr = VariantAssign( &varValue, szModuleName ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = SetElementProperty( pNewModuleElement, + L"name", + &varValue ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = VariantAssign( &varValue, szModuleTypeInfo ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = SetElementProperty( pNewModuleElement, + L"type", + &varValue ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if (fAddElement) + { + cIndex = -1; + if (szPrependToList && *szPrependToList) + { + cIndex = 0; + } + + hr = pProvidersCollection->AddElement( pNewModuleElement, + cIndex ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + if( szRegisterInModulesSection && *szRegisterInModulesSection ) + { + // register global section + hr = pAdminMgr->GetAdminSection( bstrModulesSectionName, + bstrCommitPath, + &pModulesSection ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pModulesSection->get_Collection( &pModulesCollection ); + + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pModulesCollection->CreateNewElement( bstrAdd, + &pModulesCollectionElement ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = VariantAssign( &varValue, szModuleName ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = SetElementProperty( pModulesCollectionElement, + L"name", + &varValue ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + cIndex = -1; + if (szPrependToList && *szPrependToList) + { + cIndex = 0; + } + + hr = pModulesCollection->AddElement( pModulesCollectionElement, + cIndex ); + if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) + { + hr = S_OK; + } + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + + hr = pAdminMgr->CommitChanges(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + +exit: + + SysFreeString( bstrCommitPath ); + SysFreeString( bstrModuleProvidersName ); + SysFreeString( bstrAdd ); + SysFreeString( bstrModulesSectionName ); + + VariantClear( &varValue ); + + return hr; +} + +HRESULT +UnRegisterUIModule( + IN CONST WCHAR * szModuleName, + IN CONST WCHAR * szModuleTypeInfo + ) +{ + HRESULT hr = NOERROR; + + CComPtr pAdminMgr; + CComPtr pProvidersSection; + CComPtr pProvidersCollection; + CComPtr pProviderElement; + CComPtr pModulesSection; + CComPtr pModulesCollection; + + BSTR bstrCommitPath = SysAllocString( L"MACHINE/WEBROOT" ); + BSTR bstrModuleProvidersName = SysAllocString( L"moduleProviders" ); + BSTR bstrModulesSectionName = SysAllocString( L"modules" ); + BSTR bstrType = NULL; + DWORD dwIndex; + + if( !bstrCommitPath || + !bstrModuleProvidersName || + !bstrModulesSectionName ) + { + hr = E_OUTOFMEMORY; + DBGERROR_HR(hr); + goto exit; + } + + hr = CoCreateInstance( __uuidof( AppHostWritableAdminManager ), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof( IAppHostWritableAdminManager ), + (VOID **)&pAdminMgr ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = InitAdminMgrForAdminConfig( pAdminMgr, bstrCommitPath ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pAdminMgr->GetAdminSection( bstrModuleProvidersName, + bstrCommitPath, + &pProvidersSection ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pProvidersSection->get_Collection( &pProvidersCollection ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + BOOL fProvidersDeleted = FALSE; + + hr = FindElementInCollection( + pProvidersCollection, + L"name", + szModuleName, + FIND_ELEMENT_CASE_SENSITIVE, + &dwIndex); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + if (hr == S_OK) + { + VARIANT vtIndex; + vtIndex.vt = VT_UI4; + vtIndex.ulVal = dwIndex; + + hr = pProvidersCollection->get_Item( + vtIndex, + &pProviderElement); + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = GetElementStringProperty( + pProviderElement, + L"type", + &bstrType); + if (FAILED(hr)) + { + DBGERROR_HR(hr); + goto exit; + } + + if (wcscmp(bstrType, szModuleTypeInfo) == 0) + { + hr = pProvidersCollection->DeleteElement(vtIndex); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + fProvidersDeleted = TRUE; + } + else + { + goto exit; + } + } + + // now remove from global section if present + hr = pAdminMgr->GetAdminSection( bstrModulesSectionName, + bstrCommitPath, + &pModulesSection ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + hr = pModulesSection->get_Collection( &pModulesCollection ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + BOOL fModulesDeleted = FALSE; + hr = DeleteElementFromCollection( pModulesCollection, + L"name", + szModuleName, + FIND_ELEMENT_CASE_SENSITIVE, + &fModulesDeleted ); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + + if( fProvidersDeleted || fModulesDeleted ) + { + hr = pAdminMgr->CommitChanges(); + if( FAILED(hr) ) + { + DBGERROR_HR(hr); + goto exit; + } + } + +exit: + + SysFreeString( bstrCommitPath ); + SysFreeString( bstrModuleProvidersName ); + SysFreeString( bstrModulesSectionName ); + SysFreeString( bstrType ); + + return hr; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/wuerror.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/wuerror.h new file mode 100644 index 0000000000..a735af0cf7 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/lib/wuerror.h @@ -0,0 +1,2456 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +/*************************************************************************** +* * +* wuerror.mc -- error code definitions for Windows Update. * +* * +***************************************************************************/ +#ifndef _WUERROR_ +#define _WUERROR_ + +#if defined (_MSC_VER) && (_MSC_VER >= 1020) && !defined(__midl) +#pragma once +#endif + +#ifdef RC_INVOKED +#define _HRESULT_TYPEDEF_(_sc) _sc +#else // RC_INVOKED +#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc) +#endif // RC_INVOKED + + +/////////////////////////////////////////////////////////////////////////////// +// Windows Update Success Codes +/////////////////////////////////////////////////////////////////////////////// +// +// Values are 32 bit values laid out as follows: +// +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +// +---+-+-+-----------------------+-------------------------------+ +// |Sev|C|R| Facility | Code | +// +---+-+-+-----------------------+-------------------------------+ +// +// where +// +// Sev - is the severity code +// +// 00 - Success +// 01 - Informational +// 10 - Warning +// 11 - Error +// +// C - is the Customer code flag +// +// R - is a reserved bit +// +// Facility - is the facility code +// +// Code - is the facility's status code +// +// +// Define the facility codes +// + + +// +// Define the severity codes +// + + +// +// MessageId: WU_S_SERVICE_STOP +// +// MessageText: +// +// Windows Update Agent was stopped successfully. +// +#define WU_S_SERVICE_STOP _HRESULT_TYPEDEF_(0x00240001L) + +// +// MessageId: WU_S_SELFUPDATE +// +// MessageText: +// +// Windows Update Agent updated itself. +// +#define WU_S_SELFUPDATE _HRESULT_TYPEDEF_(0x00240002L) + +// +// MessageId: WU_S_UPDATE_ERROR +// +// MessageText: +// +// Operation completed successfully but there were errors applying the updates. +// +#define WU_S_UPDATE_ERROR _HRESULT_TYPEDEF_(0x00240003L) + +// +// MessageId: WU_S_MARKED_FOR_DISCONNECT +// +// MessageText: +// +// A callback was marked to be disconnected later because the request to disconnect the operation came while a callback was executing. +// +#define WU_S_MARKED_FOR_DISCONNECT _HRESULT_TYPEDEF_(0x00240004L) + +// +// MessageId: WU_S_REBOOT_REQUIRED +// +// MessageText: +// +// The system must be restarted to complete installation of the update. +// +#define WU_S_REBOOT_REQUIRED _HRESULT_TYPEDEF_(0x00240005L) + +// +// MessageId: WU_S_ALREADY_INSTALLED +// +// MessageText: +// +// The update to be installed is already installed on the system. +// +#define WU_S_ALREADY_INSTALLED _HRESULT_TYPEDEF_(0x00240006L) + +// +// MessageId: WU_S_ALREADY_UNINSTALLED +// +// MessageText: +// +// The update to be removed is not installed on the system. +// +#define WU_S_ALREADY_UNINSTALLED _HRESULT_TYPEDEF_(0x00240007L) + +// +// MessageId: WU_S_ALREADY_DOWNLOADED +// +// MessageText: +// +// The update to be downloaded has already been downloaded. +// +#define WU_S_ALREADY_DOWNLOADED _HRESULT_TYPEDEF_(0x00240008L) + +/////////////////////////////////////////////////////////////////////////////// +// Windows Update Error Codes +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_NO_SERVICE +// +// MessageText: +// +// Windows Update Agent was unable to provide the service. +// +#define WU_E_NO_SERVICE _HRESULT_TYPEDEF_(0x80240001L) + +// +// MessageId: WU_E_MAX_CAPACITY_REACHED +// +// MessageText: +// +// The maximum capacity of the service was exceeded. +// +#define WU_E_MAX_CAPACITY_REACHED _HRESULT_TYPEDEF_(0x80240002L) + +// +// MessageId: WU_E_UNKNOWN_ID +// +// MessageText: +// +// An ID cannot be found. +// +#define WU_E_UNKNOWN_ID _HRESULT_TYPEDEF_(0x80240003L) + +// +// MessageId: WU_E_NOT_INITIALIZED +// +// MessageText: +// +// The object could not be initialized. +// +#define WU_E_NOT_INITIALIZED _HRESULT_TYPEDEF_(0x80240004L) + +// +// MessageId: WU_E_RANGEOVERLAP +// +// MessageText: +// +// The update handler requested a byte range overlapping a previously requested range. +// +#define WU_E_RANGEOVERLAP _HRESULT_TYPEDEF_(0x80240005L) + +// +// MessageId: WU_E_TOOMANYRANGES +// +// MessageText: +// +// The requested number of byte ranges exceeds the maximum number (2^31 - 1). +// +#define WU_E_TOOMANYRANGES _HRESULT_TYPEDEF_(0x80240006L) + +// +// MessageId: WU_E_INVALIDINDEX +// +// MessageText: +// +// The index to a collection was invalid. +// +#define WU_E_INVALIDINDEX _HRESULT_TYPEDEF_(0x80240007L) + +// +// MessageId: WU_E_ITEMNOTFOUND +// +// MessageText: +// +// The key for the item queried could not be found. +// +#define WU_E_ITEMNOTFOUND _HRESULT_TYPEDEF_(0x80240008L) + +// +// MessageId: WU_E_OPERATIONINPROGRESS +// +// MessageText: +// +// Another conflicting operation was in progress. Some operations such as installation cannot be performed twice simultaneously. +// +#define WU_E_OPERATIONINPROGRESS _HRESULT_TYPEDEF_(0x80240009L) + +// +// MessageId: WU_E_COULDNOTCANCEL +// +// MessageText: +// +// Cancellation of the operation was not allowed. +// +#define WU_E_COULDNOTCANCEL _HRESULT_TYPEDEF_(0x8024000AL) + +// +// MessageId: WU_E_CALL_CANCELLED +// +// MessageText: +// +// Operation was cancelled. +// +#define WU_E_CALL_CANCELLED _HRESULT_TYPEDEF_(0x8024000BL) + +// +// MessageId: WU_E_NOOP +// +// MessageText: +// +// No operation was required. +// +#define WU_E_NOOP _HRESULT_TYPEDEF_(0x8024000CL) + +// +// MessageId: WU_E_XML_MISSINGDATA +// +// MessageText: +// +// Windows Update Agent could not find required information in the update's XML data. +// +#define WU_E_XML_MISSINGDATA _HRESULT_TYPEDEF_(0x8024000DL) + +// +// MessageId: WU_E_XML_INVALID +// +// MessageText: +// +// Windows Update Agent found invalid information in the update's XML data. +// +#define WU_E_XML_INVALID _HRESULT_TYPEDEF_(0x8024000EL) + +// +// MessageId: WU_E_CYCLE_DETECTED +// +// MessageText: +// +// Circular update relationships were detected in the metadata. +// +#define WU_E_CYCLE_DETECTED _HRESULT_TYPEDEF_(0x8024000FL) + +// +// MessageId: WU_E_TOO_DEEP_RELATION +// +// MessageText: +// +// Update relationships too deep to evaluate were evaluated. +// +#define WU_E_TOO_DEEP_RELATION _HRESULT_TYPEDEF_(0x80240010L) + +// +// MessageId: WU_E_INVALID_RELATIONSHIP +// +// MessageText: +// +// An invalid update relationship was detected. +// +#define WU_E_INVALID_RELATIONSHIP _HRESULT_TYPEDEF_(0x80240011L) + +// +// MessageId: WU_E_REG_VALUE_INVALID +// +// MessageText: +// +// An invalid registry value was read. +// +#define WU_E_REG_VALUE_INVALID _HRESULT_TYPEDEF_(0x80240012L) + +// +// MessageId: WU_E_DUPLICATE_ITEM +// +// MessageText: +// +// Operation tried to add a duplicate item to a list. +// +#define WU_E_DUPLICATE_ITEM _HRESULT_TYPEDEF_(0x80240013L) + +// +// MessageId: WU_E_INSTALL_NOT_ALLOWED +// +// MessageText: +// +// Operation tried to install while another installation was in progress or the system was pending a mandatory restart. +// +#define WU_E_INSTALL_NOT_ALLOWED _HRESULT_TYPEDEF_(0x80240016L) + +// +// MessageId: WU_E_NOT_APPLICABLE +// +// MessageText: +// +// Operation was not performed because there are no applicable updates. +// +#define WU_E_NOT_APPLICABLE _HRESULT_TYPEDEF_(0x80240017L) + +// +// MessageId: WU_E_NO_USERTOKEN +// +// MessageText: +// +// Operation failed because a required user token is missing. +// +#define WU_E_NO_USERTOKEN _HRESULT_TYPEDEF_(0x80240018L) + +// +// MessageId: WU_E_EXCLUSIVE_INSTALL_CONFLICT +// +// MessageText: +// +// An exclusive update cannot be installed with other updates at the same time. +// +#define WU_E_EXCLUSIVE_INSTALL_CONFLICT _HRESULT_TYPEDEF_(0x80240019L) + +// +// MessageId: WU_E_POLICY_NOT_SET +// +// MessageText: +// +// A policy value was not set. +// +#define WU_E_POLICY_NOT_SET _HRESULT_TYPEDEF_(0x8024001AL) + +// +// MessageId: WU_E_SELFUPDATE_IN_PROGRESS +// +// MessageText: +// +// The operation could not be performed because the Windows Update Agent is self-updating. +// +#define WU_E_SELFUPDATE_IN_PROGRESS _HRESULT_TYPEDEF_(0x8024001BL) + +// +// MessageId: WU_E_INVALID_UPDATE +// +// MessageText: +// +// An update contains invalid metadata. +// +#define WU_E_INVALID_UPDATE _HRESULT_TYPEDEF_(0x8024001DL) + +// +// MessageId: WU_E_SERVICE_STOP +// +// MessageText: +// +// Operation did not complete because the service or system was being shut down. +// +#define WU_E_SERVICE_STOP _HRESULT_TYPEDEF_(0x8024001EL) + +// +// MessageId: WU_E_NO_CONNECTION +// +// MessageText: +// +// Operation did not complete because the network connection was unavailable. +// +#define WU_E_NO_CONNECTION _HRESULT_TYPEDEF_(0x8024001FL) + +// +// MessageId: WU_E_NO_INTERACTIVE_USER +// +// MessageText: +// +// Operation did not complete because there is no logged-on interactive user. +// +#define WU_E_NO_INTERACTIVE_USER _HRESULT_TYPEDEF_(0x80240020L) + +// +// MessageId: WU_E_TIME_OUT +// +// MessageText: +// +// Operation did not complete because it timed out. +// +#define WU_E_TIME_OUT _HRESULT_TYPEDEF_(0x80240021L) + +// +// MessageId: WU_E_ALL_UPDATES_FAILED +// +// MessageText: +// +// Operation failed for all the updates. +// +#define WU_E_ALL_UPDATES_FAILED _HRESULT_TYPEDEF_(0x80240022L) + +// +// MessageId: WU_E_EULAS_DECLINED +// +// MessageText: +// +// The license terms for all updates were declined. +// +#define WU_E_EULAS_DECLINED _HRESULT_TYPEDEF_(0x80240023L) + +// +// MessageId: WU_E_NO_UPDATE +// +// MessageText: +// +// There are no updates. +// +#define WU_E_NO_UPDATE _HRESULT_TYPEDEF_(0x80240024L) + +// +// MessageId: WU_E_USER_ACCESS_DISABLED +// +// MessageText: +// +// Group Policy settings prevented access to Windows Update. +// +#define WU_E_USER_ACCESS_DISABLED _HRESULT_TYPEDEF_(0x80240025L) + +// +// MessageId: WU_E_INVALID_UPDATE_TYPE +// +// MessageText: +// +// The type of update is invalid. +// +#define WU_E_INVALID_UPDATE_TYPE _HRESULT_TYPEDEF_(0x80240026L) + +// +// MessageId: WU_E_URL_TOO_LONG +// +// MessageText: +// +// The URL exceeded the maximum length. +// +#define WU_E_URL_TOO_LONG _HRESULT_TYPEDEF_(0x80240027L) + +// +// MessageId: WU_E_UNINSTALL_NOT_ALLOWED +// +// MessageText: +// +// The update could not be uninstalled because the request did not originate from a WSUS server. +// +#define WU_E_UNINSTALL_NOT_ALLOWED _HRESULT_TYPEDEF_(0x80240028L) + +// +// MessageId: WU_E_INVALID_PRODUCT_LICENSE +// +// MessageText: +// +// Search may have missed some updates before there is an unlicensed application on the system. +// +#define WU_E_INVALID_PRODUCT_LICENSE _HRESULT_TYPEDEF_(0x80240029L) + +// +// MessageId: WU_E_MISSING_HANDLER +// +// MessageText: +// +// A component required to detect applicable updates was missing. +// +#define WU_E_MISSING_HANDLER _HRESULT_TYPEDEF_(0x8024002AL) + +// +// MessageId: WU_E_LEGACYSERVER +// +// MessageText: +// +// An operation did not complete because it requires a newer version of server. +// +#define WU_E_LEGACYSERVER _HRESULT_TYPEDEF_(0x8024002BL) + +// +// MessageId: WU_E_BIN_SOURCE_ABSENT +// +// MessageText: +// +// A delta-compressed update could not be installed because it required the source. +// +#define WU_E_BIN_SOURCE_ABSENT _HRESULT_TYPEDEF_(0x8024002CL) + +// +// MessageId: WU_E_SOURCE_ABSENT +// +// MessageText: +// +// A full-file update could not be installed because it required the source. +// +#define WU_E_SOURCE_ABSENT _HRESULT_TYPEDEF_(0x8024002DL) + +// +// MessageId: WU_E_WU_DISABLED +// +// MessageText: +// +// Access to an unmanaged server is not allowed. +// +#define WU_E_WU_DISABLED _HRESULT_TYPEDEF_(0x8024002EL) + +// +// MessageId: WU_E_CALL_CANCELLED_BY_POLICY +// +// MessageText: +// +// Operation did not complete because the DisableWindowsUpdateAccess policy was set. +// +#define WU_E_CALL_CANCELLED_BY_POLICY _HRESULT_TYPEDEF_(0x8024002FL) + +// +// MessageId: WU_E_INVALID_PROXY_SERVER +// +// MessageText: +// +// The format of the proxy list was invalid. +// +#define WU_E_INVALID_PROXY_SERVER _HRESULT_TYPEDEF_(0x80240030L) + +// +// MessageId: WU_E_INVALID_FILE +// +// MessageText: +// +// The file is in the wrong format. +// +#define WU_E_INVALID_FILE _HRESULT_TYPEDEF_(0x80240031L) + +// +// MessageId: WU_E_INVALID_CRITERIA +// +// MessageText: +// +// The search criteria string was invalid. +// +#define WU_E_INVALID_CRITERIA _HRESULT_TYPEDEF_(0x80240032L) + +// +// MessageId: WU_E_EULA_UNAVAILABLE +// +// MessageText: +// +// License terms could not be downloaded. +// +#define WU_E_EULA_UNAVAILABLE _HRESULT_TYPEDEF_(0x80240033L) + +// +// MessageId: WU_E_DOWNLOAD_FAILED +// +// MessageText: +// +// Update failed to download. +// +#define WU_E_DOWNLOAD_FAILED _HRESULT_TYPEDEF_(0x80240034L) + +// +// MessageId: WU_E_UPDATE_NOT_PROCESSED +// +// MessageText: +// +// The update was not processed. +// +#define WU_E_UPDATE_NOT_PROCESSED _HRESULT_TYPEDEF_(0x80240035L) + +// +// MessageId: WU_E_INVALID_OPERATION +// +// MessageText: +// +// The object's current state did not allow the operation. +// +#define WU_E_INVALID_OPERATION _HRESULT_TYPEDEF_(0x80240036L) + +// +// MessageId: WU_E_NOT_SUPPORTED +// +// MessageText: +// +// The functionality for the operation is not supported. +// +#define WU_E_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80240037L) + +// +// MessageId: WU_E_WINHTTP_INVALID_FILE +// +// MessageText: +// +// The downloaded file has an unexpected content type. +// +#define WU_E_WINHTTP_INVALID_FILE _HRESULT_TYPEDEF_(0x80240038L) + +// +// MessageId: WU_E_TOO_MANY_RESYNC +// +// MessageText: +// +// Agent is asked by server to resync too many times. +// +#define WU_E_TOO_MANY_RESYNC _HRESULT_TYPEDEF_(0x80240039L) + +// +// MessageId: WU_E_NO_SERVER_CORE_SUPPORT +// +// MessageText: +// +// WUA API method does not run on Server Core installation. +// +#define WU_E_NO_SERVER_CORE_SUPPORT _HRESULT_TYPEDEF_(0x80240040L) + +// +// MessageId: WU_E_SYSPREP_IN_PROGRESS +// +// MessageText: +// +// Service is not available while sysprep is running. +// +#define WU_E_SYSPREP_IN_PROGRESS _HRESULT_TYPEDEF_(0x80240041L) + +// +// MessageId: WU_E_UNKNOWN_SERVICE +// +// MessageText: +// +// The update service is no longer registered with AU. +// +#define WU_E_UNKNOWN_SERVICE _HRESULT_TYPEDEF_(0x80240042L) + +// +// MessageId: WU_E_NO_UI_SUPPORT +// +// MessageText: +// +// There is no support for WUA UI. +// +#define WU_E_NO_UI_SUPPORT _HRESULT_TYPEDEF_(0x80240043L) + +// +// MessageId: WU_E_UNEXPECTED +// +// MessageText: +// +// An operation failed due to reasons not covered by another error code. +// +#define WU_E_UNEXPECTED _HRESULT_TYPEDEF_(0x80240FFFL) + +/////////////////////////////////////////////////////////////////////////////// +// Windows Installer minor errors +// +// The following errors are used to indicate that part of a search failed for +// MSI problems. Another part of the search may successfully return updates. +// All MSI minor codes should share the same error code range so that the caller +// tell that they are related to Windows Installer. +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_MSI_WRONG_VERSION +// +// MessageText: +// +// Search may have missed some updates because the Windows Installer is less than version 3.1. +// +#define WU_E_MSI_WRONG_VERSION _HRESULT_TYPEDEF_(0x80241001L) + +// +// MessageId: WU_E_MSI_NOT_CONFIGURED +// +// MessageText: +// +// Search may have missed some updates because the Windows Installer is not configured. +// +#define WU_E_MSI_NOT_CONFIGURED _HRESULT_TYPEDEF_(0x80241002L) + +// +// MessageId: WU_E_MSP_DISABLED +// +// MessageText: +// +// Search may have missed some updates because policy has disabled Windows Installer patching. +// +#define WU_E_MSP_DISABLED _HRESULT_TYPEDEF_(0x80241003L) + +// +// MessageId: WU_E_MSI_WRONG_APP_CONTEXT +// +// MessageText: +// +// An update could not be applied because the application is installed per-user. +// +#define WU_E_MSI_WRONG_APP_CONTEXT _HRESULT_TYPEDEF_(0x80241004L) + +// +// MessageId: WU_E_MSP_UNEXPECTED +// +// MessageText: +// +// Search may have missed some updates because there was a failure of the Windows Installer. +// +#define WU_E_MSP_UNEXPECTED _HRESULT_TYPEDEF_(0x80241FFFL) + +/////////////////////////////////////////////////////////////////////////////// +// Protocol Talker errors +// +// The following map to SOAPCLIENT_ERRORs from atlsoap.h. These errors +// are obtained from calling GetClientError() on the CClientWebService +// object. +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_PT_SOAPCLIENT_BASE +// +// MessageText: +// +// WU_E_PT_SOAPCLIENT_* error codes map to the SOAPCLIENT_ERROR enum of the ATL Server Library. +// +#define WU_E_PT_SOAPCLIENT_BASE _HRESULT_TYPEDEF_(0x80244000L) + +// +// MessageId: WU_E_PT_SOAPCLIENT_INITIALIZE +// +// MessageText: +// +// Same as SOAPCLIENT_INITIALIZE_ERROR - initialization of the SOAP client failed, possibly because of an MSXML installation failure. +// +#define WU_E_PT_SOAPCLIENT_INITIALIZE _HRESULT_TYPEDEF_(0x80244001L) + +// +// MessageId: WU_E_PT_SOAPCLIENT_OUTOFMEMORY +// +// MessageText: +// +// Same as SOAPCLIENT_OUTOFMEMORY - SOAP client failed because it ran out of memory. +// +#define WU_E_PT_SOAPCLIENT_OUTOFMEMORY _HRESULT_TYPEDEF_(0x80244002L) + +// +// MessageId: WU_E_PT_SOAPCLIENT_GENERATE +// +// MessageText: +// +// Same as SOAPCLIENT_GENERATE_ERROR - SOAP client failed to generate the request. +// +#define WU_E_PT_SOAPCLIENT_GENERATE _HRESULT_TYPEDEF_(0x80244003L) + +// +// MessageId: WU_E_PT_SOAPCLIENT_CONNECT +// +// MessageText: +// +// Same as SOAPCLIENT_CONNECT_ERROR - SOAP client failed to connect to the server. +// +#define WU_E_PT_SOAPCLIENT_CONNECT _HRESULT_TYPEDEF_(0x80244004L) + +// +// MessageId: WU_E_PT_SOAPCLIENT_SEND +// +// MessageText: +// +// Same as SOAPCLIENT_SEND_ERROR - SOAP client failed to send a message for reasons of WU_E_WINHTTP_* error codes. +// +#define WU_E_PT_SOAPCLIENT_SEND _HRESULT_TYPEDEF_(0x80244005L) + +// +// MessageId: WU_E_PT_SOAPCLIENT_SERVER +// +// MessageText: +// +// Same as SOAPCLIENT_SERVER_ERROR - SOAP client failed because there was a server error. +// +#define WU_E_PT_SOAPCLIENT_SERVER _HRESULT_TYPEDEF_(0x80244006L) + +// +// MessageId: WU_E_PT_SOAPCLIENT_SOAPFAULT +// +// MessageText: +// +// Same as SOAPCLIENT_SOAPFAULT - SOAP client failed because there was a SOAP fault for reasons of WU_E_PT_SOAP_* error codes. +// +#define WU_E_PT_SOAPCLIENT_SOAPFAULT _HRESULT_TYPEDEF_(0x80244007L) + +// +// MessageId: WU_E_PT_SOAPCLIENT_PARSEFAULT +// +// MessageText: +// +// Same as SOAPCLIENT_PARSEFAULT_ERROR - SOAP client failed to parse a SOAP fault. +// +#define WU_E_PT_SOAPCLIENT_PARSEFAULT _HRESULT_TYPEDEF_(0x80244008L) + +// +// MessageId: WU_E_PT_SOAPCLIENT_READ +// +// MessageText: +// +// Same as SOAPCLIENT_READ_ERROR - SOAP client failed while reading the response from the server. +// +#define WU_E_PT_SOAPCLIENT_READ _HRESULT_TYPEDEF_(0x80244009L) + +// +// MessageId: WU_E_PT_SOAPCLIENT_PARSE +// +// MessageText: +// +// Same as SOAPCLIENT_PARSE_ERROR - SOAP client failed to parse the response from the server. +// +#define WU_E_PT_SOAPCLIENT_PARSE _HRESULT_TYPEDEF_(0x8024400AL) + +// The following map to SOAP_ERROR_CODEs from atlsoap.h. These errors +// are obtained from the m_fault.m_soapErrCode member on the +// CClientWebService object when GetClientError() returned +// SOAPCLIENT_SOAPFAULT. +// +// MessageId: WU_E_PT_SOAP_VERSION +// +// MessageText: +// +// Same as SOAP_E_VERSION_MISMATCH - SOAP client found an unrecognizable namespace for the SOAP envelope. +// +#define WU_E_PT_SOAP_VERSION _HRESULT_TYPEDEF_(0x8024400BL) + +// +// MessageId: WU_E_PT_SOAP_MUST_UNDERSTAND +// +// MessageText: +// +// Same as SOAP_E_MUST_UNDERSTAND - SOAP client was unable to understand a header. +// +#define WU_E_PT_SOAP_MUST_UNDERSTAND _HRESULT_TYPEDEF_(0x8024400CL) + +// +// MessageId: WU_E_PT_SOAP_CLIENT +// +// MessageText: +// +// Same as SOAP_E_CLIENT - SOAP client found the message was malformed; fix before resending. +// +#define WU_E_PT_SOAP_CLIENT _HRESULT_TYPEDEF_(0x8024400DL) + +// +// MessageId: WU_E_PT_SOAP_SERVER +// +// MessageText: +// +// Same as SOAP_E_SERVER - The SOAP message could not be processed due to a server error; resend later. +// +#define WU_E_PT_SOAP_SERVER _HRESULT_TYPEDEF_(0x8024400EL) + +// +// MessageId: WU_E_PT_WMI_ERROR +// +// MessageText: +// +// There was an unspecified Windows Management Instrumentation (WMI) error. +// +#define WU_E_PT_WMI_ERROR _HRESULT_TYPEDEF_(0x8024400FL) + +// +// MessageId: WU_E_PT_EXCEEDED_MAX_SERVER_TRIPS +// +// MessageText: +// +// The number of round trips to the server exceeded the maximum limit. +// +#define WU_E_PT_EXCEEDED_MAX_SERVER_TRIPS _HRESULT_TYPEDEF_(0x80244010L) + +// +// MessageId: WU_E_PT_SUS_SERVER_NOT_SET +// +// MessageText: +// +// WUServer policy value is missing in the registry. +// +#define WU_E_PT_SUS_SERVER_NOT_SET _HRESULT_TYPEDEF_(0x80244011L) + +// +// MessageId: WU_E_PT_DOUBLE_INITIALIZATION +// +// MessageText: +// +// Initialization failed because the object was already initialized. +// +#define WU_E_PT_DOUBLE_INITIALIZATION _HRESULT_TYPEDEF_(0x80244012L) + +// +// MessageId: WU_E_PT_INVALID_COMPUTER_NAME +// +// MessageText: +// +// The computer name could not be determined. +// +#define WU_E_PT_INVALID_COMPUTER_NAME _HRESULT_TYPEDEF_(0x80244013L) + +// +// MessageId: WU_E_PT_REFRESH_CACHE_REQUIRED +// +// MessageText: +// +// The reply from the server indicates that the server was changed or the cookie was invalid; refresh the state of the internal cache and retry. +// +#define WU_E_PT_REFRESH_CACHE_REQUIRED _HRESULT_TYPEDEF_(0x80244015L) + +// +// MessageId: WU_E_PT_HTTP_STATUS_BAD_REQUEST +// +// MessageText: +// +// Same as HTTP status 400 - the server could not process the request due to invalid syntax. +// +#define WU_E_PT_HTTP_STATUS_BAD_REQUEST _HRESULT_TYPEDEF_(0x80244016L) + +// +// MessageId: WU_E_PT_HTTP_STATUS_DENIED +// +// MessageText: +// +// Same as HTTP status 401 - the requested resource requires user authentication. +// +#define WU_E_PT_HTTP_STATUS_DENIED _HRESULT_TYPEDEF_(0x80244017L) + +// +// MessageId: WU_E_PT_HTTP_STATUS_FORBIDDEN +// +// MessageText: +// +// Same as HTTP status 403 - server understood the request, but declined to fulfill it. +// +#define WU_E_PT_HTTP_STATUS_FORBIDDEN _HRESULT_TYPEDEF_(0x80244018L) + +// +// MessageId: WU_E_PT_HTTP_STATUS_NOT_FOUND +// +// MessageText: +// +// Same as HTTP status 404 - the server cannot find the requested URI (Uniform Resource Identifier). +// +// +#define WU_E_PT_HTTP_STATUS_NOT_FOUND _HRESULT_TYPEDEF_(0x80244019L) + +// +// MessageId: WU_E_PT_HTTP_STATUS_BAD_METHOD +// +// MessageText: +// +// Same as HTTP status 405 - the HTTP method is not allowed. +// +#define WU_E_PT_HTTP_STATUS_BAD_METHOD _HRESULT_TYPEDEF_(0x8024401AL) + +// +// MessageId: WU_E_PT_HTTP_STATUS_PROXY_AUTH_REQ +// +// MessageText: +// +// Same as HTTP status 407 - proxy authentication is required. +// +#define WU_E_PT_HTTP_STATUS_PROXY_AUTH_REQ _HRESULT_TYPEDEF_(0x8024401BL) + +// +// MessageId: WU_E_PT_HTTP_STATUS_REQUEST_TIMEOUT +// +// MessageText: +// +// Same as HTTP status 408 - the server timed out waiting for the request. +// +#define WU_E_PT_HTTP_STATUS_REQUEST_TIMEOUT _HRESULT_TYPEDEF_(0x8024401CL) + +// +// MessageId: WU_E_PT_HTTP_STATUS_CONFLICT +// +// MessageText: +// +// Same as HTTP status 409 - the request was not completed due to a conflict with the current state of the resource. +// +#define WU_E_PT_HTTP_STATUS_CONFLICT _HRESULT_TYPEDEF_(0x8024401DL) + +// +// MessageId: WU_E_PT_HTTP_STATUS_GONE +// +// MessageText: +// +// Same as HTTP status 410 - requested resource is no longer available at the server. +// +#define WU_E_PT_HTTP_STATUS_GONE _HRESULT_TYPEDEF_(0x8024401EL) + +// +// MessageId: WU_E_PT_HTTP_STATUS_SERVER_ERROR +// +// MessageText: +// +// Same as HTTP status 500 - an error internal to the server prevented fulfilling the request. +// +#define WU_E_PT_HTTP_STATUS_SERVER_ERROR _HRESULT_TYPEDEF_(0x8024401FL) + +// +// MessageId: WU_E_PT_HTTP_STATUS_NOT_SUPPORTED +// +// MessageText: +// +// Same as HTTP status 500 - server does not support the functionality required to fulfill the request. +// +#define WU_E_PT_HTTP_STATUS_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80244020L) + +// +// MessageId: WU_E_PT_HTTP_STATUS_BAD_GATEWAY +// +// MessageText: +// +// Same as HTTP status 502 - the server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request. +// +#define WU_E_PT_HTTP_STATUS_BAD_GATEWAY _HRESULT_TYPEDEF_(0x80244021L) + +// +// MessageId: WU_E_PT_HTTP_STATUS_SERVICE_UNAVAIL +// +// MessageText: +// +// Same as HTTP status 503 - the service is temporarily overloaded. +// +#define WU_E_PT_HTTP_STATUS_SERVICE_UNAVAIL _HRESULT_TYPEDEF_(0x80244022L) + +// +// MessageId: WU_E_PT_HTTP_STATUS_GATEWAY_TIMEOUT +// +// MessageText: +// +// Same as HTTP status 503 - the request was timed out waiting for a gateway. +// +#define WU_E_PT_HTTP_STATUS_GATEWAY_TIMEOUT _HRESULT_TYPEDEF_(0x80244023L) + +// +// MessageId: WU_E_PT_HTTP_STATUS_VERSION_NOT_SUP +// +// MessageText: +// +// Same as HTTP status 505 - the server does not support the HTTP protocol version used for the request. +// +#define WU_E_PT_HTTP_STATUS_VERSION_NOT_SUP _HRESULT_TYPEDEF_(0x80244024L) + +// +// MessageId: WU_E_PT_FILE_LOCATIONS_CHANGED +// +// MessageText: +// +// Operation failed due to a changed file location; refresh internal state and resend. +// +#define WU_E_PT_FILE_LOCATIONS_CHANGED _HRESULT_TYPEDEF_(0x80244025L) + +// +// MessageId: WU_E_PT_REGISTRATION_NOT_SUPPORTED +// +// MessageText: +// +// Operation failed because Windows Update Agent does not support registration with a non-WSUS server. +// +#define WU_E_PT_REGISTRATION_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80244026L) + +// +// MessageId: WU_E_PT_NO_AUTH_PLUGINS_REQUESTED +// +// MessageText: +// +// The server returned an empty authentication information list. +// +#define WU_E_PT_NO_AUTH_PLUGINS_REQUESTED _HRESULT_TYPEDEF_(0x80244027L) + +// +// MessageId: WU_E_PT_NO_AUTH_COOKIES_CREATED +// +// MessageText: +// +// Windows Update Agent was unable to create any valid authentication cookies. +// +#define WU_E_PT_NO_AUTH_COOKIES_CREATED _HRESULT_TYPEDEF_(0x80244028L) + +// +// MessageId: WU_E_PT_INVALID_CONFIG_PROP +// +// MessageText: +// +// A configuration property value was wrong. +// +#define WU_E_PT_INVALID_CONFIG_PROP _HRESULT_TYPEDEF_(0x80244029L) + +// +// MessageId: WU_E_PT_CONFIG_PROP_MISSING +// +// MessageText: +// +// A configuration property value was missing. +// +#define WU_E_PT_CONFIG_PROP_MISSING _HRESULT_TYPEDEF_(0x8024402AL) + +// +// MessageId: WU_E_PT_HTTP_STATUS_NOT_MAPPED +// +// MessageText: +// +// The HTTP request could not be completed and the reason did not correspond to any of the WU_E_PT_HTTP_* error codes. +// +#define WU_E_PT_HTTP_STATUS_NOT_MAPPED _HRESULT_TYPEDEF_(0x8024402BL) + +// +// MessageId: WU_E_PT_WINHTTP_NAME_NOT_RESOLVED +// +// MessageText: +// +// Same as ERROR_WINHTTP_NAME_NOT_RESOLVED - the proxy server or target server name cannot be resolved. +// +#define WU_E_PT_WINHTTP_NAME_NOT_RESOLVED _HRESULT_TYPEDEF_(0x8024402CL) + +// +// MessageId: WU_E_PT_SAME_REDIR_ID +// +// MessageText: +// +// Windows Update Agent failed to download a redirector cabinet file with a new redirectorId value from the server during the recovery. +// +#define WU_E_PT_SAME_REDIR_ID _HRESULT_TYPEDEF_(0x8024502DL) + +// +// MessageId: WU_E_PT_NO_MANAGED_RECOVER +// +// MessageText: +// +// A redirector recovery action did not complete because the server is managed. +// +#define WU_E_PT_NO_MANAGED_RECOVER _HRESULT_TYPEDEF_(0x8024502EL) + +// +// MessageId: WU_E_PT_ECP_SUCCEEDED_WITH_ERRORS +// +// MessageText: +// +// External cab file processing completed with some errors. +// +#define WU_E_PT_ECP_SUCCEEDED_WITH_ERRORS _HRESULT_TYPEDEF_(0x8024402FL) + +// +// MessageId: WU_E_PT_ECP_INIT_FAILED +// +// MessageText: +// +// The external cab processor initialization did not complete. +// +#define WU_E_PT_ECP_INIT_FAILED _HRESULT_TYPEDEF_(0x80244030L) + +// +// MessageId: WU_E_PT_ECP_INVALID_FILE_FORMAT +// +// MessageText: +// +// The format of a metadata file was invalid. +// +#define WU_E_PT_ECP_INVALID_FILE_FORMAT _HRESULT_TYPEDEF_(0x80244031L) + +// +// MessageId: WU_E_PT_ECP_INVALID_METADATA +// +// MessageText: +// +// External cab processor found invalid metadata. +// +#define WU_E_PT_ECP_INVALID_METADATA _HRESULT_TYPEDEF_(0x80244032L) + +// +// MessageId: WU_E_PT_ECP_FAILURE_TO_EXTRACT_DIGEST +// +// MessageText: +// +// The file digest could not be extracted from an external cab file. +// +#define WU_E_PT_ECP_FAILURE_TO_EXTRACT_DIGEST _HRESULT_TYPEDEF_(0x80244033L) + +// +// MessageId: WU_E_PT_ECP_FAILURE_TO_DECOMPRESS_CAB_FILE +// +// MessageText: +// +// An external cab file could not be decompressed. +// +#define WU_E_PT_ECP_FAILURE_TO_DECOMPRESS_CAB_FILE _HRESULT_TYPEDEF_(0x80244034L) + +// +// MessageId: WU_E_PT_ECP_FILE_LOCATION_ERROR +// +// MessageText: +// +// External cab processor was unable to get file locations. +// +#define WU_E_PT_ECP_FILE_LOCATION_ERROR _HRESULT_TYPEDEF_(0x80244035L) + +// +// MessageId: WU_E_PT_UNEXPECTED +// +// MessageText: +// +// A communication error not covered by another WU_E_PT_* error code. +// +#define WU_E_PT_UNEXPECTED _HRESULT_TYPEDEF_(0x80244FFFL) + +/////////////////////////////////////////////////////////////////////////////// +// Redirector errors +// +// The following errors are generated by the components that download and +// parse the wuredir.cab +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_REDIRECTOR_LOAD_XML +// +// MessageText: +// +// The redirector XML document could not be loaded into the DOM class. +// +#define WU_E_REDIRECTOR_LOAD_XML _HRESULT_TYPEDEF_(0x80245001L) + +// +// MessageId: WU_E_REDIRECTOR_S_FALSE +// +// MessageText: +// +// The redirector XML document is missing some required information. +// +#define WU_E_REDIRECTOR_S_FALSE _HRESULT_TYPEDEF_(0x80245002L) + +// +// MessageId: WU_E_REDIRECTOR_ID_SMALLER +// +// MessageText: +// +// The redirectorId in the downloaded redirector cab is less than in the cached cab. +// +#define WU_E_REDIRECTOR_ID_SMALLER _HRESULT_TYPEDEF_(0x80245003L) + +// +// MessageId: WU_E_REDIRECTOR_UNEXPECTED +// +// MessageText: +// +// The redirector failed for reasons not covered by another WU_E_REDIRECTOR_* error code. +// +#define WU_E_REDIRECTOR_UNEXPECTED _HRESULT_TYPEDEF_(0x80245FFFL) + +/////////////////////////////////////////////////////////////////////////////// +// driver util errors +// +// The device PnP enumerated device was pruned from the SystemSpec because +// one of the hardware or compatible IDs matched an installed printer driver. +// This is not considered a fatal error and the device is simply skipped. +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_DRV_PRUNED +// +// MessageText: +// +// A driver was skipped. +// +#define WU_E_DRV_PRUNED _HRESULT_TYPEDEF_(0x8024C001L) + +// +// MessageId: WU_E_DRV_NOPROP_OR_LEGACY +// +// MessageText: +// +// A property for the driver could not be found. It may not conform with required specifications. +// +#define WU_E_DRV_NOPROP_OR_LEGACY _HRESULT_TYPEDEF_(0x8024C002L) + +// +// MessageId: WU_E_DRV_REG_MISMATCH +// +// MessageText: +// +// The registry type read for the driver does not match the expected type. +// +#define WU_E_DRV_REG_MISMATCH _HRESULT_TYPEDEF_(0x8024C003L) + +// +// MessageId: WU_E_DRV_NO_METADATA +// +// MessageText: +// +// The driver update is missing metadata. +// +#define WU_E_DRV_NO_METADATA _HRESULT_TYPEDEF_(0x8024C004L) + +// +// MessageId: WU_E_DRV_MISSING_ATTRIBUTE +// +// MessageText: +// +// The driver update is missing a required attribute. +// +#define WU_E_DRV_MISSING_ATTRIBUTE _HRESULT_TYPEDEF_(0x8024C005L) + +// +// MessageId: WU_E_DRV_SYNC_FAILED +// +// MessageText: +// +// Driver synchronization failed. +// +#define WU_E_DRV_SYNC_FAILED _HRESULT_TYPEDEF_(0x8024C006L) + +// +// MessageId: WU_E_DRV_NO_PRINTER_CONTENT +// +// MessageText: +// +// Information required for the synchronization of applicable printers is missing. +// +#define WU_E_DRV_NO_PRINTER_CONTENT _HRESULT_TYPEDEF_(0x8024C007L) + +// +// MessageId: WU_E_DRV_UNEXPECTED +// +// MessageText: +// +// A driver error not covered by another WU_E_DRV_* code. +// +#define WU_E_DRV_UNEXPECTED _HRESULT_TYPEDEF_(0x8024CFFFL) + +////////////////////////////////////////////////////////////////////////////// +// data store errors +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_DS_SHUTDOWN +// +// MessageText: +// +// An operation failed because Windows Update Agent is shutting down. +// +#define WU_E_DS_SHUTDOWN _HRESULT_TYPEDEF_(0x80248000L) + +// +// MessageId: WU_E_DS_INUSE +// +// MessageText: +// +// An operation failed because the data store was in use. +// +#define WU_E_DS_INUSE _HRESULT_TYPEDEF_(0x80248001L) + +// +// MessageId: WU_E_DS_INVALID +// +// MessageText: +// +// The current and expected states of the data store do not match. +// +#define WU_E_DS_INVALID _HRESULT_TYPEDEF_(0x80248002L) + +// +// MessageId: WU_E_DS_TABLEMISSING +// +// MessageText: +// +// The data store is missing a table. +// +#define WU_E_DS_TABLEMISSING _HRESULT_TYPEDEF_(0x80248003L) + +// +// MessageId: WU_E_DS_TABLEINCORRECT +// +// MessageText: +// +// The data store contains a table with unexpected columns. +// +#define WU_E_DS_TABLEINCORRECT _HRESULT_TYPEDEF_(0x80248004L) + +// +// MessageId: WU_E_DS_INVALIDTABLENAME +// +// MessageText: +// +// A table could not be opened because the table is not in the data store. +// +#define WU_E_DS_INVALIDTABLENAME _HRESULT_TYPEDEF_(0x80248005L) + +// +// MessageId: WU_E_DS_BADVERSION +// +// MessageText: +// +// The current and expected versions of the data store do not match. +// +#define WU_E_DS_BADVERSION _HRESULT_TYPEDEF_(0x80248006L) + +// +// MessageId: WU_E_DS_NODATA +// +// MessageText: +// +// The information requested is not in the data store. +// +#define WU_E_DS_NODATA _HRESULT_TYPEDEF_(0x80248007L) + +// +// MessageId: WU_E_DS_MISSINGDATA +// +// MessageText: +// +// The data store is missing required information or has a NULL in a table column that requires a non-null value. +// +#define WU_E_DS_MISSINGDATA _HRESULT_TYPEDEF_(0x80248008L) + +// +// MessageId: WU_E_DS_MISSINGREF +// +// MessageText: +// +// The data store is missing required information or has a reference to missing license terms, file, localized property or linked row. +// +#define WU_E_DS_MISSINGREF _HRESULT_TYPEDEF_(0x80248009L) + +// +// MessageId: WU_E_DS_UNKNOWNHANDLER +// +// MessageText: +// +// The update was not processed because its update handler could not be recognized. +// +#define WU_E_DS_UNKNOWNHANDLER _HRESULT_TYPEDEF_(0x8024800AL) + +// +// MessageId: WU_E_DS_CANTDELETE +// +// MessageText: +// +// The update was not deleted because it is still referenced by one or more services. +// +#define WU_E_DS_CANTDELETE _HRESULT_TYPEDEF_(0x8024800BL) + +// +// MessageId: WU_E_DS_LOCKTIMEOUTEXPIRED +// +// MessageText: +// +// The data store section could not be locked within the allotted time. +// +#define WU_E_DS_LOCKTIMEOUTEXPIRED _HRESULT_TYPEDEF_(0x8024800CL) + +// +// MessageId: WU_E_DS_NOCATEGORIES +// +// MessageText: +// +// The category was not added because it contains no parent categories and is not a top-level category itself. +// +#define WU_E_DS_NOCATEGORIES _HRESULT_TYPEDEF_(0x8024800DL) + +// +// MessageId: WU_E_DS_ROWEXISTS +// +// MessageText: +// +// The row was not added because an existing row has the same primary key. +// +#define WU_E_DS_ROWEXISTS _HRESULT_TYPEDEF_(0x8024800EL) + +// +// MessageId: WU_E_DS_STOREFILELOCKED +// +// MessageText: +// +// The data store could not be initialized because it was locked by another process. +// +#define WU_E_DS_STOREFILELOCKED _HRESULT_TYPEDEF_(0x8024800FL) + +// +// MessageId: WU_E_DS_CANNOTREGISTER +// +// MessageText: +// +// The data store is not allowed to be registered with COM in the current process. +// +#define WU_E_DS_CANNOTREGISTER _HRESULT_TYPEDEF_(0x80248010L) + +// +// MessageId: WU_E_DS_UNABLETOSTART +// +// MessageText: +// +// Could not create a data store object in another process. +// +#define WU_E_DS_UNABLETOSTART _HRESULT_TYPEDEF_(0x80248011L) + +// +// MessageId: WU_E_DS_DUPLICATEUPDATEID +// +// MessageText: +// +// The server sent the same update to the client with two different revision IDs. +// +#define WU_E_DS_DUPLICATEUPDATEID _HRESULT_TYPEDEF_(0x80248013L) + +// +// MessageId: WU_E_DS_UNKNOWNSERVICE +// +// MessageText: +// +// An operation did not complete because the service is not in the data store. +// +#define WU_E_DS_UNKNOWNSERVICE _HRESULT_TYPEDEF_(0x80248014L) + +// +// MessageId: WU_E_DS_SERVICEEXPIRED +// +// MessageText: +// +// An operation did not complete because the registration of the service has expired. +// +#define WU_E_DS_SERVICEEXPIRED _HRESULT_TYPEDEF_(0x80248015L) + +// +// MessageId: WU_E_DS_DECLINENOTALLOWED +// +// MessageText: +// +// A request to hide an update was declined because it is a mandatory update or because it was deployed with a deadline. +// +#define WU_E_DS_DECLINENOTALLOWED _HRESULT_TYPEDEF_(0x80248016L) + +// +// MessageId: WU_E_DS_TABLESESSIONMISMATCH +// +// MessageText: +// +// A table was not closed because it is not associated with the session. +// +#define WU_E_DS_TABLESESSIONMISMATCH _HRESULT_TYPEDEF_(0x80248017L) + +// +// MessageId: WU_E_DS_SESSIONLOCKMISMATCH +// +// MessageText: +// +// A table was not closed because it is not associated with the session. +// +#define WU_E_DS_SESSIONLOCKMISMATCH _HRESULT_TYPEDEF_(0x80248018L) + +// +// MessageId: WU_E_DS_NEEDWINDOWSSERVICE +// +// MessageText: +// +// A request to remove the Windows Update service or to unregister it with Automatic Updates was declined because it is a built-in service and/or Automatic Updates cannot fall back to another service. +// +#define WU_E_DS_NEEDWINDOWSSERVICE _HRESULT_TYPEDEF_(0x80248019L) + +// +// MessageId: WU_E_DS_INVALIDOPERATION +// +// MessageText: +// +// A request was declined because the operation is not allowed. +// +#define WU_E_DS_INVALIDOPERATION _HRESULT_TYPEDEF_(0x8024801AL) + +// +// MessageId: WU_E_DS_SCHEMAMISMATCH +// +// MessageText: +// +// The schema of the current data store and the schema of a table in a backup XML document do not match. +// +#define WU_E_DS_SCHEMAMISMATCH _HRESULT_TYPEDEF_(0x8024801BL) + +// +// MessageId: WU_E_DS_RESETREQUIRED +// +// MessageText: +// +// The data store requires a session reset; release the session and retry with a new session. +// +#define WU_E_DS_RESETREQUIRED _HRESULT_TYPEDEF_(0x8024801CL) + +// +// MessageId: WU_E_DS_IMPERSONATED +// +// MessageText: +// +// A data store operation did not complete because it was requested with an impersonated identity. +// +#define WU_E_DS_IMPERSONATED _HRESULT_TYPEDEF_(0x8024801DL) + +// +// MessageId: WU_E_DS_UNEXPECTED +// +// MessageText: +// +// A data store error not covered by another WU_E_DS_* code. +// +#define WU_E_DS_UNEXPECTED _HRESULT_TYPEDEF_(0x80248FFFL) + +///////////////////////////////////////////////////////////////////////////// +//Inventory Errors +///////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_INVENTORY_PARSEFAILED +// +// MessageText: +// +// Parsing of the rule file failed. +// +#define WU_E_INVENTORY_PARSEFAILED _HRESULT_TYPEDEF_(0x80249001L) + +// +// MessageId: WU_E_INVENTORY_GET_INVENTORY_TYPE_FAILED +// +// MessageText: +// +// Failed to get the requested inventory type from the server. +// +#define WU_E_INVENTORY_GET_INVENTORY_TYPE_FAILED _HRESULT_TYPEDEF_(0x80249002L) + +// +// MessageId: WU_E_INVENTORY_RESULT_UPLOAD_FAILED +// +// MessageText: +// +// Failed to upload inventory result to the server. +// +#define WU_E_INVENTORY_RESULT_UPLOAD_FAILED _HRESULT_TYPEDEF_(0x80249003L) + +// +// MessageId: WU_E_INVENTORY_UNEXPECTED +// +// MessageText: +// +// There was an inventory error not covered by another error code. +// +#define WU_E_INVENTORY_UNEXPECTED _HRESULT_TYPEDEF_(0x80249004L) + +// +// MessageId: WU_E_INVENTORY_WMI_ERROR +// +// MessageText: +// +// A WMI error occurred when enumerating the instances for a particular class. +// +#define WU_E_INVENTORY_WMI_ERROR _HRESULT_TYPEDEF_(0x80249005L) + +///////////////////////////////////////////////////////////////////////////// +//AU Errors +///////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_AU_NOSERVICE +// +// MessageText: +// +// Automatic Updates was unable to service incoming requests. +// +#define WU_E_AU_NOSERVICE _HRESULT_TYPEDEF_(0x8024A000L) + +// +// MessageId: WU_E_AU_NONLEGACYSERVER +// +// MessageText: +// +// The old version of the Automatic Updates client has stopped because the WSUS server has been upgraded. +// +#define WU_E_AU_NONLEGACYSERVER _HRESULT_TYPEDEF_(0x8024A002L) + +// +// MessageId: WU_E_AU_LEGACYCLIENTDISABLED +// +// MessageText: +// +// The old version of the Automatic Updates client was disabled. +// +#define WU_E_AU_LEGACYCLIENTDISABLED _HRESULT_TYPEDEF_(0x8024A003L) + +// +// MessageId: WU_E_AU_PAUSED +// +// MessageText: +// +// Automatic Updates was unable to process incoming requests because it was paused. +// +#define WU_E_AU_PAUSED _HRESULT_TYPEDEF_(0x8024A004L) + +// +// MessageId: WU_E_AU_NO_REGISTERED_SERVICE +// +// MessageText: +// +// No unmanaged service is registered with AU. +// +#define WU_E_AU_NO_REGISTERED_SERVICE _HRESULT_TYPEDEF_(0x8024A005L) + +// +// MessageId: WU_E_AU_UNEXPECTED +// +// MessageText: +// +// An Automatic Updates error not covered by another WU_E_AU * code. +// +#define WU_E_AU_UNEXPECTED _HRESULT_TYPEDEF_(0x8024AFFFL) + +////////////////////////////////////////////////////////////////////////////// +// update handler errors +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_UH_REMOTEUNAVAILABLE +// +// MessageText: +// +// A request for a remote update handler could not be completed because no remote process is available. +// +#define WU_E_UH_REMOTEUNAVAILABLE _HRESULT_TYPEDEF_(0x80242000L) + +// +// MessageId: WU_E_UH_LOCALONLY +// +// MessageText: +// +// A request for a remote update handler could not be completed because the handler is local only. +// +#define WU_E_UH_LOCALONLY _HRESULT_TYPEDEF_(0x80242001L) + +// +// MessageId: WU_E_UH_UNKNOWNHANDLER +// +// MessageText: +// +// A request for an update handler could not be completed because the handler could not be recognized. +// +#define WU_E_UH_UNKNOWNHANDLER _HRESULT_TYPEDEF_(0x80242002L) + +// +// MessageId: WU_E_UH_REMOTEALREADYACTIVE +// +// MessageText: +// +// A remote update handler could not be created because one already exists. +// +#define WU_E_UH_REMOTEALREADYACTIVE _HRESULT_TYPEDEF_(0x80242003L) + +// +// MessageId: WU_E_UH_DOESNOTSUPPORTACTION +// +// MessageText: +// +// A request for the handler to install (uninstall) an update could not be completed because the update does not support install (uninstall). +// +#define WU_E_UH_DOESNOTSUPPORTACTION _HRESULT_TYPEDEF_(0x80242004L) + +// +// MessageId: WU_E_UH_WRONGHANDLER +// +// MessageText: +// +// An operation did not complete because the wrong handler was specified. +// +#define WU_E_UH_WRONGHANDLER _HRESULT_TYPEDEF_(0x80242005L) + +// +// MessageId: WU_E_UH_INVALIDMETADATA +// +// MessageText: +// +// A handler operation could not be completed because the update contains invalid metadata. +// +#define WU_E_UH_INVALIDMETADATA _HRESULT_TYPEDEF_(0x80242006L) + +// +// MessageId: WU_E_UH_INSTALLERHUNG +// +// MessageText: +// +// An operation could not be completed because the installer exceeded the time limit. +// +#define WU_E_UH_INSTALLERHUNG _HRESULT_TYPEDEF_(0x80242007L) + +// +// MessageId: WU_E_UH_OPERATIONCANCELLED +// +// MessageText: +// +// An operation being done by the update handler was cancelled. +// +#define WU_E_UH_OPERATIONCANCELLED _HRESULT_TYPEDEF_(0x80242008L) + +// +// MessageId: WU_E_UH_BADHANDLERXML +// +// MessageText: +// +// An operation could not be completed because the handler-specific metadata is invalid. +// +#define WU_E_UH_BADHANDLERXML _HRESULT_TYPEDEF_(0x80242009L) + +// +// MessageId: WU_E_UH_CANREQUIREINPUT +// +// MessageText: +// +// A request to the handler to install an update could not be completed because the update requires user input. +// +#define WU_E_UH_CANREQUIREINPUT _HRESULT_TYPEDEF_(0x8024200AL) + +// +// MessageId: WU_E_UH_INSTALLERFAILURE +// +// MessageText: +// +// The installer failed to install (uninstall) one or more updates. +// +#define WU_E_UH_INSTALLERFAILURE _HRESULT_TYPEDEF_(0x8024200BL) + +// +// MessageId: WU_E_UH_FALLBACKTOSELFCONTAINED +// +// MessageText: +// +// The update handler should download self-contained content rather than delta-compressed content for the update. +// +#define WU_E_UH_FALLBACKTOSELFCONTAINED _HRESULT_TYPEDEF_(0x8024200CL) + +// +// MessageId: WU_E_UH_NEEDANOTHERDOWNLOAD +// +// MessageText: +// +// The update handler did not install the update because it needs to be downloaded again. +// +#define WU_E_UH_NEEDANOTHERDOWNLOAD _HRESULT_TYPEDEF_(0x8024200DL) + +// +// MessageId: WU_E_UH_NOTIFYFAILURE +// +// MessageText: +// +// The update handler failed to send notification of the status of the install (uninstall) operation. +// +#define WU_E_UH_NOTIFYFAILURE _HRESULT_TYPEDEF_(0x8024200EL) + +// +// MessageId: WU_E_UH_INCONSISTENT_FILE_NAMES +// +// MessageText: +// +// The file names contained in the update metadata and in the update package are inconsistent. +// +#define WU_E_UH_INCONSISTENT_FILE_NAMES _HRESULT_TYPEDEF_(0x8024200FL) + +// +// MessageId: WU_E_UH_FALLBACKERROR +// +// MessageText: +// +// The update handler failed to fall back to the self-contained content. +// +#define WU_E_UH_FALLBACKERROR _HRESULT_TYPEDEF_(0x80242010L) + +// +// MessageId: WU_E_UH_TOOMANYDOWNLOADREQUESTS +// +// MessageText: +// +// The update handler has exceeded the maximum number of download requests. +// +#define WU_E_UH_TOOMANYDOWNLOADREQUESTS _HRESULT_TYPEDEF_(0x80242011L) + +// +// MessageId: WU_E_UH_UNEXPECTEDCBSRESPONSE +// +// MessageText: +// +// The update handler has received an unexpected response from CBS. +// +#define WU_E_UH_UNEXPECTEDCBSRESPONSE _HRESULT_TYPEDEF_(0x80242012L) + +// +// MessageId: WU_E_UH_BADCBSPACKAGEID +// +// MessageText: +// +// The update metadata contains an invalid CBS package identifier. +// +#define WU_E_UH_BADCBSPACKAGEID _HRESULT_TYPEDEF_(0x80242013L) + +// +// MessageId: WU_E_UH_POSTREBOOTSTILLPENDING +// +// MessageText: +// +// The post-reboot operation for the update is still in progress. +// +#define WU_E_UH_POSTREBOOTSTILLPENDING _HRESULT_TYPEDEF_(0x80242014L) + +// +// MessageId: WU_E_UH_POSTREBOOTRESULTUNKNOWN +// +// MessageText: +// +// The result of the post-reboot operation for the update could not be determined. +// +#define WU_E_UH_POSTREBOOTRESULTUNKNOWN _HRESULT_TYPEDEF_(0x80242015L) + +// +// MessageId: WU_E_UH_POSTREBOOTUNEXPECTEDSTATE +// +// MessageText: +// +// The state of the update after its post-reboot operation has completed is unexpected. +// +#define WU_E_UH_POSTREBOOTUNEXPECTEDSTATE _HRESULT_TYPEDEF_(0x80242016L) + +// +// MessageId: WU_E_UH_NEW_SERVICING_STACK_REQUIRED +// +// MessageText: +// +// The OS servicing stack must be updated before this update is downloaded or installed. +// +#define WU_E_UH_NEW_SERVICING_STACK_REQUIRED _HRESULT_TYPEDEF_(0x80242017L) + +// +// MessageId: WU_E_UH_UNEXPECTED +// +// MessageText: +// +// An update handler error not covered by another WU_E_UH_* code. +// +#define WU_E_UH_UNEXPECTED _HRESULT_TYPEDEF_(0x80242FFFL) + +////////////////////////////////////////////////////////////////////////////// +// download manager errors +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_DM_URLNOTAVAILABLE +// +// MessageText: +// +// A download manager operation could not be completed because the requested file does not have a URL. +// +#define WU_E_DM_URLNOTAVAILABLE _HRESULT_TYPEDEF_(0x80246001L) + +// +// MessageId: WU_E_DM_INCORRECTFILEHASH +// +// MessageText: +// +// A download manager operation could not be completed because the file digest was not recognized. +// +#define WU_E_DM_INCORRECTFILEHASH _HRESULT_TYPEDEF_(0x80246002L) + +// +// MessageId: WU_E_DM_UNKNOWNALGORITHM +// +// MessageText: +// +// A download manager operation could not be completed because the file metadata requested an unrecognized hash algorithm. +// +#define WU_E_DM_UNKNOWNALGORITHM _HRESULT_TYPEDEF_(0x80246003L) + +// +// MessageId: WU_E_DM_NEEDDOWNLOADREQUEST +// +// MessageText: +// +// An operation could not be completed because a download request is required from the download handler. +// +#define WU_E_DM_NEEDDOWNLOADREQUEST _HRESULT_TYPEDEF_(0x80246004L) + +// +// MessageId: WU_E_DM_NONETWORK +// +// MessageText: +// +// A download manager operation could not be completed because the network connection was unavailable. +// +#define WU_E_DM_NONETWORK _HRESULT_TYPEDEF_(0x80246005L) + +// +// MessageId: WU_E_DM_WRONGBITSVERSION +// +// MessageText: +// +// A download manager operation could not be completed because the version of Background Intelligent Transfer Service (BITS) is incompatible. +// +#define WU_E_DM_WRONGBITSVERSION _HRESULT_TYPEDEF_(0x80246006L) + +// +// MessageId: WU_E_DM_NOTDOWNLOADED +// +// MessageText: +// +// The update has not been downloaded. +// +#define WU_E_DM_NOTDOWNLOADED _HRESULT_TYPEDEF_(0x80246007L) + +// +// MessageId: WU_E_DM_FAILTOCONNECTTOBITS +// +// MessageText: +// +// A download manager operation failed because the download manager was unable to connect the Background Intelligent Transfer Service (BITS). +// +#define WU_E_DM_FAILTOCONNECTTOBITS _HRESULT_TYPEDEF_(0x80246008L) + +// +// MessageId: WU_E_DM_BITSTRANSFERERROR +// +// MessageText: +// +// A download manager operation failed because there was an unspecified Background Intelligent Transfer Service (BITS) transfer error. +// +#define WU_E_DM_BITSTRANSFERERROR _HRESULT_TYPEDEF_(0x80246009L) + +// +// MessageId: WU_E_DM_DOWNLOADLOCATIONCHANGED +// +// MessageText: +// +// A download must be restarted because the location of the source of the download has changed. +// +#define WU_E_DM_DOWNLOADLOCATIONCHANGED _HRESULT_TYPEDEF_(0x8024600AL) + +// +// MessageId: WU_E_DM_CONTENTCHANGED +// +// MessageText: +// +// A download must be restarted because the update content changed in a new revision. +// +#define WU_E_DM_CONTENTCHANGED _HRESULT_TYPEDEF_(0x8024600BL) + +// +// MessageId: WU_E_DM_UNEXPECTED +// +// MessageText: +// +// There was a download manager error not covered by another WU_E_DM_* error code. +// +#define WU_E_DM_UNEXPECTED _HRESULT_TYPEDEF_(0x80246FFFL) + +////////////////////////////////////////////////////////////////////////////// +// Setup/SelfUpdate errors +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_SETUP_INVALID_INFDATA +// +// MessageText: +// +// Windows Update Agent could not be updated because an INF file contains invalid information. +// +#define WU_E_SETUP_INVALID_INFDATA _HRESULT_TYPEDEF_(0x8024D001L) + +// +// MessageId: WU_E_SETUP_INVALID_IDENTDATA +// +// MessageText: +// +// Windows Update Agent could not be updated because the wuident.cab file contains invalid information. +// +#define WU_E_SETUP_INVALID_IDENTDATA _HRESULT_TYPEDEF_(0x8024D002L) + +// +// MessageId: WU_E_SETUP_ALREADY_INITIALIZED +// +// MessageText: +// +// Windows Update Agent could not be updated because of an internal error that caused setup initialization to be performed twice. +// +#define WU_E_SETUP_ALREADY_INITIALIZED _HRESULT_TYPEDEF_(0x8024D003L) + +// +// MessageId: WU_E_SETUP_NOT_INITIALIZED +// +// MessageText: +// +// Windows Update Agent could not be updated because setup initialization never completed successfully. +// +#define WU_E_SETUP_NOT_INITIALIZED _HRESULT_TYPEDEF_(0x8024D004L) + +// +// MessageId: WU_E_SETUP_SOURCE_VERSION_MISMATCH +// +// MessageText: +// +// Windows Update Agent could not be updated because the versions specified in the INF do not match the actual source file versions. +// +#define WU_E_SETUP_SOURCE_VERSION_MISMATCH _HRESULT_TYPEDEF_(0x8024D005L) + +// +// MessageId: WU_E_SETUP_TARGET_VERSION_GREATER +// +// MessageText: +// +// Windows Update Agent could not be updated because a WUA file on the target system is newer than the corresponding source file. +// +#define WU_E_SETUP_TARGET_VERSION_GREATER _HRESULT_TYPEDEF_(0x8024D006L) + +// +// MessageId: WU_E_SETUP_REGISTRATION_FAILED +// +// MessageText: +// +// Windows Update Agent could not be updated because regsvr32.exe returned an error. +// +#define WU_E_SETUP_REGISTRATION_FAILED _HRESULT_TYPEDEF_(0x8024D007L) + +// +// MessageId: WU_E_SELFUPDATE_SKIP_ON_FAILURE +// +// MessageText: +// +// An update to the Windows Update Agent was skipped because previous attempts to update have failed. +// +#define WU_E_SELFUPDATE_SKIP_ON_FAILURE _HRESULT_TYPEDEF_(0x8024D008L) + +// +// MessageId: WU_E_SETUP_SKIP_UPDATE +// +// MessageText: +// +// An update to the Windows Update Agent was skipped due to a directive in the wuident.cab file. +// +#define WU_E_SETUP_SKIP_UPDATE _HRESULT_TYPEDEF_(0x8024D009L) + +// +// MessageId: WU_E_SETUP_UNSUPPORTED_CONFIGURATION +// +// MessageText: +// +// Windows Update Agent could not be updated because the current system configuration is not supported. +// +#define WU_E_SETUP_UNSUPPORTED_CONFIGURATION _HRESULT_TYPEDEF_(0x8024D00AL) + +// +// MessageId: WU_E_SETUP_BLOCKED_CONFIGURATION +// +// MessageText: +// +// Windows Update Agent could not be updated because the system is configured to block the update. +// +#define WU_E_SETUP_BLOCKED_CONFIGURATION _HRESULT_TYPEDEF_(0x8024D00BL) + +// +// MessageId: WU_E_SETUP_REBOOT_TO_FIX +// +// MessageText: +// +// Windows Update Agent could not be updated because a restart of the system is required. +// +#define WU_E_SETUP_REBOOT_TO_FIX _HRESULT_TYPEDEF_(0x8024D00CL) + +// +// MessageId: WU_E_SETUP_ALREADYRUNNING +// +// MessageText: +// +// Windows Update Agent setup is already running. +// +#define WU_E_SETUP_ALREADYRUNNING _HRESULT_TYPEDEF_(0x8024D00DL) + +// +// MessageId: WU_E_SETUP_REBOOTREQUIRED +// +// MessageText: +// +// Windows Update Agent setup package requires a reboot to complete installation. +// +#define WU_E_SETUP_REBOOTREQUIRED _HRESULT_TYPEDEF_(0x8024D00EL) + +// +// MessageId: WU_E_SETUP_HANDLER_EXEC_FAILURE +// +// MessageText: +// +// Windows Update Agent could not be updated because the setup handler failed during execution. +// +#define WU_E_SETUP_HANDLER_EXEC_FAILURE _HRESULT_TYPEDEF_(0x8024D00FL) + +// +// MessageId: WU_E_SETUP_INVALID_REGISTRY_DATA +// +// MessageText: +// +// Windows Update Agent could not be updated because the registry contains invalid information. +// +#define WU_E_SETUP_INVALID_REGISTRY_DATA _HRESULT_TYPEDEF_(0x8024D010L) + +// +// MessageId: WU_E_SELFUPDATE_REQUIRED +// +// MessageText: +// +// Windows Update Agent must be updated before search can continue. +// +#define WU_E_SELFUPDATE_REQUIRED _HRESULT_TYPEDEF_(0x8024D011L) + +// +// MessageId: WU_E_SELFUPDATE_REQUIRED_ADMIN +// +// MessageText: +// +// Windows Update Agent must be updated before search can continue. An administrator is required to perform the operation. +// +#define WU_E_SELFUPDATE_REQUIRED_ADMIN _HRESULT_TYPEDEF_(0x8024D012L) + +// +// MessageId: WU_E_SETUP_WRONG_SERVER_VERSION +// +// MessageText: +// +// Windows Update Agent could not be updated because the server does not contain update information for this version. +// +#define WU_E_SETUP_WRONG_SERVER_VERSION _HRESULT_TYPEDEF_(0x8024D013L) + +// +// MessageId: WU_E_SETUP_UNEXPECTED +// +// MessageText: +// +// Windows Update Agent could not be updated because of an error not covered by another WU_E_SETUP_* error code. +// +#define WU_E_SETUP_UNEXPECTED _HRESULT_TYPEDEF_(0x8024DFFFL) + +////////////////////////////////////////////////////////////////////////////// +// expression evaluator errors +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_EE_UNKNOWN_EXPRESSION +// +// MessageText: +// +// An expression evaluator operation could not be completed because an expression was unrecognized. +// +#define WU_E_EE_UNKNOWN_EXPRESSION _HRESULT_TYPEDEF_(0x8024E001L) + +// +// MessageId: WU_E_EE_INVALID_EXPRESSION +// +// MessageText: +// +// An expression evaluator operation could not be completed because an expression was invalid. +// +#define WU_E_EE_INVALID_EXPRESSION _HRESULT_TYPEDEF_(0x8024E002L) + +// +// MessageId: WU_E_EE_MISSING_METADATA +// +// MessageText: +// +// An expression evaluator operation could not be completed because an expression contains an incorrect number of metadata nodes. +// +#define WU_E_EE_MISSING_METADATA _HRESULT_TYPEDEF_(0x8024E003L) + +// +// MessageId: WU_E_EE_INVALID_VERSION +// +// MessageText: +// +// An expression evaluator operation could not be completed because the version of the serialized expression data is invalid. +// +#define WU_E_EE_INVALID_VERSION _HRESULT_TYPEDEF_(0x8024E004L) + +// +// MessageId: WU_E_EE_NOT_INITIALIZED +// +// MessageText: +// +// The expression evaluator could not be initialized. +// +#define WU_E_EE_NOT_INITIALIZED _HRESULT_TYPEDEF_(0x8024E005L) + +// +// MessageId: WU_E_EE_INVALID_ATTRIBUTEDATA +// +// MessageText: +// +// An expression evaluator operation could not be completed because there was an invalid attribute. +// +#define WU_E_EE_INVALID_ATTRIBUTEDATA _HRESULT_TYPEDEF_(0x8024E006L) + +// +// MessageId: WU_E_EE_CLUSTER_ERROR +// +// MessageText: +// +// An expression evaluator operation could not be completed because the cluster state of the computer could not be determined. +// +#define WU_E_EE_CLUSTER_ERROR _HRESULT_TYPEDEF_(0x8024E007L) + +// +// MessageId: WU_E_EE_UNEXPECTED +// +// MessageText: +// +// There was an expression evaluator error not covered by another WU_E_EE_* error code. +// +#define WU_E_EE_UNEXPECTED _HRESULT_TYPEDEF_(0x8024EFFFL) + +////////////////////////////////////////////////////////////////////////////// +// UI errors +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_INSTALLATION_RESULTS_UNKNOWN_VERSION +// +// MessageText: +// +// The results of download and installation could not be read from the registry due to an unrecognized data format version. +// +#define WU_E_INSTALLATION_RESULTS_UNKNOWN_VERSION _HRESULT_TYPEDEF_(0x80243001L) + +// +// MessageId: WU_E_INSTALLATION_RESULTS_INVALID_DATA +// +// MessageText: +// +// The results of download and installation could not be read from the registry due to an invalid data format. +// +#define WU_E_INSTALLATION_RESULTS_INVALID_DATA _HRESULT_TYPEDEF_(0x80243002L) + +// +// MessageId: WU_E_INSTALLATION_RESULTS_NOT_FOUND +// +// MessageText: +// +// The results of download and installation are not available; the operation may have failed to start. +// +#define WU_E_INSTALLATION_RESULTS_NOT_FOUND _HRESULT_TYPEDEF_(0x80243003L) + +// +// MessageId: WU_E_TRAYICON_FAILURE +// +// MessageText: +// +// A failure occurred when trying to create an icon in the taskbar notification area. +// +#define WU_E_TRAYICON_FAILURE _HRESULT_TYPEDEF_(0x80243004L) + +// +// MessageId: WU_E_NON_UI_MODE +// +// MessageText: +// +// Unable to show UI when in non-UI mode; WU client UI modules may not be installed. +// +#define WU_E_NON_UI_MODE _HRESULT_TYPEDEF_(0x80243FFDL) + +// +// MessageId: WU_E_WUCLTUI_UNSUPPORTED_VERSION +// +// MessageText: +// +// Unsupported version of WU client UI exported functions. +// +#define WU_E_WUCLTUI_UNSUPPORTED_VERSION _HRESULT_TYPEDEF_(0x80243FFEL) + +// +// MessageId: WU_E_AUCLIENT_UNEXPECTED +// +// MessageText: +// +// There was a user interface error not covered by another WU_E_AUCLIENT_* error code. +// +#define WU_E_AUCLIENT_UNEXPECTED _HRESULT_TYPEDEF_(0x80243FFFL) + +////////////////////////////////////////////////////////////////////////////// +// reporter errors +/////////////////////////////////////////////////////////////////////////////// +// +// MessageId: WU_E_REPORTER_EVENTCACHECORRUPT +// +// MessageText: +// +// The event cache file was defective. +// +#define WU_E_REPORTER_EVENTCACHECORRUPT _HRESULT_TYPEDEF_(0x8024F001L) + +// +// MessageId: WU_E_REPORTER_EVENTNAMESPACEPARSEFAILED +// +// MessageText: +// +// The XML in the event namespace descriptor could not be parsed. +// +#define WU_E_REPORTER_EVENTNAMESPACEPARSEFAILED _HRESULT_TYPEDEF_(0x8024F002L) + +// +// MessageId: WU_E_INVALID_EVENT +// +// MessageText: +// +// The XML in the event namespace descriptor could not be parsed. +// +#define WU_E_INVALID_EVENT _HRESULT_TYPEDEF_(0x8024F003L) + +// +// MessageId: WU_E_SERVER_BUSY +// +// MessageText: +// +// The server rejected an event because the server was too busy. +// +#define WU_E_SERVER_BUSY _HRESULT_TYPEDEF_(0x8024F004L) + +// +// MessageId: WU_E_REPORTER_UNEXPECTED +// +// MessageText: +// +// There was a reporter error not covered by another error code. +// +#define WU_E_REPORTER_UNEXPECTED _HRESULT_TYPEDEF_(0x8024FFFFL) + +// +// MessageId: WU_E_OL_INVALID_SCANFILE +// +// MessageText: +// +// An operation could not be completed because the scan package was invalid. +// +#define WU_E_OL_INVALID_SCANFILE _HRESULT_TYPEDEF_(0x80247001L) + +// +// MessageId: WU_E_OL_NEWCLIENT_REQUIRED +// +// MessageText: +// +// An operation could not be completed because the scan package requires a greater version of the Windows Update Agent. +// +#define WU_E_OL_NEWCLIENT_REQUIRED _HRESULT_TYPEDEF_(0x80247002L) + +// +// MessageId: WU_E_OL_UNEXPECTED +// +// MessageText: +// +// Search using the scan package failed. +// +#define WU_E_OL_UNEXPECTED _HRESULT_TYPEDEF_(0x80247FFFL) + +#endif //_WUERROR_ diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix/iisca.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix/iisca.wxs new file mode 100644 index 0000000000..5bf076f74d --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix/iisca.wxs @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + NOT SKIPINSTALLCA AND NOT( REMOVE="ALL" ) + NOT SKIPUNINSTALLCA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NOT SKIPINSTALLWINDOWSHOTFIX + NOT SKIPREBOOTIFREQUIRED + + + + + + + + + + + + + + + + + NOT SKIPMAKESHORTCUTELEVATED + + + + + + + + + + + + + + + + + + + + + + + NOT SKIPSETCONSOLEPROPERTIES + + + + + + + + + + + + + + + + + + + + + + + + NOT SKIPINSTALLHTTPLISTENER + NOT SKIPUNINSTALLHTTPLISTENER + + + + + + + + + + + Installed And PATCH + Installed And PATCH + Installed And PATCH + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix/setupstrings.wxl new file mode 100644 index 0000000000..ccb1a67cfb --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix/setupstrings.wxl @@ -0,0 +1,255 @@ + + + + + + + 1033 + + + + Shared Config Install Options + Select option for installation to IIS shared configuration + Update shared configuration on install + You are installing this module onto an IIS server that is using shared configuration. If additional IIS servers are using this shared configuration then you will need to install this module onto all of these machines. To minimize disruption of the individual web servers you will need to install this module in the following steps: First, on all but the last of the machines you should install the module without updating shared config. Do this by not selecting the checkbox + below. This will install all binaries and files necessary for the module on each machine without making any changes to shared config. Second, on the last machine you will need to verify that the user idenity you are running under has read and write access to the applicationhost.config file on the UNC share. Then you should install the module and select the update shared config option below. + + + Initializing WebConfig custom action + Updating web.config + + + + IIS Advanced Logging + Enables advanced logging of IIS pipeline data. + IIS Advanced Logging + Enables creation of custom log files with extensible field selection. + Update for IIS Advanced Logging + + + + IIS Transform Manager + Beta + Enables the Transform Manager IIS Media Services. + IIS Transform Manager + Enables creation of media transforms. + IIS Transform Manager Host + Service host for [ProductName]. + IIS Transform Manager + Batch convert on-demand media files to alternate file and container formats. + An IIS Transform Manager 1.0 Expression Encoder SP Task package is installed on the computer. You must uninstall it before you can install [ProductName]. + + Microsoft .NET Framework 3.5 is required to install [ProductName]. Use the 'Add Features Wizard' in Server Manager to install .NET Framework 3.5.1 Features or use 'Turn Windows features on or off' to turn on Microsoft .NET Framework 3.5. + [ProductName] requires Microsoft Windows Vista Service Pack 1 or later. + [ProductName] cannot be installed on Vista Home Basic. + [ProductName] requires Microsoft Windows 7 Service Pack 1 or later. + + + Microsoft Web Management Service 2 + Microsoft Web Management Service + Installs the basic features of the [ProductName]. + Microsoft Web Management Service 2 + The Web Management Service enables remote and delegated management capabilities for administrators to manage for the Web server, sites and applications present on this machine. + + + Microsoft URL Rewrite Module 1.1 for IIS 7 + Update for URL Rewrite Module 1.1 for IIS 7 + URL Rewrite + Enables URL and content rewriting capabilities to IIS 7. + User Interface + Configures the URL Rewrite Module feature in IIS Manager. + + + IIS URL Rewrite Module 2 + Update for IIS URL Rewrite Module 2 + URL Rewrite + Enables URL and content rewriting capabilities to IIS 7. + User Interface + Configures the URL Rewrite Module feature in IIS Manager. + + + Administration Pack for IIS 7.0 + Installs the basic features of the [ProductName]. + 1252 + Administration Pack for IIS 7.0 + Microsoft Corporation + This version of the operating system is not supported. [ProductName] can be installed only on Windows Server 2008, or Windows Vista Service Pack 1, and higher. + ASP.Net Features + ASP.NET includes Authorization and Error Pages features, which let you manage your authorization and custom error settings. + Authentication + ASP.Net Authentication Description. + Authorization + ASP.NET Authorization lets you configure rules for authorizing users to access your Web sites and applications. + Error Pages + ASP.NET Error Pages lets you configure HTTP error responses to return when errors occur. + Modules + ASP.Net Modules Description. + Handlers + ASP.Net Handers Description. + Configuration Editor + Configuration Editor lets you manage your configuration files in IIS Manager by letting you edit sections, attributes, elements, and collections in your configuration files. + Request Filtering + Request Filtering lets you configure filtering rules for your Web site, and restrict protocol and content behavior. + Fast CGI + FastCGI lets you configure process pool settings for the FastCGI applications on your Web server. + + + Dynamic IP Restrictions for IIS 7 Setup + + + + + + + + + + + + + Dynamic IP Restrictions for IIS 7 - Beta + Dynamic IP Restrictions for IIS 7 - Beta 2 + Dynamic IP Restrictions for IIS 7 - Beta 3 + + Dynamic IP Restrictions for IIS 7 - Release Candidate + Dynamic IP Restrictions for IIS 7 - Release Candidate 2 + Dynamic IP Restrictions for IIS 7 - Release Candidate 3 + + Dynamic IP Restrictions for IIS 7 + + Dynamic IP Restrictions for IIS 7 + Dynamic IP Restrictions User Interface for IIS 7 + + Dynamic IP Restrictions for IIS 7 - Beta was found on this machine. Please uninstall it and try again + + + WebDAV 7.5 For IIS 7.0 + The IIS 7.0 CoreWebEngine and W3SVC features must be installed to use this product. + WebDAV Server Module + WebDAV Administration User Interface + + + IIS Search Engine Optimization Toolkit 1.0 + IIS Search Engine Optimization Toolkit 1.0 + Search Engine Optimization (SEO) Toolkit 1.0 + This installer database contains the logic and data required to install IIS Search Engine Optimization Toolkit 1.0. + + + IIS Editor + + + IIS Reports + Log Parser is not installed on this machine, Please install Log Parser 2.2 from http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07 and then proceed with IIS Reports installation + + + Microsoft Web Farm Framework + Microsoft External Cache + Web Farm Framework is a requisite for installing Application Request Routing. Please install the Web Farm Framework. + Microsoft Application Request Routing 3.0 + Runtime + Adds the Application Request Routing capabilities to IIS. + User Interface + Configures the Application Request Routing feature in IIS Manager. + + + Microsoft CORS Module + IIS CORS Runtime + Adds the support of cross-origin resource sharing (CORS) to IIS. + + + Microsoft IIS Compression + IIS Compression + Adds the Zlib and Brotli compression schemes to IIS. + + + IIS Team Template Module + Template Module Runtime + An example of an IIS module. + + + Microsoft Windows PowerShell snap-in for IIS 7.0 + + + IIS Manager Publishing for IIS 7.0 + Publishing User Interface + + + Application Warm-Up 1.0 for IIS 7.5 + + + + An incompatible product, [CONFLICTING_PRODUCT_NAME], is on this computer. Installation of [ProductName] cannot continue. To install this product, use Add/Remove Programs on the Control Panel to remove [CONFLICTING_PRODUCT_NAME]. + Administrator privilege is required to install [ProductName]. + IIS Version 7.0 is required to use [ProductName]. + IIS Version 7.0 or greater is required to install [ProductName]. + IIS Version 7.5 or greater is required to install [ProductName]. + IIS Version 7 or 7.5 is required to install [ProductName]. + IIS Version 8.0 or greater is required to install [ProductName]. + The beta version of [ProductName] was found on this machine. + A newer version of [ProductName] was found on this machine. + Setup cannot continue because another instance of [ProductName] is already installed on this computer. Please uninstall it first and then re-launch this installation. + The IIS 7.0 CoreWebEngine and W3SVC features must be installed to use [ProductName]. + The IIS Management Console must be installed to use [ProductName]. + Please stop both services Windows Process Activation Service (WAS) and Web Management Service (WMSvc) before installing [ProductName]. You will need to start the services after installing [ProductName]. + IIS Metabase is required to install [ProductName]. + The 64-bit version of [ProductName] cannot be installed on a 32-bit edition of Microsoft Windows. + The 32-bit version of [ProductName] cannot be installed on a 64-bit edition of Microsoft Windows. + Microsoft .NET Framework Version 2.0 or greater is required to install [ProductName]. + Microsoft .NET Framework Version 3.5 or greater is required to install [ProductName]. Use 'Add Features' under the Server Manager to install Microsoft .Net Version 3.5. + Microsoft .NET Framework Version 4.0 or greater is required to install [ProductName]. + Please install Microsoft .NET Framework Version 2.0 Service Pack 1 (or a later service pack), before installing [ProductName]. + The Windows Update (wuauserv) service cannot be disabled, it is required to install [ProductName]. + The PowerShell snap-in is part of Windows Operating System. Please install it via 'Programs and Features' or 'Server Manager'. + Microsoft Web Platform Installer Version 3.0 or greater is required to install [ProductName]. + + Setup failed to detect shared configuration. + Shared configuration is enabled for IIS. Installing [ProductName] is not supported when using shared configuration. Please disable shared configuration before installing this feature. + + Please stop World Wide Web Publishing Service (W3SVC) before installing [ProductName]. You will need to start the service after installation. + IIS PowerShell Management Console + IIS PowerShell snap-in + IIS PowerShell snap-in requires PowerShell v1.0 or v2.0 installed + IIS PowerShell snap-in requires WAS and configuration installed + This is a bogus string. + + + Microsoft Web Farm Framework Version 2.2 + Microsoft Web Farm Agent Version 2.2 + Web Farm Service + Web Farm Service + Web Farm Controller Service + Web Farm Controller Service + Web Farm Agent Service + Web Farm Agent Service + Web Platform Installer is a pre-requisite for installing Web Farm Framework. Please install the Web Plaform Installer from http://www.microsoft.com/web/downloads/platform.aspx. + Web Deployment Tool is a pre-requisite for installing Web Farm Framework. Please install the Web Deployment Tool from http://www.iis.net/download/WebDeploy. + + + Microsoft Web Hosting Framework + Web Hosting Framework + Web Hosting roles and features. + Hosting Framework + Hosting Framework provides API's and PowerShell commands for managing the Web Hosting. + Web Role + Web Role installs Dynamic WAS service and URL Rewrite provider for Web Hosting. + Antares Express + Deploys a Control Panel configuration optimized for single machine setup. + Load Balancer Role + Load Balancer Role configures Application Request Router to route based on Web Hosting rules. + Hosting Controller + Hosting Controller extends the Web Farm Framework 2.0 to work with Web Hosting. + Publishing Role + Installs support for Web Deploy and FTP publishing. + This is a PowerShell snap-in that contains cmdlets for managing Microsoft Web Hosting infrastructure. + Dynamic WAS Service + Windows Process Activation service optimized for high density Web Hosting. + Resource Metering Service + Installs the Resource Metering service that enables collecting and publishing both runtime and health information. + Resource Metering + Enables collecting and publishing runtime and health information from Web Role. + Hosting Quota Enforcement + Monitors the web sites resource usage and executes custom actions when usage quota is exceeded. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/ElevatedShortcut.wxi b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/ElevatedShortcut.wxi new file mode 100644 index 0000000000..ee5e988a1b --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/ElevatedShortcut.wxi @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + NOT SKIPMAKESHORTCUTELEVATED + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/FixPatchingBehavior.wxi b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/FixPatchingBehavior.wxi new file mode 100644 index 0000000000..ae6e3b76d5 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/FixPatchingBehavior.wxi @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + Installed And PATCH + Installed And PATCH + Installed And PATCH + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/HttpListener.wxi b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/HttpListener.wxi new file mode 100644 index 0000000000..68db6852d1 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/HttpListener.wxi @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NOT SKIPINSTALLHTTPLISTENER + NOT SKIPUNINSTALLHTTPLISTENER + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/ShortcutConsoleProperties.wxi b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/ShortcutConsoleProperties.wxi new file mode 100644 index 0000000000..236e0f51ef --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/ShortcutConsoleProperties.wxi @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + NOT SKIPSETCONSOLEPROPERTIES + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/WindowsHotfix.wxi b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/WindowsHotfix.wxi new file mode 100644 index 0000000000..78b26d6404 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/WindowsHotfix.wxi @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + NOT SKIPINSTALLWINDOWSHOTFIX + NOT SKIPREBOOTIFREQUIRED + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/iisca.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/iisca.wxs new file mode 100644 index 0000000000..68324e1484 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/iisca/wix3/iisca.wxs @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + NOT SKIPINSTALLCA + (NOT SKIPUNINSTALLCA) AND (IISCOREWEBENGINEINSTALLED = "#1") AND (IISW3SVCINSTALLED = "#1") + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/include.wxi b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/include.wxi new file mode 100644 index 0000000000..e22cdce8a4 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/include.wxi @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/CHS/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/CHS/misc/setupstrings.wxl new file mode 100644 index 0000000000..3acd415df3 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/CHS/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 2052 + + + + 共享配置安装选项 + 选择用于安装到 IIS 共享配置的选项 + 安装时更新共享配置 + 您要将此模块安装到使用共享配置的 IIS 服务器上。如果其他 IIS 服务器正在使用此共享配置,则您需要将此模块安装到所有这些计算机上。为了尽可能减少对各个 Web 服务器的中断,您需要按以下步骤安装此模块: 首先,在除最后一台计算机外的所有其他计算机上,安装此模块但不更新共享配置。可通过不选中下面的复选框来执行 +此操作。这将在每台计算机上安装模块所需的所有二进制文件和其他文件,而不对共享配置进行任何更改。其次,在最后一台计算机上,您需要确保运行时使用的用户标识对 UNC 共享上的 applicationhost.config 文件具有读取和写入权限。然后,您应安装此模块并选中下面的更新共享配置选项。 + + + 正在初始化 WebConfig 自定义操作 + 正在更新 web.config + + + + IIS 高级日志 + 启用 IIS 管道数据高级日志。 + IIS 高级日志 + 允许通过选择可扩展的字段来创建自定义日志文件。 + 适用于 IIS 高级日志记录的更新 + + + + IIS Transform Manager + Beta + 启用 Transform Manager IIS 媒体服务。 + IIS Transform Manager + 允许创建媒体转换。 + IIS Transform Manager 主机 + [ProductName] 的服务主机。 + IIS Transform Manager + 根据需要将媒体文件批量转换为其他文件和容器格式。 + 计算机上安装了某个 IIS Transform Manager 1.0 表达式编码器 SP 任务包。您必须先将它卸载,然后才能安装 [ProductName]。 + + 安装 [ProductName] 需要 Microsoft .NET Framework 3.5。可在服务器管理器中使用“添加功能向导”来安装 .NET Framework 3.5.1 功能,或使用“打开或关闭 Windows 功能”来打开 Microsoft .NET Framework 3.5。 + + + + IIS 数字版权管理 + Beta + 启用平滑流式处理演示的数字版权管理。 + + + 未安装 ASP.NET + + + + + + + + + 此计算机上找到了 IIS 平滑流式处理 - Beta。无法继续安装 [ProductName]。若要安装此产品,请使用控制面板中的“添加/删除程序”将 IIS 平滑流式处理 - Beta 删除。 + 此计算机上装有 IIS Media Services 的不兼容版本。无法继续安装 [ProductName]。若要安装此产品,请使用控制面板中的“添加/删除程序”将 IIS Media Services 删除。 + 此计算机上已安装了该产品的新版本,或者可以在此计算机上安装该产品的新版本。无法继续安装 [ProductName]。若要安装该产品的新版本,请使用控制面板上的“添加/删除程序”更新 IIS Media Services。 + 需要进行播放列表文件转换 + + + + + 发现早期版本的 IIS Media Services 文件 + + + + + 发现 Beta IIS Media Services 文件 + + + + + + IIS Media Pack 1.0 + 适用于 IIS Media Pack 1.0 的更新 + IIS Media Services 2.0 + 适用于 IIS Media Services 2.0 的更新 + IIS Media Services 3.0 + IIS Media Services 3.0 TAP 2 + 适用于 IIS Media Services 3.0 的更新 + IIS Media Services 功能和工具。 + IIS Media Services 5 Premium 功能和工具。 + IIS Media Services 4.0 Beta 1 + IIS Media Services 4.0 + IIS Media Services 4.5 Beta 1 + IIS Media Services 5 Premium + + Web 播放列表 + 对客户端播放在播放列表中引用的媒体资产的行为进行控制。 + 会话帮助程序 + 启用 ASP.NET 会话状态持续性。(需要适用于 Web 服务器(IIS)的 ASP.NET 角色服务)。 + 用户界面 + 在 IIS 管理器中配置 Web 播放列表功能。 + + 比特率限制 + 对客户端下载的文件的传送进行限制,从而节省带宽。 + 用户界面 + 在 IIS 管理器中配置比特率限制功能。 + + 资产 + 对客户端的按需资产启用 HTTP 自适应流式处理。 + 用户界面 + 在 IIS 管理器中配置平滑流式处理功能。 + + 频道 + 对客户端的频道广播启用 HTTP 自适应流式处理。 + 用户界面 + 在 IIS 管理器中配置实时平滑流式处理功能。 + + 数字版权管理 + 提供平滑流式处理媒体的加密和许可。 + 用户界面 + 配置 IIS 管理器中的数字版权管理功能。 + + [ProductName] 需要 Microsoft Windows Vista Service Pack 1 或更高版本。 + 无法在 Vista Home Basic 上安装 [ProductName]。 + [ProductName] 需要 Microsoft Windows 7 Service Pack 1 或更高版本。 + + + IIS 数据库管理器 + IIS 数据库管理器 + + + Microsoft Web 管理服务 2 + Microsoft Web 管理服务 + 安装 [ProductName] 的基本功能。 + Microsoft Web 管理服务 2 + Web 管理服务提供远程和委派管理功能,供管理员管理位于此计算机上的 Web 服务器、站点和应用程序。 + + + 用于 IIS 7 的 Microsoft URL 重写模块 1.1 + 对用于 IIS 7 的 URL 重写模块 1.1 的更新 + URL 重写 + 对 IIS 7 启用 URL 和内容重写功能。 + 用户界面 + 在 IIS 管理器中配置 URL 重写模块功能。 + + + IIS URL 重写模块 2 + 适用于 IIS URL 重写模块 2 的更新 + URL 重写 + 对 IIS 7 启用 URL 和内容重写功能。 + 用户界面 + 在 IIS 管理器中配置 URL 重写模块功能。 + + + Administration Pack for IIS 7.0 + 安装 [ProductName] 的基本功能。 + 1252 + Administration Pack for IIS 7.0 + Microsoft Corporation + 不支持此操作系统版本。[ProductName] 只能安装在 Windows Server 2008 或 Windows Vista Service Pack 1 及更高版本上。 + ASP.Net 功能 + ASP.NET 包括“授权”和“错误页”功能,利用这些功能,您可以管理您的授权和自定义错误设置。 + 身份验证 + ASP.Net 身份验证说明。 + 授权 + 利用 ASP.NET 授权,您可以配置规则,以便允许用户访问您的网站和应用程序。 + 错误页 + 利用 ASP.NET 错误页,您可以配置要在发生错误时返回的 HTTP 错误响应。 + 模块 + ASP.Net 模块说明。 + 处理程序 + ASP.Net 处理程序说明。 + 配置编辑器 + 利用配置编辑器,您可以编辑配置文件中的节、属性、元素和集合,从而在 IIS 管理器中管理配置文件。 + 请求筛选 + 利用请求筛选,您可以为您的网站配置筛选规则,并限制协议和内容行为。 + FastCGI + 利用 FastCGI,您可以在 Web 服务器上为 FastCGI 应用程序配置进程池设置。 + + + 安装 Dynamic IP Restrictions for IIS 7 + + + + + + + + + + + + + Dynamic IP Restrictions for IIS 7 - Beta + Dynamic IP Restrictions for IIS 7 - Beta 2 + Dynamic IP Restrictions for IIS 7 - Beta 3 + + Dynamic IP Restrictions for IIS 7 - 候选发布 + Dynamic IP Restrictions for IIS 7 - 候选发布 2 + Dynamic IP Restrictions for IIS 7 - 候选发布 3 + + Dynamic IP Restrictions for IIS 7 - RTW + + Dynamic IP Restrictions for IIS 7 + Dynamic IP Restrictions for IIS 7 用户界面 + + IIS 7 的动态 IP 限制 - 在此计算机上找到 Beta 版本。请卸载它,然后重试 + + + WebDAV 7.5 For IIS 7.0 + 若要使用此产品,必须安装 IIS 7.0 CoreWebEngine 和 W3SVC 功能。 + WebDAV 服务器模块 + WebDAV 管理用户界面 + + + IIS 搜索引擎优化工具包 1.0 + IIS 搜索引擎优化工具包 1.0 + 搜索引擎优化(SEO)工具包 1.0 + 此安装程序数据库包含安装 IIS 搜索引擎优化工具包 1.0 所需的逻辑和数据。 + + + IIS 编辑器 + + + IIS Reports + 未在此计算机上安装 Log Parser,请通过 http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07 安装 Log Parser 2.2,然后继续安装 IIS Reports + + + 未找到系统必备包。请运行 setup.exe 以解析依赖关系并安装此程序。 + Microsoft SQL Server 2008 管理对象是安装 IIS 数据库管理器的必备组件。可以从 http://go.microsoft.com/fwlink/?LinkID=150946 安装 Micrsoft SQL Server 2008 管理对象。 + Microsoft SQL Server System CLR Types 是安装 IIS 数据库管理器的必备组件。可以从 http://go.microsoft.com/fwlink/?LinkID=150949 安装 Microsoft SQL Server System CLR Types。 + + + Microsoft Web Farm Framework + Microsoft External Cache + Web Farm Framework 是安装 Application Request Routing 的必备组件。请安装 Web Farm Framework。 + Microsoft Application Request Routing 2.5 + 运行时 + 向 IIS 7 添加 Application Request Routing 功能。 + 用户界面 + 在 IIS 管理器中配置应用程序请求路由功能。 + + + 用于 IIS 7.0 的 Microsoft Windows PowerShell 管理单元 + + + Microsoft Web 平台安装程序 4.0 + Microsoft Web 平台安装程序 + [ProductName] 需要 Windows XP SP2、Windows 2003 SP1、Windows Vista 或更高版本。 + [ProductName] 需要 Windows XP Service Pack 3、Windows Server 2003 Service Pack 2 或更高版本。 + + + Microsoft Windows Azure 服务安装程序 + Microsoft Windows Azure 服务安装程序 + + + Internet Information Services (IIS) 7+ 管理器 + IIS 管理器客户端 + 远程支持 + 此产品需要 Windows XP SP2、Windows 2003 SP1、Windows Vista SP1 或 Windows 7 或更高版本 + 未安装 IIS 管理控制台,但需要此控制台才能管理远程 IIS 服务器。在安装远程管理支持之前,请先安装 IIS 管理控制台,方法是打开“控制面板”->“程序”->“打开或关闭 Windows 功能”,然后在 Ineternet Information Services 功能中选择 IIS 管理控制台。 + 此产品在 Windows Server 2008、Windows Server 2008 R2 或更高版本中不是必需的。请打开服务器管理器并在 Web 服务器角色的角色服务中选择 IIS 管理控制台,从而安装 IIS 管理控制台。 + + + IIS Manager Publishing for IIS 7.0 + Publishing 用户界面 + + + Application Warm-Up 1.0 for IIS 7.5 + + + + 此计算机上安装了不兼容的产品 [CONFLICTING_PRODUCT_NAME]。无法继续安装 [ProductName]。要安装此产品,请使用控制面板上的“添加/删除程序”来删除 [CONFLICTING_PRODUCT_NAME]。 + 若要安装 [ProductName],需要管理员特权。 + 若要使用 [ProductName],需要 IIS 7.0 版。 + 若要安装 [ProductName],需要 IIS 7.0 版或更高版本。 + 安装 [ProductName] 必须具有 IIS 7.5 版或更高版本。 + 要安装 [产品名称],要求使用 IIS 版本 7 或 7.5。 + 已在此计算机上找到 [ProductName] 的 Beta 版本。 + 已在此计算机上找到 [ProductName] 的新版本。 + 安装程序无法继续,因为已在此计算机上安装了另一个 [ProductName] 实例。请先将其卸载,然后重新启动此安装。 + 若要使用 [ProductName],必须安装 IIS 7.0 CoreWebEngine 和 W3SVC 功能。 + 要使用 [ProductName],必须安装 IIS 管理控制台。 + 请先停止 Windows Process Activation Service (WAS)和 Web 管理服务(WMSvc),然后安装 [ProductName]。您将需要在安装 [ProductName] 后启动这两个服务。 + 若要安装 [ProductName],需要 IIS 元数据库。 + 无法在 32 位版本的 Microsoft Windows 上安装 64 位版本的 [ProductName]。 + 无法在 64 位版本的 Microsoft Windows 上安装 32 位版本的 [ProductName]。 + 若要安装 [ProductName],需要 Microsoft .NET Framework 2.0 版或更高版本。 + 需要有 Microsoft .NET Framework 3.5 版或更高版本才能安装 [ProductName]。使用“服务器管理器”下的“添加功能”可安装 Microsoft .Net 3.5 版。 + 需要有 Microsoft .NET Framework 4.0 版或更高版本才能安装 [ProductName]。 + 请先安装 Microsoft .NET Framework 2.0 Service Pack 1(或更高版本的 Service Pack),然后再安装 [ProductName]。 + 不能禁用 Windows Update (wuauserv)服务,安装 [ProductName] 需要此服务。 + PowerShell 管理单元是 Windows 操作系统的一部分。请通过“程序和功能”或“服务器管理器”来安装它。 + 需要有 Microsoft Web 平台安装程序 3.0 版或更高版本才能安装 [ProductName]。 + + 安装程序无法检测到共享配置。 + 已为 IIS 启用了共享配置。使用共享配置时,不支持安装 [ProductName]。请先禁用共享配置,然后再安装此功能。 + + 请在安装 [ProductName] 之前停止 World Wide Web 发布服务(W3SVC)。您将需要在安装后启动此服务。 + IIS PowerShell 管理控制台 + IIS PowerShell 管理单元 + IIS PowerShell 管理单元要求安装 PowerShell v1.0 或 v2.0 + IIS PowerShell 管理单元要求安装 WAS 和配置 + 这是一个假字符串。 + + + Microsoft Web Farm Framework 版本 2.2 + Microsoft Web 场代理版本 2.2 + Web 场服务 + Web 场服务 + Web 场控制器服务 + Web 场控制器服务 + Web 场代理服务 + Web 场代理服务 + Web 平台安装程序是安装 Web Farm Framework 的必备组件。请从 http://www.microsoft.com/web/downloads/platform.aspx 安装 Web 平台安装程序。 + Web 部署工具是安装 Web Farm Framework 的必备组件。请从 http://www.iis.net/download/WebDeploy 安装 Web 部署工具。 + + + Microsoft Web Hosting 框架 + Web Hosting 框架 + Web Hosting 角色和功能。 + Hosting 框架 + Hosting 框架提供用于管理 Web Hosting 的 API 和 PowerShell 命令。 + Web 角色 + Web 角色为 Web Hosting 安装动态 WAS 服务和 URL 重写提供程序。 + Antares Express + 部署已针对单一计算机设置优化的控制面板配置。 + 负载平衡器角色 + 负载平衡器将应用程序请求路由器配置为基于 Web Hosting 规则进行路由。 + Hosting 控制器 + Hosting 控制器扩展了 Web Farm Framework 2.0,使之能够与 Web Hosting 一起使用。 + 发布角色 + 安装针对 Web Deploy 和 FTP 发布功能的支持。 + 这是 PowerShell 管理单元,其中包含用于管理 Microsoft Web Hosting 基础架构的 cmdlet。 + 动态 WAS 服务 + 已为高密度 Web Hosting 优化了 Windows Process Activation Service。 + 资源计量服务 + 安装资源计量服务,该服务可以收集和发布运行时信息和运行状况信息。 + 资源计量 + 允许从 Web 角色收集和发布运行时信息与运行状况信息。 + 强制实施宿主配额 + 监视网站资源使用情况,并在超出使用配额时执行自定义操作。 + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/CHT/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/CHT/misc/setupstrings.wxl new file mode 100644 index 0000000000..fc4295abf7 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/CHT/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 1028 + + + + 共用設定安裝選項 + 請選取安裝 IIS 共用設定的選項 + 在安裝時更新共用設定 + 您正在將這個模組安裝到使用共用設定的 IIS 伺服器上。如果有其他 IIS 伺服器也使用這個共用設定,您必須將這個模組安裝到所有電腦。若要將個別網頁伺服器發生中斷的情形降至最低,您必須依照下列步驟安裝這個模組: 首先,在所有電腦上 (最後一部電腦例外) 安裝模組,而且不要更新共用設定。請不要選取下面的核取方塊。 +這將會為每部電腦上的模組安裝所有二進位檔和必要檔案,而不會對共用設定進行任何變更。第二,在最後一部電腦上,您必須確認執行作業所使用的使用者識別具有讀取和寫入 UNC 共用上 applicationhost.config 檔案的權限。然後,您應安裝模組並選取下面的更新共用設定選項。 + + + 正在初始化 WebConfig 自訂動作 + 正在更新 web.config + + + + IIS 進階記錄 + 啟用 IIS 管線資料的進階記錄。 + IIS 進階記錄 + 啟用以可延伸的欄位選擇建立自訂記錄檔。 + IIS Advanced Logging 的更新 + + + + IIS Transform Manager + Beta + 啟用 Transform Manager IIS Media Services。 + IIS Transform Manager + 啟用媒體轉換的建立。 + IIS Transform Manager 主機 + [ProductName] 的服務主機。 + IIS Transform Manager + 將隨選媒體檔案批次轉換為替代的檔案及容器格式。 + IIS Transform Manager 1.0 Expression Encoder SP Task 套件已安裝於電腦。您必須先將它解除安裝,才能安裝 [ProductName]。 + + 需要 Microsoft .NET Framework 3.5 才能安裝 [ProductName]。請使用 [\[]伺服器管理員[\]] 中的 [\[]新增功能精靈[\]] 安裝 .NET Framework 3.5.1 功能,或者使用 [\[]開啟或關閉 Windows 功能[\]] 開啟 Microsoft .NET Framework 3.5。 + + + + IIS 數位版權管理 + Beta + 啟用 Smooth Streaming 展示檔的數位版權管理。 + + + 未安裝 ASP.NET + + + + + + + + + 在這部電腦上找到 IIS Smooth Streaming - Beta。[ProductName] 的安裝無法繼續。若要安裝這個產品,請使用 [控制台] 中的 [新增/移除程式] 移除 IIS Smooth Streaming - Beta。 + 這部電腦已經安裝不相容版本的 IIS Media Services。[ProductName] 的安裝無法繼續。若要安裝這個產品,請使用 [控制台] 中的 [新增/移除程式] 移除 IIS Media Services。 + 這部電腦可能已安裝這個產品的新版本或有新版本可供安裝。[ProductName] 的安裝無法繼續。若要安裝這個產品的新版本,請使用 [控制台] 中的 [新增/移除程式] 更新 IIS Media Services。 + 需要播放清單檔案轉換 + + + + + 找到舊的 IIS Media Services 檔案 + + + + + 找到 Beta IIS Media Services 檔案 + + + + + + IIS Media Pack 1.0 + IIS Media Pack 1.0 的更新 + IIS Media Services 2.0 + IIS Media Services 2.0 的更新 + IIS Media Services 3.0 + IIS Media Services 3.0 TAP 2 + IIS Media Services 3.0 的更新 + IIS Media Services 功能和工具。 + IIS Media Services 5 Premium 功能及工具。 + IIS Media Services 4.0 Beta 1 + IIS Media Services 4.0 + IIS Media Services 4.5 Beta 1 + IIS Media Services 5 Premium + + Web 播放清單 + 控制播放清單中參考之媒體資產的用戶端播放方式。 + Session Helper + 啟用 ASP.NET 工作階段狀態持續性 (需要網頁伺服器 (IIS) 的 ASP.NET 角色服務)。 + 使用者介面 + 設定 IIS 管理員中的 Web 播放清單功能。 + + 位元速度節流設定 + 藉由節流設定傳遞用戶端下載的檔案,以節省頻寬。 + 使用者介面 + 設定 IIS 管理員中的位元速度節流設定功能。 + + 資產 + 啟用對用戶端的隨選資產 HTTP 彈性資料流。 + 使用者介面 + 設定 IIS 管理員中的 Smooth Streaming 功能。 + + 通道 + 啟用對用戶端的通道廣播 HTTP 彈性資料流。 + 使用者介面 + 設定 IIS 管理員中的 Live Smooth Streaming 功能。 + + 數位版權管理 + 提供 Smooth Streaming 媒體的加密和授權。 + 使用者介面 + 設定 IIS 管理員中的數位版權管理功能。 + + [ProductName] 需要 Microsoft Windows Vista Service Pack 1 或更新版本。 + 無法將 [ProductName] 安裝在 Vista Home Basic 上。 + [ProductName] 需要 Microsoft Windows 7 Service Pack 1 或更新版本。 + + + IIS Database Manager + IIS Database Manager + + + Microsoft Web Management Service 2 + Microsoft Web Management Service + 安裝 [ProductName] 的基本功能。 + Microsoft Web Management Service 2 + Web Management Service 可啟用遠端及委派管理功能,讓系統管理員管理呈現在這部電腦上的網頁伺服器、站台及應用程式。 + + + Microsoft URL Rewrite Module 1.1 for IIS 7 + URL Rewrite Module 1.1 for IIS 7 的更新 + URL Rewrite + 啟用 IIS 7 的 URL 和內容重寫功能。 + 使用者介面 + 設定 IIS 管理員中的 URL Rewrite Module 功能。 + + + IIS URL Rewrite Module 2 + IIS URL Rewrite Module 2 的更新 + URL Rewrite + 啟用 IIS 7 的 URL 和內容重寫功能。 + 使用者介面 + 設定 IIS 管理員中的 URL Rewrite Module 功能。 + + + Administration Pack for IIS 7.0 + 安裝 [ProductName] 的基本功能。 + 1252 + Administration Pack for IIS 7.0 + Microsoft Corporation + 不支援這個版本的作業系統。[ProductName] 只能安裝在 Windows Server 2008 或 Windows Vista Service Pack 1 和更新版本上。 + ASP.NET 功能 + ASP.NET 包含授權和錯誤網頁功能,可讓您管理授權和自訂錯誤訊息。 + 驗證 + ASP.NET 驗證描述。 + 授權 + ASP.NET 授權可讓您設定規則,來授權使用者存取您的網站和應用程式。 + 錯誤網頁 + ASP.NET 錯誤網頁可讓您設定發生錯誤時要傳回的 HTTP 錯誤回應。 + 模組 + ASP.NET 模組描述。 + 處理常式 + ASP.NET 處理常式描述。 + 設定編輯器 + 設定編輯器可讓您管理 IIS 管理員中的設定檔案,讓您編輯設定檔案中的區段、屬性、元素和集合。 + 要求篩選 + 要求篩選可讓您為網站設定篩選規則,並限制通訊協定和內容的行為。 + Fast CGI + FastCGI 可讓您設定您的網頁伺服器上 FastCGI 應用程式的處理序集區設定。 + + + Dynamic IP Restrictions for IIS 7 安裝程式 + + + + + + + + + + + + + Dynamic IP Restrictions for IIS 7 - Beta + Dynamic IP Restrictions for IIS 7 - Beta 2 + Dynamic IP Restrictions for IIS 7 - Beta 3 + + Dynamic IP Restrictions for IIS 7 - 發行候選版本 + Dynamic IP Restrictions for IIS 7 - 發行候選版本 2 + Dynamic IP Restrictions for IIS 7 - 發行候選版本 3 + + Dynamic IP Restrictions for IIS 7 - RTW + + Dynamic IP Restrictions for IIS 7 + IIS 7 的動態 IP 限制使用者介面 + + 在這部電腦上發現 Dynamic IP Restrictions for IIS 7 - Beta 版。請解除安裝,然後再試一次 + + + WebDAV 7.5 For IIS 7.0 + 必須安裝 IIS 7.0 CoreWebEngine 和 W3SVC 功能才能使用這個產品。 + WebDAV 伺服器模組 + WebDAV Administration 使用者介面 + + + IIS Search Engine Optimization Toolkit 1.0 + IIS Search Engine Optimization Toolkit 1.0 + Search Engine Optimization (SEO) Toolkit 1.0 + 這個安裝程式資料庫內含安裝 IIS Search Engine Optimization Toolkit 1.0 所需的邏輯和資料。 + + + IIS 編輯器 + + + IIS 報告 + 這部電腦上未安裝記錄檔剖析器。請從 http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07 安裝記錄檔剖析器 2.2,然後繼續安裝 IIS 報告 + + + 找不到必要條件封裝。請執行 setup.exe 解決相依性,然後再安裝這個程式。 + Microsoft SQL Server 2008 管理物件是安裝 IIS Database Manager 的必要條件。您可以從 http://go.microsoft.com/fwlink/?LinkID=150946 安裝 Micrsoft SQL Server 2008 管理物件。 + Microsoft SQL Server 系統 CLR 類型是安裝 IIS Database Manager 的必要條件。您可以從 http://go.microsoft.com/fwlink/?LinkID=150949 安裝 Microsoft SQL Server 系統 CLR 類型。 + + + Microsoft Web Farm Framework + Microsoft External Cache + Web Farm Framework 是安裝應用程式要求路由的必要條件。請安裝 Web Farm Framework。 + Microsoft Application Request Routing 2.5 + 執行階段 + 將應用程式要求路由功能新增至 IIS。 + 使用者介面 + 設定 IIS 管理員中的應用程式要求路由功能。 + + + IIS 7.0 的 Microsoft Windows PowerShell 嵌入式管理單元 + + + Microsoft Web Platform Installer 4.0 + Microsoft Web Platform Installer + [ProductName] 需要 Windows XP SP2、Windows 2003 SP1、Windows Vista 或更新版本。 + [ProductName] 需要 Windows XP Service Pack 3、Windows Server 2003 Service Pack 2 (含) 以上版本。 + + + Microsoft Windows Azure Services 安裝程式 + Microsoft Windows Azure Services 安裝程式 + + + Internet Information Services (IIS) 7+ 管理員 + IIS 管理員用戶端 + 遠端支援 + 這個產品需要 Windows XP SP2、Windows 2003 SP1、Windows Vista SP1、Windows 7 或更新版本 + 未安裝 IIS 管理主控台,但需要它才能管理遠端 IIS 伺服器。安裝遠端管理支援之前,請先安裝 IIS 管理主控台,安裝方式是開啟 [控制台]->[所有程式]->[開啟或關閉 Windows 功能],並在 Internet Information Services 功能中選取 [IIS 管理主控台]。 + 在 Windows Server 2008、Windows Server 2008 R2 或更新版本中不需要這個產品。請安裝 IIS 管理主控台,安裝方式是開啟伺服器管理員,然後在網頁伺服器角色的角色服務中選取 [IIS 管理主控台]。 + + + IIS Manager Publishing for IIS 7.0 + 發行使用者介面 + + + Application Warm-Up 1.0 for IIS 7.5 + + + + 不相容的產品 [CONFLICTING_PRODUCT_NAME] 出現在這部電腦上。無法繼續安裝 [ProductName]。若要安裝這個產品,請使用 [控制台] 的 [新增/移除程式移除 [CONFLICTING_PRODUCT_NAME]。 + 需要有系統管理員權限,才能安裝 [ProductName]。 + 需要 IIS 7.0 版才能使用 [ProductName]。 + 需要 IIS 7.0 版或更新版本,才能安裝 [ProductName]。 + 需要 IIS 7.5 版或更新版本,才能安裝 [ProductName]。 + 需要 IIS 第 7 版或第 7.5 版才能安裝 [ProductName]。 + 在這部電腦上發現 [ProductName] 的 Beta 版。 + 在這部電腦上發現 [ProductName] 較新的版本。 + 安裝程式無法繼續,因為這部電腦上已安裝另一份 [ProductName]。請先解除該安裝後,再重新啟動這個安裝。 + 必須安裝 IIS 7.0 CoreWebEngine 和 W3SVC 功能才能使用 [ProductName]。 + 必須安裝 IIS 管理主控台才能使用 [ProductName]。 + 安裝 [ProductName] 前,請先停止 Windows 處理序啟用服務 (WAS) 和 Web Management Service (WMSvc) 兩個服務。您必須在安裝 [ProductName] 後再啟動服務。 + 需要 IIS Metabase 才能安裝 [ProductName]。 + 無法將 64 位元版本的 [ProductName] 安裝在 32 位元版本的 Microsoft Windows 上。 + 無法將 32 位元版本的 [ProductName] 安裝在 64 位元版本的 Microsoft Windows 上。 + 需要 Microsoft .NET Framework 2.0 版本或更新版本,才能安裝 [ProductName]。 + 必須安裝 Microsoft .NET Framework 3.5 (含) 以上版本,才能安裝 [ProductName]。請使用伺服器管理員底下的「新增功能」安裝 Microsoft .NET 3.5 版。 + 需要 Microsoft .NET Framework 4 (含) 以上版本才能安裝 [ProductName]。 + 請先安裝 Microsoft .NET Framework 2.0 版 Service Pack 1 (或更新版的 Service Pack),再安裝 [ProductName]。 + 無法停用 Windows Update (wuauserv) 服務,需要它才能安裝 [ProductName]。 + PowerShell 嵌入式管理單元是 Windows 作業系統的一部分。請用 [程式和功能] 或 [伺服器管理員] 進行安裝。 + 需要 Microsoft Web Platform Installer 3.0 (含) 以上版本才能安裝 [ProductName]。 + + 安裝程式偵測不到共用設定。 + 已為 IIS 啟用共用設定。不支援在使用共用設定時安裝 [ProductName]。請先停用共用設定,再安裝這項功能。 + + 安裝 [ProductName] 前,請先停止 World Wide Web Publishing 服務 (W3SVC)。您必須在安裝後再啟動服務。 + IIS PowerShell 管理主控台 + IIS PowerShell 嵌入式管理單元 + IIS PowerShell 嵌入式管理單元要求必須已安裝 PowerShell v1.0 或 v2.0 + IIS PowerShell 嵌入式管理單元要求必須已安裝 WAS 和設定 + 這是假的字串。 + + + Microsoft Web Farm Framework 2.2版 + Microsoft Web Farm Agent 2.2 版 + Web 伺服陣列服務 + Web 伺服陣列服務 + Web 伺服陣列控制器服務 + Web 伺服陣列控制器服務 + Web 伺服陣列代理程式服務 + Web 伺服陣列代理程式服務 + Web Platform Installer 是安裝 Web Farm Framework 2.0 的必要元件。請從 http://www.microsoft.com/web/downloads/platform.aspx 安裝 Web Plaform Installer。 + Web Deployment Tool 是安裝 Web Farm Framework 的必要元件。請從 http://www.iis.net/download/WebDeploy 安裝 Web Deployment Tool。 + + + Microsoft Web Hosting Framework + Web Hosting Framework + Web Hosting 角色及功能。 + Hosting Framework + Hosting Framework 提供用於管理 Web Hosting 的 API 命令和 PowerShell 命令。 + Web 角色 + Web 角色會安裝 Web Hosting 的 Dynamic WAS 服務及 URL Rewrite 提供者。 + Antares Express + 部署已針對單一電腦環境最佳化的控制台設定。 + 負載平衡器角色 + 負載平衡器角色會將應用程式要求路由器設定為根據 Web Hosting 規則進行路由。 + 主機控制器 + 主機控制器會擴充 Web Farm Framework 2.0 以搭配 Web Hosting 運作。 + 發行角色 + 安裝 Web Deploy 及 FTP 發行的支援。 + 這是包含 Cmdlet 的 PowerShell 嵌入式管理單元,可用來管理 Microsoft Web Hosting 基礎結構。 + 動態 WAS 服務 + 針對高密度 Web Hosting 最佳化的 Windows Process Activation 服務。 + 資源計量服務 + 安裝資源計量服務,此服務可收集和發行執行階段和健康狀態資訊。 + 資源計量 + 可從 Web 角色收集及發行執行階段和健康狀態資訊。 + 主機配額強制 + 監視網站資源使用量,並且在超過使用量配額時執行自訂動作。 + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/CSY/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/CSY/misc/setupstrings.wxl new file mode 100644 index 0000000000..2e4fca8c5c --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/CSY/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 1029 + + + + Možnosti instalace sdílené konfigurace + Vyberte možnosti instalace pro sdílenou konfiguraci služby IIS. + Při instalaci aktualizovat sdílenou konfiguraci + Tento modul instalujete na server služby IIS, který používá sdílenou konfiguraci. Používají-li tuto sdílenou konfiguraci další servery služby IIS, bude tento modul nainstalován na všechny tyto servery. Chcete-li co nejméně narušit jednotlivé webové servery, nainstalujte tento modul následovně: Nejprve na všechny servery kromě jednoho nainstalujte modul, aniž byste aktualizovali sdílenou konfiguraci. To provedete tak, že zrušíte zaškrtnutí následujícího + políčka. Tak nainstalujete všechny binární i ostatní soubory modulu na každý server, ale sdílená konfigurace zůstane beze změn. Následně na posledním serveru ověřte, zda má uživatelský účet, se kterým jste přihlášeni, dostatečná oprávnění ke čtení a zápisu do souboru applicationhost.config ve sdíleném úložišti UNC. Poté nainstalujte modul a vyberte níže uvedenou možnost aktualizace sdílené konfigurace. + + + Probíhá inicializace vlastní akce souboru web.config. + Probíhá aktualizace souboru web.config. + + + + Rozšířené protokolování Internetové informační služby + Umožňuje rozšířené protokolování dat kanálu IIS. + Rozšířené protokolování Internetové informační služby + Umožňuje vytváření vlastních souborů protokolu s rozšířeným výběrem polí. + Aktualizace pro rozšířené protokolování Internetové informační služby + + + + Správce transformace služby IIS + Beta + Povoluje správce transformace služby IIS Media Services. + Správce transformace služby IIS + Umožňuje tvorbu mediálních transformací. + Hostitel správce transformace služby IIS + Hostitel služby pro [ProductName]. + Správce transformace služby IIS + Dávkový převod souborů médií na vyžádání na jiné formáty souborů a kontejneru + V počítači je nainstalován balíček Expression Encoder SP Task Správce transformace služby IIS 1.0. Ten je třeba před instalací produktu [ProductName] odinstalovat. + + K instalaci produktu [ProductName] je vyžadováno rozhraní Microsoft .NET Framework 3.5. Můžete nainstalovat funkce rozhraní .NET Framework 3.5.1 pomocí Průvodce přidáním funkcí ve Správci serveru nebo zapnout rozhraní Microsoft .NET Framework 3.5 pomocí položky Zapnout nebo vypnout funkce systému Windows. + + + + Správa digitálních práv služby IIS + Beta + Povoluje správu digitálních práv pro prezentace Smooth Streaming. + + + Není nainstalována součást ASP.NET. + + + + + + + + + V tomto počítači byla nalezena beta verze rozšíření IIS Smooth Streaming. Instalace produktu [ProductName] nemůže pokračovat. Pokud chcete tento produkt nainstalovat, pomocí ovládacího panelu Přidat nebo odebrat programy odeberte položku IIS Smooth Streaming – Beta. + V tomto počítači je nekompatibilní verze služby IIS Media Services. Instalace produktu [ProductName] nemůže pokračovat. Pokud chcete tento produkt nainstalovat, pomocí ovládacího panelu Přidat nebo odebrat programy odeberte položku IIS Media Services. + V tomto počítači je již nainstalována nebo je k dispozici k instalaci novější verze tohoto produktu. Instalace produktu [ProductName] nemůže pokračovat. Pokud chcete nainstalovat novější verzi tohoto produktu, pomocí ovládacího panelu Přidat nebo odebrat programy aktualizujte položku IIS Media Services. + Je nutný převod souboru seznamu stop. + + + + + Byly nalezeny starší soubory služby IIS Media Services. + + + + + Byly nalezeny soubory beta verze služby IIS Media Services. + + + + + + IIS Media Pack 1.0 + Aktualizace pro sadu IIS Media Pack 1.0 + IIS Media Services 2.0 + Aktualizace pro službu IIS Media Services 2.0 + IIS Media Services 3.0 + IIS Media Services 3.0 TAP 2 + Aktualizace pro službu IIS Media Services 3.0 + Součásti a nástroje služby IIS Media Services. + Funkce a nástroje služby IIS Media Services 5 Premium + IIS Media Services 4.0 Beta 1 + IIS Media Services 4.0 + IIS Media Services 4.5 Beta 1 + IIS Media Services 5 Premium + + Webové seznamy stop + Řídí přehrávání mediálních materiálů odkazovaných v seznamech stop pro klienta. + Pomocník relace + Umožňuje trvalost stavu relace ASP.NET. (Je požadována služba role ASP.NET pro roli Webový server (IIS)). + Uživatelské rozhraní + Konfiguruje funkci Webové seznamy stop ve Správci služby IIS. + + Omezení přenosové rychlosti + Uspoří šířku pásma omezením doručování souborů stahovaných klienty. + Uživatelské rozhraní + Konfiguruje funkci Omezení přenosové rychlosti ve Správci služby IIS. + + Aktiva + Umožňuje vysílání adaptivních datových proudů protokolu HTTP aktiv na vyžádání pro klienty. + Uživatelské rozhraní + Konfiguruje funkci Smooth Streaming ve Správci služby IIS. + + Kanály + Umožňuje vysílání adaptivních datových proudů protokolu HTTP všesmerového vysílání kanálů pro klienty. + Uživatelské rozhraní + Konfiguruje funkci Live Smooth Streaming ve Správci služby IIS. + + Správa digitálních práv (DRM) + Zajišťuje šifrování a správu licencí médií Smooth Streaming. + Uživatelské rozhraní + Konfiguruje funkci správy digitálních práv ve správci služby IIS. + + [ProductName] požaduje systém Microsoft Windows Vista Service Pack 1 nebo novější. + [ProductName] nelze nainstalovat v systému Vista Home Basic. + [ProductName] požaduje systém Microsoft Windows 7 Service Pack 1 nebo novější. + + + Správce databáze služby IIS + Správce databáze služby IIS + + + Služba webové správy Microsoft 2 + Služba webové správy Microsoft + Nainstaluje základní součásti produktu [ProductName]. + Služba webové správy Microsoft 2 + Služba webové správy umožňuje vzdáleným a delegovaným funkcím správy pracovat s webovým serverem, weby a aplikacemi, které jsou uloženy v tomto počítači. + + + Microsoft URL Rewrite Module 1.1 for IIS 7 + Aktualizace pro produkt URL Rewrite Module 1.1 for IIS 7 + Přepisování adres URL + Dává službě IIS 7 možnost přepisovat adresy URL a obsah. + Uživatelské rozhraní + Konfiguruje funkci URL Rewrite Module ve Správci služby IIS. + + + IIS URL Rewrite Module 2 + Aktualizace pro produkt IIS URL Rewrite Module 2 + Přepisování adres URL + Dává službě IIS 7 možnost přepisovat adresy URL a obsah. + Uživatelské rozhraní + Konfiguruje funkci URL Rewrite Module ve Správci služby IIS. + + + Balíček pro správu služby IIS 7.0 + Nainstaluje základní součásti produktu [ProductName]. + 1250 + Balíček pro správu služby IIS 7.0 + Microsoft Corporation + Tato verze operačního systému není podporována. Produkt [ProductName] lze nainstalovat pouze v systémech Windows Server 2008 nebo Windows Vista Service Pack 1 a novějších. + Součásti ASP.NET + Technologie ASP.NET obsahuje součásti Autorizace a Chybové stránky, které umožňují spravovat nastavení autorizace a vlastních chyb. + Ověřování + Popis ověřování ASP.NET. + Autorizace + Autorizace ASP.NET umožňuje konfigurovat pravidla pro autorizaci uživatelů pro přístup k vašim webům a aplikacím. + Chybové stránky + Součást Chybové stránky ASP.NET umožňuje konfigurovat chybové odpovědi protokolu HTTP (stránky vrácené při chybě). + Moduly + Popis modulů ASP.NET. + Obslužné rutiny + Popis obslužných rutin ASP.NET. + Editor konfigurací + Editor konfigurací umožňuje spravovat konfigurační soubory ve Správci služby IIS. Umožňuje upravovat sekce, atributy, elementy a kolekce v konfiguračních souborech. + Filtrování požadavků + Funkce Filtrování žádostí umožňuje konfigurovat pravidla filtrování pro vaše weby a stanovit omezení pro protokol a chování obsahu. + FastCGI + Rozšíření FastCGI umožňuje konfigurovat nastavení fondu procesů pro aplikace FastCGI na vašem webovém serveru. + + + Dynamická omezení IP adres pro službu IIS 7 – instalace + + + + + + + + + + + + + Dynamická omezení IP adres pro službu IIS 7 – beta + Dynamická omezení IP adres pro službu IIS 7 – beta 2 + Dynamická omezení IP adres pro službu IIS 7 – beta 3 + + Dynamická omezení IP adres pro službu IIS 7 – Release Candidate + Dynamická omezení IP adres pro službu IIS 7 – Release Candidate 2 + Dynamická omezení IP adres pro službu IIS 7 – Release Candidate 3 + + Dynamická omezení IP adres pro službu IIS 7 – RTW + + Dynamická omezení IP adres pro službu IIS 7 + Uživatelské rozhraní pro dynamického omezení IP adres pro službu IIS 7 + + Na tomto serveru byla zjištěn dynamická omezení IP adres pro službu IIS 7 – Beta. Odinstalujte službu a opakujte akci. + + + WebDAV 7.5 pro službu IIS 7.0 + Tento produkt lze používat pouze tehdy, jsou-li nainstalovány součásti webového jádra a W3SVC služby IIS 7.0. + Modul serveru WebDAV + Uživatelské rozhraní pro správu protokolu WebDAV + + + Sada nástrojů optimalizace pro vyhledávací weby 1.0 + Sada nástrojů optimalizace pro vyhledávací weby 1.0 + Sada nástrojů optimalizace pro vyhledávací weby (SEO) 1.0 + Databáze instalačního programu obsahuje logiku a data vyžadovaná k instalaci sady nástrojů optimalizace pro vyhledávací weby služby IIS ve verzi 1.0. + + + Editor služby IIS + + + Sestavy služby IIS + V tomto počítači není nainstalován analyzátor protokolu Log Parser. Nainstalujte nástroj Log Parser 2.2 ze stránky http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07 a pokračujte dále v instalaci součásti Sestavy služby IIS. + + + Nebyly nalezeny požadované balíčky. Spusťte soubor setup.exe, abyste vyřešili potíže se závislostmi, a potom nainstalujte tento program. + Microsoft SQL Server 2008 Management Objects je požadovaným produktem pro instalaci Správce databáze služby IIS. Produkt Microsoft SQL Server 2008 Management Objects lze nainstalovat ze stránky http://go.microsoft.com/fwlink/?LinkID=150946. + Microsoft SQL Server System CLR Types je požadovaným produktem pro instalaci Správce databáze služby IIS. Produkt Microsoft SQL Server System CLR Types lze nainstalovat ze stránky http://go.microsoft.com/fwlink/?LinkID=150949. + + + Microsoft Web Farm Framework + Microsoft External Cache + Technologie Směrování žádostí na aplikace požaduje, aby byla nainstalováno rozhraní Web Farm Framework. Nainstalujte rozhraní Web Farm Framework. + Microsoft Application Request Routing 2.5 + Modul runtime + Přidá do služby IIS možnosti směrování žádostí na aplikace. + Uživatelské rozhraní + Konfiguruje funkci směrování žádostí na aplikace ve správci služby IIS. + + + Modul snap-in Microsoft Windows PowerShell pro službu IIS 7.0 + + + Instalace webové platformy Microsoft 4.0 + Instalační služba webové platformy Microsoft + Produkt [ProductName] požaduje systém Windows XP SP2, Windows 2003 SP1, Windows Vista nebo novější. + Produkt [ProductName] vyžaduje systém Windows XP Service Pack 3, Windows Server 2003 Service Pack 2 nebo novější. + + + Instalační program služby Microsoft Windows Azure Services + Instalační program služby Microsoft Windows Azure Services + + + Správce Internetové informační služby (IIS) 7+ + Klient Správce služby IIS + Podpora vzdálené komunikace + Tento produkt vyžaduje systém Windows XP SP2, Windows 2003 SP1, Windows Vista SP1, Windows 7 nebo novější. + Není nainstalována konzola pro správu služby IIS, která je nutná pro správu vzdálených serverů služby IIS. Před instalací podpory vzdálené správy nainstalujte konzolu pro správu služby IIS: Přejděte na Ovládací panely ->Programy-> Zapnout nebo vypnout funkce systému Windows a v součásti Internetová informační služba vyberte položku Konzola pro správu služby IIS. + Tento produkt není požadován v systémech Windows Server 2008 nebo Windows Server 2008 R2 nebo novějších. Nainstalujte konzolu pro správu služby IIS otevřením Správce serveru a výběrem položky Konzola pro správu služby IIS v uzlu Služby rolí pro roli Webový server. + + + Publikování Správce služby IIS pro službu IIS 7.0 + Uživatelské rozhraní publikování + + + Application Warm-Up 1.0 pro službu IIS 7.5 + + + + V tomto počítači je nekompatibilní produkt [CONFLICTING_PRODUCT_NAME]. Instalace produktu [ProductName] nemůže pokračovat. Chcete-li tento produkt nainstalovat, odeberte pomocí funkce Přidat nebo odebrat programy v Ovládacích panelech produkt [CONFLICTING_PRODUCT_NAME]. + K instalaci produktu [ProductName] jsou nutná oprávnění správce. + Produkt [ProductName] lze používat pouze ve verzi 7.0 služby IIS. + K instalaci produktu [ProductName] je požadována služba IIS verze 7.0 nebo vyšší. + K instalaci produktu [ProductName] je požadována služba IIS verze 7.5 nebo vyšší. + K instalaci produktu [ProductName] je vyžadována služba IIS verze 7 nebo 7.5. + V tomto počítači byla nalezena beta verze produktu [ProductName]. + V tomto počítači byla nalezena novější verze produktu [ProductName]. + Instalační program nemůže pokračovat, protože v tomto počítači je již nainstalována jiná instance produktu [ProductName]. Odinstalujte tuto instanci a poté znovu spusťte instalaci. + Produkt [ProductName] lze používat pouze tehdy, jsou-li nainstalovány součásti webového jádra a W3SVC služby IIS 7.0. + Produkt [ProductName] lze používat pouze v případě, že je nainstalována konzola pro správu služby IIS. + Před instalací produktu [ProductName] je třeba zastavit Aktivační službu procesů systému Windows (WAS) a Službu webové správy (WMSvc). Po instalaci produktu [ProductName] bude třeba tyto služby opět spustit. + K instalaci produktu [ProductName] je požadována metabáze služby IIS. + 64bitovou verzi produktu [ProductName] nelze nainstalovat do 32bitové edice systému Microsoft Windows. + 32bitovou verzi produktu [ProductName] nelze nainstalovat do 64bitové edice systému Microsoft Windows. + K instalaci produktu [ProductName] je požadováno rozhraní Microsoft .NET Framework 2.0 nebo vyšší. + K instalaci produktu [ProductName] je vyžadováno rozhraní Microsoft .NET Framework 3.5 nebo vyšší. Nainstalujte toto rozhraní pomocí tlačítka Přidat funkce ve správci serveru. + K instalaci produktu [ProductName] je vyžadováno rozhraní Microsoft .NET Framework 4.0 nebo vyšší. + Před instalací produktu [ProductName] nainstalujte rozhraní Microsoft .NET Framework verze 2.0 Service Pack 1 (nebo novější aktualizaci Service Pack). + Služba Windows Update (wuauserv) nemůže být zakázána. Je požadována pro instalaci produktu [ProductName]. + Modul snap-in PowerShell je součástí operačního systému Windows. Nainstalujte jej prostřednictvím ovládacího panelu Programy a funkce nebo prostřednictvím Správce serveru. + K instalaci produktu [ProductName] je vyžadována Instalace webové platformy společnosti Microsoft verze 3.0 nebo vyšší. + + Instalačnímu programu se nepodařilo zjistit sdílenou konfiguraci. + Pro službu IIS je povolena sdílená konfigurace. Instalace produktu [ProductName] není podporována při použití sdílené konfigurace. Před instalací této součásti je třeba sdílenou konfiguraci zakázat. + + Před instalací produktu [ProductName] zastavte Službu publikování na webu (W3SVC). Po instalaci bude třeba ji opět spustit. + Konzola pro správu prostředí PowerShell služby IIS + Modul snap-in PowerShell služby IIS + Modul snap-in PowerShell služby IIS požaduje, aby byl nainstalována součást PowerShell v1.0 nebo v2.0. + Modul snap-in PowerShell služby IIS požaduje, aby byl nainstalována služba WAS a konfigurace. + Toto je nepravý řetězec. + + + Rozhraní Microsoft Web Farm Framework verze 2.2 + Agent Microsoft Web Farm verze 2.2 + Služba Web Farm + Služba Web Farm + Služba řadiče Web Farm + Služba řadiče Web Farm + Služba agenta Web Farm + Služba agenta Web Farm + K instalaci rozhraní Web Farm Framework je vyžadován průvodce Instalace webové platformy. Nainstalujte jej z adresy http://www.microsoft.com/web/downloads/platform.aspx. + K instalaci rozhraní Web Farm Framework je vyžadován Nástroj pro nasazení webu. Nainstalujte jej z adresy http://www.iis.net/download/WebDeploy. + + + Architektura webových hostitelských služeb společnosti Microsoft + Architektura webových hostitelských služeb + Role a funkce webových hostitelských služeb + Architektura hostitelských služeb + Architektura hostitelských služeb poskytuje příkazy rozhraní API a prostředí PowerShell pro správu webových hostitelských služeb. + Webová role + Webová role nainstaluje Dynamickou službu WAS a zprostředkovatele pro přepis adresy URL pro webové hostitelské služby. + Antares Express + Nasadí konfiguraci ovládacích panelů optimalizovanou pro instalaci v jednom počítači. + Role nástroje pro vyrovnávání zatížení + Role nástroje pro vyrovnávání zatížení nakonfiguruje směrovač žádostí aplikace na směrování na základě pravidel webových hostitelských služeb. + Řadič hostingu + Řadič hostitelských služeb rozšiřuje rozhraní Web Farm Framework 2.0 na práci s webovými hostitelskými službami. + Role publikování + Nainstaluje podporu pro nasazení webu a publikování FTP. + Jde o modul snap-in prostředí PowerShell obsahující rutiny umožňující správu infrastruktury Microsoft Web Hosting. + Dynamická služba WAS + Aktivační služba procesů systému Windows optimalizovaná pro webové hostitelské služby s vysokou hustotou + Služba měření četnosti odesílání dat ze zdrojů + Nainstaluje službu měření četnosti odesílání dat ze zdrojů, která umožňuje shromažďovat a publikovat informace o běhu i o stavu. + Resource Metering + Povolí shromažďování a publikování informací o běhu a stavu z webové role. + Vynucení kvóty hostitelských služeb + Monitoruje využití prostředků na webech a v případě překročení kvóty použití spustí vlastní akce. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/DEU/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/DEU/misc/setupstrings.wxl new file mode 100644 index 0000000000..436243b9ad --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/DEU/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 1031 + + + + Installationsoptionen für freigegebene Konfiguration + Wählen Sie eine Option für die Installation in der freigegebenen IIS-Konfiguration aus. + Freigegebene Konfiguration bei Installation aktualisieren + Die Installation des Moduls erfolgt auf einem IIS-Server, der eine freigegebene Konfiguration verwendet. Wenn weitere IIS-Server diese freigegebene Konfiguration verwenden, müssen Sie dieses Modul auf allen beteiligten Computern installieren. Um Unterbrechungen auf den einzelnen Webservern zu vermeiden, beachten Sie bei der Installation des Moduls die folgenden Schritte: Führen Sie die Modulinstallation auf allen bis auf dem letzten Computer durch, ohne die freigegebene Konfiguration zu aktualisieren. Deaktivieren Sie hierzu das folgende + Kontrollkästchen. Dadurch werden alle Binärdateien und andere für das Modul benötigten Dateien auf jedem Computer installiert, ohne Änderungen an der freigegebenen Konfiguration vorzunehmen. Anschließend müssen Sie auf dem letzten Computer sicherstellen, dass das verwendete Benutzerkonto über Lese- und Schreibzugriff auf die Datei "applicationhost.config" auf der UNC-Freigabe verfügt. Installieren Sie dann das Modul, und aktivieren Sie dabei die folgend gezeigte Option zum Aktualisieren der freigegebenen Konfiguration. + + + Die benutzerdefinierte WebConfig-Aktion wird initialisiert. + "web.config" wird aktualisiert. + + + + IIS Advanced Logging + Aktiviert die erweiterte Protokollierung von IIS-Pipelinedaten. + IIS Advanced Logging + Aktiviert die Erstellung von Protokolldateien mit umfangreicher Feldauswahl. + Update für IIS Advanced Logging + + + + IIS Transform Manager + Beta + Aktiviert die Transform Manager IIS Media Services. + IIS Transform Manager + Aktiviert die Erstellung von Medientransformationen. + IIS Transform Manager-Host + Diensthost für [ProductName]. + IIS Transform Manager + Bedarfsgesteuerte Batchkonvertierung von Mediendateien in andere Datei- und Containerformate. + Ein IIS Transform Manager 1.0 Expression Encoder SP-Aufgabenpaket ist auf dem Computer installiert. Sie müssen das Paket deinstallieren, bevor Sie [ProductName] installieren können. + + Microsoft .NET Framework 3.5 ist für die Installation von [ProductName] erforderlich. Verwenden Sie den Assistenten zum Hinzufügen von Features im Server-Manager, um .NET Framework 3.5.1-Features zu installieren, oder verwenden Sie die Option "Windows-Features ein- oder ausschalten" zum Aktivieren von Microsoft .NET Framework 3.5. + + + + IIS-Verwaltung digitaler Rechte (DRM) + Beta + Aktiviert die Verwaltung digitaler Rechte (DRM) für Smooth Streaming-Präsentationen. + + + ASP.NET ist nicht installiert. + + + + + + + + + IIS Smooth Streaming Beta wurde auf diesem Computer gefunden. Die Installation von [ProductName] kann nicht fortgesetzt werden. Um dieses Produkt zu installieren, können Sie IIS Smooth Streaming Beta über die Funktion "Software" in der Systemsteuerung entfernen. + Auf diesem Computer befindet sich eine inkompatible Version der IIS Media Services. Die Installation von [ProductName] kann nicht fortgesetzt werden. Um dieses Produkt zu installieren, können Sie IIS Media Services über die Funktion "Software" in der Systemsteuerung entfernen. + Eine neuere Version dieses Produkts ist entweder bereits installiert oder für die Installation auf diesem Computer verfügbar. Die Installation von [ProductName] kann nicht fortgesetzt werden. Zum Installieren einer neueren Version des Produkts rufen Sie die Systemsteuerung auf, wählen 'Software' und aktualisieren dann die IIS Media Services. + Die Konvertierung der Wiedergabelistendatei ist erforderlich. + + + + + Es wurden ältere IIS Media Services-Dateien gefunden. + + + + + Es wurden IIS Media Services-Dateien der Betaversion gefunden. + + + + + + IIS Media Pack 1.0 + Update für IIS Media Pack 1.0 + IIS Media Services 2.0 + Update für IIS Media Services 2.0 + IIS Media Services 3.0 + IIS Media Services 3.0 TAP 2 + Update für IIS Media Services 3.0 + Features und Tools der IIS Media Services. + Features und Tools der IIS Media Services 5 Premium. + IIS Media Services 4.0 Beta 1 + IIS Media Services 4.0 + IIS Media Services 4.5 Beta 1 + IIS Media Services 5 Premium + + Internet-Wiedergabelisten + Steuert die Clientwiedergabe von Medienobjekten, auf die in Wiedergabelisten verwiesen wird. + Session Helper + Aktiviert die Dauerhaftigkeit des ASP.NET-Sitzungszustands (erfordert den ASP.NET-Rollendienst für Webserver (IIS)). + Benutzeroberfläche + Konfiguriert das Feature 'Internet-Wiedergabelisten' im IIS-Manager. + + Bitratendrosselung + Spart Bandbreite durch Drosselung der Übermittlung von Dateien ein, die von Clients heruntergeladen wurden. + Benutzeroberfläche + Konfiguriert das Feature 'Bitratendrosselung' im IIS-Manager. + + Objekte + Aktiviert adaptives HTTP-Streaming von bedarfsgesteuerten Objekten an Clients. + Benutzeroberfläche + Konfiguriert das Feature 'Smooth Streaming' im IIS-Manager. + + Kanäle + Aktiviert adaptives HTTP-Streaming von Kanalübertragungen an Clients. + Benutzeroberfläche + Konfiguriert das Live Smooth Streaming-Feature im IIS-Manager. + + Verwaltung digitaler Rechte (DRM) + Stellt Verschlüsselung und Lizenzierung für Smooth Streaming-Medien bereit. + Benutzeroberfläche + Konfiguriert die Funktion zur Verwaltung digitaler Rechte (DRM) im IIS-Manager. + + [ProductName] erfordert Microsoft Windows Vista Service Pack 1 oder höher. + [ProductName] darf nicht unter Vista Home Basic installiert werden. + [ProductName] erfordert Microsoft Windows 7 Service Pack 1 oder höher. + + + IIS-Datenbank-Manager + IIS-Datenbank-Manager + + + Microsoft-Webverwaltungsdienst 2 + Microsoft-Webverwaltungsdienst + Installiert die grundlegenden Features von [ProductName]. + Microsoft-Webverwaltungsdienst 2 + Der Webverwaltungsdienst bietet Remote- und delegierte Verwaltungsfunktionen für Administratoren zur Verwaltung des Webservers, der Websites und der Anwendungen auf diesem Computer. + + + Microsoft URL Rewrite-Modul 1.1 für IIS 7 + Update für das URL Rewrite-Modul 1.1 für IIS 7 + URL Rewrite + Aktiviert URL- und Inhaltsumschreibfunktionen für IIS 7. + Benutzeroberfläche + Konfiguriert das Feature 'URL Rewrite-Modul' im IIS-Manager. + + + IIS-URL-Rewrite-Modul 2 + Update für IIS-URL-Rewrite-Modul 2 + URL Rewrite + Aktiviert URL- und Inhaltsumschreibfunktionen für IIS 7. + Benutzeroberfläche + Konfiguriert das Feature 'URL Rewrite-Modul' im IIS-Manager. + + + Administration Pack für IIS 7.0 + Installiert die grundlegenden Features von [ProductName]. + 1252 + Administration Pack für IIS 7.0 + Microsoft Corporation + Diese Version des Betriebssystems wird nicht unterstützt. [ProductName] kann nur unter Windows Server 2008 oder Windows Vista Service Pack 1 und höher installiert werden. + ASP.NET-Features + ASP.NET umfasst Features für Autorisierung und Fehlerseiten, mit denen Sie die Autorisierungs- und benutzerdefinierten Fehlereinstellungen verwalten können. + Authentifizierung + ASP.NET-Authentifizierungsbeschreibung. + Autorisierung + Mit der ASP.NET-Autorisierung können Sie Regeln für die Autorisierung von Benutzern für den Zugriff auf Websites und Anwendungen konfigurieren. + Fehlerseiten + Mit den ASP.NET-Fehlerseiten können Sie HTTP-Fehlerreaktionen konfigurieren. + Module + ASP.NET-Modulbeschreibung. + Handler + ASP.NET-Handlerbeschreibung. + Konfigurations-Editor + Mit dem Konfigurations-Editor können Sie Konfigurationsdateien im IIS-Manager verwalten, indem Sie Abschnitte, Attribute, Elemente und Sammlungen der Konfigurationsdateien bearbeiten. + Anforderungsfilterung + Bei der Anforderungsfilterung können Sie Filterregeln für Ihre Website konfigurieren und das Protokoll- und Inhaltsverhalten beschränken. + FastCGI + Mit 'FastCGI' können Sie Prozesspooleinstellungen für die FastCGI-Anwendungen auf Ihrem Webserver konfigurieren. + + + Dynamische IP-Einschränkungen für die IIS 7-Konfiguration + + + + + + + + + + + + + Dynamische IP-Einschränkungen für IIS 7 - Beta + Dynamische IP-Einschränkungen für IIS 7 - Beta 2 + Dynamische IP-Einschränkungen für IIS 7 - Beta 3 + + Dynamische IP-Einschränkungen für IIS 7 - Release Candidate + Dynamische IP-Einschränkungen für IIS 7 - Release Candidate 2 + Dynamische IP-Einschränkungen für IIS 7 - Release Candidate 3 + + Dynamische IP-Einschränkungen für IIS 7 - RTW + + Dynamische IP-Einschränkungen für IIS 7 + Dynamische IP-Einschränkungen - Benutzeroberfläche für IIS 7 + + Dynamische IP-Einschränkungen für IIS 7 - Beta wurde auf diesem Computer gefunden. Deinstallieren Sie diese Anwendung, und versuchen Sie es erneut. + + + WebDAV 7.5 für IIS 7.0 + Die IIS 7.0-Features CoreWebEngine und W3SVC müssen für die Verwendung dieses Produkts installiert sein. + WebDAV-Servermodul + WebDAV-Administrationsbenutzeroberfläche + + + IIS Search Engine Optimization Toolkit 1.0 + IIS Search Engine Optimization Toolkit 1.0 + Search Engine Optimization (SEO) Toolkit 1.0 + Diese Installer-Datenbank enthält die zum Installieren von IIS Search Engine Optimization Toolkit 1.0 erforderliche Logik. + + + IIS-Editor + + + IIS-Berichte + Der Protokollparser ist nicht auf diesem Computer installiert. Installieren Sie Log Parser 2.2 über http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07, und setzen Sie dann die Installation der IIS-Berichte fort. + + + Erforderliche Pakete wurden nicht gefunden. Führen Sie 'setup.exe' aus, um Abhängigkeiten aufzulösen und dieses Programm zu installieren. + Microsoft SQL Server 2008 Management Objects ist eine Voraussetzung für die Installation von IIS-Datenbank-Manager. Sie können Microsoft SQL Server 2008 Management Objects über http://go.microsoft.com/fwlink/?LinkID=150946 installieren. + Microsoft SQL Server System CLR Types ist eine Voraussetzung für die Installation von IIS-Datenbank-Manager. Sie können Microsoft SQL Server System CLR Types über http://go.microsoft.com/fwlink/?LinkID=150949 installieren. + + + Microsoft Web Farm Framework + Microsoft External Cache + Web Farm Framework ist eine Voraussetzung für die Installation des Routings von Anwendungsanforderungen. Installieren Sie Web Farm Framework. + Microsoft Application Request Routing 2.5 + Laufzeit + Fügt die Funktionen des Routings von Anwendungsanforderungen zu IIS hinzu. + Benutzeroberfläche + Konfiguriert das Feature "Routing von Anwendungsanforderungen" im IIS-Manager. + + + Microsoft Windows PowerShell snap-in für IIS 7.0 + + + Microsoft-Webplattform-Installer 4.0 + Microsoft-Webplattform-Installer + [ProductName] erfordert Windows XP SP2, Windows 2003 SP1, Windows Vista oder höher. + [ProductName] benötigt Windows XP Service Pack 3, Windows Server 2003 Service Pack 2 oder höher. + + + Microsoft Windows Azure Services Installer + Microsoft Windows Azure Services Installer + + + Internetinformationsdienste (IIS) 7+-Manager + IIS-Manager-Client + Remotesupport + Das Produkt erfordert Windows XP SP2, Windows 2003 SP1, Windows Vista SP1 oder Windows 7 oder höher. + Die IIS-Verwaltungskonsole ist nicht installiert, sie ist aber zur Verwaltung von Remote-IIS-Servern erforderlich. Installieren Sie die IIS-Verwaltungskonsole vor der Installation des Remoteverwaltungssupports durch Öffnen von 'Systemsteuerung->Programme->Windows-Funktionen ein- oder ausschalten' und Auswahl der IIS-Verwaltungskonsole im Feature 'Internetinformationsdienste'. + Dieses Produkt ist in Windows Server 2008 oder Windows Server 2008 R2 oder höher nicht erforderlich. Installieren Sie die IIS-Verwaltungskonsole durch Öffnen des Server-Managers und Auswahl der IIS-Verwaltungskonsole in den Rollendiensten für die Webserverrolle. + + + IIS-Manager-Publishing für IIS 7.0 + Publishing-Benutzeroberfläche + + + Application Warm-Up 1.0 für IIS 7.5 + + + + Ein inkompatibles Produkt ( [CONFLICTING_PRODUCT_NAME]) ist auf dem Computer. installiert. Die Installation von [ProductName] kann nicht fortgesetzt werden. Verwenden Sie zum Installieren dieses Produkts "Software" in der Systemsteuerung, um [CONFLICTING_PRODUCT_NAME] zu entfernen. + Administratorberechtigungen sind für die Installation von [ProductName] erforderlich. + IIS Version 7.0 ist für die Verwendung von [ProductName] erforderlich. + IIS Version 7.0 oder höher ist für die Installation von [ProductName] erforderlich. + IIS Version 7.5 oder höher ist für die Installation von [ProductName] erforderlich. + IIS Version 7.0 oder 7.5 ist für die Installation von [ProductName] erforderlich. + Eine Betaversion von [ProductName] wurde auf diesem Computer gefunden. + Eine neuere Version von [ProductName] wurde auf diesem Computer gefunden. + Die Installation kann nicht fortgesetzt werden, da eine andere Instanz von [ProductName] bereits auf diesem Computer installiert ist. Deinstallieren Sie diese zuerst, und starten Sie die Installation dann erneut. + Die IIS 7.0-Features CoreWebEngine und W3SVC müssen für die Verwendung von [ProductName] installiert sein. + Die IIS-Verwaltungskonsole muss für die Verwendung von [ProductName] installiert sein. + Halten Sie die den Windows-Prozessaktivierungsdienst (WAS) und den Webverwaltungsdienst (WMSvc) vor der Installation von [ProductName] an. Sie müssen die Dienste nach der Installation von [ProductName] wieder starten. + IIS-Metabasis ist für die Installation von [ProductName] erforderlich. + Die 64-Bit-Version von [ProductName] kann nicht in einer 32-Bit-Version von Microsoft Windows installiert werden. + Die 32-Bit-Version von [ProductName] kann nicht in einer 64-Bit-Version von Microsoft Windows installiert werden. + Microsoft .NET Framework Version 2.0 oder höher ist für die Installation von [ProductName] erforderlich. + Microsoft .NET Framework Version 3.5 oder höher ist für die Installation von [ProductName] erforderlich. Verwenden Sie die Option "Features hinzufügen" im Server-Manager, um Microsoft .Net Version 3.5 zu installieren. + Microsoft .NET Framework Version 4.0 oder höher ist für die Installation von [ProductName] erforderlich. + Installieren Sie Microsoft .NET Framework Version 2.0 Service Pack 1 (oder ein höheres Service Pack) vor der Installation von [ProductName]. + Der Windows Update (wuauserv)-Dienst kann nicht deaktiviert werden, er ist zur Installation von [ProductName] erforderlich. + Das PowerShell-Snap-In ist Teil des Windows-Betriebssystems. Installieren Sie es über 'Programme und Funktionen' oder 'Server-Manager'. + Microsoft-Webplattform-Installer Version 3.0 oder höher ist für die Installation von [ProductName] erforderlich. + + Die freigegebene Konfiguration konnte nicht ermittelt werden. + Die freigegebene Konfiguration ist für IIS aktiviert. Die Installation von [ProductName] wird bei Verwendung der freigegebenen Konfiguration nicht unterstützt. Deaktivieren Sie die freigegebene Konfiguration vor der Installation des Features. + + Halten Sie den WWW-Publishingdienst (W3SVC) vor der Installation von [ProductName] an. Sie müssen den Dienst nach der Installation wieder starten. + IIS-PowerShell-Verwaltungskonsole + IIS-PowerShell-Snap-In + Das IIS-PowerShell-Snap-In erfordert die Installation von PowerShell v1.0 oder v2.0. + Das IIS-PowerShell-Snap-In erfordert die Installation des Windows-Prozessaktivierungsdiensts und der Konfiguration. + Dies ist eine Platzhalter-Zeichenfolge. + + + Microsoft Web Farm Framework Version 2.2 + Microsoft Webfarm-Agent Version 2.2 + Webfarmdienst + Webfarmdienst + Webfarm-Controllerdienst + Webfarm-Controllerdienst + Webfarm-Agent-Dienst + Webfarm-Agent-Dienst + Webplattform-Installer ist eine Voraussetzung für die Installation von Web Farm Framework. Installieren Sie den Webplattform-Installer von "http://www.microsoft.com/web/downloads/platform.aspx". + Die Webbereitstellungstools sind eine Voraussetzung für die Installation von Web Farm Framework. Installieren Sie das Webbereitstellungstool von "http://www.iis.net/download/WebDeploy". + + + Microsoft Web Hosting Framework + Web Hosting Framework + Rollen und Funktionen für Web Hosting. + Hosting Framework + Hosting Framework stellt APIs und PowerShell-Befehle zum Verwalten von Web Hosting zur Verfügung. + Webrolle + Die Webrolle installiert den dynamischen WAS-Dienst und den URL-Rewrite-Anbieter für Web Hosting. + Antares Express + Stellt eine Systemsteuerungskonfiguration bereit, die für die Einrichtung eines einzelnen Computers optimiert ist. + Lastenausgleichsrolle + Die Lastenausgleichsrolle konfiguriert den Anwendungsanforderungsrouter für Routing basierend auf Web Hosting-Regeln. + Hostingcontroller + Der Hostingcontroller erweitert Web Farm Framework 2.0 für die Zusammenarbeit mit Web Hosting. + Veröffentlichungsrolle + Installiert Unterstützung für Web Deploy und FTP-Veröffentlichung. + Hierbei handelt es sich um ein PowerShell-Snap-In mit Cmdlets zur Verwaltung der Microsoft Web Hosting-Infrastruktur. + Dynamischer WAS-Dienst + Windows-Prozessaktivierungsdienst, der für HD-Web Hosting optimiert ist. + Resource Metering-Dienst + Installiert den Resource Metering-Dienst, der das Sammeln und Veröffentlichen von Laufzeit- und Systemintegritätsinformationen ermöglicht. + Resource Metering + Aktiviert das Sammeln und Veröffentlichen von Laufzeit- und Systemintegritätsinformationen aus der Webrolle. + Durchsetzung des Hostingkontingents + Überwacht den Website-Ressourceneinsatz und führt benutzerdefinierte Aktionen aus, wenn das Verwendungskontingent überschritten wurde. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/ESN/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/ESN/misc/setupstrings.wxl new file mode 100644 index 0000000000..ea1579e794 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/ESN/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 3082 + + + + Opciones de instalación de la configuración compartida + Seleccionar la opción de instalación en la configuración compartida de IIS + Actualizar configuración compartida al instalar + Está instalando este módulo en un servidor IIS que usa una configuración compartida. Si otros servidores IIS usan esta configuración compartida, tendrá que instalar este módulo en todas estas máquinas. Para minimizar las interrupciones de los servidores web individuales, tendrá que instalar este módulo realizando los pasos siguientes. En primer lugar, en todas las máquinas, excepto en la última, debe instalar el módulo sin actualizar la configuración compartida. Hágalo sin activar la casilla + siguiente. Esto instalará todos los binarios y archivos necesarios para el módulo en cada máquina sin modificar la configuración compartida. En segundo lugar, en la última máquina tendrá que comprobar que la identidad del usuario con la que está trabajando tiene acceso de lectura y escritura al archivo applicationhost.config del recurso compartido UNC. Después, debe instalar el módulo y seleccionar la opción de actualización de configuración compartida que figura a continuación. + + + Inicialización de acción personalizada de WebConfig + Actualización de archivo web.config + + + + Registro avanzado de IIS + Permite el registro avanzado de datos de canalización de IIS. + Registro avanzado de IIS + Permite la creación de archivos de registro personalizados con selección de campos extensible. + Actualización de Advanced Logging de IIS + + + + Transform Manager para IIS + Beta + Habilita los Servicios multimedia de IIS para Transform Manager. + Transform Manager para IIS + Habilita la creación de transformaciones multimedia. + Host de Transform Manager para IIS + Host de servicios para [ProductName]. + Transform Manager para IIS + Permite convertir por lotes archivos multimedia a petición para alternar formatos de archivo y contenedor. + Existe un paquete de tareas de IIS Transform Manager 1.0 Expression Encoder SP instalado en el equipo. Deberá desinstalarlo antes de instalar [ProductName]. + + Se necesita Microsoft .NET Framework 3.5 para instalar [ProductName]. Use el 'Asistente para agregar características' del Administrador del servidor para instalar las características de .NET Framework 3.5.1 o la opción 'Activar o desactivar las características de Windows' para activar Microsoft .NET Framework 3.5. + + + + Administración de derechos digitales de IIS + Beta + Habilita la administración de derechos digitales de presentaciones de transmisión por secuencias suave. + + + ASP.NET no está instalado + + + + + + + + + Se encontró IIS Smooth Streaming - Beta en este equipo. La instalación de [ProductName] no puede continuar. Para instalar este producto, use Agregar o quitar programas en el Panel de control para quitar IIS Smooth Streaming - Beta. + Este equipo cuenta con una versión no compatible de Servicios multimedia de IIS. La instalación de [ProductName] no puede continuar. Para instalar este producto, use Agregar o quitar programas en el Panel de control para quitar Servicios multimedia de IIS. + Una versión más reciente de este producto está ya instalada o disponible para instalarla en este equipo. La instalación de [ProductName] no puede continuar. Para instalar la versión más reciente de este producto, use Agregar o quitar programas en el Panel de control para actualizar Servicios multimedia de IIS. + Conversión necesaria de archivo de lista de reproducción + + + + + Archivos de versiones anteriores de Servicios multimedia de IIS encontrados + + + + + Versión beta de los Servicios Multimedia de IIS encontrada + + + + + + IIS Media Pack 1.0 + Actualización de IIS Media Pack 1.0 + Servicios multimedia 2.0 de IIS + Actualización de Servicios multimedia 2.0 de IIS + Servicios multimedia 3.0 de IIS + Servicios multimedia 3.0 de IIS (TAP 2) + Actualización de Servicios multimedia 3.0 de IIS + Características y herramientas de Servicios multimedia de IIS. + Características y herramientas de Servicios multimedia de IIS 5 Premium. + Servicios multimedia 4.0 beta 1 de IIS + Servicios multimedia 4.0 de IIS + Servicios multimedia 4.5 beta 1 de IIS + Servicios multimedia de IIS 5 Premium + + Listas de reproducción en web + Controla la reproducción en clientes de recursos multimedia digitales a los que se hace referencia en listas de reproducción. + Aplicación auxiliar para sesiones + Habilita la persistencia de estado de sesión de ASP.NET. Requiere el servicio de rol ASP.NET para el rol Servidor web (IIS). + Interfaz de usuario + Configura la característica Listas de reproducción en web en el Administrador de IIS. + + Limitación de velocidad de bits + Ahorra ancho de banda limitando la entrega de archivos descargados por los clientes. + Interfaz de usuario + Configura la característica Limitación de velocidad de bits en el Administrador de IIS. + + Activos + Habilita la transmisión por secuencias adaptativa HTTP de archivos a petición a los clientes. + Interfaz de usuario + Configura la característica Transmisión por secuencias suave en el Administrador de IIS. + + Canales + Habilita la transmisión por secuencias adaptativa HTTP de las difusiones de canal a los clientes. + Interfaz de usuario + Configura la característica Live Smooth Streaming en el Administrador de IIS. + + Administración de derechos digitales + Proporciona cifrado y licencias de medios de transmisión por secuencias suave. + Interfaz de usuario + Configura la característica de administración de derechos digitales en el administrador de IIS. + + [ProductName] requiere Microsoft Windows Vista Service Pack 1 o posterior. + [ProductName] no se puede instalar en Vista Home Basic. + [ProductName] requiere Microsoft Windows 7 Service Pack 1 o posterior. + + + Administrador de bases de datos de IIS + Administrador de bases de datos de IIS + + + Servicio de administración web de Microsoft 2 + Servicio de administración web de Microsoft + Instala las características básicas de [ProductName]. + Servicio de administración web de Microsoft 2 + El Servicio de administración web habilita funciones de administración remota y delegada para quienes administren los sitios, las aplicaciones y el servidor web presentes en este equipo. + + + Módulo URL Rewrite 1.1 para IIS 7 + Actualización de Módulo URL Rewrite 1.1 para IIS 7 + URL Rewrite + Habilita la reescritura de direcciones URL y contenido en IIS 7. + Interfaz de usuario + Configura la característica Módulo URL Rewrite en el Administrador de IIS. + + + Módulo URL Rewrite 2 de IIS + Actualización de Módulo URL Rewrite 2 de IIS + URL Rewrite + Habilita la reescritura de direcciones URL y contenido en IIS 7. + Interfaz de usuario + Configura la característica Módulo URL Rewrite en el Administrador de IIS. + + + Administration Pack para IIS 7.0 + Instala las características básicas de [ProductName]. + 1252 + Administration Pack para IIS 7.0 + Microsoft Corporation + No se admite esta versión del sistema operativo. [ProductName] se puede instalar sólo en Windows Server 2008 o Windows Vista Service Pack 1 y posterior. + Características de ASP.NET + ASP.NET incluye las características Autorización y Páginas de errores, que permiten administrar la autorización y la configuración de errores personalizada. + Autenticación + Descripción de autenticación ASP.NET. + Autorización + Autorización de ASP.NET permite configurar reglas para autorizar a usuarios a obtener acceso a sitios y aplicaciones web. + Páginas de errores + Páginas de errores de ASP.NET permite configurar respuestas a errores HTTP para devolverlas cuando se producen errores. + Módulos + Descripción de módulos de ASP.NET. + Controladores + Descripción de controladores de ASP.NET. + Editor de configuración + El Editor de configuración permite administrar los archivos de configuración en el Administrador de IIS. Permite editar secciones, atributos, elementos y colecciones en los archivos de configuración. + Filtrado de solicitudes + Filtrado de solicitudes permite configurar reglas de filtrado para un sitio web y restringir el comportamiento de protocolo y contenido. + FastCGI + FastCGI permite configurar grupos de procesos para aplicaciones FastCGI del servidor web. + + + Programa de instalación de Restricciones de IP dinámicas para IIS 7 + + + + + + + + + + + + + Restricciones de IP dinámicas para IIS 7 - Beta + Restricciones de IP dinámicas para IIS 7 - Beta 2 + Restricciones de IP dinámicas para IIS 7 - Beta 3 + + Restricciones de IP dinámicas para IIS 7 - Release Candidate + Restricciones de IP dinámicas para IIS 7 - Release Candidate 2 + Restricciones de IP dinámicas para IIS 7 - Release Candidate 3 + + Restricciones de IP dinámicas para IIS 7 - RTW + + Restricciones de IP dinámicas para IIS 7 + Interfaz de usuario de Restricciones de IP dinámicas para IIS 7 + + Se encontraron restricciones de IP dinámicas para IIS 7 - Beta en esta máquina. Desinstálelo e inténtelo de nuevo. + + + WebDAV 7.5 para IIS 7.0 + Deben instalarse las características CoreWebEngine y W3SVC de IIS 7.0 para usar este producto. + Módulo de servidor de WebDAV + Interfaz de usuario de administración de WebDAV + + + Herramientas de optimización para el motor de búsqueda de IIS 1.0 + Herramientas de optimización para el motor de búsqueda de IIS 1.0 + Herramientas de optimización para el motor de búsqueda (SEO) de IIS 1.0 + Esta base de datos de instalador contiene la lógica y los datos necesarios para instalar las Herramientas de optimización para el motor de búsqueda de IIS 1.0. + + + Editor de IIS + + + Informes de IIS + Log Parser no está instalado en esta máquina. Instale Log Parser 2.2 desde http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07 y después continúe con la instalación de Informes de IIS. + + + No se encontraron algunos paquetes de requisitos previos. Ejecute setup.exe para resolver las dependencias e instalar este programa. + Objetos de administración de Microsoft SQL Server 2008 es un requisito previo para instalar el Administrador de bases de datos de IIS. Puede instalar Objetos de administración de Microsoft SQL Server 2008 desde http://go.microsoft.com/fwlink/?LinkID=150946 . + Microsoft SQL Server System CLR Types es un requisito previo para instalar el Administrador de bases de datos de IIS. Puede instalar Microsoft SQL Server System CLR Types desde http://go.microsoft.com/fwlink/?LinkID=150949 . + + + Microsoft Web Farm Framework + Microsoft External Cache + Web Farm Framework es un requisito para instalar Enrutamiento de solicitud de aplicaciones. Instale Web Farm Framework. + Enrutamiento de solicitud de aplicaciones de Microsoft 2.5 + Runtime + Agrega las capacidades de Enrutamiento de solicitud de aplicaciones a IIS. + Interfaz de usuario + Configura la característica Enrutamiento de solicitud de aplicaciones en el Administrador de IIS. + + + Complemento PowerShell de Microsoft Windows para IIS 7.0 + + + Instalador de plataforma web 4.0 de Microsoft + Instalador de plataforma web de Microsoft + [ProductName] requiere Windows XP SP2, Windows 2003 SP1, Windows Vista o posterior. + [ProductName] requiere Windows XP Service Pack 3, Windows Server 2003 Service Pack 2 o posterior. + + + Instalador de Microsoft Windows Azure Services + Instalador de Microsoft Windows Azure Services + + + Administrador de Internet Information Services (IIS) 7 o posterior + Cliente del Administrador de IIS + Compatibilidad con comunicación remota + Este producto requiere Windows XP SP2, Windows 2003 SP1, Windows Vista SP1, Windows 7 o posterior. + La Consola de administración de IIS no está instalada, pero es necesaria para administrar servidores IIS remotos. Instale la Consola de administración de IIS antes de instalar la compatibilidad con administración remota. Para ello, abra 'Panel de control->Programas->Activar o desactivar las características de Windows' y seleccione Consola de administración de IIS en la característica Internet Information Services. + Este producto no es necesario en Windows Server 2008 ni Windows Server 2008 R2 o posterior. Para instalar la Consola de administración de IIS, abra el Administrador del servidor y seleccione Consola de administración de IIS en los servicios del rol Servidor web. + + + Servicio de publicación del Administrador de IIS para IIS 7.0 + Interfaz de usuario para publicación + + + Application Warm-Up 1.0 para IIS 7.5 + + + + El equipo tiene un producto no compatible, [CONFLICTING_PRODUCT_NAME]. No es posible continuar con la instalación de [ProductName]. Para instalar este producto, vaya a Panel de control > Agregar o quitar programas para quitar [CONFLICTING_PRODUCT_NAME]. + Es necesario el privilegio de administrador para instalar [ProductName]. + Es necesaria la versión 7.0 de IIS para usar [ProductName]. + Es necesaria la versión 7.0 o posterior de IIS para instalar [ProductName]. + Es necesaria la versión 7.5 o posterior de IIS para instalar [ProductName]. + Se requiere la versión 7 o 7.5 de IIS para instalar [ProductName]. + Se encontró la versión beta de [ProductName] en esta máquina. + Se encontró una versión más reciente de [ProductName] en esta máquina. + El programa de instalación no puede continuar porque ya hay instalada otra instancia de [ProductName] en esta máquina. Desinstale primero esa instancia y vuelva a iniciar esta instalación. + Deben estar instaladas las características CoreWebEngine y W3SVC de IIS 7.0 para usar [ProductName]. + Para usar [ProductName], debe estar instalada la Consola de administración de IIS. + Detenga los servicios WAS (Windows Process Activation) y WMSvc (Servicio de administración web) antes de instalar [ProductName]. Deberá iniciar los servicios después de instalar [ProductName]. + Es necesaria la metabase de IIS para instalar [ProductName]. + No se puede instalar la versión de 64 bits de [ProductName] en una edición de 32 bits de Microsoft Windows. + No se puede instalar la versión de 32 bits de [ProductName] en una edición de 64 bits de Microsoft Windows. + Es necesario Microsoft .NET Framework 2.0 o posterior para instalar [ProductName]. + Se requiere Microsoft .NET Framework, versión 3.5 o posterior, para instalar [ProductName]. Use la opción 'Agregar características' del Administrador del servidor para instalar Microsoft .Net, versión 3.5. + Se requiere Microsoft .NET Framework, versión 4.0 o posterior, para instalar [ProductName]. + Instale Microsoft .NET Framework 2.0 Service Pack 1 (o un Service Pack posterior) antes de instalar [ProductName]. + No se puede deshabilitar el servicio Windows Update (wuauserv), porque es necesario para instalar [ProductName]. + El complemento PowerShell forma parte del sistema operativo Windows. Instálelo desde 'Programas y características' o 'Administrador del servidor'. + Se requiere Instalador de plataforma web de Microsoft, versión 3.0 o posterior, para instalar [ProductName]. + + El programa de instalación no detectó ninguna configuración compartida. + Está habilitada la configuración compartida para IIS. No se admite la instalación de [ProductName] cuando se usa configuración compartida. Deshabilite la configuración compartida antes de instalar esta característica. + + Detenga el servicio de publicación World Wide Web (W3SVC) antes de instalar [ProductName]. Deberá iniciar el servicio después de la instalación. + Consola de administración de PowerShell para IIS + Complemento PowerShell para IIS + El complemento PowerShell para IIS requiere que esté instalado PowerShell v1.0 o v2.0. + El complemento PowerShell para IIS requiere que estén instalados el servicio WAS y la configuración. + This is a bogus string. + + + Microsoft Web Farm Framework versión 2.2 + Microsoft Web Farm Agent versión 2.2 + Servicio de Web Farm + Servicio de Web Farm + Servicio de controlador de Web Farm + Servicio de controlador de Web Farm + Servicio de agente de Web Farm + Servicio de agente de Web Farm + El Instalador de plataforma web es un requisito previo para instalar Web Farm Framework. Instale el Instalador de plataforma web desde http://www.microsoft.com/web/downloads/platform.aspx. + La Herramienta de implementación web es un requisito previo para instalar Web Farm Framework. Instale la Herramienta de implementación web desde http://www.iis.net/download/WebDeploy. + + + Microsoft Web Hosting Framework + Web Hosting Framework + Roles y características de Microsoft Web Hosting. + Hosting Framework + Hosting Framework ofrece comandos de las API y PowerShell para administrar Web Hosting. + Rol web + El rol web instala el servicio WAS dinámico y el proveedor de URL Rewrite para Web Hosting. + Antares Express + Implementa una configuración de Panel de control optimizada para la configuración de un único equipo. + Rol Equilibrador de carga + El rol Equilibrador de carga configura Application Request Router para enrutar en función de las reglas de Web Hosting. + Controlador de hospedaje + El controlador de hospedaje amplía Web Farm Framework 2.0 para que funcione con Web Hosting. + Rol de publicación + Instala el soporte para la publicación FTP y de Web Deploy. + Se trata de un complemento de PowerShell que contiene cmdlets para administrar la infraestructura de Microsoft Web Hosting. + Servicio WAS dinámico + Servicio WAS (Windows Process Activation) optimizado para hospedaje web de alta densidad. + Servicio de medición de recursos + Instala el servicio Medición de recursos que habilita la recopilación y la publicación de información de estado y en tiempo de ejecución. + Medición de recursos + Habilita la recopilación y publicación de información de estado y en tiempo de ejecución del rol web. + Cumplimiento de cuota de hospedaje + Supervisa el uso de recursos de los sitios web y ejecuta acciones personalizadas si se supera la cuota. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/FRA/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/FRA/misc/setupstrings.wxl new file mode 100644 index 0000000000..c00688e50c --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/FRA/misc/setupstrings.wxl @@ -0,0 +1,352 @@ + + + + + + + 1036 + + + + Options d'installation pour la configuration partagée + Sélectionnez une option pour l'installation dans une partagée IIS + Mettre à jour la configuration partagée lors de l'installation + Vous installez ce module sur un serveur IIS qui utilise une configuration partagée. Si des serveurs IIS supplémentaires utilisent cette configuration partagée, vous devez installer ce module sur tous ces ordinateurs. Pour réduire le risque d'interruptions sur les différents serveurs Web, installez ce module en respectant les étapes suivantes : premièrement, sur tous les ordinateurs à l'exception du dernier, vous devez installer le module sans mettre à jour la configuration partagée. Pour ce faire, n'activez pas la case à cocher + ci-dessous. Cette opération installe l'ensemble des fichiers et ressources binaires requis pour le module sur chaque ordinateur sans apporter de modifications à la configuration partagée. Deuxièmement, sur le dernier ordinateur, vous devez vérifier que l'identité d'utilisateur que vous utilisez actuellement dispose d'un accès en lecture/écriture au fichier applicationhost.config du partage UNC. Vous devez ensuite installer le module et sélectionner l'option de mise à jour de la configuration partagée ci-dessous. + + + Initialisation de l'action personnalisée WebConfig + Mise à jour de web.config + + + + IIS Advanced Logging + Active la journalisation avancée des données de pipeline IIS. + IIS Advanced Logging + Permet la création de fichiers journaux personnalisés avec une sélection de champ extensible. + Mise à jour pour IIS Advanced Logging + + + + IIS Transform Manager + Bêta + Active IIS Services Multimédia pour Transform Manager. + IIS Transform Manager + Active la création de transformations multimédias. + Hôte IIS Transform Manager + Hôte de service pour [ProductName]. + IIS Transform Manager + Convertir sous forme de lot sur demande les fichiers multimédias en d'autres formats de fichier et de conteneur. + Un package IIS Transform Manager 1.0 Expression Encoder SP Task est installé sur l'ordinateur. Vous devez le désinstaller avant d'installer [ProductName]. + + Microsoft .NET Framework 3.5 est requis pour installer [ProductName]. Utilisez l'Assistant Ajout de fonctionnalités du Gestionnaire de serveur pour installer le composant Fonctionnalités du .NET Framework 3.5.1, ou utilisez l'option Activer ou désactiver des fonctionnalités Windows pour activer Microsoft .NET Framework 3.5. + + + + Gestion des droits numériques (DRM) IIS + Bêta + Active la gestion des droits numériques (DRM) des présentations de diffusion en continu lisse. + + + ASP.NET n'est pas installé + + + + + + + + + Diffusion en continu lisse IIS - Bêta a été détecté sur cet ordinateur. L'installation de [ProductName] ne peut pas continuer. Pour installer ce produit, utilisez Ajouter ou supprimer des programmes dans le Panneau de configuration afin de supprimer Diffusion en continu lisse IIS - Bêta. + Une version incompatible d'IIS Services Multimédia se trouve sur cet ordinateur. L'installation de [ProductName] ne peut pas continuer. Pour installer ce produit, utilisez Ajouter ou supprimer des programme dans le Panneau de configuration afin de supprimer IIS Services Multimédia. + Une version plus récente de ce produit est déjà installée ou disponible à l'installation sur cet ordinateur. L'installation de [ProductName] ne peut pas continuer. Pour installer la version la plus récente de ce produit, utilisez Ajouter ou supprimer des programme dans le Panneau de configuration pour mettre à jour IIS Services Multimédia. + Conversion du fichier de sélections requise + + + + + Anciens fichiers IIS Services Multimédia trouvés + + + + + Fichiers IIS Services Multimédia Bêta trouvés + + + + + + IIS Pack Multimédia 1.0 + Mise à jour pour IIS Pack Multimédia 1.0 + IIS Services Multimédia 2.0 + Mise à jour pour IIS Services Multimédia 2.0 + IIS Services Multimédia 3.0 + IIS Services Multimédia 3.0 TAP 2 + Mise à jour pour IIS Services Multimédia 3.0 + Fonctionnalités et outils IIS Services Multimédia. + Fonctionnalités et outils IIS Media Services 5. + IIS Services Multimédia 4.0 Bêta 1 + IIS Services Multimédia 4.0 + IIS Services Multimédia 4.5 Bêta 1 + IIS Media Services 5 Premium + + Sélections Web + Contrôle la lecture sur le client des fichiers multimédias référencés dans les sélections. + Session Helper + Active la persistance d'état de session ASP.NET. (Requiert le service de rôle ASP.NET pour le serveur Web (IIS)). + Interface utilisateur + Configure la fonctionnalité Sélections Web dans le Gestionnaire des services Internet. + + Bit Rate Throttling + Économise la bande passante en limitant la remise de fichiers téléchargés par les clients. + Interface utilisateur + Configure la fonctionnalité Bit Rate Throttling dans le Gestionnaire des services Internet. + + Éléments + Active la diffusion adaptive en continu HTTP d’éléments à la demande sur les clients. + Interface utilisateur + Configure la fonctionnalité de diffusion en continu lisse dans le Gestionnaire des services Internet. + + Canaux + Active la diffusion adaptive en continu HTTP de canaux sur les clients. + Interface utilisateur + Configure la fonctionnalité Live Smooth Streaming dans le Gestionnaire des services Internet. + + Gestion des droits numériques (DRM) + Fournit le chiffrement et la licence des médias de diffusion en continu lisse. + Interface utilisateur + Configure la fonctionnalité Gestion des droits numériques (DRM) dans le Gestionnaire des services Internet. + + [ProductName] requiert Microsoft Windows Vista Service Pack 1 ou version ultérieure. + [ProductName] ne peut pas être installé sur Vista Édition Familiale Basique. + [ProductName] requiert Microsoft Windows 7 Service Pack 1 ou version ultérieure. + + + Gestionnaire de bases de données IIS + Gestionnaire de bases de données IIS + + + Service de gestion Web Microsoft 2 + Service de gestion Web Microsoft + Installe les fonctionnalités de base de [ProductName]. + Service de gestion Web Microsoft 2 + Le service de gestion Web offre des fonctionnalités de gestion déléguée et à distance permettant aux administrateurs de gérer le serveur Web, les sites et les applications présents sur cet ordinateur. + + + Module de réécriture d'URL 1.1 Microsoft pour IIS 7 + Mise à jour pour le Module de réécriture d'URL 1.1 pour IIS 7 + Réécriture d'URL + Active des fonctionnalités de réécriture d'URL et de contenu pour IIS 7. + Interface utilisateur + Configure la fonctionnalité Module de réécriture d'URL dans le Gestionnaire des services Internet. + + + Module de réécriture d'URL 2 d'IIS + Mise à jour pour le Module de réécriture d'URL 2 d'IIS + Réécriture d'URL + Active des fonctionnalités de réécriture d'URL et de contenu pour IIS 7. + Interface utilisateur + Configure la fonctionnalité Module de réécriture d'URL dans le Gestionnaire des services Internet. + + + Pack d'administration IIS 7.0 + Installe les fonctionnalités de base de [ProductName]. + 1252 + Pack d'administration IIS 7.0 + Microsoft Corporation + Cette version du système d'exploitation n'est pas prise en charge. [ProductName] ne peut être installé que sur Windows Server 2008 ou Windows Vista Service Pack 1 et versions ultérieures. + Fonctionnalités ASP.Net + ASP.NET comprend les fonctionnalités d'autorisation et de pages d'erreurs, qui vous permettent de gérer les paramètres d'autorisations et d'erreurs personnalisées. + Authentification + Description de l'authentification ASP.Net. + Autorisation + L'autorisation ASP.NET vous permet de configurer des règles pour autoriser les utilisateurs à accéder à vos applications et sites Web. + Pages d'erreurs + Les pages d'erreurs ASP.NET vous permettent de configurer les réponses d'erreurs HTTP à retourner lorsque des erreurs se produisent. + Modules + Description des modules ASP.Net. + Gestionnaires + Description des gestionnaires ASP.Net. + Éditeur de configuration + L'éditeur de configuration vous permet de gérer vos fichiers de configuration dans le Gestionnaire des services Internet en vous permettant de modifier des sections, des attributs, des éléments et des collections dans vos fichiers de configuration. + Filtrage des demandes + Le filtrage des demandes vous permet de configurer les règles de filtrage pour votre site Web et de limiter le comportement du protocole et du contenu. + FastCGI + FastCGI vous permet de configurer les paramètres du pool de processus pour les applications FastCGI sur votre serveur Web. + + + Programme d'installation de Restrictions dynamiques d'adresse IP pour IIS 7 + + + + + + + + + + + + + Restrictions dynamiques d'adresse IP pour IIS 7 - Bêta + Restrictions dynamiques d'adresse IP pour IIS 7 - Bêta 2 + Restrictions dynamiques d'adresse IP pour IIS 7 - Bêta 3 + + Restrictions dynamiques d'adresse IP pour IIS 7 - version finale (RC) + Restrictions dynamiques d'adresse IP pour IIS 7 - version finale (RC) 2 + Restrictions dynamiques d'adresse IP pour IIS 7 - version finale (RC) 3 + + Restrictions dynamiques d'adresse IP pour IIS 7 - RTW + + Restrictions dynamiques d'adresse IP pour IIS 7 + Interface utilisateur de Restrictions dynamiques d'adresse IP pour IIS 7 + + Restrictions d'adressage IP dynamique pour IIS 7 - Une version bêta a été détectée sur cet ordinateur. Désinstallez-la, puis réessayez + + + WebDAV 7.5 pour IIS 7.0 + Les fonctionnalités IIS 7.0 CoreWebEngine et W3SVC doivent être installées pour utiliser ce produit. + Module serveur WebDAV + Interface utilisateur de l'administration WebDAV + + + Kit de ressources d'optimisation du référencement d'un site auprès d'un moteur de recherche IIS 1.0 + Kit de ressources d'optimisation du référencement d'un site auprès d'un moteur de recherche IIS 1.0 + Kit de ressources d'optimisation du référencement d'un site auprès d'un moteur de recherche (SEO) 1.0 + La base de données de ce programme d'installation contient la logique et les données requises pour installer le Kit de ressources d'optimisation du référencement d'un site auprès d'un moteur de recherche IIS 1.0. + + + Éditeur IIS + + + Rapports IIS + Log Parser n'est pas installé sur cet ordinateur. Installez Log Parser 2.2 à partir de http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07, puis installez les rapports IIS + + + Les packages de composants requis sont introuvables. Exécutez setup.exe pour résoudre les dépendances et installer ce programme. + Microsoft SQL Server 2008 Management Objects doit être installé avant l'installation du Gestionnaire de bases de données IIS. Vous pouvez installer Microsoft SQL Server 2008 Management Objects à partir de http://go.microsoft.com/fwlink/?LinkID=150946 . + Microsoft SQL Server System CLR Types doit être installé avant l'installation du Gestionnaire de bases de données IIS. Vous pouvez installer Microsoft SQL Server System CLR Types à partir de http://go.microsoft.com/fwlink/?LinkID=150949. + + + Microsoft Web Farm Framework + Microsoft External Cache + Web Farm Framework est un composant requis pour l'installation d'Application Request Routing. Installez Web Farm Framework. + Microsoft Application Request Routing 2.5 + Exécution + Ajoute les fonctionnalités d'Application Request Routing à IIS. + Interface utilisateur + Configure la fonctionnalité Application Request Routing dans le Gestionnaire des services Internet. + + + Composant logiciel enfichable Microsoft Windows PowerShell pour IIS 7.0 + + + Microsoft Web Platform Installer 4.0 + + Microsoft Web Platform Installer + [ProductName] requiert Windows XP SP2, Windows 2003 SP1, Windows Vista ou versions ultérieures. + [ProductName] requiert Windows XP Service Pack 3, Windows Server 2003 Service Pack 2 ou versions ultérieures. + + + Programme d'installation des services Microsoft Windows Azure + Programme d'installation des services Microsoft Windows Azure + + + Gestionnaire des services Internet (IIS) 7+ + Client du Gestionnaire des services Internet + Support à distance + Ce produit requiert Windows XP SP2, Windows 2003 SP1, Windows Vista SP1, Windows 7 ou une version supérieure + La console de gestion IIS n'est pas installée, mais est requise pour gérer les serveurs IIS distants. Installez la console de gestion IIS avant d'installer le support de gestion à distance en ouvrant 'Panneau de configuration->Programmes->Activer ou désactiver des fonctionnalités Windows' et en sélectionnant la console de gestion IIS dans la fonctionnalité Services Internet. + Ce produit n'est pas requis dans Windows Server 2008 ou Windows Server 2008 R2 ou une version ultérieure. Installez la console de gestion IIS en ouvrant le Gestionnaire de serveur et en sélectionnant la console de gestion IIS dans les services de rôle pour le rôle Serveur Web. + + + Gestionnaire de publication pour IIS 7.0 + Interface utilisateur de publication + + + Application Warm-Up 1.0 pour IIS 7.5 + + + + Un produit incompatible, [CONFLICTING_PRODUCT_NAME], se trouve sur cet ordinateur. Impossible de poursuivre l'installation de [ProductName]. Pour installer ce produit, utilisez Ajouter/Supprimer les programmes dans le Panneau de configuration pour supprimer [CONFLICTING_PRODUCT_NAME]. + Des privilèges administrateur sont requis pour installer [ProductName]. + IIS version 7.0 est requis pour utiliser [ProductName]. + IIS version 7.0 ou supérieure est requis pour installer [ProductName]. + IIS version 7.5 ou supérieure est requis pour installer [ProductName]. + IIS version 7 ou 7.5 est requis pour installer [ProductName]. + La version bêta de [ProductName] est installée sur cet ordinateur. + Une version plus récente de [ProductName] est installée sur cet ordinateur. + Le programme d'installation ne peut pas continuer car une autre instance de [ProductName] est déjà installée sur cet ordinateur. Désinstallez-la, puis relancez l'installation. + Les fonctionnalités IIS 7.0 CoreWebEngine et W3SVC doivent être installées pour utiliser [ProductName]. + Les fonctionnalités de la console de gestion IIS doivent être installées pour utiliser [ProductName]. + Arrêtez les services d'activation des processus Windows (WAS) et de gestion Web (WMSvc) avant d'installer [ProductName]. Vous devrez redémarrer les services après avoir installé [ProductName]. + La métabase IIS est requise pour installer [ProductName]. + La version 64 bits de [ProductName] ne peut pas être installée sur une édition 32 bits de Microsoft Windows. + La version 32 bits de [ProductName] ne peut pas être installée sur une édition 64 bits de Microsoft Windows. + Microsoft .NET Framework version 2.0 ou supérieure est requise pour installer [ProductName]. + Microsoft .NET Framework version 3.5 ou supérieure est requis pour installer [ProductName]. Utilisez l'option d'ajout de fonctionnalités du Gestionnaire de serveur pour installer Microsoft .NET Framework version 3.5. + Microsoft .NET Framework version 4.0 ou supérieure est requis pour installer [ProductName]. + Installez Microsoft .NET Framework version 2.0 Service Pack 1 (ou SP supérieur), avant d'installer [ProductName]. + Le service Windows Update (wuauserv) ne peut pas être désactivé, il est requis pour installer [ProductName]. + Le composant logiciel enfichable PowerShell fait partie du système d'exploitation Windows. Installez-le via 'Programmes et fonctionnalités' ou 'Gestionnaire de serveur'. + Microsoft Web Platform Installer version 3.0 ou supérieure est requis pour installer [ProductName]. + + Le programme d'installation n'a pas réussi à détecter la configuration partagée. + La configuration partagée est activée pour IIS. L'installation de [ProductName] n'est pas prise en charge lors de l'utilisation d'une configuration partagée. Désactivez la configuration partagée avant d'installer cette fonctionnalité. + + Arrêtez le service de publication World Wide Web (W3SVC) avant d'installer [ProductName]. Vous devrez le redémarrer après l'installation. + Console de gestion PowerShell IIS + Composant logiciel enfichable PowerShell IIS + Le composant logiciel enfichable PowerShell IIS requiert PowerShell v1.0 ou v2.0 + Le composant logiciel enfichable PowerShell IIS requiert WAS et une configuration + Chaîne d'exemple. + + + Microsoft Web Farm Framework Version 2.2 + Microsoft Web Farm Agent Version 2.2 + Service de batterie de serveurs Web + Service de batterie de serveurs Web + Service du contrôleur de batterie de serveurs Web + Service du contrôleur de batterie de serveurs Web + Service de l'agent de batterie de serveurs Web + Service de l'agent de batterie de serveurs Web + Web Platform Installer est un composant requis pour l'installation de Web Farm Framework 2.0. Installez Web Platform Installer à partir de http://www.microsoft.com/web/downloads/platform.aspx. + L'Outil de déploiement Web est un composant requis pour l'installation de Web Farm Framework. Installez l'Outil de déploiement Web à partir de http://www.iis.net/download/WebDeploy. + + + Microsoft Web Hosting Framework + Web Hosting Framework + Rôles et fonctionnalités de l'hébergement Web. + Hosting Framework + Hosting Framework fournit les commandes des API et de PowerShell pour la gestion de l'hébergement Web. + Rôle Web + Le rôle Web installe le service dynamique WAS et le fournisseur de réécriture d'URL pour l'hébergement Web. + Antares Express + Déploie une configuration du Panneau de configuration optimisée pour l'installation sur un seul ordinateur. + Rôle de l'équilibrage de charge + Le rôle de l'équilibrage de charge configure le routeur des requêtes d'applications pour diriger les règles d'hébergement Web. + Contrôleur d'hébergement + Le contrôleur d'hébergement étend Web Farm Framework 2.0 pour être utilisé avec l'hébergement Web. + Rôle de publication + Installe le support pour le déploiement Web et la publication FTP. + Il s'agit d'un composant logiciel enfichable PowerShell qui contient des applets de commande pour gérer l'infrastructure Microsoft Web Hosting. + Service WAS dynamique + Service d'activation de processus Windows optimisé pour l'hébergement Web grande densité. + Service Contrôle des ressources + Installe le service Contrôle des ressources qui permet de collecter et de publier des informations d'exécution et d'intégration. + Contrôle des ressources + Active la collecte et la publication des informations sur l'exécution et l'intégration à partir du rôle Web. + Hébergement de l'application des quotas + Surveille l'utilisation des ressources des sites Web et exécute des actions personnalisées lorsque le quota d'utilisation est dépassé. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/ITA/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/ITA/misc/setupstrings.wxl new file mode 100644 index 0000000000..238a9292f9 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/ITA/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 1040 + + + + Opzioni di installazione configurazione condivisa + Selezionare un'opzione per l'installazione nella configurazione condivisa di IIS + Aggiorna configurazione condivisa al momento dell'installazione + Questo modulo verrà installato su un server IIS che utilizza una configurazione condivisa. Se altri server IIS utilizzano la medesima configurazione condivisa, sarà necessario installare il modulo in ciascuno di essi. Per ridurre al minimo l'interruzione dei servizi dei singoli server Web, sarà necessario installare il modulo attenendosi alla procedura seguente: in tutti i computer tranne l'ultimo installare il modulo senza aggiornare la configurazione condivisa. A tale scopo, non selezionare la casella di controllo sotto. +In questo modo, verranno installati tutti i dati binari e i file necessari per il modulo in ogni computer senza apportare modifiche alla configurazione condivisa. A questo punto, nell'ultimo computer sarà necessario verificare che l'identità dell'utente in uso disponga di accesso in lettura e scrittura al file applicationhost.config nella condivisione UNC. Installare quindi il modulo e selezionare l'opzione di configurazione aggiornata sotto. + + + Inizializzazione dell'azione personalizzata WebConfig + Aggiornamento di web.config + + + + Registrazione avanzata IIS + Consente la registrazione avanzata dei della pipeline IIS. + Registrazione avanzata IIS + Consente la creazione di file di registro personalizzati con selezione campi estendibile. + Aggiornamento per IIS Advanced Logging + + + + IIS Transform Manager + Beta + Abilita IIS Media Services di Transform Manager. + IIS Transform Manager + Abilita la creazione di trasformazioni multimediali. + Host di IIS Transform Manager + Host del servizio per [ProductName]. + IIS Transform Manager + Esegue la conversione batch dei file multimediali su richiesta per alternare formati di file e contenitori. + Nel computer è installato un pacchetto IIS Transform Manager 1.0 Expression Encoder SP Task. È necessario disinstallarlo prima di eseguire l'installazione di [ProductName]. + + Per installare [ProductName] è necessario Microsoft .NET Framework 3.5. Utilizzare 'Aggiunta guidata funzionalità' in Server Manager per installare Funzionalità di .NET Framework 3.5.1 oppure utilizzare 'Attiva o disattiva le funzionalità Windows' per attivare Microsoft .NET Framework 3.5. + + + + IIS Digital Rights Management + Beta + Abilita Digital Rights Management di presentazioni Smooth Streaming. + + + ASP.NET non installato + + + + + + + + + IIS Smooth Streaming - Beta rilevato in questo computer. Impossibile continuare l'installazione di [ProductName]. Per installare il prodotto, utilizzare Installazione applicazioni nel Pannello di controllo per rimuovere IIS Smooth Streaming - Beta. + Una versione non compatibile di IIS Media Services è stata rilevata in questo computer. Impossibile continuare l'installazione di [ProductName]. Per installare il prodotto, utilizzare Installazione applicazioni nel Pannello di controllo per rimuovere IIS Media Services. + Nel computer in uso è già installata o disponibile per l'installazione una versione più recente del prodotto. Impossibile continuare l'installazione di [ProductName]. Per installare la versione più recente del prodotto, utilizzare Installazione applicazioni nel Pannello di controllo per aggiornare IIS Media Services. + Conversione file elenco di riproduzione obbligatoria + + + + + Rilevati file di una versione precedente di IIS Media Services + + + + + Rilevati file di una versione beta di IIS Media Services + + + + + + IIS Media Pack 1.0 + Aggiornamento per IIS Media Pack 1.0 + IIS Media Services 2.0 + Aggiornamento per IIS Media Services 2.0 + IIS Media Services 3.0 + IIS Media Services 3.0 TAP 2 + Aggiornamento per IIS Media Services 3.0 + Funzionalità e strumenti di IIS Media Services. + Funzionalità e strumenti di IIS Media Services 5 Premium. + IIS Media Services 4.0 Beta 1 + IIS Media Services 4.0 + IIS Media Services 4.5 Beta 1 + IIS Media Services 5 Premium + + Web Playlists + Controlla la riproduzione del client di asset di file multimediali a cui si fa riferimento negli elenchi di riproduzione. + Session Helper + Consente la persistenza dello stato della sessione ASP.NET. Richiede il servizio ruolo ASP.NET per Server Web (IIS). + Interfaccia utente + Configura la funzionalità Web Playlists in Gestione IIS. + + Bit Rate Throttling + Riduce la larghezza di banda necessaria limitando il recapito dei file scaricati dai client. + Interfaccia utente + Configura la funzionalità Bit Rate Throttling in Gestione IIS. + + Asset + Consente il flusso adattivo HTTP degli asset su richiesta nei client. + Interfaccia utente + Configura la funzionalità Smooth Streaming in Gestione IIS. + + Canali + Consente il flusso adattivo HTTP delle trasmissioni di canale ai client. + Interfaccia utente + Configura la funzionalità Live Smooth Streaming in Gestione IIS. + + Digital Rights Management + Fornisce crittografia e licenze dei file multimediali Smooth Streaming. + Interfaccia utente + Configura la funzionalità Digital Rights Management in Gestione IIS. + + [ProductName] richiede Microsoft Windows Vista Service Pack 1 o versione successiva. + Impossibile installare [ProductName] in Vista Home Basic. + [ProductName] richiede Microsoft Windows 7 Service Pack 1 o versione successiva. + + + IIS Database Manager + IIS Database Manager + + + Servizio Gestione Web Microsoft 2 + Servizio Gestione Web Microsoft + Installa le funzionalità di base di [ProductName]. + Servizio Gestione Web Microsoft 2 + Il servizio Gestione Web offre agli amministratori funzionalità di gestione remota e delegata per il server Web, i siti e le applicazioni presenti nel computer. + + + Microsoft URL Rewrite Module 1.1 per IIS 7 + Aggiornamento per URL Rewrite Module 1.1 per IIS 7 + URL Rewrite + Abilita le funzionalità di riscrittura del contenuto e degli URL in IIS 7. + Interfaccia utente + Configura la funzionalità URL Rewrite Module in Gestione IIS. + + + IIS URL Rewrite Module 2 + Aggiornamento per IIS URL Rewrite Module 2 + URL Rewrite + Abilita le funzionalità di riscrittura del contenuto e degli URL in IIS 7. + Interfaccia utente + Configura la funzionalità URL Rewrite Module in Gestione IIS. + + + Administration Pack per IIS 7.0 + Installa le funzionalità di base di [ProductName]. + 1252 + Administration Pack per IIS 7.0 + Microsoft Corporation + Questa versione del sistema operativo non è supportata. [ProductName] può essere installato solo con Windows Server 2008 o Windows Vista Service Pack 1 e versioni successive. + Funzionalità ASP.Net + ASP.NET include le funzionalità Pagine errori e autorizzazione, che consentono di gestire le impostazioni di errori personalizzati e di autorizzazione. + Autenticazione + Descrizione dell'autenticazione ASP.Net. + Autorizzazione + L'autorizzazione ASP.NET consente di configurare le regole per autorizzare gli utenti ad accedere a siti Web e applicazioni. + Pagine errori + Le pagine errori ASP.NET consentono di configurare le risposte di errore HTTP da restituire in caso di errori. + Moduli + Descrizione dei moduli ASP.Net. + Gestori + Descrizione dei gestori ASP.Net. + Editor di configurazione + Editor di configurazione consente di gestire i file di configurazione in Gestione IIS offrendo la possibilità di modificare sezioni, attributi, elementi e raccolte all'interno dei file di configurazione. + Filtro richieste + Filtro richieste consente di configurare le regole di filtro per il sito Web e di limitare il comportamento di protocollo e contenuto. + FastCGI + FastCGI consente di configurare le impostazioni del pool di processi per le applicazioni FastCGI del server Web. + + + Restrizioni IP dinamico per l'installazione di IIS 7 + + + + + + + + + + + + + Restrizioni IP dinamico per IIS 7 - Beta + Restrizioni IP dinamico per IIS 7 - Beta 2 + Restrizioni IP dinamico per IIS 7 - Beta 3 + + Restrizioni IP dinamico per IIS 7 - Versione finale candidata + Restrizioni IP dinamico per IIS 7 - Versione finale candidata 2 + Restrizioni IP dinamico per IIS 7 - Versione finale candidata 3 + + Restrizioni IP dinamico per IIS 7 - RTW + + Restrizioni IP dinamico per IIS 7 + Interfaccia utente di Restrizioni IP dinamico per IIS 7 + + Restrizioni IP dinamico per IIS 7 - Beta rilevato nel computer. Disinstallarlo, quindi riprovare + + + WebDAV 7.5 per IIS 7.0 + Per utilizzare questo prodotto, è necessario installare le funzionalità CoreWebEngine e W3SVC di IIS 7.0. + Modulo server WebDAV + Interfaccia utente di amministrazione WebDAV + + + IIS Search Engine Optimization Toolkit 1.0 + IIS Search Engine Optimization Toolkit 1.0 + Search Engine Optimization (SEO) Toolkit 1.0 + Il database del programma di installazione contiene la logica e i dati necessari per l'installazione di IIS Search Engine Optimization Toolkit 1.0. + + + Editor IIS + + + Report IIS + Log Parser non installato nel computer in uso. Installare Log Parser 2.2 dal sito Web http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07, quindi continuare con l'installazione di Report IIS. + + + Pacchetti dei prerequisiti non trovati. Eseguire setup.exe per risolvere le dipendenze e installare il programma. + Microsoft SQL Server 2008 Management Objects è un prerequisito per l'installazione di IIS Database Manager. È possibile installare Microsoft SQL Server 2008 Management Objects dal sito http://go.microsoft.com/fwlink/?LinkID=150946. + Microsoft SQL Server System CLR Types è un prerequisito per l'installazione di IIS Database Manager. È possibile installare Microsoft SQL Server System CLR Types dal sito http://go.microsoft.com/fwlink/?LinkID=150949. + + + Microsoft Web Farm Framework + Microsoft External Cache + Web Farm Framework è un requisito per l'installazione di Application Request Routing. Installare Web Farm Framework. + Microsoft Application Request Routing 2.5 + Runtime + Aggiunge le funzionalità di Application Request Routing a IIS. + Interfaccia utente + Configura la funzionalità Application Request Routing in Gestione IIS. + + + Snap-in di Microsoft Windows PowerShell per IIS 7.0 + + + Installazione guidata piattaforma Web Microsoft 4.0 + Installazione guidata piattaforma Web Microsoft + [ProductName] richiede Windows XP SP2, Windows 2003 SP1, Windows Vista o versione successiva. + [ProductName] richiede Windows XP Service Pack 3, Windows Server 2003 Service Pack 2 o versione successiva. + + + Programma di installazione servizi Microsoft Windows Azure + Programma di installazione servizi Microsoft Windows Azure + + + Gestione Internet Information Services (IIS) 7+ + Client Gestione IIS + Remoting Support + Per questo prodotto è necessario Windows XP SP2, Windows 2003 SP1, Windows Vista SP1, Windows 7 o versione successiva + La Console di gestione IIS necessaria per la gestione dei server IIS remoti non è installata. Installare la Console di gestione IIS prima di installare il supporto di gestione remoto. A tale scopo, aprire "Pannello di controllo->Programmi->Attiva o disattiva le funzionalità Windows" e selezionare Console di gestione IIS nella funzionalità Internet Information Services. + Questo prodotto non è necessario in Windows Server 2008 o in Windows Server 2008 R2 o versione successiva. Per installare la Console di gestione IIS, aprire Gestione server e selezionare la Console di gestione IIS nei Servizi ruolo per il ruolo Server Web. + + + IIS Manager Publishing per IIS 7.0 + Interfaccia utente di pubblicazione + + + Application Warm-Up 1.0 per IIS 7.5 + + + + Nel computer è installato un prodotto incompatibile, [CONFLICTING_PRODUCT_NAME]. Non è possibile continuare l'installazione di [ProductName]. Per installare il prodotto, utilizzare Installazione applicazioni nel Pannello di controllo e rimuovere [CONFLICTING_PRODUCT_NAME]. + Per installare [ProductName], sono richiesti i privilegi di amministratore. + Per utilizzare [ProductName], è richiesto IIS versione 7.0. + Per installare [ProductName], è richiesto IIS versione 7.0 o versione successiva. + Per installare [ProductName] è necessario IIS 7.5 o versione successiva. + Per installare [ProductName] è necessario IIS versione 7 o 7.5. + Versione beta di [ProductName] rilevata nel computer in uso. + Nel computer in uso è stata rilevata una versione più recente di [ProductName]. + L'installazione non può continuare poiché un'altra istanza di [ProductName] è già installata nel computer in uso. Disinstallarla e quindi riavviare l'installazione. + Per utilizzare [ProductName], è necessario installare le funzionalità CoreWebEngine e W3SVC di IIS 7.0. + Per utilizzare [ProductName], è necessario installare la Console di gestione IIS. + Arrestare Servizio Attivazione processo Windows (WAS) e Servizio di gestione Web (WMSvc) prima di installare [ProductName]. Avviare i servizi dopo l'installazione di [ProductName]. + Per installare [ProductName], è richiesta la metabase IIS. + Impossibile installare la versione a 64 bit di [ProductName] in un'edizione a 32 bit di Microsoft Windows. + Impossibile installare la versione a 32 bit di [ProductName] in un'edizione a 64 bit di Microsoft Windows. + Per installare [ProductName], è richiesto Microsoft .NET Framework versione 2.0 o versione successiva. + Microsoft .NET Framework versione 3.5 o successiva necessario per installare [ProductName]. Utilizzare 'Aggiungi funzionalità' in Server Manager per installare Microsoft .NET versione 3.5. + Microsoft .NET Framework versione 4.0 o successiva necessario per installare [ProductName]. + Prima di installare [ProductName], installare Microsoft .NET Framework versione 2.0 Service Pack 1 o versione successiva. + Impossibile disabilitare il servizio Windows Update (wuauserv). È richiesto per installare [ProductName]. + Lo snap-in di PowerShell fa parte del sistema operativo Windows. Installarlo mediante 'Programmi e funzionalità' o 'Server Manager'. + Installazione guidata piattaforma Web di Microsoft versione 3.0 o successiva necessaria per installare [ProductName]. + + Impossibile rilevare la configurazione condivisa. + Configurazione condivisa abilitata per IIS. L'installazione di [ProductName] non è supportata quando si utilizza la configurazione condivisa. Disabilitare la configurazione condivisa prima di installare questa funzionalità. + + Arrestare il Servizio Pubblicazione sul Web (W3SVC) prima di installare [ProductName]. Avviare il servizio dopo l'installazione. + Console di gestione IIS PowerShell + Snap-in di IIS PowerShell + Lo snap-in di IIS PowerShell richiede l'installazione di PowerShell v1.0 o v2.0 + Lo snap-in di IIS PowerShell richiede l'installazione di WAS e della configurazione + Stringa non valida. + + + Microsoft Web Farm Framework versione 2.2 + Microsoft Web Farm Agent versione 2.2 + Servizio Web Farm + Servizio Web Farm + Servizio controller Web Farm + Servizio controller Web Farm + Servizio agente Web Farm + Servizio agente Web Farm + L'Installazione guidata piattaforma Web è un prerequisito per l'installazione di Web Farm Framework. Eseguire l'Installazione guidata piattaforma Web dall'indirizzo http://www.microsoft.com/web/downloads/platform.aspx. + Lo Strumento di distribuzione Web è un prerequisito per l'installazione di Web Farm Framework. Installare lo Strumento di distribuzione Web dall'indirizzo http://www.iis.net/download/WebDeploy. + + + Microsoft Web Hosting Framework + Web Hosting Framework + Ruoli e funzionalità di Web Hosting. + Framework di hosting + Framework di hosting fornisce le API e i comandi PowerShell per la gestione di Web Hosting. + Ruolo Web + Ruolo Web esegue l'installazione del Servizio Attivazione processo Windows dinamico e del provider di URL Rewrite per Web Hosting. + Antares Express + Esegue la distribuzione di una configurazione del Pannello di controllo ottimizzata per l'installazione su singolo computer. + Ruolo bilanciamento del carico + Ruolo bilanciamento del carico configura Application Request Router per il routing in base alle regole di Web Hosting. + Controller di hosting + Controller di hosting estende Web Farm Framework 2.0 per consentirne il funzionamento con Web Hosting. + Ruolo di pubblicazione + Installa il supporto per la pubblicazione mediante Distribuzione Web e FTP. + Lo snap-in di PowerShell contiene i cmdlet per gestire l'infrastruttura Microsoft Web Hosting. + Servizio Attivazione processo Windows dinamico + Servizio Attivazione processo Windows dinamico ottimizzato per Web Hosting ad alta densità. + Servizio Misurazione risorse + Installa il servizio Misurazione risorse che abilita la raccolta e la pubblicazione delle informazioni sul runtime e sull'integrità. + Misurazione risorse + Abilita la raccolta e la pubblicazione delle informazioni sul runtime e sull'integrità da parte di Ruolo Web. + Imposizione quota hosting + Esegue il monitoraggio dell'utilizzo delle risorse dei siti Web ed esegue azioni personalizzate quando la quota relativa all'utilizzo viene superata. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/JPN/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/JPN/misc/setupstrings.wxl new file mode 100644 index 0000000000..ac70825d59 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/JPN/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 1041 + + + + 共有構成のインストール オプション + IIS 共有構成をインストールするためのオプションを選択します + インストール時に共有構成を更新する + 共有構成を使用する IIS サーバーに、このモジュールをインストールしようとしています。その他の IIS サーバーでこの共有構成を使用している場合は、これらすべてのコンピューターにこのモジュールをインストールする必要があります。個々の Web サーバーの障害を最小限に抑えるには、以下の手順でこのモジュールをインストールします。まず、最後の 1 台を除くすべてのコンピューターに、共有構成を更新せずにモジュールをインストールします。そのためには、下のチェック ボックスをオフにします。 +これにより、共有構成に変更を加えることなく、各コンピューターでモジュールに必要なバイナリとファイルがすべてインストールされます。次に、最後のコンピューターで、実行に使用しているユーザー ID が、UNC 共有にある applicationhost.config ファイルに対する読み取りと書き込みのアクセス権を持っていることを確認します。そのうえで、モジュールをインストールし、下にある [インストール時に共有構成を更新する] チェック ボックスをオンにします。 + + + WebConfig カスタム アクションを初期化しています + web.config を更新しています + + + + IIS 詳細ログ + IIS パイプライン データの詳細ログを有効にします。 + IIS 詳細ログ + 拡張可能なフィールド選択機能を備えたカスタム ログ ファイルの作成を有効にします。 + IIS 詳細ログの更新 + + + + IIS Transform Manager + Beta + Transform Manager の IIS Media Services を有効にします。 + IIS Transform Manager + メディア変換の作成を有効にします。 + IIS Transform Manager ホスト + [ProductName] 用のサービス ホスト。 + IIS Transform Manager + オンデマンド メディア ファイルを代替ファイルおよびコンテナー形式にバッチで変換します。 + IIS Transform Manager 1.0 Expression Encoder SP Task パッケージがコンピューターにインストールされています。[ProductName] をインストールする前にそのパッケージをアンインストールする必要があります。 + + [ProductName] をインストールするには、Microsoft .NET Framework 3.5 が必要です。サーバー マネージャーの機能の追加ウィザードを使用して .NET Framework 3.5.1 の各機能をインストールするか、[Windows の機能の有効化または無効化] を使用して Microsoft .NET Framework 3.5 を有効にします。 + + + + IIS デジタル著作権管理 + Beta + Smooth Streaming プレゼンテーションのデジタル著作権管理を有効にします。 + + + ASP.NET がインストールされていません + + + + + + + + + このコンピューターで、IIS Smooth Streaming - Beta が見つかりました。[ProductName] のインストールを続行できません。この製品をインストールするには、コントロール パネルの [プログラムの追加と削除] を使用して、IIS Smooth Streaming - Beta をアンインストールしてください。 + このコンピューターには、互換性のないバージョンの IIS Media Services が存在します。[ProductName] のインストールを続行できません。この製品をインストールするには、コントロール パネルの [プログラムの追加と削除] を使用して、IIS Media Services をアンインストールしてください。 + このコンピューターには、この製品の新しいバージョンが既にインストールされているか、新しいバージョンを入手してインストールすることができます。[ProductName] のインストールを続行できません。この製品のより新しいバージョンをインストールするには、コントロール パネルの [プログラムの追加と削除] を使用して、IIS Media Services を更新してください。 + プレイリスト ファイルの変換が必要 + + + + + 古い IIS Media Services ファイルが見つかりました + + + + + ベータ版の IIS Media Services ファイルが見つかりました + + + + + + IIS Media Pack 1.0 + IIS Media Pack 1.0 の更新 + IIS Media Services 2.0 + IIS Media Services 2.0 の更新 + IIS Media Services 3.0 + IIS Media Services 3.0 TAP 2 + IIS Media Services 3.0 の更新 + IIS Media Services の機能とツール。 + IIS Media Services 5 Premium の機能およびツール。 + IIS Media Services 4.0 Beta 1 + IIS Media Services 4.0 + IIS Media Services 4.5 Beta 1 + IIS Media Services 5 Premium + + Web プレイリスト + プレイリストで参照されたメディア アセットに対するクライアントの再生を制御します。 + セッション ヘルパー + ASP.NET セッション状態保持を有効にします (Web サーバー (IIS) の ASP.NET 役割サービスが必要)。 + ユーザー インターフェイス + IIS マネージャーで Web プレイリスト機能を構成します。 + + ビット レート調整 + クライアントによってダウンロードされるファイルの配信を制限することによって帯域幅を節約します。 + ユーザー インターフェイス + IIS マネージャーでビット レート調整機能を構成します。 + + アセット + クライアントに対し、オンデマンド アセットの HTTP アダプティブ ストリーミングを有効にします。 + ユーザー インターフェイス + IIS マネージャーで Smooth Streaming 機能を構成します。 + + チャネル + クライアントに対し、チャネル ブロードキャストの HTTP アダプティブ ストリーミングを有効にします。 + ユーザー インターフェイス + IIS Manager で Live Smooth Streaming 機能を構成します。 + + デジタル著作権管理 + Smooth Streaming メディアの暗号化とライセンスを提供します。 + ユーザー インターフェイス + IIS マネージャーでデジタル著作権管理機能を構成します。 + + [ProductName] には Microsoft Windows Vista Service Pack 1 以降が必要です。 + [ProductName] を Vista Home Basic にインストールすることはできません。 + [ProductName] には Microsoft Windows 7 Service Pack 1 以降が必要です。 + + + IIS Database Manager + IIS Database Manager + + + Microsoft Web Management Service 2 + Microsoft Web Management Service + [ProductName] の基本的な機能をインストールします。 + Microsoft Web Management Service 2 + Web 管理サービスでは、管理者がこのコンピューターの Web サーバー、サイトおよびアプリケーションを管理する機能をリモートで操作したり、委任したりすることができます。 + + + Microsoft URL Rewrite Module 1.1 for IIS 7 + URL Rewrite Module 2 for IIS 7 の更新 + URL 書き換え + IIS 7 への URL およびコンテンツの書き換え機能を有効にします。 + ユーザー インターフェイス + URL 書き換えモジュール機能を IIS マネージャーで構成します。 + + + IIS URL Rewrite Module 2 + IIS URL Rewrite Module 2 の更新プログラム + URL 書き換え + IIS 7 への URL およびコンテンツの書き換え機能を有効にします。 + ユーザー インターフェイス + URL 書き換えモジュール機能を IIS マネージャーで構成します。 + + + Administration Pack for IIS 7.0 + [ProductName] の基本的な機能をインストールします。 + 1252 + Administration Pack for IIS 7.0 + Microsoft Corporation + このバージョンのオペレーティング システムはサポートされません。[ProductName] は、Windows Server 2008 か、または Windows Vista Service Pack 1 以降にのみインストールできます。 + ASP.Net の機能 + ASP.NET には、承認とエラー ページの機能があり、それを使って承認やカスタム エラーの設定を管理できます。 + 認証 + ASP.Net 認証の説明。 + 承認 + ASP.NET の承認では、Web サイトおよびアプリケーションへのユーザーのアクセスを承認するための規則を構成できます。 + エラー ページ + ASP.NET エラー ページでは、エラー発生時に返す HTTP エラー応答を構成できます。 + モジュール + ASP.Net モジュールの説明。 + ハンドラー + ASP.Net ハンドラーの説明。 + 構成エディター + 構成エディターを使用して、IIS マネージャー内の構成ファイルを管理できます。構成ファイル内のセクション、属性、要素、およびコレクションを編集することができます。 + 要求のフィルタリング + 要求のフィルタリングでは、Web サイトのフィルタリング規則を構成したり、プロトコルやコンテンツの動作を制限したりできます。 + Fast CGI + FastCGI では、Web サーバー上の FastCGI アプリケーション用のプロセス プール設定を構成できます。 + + + Dynamic IP Restrictions for IIS 7 セットアップ + + + + + + + + + + + + + Dynamic IP Restrictions for IIS 7 - Beta + Dynamic IP Restrictions for IIS 7 - Beta 2 + Dynamic IP Restrictions for IIS 7 - Beta 3 + + Dynamic IP Restrictions for IIS 7 - リリース候補 + Dynamic IP Restrictions for IIS 7 - リリース候補 2 + Dynamic IP Restrictions for IIS 7 - リリース候補 3 + + Dynamic IP Restrictions for IIS 7 - RTW + + Dynamic IP Restrictions for IIS 7 + Dynamic IP Restrictions for IIS 7 のユーザー インターフェイス + + このコンピューターに Dynamic IP Restrictions for IIS 7 - Beta が見つかりました。アンインストールしてからやり直してください + + + WebDAV 7.5 For IIS 7.0 + この製品を使用するには、IIS 7.0 の CoreWebEngine および W3SVC 機能をインストールする必要があります。 + WebDAV サーバー モジュール + WebDAV 管理ユーザー インターフェイス + + + IIS Search Engine Optimization ツールキット 1.0 + IIS Search Engine Optimization ツールキット 1.0 + Search Engine Optimization (SEO) ツールキット 1.0 + このインストーラー データベースには、IIS Search Engine Optimization ツールキット 1.0 のインストールに必要なロジックとデータが含まれています。 + + + IIS エディター + + + IIS レポート + このコンピューターには、Log Parser がインストールされていません。http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07 から Log Parser 2.2 をインストールし、IIS レポートのインストールを続行してください。 + + + 前提条件のパッケージが見つかりませんでした。setup.exe を実行して依存関係を解決してから、このプログラムをインストールしてください。 + IIS Database Manager のインストールの前提条件として、Microsoft SQL Server 2008 管理オブジェクトが必要です。Micrsoft SQL Server 2008 管理オブジェクトは http://go.microsoft.com/fwlink/?LinkID=150946 からインストールできます。 + IIS Database Manager のインストールの前提要件として、Microsoft SQL Server System CLR Types が必要です。Microsoft SQL Server System CLR Types は、http://go.microsoft.com/fwlink/?LinkID=150949 からインストールできます。 + + + Microsoft Web Farm Framework + Microsoft External Cache + アプリケーション要求ルーティング処理の前提条件として、Web Farm Framework が必要です。Web Farm Framework をインストールしてください。 + Microsoft Application Request Routing 2.5 + ランタイム + アプリケーション要求ルーティング処理の機能を IIS に追加します。 + ユーザー インターフェイス + アプリケーション要求ルーティング処理の機能を IIS マネージャーで構成します。 + + + Microsoft Windows PowerShell snap-in for IIS 7.0 + + + Microsoft Web Platform Installer 4.0 + Microsoft Web Platform Installer + [ProductName] には、Windows XP SP2、Windows 2003 SP1、Windows Vista 以降が必要です。 + [ProductName] には、Windows XP Service Pack 3、Windows Server 2003 Service Pack 2 以降が必要です。 + + + Microsoft Windows Azure サービス インストーラー + Microsoft Windows Azure サービス インストーラー + + + インターネット インフォメーション サービス (IIS) 7 以上のマネージャー + IIS マネージャー クライアント + リモート処理サポート + この製品には、Windows XP SP2、Windows 2003 SP1、Windows Vista SP1、または Windows 7 以上が必要です。 + リモート IIS サーバーを管理するために必要な IIS 管理コンソールがインストールされていません。コントロール パネルの [プログラム] で、[Windows の機能の有効化または無効化] を開き、Ineternet Information Services 機能から [IIS 管理コンソール] を選択して、IIS 管理コンソールをインストールしてから、リモート管理サポートをインストールしてください。 + この製品は、Windows Server 2008 または Windows Server 2008 R2 以上では必須ではありません。サーバー マネージャーを開き、Web サーバーの役割の役割サービスで [IIS 管理コンソール] を選択して、IIS 管理コンソールをインストールしてください。 + + + IIS Manager Publishing for IIS 7.0 + Publishing のユーザー インターフェイス + + + Application Warm-Up 1.0 for IIS 7.5 + + + + 互換性のない製品 [CONFLICTING_PRODUCT_NAME] がこのコンピューター上にあります。[ProductName] のインストールを続行できません。この製品をインストールするには、[コントロール パネル] の [プログラムの追加と削除] を使用して、[CONFLICTING_PRODUCT_NAME] を削除してください。 + [ProductName] をインストールするには管理者特権が必要です。 + [ProductName] を使用するには、IIS Version 7.0 が必要です。 + [ProductName] をインストールするには、IIS Version 7.0 以降が必要です。 + [ProductName] をインストールするには、IIS Version 7.5 以降が必要です。 + [ProductName] をインストールするには、IIS Version 7 または 7.5 が必要です。 + このコンピューターに [ProductName] のベータ版が見つかりました。 + このコンピューターに、より新しいバージョンの [ProductName] が見つかりました。 + このコンピューターには、[ProductName] の別のインスタンスが既にインストールされているため、セットアップを続行できません。最初にアンインストールしてから、再度インストールを行ってください。 + [ProductName] を使用するには、IIS 7.0 の CoreWebEngine および W3SVC 機能をインストールする必要があります。 + [ProductName] を使用するには、IIS 管理コンソールをインストールする必要があります。 + Windows プロセス起動サービス (WAS) と Web 管理サービス (WMSvc) の両方のサービスを停止してから、[ProductName] をインストールしてください。[ProductName] のインストール後にサービスを起動する必要があります。 + [ProductName] をインストールするには、IIS メタベースが必要です。 + 64 ビット版の [ProductName] を 32 ビット版の Microsoft Windows にインストールすることはできません。 + 32 ビット版の [ProductName] を 64 ビット版の Microsoft Windows にインストールすることはできません。 + [ProductName] をインストールするには、Microsoft .NET Framework Version 2.0 以降が必要です。 + [ProductName] をインストールするには、Microsoft .NET Framework Version 3.5 以降が必要です。サーバー マネージャーの [機能の追加] を使用して、Microsoft .Net Version 3.5 をインストールしてください。 + [ProductName] をインストールするには、Microsoft .NET Framework Version 4.0 以降が必要です。 + [ProductName] をインストールする前に、Microsoft .NET Framework Version 2.0 Service Pack 1 (またはそれ以降の Service Pack) をインストールしてください。 + Windows Update (wuauserv) サービスを無効にすることはできません。[ProductName] をインストールする場合は必須です。 + PowerShell スナップインは、Windows オペレーティング システムに付属しています。[プログラムと機能] またはサーバー マネージャーからインストールしてください。 + [ProductName] をインストールするには、Microsoft Web Platform Installer Version 3.0 以降が必要です。 + + 共有構成を検出できませんでした。 + IIS に対して共有構成が有効になっています。共有構成を使用している場合、[ProductName] をインストールすることはサポートされません。この機能をインストールする場合は、あらかじめ共有構成を無効にしてください。 + + [ProductName] をインストールする前に、World Wide Web 発行サービス (W3SVC) を停止してください。インストール後は、このサービスを起動する必要があります。 + IIS PowerShell 管理コンソール + IIS PowerShell スナップイン + IIS PowerShell スナップインを使用するには、PowerShell v1.0 または v2.0 がインストールされている必要があります。 + IIS PowerShell スナップインを使用するには、WAS および構成がインストールされている必要があります。 + これは仮の文字列です。 + + + Microsoft Web Farm Framework Version 2.2 + Microsoft Web Farm Agent Version 2.2 + Web Farm サービス + Web Farm サービス + Web Farm コントローラー サービス + Web Farm コントローラー サービス + Web Farm エージェント サービス + Web Farm エージェント サービス + Web Farm Framework をインストールする前提条件として、Web Platform Installer が必要です。http://www.microsoft.com/web/downloads/platform.aspx から Web Platform Installer をインストールしてください。 + Web Farm Framework をインストールする前提条件として、Web 配置ツールが必要です。http://www.microsoft.com/downloads/details.aspx?displaylang=ja&FamilyID=c7ca4240-5427-42ba-bd46-29a755549e37 (x64) または、http://www.microsoft.com/downloads/details.aspx?displaylang=ja&FamilyID=f2b0fe35-15ae-4638-b72e-f96535c64591 (x86) から Web 配置ツールをインストールしてください。 + + + Microsoft Web Hosting Framework + Web Hosting Framework + Web ホスティングの役割と機能。 + Hosting Framework + Hosting Framework は、Web ホスティングを管理するための API と PowerShell コマンドを提供します。 + Web ロール + Web ロールは、Web ホスティングのための動的 WAS サービスおよび URL 書き換えプロバイダーをインストールします。 + Antares Express + シングル コンピューター セットアップ用に最適化されたコントロール パネルの構成を展開します。 + 負荷分散装置の役割 + 負荷分散装置の役割は、Web ホスティングの規則を基にしてルーティングするようにアプリケーション要求ルーターを構成します。 + ホスティング コントローラー + ホスティング コントローラーは、Web ホスティングと連携するように Web Farm Framework 2.0 を拡張します。 + Publishing ロール + Web 配置および FTP 発行のサポートをインストールします。 + これは、Microsoft Web Hosting インフラストラクチャを管理するためのコマンドレットを含む PowerShell スナップインです。 + 動的 WAS サービス + 高密度な Web ホスティング用に最適化された Windows プロセス アクティブ化サービス。 + リソース メータリング サービス + ランタイムおよび正常性情報の両方の収集と発行を有効にする、リソース メータリング サービスをインストールします。 + リソース メータリング + Web ロールからのランタイムおよび正常性情報の収集と発行を有効にします。 + ホスティング クォータの強制 + Web サイトのリソースの使用率を監視し、使用率のクォータを超えた場合にカスタム アクションを実行します。 + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/KOR/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/KOR/misc/setupstrings.wxl new file mode 100644 index 0000000000..f4cb5f3312 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/KOR/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 1042 + + + + 공유 구성 설치 옵션 + IIS 공유 구성 설치 옵션을 선택합니다. + 설치 시 공유 구성 업데이트 + 공유 구성을 사용 중인 IIS 서버에 이 모듈을 설치하는 중입니다. 이 공유 구성을 사용하는 IIS 서버가 더 있는 경우 해당하는 모든 컴퓨터에 이 모듈을 설치해야 합니다. 각 웹 서버의 장애를 최소화하려면 다음 절차에 따라 이 모듈을 설치해야 합니다. 첫째, 마지막 컴퓨터를 제외한 모든 컴퓨터에서 공유 구성을 업데이트하지 않고 모듈을 설치합니다. 아래의 확인란을 선택하지 않고 이 작업을 실행하십시오. +이렇게 하면 공유 구성을 변경하지 않고 모듈에 필요한 모든 파일 및 이진 파일이 각 컴퓨터에 설치됩니다. 둘째, 마지막 컴퓨터에서 사용자가 실행 중인 사용자 ID에 UNC 공유의 applicationhost.config 파일에 대한 읽기 및 쓰기 권한이 있는지 확인합니다. 그런 다음 모듈을 설치하고 아래의 업데이트 공유 구성 옵션을 선택합니다. + + + WebConfig 사용자 지정 작업을 초기화하는 중 + web.config 업데이트 중 + + + + IIS 고급 로깅 + IIS 파이프라인 데이터의 고급 로깅을 사용합니다. + IIS 고급 로깅 + 확장 가능한 필드 선택으로 사용자 지정 로그 파일을 만들 수 있도록 설정합니다. + IIS 고급 로깅 업데이트 + + + + IIS Transform Manager + 베타 + Transform Manager IIS 미디어 서비스를 활성화합니다. + IIS Transform Manager + 미디어 변환을 만들 수 있도록 설정합니다. + IIS Transform Manager 호스트 + [ProductName]의 서비스 호스트입니다. + IIS Transform Manager + 요청 시 미디어 파일을 대체 파일 및 컨테이너 형식으로 일괄 변환합니다. + 컴퓨터에 IIS Transform Manager 1.0 Expression Encoder SP 작업 패키지가 설치되어 있습니다. [ProductName]을(를) 설치하기 전에 IIS Transform Manager 1.0 Expression Encoder SP 작업 패키지를 제거해야 합니다. + + [ProductName]을(를) 설치하려면 Microsoft .NET Framework 3.5가 필요합니다. 서버 관리자에서 '기능 추가 마법사'를 사용하여 .NET Framework 3.5.1 기능을 설치하거나 'Windows 기능 사용/사용 안 함'을 사용하여 Microsoft .NET Framework 3.5 기능을 활성화합니다. + + + + IIS 디지털 권한 관리 + 베타 + 부드러운 스트리밍 프레젠테이션의 디지털 권한 관리를 활성화합니다. + + + ASP.NET이 설치되어 있지 않습니다. + + + + + + + + + 이 컴퓨터에 IIS 부드러운 스트리밍 - 베타가 있으므로 [ProductName] 설치를 계속할 수 없습니다. 이 제품을 설치하려면 제어판의 [프로그램 추가/제거]를 사용하여 IIS 부드러운 스트리밍 - 베타를 제거하십시오. + 이 컴퓨터에 IIS 미디어 서비스의 비호환 버전이 있으므로 [ProductName] 설치를 계속할 수 없습니다. 이 제품을 설치하려면 제어판의 [프로그램 추가/제거]를 사용하여 IIS 미디어 서비스를 제거하십시오. + 컴퓨터에 이 제품의 최신 버전이 이미 설치되어 있거나 설치에 사용할 수 있으므로 [ProductName] 설치를 계속할 수 없습니다. 이 제품의 최신 버전을 설치하려면 [제어판]에서 [프로그램 추가/제거]를 사용하여 IIS Media Services를 업데이트하십시오. + 재생 목록 파일 변환이 필요합니다. + + + + + 이전 IIS 미디어 서비스 파일이 있습니다. + + + + + 베타 IIS 미디어 서비스 파일이 있습니다. + + + + + + IIS Media Pack 1.0 + IIS Media Pack 1.0에 대한 업데이트 + IIS Media Services 2.0 + IIS Media Services 2.0에 대한 업데이트 + IIS Media Services 3.0 + IIS 미디어 서비스 3.0 TAP 2 + IIS Media Services 3.0에 대한 업데이트 + IIS Media Services 기능 및 도구입니다. + IIS Media Services 5 Premium 기능 및 도구입니다. + IIS 미디어 서비스 4.0 베타 1 + IIS 미디어 서비스 4.0 + IIS 미디어 서비스 4.5 베타 1 + IIS Media Services 5 Premium + + 웹 재생 목록 + 재생 목록에 참조된 미디어 자산의 클라이언트 재생을 제어합니다. + Session Helper + ASP.NET 세션 상태가 지속되도록 설정합니다(웹 서버(IIS)에 대한 ASP.NET 역할 서비스 필요). + 사용자 인터페이스 + IIS 관리자에서 웹 재생 목록 기능을 구성합니다. + + 비트 전송률 제한 + 클라이언트가 다운로드하는 파일 전달을 제한하여 대역폭을 절약합니다. + 사용자 인터페이스 + IIS 관리자에서 비트 전송률 제한 기능을 구성합니다. + + 자산 + 클라이언트에 대한 주문형 자산의 HTTP 적응 스트리밍을 사용하도록 설정합니다. + 사용자 인터페이스 + IIS 관리자에서 부드러운 스트리밍 기능을 구성합니다. + + 채널 + 클라이언트에 대한 채널 브로드캐스트의 HTTP 적응 스트리밍을 사용하도록 설정합니다. + 사용자 인터페이스 + IIS 관리자에서 Live Smooth Streaming 기능을 구성합니다. + + 디지털 권한 관리 + 부드러운 스트리밍 미디어의 암호화 및 라이선스를 제공합니다. + 사용자 인터페이스 + IIS 관리자의 디지털 권한 관리 기능을 구성합니다. + + [ProductName]에는 Microsoft Windows Vista 서비스 팩 1 이상이 필요합니다. + [ProductName]은(는) Vista Home Basic에 설치할 수 없습니다. + [ProductName]에는 Microsoft Windows 7 서비스 팩 1 이상이 필요합니다. + + + IIS 데이터베이스 관리자 + IIS 데이터베이스 관리자 + + + Microsoft Web Management Service 2 + Microsoft Web Management Service + [ProductName]의 기본 기능을 설치합니다. + Microsoft Web Management Service 2 + Web Management Service를 사용하면 관리자가 원격 및 위임된 관리 기능을 사용하여 이 컴퓨터에 있는 웹 서버, 사이트 및 응용 프로그램을 관리할 수 있습니다. + + + IIS 7용 Microsoft URL 재작성 모듈 1.1 + IIS 7용 URL 재작성 모듈 1.1에 대한 업데이트 + URL 재작성 + IIS 7에 대한 URL 및 콘텐츠 재작성 기능을 활성화합니다. + 사용자 인터페이스 + IIS 관리자에서 URL 재작성 모듈 기능을 구성합니다. + + + IIS URL 재작성 모듈 2 + IIS URL 재작성 모듈 2에 대한 업데이트 + URL 재작성 + IIS 7에 대한 URL 및 콘텐츠 재작성 기능을 활성화합니다. + 사용자 인터페이스 + IIS 관리자에서 URL 재작성 모듈 기능을 구성합니다. + + + IIS 7.0 관리 팩 + [ProductName]의 기본 기능을 설치합니다. + 1252 + IIS 7.0 관리 팩 + Microsoft Corporation + 이 운영 체제 버전은 지원되지 않습니다. [ProductName]은(는) Windows Server 2008 또는 Windows Vista 서비스 팩 1 이상에만 설치할 수 있습니다. + ASP.NET 기능 + ASP.NET에는 권한 부여 및 사용자 지정 오류 설정을 관리하는 데 사용할 수 있는 권한 부여 및 오류 페이지 기능이 있습니다. + 인증 + ASP.NET 인증에 대한 설명입니다. + 권한 부여 + ASP.NET 권한 부여를 사용하여 사용자에게 웹 사이트 및 응용 프로그램에 액세스할 수 있는 권한을 부여하는 규칙을 구성할 수 있습니다. + 오류 페이지 + ASP.NET 오류 페이지를 사용하여 오류가 발생했을 때 반환할 HTTP 오류 응답을 구성할 수 있습니다. + 모듈 + ASP.NET 모듈에 대한 설명입니다. + 처리기 + ASP.NET 처리기에 대한 설명입니다. + 구성 편집기 + 구성 편집기를 통해 구성 파일의 섹션, 특성, 요소 및 컬렉션을 편집하여 IIS 관리자의 구성 파일을 관리할 수 있습니다. + 요청 필터링 + 요청 필터링을 사용하여 웹 사이트에 대한 필터링 규칙을 구성하고 프로토콜 및 콘텐츠 동작을 제한할 수 있습니다. + Fast CGI + FastCGI를 사용하여 웹 서버의 FastCGI 응용 프로그램에 대한 프로세스 풀 설정을 구성할 수 있습니다. + + + IIS 7 설치에 대한 동적 IP 제한 + + + + + + + + + + + + + IIS 7용 동적 IP 제한 - 베타 + IIS 7용 동적 IP 제한 - 베타 2 + IIS 7용 동적 IP 제한 - 베타 3 + + IIS 7용 동적 IP 제한 - 릴리스 후보 + IIS 7용 동적 IP 제한 - 릴리스 후보 2 + IIS 7용 동적 IP 제한 - 릴리스 후보 3 + + IIS 7용 동적 IP 제한 - RTW + + IIS 7용 동적 IP 제한 + IIS 7용 동적 IP 제한 사용자 인터페이스 + + 이 시스템에서 IIS 7 - 베타에 대한 동적 IP 제한 사항이 발견되었습니다. 이 제한 사항을 제거한 후 다시 시도하십시오. + + + IIS 7.0용 WebDAV 7.5 + 이 제품을 사용하려면 IIS 7.0 CoreWebEngine 및 W3SVC 기능이 설치되어 있어야 합니다. + WebDAV 서버 모듈 + WebDAV 관리 사용자 인터페이스 + + + IIS 검색 엔진 최적화 도구 키트 1.0 + IIS 검색 엔진 최적화 도구 키트 1.0 + 검색 엔진 최적화(SEO) 도구 키트 1.0 + 이 설치 프로그램 데이터베이스에는 IIS 검색 엔진 최적화 도구 키트 1.0을 설치하는 데 필요한 논리 및 데이터가 들어 있습니다. + + + IIS 편집기 + + + IIS 보고서 + 이 컴퓨터에 Log Parser가 설치되어 있지 않습니다. http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07에서 Log Parser 2.2를 설치한 다음 IIS 보고서 설치를 계속하십시오. + + + 필수 구성 요소 패키지가 없습니다. setup.exe를 실행하여 종속성을 해결한 다음 이 프로그램을 설치하십시오. + IIS 데이터베이스 관리자를 설치하려면 Microsoft SQL Server 2008 관리 개체가 설치되어 있어야 합니다. http://go.microsoft.com/fwlink/?LinkID=150946에서 Microsoft SQL Server 2008 관리 개체를 설치할 수 있습니다. + IIS 데이터베이스 관리자를 설치하려면 Microsoft SQL Server System CLR Types가 설치되어 있어야 합니다. http://go.microsoft.com/fwlink/?LinkID=150949에서 Microsoft SQL Server System CLR Types를 설치할 수 있습니다. + + + Microsoft Web Farm Framework + Microsoft External Cache + 응용 프로그램 요청 라우팅을 설치하려면 Web Farm Framework가 설치되어 있어야 합니다. Web Farm Framework를 설치하십시오. + Microsoft 응용 프로그램 요청 라우팅 버전 2.5 + 런타임 + IIS에 응용 프로그램 요청 라우팅 기능을 추가합니다. + 사용자 인터페이스 + IIS 관리자에서 응용 프로그램 요청 라우팅 기능을 구성합니다. + + + IIS 7.0용 Microsoft Windows PowerShell 스냅인 + + + Microsoft 웹 플랫폼 설치 관리자 4.0 + Microsoft 웹 플랫폼 설치 관리자 + [ProductName]에는 Windows XP SP2, Windows 2003 SP1, Windows Vista 이상이 필요합니다. + [ProductName]을(를) 사용하려면 Windows XP 서비스 팩 3, Windows Server 2003 서비스 팩 2 이상이 필요합니다. + + + Microsoft Windows Azure Services 설치 관리자 + Microsoft Windows Azure Services 설치 관리자 + + + IIS(인터넷 정보 서비스) 7+ 관리자 + IIS 관리자 클라이언트 + 원격 지원 + 이 제품에는 Windows XP SP2, Windows 2003 SP1, Windows Vista SP1, Windows 7 이상이 있어야 합니다. + 원격 IIS 서버 관리에 필요한 IIS 관리 콘솔이 설치되어 있지 않습니다. 원격 관리 지원을 설치하기 전에 '제어판->프로그램->Windows 기능 사용/사용 안 함'을 열고 인터넷 정보 서비스 기능에서 IIS 관리 콘솔을 선택하여 IIS 관리 콘솔을 설치하십시오. + 이 제품은 Windows Server 2008 또는 Windows Server 2008 R2 이상에서 필수 사항이 아닙니다. 서버 관리자를 열고 웹 서버 역할에 대한 역할 서비스에서 IIS 관리 콘솔을 선택하여 IIS 관리 콘솔을 설치하십시오. + + + IIS 7.0용 IIS 관리자 게시 + 게시 사용자 인터페이스 + + + IIS 7.5용 응용 프로그램 웜업 + + + + 이 컴퓨터에 호환되지 않는 제품 [CONFLICTING_PRODUCT_NAME]이(가) 있습니다. [ProductName]의 설치를 계속할 수 없습니다. 이 제품을 설치하려면 제어판에서 프로그램 추가/제거를 사용하여 [CONFLICTING_PRODUCT_NAME]을(를) 제거하십시오. + [ProductName]을(를) 설치하려면 관리자 권한이 있어야 합니다. + [ProductName]을(를) 사용하려면 IIS 버전 7.0이 있어야 합니다. + [ProductName]을(를) 설치하려면 IIS 버전 7.0 이상이 있어야 합니다. + [ProductName]을(를) 설치하려면 IIS 버전 7.5 이상이 있어야 합니다. + [ProductName]을(를) 설치하려면 IIS 버전 7 또는 7.5가 있어야 합니다. + 이 컴퓨터에 [ProductName]의 베타 버전이 설치되어 있습니다. + 이 컴퓨터에 [ProductName]의 상위 버전이 설치되어 있습니다. + 컴퓨터에 [ProductName]의 다른 인스턴스가 이미 설치되어 있어서 설치를 계속할 수 없습니다. 먼저 해당 인스턴스를 제거한 다음 설치 프로그램을 다시 시작하십시오. + [ProductName]을(를) 사용하려면 IIS 7.0 CoreWebEngine 및 W3SVC 기능이 설치되어 있어야 합니다. + [ProductName]을(를) 사용하려면 IIS 관리 콘솔이 설치되어 있어야 합니다. + [ProductName]을(를) 설치하기 전에 WAS(Windows Process Activation Service) 및 WMSvc(Web Management Service)를 모두 중지하십시오. [ProductName]을(를) 설치한 후에 해당 서비스를 시작해야 합니다. + [ProductName]을(를) 설치하려면 IIS 메타베이스가 있어야 합니다. + [ProductName] 64비트 버전은 Microsoft Windows 32비트 버전에 설치할 수 없습니다. + [ProductName] 32비트 버전은 Microsoft Windows 64비트 버전에 설치할 수 없습니다. + [ProductName]을(를) 설치하려면 Microsoft .NET Framework 버전 2.0 이상이 설치되어 있어야 합니다. + [ProductName]을(를) 설치하려면 Microsoft .NET Framework 버전 3.5 이상이 필요합니다. 서버 관리자에서 '기능 추가'를 사용하여 Microsoft .Net 버전 3.5를 설치하십시오. + [ProductName]을(를) 설치하려면 Microsoft .NET Framework 버전 4.0 이상이 필요합니다. + [ProductName]을(를) 설치하기 전에 Microsoft .NET Framework 버전 2.0 서비스 팩 1 이상을 설치하십시오. + [ProductName]을(를) 설치하는 데 필요하므로 Windows Update(wuauserv) 서비스를 비활성화할 수 없습니다. + PowerShell 스냅인은 Windows 운영 체제에 포함되어 있습니다. '프로그램 및 기능' 또는 '서버 관리자'를 사용하여 설치하십시오. + [ProductName]을(를) 설치하려면 Microsoft 웹 플랫폼 설치 관리자 버전 3.0 이상이 필요합니다. + + 설치 프로그램이 공유 구성을 검색하지 못했습니다. + IIS에 대해 공유 구성이 활성화되어 있습니다. 공유 구성을 사용하는 경우 [ProductName]을(를) 설치할 수 없습니다. 이 기능을 설치하려면 공유 구성을 비활성화하십시오. + + [ProductName]을(를) 설치하려면 먼저 W3SVC(World Wide Web Publishing Service)를 중지하십시오. 설치 후 해당 서비스를 다시 시작해야 합니다. + IIS PowerShell 관리 콘솔 + IIS PowerShell 스냅인 + IIS PowerShell 스냅인을 사용하려면 PowerShell v1.0 또는 v2.0이 설치되어 있어야 합니다. + IIS PowerShell 스냅인을 사용하려면 WAS 및 구성이 설치되어 있어야 합니다. + 임시 문자열입니다. + + + Microsoft Web Farm Framework 버전 2.2 + Microsoft 웹 팜 에이전트 버전 2.2 + 웹 팜 서비스 + 웹 팜 서비스 + 웹 팜 컨트롤러 서비스 + 웹 팜 컨트롤러 서비스 + 웹 팜 에이전트 서비스 + 웹 팜 에이전트 서비스 + Web Farm Framework를 설치하려면 웹 플랫폼 설치 관리자가 설치되어 있어야 합니다. 웹 플랫폼 설치 관리자는 http://www.microsoft.com/web/downloads/platform.aspx에서 설치하십시오. + Web Farm Framework를 설치하려면 웹 배포 도구가 설치되어 있어야 합니다. 웹 배포 도구는 http://www.iis.net/download/WebDeploy에서 설치하십시오. + + + Microsoft Web Hosting Framework + Web Hosting Framework + 웹 호스팅 역할 및 기능입니다. + Hosting Framework + Hosting Framework는 웹 호스팅을 관리하기 위한 API 및 PowerShell 명령을 제공합니다. + 웹 역할 + 웹 역할은 웹 호스팅용 동적 WAS 서비스 및 URL 재작성 공급자를 설치합니다. + Antares Express + 단일 컴퓨터 설치에 대해 최적화된 제어판 구성을 배포합니다. + 부하 분산 장치 역할 + 부하 분산 장치 역할은 웹 호스팅 규칙을 기반으로 라우팅하기 위한 응용 프로그램 요청 라우터를 구성합니다. + 호스팅 컨트롤러 + 호스팅 컨트롤러는 웹 호스팅과 작동하도록 Web Farm Framework 2.0을 확장합니다. + 게시 역할 + 웹 배포 및 FTP 게시에 대한 지원을 설치합니다. + Microsoft Web Hosting 인프라 관리를 위한 cmdlets가 포함된 PowerShell 스냅인입니다. + 동적 WAS 서비스 + 고밀도 웹 호스팅에 대해 최적화된 Windows Process Activation Service입니다. + 리소스 계량 서비스 + 런타임 및 상태 정보를 둘 다 수집하고 게시하는 리소스 계량 서비스를 설치합니다. + 리소스 계량 + 웹 역할의 런타임 및 상태 정보를 수집하고 게시할 수 있습니다. + 호스팅 할당량 적용 + 웹 사이트 리소스 사용을 모니터링하고 사용 할당량을 초과하면 사용자 지정 작업을 실행합니다. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/PLK/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/PLK/misc/setupstrings.wxl new file mode 100644 index 0000000000..fccd7b5d05 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/PLK/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 1045 + + + + Opcje instalacji w konfiguracji udostępnionej + Wybierz opcję instalacji w konfiguracji udostępnionej usług IIS + Aktualizuj konfigurację udostępnioną podczas instalacji + Ten moduł zostanie zainstalowany na serwerze usług IIS korzystającym z konfiguracji udostępnionej. Jeśli z tej konfiguracji udostępnionej korzysta więcej serwerów usług IIS, należy zainstalować ten moduł na wszystkich tych komputerach. Aby zminimalizować zakłócenia pracy poszczególnych serwerów sieci Web, najlepiej jest zainstalować ten moduł w następujący sposób: Najpierw zainstaluj moduł na wszystkich komputerach z wyjątkiem ostatniego bez aktualizowania konfiguracji udostępnionej. W tym celu nie zaznaczaj poniższego pola wyboru. + Wtedy na wszystkich komputerach zostaną zainstalowane wszystkie pliki binarne i inne wymagane przez moduł, ale nie zostaną wprowadzone żadne zmiany w konfiguracji udostępnionej. Następnie na ostatnim komputerze sprawdź, czy używana tożsamość użytkownika ma dostęp z prawem do zapisu i odczytu do pliku applicationhost.config w udziale UNC. Jeśli ma, zainstaluj moduł i wybierz poniższą opcję aktualizacji konfiguracji udostępnionej. + + + Inicjowanie akcji niestandardowej WebConfig + Aktualizowanie pliku web.config + + + + Zaawansowane rejestrowanie usług IIS + Włącza zaawansowane rejestrowanie danych potoku usług IIS. + Zaawansowane rejestrowanie usług IIS + Umożliwia tworzenie niestandardowych plików dziennika przy użyciu rozszerzalnego wyboru pól. + Aktualizacja zaawansowanego rejestrowania usług IIS + + + + Menedżer transformat usług IIS + Beta + Włącza menedżera transformat usług IIS Media. + Menedżer transformat usług IIS + Włącza tworzenie transformat plików multimedialnych. + Host menedżera transformat usług IIS + Host usługi programu [ProductName]. + Menedżer transformat usług IIS + Konwersja wsadowa plików multimedialnych na żądnie w celu zmiany formatów kontenerów i plików. + Na komputerze zainstalowano pakiet „IIS Transform Manager 1.0 Expression Encoder SP Task”. Należy go odinstalować przed zainstalowaniem produktu [ProductName]. + + Do zainstalowania produktu [ProductName] jest wymagany program Microsoft .NET Framework w wersji 3.5. Aby zainstalować funkcje programu .NET Framework 3.5.1, należy użyć Kreatora dodawania funkcji w Menedżerze serwerów. Aby włączyć program Microsoft .NET Framework 3.5, należy użyć apletu Włącz lub wyłącz funkcje systemu Windows. + + + + Zarządzanie prawami cyfrowymi w usługach IIS + Beta + Włącza zarządzanie prawami cyfrowymi prezentacji w formacie Smooth Streaming. + + + Niezainstalowany program ASP.NET + + + + + + + + + Na tym komputerze wykryto funkcję Płynne przesyłanie strumieniowe w wersji beta. Nie można kontynuować instalacji produktu [ProductName]. Aby zainstalować ten produkt, usuń funkcję Płynne przesyłanie strumieniowe w wersji beta, używając apletu Dodaj/Usuń programy w Panelu sterowania. + Na tym komputerze znajduje się niezgodna wersja usług IIS Media Services. Nie można kontynuować instalacji produktu [ProductName]. Aby zainstalować ten produkt, usuń usługi IIS Media Services, używając apletu Dodaj/Usuń programy w Panelu sterowania. + Nowsza wersja tego produktu jest już zainstalowana lub dostępna do zainstalowania na tym komputerze. Nie można kontynuować instalacji produktu [ProductName]. Aby zainstalować nowszą wersję tego produktu, używaj apletu Dodaj/Usuń programy w Panelu sterowania w celu zaktualizowania usług IIS Media Services. + Wymagana konwersja pliku listy odtwarzania + + + + + Odnaleziono starsze pliki usług IIS Media Services + + + + + Odnaleziono pliki usług IIS Media Services w wersji beta + + + + + + IIS Media Pack 1.0 + Aktualizacja pakietu IIS Media Pack 1.0 + IIS Media Services 2.0 + Aktualizacja usług IIS Media Services 2.0 + IIS Media Services 3.0 + IIS Media Services 3.0 TAP 2 + Aktualizacja usług IIS Media Services 3.0 + Funkcje i narzędzia usług IIS Media Services. + Funkcje i narzędzia usług IIS Media Services 5 Premium. + Usługi IIS Media 4.0 w wersji beta 1 + IIS Media Services 4.0 + IIS Media Services 4.5 w wersji beta 1 + IIS Media Services 5 Premium + + Listy odtwarzania w sieci Web + Steruje odtwarzaniem przez klienta zasobów multimedialnych wymienionych na listach odtwarzania. + Pomocnik sesji + Umożliwia utrwalanie stanu sesji programu ASP.NET. (Wymaga usługi roli programu ASP.NET dla serwera sieci Web [IIS]). + Interfejs użytkownika + Konfiguruje funkcję Listy odtwarzania w sieci Web w Menedżerze usług IIS. + + Ograniczanie szybkości transmisji bitów + Oszczędza przepustowość, ograniczając dostarczanie plików pobieranych przez klientów. + Interfejs użytkownika + Konfiguruje funkcję Ograniczanie szybkości transmisji bitów w Menedżerze usług IIS. + + Zasoby + Włącza adaptacyjne przesyłanie strumieniowe zasobów na żądanie przez protokół HTTP do klientów. + Interfejs użytkownika + Konfiguruje funkcję Płynne przesyłanie strumieniowe w Menedżerze usług IIS. + + Kanały + Włącza adaptacyjne przesyłanie strumieniowe emisji kanałów przez protokół HTTP do klientów. + Interfejs użytkownika + Konfiguruje funkcję Płynne przesyłanie strumieniowe na żywo w Menedżerze usług IIS. + + Zarządzanie prawami cyfrowymi + Realizuje szyfrowanie i licencjonowanie plików multimedialnych w formacie Smooth Streaming. + Interfejs użytkownika + Konfiguruje funkcję zarządzania prawami cyfrowymi w module Menedżer usług IIS. + + Produkt [ProductName] wymaga systemu Microsoft Windows Vista z dodatkiem Service Pack 1 lub nowszym. + Produktu [ProductName] nie można zainstalować w systemie Vista Home Basic. + Produkt [ProductName] wymaga systemu Microsoft Windows 7 z dodatkiem Service Pack 1 lub nowszym. + + + Menedżer baz danych usług IIS + Menedżer baz danych usług IIS + + + Usługa zarządzania siecią Web firmy Microsoft 2 + Usługa zarządzania siecią Web firmy Microsoft + Instaluje podstawowe funkcje produktu [ProductName]. + Usługa zarządzania siecią Web firmy Microsoft 2 + Usługa zarządzania siecią Web zawiera mechanizmy zarządzania zdalnego i delegowanego, dzięki którym administratorzy mogą skutecznie zarządzać serwerem sieci Web, witrynami i aplikacjami obecnymi na komputerze. + + + Moduł ponownego zapisywania adresów URL firmy Microsoft w wersji 1.1 dla usług IIS 7 + Aktualizacja Modułu ponownego zapisywania adresów URL firmy Microsoft w wersji 1.1 dla usług IIS 7 + Ponowne zapisywanie adresów URL + Włącza funkcje ponownego zapisywania adresów URL i zawartości w usługach IIS 7. + Interfejs użytkownika + Konfiguruje funkcję Moduł ponownego zapisywania adresów URL w Menedżerze usług IIS. + + + Moduł ponownego zapisywania adresów URL usług IIS w wersji 2 + Aktualizacja modułu ponownego zapisywania adresów URL usług IIS w wersji 2 + Ponowne zapisywanie adresów URL + Włącza funkcje ponownego zapisywania adresów URL i zawartości w usługach IIS 7. + Interfejs użytkownika + Konfiguruje funkcję Moduł ponownego zapisywania adresów URL w Menedżerze usług IIS. + + + Pakiet administracyjny dla usług IIS 7.0 + Instaluje podstawowe funkcje produktu [ProductName]. + 1252 + Pakiet administracyjny dla usług IIS 7.0 + Microsoft Corporation + Ta wersja systemu operacyjnego jest nieobsługiwana. Produkt [ProductName] można zainstalować tylko w systemie Windows Server 2008 lub Windows Vista z dodatkiem Service Pack 1 lub nowszym. + Funkcje programu ASP.NET + Program ASP.NET zawiera funkcje Autoryzacja i Strony błędów, które umożliwiają zarządzanie ustawieniami autoryzacji i błędów niestandardowych. + Uwierzytelnianie + Opis funkcji Uwierzytelnianie programu ASP.NET. + Autoryzacja + Funkcja Autoryzacja programu ASP.NET umożliwia konfigurowanie reguł dotyczących autoryzacji użytkowników uzyskujących dostęp do witryn i aplikacji sieci Web. + Strony błędów + Funkcja Strony błędów programu ASP.NET umożliwia konfigurowanie odpowiedzi na błędy protokołu HTTP, które będą zwracane w przypadku wystąpienia błędów. + Moduły + Opis funkcji Moduły programu ASP.NET. + Obsługa + Opis funkcji Obsługa programu ASP.NET. + Edytor konfiguracji + Edytor konfiguracji służy do zarządzania plikami konfiguracji w Menedżerze usług IIS, umożliwiając edytowanie sekcji, atrybutów, elementów i kolekcji w plikach konfiguracji. + Filtrowanie żądań + Filtrowanie żądań umożliwia konfigurowania reguł filtrowania dla witryny sieci Web oraz ograniczanie zachowania protokołu i zawartości. + FastCGI + Funkcja FastCGI umożliwia konfigurowanie ustawień puli procesów dla aplikacji FastCGI na serwerze sieci Web. + + + Dynamiczne ograniczenia adresów IP dla Instalatora usług IIS 7 + + + + + + + + + + + + + Dynamiczne ograniczenia adresów IP dla usług IIS 7 — wersja Beta + Dynamiczne ograniczenia adresów IP dla usług IIS 7 — wersja Beta 2 + Dynamiczne ograniczenia adresów IP dla usług IIS 7 — wersja Beta 3 + + Dynamiczne ograniczenia adresów IP dla usług IIS 7 — wersja Release Candidate + Dynamiczne ograniczenia adresów IP dla usług IIS 7 — wersja Release Candidate 2 + Dynamiczne ograniczenia adresów IP dla usług IIS 7 — wersja Release Candidate 3 + + Dynamiczne ograniczenia adresów IP dla usług IIS 7 — wersja RTW + + Dynamiczne ograniczenia adresów IP dla usług IIS 7 + Interfejs użytkownika funkcji Dynamiczne ograniczenia adresów IP dla usług IIS 7 + + Dynamiczne ograniczenia adresu IP w usługach IIS 7 — na komputerze znaleziono wersję beta. Odinstaluj ją i spróbuj ponownie + + + WebDAV 7.5 dla usług IIS 7.0 + Aby można było używać tego produktu, muszą być zainstalowane funkcje CoreWebEngine i W3SVC usług IIS 7.0. + Moduł serwera WebDAV + Interfejs użytkownika administracji funkcją WebDAV + + + Zestaw narzędzi do optymalizacji aparatu wyszukiwania usług IIS w wersji 1.0 + Zestaw narzędzi do optymalizacji aparatu wyszukiwania usług IIS w wersji 1.0 + Zestaw narzędzi do optymalizacji aparatu wyszukiwania (SEO) w wersji 1.0 + Ta baza danych instalatora zawiera logikę i dane wymagane do zainstalowania narzędzia do optymalizacji aparatu wyszukiwania usług IIS w wersji 1.0. + + + Edytor usług IIS + + + Raporty usług IIS + Analizator dzienników nie jest zainstalowany na tym komputerze; zainstaluj funkcję Analizator dzienników w wersji 2.2 spod adresu http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07, a następnie kontynuuj instalowanie funkcji Raporty usług IIS. + + + Nie można odnaleźć wstępnie wymaganych pakietów. Uruchom plik setup.exe, aby rozpoznać zależności i zainstalować ten program. + Program Microsoft SQL Server 2008 Management Objects jest wstępnie wymaganym składnikiem instalacji Menedżera baz danych usług IIS. Program Microsoft SQL Server 2008 Management Objects można zainstalować spod adresu http://go.microsoft.com/fwlink/?LinkID=150946. + Program Microsoft SQL Server System CLR Types jest wstępnie wymaganym składnikiem instalacji Menedżera baz danych usług IIS. Program Microsoft SQL Server System CLR Types można zainstalować spod adresu http://go.microsoft.com/fwlink/?LinkID=150946. + + + Microsoft Web Farm Framework + Zewnętrzna pamięć podręczna firmy Microsoft + Struktura farmy sieci Web jest wymaganym składnikiem instalacji funkcji Routing żądań aplikacji. Zainstaluj strukturę farmy sieci Web. + Routing żądań aplikacji firmy Microsoft 2.5 + Wersja wykonawcza + Dodaje funkcje routingu żądań aplikacji do usług IIS. + Interfejs użytkownika + Konfiguruje funkcję routingu żądań aplikacji w module Menedżer usług IIS. + + + Przystawka środowiska Microsoft Windows PowerShell dla usług IIS 7.0 + + + Instalator platformy Microsoft Web 4.0 + Instalator platformy sieci Web firmy Microsoft + Produkt [ProductName] wymaga systemu Windows XP z dodatkiem SP2, Windows 2003 z dodatkiem SP1, Windows Vista lub nowszego. + Program [ProductName] wymaga systemu Windows XP z dodatkiem Service Pack 3, Windows Server 2003 z dodatkiem Service Pack 2 lub nowszego. + + + Instalator usług Microsoft Windows Azure + Instalator usług Microsoft Windows Azure + + + Menedżer internetowych usług informacyjnych (IIS) 7+ + Klient Menedżera usług IIS + Obsługa operacji zdalnych + Ten produkt wymaga systemu Windows XP z dodatkiem SP2, Windows 2003 z dodatkiem SP1, Windows Vista z dodatkiem SP1, Windows 7 lub nowszego + Konsola zarządzania usługami IIS nie jest zainstalowana, ale jest wymagana do zarządzania zdalnymi serwerami usług IIS. Zainstaluj Konsolę zarządzania usługami IIS przed zainstalowaniem obsługi operacji zdalnych, klikając polecenia Panel sterowania -> Programy -> Włącz lub wyłącz funkcje systemu Windows i wybierając opcję Konsola zarządzania usługami IIS w funkcji Internetowe usługi informacyjne. + Ten produkt nie jest wymagany w systemach Windows Server 2008 i Windows Server 2008 R2 ani w nowszych. Zainstaluj Konsolę zarządzania usługami IIS, otwierając Menedżera serwera i wybierając pozycję Konsola zarządzania usługami IIS z usług roli dla roli Serwer sieci Web. + + + Publikowanie Menedżera usług IIS dla usług IIS 7.0 + Interfejs użytkownika funkcji Publikowanie + + + Zwiększanie gotowości aplikacji w wersji 1.0 dla usług IIS 7.5 + + + + Na tym komputerze znajduje się niezgodny produkt: [CONFLICTING_PRODUCT_NAME]. Nie można kontynuować instalowania produktu [ProductName]. Aby zainstalować ten produkt, usuń produkt [CONFLICTING_PRODUCT_NAME] za pomocą apletu Dodaj/Usuń programy w Panelu sterowania. + Do zainstalowania produktu [ProductName] jest wymagane uprawnienie administratora. + Do używania produktu [ProductName] są wymagane usługi IIS w wersji 7.0. + Do używania produktu [ProductName] są wymagane usługi IIS w wersji 7.0 lub nowsze. + Do używania produktu [ProductName] są wymagane usługi IIS w wersji 7.5 lub nowsze. + Do zainstalowania produktu [ProductName] wymagany jest program IIS 7 lub 7.5. + Odnaleziono wersję beta produktu [ProductName] na tym komputerze. + Odnaleziono nowszą wersję produktu [ProductName] na tym komputerze. + Instalator nie może kontynuować, ponieważ na tym komputerze jest już zainstalowane inne wystąpienie produktu [ProductName]. Odinstaluj je, a następnie ponownie rozpocznij tę instalację. + Aby można było używać produktu [ProductName], muszą być zainstalowane funkcje CoreWebEngine i W3SVC usług IIS 7.0. + Aby można było używać produktu [ProductName], musi być zainstalowana Konsola zarządzania usługami IIS. + Przed zainstalowaniem produktu [ProductName] zatrzymaj usługę aktywacji procesów systemu Windows (WAS) i usługę zarządzania siecią Web (WMSvc). Te usługi trzeba będzie uruchomić po zainstalowaniu produktu [ProductName]. + Do zainstalowania produktu [ProductName] jest wymagana metabaza usług IIS. + Nie można zainstalować 64-bitowej wersji produktu [ProductName] w 32-bitowej wersji systemu Microsoft Windows. + Nie można zainstalować 32-bitowej wersji produktu [ProductName] w 64-bitowej wersji systemu Microsoft Windows. + Do zainstalowania produktu [ProductName] jest wymagany program .NET Framework w wersji 2.0 lub nowszy. + Do zainstalowania programu [ProductName] jest potrzebny program Microsoft .NET Framework w wersji 3.5 lub nowszej. Naciśnij przycisk „Dodaj funkcje” w sekcji Menedżer serwera, aby zainstalować program Microsoft .Net w wersji 3.5. + Do zainstalowania programu [ProductName] jest wymagany program Microsoft .NET Framework w wersji 4.0 lub nowszej. + Przed zainstalowaniem produktu [ProductName] zainstaluj dodatek Service Pack 1 (lub nowszy) dla programu Microsoft .NET Framework w wersji 2.0. + Nie można wyłączyć usługi Windows Update (wuauserv), ponieważ jest ona wymagana do zainstalowania produktu [ProductName]. + Przystawka PowerShell stanowi część systemu operacyjnego Windows. Zainstaluj ją za pomocą menu Programy i funkcje lub narzędzia Menedżer serwera. + Do zainstalowania programu [ProductName] jest wymagany instalator platformy sieci Web firmy Microsoft w wersji 3.0 lub nowszej. + + Instalator nie może wykryć konfiguracji udostępnionej. + Konfiguracja udostępniona jest włączona dla usług IIS. Instalowanie produktu [ProductName] jest nieobsługiwane, gdy jest używana konfiguracja udostępniona. Wyłącz konfigurację udostępnioną przed zainstalowaniem tej funkcji. + + Zatrzymaj usługę publikowania w sieci World Wide Web (W3SVC) przed zainstalowaniem produktu [ProductName]. Tę usługę trzeba będzie uruchomić po instalacji. + Konsola zarządzania środowiskiem IIS PowerShell + Przystawka IIS PowerShell + Przystawka IIS PowerShell wymaga zainstalowanego środowiska PowerShell w wersji 1.0 lub 2.0. + Przystawka IIS PowerShell wymaga zainstalowanej usługi WAS oraz konfiguracji. + To jest nieprawdziwy ciąg. + + + Microsoft Web Farm Framework 2.2 + Microsoft Web Farm Agent 2.2 + Usługa kolektywu serwerów sieci Web + Usługa kolektywu serwerów sieci Web + Usługa kontrolera kolektywu serwerów sieci Web + Usługa kontrolera kolektywu serwerów sieci Web + Usługa agenta kolektywu serwerów sieci Web + Usługa agenta kolektywu serwerów sieci Web + Do zainstalowania składnika Web Farm Framework jest wymagany instalator platformy sieci Web. Zainstaluj instalatora platformy sieci Web ze strony http://www.microsoft.com/web/downloads/platform.aspx. + Do zainstalowania składnika Web Farm Framework jest wymagane narzędzie Web Deployment. Zainstaluj narzędzie Web Deployment ze strony http://www.iis.net/download/WebDeploy. + + + Microsoft Web Hosting Framework + Web Hosting Framework + Role i funkcje obsługi hostingu sieci Web. + Hosting Framework + Składnik Hosting Framework udostępnia interfejsy API i polecenia programu PowerShell do zarządzania hostingiem sieci Web. + Rola sieci Web + Rola sieci Web instaluje usługę Dynamiczna usługa WAS i dostawcę Moduł ponownego zapisywania adresów URL na potrzeby hostingu sieci Web. + Antares Express + Wdraża konfigurację Panelu sterowania zoptymalizowaną pod kątem konfiguracji jednego komputera. + Rola Usługa równoważenia obciążenia + Rola Usługa równoważenia obciążenia konfiguruje router żądań aplikacji do routingu na podstawie reguł hostingu sieci Web. + Kontroler hostingu + Kontroler hostingu rozszerza funkcje składnika Web Farm Framework 2.0 o współdziałanie z hostingiem sieci Web. + Rola publikowania + Instaluje obsługę narzędzia Web Deploy i publikowana FTP. + To jest przystawka PowerShell zawierająca aplety poleceń służące do zarządzania infrastrukturą Microsoft Web Hosting. + Dynamiczna usługa WAS + Usługa aktywacji procesów systemu Windows zoptymalizowana pod kątem hostingu sieci Web o dużej gęstości. + Usługa pomiaru użycia zasobów + Instaluje usługę pomiaru użycia zasobów, która umożliwia gromadzenie i publikowanie informacji na temat środowiska wykonawczego i kondycji. + Miernik zasobów + Umożliwia gromadzenie i publikowanie informacji na temat środowiska wykonawczego i kondycji pochodzących z roli sieci Web. + Wymuszanie przydziału hostingu + Monitoruje użycie zasobów witryn sieci Web i w razie przekroczenia przydziału użycia wykonuje akcje niestandardowe. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/PTB/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/PTB/misc/setupstrings.wxl new file mode 100644 index 0000000000..4fdfeffca5 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/PTB/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 1046 + + + + Opções de Instalação da Configuração Compartilhada + Selecionar a opção de instalação na configuração compartilhada do IIS + Atualizar configuração compartilhada na instalação + Você está instalando este módulo em um servidor do IIS que usa a configuração compartilhada. Se outros servidores do IIS estiverem usando essa configuração compartilhada, você precisará instalar este módulo em todos os computadores. Para minimizar interrupções de servidores Web individuais, será preciso instalar este módulo de acordo com as seguintes etapas: primeiro, em todos os computadores, com exceção do último, você deverá instalar o módulo sem atualizar a configuração compartilhada. Para isso, não marque a caixa de seleção + a seguir. Isso instalará todos os binários e arquivos necessários para o módulo em cada computador sem fazer alterações na configuração compartilhada. Em segundo lugar, no último computador, será preciso verificar se a identidade do usuário usada por você na execução tem acesso de leitura e gravação ao arquivo applicationhost.config no compartilhamento UNC. Em seguida, instale o módulo e selecione a opção abaixo de atualização da configuração compartilhada. + + + Inicializando a ação personalizada do WebConfig + Atualizando o web.config + + + + Registro em Log Avançado do IIS + Habilita o registro em log avançado dos dados de pipeline do IIS. + Registro em Log Avançado do IIS + Habilita a criação de arquivos de log personalizados com seleção de campo extensível. + Atualização para o Registro em Log Avançado do IIS + + + + IIS Transform Manager + Beta + Habilita o IIS Media Services do Transform Manager. + IIS Transform Manager + Habilita a criação de transformações de mídia. + Host do IIS Transform Manager + Host de serviço de [ProductName]. + IIS Transform Manager + Conversão em lote de arquivos de mídia por demanda para formatos de arquivo e de contêiner alternativos. + Um pacote de Tarefa do Expression Encoder SP do IIS Transform Manager 1.0 está instalado no computador. Desinstale-o para que possa instalar o [ProductName]. + + O Microsoft .NET Framework 3.5 é exigido para instalar o produto [ProductName]. Use o "Assistente Adicionar Recursos" no Gerenciador do Servidor para instalar os Recursos do .NET Framework 3.5.1 ou use a opção "Ativar ou desativar os recursos do Windows" para ativar o Microsoft .NET Framework 3.5. + + + + Gerenciamento de Direitos Digitais do IIS + Beta + Habilita o Gerenciamento de Direitos Digitais de apresentações de Smooth Streaming. + + + O ASP.NET Não Está Instalado + + + + + + + + + O IIS Smooth Streaming - Beta foi encontrado no computador. Não é possível continuar a instalação do [ProductName]. Para instalar o produto, use Adicionar/Remover Programas no Painel de Controle para remover o IIS Smooth Streaming - Beta. + Uma versão incompatível do IIS Media Services está no computador. Não é possível continuar a instalação do [ProductName]. Para instalar o produto, use Adicionar/Remover Programas no Painel de Controle para remover o IIS Media Services. + Uma versão mais recente do produto já está instalada ou disponível para instalação neste computador. Não é possível continuar a instalação do [ProductName]. Para instalar a versão mais recente do produto, use Adicionar/Remover Programas no Painel de Controle para atualizar o IIS Media Services. + Conversão do Arquivo da Lista de Reprodução Necessária + + + + + Arquivos Antigos do IIS Media Services Encontrados + + + + + Arquivos do IIS Media Services Beta Encontrados + + + + + + IIS Media Pack 1.0 + Atualização para o IIS Media Pack 1.0 + IIS Media Services 2.0 + Atualização para o IIS Media Services 2.0 + IIS Media Services 3.0 + IIS Media Services 3.0 TAP 2 + Atualização para o IIS Media Services 3.0 + Recursos e ferramentas do IIS Media Services. + Recursos e ferramentas do IIS Media Services 5 Premium. + IIS Media Services 4.0 Beta 1 + IIS Media Services 4.0 + IIS Media Services 4.5 Beta 1 + IIS Media Services 5 Premium + + Web Playlists + Controla a reprodução no cliente de ativos de mídia referenciados em listas de reprodução. + Auxiliar de Sessão + Habilita a persistência do estado de sessão do ASP.NET. (Requer o serviço de função do ASP.NET para o Servidor Web (IIS)). + Interface do Usuário + Configura o recurso Web Playlists no Gerenciador do IIS. + + Limitação da Taxa de Bits + Economiza largura de banda limitando a entrega de arquivos baixados por clientes. + Interface do Usuário + Configura o recurso Limitação da Taxa de Bits no Gerenciador do IIS. + + Ativos + Habilita o streaming HTTP adaptável de ativos por demanda para clientes. + Interface do Usuário + Configura o recurso Smooth Streaming no Gerenciador do IIS. + + Canais + Habilita o streaming HTTP adaptável de difusões de canais para clientes. + Interface do Usuário + Configura o recurso Live Smooth Streaming no Gerenciador do IIS. + + Gerenciamento de Direitos Digitais + Fornece criptografia e licenciamento de mídia Smooth Streaming. + Interface do Usuário + Configura o recurso de Gerenciamento de Direitos Digitais no Gerenciador do IIS. + + O [ProductName] requer o Microsoft Windows Vista Service Pack 1 ou posterior. + Não é possível instalar o [ProductName] no Vista Home Basic. + O [ProductName] requer o Microsoft Windows 7 Service Pack 1 ou posterior. + + + Gerenciador de Banco de Dados do IIS + Gerenciador de Banco de Dados do IIS + + + Serviço de Gerenciamento da Web 2 da Microsoft + Serviço de Gerenciamento da Web da Microsoft + Instala os recursos básicos do [ProductName]. + Serviço de Gerenciamento da Web 2 da Microsoft + O Serviço de Gerenciamento da Web habilita recursos de gerenciamento remotos e delegados para que os administradores gerenciem o servidor Web, os sites e os aplicativos presentes neste computador. + + + Módulo 1.1 de Reescrita de URL da Microsoft para IIS 7 + Atualização do Módulo 1.1 de Reescrita de URL para IIS 7 + Reescrita de URL + Habilita os recursos de reescrita de conteúdo e URL do IIS 7. + Interface do Usuário + Configura o recurso do Módulo de Reescrita de URL no Gerenciador do IIS. + + + Módulo 2 de Reescrita de URL do IIS + Atualização do Módulo 2 de Reescrita de URL do IIS + Reescrita de URL + Habilita os recursos de reescrita de conteúdo e URL do IIS 7. + Interface do Usuário + Configura o recurso do Módulo de Reescrita de URL no Gerenciador do IIS. + + + Administration Pack para IIS 7.0 + Instala os recursos básicos do [ProductName]. + 1252 + Administration Pack para IIS 7.0 + Microsoft Corporation + Não há suporte a esta versão do sistema operacional. Só é possível instalar o [ProductName] no Windows Server 2008 ou no Windows Vista Service Pack 1 ou posterior. + Recursos do ASP.Net + O ASP.NET inclui os recursos Páginas de Erro e Autorização, que permitem o gerenciamento das configurações de erro personalizadas e de autorizações. + Autenticação + Descrição da Autenticação do ASP.Net. + Autorização + A Autorização do ASP.NET permite a configuração de regras para autorizar usuários a acessar seus sites e aplicativos. + Páginas de Erro + As Páginas de Erro do ASP.NET permitem a configuração de respostas de erro de HTTP retornadas quando um erro ocorre. + Módulos + Descrição dos Módulos do ASP.Net. + Manipuladores + Descrição dos Manipuladores do ASP.Net. + Editor de Configurações + O Editor de Configurações permite o gerenciamento de arquivos de configuração no Gerenciador do IIS por meio da edição de seções, atributos, elementos e coleções nos arquivos de configuração. + Filtragem de Solicitações + A Filtragem de Solicitações permite a configuração de regras de filtragem para o seu site, protocolo restrito e comportamento de conteúdo. + FastCGI + O FastCGI permite a definição de configurações do pool de processos para os aplicativos FastCGI no servidor Web. + + + Instalação de Restrições de IP Dinâmico para IIS 7 + + + + + + + + + + + + + Restrições de IP Dinâmico para IIS 7 - Beta + Restrições de IP Dinâmico para IIS 7 - Beta 2 + Restrições de IP Dinâmico para IIS 7 - Beta 3 + + Restrições de IP Dinâmico para IIS 7 - Versão Release Candidate + Restrições de IP Dinâmico para IIS 7 - Versão Release Candidate 2 + Restrições de IP Dinâmico para IIS 7 - Versão Release Candidate 3 + + Restrições de IP Dinâmico para IIS 7 - RTW + + Restrições de IP Dinâmico para IIS 7 + Interface do Usuário de Restrições de IP Dinâmico para IIS 7 + + Restrições de IP Dinâmico para IIS 7 - Beta encontradas neste computador. Desinstale-as e tente novamente + + + WebDAV 7.5 para IIS 7.0 + Os recursos CoreWebEngine e W3SVC do IIS 7.0 devem ser instalados para usar este produto. + Módulo do Servidor WebDAV + Interface do Usuário de Administração do WebDAV + + + Toolkit de Otimização do Mecanismo de Pesquisa do IIS 1.0 + Toolkit de Otimização do Mecanismo de Pesquisa do IIS 1.0 + Toolkit de SEO (Otimização do Mecanismo de Pesquisa) 1.0 + Este banco de dados de instalador contém a lógica e os dados necessários para instalar o Kit de Ferramentas de Otimização do Mecanismo de Pesquisa do IIS 1.0. + + + Editor do IIS + + + Relatórios do IIS + O Analisador de Log não foi instalado neste computador. Instale o Analisador de Log 2.2 de http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07 e continue a instalação dos Relatórios do IIS + + + Os pacotes de pré-requisito não foram encontrados. Execute setup.exe para resolver as dependências e instalar o programa. + O Microsoft SQL Server 2008 Management Objects é um pré-requisito para a instalação do Gerenciador de Banco de Dados do IIS. É possível instalar o Microsoft SQL Server 2008 Management Objects de http://go.microsoft.com/fwlink/?LinkID=150946. + Os Microsoft SQL Server System CLR Types são um pré-requisito para a instalação do Gerenciador de Banco de Dados do IIS. É possível instalar os Microsoft SQL Server System CLR Types de http://go.microsoft.com/fwlink/?LinkID=150949. + + + Microsoft Web Farm Framework + Microsoft External Cache + O Web Farm Framework é um requisito para a instalação do Application Request Routing. Instale o Web Farm Framework. + Microsoft Application Request Routing 2.5 + Tempo de Execução + Adiciona os recursos de Roteamento de Solicitações de Aplicativo no IIS. + Interface do Usuário + Configura o recurso de Roteamento de Solicitações de Aplicativo no Gerenciador do IIS. + + + Snap-in do Microsoft Windows PowerShell para o IIS 7.0 + + + Microsoft Web Platform Installer 4.0 + Microsoft Web Platform Installer + O [ProductName] requer o Windows XP SP2, o Windows 2003 SP1, o Windows Vista ou posterior. + O [ProductName] exige o Windows XP Service Pack 3, o Windows Server 2003 Service Pack 2 ou versão posterior. + + + Instalador de Serviços do Microsoft Windows Azure + Instalador de Serviços do Microsoft Windows Azure + + + Gerenciador do IIS (Serviços de Informações da Internet) 7+ + Cliente do Gerenciador do IIS + Suporte Remoto + Este produto requer o Windows XP SP2, o Windows 2003 SP1, o Windows Vista SP1, o Windows 7 ou mais recente + O Console de Gerenciamento do IIS não foi instalado, mas é necessário para o gerenciamento de servidores remotos do IIS. Para instalar o Console de Gerenciamento do IIS antes de instalar o suporte de gerenciamento remoto, abra o 'Painel de Controle->Programas->Ativar ou Desativar Recursos do Windows' e selecione o Console de Gerenciamento do IIS no recurso Serviços de Informações da Internet. + Este produto não é necessário no Windows Server 2008 ou no Windows Server 2008 R2 ou mais recente. Para instalar o Console de Gerenciamento do IIS, abra o Gerenciador do Servidor e selecione o Console de Gerenciamento do IIS em Serviços de Função para a Função de Servidor Web. + + + IIS Manager Publishing para IIS 7.0 + Interface do Usuário de Publicação + + + Application Warm-Up 1.0 para IIS 7.5 + + + + Este computador contém um produto incompatível, [CONFLICTING_PRODUCT_NAME]. A instalação do [ProductName] não pode continuar. Para instalar esse produto, use Adicionar/Remover Programas no Painel de Controle para remover o [CONFLICTING_PRODUCT_NAME]. + São necessários privilégios de Administrador para instalar o [ProductName]. + É necessário o IIS Versão 7.0 para usar o [ProductName]. + É necessário o IIS Versão 7.0 ou posterior para instalar o [ProductName]. + É necessário o IIS Versão 7.5 ou posterior para instalar o [ProductName]. + É necessário o IIS versão 7 ou 7.5 para instalar o [ProductName]. + A versão beta do [ProductName] foi encontrada no computador. + Uma versão mais recente do [ProductName] foi encontrada no computador. + Não é possível continuar a instalação, pois outra instância do [ProductName] já está instalada no computador. Desinstale a versão antiga e reinicie a instalação. + Os recursos CoreWebEngine e W3SVC do IIS 7.0 devem estar instalados para usar o [ProductName]. + O Console de Gerenciamento do IIS deve estar instalado para usar o [ProductName]. + Interrompa o WAS (Serviço de Ativação de Processos do Windows) e o WMSvc (Serviço de Gerenciamento da Web) antes de instalar o [ProductName]. Será necessário instalar os serviços após a instalação do [ProductName]. + É necessária a Metabase do IIS para instalar o [ProductName]. + Não é possível instalar a versão de 64 bits do [ProductName] em uma edição de 32 bits do Microsoft Windows. + Não é possível instalar a versão de 32 bits do [ProductName] em uma edição de 64 bits do Microsoft Windows. + É necessário o Microsoft .NET Framework Versão 2.0 ou posterior para instalar o [ProductName]. + O Microsoft .NET Framework Versão 3.5 ou posterior é necessário para instalar o [ProductName]. Use 'Adicionar Recursos' no Gerenciador do Servidor para instalar o Microsoft .Net Versão 3.5. + O Microsoft .NET Framework Versão 4.0 ou posterior é necessário para instalar o [ProductName]. + Instale o Microsoft .NET Framework Service Pack 1 Versão 2.0, ou um service pack posterior, antes de instalar o [ProductName]. + Não é possível desabilitar o serviço Windows Update (wuauserv), pois ele é necessário para instalar o [ProductName]. + O snap-in do PowerShell é parte o Sistema Operacional Windows. Instale o snap-in por meio dos 'Programas e Recursos' ou 'Gerenciador do Servidor'. + O Microsoft Web Platform Installer Versão 3.0 ou posterior é necessário para instalar o [ProductName]. + + A instalação não detectou configurações compartilhadas. + A configuração compartilhada está habilitada para o IIS. Não há suporte à instalação do [ProductName] quando é usada uma configuração compartilhada. Desabilite a configuração compartilhada antes de instalar este recurso. + + Interrompa o Serviço de Publicação na World Wide Web (W3SVC) antes de instalar o [ProductName]. Será necessário iniciar o serviço após a instalação. + Console de Gerenciamento do PowerShell do IIS + Snap-in do PowerShell do IIS + O snap-in do PowerShell do IIS requer o PowerShell versão 1.0 ou 2.0 instalado + O snap-in do PowerShell do IIS requer WAS e configuração instalados + Cadeia de caracteres inválida. + + + Estrutura do Microsoft Web Farm Versão 2.2 + Agente do Microsoft Web Farm Versão 2.2 + Serviço de Web Farm + Serviço de Web Farm + Serviço Controlador de Web Farm + Serviço Controlador de Web Farm + Serviço de Agente de Web Farm + Serviço de Agente de Web Farm + O Web Plaform Installer é um pré-requisito para instalar a Estrutura do Web Farm. Instale o Web Plaform Installer a partir de http://www.microsoft.com/web/downloads/platform.aspx. + A Ferramenta de Implantação da Web é um pré-requisito para instalar a Estrutura do Web Farm. Instale a Ferramenta de Implantação da Web a partir de http://www.iis.net/download/WebDeploy. + + + Estrutura de Hospedagem na Web da Microsoft + Estrutura de Hospedagem na Web + Funções e recursos de Hospedagem na Web. + Estrutura de Hospedagem + A Estrutura de Hospedagem oferece comandos de API e PowerShell para gerenciamento de Hospedagem na Web. + Função da Web + A Função Web instala o serviço WAS Dinâmico e o provedor de Reescrita de URL de Hospedagem na Web. + Antares Express + Implanta uma configuração do Painel de Controle otimizada para configuração de máquina única. + Função do Balanceador de Carga + A Função do Balanceador de Carga configura o Roteador de Solicitação de Aplicativo para rotear com base nas regras de Hospedagem na Web. + Controlador de Hospedagem + O Controlador de Hospedagem estende a Estrutura do Web Farm 2.0 para trabalhar com Hospedagem na Web. + Função de Publicação + Instala suporte para Implantação da Web e publicação em FTP. + Este é um snap-in do PowerShellque contém cmdlets para gerenciar a infraestrutura de Hospedagem na Web da Microsoft. + Serviço WAS Dinâmico + Serviço de Ativação de Processos do Windows otimizado para Hospedagem na Web de alta densidade. + Serviço de Medição de Recursos + Instala o serviço de Medição de Recursos que habilita a coleta e a publicação de informações de integridade e tempo de execução. + Medição de Recursos + Habilita a coleta e a publicação de informações de tempo de execução e integridade a partir da Função Web. + Imposição de Cota de Hospedagem + Monitora o uso de recursos de sites e executa ações personalizadas quando a cota de uso é excedida. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/RUS/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/RUS/misc/setupstrings.wxl new file mode 100644 index 0000000000..e9613c04ec --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/RUS/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 1049 + + + + Параметры установки общей конфигурации + Выбор параметров установки общей конфигурации IIS + Обновить общую конфигурацию при установке + Вы устанавливаете этот модуль на сервер IIS, использующий общую конфигурацию. Если дополнительные серверы IIS используют эту общую конфигурацию, вам необходимо установить этот модуль на все эти компьютеры. Чтобы минимизировать нарушение работы отдельных веб-серверов, вам потребуется устанавливать этот модуль в соответствии с шагами, описанными ниже. Сначала следует установить модуль на все компьютеры, кроме последнего, не обновляя при этом общую конфигурацию. Для этого не устанавливайте флажок ниже. +При этом на каждый компьютер будут установлены все файлы, необходимые для модуля, но не будет изменена общая конфигурация. Затем на последнем компьютере следует убедиться в том, что у используемой для работы учетной записи есть права чтения и записи файла applicationhost.config, расположенного на общем ресурсе UNC. Затем следует установить модуль и установить флажок "Обновить общую конфигурацию" ниже. + + + Инициализируется настраиваемое действие WebConfig + Обновляется файл web.config + + + + Расширенное ведение журнала IIS + Обеспечивает расширенные возможности ведения журнала данных конвейера IIS. + Расширенное ведение журнала IIS + Позволяет создавать настраиваемые файлы журналов с расширяемым набором полей. + Обновление для расширенного ведения журнала + + + + IIS Transform Manager + Бета-версия + Включает диспетчер Transform Manager IIS Media Services. + IIS Transform Manager + Включает создание преобразований мультимедиа. + Узел диспетчера IIS Transform Manager + Узел службы для [ProductName]. + IIS Transform Manager + Пакетное преобразование файлов мультимедиа в альтернативные форматы файлов и контейнеров по запросу. + На компьютере установлен пакет задач IIS Transform Manager 1.0 Expression Encoder SP. Его следует удалить перед установкой [ProductName]. + + Microsoft .NET Framework 3.5 требуется для установки [ProductName]. Используйте мастер добавления компонентов в диспетчере сервера, чтобы установить компоненты .NET Framework 3.5.1, или используйте параметр "Включение или отключение компонентов Windows", чтобы включить Microsoft .NET Framework 3.5. + + + + IIS: управление цифровыми правами + Бета-версия + Включает управление цифровыми правами для презентаций Smooth Streaming. + + + ASP.NET не установлен + + + + + + + + + На компьютере обнаружена бета-версия IIS Smooth Streaming. Установка [ProductName] не будет продолжена. Чтобы установить этот продукт, используйте компонент "Установка и удаление программ" панели управления для удаления бета-версии IIS Smooth Streaming. + На компьютере имеется несовместимая версия служб IIS Media Services. Установка [ProductName] не будет продолжена. Чтобы установить этот продукт, используйте компонент "Установка и удаление программ" панели управления для удаления служб IIS Media Services. + Более новая версия этого продукта уже установлена или доступна для установки на этом компьютере. Установка [ProductName] не будет продолжена. Чтобы установить более новую версию этой программы, используйте элемент панели управления "Установка и удаление программ" для обновления служб мультимедиа IIS. + Необходимо преобразовать файл списка воспроизведения + + + + + Обнаружены старые файлы служб IIS Media + + + + + Обнаружены старые файлы бета-версии служб IIS Media + + + + + + IIS Media Pack 1.0 + Обновление для IIS Media Pack 1.0 + IIS Media Services 2.0 + Обновление для IIS Media Services 2.0 + IIS Media Services 3.0 + IIS Media Services 3.0 TAP 2 + Обновление для IIS Media Services 3.0 + Средства и компоненты IIS Media Services. + Средства и компоненты IIS Media Services 5 Premium. + Бета-версия 1 служб IIS Media Services 4.0 + Службы IIS Media Services 4.0 + Бета-версия 1 служб IIS Media Services 4.5 + IIS Media Services 5 Premium + + Веб-списки воспроизведения + Управляет воспроизведением клиентами данных мультимедиа, на которые есть ссылки в списках воспроизведения. + Модуль поддержки сеансов + Поддерживает сохранение сеансов ASP.NET. (Требуется служба роли ASP.NET ля веб-сервера (IIS)). + Пользовательский интерфейс + Настройка компонента веб-списков воспроизведения в диспетчере IIS. + + Регулирование скорости + Экономия полосы пропускания путем регулирования доставки файлов, загружаемых клиентами. + Пользовательский интерфейс + Настройка функции регулирования скорости в диспетчере IIS. + + Файлы + Поддерживает адаптивную потоковую передачу файлов по запросу клиентам. + Пользовательский интерфейс + Настройка Smooth Streaming в диспетчере IIS. + + Каналы + Поддерживает адаптивную потоковую передачу при канальной широковещательной трансляции клиентам. + Пользовательский интерфейс + Настраивает компонент Live Smooth Streaming в диспетчере IIS. + + Управление цифровыми правами + Обеспечивает шифрование и лицензирование содержимого Smooth Streaming. + Пользовательский интерфейс + Настройка функции управления цифровыми правами в диспетчере IIS. + + Для [ProductName] требуется Microsoft Windows Vista с пакетом обновления 1 (SP1) или более поздней версии. + Невозможно установить [ProductName] в операционной системе Vista Home Basic. + Для [ProductName] требуется Microsoft Windows 7 с пакетом обновления 1 (SP1) или более поздней версии. + + + Диспетчер баз данных IIS + Диспетчер баз данных IIS + + + Служба веб-управления 2 (Майкрософт) + Служба веб-управления (Майкрософт) + Установка основных компонентов [ProductName]. + Служба веб-управления 2 (Майкрософт) + Служба управления сетью предоставляет для администраторов удаленные и делегированные возможности управления веб-сервером, сайтами и приложениями, существующими на данном компьютере. + + + Модуль 1.1 видоизменения URL-адресов (Майкрософт) для IIS 7 + Обновление для модуля 1.1 видоизменения URL-адресов для IIS 7 + Видоизменение URL-адресов + Включает функции, отвечающие за видоизменение URL-адресов и содержимого в IIS 7. + Пользовательский интерфейс + Настраивает компонент "модуль видоизменения URL-адресов" в диспетчере служб IIS. + + + Модуль переопределения URL-адресов 2 для IIS + Обновление для модуля 2 переопределения URL-адресов для IIS + Видоизменение URL-адресов + Включает функции, отвечающие за видоизменение URL-адресов и содержимого в IIS 7. + Пользовательский интерфейс + Настраивает компонент "модуль видоизменения URL-адресов" в диспетчере служб IIS. + + + Пакет администрирования IIS 7.0 + Установка основных компонентов [ProductName]. + 1251 + Пакет администрирования IIS 7.0 + Корпорация Майкрософт + Эта версия операционной системы не поддерживается. [ProductName] можно установить только в Windows Server 2008 или Windows Vista с пакетом обновления 1 (SP1) или более поздних версий. + Компоненты ASP.Net + В ASP.NET содержатся компоненты авторизации и страниц ошибок, позволяющие управлять параметрами авторизации и настраиваемых сообщений об ошибках. + Проверка подлинности + Описание проверки подлинности ASP.Net. + Авторизация + Модуль проверки подлинности ASP.NET позволяет настраивать правила проверки подлинности пользователей для доступа к веб-сайтам и приложениям. + Страницы ошибок + Страницы ошибок ASP.NET позволяют настраивать отклики на ошибки HTTP, отображаемые при возникновении таких ошибок. + Модули + Описание модулей ASP.Net. + Обработчики + Описание обработчиков ASP.Net. + Редактор конфигураций + Редактор конфигурации позволяет управлять файлами конфигурации в диспетчере IIS, обеспечивая возможность изменять разделы, атрибуты, элементы и семейства в файлах конфигурации. + Фильтрация запросов + Фильтрация запросов позволяет настраивать правила фильтрации для веб-сайта, ограничивать поведение протоколов и содержимого. + Fast CGI + FastCGI позволяет настраивать параметры пула процессов для приложений FastCGI на веб-сервере. + + + Программа установки ограничения динамических IP-адресов для IIS 7 + + + + + + + + + + + + + Ограничения динамических IP-адресов для IIS 7 - бета-версия + Ограничения динамических IP-адресов для IIS 7 - бета-версия 2 + Ограничения динамических IP-адресов для IIS 7 - бета-версия 3 + + Ограничения динамических IP-адресов для IIS 7 - версия-кандидат + Ограничения динамических IP-адресов для IIS 7 - версия-кандидат 2 + Ограничения динамических IP-адресов для IIS 7 - версия-кандидат 3 + + Ограничения динамических IP-адресов для IIS 7 - рабочий выпуск + + Ограничения динамических IP-адресов для IIS 7 + Пользовательский интерфейс ограничения динамических IP-адресов для IIS 7 + + Ограничения динамического IP-адреса для IIS 7 - на компьютере обнаружена бета-версия. Удалите ее и повторите попытку + + + WebDAV 7.5 для IIS 7.0 + Для использования этого продукта необходимо установить компоненты IIS 7.0 CoreWebEngine и W3SVC. + Серверный модуль WebDAV + Пользовательский интерфейс администрирования WebDAV + + + Инструменты оптимизации IIS Search Engine 1.0 + Инструменты оптимизации IIS Search Engine 1.0 + Инструменты оптимизации Search Engine (SEO) 1.0 + Эта база данных установщика содержит логику и данные, необходимые для установки инструментов оптимизации IIS Search Engine 1.0. + + + Редактор IIS + + + Отчеты IIS + Программа Log Parser не установлена на этом компьютере. Установите программу Log Parser 2.2 с сайта http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07, затем установите отчеты IIS. + + + Необходимые компоненты не найдены. Запустите setup.exe, чтобы установить необходимые зависимые компоненты и установить эту программу. + Управляющие объекты Microsoft SQL Server 2008 являются необходимым условием для установки диспетчера базы данных IIS. Управляющие объекты Micrsoft SQL Server 2008 можно установить на странице http://go.microsoft.com/fwlink/?LinkID=150946. + Системные типы Microsoft SQL Server System CLR Types являются необходимым условием для установки диспетчера базы данных IIS. Системные типы Microsoft SQL Server System CLR Types можно установить на странице http://go.microsoft.com/fwlink/?LinkID=150949. + + + Microsoft Web Farm Framework + Microsoft External Cache + Для установки маршрутизации запросов приложений требуется установить платформу веб-фермы. Установите платформу веб-фермы. + Microsoft Application Request Routing 2.5 + Среда выполнения + Добавляет функции маршрутизации запросов приложений в IIS. + Пользовательский интерфейс + Настраивает функцию маршрутизации запросов приложений в диспетчере IIS. + + + Оснастка Microsoft Windows PowerShell для IIS 7.0 + + + Установщик веб-платформы Майкрософт 4.0 + Установщик веб-платформы Майкрософт + Для [ProductName] требуется Windows XP SP2, Windows 2003 SP1, Windows Vista или более поздняя версия. + Для [ProductName] требуется Windows XP с пакетом обновления 3, Windows Server 2003 с пакетом обновления 2, или более поздние версии. + + + Установщик служб Microsoft Windows Azure + Установщик служб Microsoft Windows Azure + + + Диспетчер служб IIS 7+ + Клиент диспетчера IIS + Поддержка удаленной работы + Для этого продукта требуется Windows XP с пакетом обновления 2 (SP2), Windows 2003 с пакетом обновления 1 (SP1), Windows Vista с пакетом обновления 1 (SP1), Windows 7 или более новая система + Консоль управления IIS не установлена, но она необходима для управления удаленными серверами IIS. Установите консоль управления IIS перед установкой поддержки удаленного управления. Для этого в панели управления откройте "Программы", "Включение или отключение компонентов Windows", и выберите консоль управления IIS среди компонентов IIS. + Этот продукт не требуется при использовании Windows Server 2008, Windows Server 2008 R2 и более новых систем. Установите консоль управления IIS, открыв диспетчер сервера и выбрав консоль управления IIS в службах ролей для роли веб-сервера. + + + Публикация диспетчера IIS 7.0 + Пользовательский интерфейс публикации + + + Application Warm-Up 1.0 для IIS 7.5 + + + + На компьютере установлен несовместимый продукт: [CONFLICTING_PRODUCT_NAME]. Установку [ProductName] продолжить невозможно. Чтобы установить этот продукт, удалите CONFLICTING_PRODUCT_NAME] в разделе "Добавление и удаление программ" в панели управления. + Для установки [ProductName] требуются права администратора. + Для использования [ProductName] требуется IIS версии 7.0. + Для установки [ProductName] требуется IIS версии 7.0 или более поздней. + Для установки [ProductName] требуется IIS версии 7.5 или более поздней. + Для установки [ProductName] требуется IIS версии 7 или 7.5. + На компьютере обнаружена бета-версия [ProductName]. + На компьютере обнаружена более поздняя версия [ProductName]. + Программа установки не может продолжить работу, поскольку на компьютере уже установлен другой экземпляр [ProductName]. Удалите его, затем заново запустите эту установку. + Для использования [ProductName] необходимо установить компоненты IIS 7.0 CoreWebEngine и W3SVC. + Для использования [ProductName] требуется установить консоль управления IIS. + Перед установкой [ProductName] остановите службу активации Windows (WAS) и службу веб-управления (WMSvc). Эти службы нужно будет запустить после установки [ProductName]. + Для установки [ProductName] требуется метабаза IIS. + 64-разрядную версию [ProductName] нельзя установить на 32-разрядный выпуск Microsoft Windows. + 32-разрядную версию [ProductName] нельзя установить на 64-разрядный выпуск Microsoft Windows. + Для установки [ProductName] требуется Microsoft .NET Framework версии 2.0 или более поздней. + Для установки [ProductName] требуется Microsoft .NET Framework версии 3.5 или более поздней. Воспользуйтесь функцией диспетчера сервера "Добавить функции", чтобы установить Microsoft .Net версии 3.5. + Для установки [ProductName] требуется Microsoft .NET Framework версии 4.0 или более поздней. + Перед установкой [ProductName] установите Microsoft .NET Framework версии 2.0 с пакетом обновления 1 (SP1)или более поздним. + Службу Windows Update (wuauserv) невозможно отключить, она необходима для установки [ProductName]. + Оснастка PowerShell является частью операционной системы Windows. Установите ее с помощью элемента панели управления "Программы и компоненты" или диспетчера сервера. + Для установки [ProductName] требуется установщик веб-платформы Майкрософт, версии 3.0 или более поздней. + + Программа установки не обнаружила общую конфигурацию. + Для IIS включена общая конфигурация. Установка [ProductName] не поддерживается при использовании общей конфигурации. Отключите общую конфигурацию перед установкой этого компонента. + + Перед установкой [ProductName] необходимо остановить службу веб-публикаций (W3SVC). Эту службу нужно будет включить после установки. + Консоль управления IIS PowerShell + Оснастка IIS PowerShell + Для оснастки IIS PowerShell требуется PowerShell v1.0 или v2.0 + Для оснастки IIS PowerShell требуется установить WAS и конфигурацию + Пустая строка. + + + Платформа веб-ферм Майкрософт 2.2 + Агент веб-ферм Майкрософт 2.2 + Служба Web Farm Service + Служба Web Farm Service + Служба Web Farm Controller Service + Служба Web Farm Controller Service + Служба Web Farm Agent Service + Служба Web Farm Agent Service + Установщик веб-платформы является необходимым компонентом для установки платформы веб-ферм. Установите установщик веб-платформы с сайта http://www.microsoft.com/web/downloads/platform.aspx. + Инструмент веб-развертывания является необходимым компонентом для установки платформы веб-ферм. Установите инструмент веб-развертывания с сайта http://www.iis.net/download/WebDeploy. + + + Платформа веб-размещения Майкрософт + Платформа веб-размещения + Роли и компоненты веб-размещения. + Платформа размещения + Платформа размещения предоставляет API и команды PowerShell для управления веб-размещением. + Веб-роль + Веб-роль устанавливает динамическую службу WAS и поставщик переопределения URL-адресов для веб-размещения. + Antares Express + Развертывание панели управления в конфигурации, оптимизированной для установки на одном компьютере. + Роль подсистемы балансировки нагрузки + Роль подсистемы балансировки нагрузки позволяет настроить в маршрутизаторе запросов приложений маршрутизацию на основе правил веб-размещения. + Контроллер размещения + Контроллер размещения расширяет платформу веб-ферм 2.0, позволяя ей работать с веб-размещением. + Публикация — роль + Установка средств поддержки веб-развертывания и FTP-публикации. + Эта оснастка PowerShell, которая содержит командлеты для управления инфраструктурой Microsoft Web Hosting. + Динамическая служба WAS + Служба активации Windows, оптимизированная для веб-размещения высокой плотности. + Служба контроля ресурсов + Установка службы контроля ресурсов, которая позволяет собирать и публиковать сведения о среде выполнения и работоспособности. + Resource Metering + Позволяет собирать с веб-роли сведения о среде выполнения и работоспособности и публиковать их. + Применение квот размещения + Служит для отслеживания использования ресурсов веб-сайтами и выполнения настраиваемых действий при превышении квот. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/TRK/misc/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/TRK/misc/setupstrings.wxl new file mode 100644 index 0000000000..83599c3b1c --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/loc/TRK/misc/setupstrings.wxl @@ -0,0 +1,351 @@ + + + + + + + 1055 + + + + Paylaşılan Yapılandırma Yükleme Seçenekleri + IIS paylaşılan yapılandırmasına yükleme seçeneğini belirtin + Yüklerken paylaşılan yapılandırmayı güncelleştir + Bu modülü paylaşılan yapılandırma kullanan bir IIS sunucusuna yüklüyorsunuz. Bu paylaşılan yapılandırmayı kullanan ek IIS sunucuları varsa, bu modülü söz konusu makinelerin tümüne yüklemeniz gerekir. Web sunucularında oluşabilecek kesintileri en az indirmek için bu modülü şu adımları kullanarak yüklemeniz gerekir: İlk olarak, sonuncu hariç tüm makinelerde paylaşılan yapılandırmayı güncelleştirmeden modülü yüklemeniz gerekir. Bunu, aşağıdaki onay kutusunu seçmeden yapın. +Bu işlem, paylaşılan yapılandırmada hiçbir değişiklik yapmadan modül için gereken tüm ikili ve diğer dosyaları her bir makineye yükler. İkinci olarak, sonuncu makinede, altında çalıştığınız kullanıcı kimliğinin UNC paylaşımındaki applicationhost.config dosyasında okuma ve yazma erişimi olduğunu doğrulamalısınız. Sonra, modülü yüklemeli ve aşağıdaki paylaşılan yapılandırmayı güncelleştirme seçeneğini seçmeniz gerekir. + + + WebConfig özel eylemi başlatılıyor + web.config güncelleştiriliyor + + + + IIS Gelişmiş Günlüğü + IIS ardışık düzen verileri için gelişmiş günlüğü etkinleştirir. + IIS Gelişmiş Günlüğü + Genişletilebilir alan seçimi olan özel günlük dosyaları oluşturmaya olanak tanır. + IIS Gelişmiş Günlüğü Güncelleştirmesi + + + + IIS Dönüşüm Yöneticisi + Beta + Dönüşüm Yöneticisi IIS Medya Hizmetleri'ni etkinleştirir. + IIS Dönüşüm Yöneticisi + Medya dönüşümleri oluşturmayı etkinleştirir. + IIS Dönüşüm Yöneticisi Ana Bilgisayarı + [ProductName] için hizmet ana bilgisayarı. + IIS Dönüşüm Yöneticisi + İsteğe bağlı medya dosyalarını alternatif dosya ve kapsayıcı biçimlerine toplu olarak dönüştürün. + Bir IIS Transform Manager 1.0 Expression Encoder SP Task paketi bilgisayarda yüklü. [ProductName] ürününü yüklemeden önce bunu kaldırmalısınız. + + [ProductName] ürününü yüklemek için Microsoft .NET Framework 3.5 gereklidir. Sunucu Yöneticisi'ndeki 'Özellik Ekleme Sihirbazı'nı kullanarak .NET Framework 3.5.1 Özellikleri'ni yükleyin veya 'Windows özelliklerini aç veya kapat'ı kullanarak Microsoft .NET Framework 3.5'i açın. + + + + IIS Dijital Hak Yönetimi + Beta + Kesintisiz Akış sunularında Dijital Hak Yönetimini etkinleştirir. + + + ASP.NET Yüklü Değil + + + + + + + + + Bu bilgisayarda IIS Kesintisiz Akış - Beta bulundu. [ProductName] yüklemesi devam edemez. Bu ürünü yüklemek için, Denetim Masası'ndaki Program Ekle/Kaldır'ı kullanarak IIS Kesintisiz Akış - Beta'yı kaldırın. + Bu bilgisayarda IIS Medya Hizmetleri'nin uyumsuz bir sürümü var. [ProductName] yüklemesi devam edemez. Bu ürünü yüklemek için, Denetim Masası'ndaki Program Ekle/Kaldır'ı kullanarak IIS Medya Hizmetleri'ni kaldırın. + Bu ürünün daha yeni bir sürümü bu bilgisayarda yüklü veya bu bilgisayara yüklenebilir durumda. [ProductName] yüklemesi devam edemiyor. Bu ürünün yeni sürümünü yüklemek için, Denetim Masası'ndaki Program Ekle/Kaldır'ı kullanarak IIS Medya Hizmetleri'ni güncelleştirin. + Çalma Listesi Dosyasının Dönüştürülmesi Gerekiyor + + + + + Eski IIS Medya Hizmetleri Dosyaları Bulundu + + + + + Beta IIS Medya Hizmetleri Dosyaları Bulundu + + + + + + IIS Medya Paketi 1.0 + IIS Medya Paketi 1.0 Güncelleştirmesi + IIS Medya Hizmetleri 2.0 + IIS Medya Paketi 2.0 Güncelleştirmesi + IIS Medya Hizmetleri 3.0 + IIS Medya Hizmetleri 3.0 TAP 2 + IIS Medya Paketi 3.0 Güncelleştirmesi + IIS Medya Paketi özellikleri ve araçları. + IIS Media Services 5 Premium özellikleri ve araçları. + IIS Medya Hizmetleri 4.0 Beta 1 + IIS Medya Hizmetleri 4.0 + IIS Medya Hizmetleri 4.5 Beta 1 + IIS Media Services 5 Premium + + Web Çalma Listeleri + İstemcinin, çalma listelerinde başvurulan medya listelerini kayıttan yürütmesini denetler. + Oturum Yardımcısı + ASP.NET oturum durumu kalıcılığını etkinleştirir. (Web Sunucusu (IIS) için ASP.NET rol hizmetini gerektirir.) + Kullanıcı Arabirimi + IIS Yöneticisi'nde Web Çalma Listeleri özelliğini yapılandırır. + + Bit Hızı Azaltma + İstemcilerin karşıdan yüklediği dosyaların teslimini yavaşlatarak bant genişliğinden tasarruf sağlar. + Kullanıcı Arabirimi + IIS Yöneticisi'nde Bit Hızı Azaltma özelliğini yapılandırır. + + Varlıklar + İsteğe bağlı varlıkların istemcilere HTTP ile uyarlamalı akışını etkinleştirir. + Kullanıcı Arabirimi + IIS Yöneticisi'nde Kesintisiz Akış özelliğini yapılandırır. + + Kanallar + Kanal yayınlarının istemcilere HTTP ile uyarlamalı akışını etkinleştirir. + Kullanıcı Arabirimi + IIS Yöneticisi'nde Canlı Kesintisiz Akış özelliğini yapılandırır. + + Dijital Hak Yönetimi + Kesintisiz Akış medyası için şifreleme ve lisanslama sağlar. + Kullanıcı Arabirimi + IIS Yöneticisi'nde Dijital Hak Yönetimi özelliğini yapılandırır. + + [ProductName] için Microsoft Windows Vista Service Pack 1 veya üstü gereklidir. + [ProductName], Vista Home Basic üzerine yüklenemez. + [ProductName] için Microsoft Windows 7 Service Pack 1 veya üstü gereklidir. + + + IIS Veritabanı Yöneticisi + IIS Veritabanı Yöneticisi + + + Microsoft Web Yönetimi Hizmeti 2 + Microsoft Web Yönetimi Hizmeti + [ProductName] ürününün temel özelliklerini yükler. + Microsoft Web Yönetimi Hizmeti 2 + Web Yönetimi Hizmeti, yöneticilerin bu makinede bulunan Web sunucularını, siteleri ve uygulamaları yönetmeleri için uzaktan ve temsilci seçilmiş yönetim becerileri sağlar. + + + IIS 7 için Microsoft URL Yeniden Yazma Modülü 1.1 + IIS 7 için URL Yeniden Yazma Modülü 1.1 Güncelleştirmesi + URL Yeniden Yazma + IIS 7'nin URL ve içerik yeniden yazma yeteneklerini etkinleştirir. + Kullanıcı Arabirimi + IIS Yöneticisi'nde URL Yeniden Yazma Modülü özelliğini yapılandırır. + + + IIS URL Yeniden Yazma Modülü 2 + IIS URL Yeniden Yazma Modülü 2 Güncelleştirmesi + URL Yeniden Yazma + IIS 7'nin URL ve içerik yeniden yazma yeteneklerini etkinleştirir. + Kullanıcı Arabirimi + IIS Yöneticisi'nde URL Yeniden Yazma Modülü özelliğini yapılandırır. + + + IIS 7.0 için Yönetim Paketi + [ProductName] ürününün temel özelliklerini yükler. + 1254 + IIS 7.0 için Yönetim Paketi + Microsoft Corporation + İşletim sisteminin bu sürümü desteklenmiyor. [ProductName] yalnızca Windows Server 2008 ya da Windows Vista Service Pack 1 ve üstü üzerine yüklenebilir. + ASP.Net Özellikleri + ASP.NET, yetkilendirme ve özel hata ayarlarınızı yönetmenizi sağlayan Yetkilendirme ve Hata Sayfaları özelliklerini içerir. + Kimlik Doğrulaması + ASP.Net Kimlik Doğrulaması Açıklaması. + Yetkilendirme + ASP.NET Yetkilendirme, kullanıcılara Web sitelerinize ve uygulamalarınıza erişme yetkisi verme kurallarını yapılandırmanızı sağlar. + Hata Sayfaları + ASP.NET Hata Sayfaları, hata oluştuğunda döndürülen HTTP hata yanıtlarını yapılandırmanızı sağlar. + Modüller + ASP.Net Modülleri Açıklaması. + İşleyiciler + ASP.Net İşleyiciler Açıklaması. + Yapılandırma Düzenleyicisi + Yapılandırma Düzenleyicisi, IIS Yöneticisi'nde yapılandırma dosyalarındaki bölümleri, öznitelikleri, öğeleri ve koleksiyonları düzenlemenize olanak tanıyarak yapılandırma dosyalarınızı yönetmenizi sağlar. + İstek Filtreleme + İstek Filtreleme, Web siteniz için filtreleme kurallarını yapılandırmanızı, protokol ve içerik davranışını kısıtlamanızı sağlar. + FastCGI + FastCGI, Web sunucunuzdaki FastCGI uygulamaları için işlem havuzu ayarlarını yapılandırmanızı sağlar. + + + IIS 7 için Dinamik IP Kısıtlamaları Kurulumu + + + + + + + + + + + + + IIS 7 için Dinamik IP Kısıtlamaları - Beta + IIS 7 için Dinamik IP Kısıtlamaları - Beta 2 + IIS 7 için Dinamik IP Kısıtlamaları - Beta 3 + + IIS 7 için Dinamik IP Kısıtlamaları - Sürüm Adayı + IIS 7 için Dinamik IP Kısıtlamaları - Sürüm Adayı 2 + IIS 7 için Dinamik IP Kısıtlamaları - Sürüm Adayı 3 + + IIS 7 için Dinamik IP Kısıtlamaları - RTW + + IIS 7 için Dinamik IP Kısıtlamaları + IIS 7 için Dinamik IP Kısıtlamaları Kullanıcı Arabirimi + + Bu makinede IIS 7 - Beta için Dinamik IP Kısıtlamaları bulundu. Lütfen kaldırın ve yeniden deneyin + + + IIS 7.0 için WebDAV 7.5 + Bu ürünü kullanmak için IIS 7.0 CoreWebEngine ve W3SVC özellikleri yüklenmelidir. + WebDAV Sunucu Modülü + WebDAV Yönetimi Kullanıcı Arabirimi + + + IIS Arama Alt Yapısı İyileştirme Araç Seti 1.0 + IIS Arama Alt Yapısı İyileştirme Araç Seti 1.0 + Arama Alt Yapısı İyileştirme (SEO) Araç Seti 1.0 + Bu yükleyici veritabanı IIS Arama Alt Yapısı İyileştirme Araç Seti 1.0'ı yüklemek için gereken mantığı ve verileri içermektedir. + + + IIS Düzenleyicisi + + + IIS Raporları + Bu makinede Günlük Ayrıştırıcısı yüklü değil. Lütfen http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07 adresinden Günlük Ayrıştırıcısı 2.2 sürümünü yükleyin ve sonra IIS Raporları yüklemesine devam edin + + + Önkoşul paketler bulunamadı. Bağımlılıkları çözümlemek ve bu programı yüklemek için lütfen setup.exe'yi çalıştırın. + Microsoft SQL Server 2008 Yönetim Nesneleri, IIS Veritabanı Yöneticisi'ni yüklemek için bir önkoşuldur. Microsoft SQL Server 2008 Yönetim Nesneleri'ni http://go.microsoft.com/fwlink/?LinkID=150946 adresinden yükleyebilirsiniz. + Microsoft SQL Server Sistem CLR Türleri, IIS Veritabanı Yöneticisi'ni yüklemek için bir önkoşuldur. Microsoft SQL Server Sistem CLR Türleri'ni http://go.microsoft.com/fwlink/?LinkID=150949 adresinden yükleyebilirsiniz. + + + Microsoft Web Grubu Çerçevesi + Microsoft Dış Önbellek + Web Grubu Çerçevesi, Uygulama İsteği Yönlendirme için bir önkoşuldur. Lütfen Web Grubu Çerçevesi'ni yükleyin. + Microsoft Uygulama İsteği Yönlendirme 2.5 + Çalışma Zamanı + IIS'ye Uygulama İsteği Yönlendirme özellikleri ekler. + Kullanıcı Arabirimi + IIS Yöneticisi'nde Uygulama İsteği Yönlendirme özelliğini yapılandırır. + + + IIS 7.0 için Microsoft Windows PowerShell ek bileşeni + + + Microsoft Web Platformu Yükleyicisi 4.0 + Microsoft Web Platformu Yükleyicisi + [ProductName] için Windows XP SP2, Windows 2003 SP1, Windows Vista veya üstü gereklidir. + [ProductName] için Windows XP Service Pack 3, Windows Server 2003 Service Pack 2 veya üstü gereklidir. + + + Microsoft Windows Azure Hizmetleri Yükleyicisi + Microsoft Windows Azure Hizmetleri Yükleyicisi + + + Internet Information Services (IIS) 7+ Yöneticisi + IIS Yöneticisi İstemcisi + Uzaktan İletişim Desteği + Bu ürün için Windows XP SP2, Windows 2003 SP1, Windows Vista SP1, Windows 7 veya daha üstü gereklidir + IIS Yönetim Konsolu yüklenmedi ancak uzak IIS Sunucularını yönetmek için gerekiyor. Uzaktan yönetim desteğini yüklemeden önce lütfen 'Denetim Masası -> Programlar -> Windows Özelliklerini Aç veya Kapat'ı açın ve Internet Information Services özelliğinde IIS Yönetimi Konsolu'nu seçin. + Bu ürün Windows Server 2008, Windows Server 2008 R2 veya daha üstünde gerekli değildir. IIS Yönetim Konsolu'nu yüklemek üzere lütfen Sunucu Yöneticisi'ni açın ve Web Sunucusu Rolü için Rol Hizmetleri'nde IIS Yönetim Konsolu'nu seçin. + + + IIS 7.0 için IIS Yöneticisi Yayımlama + Yayımlama Kullanıcı Arabirimi + + + IIS 7.5 için Application Warm-Up 1.0 + + + + Bu bilgisayarda uyumsuz bir ürün ([CONFLICTING_PRODUCT_NAME]) mevcut. [ProductName] ürününün yüklemesi devam edemiyor. Bu ürünü yüklemek için [CONFLICTING_PRODUCT_NAME] ürününü kaldırmak amacıyla Denetim Masası'ndaki Program Ekle/Kaldır'ı kullanın. + [ProductName] ürününü yüklemek için yönetici ayrıcalıkları gereklidir. + [ProductName] ürününü kullanmak için IIS Sürüm 7.0 gereklidir. + [ProductName] ürününü yüklemek için IIS Sürüm 7.0 veya üstü gereklidir. + [ProductName] ürününü yüklemek için IIS Sürüm 7.5 veya üstü gereklidir. + [ProductName] ürününü yüklemek için IIS Sürüm 7 veya 7.5 gereklidir. + Bu makinede [ProductName] ürününün beta sürümü bulundu. + Bu makinede [ProductName] ürününün daha yeni bir sürümü bulundu. + Bu bilgisayara başka bir [ProductName] örneği önceden yüklendiğinden Kurulum devam edemiyor. Lütfen önce onu kaldırın ve sonra bu yükleme işlemini yeniden başlatın. + [ProductName] ürününü kullanmak için IIS 7.0 CoreWebEngine ve W3SVC özellikleri yüklenmelidir. + [ProductName] ürününü kullanmak için IIS Yönetim Konsolu yüklenmelidir. + [ProductName] ürününü yüklemeden önce lütfen Windows İşlem Etkinleştirme Hizmeti (WAS) ve Web Yönetimi Hizmeti (WMSvc) hizmetlerinin ikisini de durdurun. [ProductName] yüklendikten sonra hizmetleri yeniden başlatmanız gerekir. + [ProductName] ürününü yüklemek için IIS Metatabanı gereklidir. + [ProductName] ürünün 64-bit sürümü Microsoft Windows'un 32-bit bir sürümüne yüklenemez. + [ProductName] ürünün 32-bit sürümü Microsoft Windows'un 64-bit bir sürümüne yüklenemez. + [ProductName] ürününü yüklemek için Microsoft .NET Framework Sürüm 2.0 veya üstü gereklidir. + [ProductName] ürününü yüklemek için Microsoft .NET Framework Sürüm 3.5 veya üstü gereklidir. Microsoft .Net Sürüm 3.5'i yüklemek için Sunucu Yöneticisi altındaki 'Özellik Ekle' seçeneğini kullanın. + [ProductName] ürününü yüklemek için Microsoft .NET Framework Sürüm 4.0 veya üstü gereklidir. + [ProductName] ürününü yüklemeden önce lütfen Microsoft .NET Framework Sürüm 2.0 Service Pack 1'i (veya daha yeni bir hizmet paketini) yükleyin. + Windows Update (wuauserv) hizmeti devre dışı bırakılamaz; [ProductName] ürününü yüklemek için gereklidir. + PowerShell ek bileşeni Windows İşletim Sisteminin bir parçasıdır. Lütfen 'Programlar ve Özellikler' veya 'Sunucu Yöneticisi' aracılığıyla yükleyin. + [ProductName] ürününü yüklemek için Microsoft Web Platformu Yükleyicisi 3.0 veya üstü gereklidir. + + Kurulum paylaşılan yapılandırmayı silemedi. + IIS için paylaşılan yapılandırma etkin. Paylaşılan yapılandırma kullanılırken [ProductName] ürününün yüklenmesi desteklenmiyor. Bu özelliği yüklemeden önce lütfen paylaşılan yapılandırmayı devre dışı bırakın. + + [ProductName] ürününü yüklemeden önce lütfen World Wide Web Yayımlama Hizmeti'ni (W3SVC) durdurun. Yükleme işleminden sonra hizmeti yeniden başlatmanız gerekir. + IIS PowerShell Yönetim Konsolu + IIS PowerShell ek bileşeni + IIS PowerShell ek bileşeni için PowerShell v1.0 veya v2.0 yüklü olmalıdır + IIS PowerShell ek bileşeni için WAS ve yapılandırma yüklü olmalıdır + Bu hatalı bir dizedir. + + + Microsoft Web Grubu Çerçevesi Sürüm 2.2 + Microsoft Web Grubu Aracısı Sürüm 2.2 + Web Grubu Hizmeti + Web Grubu Hizmeti + Web Grubu Denetleyicisi Hizmeti + Web Grubu Denetleyicisi Hizmeti + Web Grubu Aracısı Hizmeti + Web Grubu Aracısı Hizmeti + Web Grubu Çerçevesi'ni yüklemek için Web Platformu Yükleyicisi bir önkoşuldur. Lütfen http://www.microsoft.com/web/downloads/platform.aspx adresinden Web Platformu Yükleyicisi'ni yükleyin. + Web Grubu Çerçevesi'ni yüklemek için Web Dağıtım Aracı bir önkoşuldur. Lütfen http://www.iis.net/download/WebDeploy adresinden Web Dağıtımı Aracı'nı yükleyin. + + + Microsoft Web Barındırma Çerçevesi + Web Barındırma Çerçevesi + Web Barındırma rolleri ve özellikleri. + Barındırma Çerçevesi + Barındırma Çerçevesi, Web Barındırma'yı yönetmek için API'ler ve PowerShell komutları sağlar. + Web Rolü + Web Rolü, Web Barındırma için Dinamik WAS hizmetini ve URL Yeniden Yazma sağlayıcısını yükler. + Antares Express + Tek makineli kurulum için en iyi duruma getirilen bir Denetim Masası yapılandırmasını dağıtır. + Yük Dengeleyici Rolü + Yük Dengeleyici Rolü, Uygulama İstek Yönlendiricisini Web Barındırma kurallarına göre yönlendirecek şekilde yapılandırır. + Barındırma Denetleyicisi + Barındırma Denetleyicisi, Web Grubu Çerçevesi 2.0'ı Web Barındırma ile çalışacak şekilde genişletir. + Yayımlama Rolü + Web Dağıtımı ve FTP yayımlama için desteği yükler. + Bu, Microsoft Web Barındırma altyapısını yönetmeyi sağlayan cmdlet'ler içeren bir PowerShell ek bileşenidir. + Dinamik WAS Hizmeti + Yüksek yoğunluklu Web Barındırma için en iyi duruma getirilmiş Windows İşlem Etkinleştirme hizmeti. + Kaynak Ölçümü Hizmeti + Çalışma zamanı ve sistem bilgisi toplamayı ve yayımlamayı sağlayan Kaynak Ölçümü hizmetini yükler. + Kaynak Ölçümü + Web Rolünden çalışma zamanı ve sistem bilgisi toplamayı ve yayımlamayı sağlar. + Barındırma Kota Uygulama + Web sitesi kaynak kullanımını izler ve kullanım kotası aşıldığında özel eylemler uygular. + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/dutil.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/dutil.h new file mode 100644 index 0000000000..2a830b7c83 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/dutil.h @@ -0,0 +1,181 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once +//------------------------------------------------------------------------------------------------- +// +// Header for utility layer that provides standard support for asserts, exit macros +// +//------------------------------------------------------------------------------------------------- + +#define DAPI __stdcall +#define DAPIV __cdecl // used only for functions taking variable length arguments + +#define DAPI_(type) EXTERN_C type DAPI +#define DAPIV_(type) EXTERN_C type DAPIV + + +// enums +enum REPORT_LEVEL { + REPORT_NONE, // turns off report (only valid for XXXSetLevel()) + REPORT_STANDARD, // written if reporting is on + REPORT_VERBOSE, // written only if verbose reporting is on + REPORT_DEBUG, // reporting useful when debugging code + REPORT_ERROR, // always gets reported, but can never be specified + }; + +// asserts and traces +#ifdef DEBUG + +typedef BOOL (DAPI *DUTIL_ASSERTDISPLAYFUNCTION)(LPCSTR sz); + +extern "C" void DAPI Dutil_SetAssertModule(__in HMODULE hAssertModule); +extern "C" void DAPI Dutil_SetAssertDisplayFunction(__in DUTIL_ASSERTDISPLAYFUNCTION pfn); +extern "C" void DAPI Dutil_Assert(const CHAR* szFile, int iLine); +extern "C" void DAPI Dutil_AssertSz(const CHAR* szFile, int iLine, const CHAR *szMsg); + +extern "C" void DAPI Dutil_TraceSetLevel(__in REPORT_LEVEL ll, __in BOOL fTraceFilenames); +extern "C" REPORT_LEVEL DAPI Dutil_TraceGetLevel(); +extern "C" void __cdecl Dutil_Trace(__in LPCSTR szFile, __in int iLine, __in REPORT_LEVEL rl, __in LPCSTR szMessage, ...); +extern "C" void __cdecl Dutil_TraceError(__in LPCSTR szFile, __in int iLine, __in REPORT_LEVEL rl, __in HRESULT hr, __in LPCSTR szMessage, ...); + +#endif + +#if defined DEBUG + +#define AssertSetModule(m) (void)Dutil_SetAssertModule(m) +#define AssertSetDisplayFunction(pfn) (void)Dutil_SetAssertDisplayFunction(pfn) +#define Assert(f) ((f) ? (void)0 : (void)Dutil_Assert(__FILE__, __LINE__)) +#define AssertSz(f, sz) ((f) ? (void)0 : (void)Dutil_AssertSz(__FILE__, __LINE__, sz)) + +#define TraceSetLevel(l, f) (void)Dutil_TraceSetLevel(l, f) +#define TraceGetLevel() (REPORT_LEVEL)Dutil_TraceGetLevel() +#define Trace(l, f) (void)Dutil_Trace(__FILE__, __LINE__, l, f, NULL) +#define Trace1(l, f, s) (void)Dutil_Trace(__FILE__, __LINE__, l, f, s) +#define Trace2(l, f, s, t) (void)Dutil_Trace(__FILE__, __LINE__, l, f, s, t) +#define Trace3(l, f, s, t, u) (void)Dutil_Trace(__FILE__, __LINE__, l, f, s, t, u) + +#define TraceError(x, f) (void)Dutil_TraceError(__FILE__, __LINE__, REPORT_ERROR, x, f, NULL) +#define TraceError1(x, f, s) (void)Dutil_TraceError(__FILE__, __LINE__, REPORT_ERROR, x, f, s) +#define TraceError2(x, f, s, t) (void)Dutil_TraceError(__FILE__, __LINE__, REPORT_ERROR, x, f, s, t) +#define TraceError3(x, f, s, t, u) (void)Dutil_TraceError(__FILE__, __LINE__, REPORT_ERROR, x, f, s, t, u) + +#define TraceErrorDebug(x, f) (void)Dutil_TraceError(__FILE__, __LINE__, REPORT_DEBUG, x, f, NULL) +#define TraceErrorDebug1(x, f, s) (void)Dutil_TraceError(__FILE__, __LINE__, REPORT_DEBUG, x, f, s) +#define TraceErrorDebug2(x, f, s, t) (void)Dutil_TraceError(__FILE__, __LINE__, REPORT_DEBUG, x, f, s, t) +#define TraceErrorDebug3(x, f, s, t, u) (void)Dutil_TraceError(__FILE__, __LINE__, REPORT_DEBUG, x, f, s, t, u) + +#else // !DEBUG + +#define AssertSetModule(m) +#define AssertSetDisplayFunction(pfn) +#define Assert(f) +#define AssertSz(f, sz) + +#define TraceSetLevel(l, f) +#define Trace(l, f) +#define Trace1(l, f, s) +#define Trace2(l, f, s, t) +#define Trace3(l, f, s, t, u) + +#define TraceError(x, f) +#define TraceError1(x, f, s) +#define TraceError2(x, f, s, t) +#define TraceError3(x, f, s, t, u) + +#define TraceErrorDebug(x, f) +#define TraceErrorDebug1(x, f, s) +#define TraceErrorDebug2(x, f, s, t) +#define TraceErrorDebug3(x, f, s, t, u) + +#endif // DEBUG + + +// ExitTrace can be overriden +#ifndef ExitTrace +#define ExitTrace TraceError +#endif +#ifndef ExitTrace1 +#define ExitTrace1 TraceError1 +#endif +#ifndef ExitTrace2 +#define ExitTrace2 TraceError2 +#endif +#ifndef ExitTrace3 +#define ExitTrace3 TraceError3 +#endif + +// Exit macros +#define ExitFunction() { goto LExit; } +#define ExitFunction1(x) { x; goto LExit; } + +#define ExitOnLastError(x, s) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { ExitTrace(x, s); goto LExit; } } +#define ExitOnLastError1(x, f, s) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { ExitTrace1(x, f, s); goto LExit; } } +#define ExitOnLastError2(x, f, s, t) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { ExitTrace2(x, f, s, t); goto LExit; } } + +#define ExitOnLastErrorDebugTrace(x, s) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { TraceErrorDebug(x, s); goto LExit; } } +#define ExitOnLastErrorDebugTrace1(x, f, s) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { TraceErrorDebug1(x, f, s); goto LExit; } } +#define ExitOnLastErrorDebugTrace2(x, f, s, t) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { TraceErrorDebug2(x, f, s, t); goto LExit; } } + +#define ExitWithLastError(x, s) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (!FAILED(x)) { x = E_FAIL; } ExitTrace(x, s); goto LExit; } +#define ExitWithLastError1(x, f, s) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (!FAILED(x)) { x = E_FAIL; } ExitTrace1(x, f, s); goto LExit; } +#define ExitWithLastError2(x, f, s, t) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (!FAILED(x)) { x = E_FAIL; } ExitTrace2(x, f, s, t); goto LExit; } + +#define ExitOnFailure(x, s) if (FAILED(x)) { ExitTrace(x, s); goto LExit; } +#define ExitOnFailure1(x, f, s) if (FAILED(x)) { ExitTrace1(x, f, s); goto LExit; } +#define ExitOnFailure2(x, f, s, t) if (FAILED(x)) { ExitTrace2(x, f, s, t); goto LExit; } +#define ExitOnFailure3(x, f, s, t, u) if (FAILED(x)) { ExitTrace3(x, f, s, t, u); goto LExit; } + +#define ExitOnFailureDebugTrace(x, s) if (FAILED(x)) { TraceErrorDebug(x, s); goto LExit; } +#define ExitOnFailureDebugTrace1(x, f, s) if (FAILED(x)) { TraceErrorDebug1(x, f, s); goto LExit; } +#define ExitOnFailureDebugTrace2(x, f, s, t) if (FAILED(x)) { TraceErrorDebug2(x, f, s, t); goto LExit; } +#define ExitOnFailureDebugTrace3(x, f, s, t, u) if (FAILED(x)) { TraceErrorDebug3(x, f, s, t, u); goto LExit; } + +#define ExitOnNull(p, x, e, s) if (NULL == p) { x = e; ExitTrace(x, s); goto LExit; } +#define ExitOnNull1(p, x, e, f, s) if (NULL == p) { x = e; ExitTrace1(x, f, s); goto LExit; } +#define ExitOnNull2(p, x, e, f, s, t) if (NULL == p) { x = e; ExitTrace2(x, f, s, t); goto LExit; } + +#define ExitOnNullWithLastError(p, x, s) if (NULL == p) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (!FAILED(x)) { x = E_FAIL; } ExitTrace(x, s); goto LExit; } +#define ExitOnNullWithLastError1(p, x, f, s) if (NULL == p) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (!FAILED(x)) { x = E_FAIL; } ExitTrace1(x, f, s); goto LExit; } + +#define ExitOnNullDebugTrace(p, x, e, s) if (NULL == p) { x = e; TraceErrorDebug(x, s); goto LExit; } +#define ExitOnNullDebugTrace1(p, x, e, f, s) if (NULL == p) { x = e; TraceErrorDebug1(x, f, s); goto LExit; } + +#define ExitOnNtError(x, s) if (NT_ERROR(x)) { ExitTrace(x, s); goto LExit; } +#define ExitOnNtError1(x, f, s) if (NT_ERROR(x)) { ExitTrace1(x, f, s); goto LExit; } + + +// release macros +#define ReleaseObject(x) if (x) { x->Release(); } +#define ReleaseVariant(x) { ::VariantClear(&x); } +#define ReleaseNullObject(x) if (x) { (x)->Release(); x = NULL; } +#define ReleaseCertificate(x) if (x) { ::CertFreeCertificateContext(x); x=NULL; } + + +// useful defines and macros +#define Unused(x) ((void)x) + +#ifndef MAXSIZE_T +#define MAXSIZE_T ((SIZE_T)~((SIZE_T)0)) +#endif + + +#if 1 +#define countof(ary) (sizeof(ary) / sizeof(ary[0])) +#else +#ifndef __cplusplus +#define countof(ary) (sizeof(ary) / sizeof(ary[0])) +#else +template static char countofVerify(void const *, T) throw() { return 0; } +template static void countofVerify(T *const, T *const *) throw() {}; +#define countof(arr) (sizeof(countofVerify(arr,&(arr))) * sizeof(arr)/sizeof(*(arr))) +#endif +#endif + + +#ifndef MAXSIZE_T +#define MAXSIZE_T ((SIZE_T)~((SIZE_T)0)) +#endif + +#define E_NOMOREITEMS HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) +#define AddRefAndRelease(x) { x->AddRef(); x->Release(); } diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/memutil.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/memutil.h new file mode 100644 index 0000000000..36077b0fc6 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/memutil.h @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once +//------------------------------------------------------------------------------------------------- +// +// Header for memory helper functions. +// +//------------------------------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +#define ReleaseMem(p) if (p) { MemFree(p); } +#define ReleaseNullMem(p) if (p) { MemFree(p); p = NULL; } + + +HRESULT DAPI MemInitialize(); +void DAPI MemUninitialize(); + +LPVOID DAPI MemAlloc( + __in SIZE_T cbSize, + __in BOOL fZero + ); +LPVOID DAPI MemReAlloc( + __in LPVOID pv, + __in SIZE_T cbSize, + __in BOOL fZero + ); + +HRESULT DAPI MemFree( + __in LPVOID pv + ); +SIZE_T DAPI MemSize( + __in LPVOID pv + ); + +#ifdef __cplusplus +} +#endif + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/precomp.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/precomp.h new file mode 100644 index 0000000000..e41eecd4e4 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/precomp.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once + +#include +#include +#include +#include + +const WCHAR MAGIC_MULTISZ_DELIM = 128; + +#include "wcautil.h" +#include "memutil.h" +#include "strutil.h" diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/qtexec.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/qtexec.cpp new file mode 100644 index 0000000000..45d0945f62 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/qtexec.cpp @@ -0,0 +1,276 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +//------------------------------------------------------------------------------------------------- +// +// Executes command line instructions without popping up a shell. +// +//------------------------------------------------------------------------------------------------- + +#include "precomp.h" + +#define OUTPUT_BUFFER 1024 + + +#define ONEMINUTE 60000 + +static HRESULT CreatePipes( + __out HANDLE *phOutRead, + __out HANDLE *phOutWrite, + __out HANDLE *phErrWrite, + __out HANDLE *phInRead, + __out HANDLE *phInWrite + ) +{ + Assert(phOutRead); + Assert(phOutWrite); + Assert(phErrWrite); + Assert(phInRead); + Assert(phInWrite); + + HRESULT hr = S_OK; + SECURITY_ATTRIBUTES sa; + HANDLE hOutTemp = INVALID_HANDLE_VALUE; + HANDLE hInTemp = INVALID_HANDLE_VALUE; + + HANDLE hOutRead = INVALID_HANDLE_VALUE; + HANDLE hOutWrite = INVALID_HANDLE_VALUE; + HANDLE hErrWrite = INVALID_HANDLE_VALUE; + HANDLE hInRead = INVALID_HANDLE_VALUE; + HANDLE hInWrite = INVALID_HANDLE_VALUE; + + // Fill out security structure so we can inherit handles + ::ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + + // Create pipes + if (!::CreatePipe(&hOutTemp, &hOutWrite, &sa, 0)) + ExitOnLastError(hr, "failed to create output pipe"); + + if (!::CreatePipe(&hInRead, &hInTemp, &sa, 0)) + ExitOnLastError(hr, "failed to create input pipe"); + + + // Duplicate output pipe so standard error and standard output write to + // the same pipe + if (!::DuplicateHandle(::GetCurrentProcess(), hOutWrite, ::GetCurrentProcess(), &hErrWrite, 0, TRUE, DUPLICATE_SAME_ACCESS)) + ExitOnLastError(hr, "failed to duplicate write handle"); + + // We need to create new output read and input write handles that are + // non inheritable. Otherwise it creates handles that can't be closed. + if (!::DuplicateHandle(::GetCurrentProcess(), hOutTemp, ::GetCurrentProcess(), &hOutRead, 0, FALSE, DUPLICATE_SAME_ACCESS)) + ExitOnLastError(hr, "failed to duplicate output pipe"); + + if (!::DuplicateHandle(::GetCurrentProcess(), hInTemp, ::GetCurrentProcess(), &hInWrite, 0, FALSE, DUPLICATE_SAME_ACCESS)) + ExitOnLastError(hr, "failed to duplicate input pipe"); + + // now that everything has succeeded, assign to the outputs + *phOutRead = hOutRead; + hOutRead = INVALID_HANDLE_VALUE; + + *phOutWrite = hOutWrite; + hOutWrite = INVALID_HANDLE_VALUE; + + *phErrWrite = hErrWrite; + hErrWrite = INVALID_HANDLE_VALUE; + + *phInRead = hInRead; + hInRead = INVALID_HANDLE_VALUE; + + *phInWrite = hInWrite; + hInWrite = INVALID_HANDLE_VALUE; + +LExit: + if (INVALID_HANDLE_VALUE != hOutRead) + ::CloseHandle(hOutRead); + if (INVALID_HANDLE_VALUE != hOutWrite) + ::CloseHandle(hOutWrite); + if (INVALID_HANDLE_VALUE != hErrWrite) + ::CloseHandle(hErrWrite); + if (INVALID_HANDLE_VALUE != hInRead) + ::CloseHandle(hInRead); + if (INVALID_HANDLE_VALUE != hInWrite) + ::CloseHandle(hInWrite); + if (INVALID_HANDLE_VALUE != hOutTemp) + ::CloseHandle(hOutTemp); + if (INVALID_HANDLE_VALUE != hInTemp) + ::CloseHandle(hInTemp); + + return hr; +} + +static HRESULT LogOutput( + __in HANDLE hRead + ) +{ + BYTE *pBuffer = NULL; + LPWSTR szLog = NULL; + LPWSTR szTemp = NULL; + LPWSTR pEnd = NULL; + LPWSTR pNext = NULL; + LPSTR szWrite = NULL; + DWORD dwBytes = OUTPUT_BUFFER; + BOOL bFirst = TRUE; + BOOL bUnicode = TRUE; + HRESULT hr = S_OK; + + // Get buffer for output + pBuffer = (BYTE *)MemAlloc(OUTPUT_BUFFER, FALSE); + ExitOnNull(pBuffer, hr, E_OUTOFMEMORY, "Failed to allocate buffer for output."); + + while (0 != dwBytes) + { + ::ZeroMemory(pBuffer, OUTPUT_BUFFER); + if(!::ReadFile(hRead, pBuffer, OUTPUT_BUFFER - 1, &dwBytes, NULL) && GetLastError() != ERROR_BROKEN_PIPE) + { + ExitOnLastError(hr, "Failed to read from handle."); + } + + // Check for UNICODE or ANSI output + if (bFirst) + { + if ((isgraph(pBuffer[0]) && isgraph(pBuffer[1])) || + (isgraph(pBuffer[0]) && isspace(pBuffer[1])) || + (isspace(pBuffer[0]) && isgraph(pBuffer[1])) || + (isspace(pBuffer[0]) && isspace(pBuffer[1]))) + bUnicode = FALSE; + bFirst = FALSE; + } + + // Keep track of output + if (bUnicode) + { + hr = StrAllocConcat(&szLog, (LPWSTR)pBuffer, 0); + ExitOnFailure(hr, "failed to concatenate output strings"); + } + else + { + hr = StrAllocStringAnsi(&szTemp, (LPSTR)pBuffer, 0, CP_OEMCP); + ExitOnFailure(hr, "failed to allocate output string"); + hr = StrAllocConcat(&szLog, szTemp, 0); + ExitOnFailure(hr, "failed to concatenate output strings"); + } + + // Log each line of the output + pNext = szLog; + pEnd = wcschr(szLog, L'\r'); + if (NULL == pEnd) + pEnd = wcschr(szLog, L'\n'); + while (pEnd && *pEnd) + { + // Find beginning of next line + pEnd[0] = 0; + pEnd++; + if ((pEnd[0] == L'\r') || (pEnd[0] == L'\n')) + pEnd++; + + // Log output + hr = StrAnsiAllocString(&szWrite, pNext, 0, CP_OEMCP); + ExitOnFailure(hr, "failed to convert output to ANSI"); + WcaLog(LOGMSG_STANDARD, szWrite); + + // Next line + pNext = pEnd; + pEnd = wcschr(pNext, L'\r'); + if (NULL == pEnd) + pEnd = wcschr(pNext, L'\n'); + } + + hr = StrAllocString(&szTemp, pNext, 0); + ExitOnFailure(hr, "failed to allocate string"); + + hr = StrAllocString(&szLog, szTemp, 0); + ExitOnFailure(hr, "failed to allocate string"); + } + + // Print any text that didn't end with a new line + if (szLog && *szLog) + { + hr = StrAnsiAllocString(&szWrite, szLog, 0, CP_OEMCP); + ExitOnFailure(hr, "failed to convert output to ANSI"); + WcaLog(LOGMSG_VERBOSE, szWrite); + } + +LExit: + if (NULL != pBuffer) + MemFree(pBuffer); + + ReleaseNullStr(szLog); + ReleaseNullStr(szTemp); + ReleaseNullStr(szWrite); + + return hr; +} + +HRESULT QuietExec( + __in LPWSTR wzCommand, + __in DWORD dwTimeout + ) +{ + HRESULT hr = S_OK; + PROCESS_INFORMATION oProcInfo; + STARTUPINFOW oStartInfo; + DWORD dwExitCode = ERROR_SUCCESS; + HANDLE hOutRead = INVALID_HANDLE_VALUE; + HANDLE hOutWrite = INVALID_HANDLE_VALUE; + HANDLE hErrWrite = INVALID_HANDLE_VALUE; + HANDLE hInRead = INVALID_HANDLE_VALUE; + HANDLE hInWrite = INVALID_HANDLE_VALUE; + + memset(&oProcInfo, 0, sizeof(oProcInfo)); + memset(&oStartInfo, 0, sizeof(oStartInfo)); + + // Create output redirect pipes + hr = CreatePipes(&hOutRead, &hOutWrite, &hErrWrite, &hInRead, &hInWrite); + ExitOnFailure(hr, "failed to create output pipes"); + + // Set up startup structure + oStartInfo.cb = sizeof(STARTUPINFOW); + oStartInfo.dwFlags = STARTF_USESTDHANDLES; + oStartInfo.hStdInput = hInRead; + oStartInfo.hStdOutput = hOutWrite; + oStartInfo.hStdError = hErrWrite; + + WcaLog(LOGMSG_VERBOSE, "%S", wzCommand); + + if (::CreateProcessW(NULL, + wzCommand, // command line + NULL, // security info + NULL, // thread info + TRUE, // inherit handles + ::GetPriorityClass(::GetCurrentProcess()) | CREATE_NO_WINDOW, // creation flags + NULL, // environment + NULL, // cur dir + &oStartInfo, + &oProcInfo)) + { + ::CloseHandle(oProcInfo.hThread); + + // Close child output/input handles so it doesn't hang + ::CloseHandle(hOutWrite); + ::CloseHandle(hErrWrite); + ::CloseHandle(hInRead); + + // Log output + LogOutput(hOutRead); + + // Wait for everything to finish + ::WaitForSingleObject(oProcInfo.hProcess, dwTimeout); + if (!::GetExitCodeProcess(oProcInfo.hProcess, &dwExitCode)) + dwExitCode = ERROR_SEM_IS_SET; + ::CloseHandle(hOutRead); + ::CloseHandle(hInWrite); + ::CloseHandle(oProcInfo.hProcess); + } + else + ExitOnLastError(hr, "Command failed to execute."); + + hr = HRESULT_FROM_WIN32(dwExitCode); + ExitOnFailure(hr, "Command line returned an error."); + +LExit: + return hr; +} + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/strutil.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/strutil.h new file mode 100644 index 0000000000..151003329e --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/strutil.h @@ -0,0 +1,165 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once +//------------------------------------------------------------------------------------------------- +// +// Header for string helper functions. +// +//------------------------------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +#define ReleaseStr(pwz) if (pwz) { StrFree(pwz); } +#define ReleaseNullStr(pwz) if (pwz) { StrFree(pwz); pwz = NULL; } +#define ReleaseBSTR(bstr) if (bstr) { ::SysFreeString(bstr); } +#define ReleaseNullBSTR(bstr) if (bstr) { ::SysFreeString(bstr); bstr = NULL; } + +HRESULT DAPI StrAlloc( + __inout LPWSTR* ppwz, + __in DWORD_PTR cch + ); +HRESULT DAPI StrAnsiAlloc( + __inout LPSTR* ppz, + __in DWORD_PTR cch + ); +HRESULT DAPI StrAllocString( + __inout LPWSTR* ppwz, + __in LPCWSTR wzSource, + __in DWORD_PTR cchSource + ); +HRESULT DAPI StrAnsiAllocString( + __inout LPSTR* ppsz, + __in LPCWSTR wzSource, + __in DWORD_PTR cchSource, + __in UINT uiCodepage + ); +HRESULT DAPI StrAllocStringAnsi( + __inout LPWSTR* ppwz, + __in LPCSTR szSource, + __in DWORD_PTR cchSource, + __in UINT uiCodepage + ); +HRESULT DAPI StrAllocPrefix( + __inout LPWSTR* ppwz, + __in LPCWSTR wzPrefix, + __in DWORD_PTR cchPrefix + ); +HRESULT DAPI StrAllocConcat( + __inout LPWSTR* ppwz, + __in LPCWSTR wzSource, + __in DWORD_PTR cchSource + ); +HRESULT __cdecl StrAllocFormatted( + __inout LPWSTR* ppwz, + __in LPCWSTR wzFormat, + ... + ); +HRESULT __cdecl StrAnsiAllocFormatted( + __inout LPSTR* ppsz, + __in LPCSTR szFormat, + ... + ); +HRESULT DAPI StrAllocFormattedArgs( + __inout LPWSTR* ppwz, + __in LPCWSTR wzFormat, + __in va_list args + ); +HRESULT DAPI StrAnsiAllocFormattedArgs( + __inout LPSTR* ppsz, + __in LPCSTR szFormat, + __in va_list args + ); + +HRESULT DAPI StrMaxLength( + __in LPVOID p, + __out DWORD_PTR* pcch + ); +HRESULT DAPI StrSize( + __in LPVOID p, + __out DWORD_PTR* pcb + ); + +HRESULT DAPI StrFree( + __in LPVOID p + ); + +HRESULT DAPI StrCurrentTime( + __inout LPWSTR* ppwz, + __in BOOL fGMT + ); +HRESULT DAPI StrCurrentDateTime( + __inout LPWSTR* ppwz, + __in BOOL fGMT + ); + +HRESULT DAPI StrHexEncode( + __in_ecount(cbSource) const BYTE* pbSource, + __in DWORD_PTR cbSource, + __out_ecount(cchDest) LPWSTR wzDest, + __in DWORD_PTR cchDest + ); +HRESULT DAPI StrHexDecode( + __in LPCWSTR wzSource, + __out_bcount(cbDest) BYTE* pbDest, + __in DWORD_PTR cbDest + ); + +HRESULT DAPI StrAllocBase85Encode( + __in_bcount(cbSource) const BYTE* pbSource, + __in DWORD_PTR cbSource, + __inout LPWSTR* pwzDest + ); +HRESULT DAPI StrAllocBase85Decode( + __in LPCWSTR wzSource, + __out BYTE** hbDest, + __out DWORD_PTR* pcbDest + ); + +HRESULT DAPI MultiSzLen( + __in LPCWSTR pwzMultiSz, + __out DWORD_PTR* pcch + ); +HRESULT DAPI MultiSzPrepend( + __inout LPWSTR* ppwzMultiSz, + __inout_opt DWORD_PTR *pcchMultiSz, + __in LPCWSTR pwzInsert + ); +HRESULT DAPI MultiSzFindSubstring( + __in LPCWSTR pwzMultiSz, + __in LPCWSTR pwzSubstring, + __out_opt DWORD_PTR* pdwIndex, + __out_opt LPCWSTR* ppwzFoundIn + ); +HRESULT DAPI MultiSzFindString( + __in LPCWSTR pwzMultiSz, + __in LPCWSTR pwzString, + __out DWORD_PTR* pdwIndex, + __out LPCWSTR* ppwzFound + ); +HRESULT DAPI MultiSzRemoveString( + __inout LPWSTR* ppwzMultiSz, + __in DWORD_PTR dwIndex + ); +HRESULT DAPI MultiSzInsertString( + __inout LPWSTR* ppwzMultiSz, + __inout_opt DWORD_PTR *pcchMultiSz, + __in DWORD_PTR dwIndex, + __in LPCWSTR pwzInsert + ); +HRESULT DAPI MultiSzReplaceString( + __inout LPWSTR* ppwzMultiSz, + __in DWORD_PTR dwIndex, + __in LPCWSTR pwzString + ); + +LPCWSTR wcsistr( + IN LPCWSTR wzString, + IN LPCWSTR wzCharSet + ); + +#ifdef __cplusplus +} +#endif diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcalog.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcalog.cpp new file mode 100644 index 0000000000..b162bd6152 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcalog.cpp @@ -0,0 +1,150 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +//------------------------------------------------------------------------------------------------- +// +// Windows Installer XML CustomAction utility library logging functions +// +//------------------------------------------------------------------------------------------------- + +#include "precomp.h" + + +/******************************************************************** + IsVerboseLogging() - internal helper function to detect if doing + verbose logging + +********************************************************************/ +static BOOL IsVerboseLogging() +{ + static int iVerbose = -1; + + if (0 > iVerbose) + { + iVerbose = WcaIsPropertySet("LOGVERBOSE"); + if (0 == iVerbose) // if the property wasn't set, check the registry to see if the logging policy was turned on + { + HKEY hkey = NULL; + WCHAR rgwc[16] = { 0 }; + DWORD cb = sizeof(rgwc); + if (ERROR_SUCCESS == ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Policies\\Microsoft\\Windows\\Installer", 0, KEY_QUERY_VALUE, &hkey)) + { + if (ERROR_SUCCESS == ::RegQueryValueExW(hkey, L"Logging", 0, NULL, reinterpret_cast(rgwc), &cb)) + { + for (LPCWSTR pwc = rgwc; (cb / sizeof(WCHAR)) > static_cast(pwc - rgwc) && *pwc; pwc++) + { + if (L'v' == *pwc || L'V' == *pwc) + { + iVerbose = 1; + break; + } + } + } + + ::RegCloseKey(hkey); + } + } + } + + Assert(iVerbose >= 0); + return (BOOL)iVerbose; +} + + +/******************************************************************** + WcaLog() - outputs trace and log info + +*******************************************************************/ +extern "C" void WcaLog( + __in LOGLEVEL llv, + __in const char* fmt, ... + ) +{ + static char szFmt[LOG_BUFFER]; + static char szBuf[LOG_BUFFER]; + static bool fInLogPrint = false; + + // prevent re-entrant logprints. (recursion issues between assert/logging code) + if (fInLogPrint) + return; + fInLogPrint = true; + + if (LOGMSG_STANDARD == llv || + (LOGMSG_VERBOSE == llv && IsVerboseLogging()) +#ifdef DEBUG + || LOGMSG_TRACEONLY == llv +#endif + ) + { + va_list args; + va_start(args, fmt); + + LPCSTR szLogName = WcaGetLogName(); + if (szLogName[0] != 0) + StringCchPrintfA(szFmt, countof(szFmt), "%s: %s", szLogName, fmt); + else + StringCchCopyA(szFmt, countof(szFmt), fmt); + + StringCchVPrintfA(szBuf, countof(szBuf), szFmt, args); + va_end(args); + +#ifdef DEBUG + // always write to the log in debug +#else + if (llv == LOGMSG_STANDARD || (llv == LOGMSG_VERBOSE && IsVerboseLogging())) +#endif + { + PMSIHANDLE hrec = MsiCreateRecord(1); + + ::MsiRecordSetStringA(hrec, 0, szBuf); + // TODO: Recursion on failure. May not be safe to assert from here. + WcaProcessMessage(INSTALLMESSAGE_INFO, hrec); + } + +#if DEBUG + StringCchCatA(szBuf, countof(szBuf), "\n"); + OutputDebugStringA(szBuf); +#endif + } + + fInLogPrint = false; + return; +} + + +/******************************************************************** + WcaDisplayAssert() - called before Assert() dialog shows + + NOTE: writes the assert string to the MSI log +********************************************************************/ +extern "C" BOOL WcaDisplayAssert( + __in LPCSTR sz + ) +{ + WcaLog(LOGMSG_STANDARD, "Debug Assert Message: %s", sz); + return TRUE; +} + + +/******************************************************************** + WcaLogError() - called before ExitOnXXX() macro exists the function + + NOTE: writes the hresult and error string to the MSI log +********************************************************************/ +extern "C" void WcaLogError( + __in HRESULT hr, + __in LPCSTR szMessage, + ... + ) +{ + char szBuffer[LOG_BUFFER]; + va_list dots; + + va_start(dots, szMessage); + StringCchVPrintfA(szBuffer, countof(szBuffer), szMessage, dots); + va_end(dots); + + // log the message if using Wca common layer + if (WcaIsInitialized()) + WcaLog(LOGMSG_STANDARD, "Error 0x%x: %s", hr, szBuffer); +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcascript.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcascript.cpp new file mode 100644 index 0000000000..b0a55946f9 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcascript.cpp @@ -0,0 +1,447 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +//------------------------------------------------------------------------------------------------- +// +// Windows Installer XML CustomAction utility library CaScript functions +// +//------------------------------------------------------------------------------------------------- + +#include "precomp.h" + + +static HRESULT CaScriptFileName( + __in WCA_ACTION action, + __in WCA_CASCRIPT script, + __in BOOL fImpersonated, + __in LPCWSTR wzScriptKey, + __out LPWSTR* pwzScriptName + ); + + +/******************************************************************** + WcaCaScriptCreateKey() - creates a unique script key for this + CustomAction. + +********************************************************************/ +extern "C" HRESULT WIXAPI WcaCaScriptCreateKey( + __out LPWSTR* ppwzScriptKey + ) +{ + AssertSz(WcaIsInitialized(), "WcaInitialize() should have been called before calling this function."); + HRESULT hr = S_OK; + + hr = StrAllocStringAnsi(ppwzScriptKey, WcaGetLogName(), 0, CP_ACP); + ExitOnFailure(hr, "Failed to create script key."); + +LExit: + return hr; +} + + +/******************************************************************** + WcaCaScriptCreate() - creates the appropriate script for this + CustomAction Script Key. + +********************************************************************/ +extern "C" HRESULT WIXAPI WcaCaScriptCreate( + __in WCA_ACTION action, + __in WCA_CASCRIPT script, + __in BOOL fImpersonated, + __in LPCWSTR wzScriptKey, + __in BOOL fAppend, + __in WCA_CASCRIPT_HANDLE* phScript + ) +{ + HRESULT hr = S_OK; + LPWSTR pwzScriptPath = NULL; + HANDLE hScriptFile = INVALID_HANDLE_VALUE; + + hr = CaScriptFileName(action, script, fImpersonated, wzScriptKey, &pwzScriptPath); + ExitOnFailure(hr, "Failed to calculate script file name."); + + hScriptFile = ::CreateFileW(pwzScriptPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, fAppend ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (INVALID_HANDLE_VALUE == hScriptFile) + { + ExitWithLastError1(hr, "Failed to open CaScript: %S", pwzScriptPath); + } + + if (fAppend && INVALID_SET_FILE_POINTER == ::SetFilePointer(hScriptFile, 0, NULL, FILE_END)) + { + ExitWithLastError(hr, "Failed to seek to end of file."); + } + + *phScript = reinterpret_cast(MemAlloc(sizeof(WCA_CASCRIPT_STRUCT), TRUE)); + ExitOnNull(*phScript, hr, E_OUTOFMEMORY, "Failed to allocate space for cascript handle."); + + (*phScript)->pwzScriptPath = pwzScriptPath; + pwzScriptPath = NULL; + (*phScript)->hScriptFile = hScriptFile; + hScriptFile = INVALID_HANDLE_VALUE; + +LExit: + if (INVALID_HANDLE_VALUE != hScriptFile) + { + ::CloseHandle(hScriptFile); + } + + ReleaseStr(pwzScriptPath); + return hr; +} + + +/******************************************************************** + WcaCaScriptOpen() - opens the appropriate script for this CustomAction + Script Key. + +********************************************************************/ +extern "C" HRESULT WIXAPI WcaCaScriptOpen( + __in WCA_ACTION action, + __in WCA_CASCRIPT script, + __in BOOL fImpersonated, + __in LPCWSTR wzScriptKey, + __in WCA_CASCRIPT_HANDLE* phScript + ) +{ + HRESULT hr = S_OK; + LPWSTR pwzScriptPath = NULL; + HANDLE hScriptFile = INVALID_HANDLE_VALUE; + + hr = CaScriptFileName(action, script, fImpersonated, wzScriptKey, &pwzScriptPath); + ExitOnFailure(hr, "Failed to calculate script file name."); + + hScriptFile = ::CreateFileW(pwzScriptPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (INVALID_HANDLE_VALUE == hScriptFile) + { + ExitWithLastError1(hr, "Failed to open CaScript: %S", pwzScriptPath); + } + + *phScript = reinterpret_cast(MemAlloc(sizeof(WCA_CASCRIPT_STRUCT), TRUE)); + ExitOnNull(*phScript, hr, E_OUTOFMEMORY, "Failed to allocate space for cascript handle."); + + (*phScript)->pwzScriptPath = pwzScriptPath; + pwzScriptPath = NULL; + (*phScript)->hScriptFile = hScriptFile; + hScriptFile = INVALID_HANDLE_VALUE; + +LExit: + if (INVALID_HANDLE_VALUE != hScriptFile) + { + ::CloseHandle(hScriptFile); + } + + ReleaseStr(pwzScriptPath); + return hr; +} + + +/******************************************************************** + WcaCaScriptClose() - closes an open script handle. + +********************************************************************/ +extern "C" void WIXAPI WcaCaScriptClose( + __in WCA_CASCRIPT_HANDLE hScript, + __in WCA_CASCRIPT_CLOSE closeOperation + ) +{ + if (hScript) + { + if (INVALID_HANDLE_VALUE != hScript->hScriptFile) + { + ::CloseHandle(hScript->hScriptFile); + } + + if (hScript->pwzScriptPath) + { + if (WCA_CASCRIPT_CLOSE_DELETE == closeOperation) + { + ::DeleteFileW(hScript->pwzScriptPath); + } + + StrFree(hScript->pwzScriptPath); + } + + MemFree(hScript); + } +} + + +/******************************************************************** + WcaCaScriptReadAsCustomActionData() - read the ca script into a format + that is useable by other CA data + functions. + +********************************************************************/ +extern "C" HRESULT WIXAPI WcaCaScriptReadAsCustomActionData( + __in WCA_CASCRIPT_HANDLE hScript, + __out LPWSTR* ppwzCustomActionData + ) +{ + HRESULT hr = S_OK; + LARGE_INTEGER liScriptSize = { 0 }; + BYTE* pbData = NULL; + DWORD cbData = 0; + + if (!::GetFileSizeEx(hScript->hScriptFile, &liScriptSize)) + { + ExitWithLastError(hr, "Failed to get size of ca script file."); + } + + if (0 != liScriptSize.HighPart || 0 != (liScriptSize.LowPart % sizeof(WCHAR))) + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + ExitOnFailure(hr, "Invalid data read from ca script."); + } + + cbData = liScriptSize.LowPart; + pbData = static_cast(MemAlloc(cbData, TRUE)); + ExitOnNull(pbData, hr, E_OUTOFMEMORY, "Failed to allocate memory to read in ca script."); + + if (INVALID_SET_FILE_POINTER == ::SetFilePointer(hScript->hScriptFile, 0, NULL, FILE_BEGIN)) + { + ExitWithLastError(hr, "Failed to reset to beginning of ca script."); + } + + DWORD cbTotalRead = 0; + DWORD cbRead = 0; + do + { + if (!::ReadFile(hScript->hScriptFile, pbData + cbTotalRead, cbData - cbTotalRead, &cbRead, NULL)) + { + ExitWithLastError(hr, "Failed to read from ca script."); + } + + cbTotalRead += cbRead; + } while (cbRead && cbTotalRead < cbData); + + if (cbTotalRead != cbData) + { + hr = E_UNEXPECTED; + ExitOnFailure(hr, "Failed to completely read ca script."); + } + + // Add one to the allocated space because the data stored in the script is not + // null terminated. After copying the memory over, we'll ensure the string is + // null terminated. + DWORD cchData = cbData / sizeof(WCHAR) + 1; + hr = StrAlloc(ppwzCustomActionData, cchData); + ExitOnFailure(hr, "Failed to copy ca script."); + + CopyMemory(*ppwzCustomActionData, pbData, cbData); + (*ppwzCustomActionData)[cchData - 1] = L'\0'; + +LExit: + ReleaseMem(pbData); + return hr; +} + + +/******************************************************************** + WcaCaScriptWriteString() - writes a string to the ca script. + +********************************************************************/ +extern "C" HRESULT WIXAPI WcaCaScriptWriteString( + __in WCA_CASCRIPT_HANDLE hScript, + __in LPCWSTR wzValue + ) +{ + HRESULT hr = S_OK; + DWORD cbFile = 0; + DWORD cbWrite = 0; + DWORD cbTotalWritten = 0; + WCHAR delim[] = { MAGIC_MULTISZ_DELIM }; // magic char followed by NULL terminator + + cbFile = ::SetFilePointer(hScript->hScriptFile, 0, NULL, FILE_END); + if (INVALID_SET_FILE_POINTER == cbFile) + { + ExitWithLastError(hr, "Failed to move file pointer to end of file."); + } + + // If there is existing data in the file, append on the magic delimeter + // before adding our new data on the end of the file. + if (0 < cbFile) + { + cbWrite = sizeof(delim); + cbTotalWritten = 0; + while (cbTotalWritten < cbWrite) + { + DWORD cbWritten = 0; + if (!::WriteFile(hScript->hScriptFile, reinterpret_cast(delim) + cbTotalWritten, cbWrite - cbTotalWritten, &cbWritten, NULL)) + { + ExitWithLastError(hr, "Failed to write data to ca script."); + } + + cbTotalWritten += cbWritten; + } + } + + cbWrite = lstrlenW(wzValue) * sizeof(WCHAR); + cbTotalWritten = 0; + while (cbTotalWritten < cbWrite) + { + DWORD cbWritten = 0; + if (!::WriteFile(hScript->hScriptFile, reinterpret_cast(wzValue) + cbTotalWritten, cbWrite - cbTotalWritten, &cbWritten, NULL)) + { + ExitWithLastError(hr, "Failed to write data to ca script."); + } + + cbTotalWritten += cbWritten; + } + +LExit: + return hr; +} + + +/******************************************************************** + WcaCaScriptWriteNumber() - writes a number to the ca script. + +********************************************************************/ +extern "C" HRESULT WIXAPI WcaCaScriptWriteNumber( + __in WCA_CASCRIPT_HANDLE hScript, + __in DWORD dwValue + ) +{ + HRESULT hr = S_OK; + WCHAR wzBuffer[13] = { 0 }; + + hr = ::StringCchPrintfW(wzBuffer, countof(wzBuffer), L"%u", dwValue); + ExitOnFailure(hr, "Failed to convert number into string."); + + hr = WcaCaScriptWriteString(hScript, wzBuffer); + ExitOnFailure(hr, "Failed to write number to script."); + +LExit: + return hr; +} + + +/******************************************************************** + WcaCaScriptFlush() - best effort function to get script written to + disk. + +********************************************************************/ +extern "C" void WIXAPI WcaCaScriptFlush( + __in WCA_CASCRIPT_HANDLE hScript + ) +{ + ::FlushFileBuffers(hScript->hScriptFile); +} + + +/******************************************************************** + WcaCaScriptCleanup() - best effort clean-up of any cascripts left + over from this install/uninstall. + +********************************************************************/ +extern "C" void WIXAPI WcaCaScriptCleanup( + __in LPCWSTR wzProductCode, + __in BOOL fImpersonated + ) +{ + HRESULT hr = S_OK; + WCHAR wzTempPath[MAX_PATH]; + LPWSTR pwzWildCardPath = NULL; + WIN32_FIND_DATAW fd = { 0 }; + HANDLE hff = INVALID_HANDLE_VALUE; + LPWSTR pwzDeletePath = NULL; + + if (fImpersonated) + { + if (!::GetTempPathW(countof(wzTempPath), wzTempPath)) + { + ExitWithLastError(hr, "Failed to get temp path."); + } + } + else + { + if (!::GetWindowsDirectoryW(wzTempPath, countof(wzTempPath))) + { + ExitWithLastError(hr, "Failed to get windows path."); + } + + hr = ::StringCchCatW(wzTempPath, countof(wzTempPath), L"\\Installer\\"); + ExitOnFailure(hr, "Failed to concat Installer directory on windows path string."); + } + + hr = StrAllocFormatted(&pwzWildCardPath, L"%swix%s.*.???", wzTempPath, wzProductCode); + ExitOnFailure(hr, "Failed to allocate wildcard path to ca scripts."); + + hff = ::FindFirstFileW(pwzWildCardPath, &fd); + if (INVALID_HANDLE_VALUE == hff) + { + ExitWithLastError1(hr, "Failed to find files with pattern: %S", pwzWildCardPath); + } + + do + { + hr = StrAllocFormatted(&pwzDeletePath, L"%s%s", wzTempPath, fd.cFileName); + if (SUCCEEDED(hr)) + { + if (!::DeleteFileW(pwzDeletePath)) + { + DWORD er = ::GetLastError(); + WcaLog(LOGMSG_VERBOSE, "Failed to clean up CAScript file: %S, er: %d", fd.cFileName, er); + } + } + else + { + WcaLog(LOGMSG_VERBOSE, "Failed to allocate path to clean up CAScript file: %S, hr: 0x%x", fd.cFileName, hr); + } + } while(::FindNextFileW(hff, &fd)); + +LExit: + if (INVALID_HANDLE_VALUE == hff) + { + ::FindClose(hff); + } + + ReleaseStr(pwzDeletePath); + ReleaseStr(pwzWildCardPath); + return; +} + + +static HRESULT CaScriptFileName( + __in WCA_ACTION action, + __in WCA_CASCRIPT script, + __in BOOL fImpersonated, + __in LPCWSTR wzScriptKey, + __out LPWSTR* ppwzScriptName + ) +{ + HRESULT hr = S_OK; + WCHAR wzTempPath[MAX_PATH]; + LPWSTR pwzProductCode = NULL; + WCHAR chInstallOrUninstall = action == WCA_ACTION_INSTALL ? L'i' : L'u'; + WCHAR chScheduledOrRollback = script == WCA_CASCRIPT_SCHEDULED ? L's' : L'r'; + WCHAR chUserOrMachine = fImpersonated ? L'u' : L'm'; + + if (fImpersonated) + { + if (!::GetTempPathW(countof(wzTempPath), wzTempPath)) + { + ExitWithLastError(hr, "Failed to get temp path."); + } + } + else + { + if (!::GetWindowsDirectoryW(wzTempPath, countof(wzTempPath))) + { + ExitWithLastError(hr, "Failed to get windows path."); + } + + hr = ::StringCchCatW(wzTempPath, countof(wzTempPath), L"\\Installer\\"); + ExitOnFailure(hr, "Failed to concat Installer directory on windows path string."); + } + + hr = WcaGetProperty(L"ProductCode", &pwzProductCode); + ExitOnFailure(hr, "Failed to get ProductCode."); + + hr = StrAllocFormatted(ppwzScriptName, L"%swix%s.%s.%c%c%c", wzTempPath, pwzProductCode, wzScriptKey, chScheduledOrRollback, chUserOrMachine, chInstallOrUninstall); + ExitOnFailure(hr, "Failed to allocate path to ca script."); + +LExit: + ReleaseStr(pwzProductCode); + return hr; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcautil.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcautil.cpp new file mode 100644 index 0000000000..5f7bbda74d --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcautil.cpp @@ -0,0 +1,201 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +//------------------------------------------------------------------------------------------------- +// +// Windows Installer XML CustomAction utility library. +// +//------------------------------------------------------------------------------------------------- + +#include "precomp.h" + +// globals +HMODULE g_hInstCADLL; + +// statics +static BOOL s_fInitialized; +static MSIHANDLE s_hInstall; +static MSIHANDLE s_hDatabase; +static char s_szCustomActionLogName[32]; +static UINT s_iRetVal; + + +/******************************************************************** + WcaGlobalInitialize() - initializes the Wca library, should be + called once per custom action Dll during + DllMain on DLL_PROCESS_ATTACH + +********************************************************************/ +extern "C" void WcaGlobalInitialize( + __in HINSTANCE hInst + ) +{ + g_hInstCADLL = hInst; + MemInitialize(); + + AssertSetModule(g_hInstCADLL); + AssertSetDisplayFunction(WcaDisplayAssert); +} + + +/******************************************************************** + WcaGlobalFinalize() - finalizes the Wca library, should be the + called once per custom action Dll during + DllMain on DLL_PROCESS_DETACH + +********************************************************************/ +extern "C" void WcaGlobalFinalize() +{ +#ifdef DEBUG + if (WcaIsInitialized()) + { + CHAR szBuf[2048]; + StringCchPrintfA(szBuf, countof(szBuf), "CustomAction %s called WcaInitialize() but not WcaTerminate()", WcaGetLogName()); + + AssertSz(FALSE, szBuf); + } +#endif + MemUninitialize(); + g_hInstCADLL = NULL; +} + + +/******************************************************************** + WcaInitialize() - initializes the Wca framework, should be the first + thing called by all CustomActions + +********************************************************************/ +extern "C" HRESULT WcaInitialize( + __in MSIHANDLE hInstall, + __in const char* szCustomActionLogName + ) +{ + // these statics should be called once per CustomAction invocation. + // Darwin does doesn't preserve DLL state across CustomAction calls so + // these should always be initialized to NULL. If that behavior changes + // we would need to do a careful review of all of our module/global data. + AssertSz(!s_fInitialized, "WcaInitialize() should only be called once per CustomAction"); + Assert(NULL == s_hInstall); + Assert(NULL == s_hDatabase); + Assert(0 == *s_szCustomActionLogName); + + HRESULT hr = S_OK; + + s_fInitialized = TRUE; + s_iRetVal = ERROR_SUCCESS; // assume all will go well + + s_hInstall = hInstall; + s_hDatabase = ::MsiGetActiveDatabase(s_hInstall); // may return null if deferred CustomAction + + hr = ::StringCchCopyA(s_szCustomActionLogName, countof(s_szCustomActionLogName), szCustomActionLogName); + ExitOnFailure1(hr, "Failed to copy CustomAction log name: %s", szCustomActionLogName); + + Assert(s_hInstall); +LExit: + if (FAILED(hr)) + { + if (s_hDatabase) + { + ::MsiCloseHandle(s_hDatabase); + s_hDatabase = NULL; + } + + s_hInstall = NULL; + s_fInitialized = FALSE; + } + + return hr; +} + + +/******************************************************************** + WcaFinalize() - cleans up after the Wca framework, should be the last + thing called by all CustomActions + +********************************************************************/ +extern "C" UINT WcaFinalize( + __in UINT iReturnValue + ) +{ + // clean up after our initialization + if (s_hDatabase) + { + ::MsiCloseHandle(s_hDatabase); + s_hDatabase = NULL; + } + + s_hInstall = NULL; + s_fInitialized = FALSE; + + // if no error occurred during the processing of the CusotmAction return the passed in return value + // otherwise return the previous failure + return (ERROR_SUCCESS == s_iRetVal) ? iReturnValue : s_iRetVal; +} + + +/******************************************************************** + WcaIsInitialized() - determines if WcaInitialize() has been called + +********************************************************************/ +extern "C" BOOL WcaIsInitialized() +{ + return s_fInitialized; +} + + +/******************************************************************** + WcaGetInstallHandle() - gets the handle to the active install session + +********************************************************************/ +extern "C" MSIHANDLE WcaGetInstallHandle() +{ + AssertSz(s_hInstall, "WcaInitialize() should be called before attempting to access the install handle."); + return s_hInstall; +} + + +/******************************************************************** + WcaGetDatabaseHandle() - gets the handle to the active database + + NOTE: this function can only be used in immediate CustomActions. + Deferred CustomActions do not have access to the active + database. +********************************************************************/ +extern "C" MSIHANDLE WcaGetDatabaseHandle() +{ + AssertSz(s_hDatabase, "WcaInitialize() should be called before attempting to access the install handle. Also note that deferred CustomActions do not have access to the active database."); + return s_hDatabase; +} + + +/******************************************************************** + WcaGetLogName() - gets the name of the CustomAction used in logging + +********************************************************************/ +extern "C" const char* WcaGetLogName() +{ + return s_szCustomActionLogName; +} + + +/******************************************************************** + WcaSetReturnValue() - sets the value to return from the CustomAction + +********************************************************************/ +extern "C" void WcaSetReturnValue( + __in UINT iReturnValue + ) +{ + s_iRetVal = iReturnValue; +} + + +/******************************************************************** + WcaCancelDetected() - determines if the user has canceled yet + + NOTE: returns true when WcaSetReturnValue() is set to ERROR_INSTALL_USEREXIT +********************************************************************/ +extern "C" BOOL WcaCancelDetected() +{ + return ERROR_INSTALL_USEREXIT == s_iRetVal; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcautil.h b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcautil.h new file mode 100644 index 0000000000..8265e27735 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcautil.h @@ -0,0 +1,344 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +#pragma once +//------------------------------------------------------------------------------------------------- +// +// Windows Installer XML CustomAction utility library. +// +//------------------------------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +#define WIXAPI __stdcall +#define ExitTrace WcaLogError +#define ExitTrace1 WcaLogError +#define ExitTrace2 WcaLogError +#define ExitTrace3 WcaLogError + +#include "dutil.h" + +#define MessageExitOnLastError(x, e, s) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { ExitTrace(x, "%s", s); WcaErrorMessage(e, x, MB_OK, 0); goto LExit; } } +#define MessageExitOnLastError1(x, e, f, s) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { ExitTrace1(x, f, s); WcaErrorMessage(e, x, MB_OK, 1, s); goto LExit; } } + +#define MessageExitOnFailure(x, e, s) if (FAILED(x)) { ExitTrace(x, "%s", s); WcaErrorMessage(e, x, INSTALLMESSAGE_ERROR | MB_OK, 0); goto LExit; } +#define MessageExitOnFailure1(x, e, f, s) if (FAILED(x)) { ExitTrace1(x, f, s); WcaErrorMessage(e, x, INSTALLMESSAGE_ERROR | MB_OK, 1, s); goto LExit; } +#define MessageExitOnFailure2(x, e, f, s, t) if (FAILED(x)) { ExitTrace2(x, f, s, t); WcaErrorMessage(e, x, INSTALLMESSAGE_ERROR | MB_OK, 2, s, t); goto LExit; } +#define MessageExitOnFailure3(x, e, f, s, t, u) if (FAILED(x)) { ExitTrace2(x, f, s, t, u); WcaErrorMessage(e, x, INSTALLMESSAGE_ERROR | MB_OK, 3, s, t, u); goto LExit; } + +#define MessageExitOnNullWithLastError(p, x, e, s) if (NULL == p) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (!FAILED(x)) { x = E_FAIL; } ExitTrace(x, "%s", s); WcaErrorMessage(e, x, MB_OK, 0); goto LExit; } +#define MessageExitOnNullWithLastError1(p, x, e, f, s) if (NULL == p) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (!FAILED(x)) { x = E_FAIL; } ExitTrace(x, f, s); WcaErrorMessage(e, x, MB_OK, 1, s); goto LExit; } +#define MessageExitOnNullWithLastError2(p, x, e, f, s, t) if (NULL == p) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (!FAILED(x)) { x = E_FAIL; } ExitTrace(x, f, s, t); WcaErrorMessage(e, x, MB_OK, 2, s, t); goto LExit; } + +#define MAX_DARWIN_KEY 73 +#define MAX_DARWIN_COLUMN 255 + +// Generic action enum. +enum WCA_ACTION +{ + WCA_ACTION_NONE, + WCA_ACTION_INSTALL, + WCA_ACTION_UNINSTALL, +}; + +enum WCA_CASCRIPT +{ + WCA_CASCRIPT_SCHEDULED, + WCA_CASCRIPT_ROLLBACK, +}; + +enum WCA_CASCRIPT_CLOSE +{ + WCA_CASCRIPT_CLOSE_PRESERVE, + WCA_CASCRIPT_CLOSE_DELETE, +}; + +typedef struct WCA_CASCRIPT_STRUCT +{ + LPWSTR pwzScriptPath; + HANDLE hScriptFile; +} *WCA_CASCRIPT_HANDLE; + +void WIXAPI WcaGlobalInitialize( + __in HINSTANCE hInst + ); +void WIXAPI WcaGlobalFinalize(); + +HRESULT WIXAPI WcaInitialize( + __in MSIHANDLE hInstall, + __in const char* szCustomActionLogName + ); +UINT WIXAPI WcaFinalize( + __in UINT iReturnValue + ); +BOOL WIXAPI WcaIsInitialized(); + +MSIHANDLE WIXAPI WcaGetInstallHandle(); +MSIHANDLE WIXAPI WcaGetDatabaseHandle(); + +const char* WIXAPI WcaGetLogName(); + +void WIXAPI WcaSetReturnValue( + __in UINT iReturnValue + ); +BOOL WIXAPI WcaCancelDetected(); + +const int LOG_BUFFER = 2048; +enum LOGLEVEL +{ + LOGMSG_TRACEONLY, // Never written to the log file (except in DEBUG builds) + LOGMSG_VERBOSE, // Written to log when LOGVERBOSE + LOGMSG_STANDARD // Written to log whenever informational logging is enabled +}; + +void __cdecl WcaLog( + __in LOGLEVEL llv, + __in const char* fmt, ... + ); +BOOL WIXAPI WcaDisplayAssert( + __in LPCSTR sz + ); +void __cdecl WcaLogError( + __in HRESULT hr, + __in LPCSTR szMessage, + ... + ); + + +UINT WIXAPI WcaProcessMessage( + __in INSTALLMESSAGE eMessageType, + __in MSIHANDLE hRecord + ); +UINT __cdecl WcaErrorMessage( + __in int iError, + __in HRESULT hrError, + __in UINT uiType, + __in DWORD cArgs, + ... + ); +HRESULT WIXAPI WcaProgressMessage( + __in UINT uiCost, + __in BOOL fExtendProgressBar + ); + +BOOL WIXAPI WcaIsInstalling( + __in INSTALLSTATE isInstalled, + __in INSTALLSTATE isAction + ); +BOOL WIXAPI WcaIsReInstalling( + __in INSTALLSTATE isInstalled, + __in INSTALLSTATE isAction + ); +BOOL WIXAPI WcaIsUninstalling( + __in INSTALLSTATE isInstalled, + __in INSTALLSTATE isAction + ); + +HRESULT WIXAPI WcaSetComponentState( + __in LPCWSTR wzComponent, + __in INSTALLSTATE isState + ); + +HRESULT WIXAPI WcaTableExists( + __in LPCWSTR wzTable + ); + +HRESULT WIXAPI WcaOpenView( + __in LPCWSTR wzSql, + __out MSIHANDLE* phView + ); +HRESULT WIXAPI WcaExecuteView( + __in MSIHANDLE hView, + __in MSIHANDLE hRec + ); +HRESULT WIXAPI WcaOpenExecuteView( + __in LPCWSTR wzSql, + __out MSIHANDLE* phView + ); +HRESULT WIXAPI WcaFetchRecord( + __in MSIHANDLE hView, + __out MSIHANDLE* phRec + ); +HRESULT WIXAPI WcaFetchSingleRecord( + __in MSIHANDLE hView, + __out MSIHANDLE* phRec + ); + +HRESULT WIXAPI WcaGetProperty( + __in LPCWSTR wzProperty, + __inout LPWSTR* ppwzData + ); +HRESULT WIXAPI WcaGetFormattedProperty( + __in LPCWSTR wzProperty, + __out LPWSTR* ppwzData + ); +HRESULT WIXAPI WcaGetFormattedString( + __in LPCWSTR wzString, + __out LPWSTR* ppwzData + ); +HRESULT WIXAPI WcaGetIntProperty( + __in LPCWSTR wzProperty, + __inout int* piData + ); +HRESULT WIXAPI WcaGetTargetPath( + __in LPCWSTR wzFolder, + __out LPWSTR* ppwzData + ); +HRESULT WIXAPI WcaSetProperty( + __in LPCWSTR wzPropertyName, + __in LPCWSTR wzPropertyValue + ); +HRESULT WIXAPI WcaSetIntProperty( + __in LPCWSTR wzPropertyName, + __in int nPropertyValue + ); +BOOL WIXAPI WcaIsPropertySet( + __in LPCSTR szProperty + ); + +HRESULT WIXAPI WcaGetRecordInteger( + __in MSIHANDLE hRec, + __in UINT uiField, + __inout int* piData + ); +HRESULT WIXAPI WcaGetRecordString( + __in MSIHANDLE hRec, + __in UINT uiField, + __inout LPWSTR* ppwzData + ); +HRESULT WIXAPI WcaGetRecordFormattedString( + __in MSIHANDLE hRec, + __in UINT uiField, + __inout LPWSTR* ppwzData + ); + +HRESULT WIXAPI WcaAllocStream(__inout BYTE** ppbData, __in DWORD cbData); +HRESULT WIXAPI WcaFreeStream(__in BYTE* pbData); + +HRESULT WIXAPI WcaGetRecordStream( + __in MSIHANDLE hRecBinary, + __in UINT uiField, + __inout BYTE** ppbData, + __inout DWORD* pcbData + ); +HRESULT WIXAPI WcaSetRecordString( + __in MSIHANDLE hRec, + __in UINT uiField, + __in LPCWSTR wzData + ); +HRESULT WIXAPI WcaSetRecordInteger( + __in MSIHANDLE hRec, + __in UINT uiField, + __in int iValue + ); + +HRESULT WIXAPI WcaDoDeferredAction( + __in LPCWSTR wzAction, + __in LPCWSTR wzCustomActionData, + __in UINT uiCost + ); +DWORD WIXAPI WcaCountOfCustomActionDataRecords( + __in LPCWSTR wzData + ); +HRESULT WIXAPI WcaReadStringFromCaData( + __inout LPWSTR* ppwzCustomActionData, + __inout LPWSTR* ppwzString + ); +HRESULT WIXAPI WcaReadIntegerFromCaData( + __inout LPWSTR* ppwzCustomActionData, + __inout int* piResult + ); +HRESULT WIXAPI WcaReadStreamFromCaData( + __inout LPWSTR* ppwzCustomActionData, + __out BYTE** ppbData, + __out DWORD_PTR* pcbData + ); +HRESULT WIXAPI WcaWriteStringToCaData( + __in LPCWSTR wzString, + __inout LPWSTR* ppwzCustomActionData + ); +HRESULT WIXAPI WcaWriteIntegerToCaData( + __in int i, + __inout LPWSTR* ppwzCustomActionData + ); +HRESULT WIXAPI WcaWriteStreamToCaData( + __in_bcount(cbData) const BYTE* pbData, + __in DWORD cbData, + __inout LPWSTR* ppwzCustomActionData + ); + +HRESULT __cdecl WcaAddTempRecord( + __inout MSIHANDLE* phTableView, + __inout MSIHANDLE* phColumns, + __in LPCWSTR wzTable, + __in UINT uiUniquifyColumn, + __in UINT cColumns, + ... + ); + +HRESULT WIXAPI WcaDumpTable( + __in LPCWSTR wzTable + ); + + +HRESULT WIXAPI WcaCaScriptCreateKey( + __out LPWSTR* ppwzScriptKey + ); + +HRESULT WIXAPI WcaCaScriptCreate( + __in WCA_ACTION action, + __in WCA_CASCRIPT script, + __in BOOL fImpersonated, + __in LPCWSTR wzScriptKey, + __in BOOL fAppend, + __out WCA_CASCRIPT_HANDLE* phScript + ); + +HRESULT WIXAPI WcaCaScriptOpen( + __in WCA_ACTION action, + __in WCA_CASCRIPT script, + __in BOOL fImpersonated, + __in LPCWSTR wzScriptKey, + __out WCA_CASCRIPT_HANDLE* phScript + ); + +void WIXAPI WcaCaScriptClose( + __in WCA_CASCRIPT_HANDLE hScript, + __in WCA_CASCRIPT_CLOSE closeOperation + ); + +HRESULT WIXAPI WcaCaScriptReadAsCustomActionData( + __in WCA_CASCRIPT_HANDLE hScript, + __out LPWSTR* ppwzCustomActionData + ); + +HRESULT WIXAPI WcaCaScriptWriteString( + __in WCA_CASCRIPT_HANDLE hScript, + __in LPCWSTR wzValue + ); + +HRESULT WIXAPI WcaCaScriptWriteNumber( + __in WCA_CASCRIPT_HANDLE hScript, + __in DWORD dwValue + ); + +void WIXAPI WcaCaScriptFlush( + __in WCA_CASCRIPT_HANDLE hScript + ); + +void WIXAPI WcaCaScriptCleanup( + __in LPCWSTR wzProductCode, + __in BOOL fImpersonated + ); + + +HRESULT QuietExec( + __in LPWSTR wzCommand, + __in DWORD dwTimeout + ); + +#ifdef __cplusplus +} +#endif diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcawrap.cpp b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcawrap.cpp new file mode 100644 index 0000000000..490a5d6713 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/IIS-Setup/wcautil/wcawrap.cpp @@ -0,0 +1,1419 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +//------------------------------------------------------------------------------------------------- +// +// Windows Installer XML CustomAction utility library wrappers for MSI API +// +//------------------------------------------------------------------------------------------------- + +#include "precomp.h" + + +/******************************************************************** + WcaProcessMessage() - sends a message from the CustomAction + +********************************************************************/ +extern "C" UINT WcaProcessMessage( + __in INSTALLMESSAGE eMessageType, + __in MSIHANDLE hRecord + ) +{ + UINT er = ::MsiProcessMessage(WcaGetInstallHandle(), eMessageType, hRecord); + if (ERROR_INSTALL_USEREXIT == er || IDCANCEL == er) + WcaSetReturnValue(ERROR_INSTALL_USEREXIT); + + return er; +} + + +/******************************************************************** + WcaErrorMessage() - sends an error message from the CustomAction using + the Error table + + NOTE: Any and all var_args (...) must be WCHAR* +********************************************************************/ +extern "C" UINT WcaErrorMessage( + __in int iError, + __in HRESULT hrError, + __in UINT uiType, + __in DWORD cArgs, + ... + ) +{ + UINT er; + MSIHANDLE hRec = NULL; + va_list args; + + uiType |= INSTALLMESSAGE_ERROR; // ensure error type is set + hRec = ::MsiCreateRecord(cArgs + 2); + if (!hRec) + { + er = ERROR_OUTOFMEMORY; + ExitOnFailure(HRESULT_FROM_WIN32(er), "failed to create record when sending error message"); + } + + er = ::MsiRecordSetInteger(hRec, 1, iError); + ExitOnFailure(HRESULT_FROM_WIN32(er), "failed to set error code into error message"); + + er = ::MsiRecordSetInteger(hRec, 2, hrError); + ExitOnFailure(HRESULT_FROM_WIN32(er), "failed to set hresult code into error message"); + + va_start(args, cArgs); + for (DWORD i = 0; i < cArgs; i++) + { + er = ::MsiRecordSetStringW(hRec, i + 3, va_arg(args, WCHAR*)); + ExitOnFailure(HRESULT_FROM_WIN32(er), "failed to set string string into error message"); + } + va_end(args); + + er = WcaProcessMessage(static_cast(uiType), hRec); +LExit: + if (hRec) + ::MsiCloseHandle(hRec); + + return er; +} + + +/******************************************************************** + WcaProgressMessage() - extends the progress bar or sends a progress + update from the CustomAction + +********************************************************************/ +extern "C" HRESULT WcaProgressMessage( + __in UINT uiCost, + __in BOOL fExtendProgressBar + ) +{ + static BOOL fExplicitProgressMessages = FALSE; + + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + MSIHANDLE hRec = ::MsiCreateRecord(3); + + // if aren't extending the progress bar and we haven't switched into explicit message mode + if (!fExtendProgressBar && !fExplicitProgressMessages) + { + AssertSz(::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_SCHEDULED) || + ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_COMMIT) || + ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK), "can only send progress bar messages in a deferred CustomAction"); + + // tell Darwin to use explicit progress messages + ::MsiRecordSetInteger(hRec, 1, 1); + ::MsiRecordSetInteger(hRec, 2, 1); + ::MsiRecordSetInteger(hRec, 3, 0); + + er = WcaProcessMessage(INSTALLMESSAGE_PROGRESS, hRec); + if (0 == er || IDOK == er || IDYES == er) + hr = S_OK; + else if (IDABORT == er || IDCANCEL == er) + { + WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit + ExitFunction1(hr = S_FALSE); + } + else + hr = E_UNEXPECTED; + ExitOnFailure(hr, "failed to tell Darwin to use explicit progress messages"); + + fExplicitProgressMessages = TRUE; + } +#if DEBUG + else if (fExtendProgressBar) // if we are extending the progress bar, make sure we're not deferred + { + AssertSz(!::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_SCHEDULED), "cannot add ticks to progress bar length from deferred CustomAction"); + } +#endif + + // send the progress message + ::MsiRecordSetInteger(hRec, 1, (fExtendProgressBar) ? 3 : 2); + ::MsiRecordSetInteger(hRec, 2, uiCost); + ::MsiRecordSetInteger(hRec, 3, 0); + + er = WcaProcessMessage(INSTALLMESSAGE_PROGRESS, hRec); + if (0 == er || IDOK == er || IDYES == er) + { + hr = S_OK; + } + else if (IDABORT == er || IDCANCEL == er) + { + WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit + hr = S_FALSE; + } + else + hr = E_UNEXPECTED; + +LExit: + if (hRec) + ::MsiCloseHandle(hRec); + + return hr; +} + + +/******************************************************************** + WcaIsInstalling() - determines if a pair of installstates means install + +********************************************************************/ +extern "C" BOOL WcaIsInstalling( + __in INSTALLSTATE isInstalled, + __in INSTALLSTATE isAction + ) +{ + return (INSTALLSTATE_LOCAL == isAction || + INSTALLSTATE_SOURCE == isAction || + (INSTALLSTATE_DEFAULT == isAction && + (INSTALLSTATE_LOCAL == isInstalled || + INSTALLSTATE_SOURCE == isInstalled))); +} + +/******************************************************************** + WcaIsReInstalling() - determines if a pair of installstates means install + +********************************************************************/ +extern "C" BOOL WcaIsReInstalling( + __in INSTALLSTATE isInstalled, + __in INSTALLSTATE isAction + ) +{ + return ((INSTALLSTATE_LOCAL == isAction || + INSTALLSTATE_SOURCE == isAction || + INSTALLSTATE_DEFAULT == isAction) && + (INSTALLSTATE_LOCAL == isInstalled || + INSTALLSTATE_SOURCE == isInstalled)); +} + + +/******************************************************************** + WcaIsUninstalling() - determines if a pair of installstates means uninstall + +********************************************************************/ +extern "C" BOOL WcaIsUninstalling( + __in INSTALLSTATE isInstalled, + __in INSTALLSTATE isAction + ) +{ + return ((INSTALLSTATE_ABSENT == isAction || + INSTALLSTATE_REMOVED == isAction) && + (INSTALLSTATE_LOCAL == isInstalled || + INSTALLSTATE_SOURCE == isInstalled)); +} + + +/******************************************************************** + WcaSetComponentState() - sets the install state of a Component + +********************************************************************/ +extern "C" HRESULT WcaSetComponentState( + __in LPCWSTR wzComponent, + __in INSTALLSTATE isState + ) +{ + UINT er = ::MsiSetComponentStateW(WcaGetInstallHandle(), wzComponent, isState); + if (ERROR_INSTALL_USEREXIT == er) + WcaSetReturnValue(er); + + return HRESULT_FROM_WIN32(er); +} + + +/******************************************************************** + WcaTableExists() - determines if installing database contains a table + +********************************************************************/ +extern "C" HRESULT WcaTableExists( + __in LPCWSTR wzTable + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + +// NOTE: The following line of commented out code should work in a +// CustomAction but does not in Windows Installer v1.1 + // er = ::MsiDatabaseIsTablePersistentW(hDatabase, wzTable); + + // a "most elegant" workaround a Darwin v1.1 bug + PMSIHANDLE hRec; + er = ::MsiDatabaseGetPrimaryKeysW(WcaGetDatabaseHandle(), wzTable, &hRec); + + if (ERROR_SUCCESS == er) + hr = S_OK; + else if (ERROR_INVALID_TABLE == er) + hr = S_FALSE; + else + hr = E_FAIL; + Assert(SUCCEEDED(hr)); + + return hr; +} + + +/******************************************************************** + WcaOpenView() - opens a view on the installing database + +********************************************************************/ +extern "C" HRESULT WcaOpenView( + __in LPCWSTR wzSql, + __out MSIHANDLE* phView + ) +{ + if (!wzSql || !*wzSql|| !phView) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er = ::MsiDatabaseOpenViewW(WcaGetDatabaseHandle(), wzSql, phView); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "failed to open view on database with SQL: %S", wzSql); + +LExit: + return hr; +} + + +/******************************************************************** + WcaExecuteView() - executes a parameterized open view on the installing database + +********************************************************************/ +extern "C" HRESULT WcaExecuteView( + __in MSIHANDLE hView, + __in MSIHANDLE hRec + ) +{ + if (!hView) + return E_INVALIDARG; + AssertSz(hRec, "Use WcaOpenExecuteView() if you don't need to pass in a record"); + + HRESULT hr = S_OK; + UINT er = ::MsiViewExecute(hView, hRec); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to execute view"); + +LExit: + return hr; +} + + +/******************************************************************** + WcaOpenExecuteView() - opens and executes a view on the installing database + +********************************************************************/ +extern "C" HRESULT WcaOpenExecuteView( + __in LPCWSTR wzSql, + __out MSIHANDLE* phView + ) +{ + if (!wzSql || !*wzSql|| !phView) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er = ::MsiDatabaseOpenViewW(WcaGetDatabaseHandle(), wzSql, phView); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to open view on database"); + + er = ::MsiViewExecute(*phView, NULL); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to execute view"); + +LExit: + return hr; +} + + +/******************************************************************** + WcaFetchRecord() - gets the next record from a view on the installing database + +********************************************************************/ +extern "C" HRESULT WcaFetchRecord( + __in MSIHANDLE hView, + __out MSIHANDLE* phRec + ) +{ + if (!hView|| !phRec) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er = ::MsiViewFetch(hView, phRec); + hr = HRESULT_FROM_WIN32(er); + if (FAILED(hr) && E_NOMOREITEMS != hr) + ExitOnFailure(hr, "failed to fetch record from view"); + +LExit: + return hr; +} + + +/******************************************************************** + WcaFetchSingleRecord() - gets a single record from a view on the installing database + +********************************************************************/ +extern "C" HRESULT WcaFetchSingleRecord( + __in MSIHANDLE hView, + __out MSIHANDLE* phRec + ) +{ + if (!hView|| !phRec) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er = ::MsiViewFetch(hView, phRec); + if (ERROR_NO_MORE_ITEMS == er) + hr = S_FALSE; + else + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to fetch single record from view"); + +#ifdef DEBUG // only do this in debug to verify that a single record was returned + MSIHANDLE hRecTest; + er = ::MsiViewFetch(hView, &hRecTest); + AssertSz(ERROR_NO_MORE_ITEMS == er && NULL == hRecTest, "WcaSingleFetch() did not fetch a single record"); + ::MsiCloseHandle(hRecTest); +#endif + +LExit: + return hr; +} + + +/******************************************************************** + WcaGetProperty - gets a string property value from the active install + +********************************************************************/ +extern "C" HRESULT WcaGetProperty( + __in LPCWSTR wzProperty, + __inout LPWSTR* ppwzData + ) +{ + if (!wzProperty || !*wzProperty || !ppwzData) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + DWORD_PTR cch = 0; + + if (!*ppwzData) + { + er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, L"", (DWORD *)&cch); + if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) + { + hr = StrAlloc(ppwzData, ++cch); + } + else + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "Failed to allocate string for Property '%S'", wzProperty); + } + else + { + hr = StrMaxLength(*ppwzData, &cch); + ExitOnFailure(hr, "Failed to get previous size of property data string."); + } + + er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, *ppwzData, (DWORD *)&cch); + if (ERROR_MORE_DATA == er) + { + Assert(*ppwzData); + hr = StrAlloc(ppwzData, ++cch); + ExitOnFailure1(hr, "Failed to allocate string for Property '%S'", wzProperty); + + er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, *ppwzData, (DWORD *)&cch); + } + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "Failed to get data for property '%S'", wzProperty); + +LExit: + return hr; +} + + +/******************************************************************** + WcaGetFormattedProperty - gets a formatted string property value from + the active install + +********************************************************************/ +extern "C" HRESULT WcaGetFormattedProperty( + __in LPCWSTR wzProperty, + __out LPWSTR* ppwzData + ) +{ + if (!wzProperty || !*wzProperty || !ppwzData) + return E_INVALIDARG; + + HRESULT hr = S_OK; + LPWSTR pwzPropertyValue = NULL; + + + hr = WcaGetProperty(wzProperty, &pwzPropertyValue); + ExitOnFailure1(hr, "failed to get %S", wzProperty); + + hr = WcaGetFormattedString(pwzPropertyValue, ppwzData); + ExitOnFailure2(hr, "failed to get formatted value for property: '%S' with value: '%S'", wzProperty, pwzPropertyValue); + +LExit: + ReleaseStr(pwzPropertyValue); + return hr; +} + + +/******************************************************************** + WcaGetFormattedString - gets a formatted string value from + the active install + +********************************************************************/ +extern "C" HRESULT WcaGetFormattedString( + __in LPCWSTR wzString, + __out LPWSTR* ppwzData + ) +{ + if (!wzString || !*wzString || !ppwzData) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + PMSIHANDLE hRecord = ::MsiCreateRecord(1); + DWORD_PTR cch = 0; + + er = ::MsiRecordSetStringW(hRecord, 0, wzString); + ExitOnFailure1(hr = HRESULT_FROM_WIN32(er), "Failed to set record field 0 with '%S'", wzString); + + if (!*ppwzData) + { + er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecord, L"", (DWORD *)&cch); + if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) + { + hr = StrAlloc(ppwzData, ++cch); + } + else + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "Failed to allocate string for formatted string: '%S'", wzString); + } + else + { + hr = StrMaxLength(*ppwzData, &cch); + ExitOnFailure(hr, "Failed to get previous size of property data string"); + } + + er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecord, *ppwzData, (DWORD *)&cch); + if (ERROR_MORE_DATA == er) + { + hr = StrAlloc(ppwzData, ++cch); + ExitOnFailure1(hr, "Failed to allocate string for formatted string: '%S'", wzString); + + er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecord, *ppwzData, (DWORD *)&cch); + } + ExitOnFailure1(hr = HRESULT_FROM_WIN32(er), "Failed to get formatted string: '%S'", wzString); + +LExit: + return hr; +} + + +/******************************************************************** + WcaGetIntProperty - gets an integer property value from the active install + +********************************************************************/ +extern "C" HRESULT WcaGetIntProperty( + __in LPCWSTR wzProperty, + __inout int* piData + ) +{ + if (!piData) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er; + + WCHAR wzValue[32]; + DWORD cch = countof(wzValue) - 1; + + er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, wzValue, &cch); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "Failed to get data for property '%S'", wzProperty); + + *piData = wcstol(wzValue, NULL, 10); + +LExit: + return hr; +} + + +/******************************************************************** + WcaGetTargetPath - gets the target path for a specified folder + +********************************************************************/ +extern "C" HRESULT WcaGetTargetPath( + __in LPCWSTR wzFolder, + __out LPWSTR* ppwzData + ) +{ + if (!wzFolder || !*wzFolder || !ppwzData) + return E_INVALIDARG; + + HRESULT hr = S_OK; + + UINT er = ERROR_SUCCESS; + DWORD_PTR cch = 0; + + if (!*ppwzData) + { + er = ::MsiGetTargetPathW(WcaGetInstallHandle(), wzFolder, L"", (DWORD*)&cch); + if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) + { + cch++; //Add one for the null terminator + hr = StrAlloc(ppwzData, cch); + } + else + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "Failed to allocate string for target path of folder: '%S'", wzFolder); + } + else + { + hr = StrMaxLength(*ppwzData, &cch); + ExitOnFailure(hr, "Failed to get previous size of string"); + } + + er = ::MsiGetTargetPathW(WcaGetInstallHandle(), wzFolder, *ppwzData, (DWORD*)&cch); + if (ERROR_MORE_DATA == er) + { + cch++; + hr = StrAlloc(ppwzData, cch); + ExitOnFailure1(hr, "Failed to allocate string for target path of folder: '%S'", wzFolder); + + er = ::MsiGetTargetPathW(WcaGetInstallHandle(), wzFolder, *ppwzData, (DWORD*)&cch); + } + ExitOnFailure1(hr = HRESULT_FROM_WIN32(er), "Failed to get target path for folder '%S'", wzFolder); + +LExit: + return hr; +} + + +/******************************************************************** + WcaSetProperty - sets a string property value in the active install + +********************************************************************/ +extern "C" HRESULT WcaSetProperty( + __in LPCWSTR wzPropertyName, + __in LPCWSTR wzPropertyValue + ) +{ + if (!wzPropertyName || !*wzPropertyName || !wzPropertyValue) + return E_INVALIDARG; + + UINT er = ::MsiSetPropertyW(WcaGetInstallHandle(), wzPropertyName, wzPropertyValue); + HRESULT hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "failed to set property: %S", wzPropertyName); + +LExit: + return hr; +} + + +/******************************************************************** + WcaSetIntProperty - sets a integer property value in the active install + +********************************************************************/ +extern "C" HRESULT WcaSetIntProperty( + __in LPCWSTR wzPropertyName, + __in int nPropertyValue + ) +{ + if (!wzPropertyName || !*wzPropertyName) + return E_INVALIDARG; + + // 12 characters should be enough for a 32-bit int: 10 digits, 1 sign, 1 null + WCHAR wzPropertyValue[13]; + HRESULT hr = StringCchPrintfW(wzPropertyValue, countof(wzPropertyValue), L"%d", nPropertyValue); + ExitOnFailure1(hr, "failed to convert into string property value: %d", nPropertyValue); + + UINT er = ::MsiSetPropertyW(WcaGetInstallHandle(), wzPropertyName, wzPropertyValue); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "failed to set property: %S", wzPropertyName); + +LExit: + return hr; +} + + +/******************************************************************** + WcaIsPropertySet() - returns TRUE if property is set + +********************************************************************/ +extern "C" BOOL WcaIsPropertySet( + __in LPCSTR szProperty + ) +{ + DWORD cchProperty = 0; + UINT er = ::MsiGetPropertyA(WcaGetInstallHandle(), szProperty, "", &cchProperty); + AssertSz(ERROR_INVALID_PARAMETER != er && ERROR_INVALID_HANDLE != er, "Unexpected return value from ::MsiGetProperty()"); + + return 0 < cchProperty; // property is set if the length is greater than zero +} + + +/******************************************************************** + WcaGetRecordInteger() - gets an integer field out of a record + + NOTE: returns S_FALSE if the field was null +********************************************************************/ +extern "C" HRESULT WcaGetRecordInteger( + __in MSIHANDLE hRec, + __in UINT uiField, + __inout int* piData + ) +{ + if (!hRec || !piData) + return E_INVALIDARG; + + HRESULT hr = S_OK; + *piData = ::MsiRecordGetInteger(hRec, uiField); + if (MSI_NULL_INTEGER == *piData) + hr = S_FALSE; + +//LExit: + return hr; +} + + +/******************************************************************** + WcaGetRecordString() - gets a string field out of a record + +********************************************************************/ +extern "C" HRESULT WcaGetRecordString( + __in MSIHANDLE hRec, + __in UINT uiField, + __inout LPWSTR* ppwzData + ) +{ + if (!hRec || !ppwzData) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er; + DWORD_PTR cch = 0; + + if (!*ppwzData) + { + er = ::MsiRecordGetStringW(hRec, uiField, L"", (DWORD*)&cch); + if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) + { + hr = StrAlloc(ppwzData, ++cch); + } + else + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "Failed to allocate memory for record string"); + } + else + { + hr = StrMaxLength(*ppwzData, &cch); + ExitOnFailure(hr, "Failed to get previous size of string"); + } + + er = ::MsiRecordGetStringW(hRec, uiField, *ppwzData, (DWORD*)&cch); + if (ERROR_MORE_DATA == er) + { + hr = StrAlloc(ppwzData, ++cch); + ExitOnFailure(hr, "Failed to allocate memory for record string"); + + er = ::MsiRecordGetStringW(hRec, uiField, *ppwzData, (DWORD*)&cch); + } + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "Failed to get string from record"); + +LExit: + return hr; +} + + +/******************************************************************** + HideNulls() - internal helper function to escape [~] in formatted strings + +********************************************************************/ +static void HideNulls( + __in LPWSTR wzData + ) +{ + LPWSTR pwz = wzData; + + while(*pwz) + { + if (pwz[0] == L'[' && pwz[1] == L'~' && pwz[2] == L']') // found a null [~] + { + pwz[0] = L'!'; // turn it into !$! + pwz[1] = L'$'; + pwz[2] = L'!'; + pwz += 3; + } + else + pwz++; + } +} + + +/******************************************************************** + RevealNulls() - internal helper function to unescape !$! in formatted strings + +********************************************************************/ +static void RevealNulls( + __in LPWSTR wzData + ) +{ + LPWSTR pwz = wzData; + + while(*pwz) + { + if (pwz[0] == L'!' && pwz[1] == L'$' && pwz[2] == L'!') // found the fake null !$! + { + pwz[0] = L'['; // turn it back into [~] + pwz[1] = L'~'; + pwz[2] = L']'; + pwz += 3; + } + else + pwz++; + } +} + + +/******************************************************************** + WcaGetRecordFormattedString() - gets formatted string filed from record + +********************************************************************/ +extern "C" HRESULT WcaGetRecordFormattedString( + __in MSIHANDLE hRec, + __in UINT uiField, + __inout LPWSTR* ppwzData + ) +{ + if (!hRec || !ppwzData) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er; + DWORD_PTR cch = 0; + PMSIHANDLE hRecFormat; + + // get the format string + hr = WcaGetRecordString(hRec, uiField, ppwzData); + ExitOnFailure(hr, "failed to get string from record"); + + if (!**ppwzData) + ExitFunction(); + + // hide the nulls '[~]' so we can get them back after formatting + HideNulls(*ppwzData); + + // set up the format record + hRecFormat = ::MsiCreateRecord(1); + ExitOnNull(hRecFormat, hr, E_UNEXPECTED, "Failed to create record to format string"); + hr = WcaSetRecordString(hRecFormat, 0, *ppwzData); + ExitOnFailure(hr, "failed to set string to format record"); + + // format the string + hr = StrMaxLength(*ppwzData, &cch); + ExitOnFailure(hr, "failed to get max length of string"); + + er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecFormat, *ppwzData, (DWORD*)&cch); + if (ERROR_MORE_DATA == er) + { + hr = StrAlloc(ppwzData, ++cch); + ExitOnFailure(hr, "Failed to allocate memory for record string"); + + er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecFormat, *ppwzData, (DWORD*)&cch); + } + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "Failed to format string"); + + // put the nulls back + RevealNulls(*ppwzData); + +LExit: + return hr; +} + + +/******************************************************************** + WcaAllocStream() - creates a byte stream of the specified size + + NOTE: Use WcaFreeStream() to release the byte stream +********************************************************************/ +extern "C" HRESULT WcaAllocStream( + __inout BYTE** ppbData, + __in DWORD cbData + ) +{ + Assert(ppbData); + HRESULT hr; + BYTE* pbNewData; + + if (*ppbData) + pbNewData = (BYTE*)MemReAlloc(*ppbData, cbData, TRUE); + else + pbNewData = (BYTE*)MemAlloc(cbData, TRUE); + + if (!pbNewData) + ExitOnLastError(hr, "Failed to allocate string"); + *ppbData = pbNewData; + pbNewData = NULL; + + hr = S_OK; +LExit: + if (pbNewData) + MemFree(pbNewData); + + return hr; +} + + +/******************************************************************** + WcaFreeStream() - frees a byte stream + +********************************************************************/ +extern "C" HRESULT WcaFreeStream( + __in BYTE* pbData + ) +{ + if (!pbData) + return E_INVALIDARG; + + HRESULT hr = MemFree(pbData); + return hr; +} + + +/******************************************************************** + WcaReadRecordStream() - gets a byte stream field from record + +********************************************************************/ +extern "C" HRESULT WcaGetRecordStream( + __in MSIHANDLE hRecBinary, + __in UINT uiField, + __inout BYTE** ppbData, + __inout DWORD* pcbData + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + if (!hRecBinary || !ppbData || !pcbData) + return E_INVALIDARG; + + *pcbData = 0; + er = ::MsiRecordReadStream(hRecBinary, uiField, NULL, pcbData); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to get size of stream"); + + hr = WcaAllocStream(ppbData, *pcbData); + ExitOnFailure(hr, "failed to allocate data for stream"); + + er = ::MsiRecordReadStream(hRecBinary, uiField, (char*)*ppbData, pcbData); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to read from stream"); + +LExit: + return hr; +} + + +/******************************************************************** + WcaSetRecordString() - set a string field in record + +********************************************************************/ +extern "C" HRESULT WcaSetRecordString( + __in MSIHANDLE hRec, + __in UINT uiField, + __in LPCWSTR wzData + ) +{ + if (!hRec || !wzData) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er = ::MsiRecordSetStringW(hRec, uiField, wzData); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to set string in record"); + +LExit: + return hr; +} + + +/******************************************************************** + WcaSetRecordInteger() - set a integer field in record + +********************************************************************/ +extern "C" HRESULT WcaSetRecordInteger( + __in MSIHANDLE hRec, + __in UINT uiField, + __in int iValue + ) +{ + if (!hRec) + return E_INVALIDARG; + + HRESULT hr = S_OK; + UINT er = ::MsiRecordSetInteger(hRec, uiField, iValue); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to set integer in record"); + +LExit: + return hr; +} + + +/******************************************************************** + + WcaDoDeferredAction() - schedules an action at this point in the script + +********************************************************************/ +extern "C" HRESULT WcaDoDeferredAction( + __in LPCWSTR wzAction, + __in LPCWSTR wzCustomActionData, + __in UINT uiCost + ) +{ + HRESULT hr = S_OK; + UINT er; + + if (wzCustomActionData && *wzCustomActionData) + { + er = ::MsiSetPropertyW(WcaGetInstallHandle(), wzAction, wzCustomActionData); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "Failed to set CustomActionData for deferred action"); + } + + if (0 < uiCost) + { + hr = WcaProgressMessage(uiCost, TRUE); // add ticks to the progress bar + // TODO: handle the return codes correctly + } + + er = ::MsiDoActionW(WcaGetInstallHandle(), wzAction); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "Failed MsiDoAction on deferred action"); + +LExit: + return hr; +} + + +/******************************************************************** + WcaCountOfCustomActionDataRecords() - counts the number of records + passed to a deferred CustomAction + +********************************************************************/ +extern "C" DWORD WcaCountOfCustomActionDataRecords( + __in LPCWSTR wzData + ) +{ + if (!wzData) + return E_INVALIDARG; + + WCHAR delim[] = {MAGIC_MULTISZ_DELIM, 0}; // magic char followed by NULL terminator + DWORD dwCount = 0; + + // Loop through until there are no delimiters, we are at the end of the string, or the delimiter is the last character in the string + for (LPCWSTR pwzCurrent = wzData; pwzCurrent && *pwzCurrent && *(pwzCurrent + 1); pwzCurrent = wcsstr(pwzCurrent, delim)) + { + dwCount++; + pwzCurrent++; + } + + return dwCount; +} + + +/******************************************************************** + BreakDownCustomActionData() - internal helper to chop up CustomActionData + + NOTE: this modifies the passed in data +********************************************************************/ +static LPWSTR BreakDownCustomActionData( + __inout LPWSTR* ppwzData + ) +{ + if (!ppwzData) + return NULL; + if (0 == *ppwzData) + return NULL; + + WCHAR delim[] = {MAGIC_MULTISZ_DELIM, 0}; // magic char followed by Null terminator + + LPWSTR pwzReturn = *ppwzData; + LPWSTR pwz = wcsstr(pwzReturn, delim); + if (pwz) + { + *pwz = 0; + *ppwzData = pwz + 1; + } + else + *ppwzData = 0; + + return pwzReturn; +} + + +/******************************************************************** + WcaReadStringFromCaData() - reads a string out of the CustomActionData + + NOTE: this modifies the passed in ppwzCustomActionData variable +********************************************************************/ +extern "C" HRESULT WcaReadStringFromCaData( + __inout LPWSTR* ppwzCustomActionData, + __inout LPWSTR* ppwzString + ) +{ + HRESULT hr = S_OK; + + LPCWSTR pwz = BreakDownCustomActionData(ppwzCustomActionData); + if (!pwz) + return E_NOMOREITEMS; + + hr = StrAllocString(ppwzString, pwz, 0); + ExitOnFailure(hr, "failed to allocate memory for string"); + + hr = S_OK; +LExit: + return hr; +} + + +/******************************************************************** + WcaReadIntegerFromCaData() - reads an integer out of the CustomActionData + + NOTE: this modifies the passed in ppwzCustomActionData variable +********************************************************************/ +extern "C" HRESULT WcaReadIntegerFromCaData( + __inout LPWSTR* ppwzCustomActionData, + __inout int* piResult + ) +{ + LPCWSTR pwz = BreakDownCustomActionData(ppwzCustomActionData); + if (!pwz) + return E_NOMOREITEMS; + + *piResult = wcstol(pwz, NULL, 10); + return S_OK; +} + + +/******************************************************************** + WcaReadStreamFromCaData() - reads a stream out of the CustomActionData + + NOTE: this modifies the passed in ppwzCustomActionData variable + NOTE: returned stream should be freed with WcaFreeStream() +********************************************************************/ +extern "C" HRESULT WcaReadStreamFromCaData( + __inout LPWSTR* ppwzCustomActionData, + __out BYTE** ppbData, + __out DWORD_PTR* pcbData + ) +{ + HRESULT hr; + + LPCWSTR pwz = BreakDownCustomActionData(ppwzCustomActionData); + if (!pwz) + return E_NOMOREITEMS; + + hr = StrAllocBase85Decode(pwz, ppbData, pcbData); + ExitOnFailure(hr, "failed to decode string into stream"); + +LExit: + return hr; +} + + +/******************************************************************** + WcaWriteStringToCaData() - adds a string to the CustomActionData to + feed a deferred CustomAction + +********************************************************************/ +extern "C" HRESULT WcaWriteStringToCaData( + __in LPCWSTR wzString, + __inout LPWSTR* ppwzCustomActionData + ) +{ + HRESULT hr = S_OK; + WCHAR delim[] = {MAGIC_MULTISZ_DELIM, 0}; // magic char followed by NULL terminator + + if (!ppwzCustomActionData) + return E_INVALIDARG; + + DWORD cchString = lstrlenW(wzString) + 1; // assume we'll be adding the delim + DWORD_PTR cchCustomActionData = 0; + + if (*ppwzCustomActionData) + { + hr = StrMaxLength(*ppwzCustomActionData, &cchCustomActionData); + ExitOnFailure(hr, "failed to get length of custom action data"); + } + + if ((cchCustomActionData - lstrlenW(*ppwzCustomActionData)) < cchString + 1) + { + cchCustomActionData += cchString + 1 + 255; // add 255 for good measure + hr = StrAlloc(ppwzCustomActionData, cchCustomActionData); + ExitOnFailure(hr, "Failed to allocate memory for CustomActionData string"); + ExitOnNull(*ppwzCustomActionData, hr, E_OUTOFMEMORY, "Failed to allocate memory for CustomActionData string"); + } + + if (**ppwzCustomActionData) // if data exists toss the delimiter on before adding more to the end + StringCchCatW(*ppwzCustomActionData, cchCustomActionData, delim); + StringCchCatW(*ppwzCustomActionData, cchCustomActionData, wzString); + +LExit: + return hr; +} + + +/******************************************************************** + WcaWriteStringToCaData() - adds an integer to the CustomActionData to + feed a deferred CustomAction + +********************************************************************/ +extern "C" HRESULT WcaWriteIntegerToCaData( + __in int i, + __inout LPWSTR* ppwzCustomActionData + ) +{ + WCHAR wzBuffer[13]; + StringCchPrintfW(wzBuffer, countof(wzBuffer), L"%d", i); + + return WcaWriteStringToCaData(wzBuffer, ppwzCustomActionData); +} + + +/******************************************************************** + WcaWriteStringToCaData() - adds a byte stream to the CustomActionData to + feed a deferred CustomAction + +********************************************************************/ +extern "C" HRESULT WcaWriteStreamToCaData( + __in_bcount(cbData) const BYTE* pbData, + __in DWORD cbData, + __inout LPWSTR* ppwzCustomActionData + ) +{ + HRESULT hr; + LPWSTR pwzData = NULL; + + hr = StrAllocBase85Encode(pbData, cbData, &pwzData); + ExitOnFailure(hr, "failed to encode data into string"); + + hr = WcaWriteStringToCaData(pwzData, ppwzCustomActionData); + +LExit: + ReleaseStr(pwzData); + return hr; +} + + +/******************************************************************** +WcaAddTempRecord - adds a temporary record to the active database + +NOTE: you cannot use PMSIHANDLEs for the __in/__out parameters +NOTE: uiUniquifyColumn can be 0 if no column needs to be made unique +********************************************************************/ +extern "C" HRESULT WcaAddTempRecord( + __inout MSIHANDLE* phTableView, + __inout MSIHANDLE* phColumns, + __in LPCWSTR wzTable, + __in UINT uiUniquifyColumn, + __in UINT cColumns, + ... + ) +{ + Assert(phTableView && phColumns); + + static DWORD dwUniquifyValue = ::GetTickCount(); + + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + LPWSTR pwzQuery = NULL; + PMSIHANDLE hTempRec; + DWORD i; + va_list args; + + LPWSTR pwzData = NULL; + LPWSTR pwzUniquify = NULL; + + // + // if we don't have a table and it's columns already + // + if (NULL == *phTableView) + { + // set the query + hr = StrAllocFormatted(&pwzQuery, L"SELECT * FROM `%s`",wzTable); + ExitOnFailure(hr, "failed to allocate string for query"); + + // Open and Execute the temp View + hr = WcaOpenExecuteView(pwzQuery, phTableView); + ExitOnFailure1(hr, "failed to openexecute temp view with query %S", pwzQuery); + } + + if (NULL == *phColumns) + { + // use GetColumnInfo to populate the datatype record + er = ::MsiViewGetColumnInfo(*phTableView, MSICOLINFO_TYPES, phColumns); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "failed to columns for table: %S", wzTable); + } + AssertSz(::MsiRecordGetFieldCount(*phColumns) == cColumns, "passed in argument does not match number of columns in table"); + + // + // create the temp record + // + hTempRec = ::MsiCreateRecord(cColumns); + ExitOnNull1(hTempRec, hr, E_UNEXPECTED, "could not create temp record for table: %S", wzTable); + + // + // loop through all the columns filling in the data + // + va_start(args, cColumns); + for (i = 1; i <= cColumns; i++) + { + hr = WcaGetRecordString(*phColumns, i, &pwzData); + ExitOnFailure1(hr, "failed to get the data type for %d", i); + + // if data type is string write string + if (L's' == *pwzData || L'S' == *pwzData || L'g' == *pwzData || L'G' == *pwzData || L'l' == *pwzData || L'L' == *pwzData) + { + LPCWSTR wz = va_arg(args, WCHAR*); + + // if this is the column that is supposed to be unique add the time stamp on the end + if (uiUniquifyColumn == i) + { + hr = StrAllocFormatted(&pwzUniquify, L"%s%u", wz, ++dwUniquifyValue); // up the count so we have no collisions on the unique name + ExitOnFailure1(hr, "failed to allocate string for unique column: %d", uiUniquifyColumn); + + wz = pwzUniquify; + } + + er = ::MsiRecordSetStringW(hTempRec, i, wz); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "failed to set string value at position %d", i); + } + // if data type is integer write integer + else if (L'i' == *pwzData || L'I' == *pwzData || L'j' == *pwzData || L'J' == *pwzData) + { + AssertSz(uiUniquifyColumn != i, "Cannot uniquify an integer column"); + int iData = va_arg(args, int); + + er = ::MsiRecordSetInteger(hTempRec, i, iData); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "failed to set integer value at position %d", i); + } + else + { + // not supporting binary streams so error out + hr = HRESULT_FROM_WIN32(ERROR_DATATYPE_MISMATCH); + ExitOnFailure2(hr, "unsupported data type '%S' in column: %d", pwzData, i); + } + } + va_end(args); + + // + // add the temporary record to the MSI + // + er = ::MsiViewModify(*phTableView, MSIMODIFY_INSERT_TEMPORARY, hTempRec); + hr = HRESULT_FROM_WIN32(er); + if (FAILED(hr)) + { + MSIDBERROR dbErr; + WCHAR wzBuf[MAX_PATH]; + DWORD cchBuf = countof(wzBuf); + + dbErr = ::MsiViewGetErrorW(*phTableView, wzBuf, &cchBuf); + ExitOnFailure2(hr, "failed to add temporary row, dberr: %d, err: %S", dbErr, wzBuf); + } + +LExit: + ReleaseStr(pwzUniquify); + ReleaseStr(pwzData); + ReleaseStr(pwzQuery); + + return hr; +} + + +/******************************************************************** +WcaDumpTable - dumps a table to the log file + +********************************************************************/ +extern "C" HRESULT WIXAPI WcaDumpTable( + __in LPCWSTR wzTable + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + LPWSTR pwzQuery = NULL; + PMSIHANDLE hView; + PMSIHANDLE hColumns; + DWORD cColumns = 0; + PMSIHANDLE hRec; + + LPWSTR pwzData = NULL; + LPWSTR pwzPrint = NULL; + + hr = StrAllocFormatted(&pwzQuery, L"SELECT * FROM `%s`",wzTable); + ExitOnFailure(hr, "failed to allocate string for query"); + + // Open and Execute the temp View + hr = WcaOpenExecuteView(pwzQuery, &hView); + ExitOnFailure1(hr, "failed to openexecute temp view with query %S", pwzQuery); + + // Use GetColumnInfo to populate the names of the columns. + er = ::MsiViewGetColumnInfo(hView, MSICOLINFO_NAMES, &hColumns); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure1(hr, "failed to columns for table: %S", wzTable); + + cColumns = ::MsiRecordGetFieldCount(hColumns); + + WcaLog(LOGMSG_STANDARD, "--- Begin Table Dump %S ---", wzTable); + + // Loop through all the columns filling in the data. + for (DWORD i = 1; i <= cColumns; i++) + { + hr = WcaGetRecordString(hColumns, i, &pwzData); + ExitOnFailure1(hr, "failed to get the column name for %d", i); + + hr = StrAllocConcat(&pwzPrint, pwzData, 0); + ExitOnFailure(hr, "Failed to add column name."); + + hr = StrAllocConcat(&pwzPrint, L"\t", 1); + ExitOnFailure(hr, "Failed to add column name."); + } + + WcaLog(LOGMSG_STANDARD, "%S", pwzPrint); + + // Now dump the actual rows. + while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) + { + if (pwzPrint && *pwzPrint) + { + *pwzPrint = L'\0'; + } + + for (DWORD i = 1; i <= cColumns; i++) + { + hr = WcaGetRecordString(hRec, i, &pwzData); + ExitOnFailure1(hr, "failed to get the column name for %d", i); + + hr = StrAllocConcat(&pwzPrint, pwzData, 0); + ExitOnFailure(hr, "Failed to add column name."); + + hr = StrAllocConcat(&pwzPrint, L"\t", 1); + ExitOnFailure(hr, "Failed to add column name."); + } + + WcaLog(LOGMSG_STANDARD, "%S", pwzPrint); + } + + WcaLog(LOGMSG_STANDARD, "--- End Table Dump %S ---", wzTable); + +LExit: + ReleaseStr(pwzPrint); + ReleaseStr(pwzData); + ReleaseStr(pwzQuery); + + return hr; +} diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV1/AncmIISExpressV1.wixproj b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV1/AncmIISExpressV1.wixproj new file mode 100644 index 0000000000..94cae34968 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV1/AncmIISExpressV1.wixproj @@ -0,0 +1,74 @@ + + + + + + AspNetCoreModuleIISExpress + D36FDC38-FE53-48CC-BC82-A17C28F1CEE1 + 2A6A4709-30D2-4716-A597-55DF0FB74D37 + Package + ICE03 + + + + ancm_iis_express_x86_en + 2A6A4709-30D2-4716-A597-55DF0FB74D37 + + + ancm_iis_express_x64_en + 2A6A4709-30D2-4716-A597-55DF0FB74D37 + + + True + + + + + iisca.wxs + + + + + + + + + + This project is trying to import a missing file: {0}. + + + + + + + + + + $(WixExtDir)\WixUtilExtension.dll + WixUtilExtension + + + $(WixExtDir)\WixDependencyExtension.dll + WixDependencyExtension + + + $(WixExtDir)\WixUIExtension.dll + WixUIExtension + + + + + + setupstrings.wxl + + + + + include.wxi + + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV1/ancm_iis_express.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV1/ancm_iis_express.wxs new file mode 100644 index 0000000000..5cd69a1331 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV1/ancm_iis_express.wxs @@ -0,0 +1,676 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Microsoft Corporation + + + + + + + + + + + (NOT NEWERVERSIONFOUND) OR Installed + + + Privileged + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + !(loc.Error30001) + !(loc.Error30002) + + !(loc.WebServicesRunning) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV2/AncmIISExpressV2.wixproj b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV2/AncmIISExpressV2.wixproj new file mode 100644 index 0000000000..ab62ca11fa --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV2/AncmIISExpressV2.wixproj @@ -0,0 +1,76 @@ + + + + + + AspNetCoreModuleV2IISExpress + D36FDC38-FE53-48CC-BC82-A17C28F1CEE1 + 17c76489-4c09-4e14-b81c-7a86cd937144 + Package + ICE03 + + + + ancm_iis_express_x86_en_v2 + + + ancm_iis_express_x64_en_v2 + + + + True + + + + + + iisca.wxs + + + + + + + + + + + This project is trying to import a missing file: {0}. + + + + + + + + + + + $(WixExtDir)\WixUtilExtension.dll + WixUtilExtension + + + $(WixExtDir)\WixDependencyExtension.dll + WixDependencyExtension + + + $(WixExtDir)\WixUIExtension.dll + WixUIExtension + + + + + + setupstrings.wxl + + + + + include.wxi + + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV2/ancm_iis_expressv2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV2/ancm_iis_expressv2.wxs new file mode 100644 index 0000000000..98739c1e4e --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMIISExpressV2/ancm_iis_expressv2.wxs @@ -0,0 +1,706 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Microsoft Corporation + + + + + + + + + + + (NOT NEWERVERSIONFOUND) OR Installed + + + Privileged + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + !(loc.Error30001) + !(loc.Error30002) + + !(loc.WebServicesRunning) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV1/AncmV1.wixproj b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV1/AncmV1.wixproj new file mode 100644 index 0000000000..27038fe2fc --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV1/AncmV1.wixproj @@ -0,0 +1,73 @@ + + + + + + AspNetCoreModule + D36FDC38-FE53-48CC-BC82-A17C28F1CEE1 + D36FDC38-FE53-48CC-BC82-A17C28F1CEE1 + Package + + + + aspnetcoremodule_x86_en + + + aspnetcoremodule_x64_en + + + + True + + + + + iisca.wxs + + + + + + + + + + + This project is trying to import a missing file: {0}. + + + + + + + + + + $(WixExtDir)\WixUtilExtension.dll + WixUtilExtension + + + $(WixExtDir)\WixDependencyExtension.dll + WixDependencyExtension + + + $(WixExtDir)\WixUIExtension.dll + WixUIExtension + + + + + + setupstrings.wxl + + + + + include.wxi + + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV1/aspnetcoremodule.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV1/aspnetcoremodule.wxs new file mode 100644 index 0000000000..0b8f359a64 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV1/aspnetcoremodule.wxs @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Microsoft Corporation + + + + + + + + + + + + + + + + + + (NOT NEWERVERSIONFOUND) OR Installed + + + + Privileged + + + + + + + + + + + + + + + + 1 + + + + = 601)]]> + + + + + ((IISCOREWEBENGINEINSTALLED = "#1") AND (IISW3SVCINSTALLED = "#1")) OR (Installed) + + + + + NOT ( (VersionNT = 600) AND (ServicePackLevel = 1) AND (WINDOWSUPDATE_START_TYPE = "#4") ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + !(loc.Error30001) + !(loc.Error30002) + + !(loc.WebServicesRunning) + + + + + + AspNetCoreModule + AspNetCoreModuleDll + + + + + + system.webServer/aspNetCore + AspNetCoreSchemaFile + Allow + + + + + + WWW Server + {3a2a4e84-4c21-4981-ae10-3fda0d9b0f83} + ANCM + 65536 + AspNetCoreModule + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV2/AncmV2.wixproj b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV2/AncmV2.wixproj new file mode 100644 index 0000000000..41bf3f3b05 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV2/AncmV2.wixproj @@ -0,0 +1,73 @@ + + + + + + AspNetCoreModuleV2 + D36FDC38-FE53-48CC-BC82-A17C28F1CEE1 + f9bacb48-3bd7-4ec2-ae31-664e8703ec12 + Package + + + + aspnetcoremodule_x86_en_v2 + + + aspnetcoremodule_x64_en_v2 + + + + True + + + + + iisca.wxs + + + + + + + + + + + This project is trying to import a missing file: {0}. + + + + + + + + + + $(WixExtDir)\WixUtilExtension.dll + WixUtilExtension + + + $(WixExtDir)\WixDependencyExtension.dll + WixDependencyExtension + + + $(WixExtDir)\WixUIExtension.dll + WixUIExtension + + + + + + setupstrings.wxl + + + + + include.wxi + + + + + + + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV2/aspnetcoremodulev2.wxs b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV2/aspnetcoremodulev2.wxs new file mode 100644 index 0000000000..1a16328d89 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/ANCMV2/aspnetcoremodulev2.wxs @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Microsoft Corporation + + + + + + + + + + + + + (NOT NEWERVERSIONFOUND) OR Installed + + + + Privileged + + + + + + + + + + + + + + + + 1 + + + + = 601)]]> + + + + + ((IISCOREWEBENGINEINSTALLED = "#1") AND (IISW3SVCINSTALLED = "#1")) OR (Installed) + + + + + NOT ( (VersionNT = 600) AND (ServicePackLevel = 1) AND (WINDOWSUPDATE_START_TYPE = "#4") ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + !(loc.Error30001) + !(loc.Error30002) + + !(loc.WebServicesRunning) + + + + + + AspNetCoreModuleV2 + AspNetCoreModuleV2Dll + + + + + + system.webServer/aspNetCore + AspNetCoreSchemaV2File + Allow + + + + + + WWW Server + {3a2a4e84-4c21-4981-ae10-3fda0d9b0f83} + ANCM + 65536 + AncmMofFile + AspNetCoreModuleV2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/bitmaps/AspNetCoreModule.ico b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/bitmaps/AspNetCoreModule.ico new file mode 100644 index 0000000000..bcafd4a5b7 Binary files /dev/null and b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/bitmaps/AspNetCoreModule.ico differ diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/bitmaps/bannrbmp.bmp b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/bitmaps/bannrbmp.bmp new file mode 100644 index 0000000000..8507592b05 Binary files /dev/null and b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/bitmaps/bannrbmp.bmp differ diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/bitmaps/dlgbmp.bmp b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/bitmaps/dlgbmp.bmp new file mode 100644 index 0000000000..c3810b4037 Binary files /dev/null and b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/bitmaps/dlgbmp.bmp differ diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/license/license.rtf b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/license/license.rtf new file mode 100644 index 0000000000..91c46e44c4 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/license/license.rtf @@ -0,0 +1,97 @@ +{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033\deflangfe2052{\fonttbl{\f0\fswiss\fprq2\fcharset0 Tahoma;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\froman\fprq2\fcharset0 Times New Roman;}{\f3\fswiss\fprq2\fcharset0 Calibri;}{\f4\fnil\fcharset2 Symbol;}} +{\colortbl ;\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;} +{\stylesheet{ Normal;}{\s1 heading 1;}} +{\*\generator Riched20 10.0.10586}\viewkind4\uc1 +\pard\nowidctlpar\sb120\sa120\b\f0\fs22 MICROSOFT SOFTWARE LICENSE TERMS\fs20\par + +\pard\brdrb\brdrs\brdrw10\brsp20 \nowidctlpar\sb120\sa120\fs22 MICROSOFT ASP.NET CORE MODULE\fs20\par + +\pard\widctlpar\sb120\sa120 These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. Please read them. They apply to the software named above, which includes the media on which you received it, if any. The terms also apply to any Microsoft\b0\par + +\pard\nowidctlpar\fi-360\li360\sb120\sa120\tx360\f1\'b7\tab\f0 updates,\par +\f1\'b7\tab\f0 supplements,\par +\f1\'b7\tab\f0 Internet-based services, and\par +\f1\'b7\tab\f0 support services\par + +\pard\nowidctlpar\sb120\sa120 for this software, unless other terms accompany those items. If so, those terms apply.\par +\b BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\par + +\pard\brdrt\brdrs\brdrw10\brsp20 \nowidctlpar\sb120\sa120 IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.\par + +\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\tx360 1.\tab INSTALLATION AND USE RIGHTS. \b0\f2\par + +\pard\widctlpar\fi-363\li720\sb120\sa120\b\f0 a.\~\~\~ Installation and Use.\b0 You may install and use any number of copies of the software to design, develop and test your programs.\b\par +b.\~\~\~ Third Party Programs.\b0 The software may include third party programs that Microsoft, not the third party, licenses to you under this agreement. Notices, if any, for the third party program are included for your information only.\b\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36 2.\tab ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS.\par + +\pard\widctlpar\fi-363\li720\sb120\sa120\kerning0 a.\~\~\~ DISTRIBUTABLE CODE.\~ \b0 The software is comprised of Distributable Code. \ldblquote Distributable Code\rdblquote is code that you are permitted to distribute in programs you develop if you comply with the terms below.\b\par + +\pard\widctlpar\fi-357\li1077\sb120\sa120 i.\~\~\~\~\~ Right to Use and Distribute. \b0\par + +\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-360\li1797\sb120\sa120 You may copy and distribute the object code form of the software.\par +{\pntext\f4\'B7\tab}Third Party Distribution. You may permit distributors of your programs to copy and distribute the Distributable Code as part of those programs.\par + +\pard\widctlpar\fi-357\li1077\sb120\sa120\b ii.\~\~\~ Distribution Requirements.\b0 \b For any Distributable Code you distribute, you must\b0\par + +\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-360\li1797\sb120\sa120 add significant primary functionality to it in your programs;\par +{\pntext\f4\'B7\tab}require distributors and external end users to agree to terms that protect it at least as much as this agreement;\par +{\pntext\f4\'B7\tab}display your valid copyright notice on your programs; and\par +{\pntext\f4\'B7\tab}indemnify, defend, and hold harmless Microsoft from any claims, including attorneys\rquote fees, related to the distribution or use of your programs.\par + +\pard\widctlpar\fi-357\li1077\sb120\sa120\b iii.\~\~ Distribution Restrictions.\b0 \b You may not\b0\par + +\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-360\li1797\sb120\sa120 alter any copyright, trademark or patent notice in the Distributable Code;\par +{\pntext\f4\'B7\tab}use Microsoft\rquote s trademarks in your programs\rquote names or in a way that suggests your programs come from or are endorsed by Microsoft;\par +{\pntext\f4\'B7\tab}include Distributable Code in malicious, deceptive or unlawful programs; or\par +{\pntext\f4\'B7\tab}modify or distribute the source code of any Distributable Code so that any part of it becomes subject to an Excluded License. An Excluded License is one that requires, as a condition of use, modification or distribution, that\par +{\pntext\f4\'B7\tab}the code be disclosed or distributed in source code form; or\par +{\pntext\f4\'B7\tab}others have the right to modify it.\f2\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\b\f0 3.\tab\kerning36 SCOPE OF LICENSE. \b0 The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not\b\par + +\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-360\li1797\sb120\sa120\kerning0\b0 work around any technical limitations in the software;\par +{\pntext\f4\'B7\tab}reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation;\par +{\pntext\f4\'B7\tab}publish the software for others to copy;\par +{\pntext\f4\'B7\tab}rent, lease or lend the software;\par +{\pntext\f4\'B7\tab}transfer the software or this agreement to any third party; or\par +{\pntext\f4\'B7\tab}use the software for commercial software hosting services.\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\b 4.\tab\cf1\highlight2 DATA.\cf0\highlight0\b0 The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the product documentation. You can learn more about data collection and use in the help documentation and the privacy statement at {{\field{\*\fldinst{HYPERLINK https://privacy.microsoft.com/en-us/privacystatement }}{\fldrslt{https://privacy.microsoft.com/en-us/privacystatement\ul0\cf0}}}}\f0\fs20 . {\f3\fs22{\field{\*\fldinst{HYPERLINK http://go.microsoft.com/fwlink/?LinkID=528096Your }}{\fldrslt{http://go.microsoft.com/fwlink/?LinkID=528096\f0\fs20 Your\ul0\cf0}}}}\f0\fs20 use of the software operates as your consent to these practices.\par +\b 5.\tab\kerning36 BACKUP COPY. \b0 You may make one backup copy of the software. You may use it only to reinstall the software.\b\par +6.\tab DOCUMENTATION. \b0 Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\b\par +7.\tab EXPORT RESTRICTIONS. \b0 The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. For additional information, see {{\field{\*\fldinst{HYPERLINK www.microsoft.com/exporting }}{\fldrslt{www.microsoft.com/exporting\ul0\cf0}}}}\f0\fs20 .\b\par +8.\tab SUPPORT SERVICES. \b0 Because this software is \ldblquote as is,\rdblquote we may not provide support services for it.\b\par +9.\tab ENTIRE AGREEMENT. \b0 This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\b\par +10.\tab APPLICABLE LAW.\par + +\pard\widctlpar\fi-363\li720\sb120\sa120\kerning0 a.\tab United States. \b0 If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\b\par +b.\~\~\~ Outside the United States. If you acquired the software in any other country, the laws of that country apply.\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36 11.\tab LEGAL EFFECT. \b0 This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\b\par +12.\tab DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED \ldblquote AS-IS.\rdblquote YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS OR STATUTORY GUARANTEES UNDER YOUR LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\par + +\pard\widctlpar\li357\sb120\sa120\kerning0 FOR AUSTRALIA \endash YOU HAVE STATUTORY GUARANTEES UNDER THE AUSTRALIAN CONSUMER LAW AND NOTHING IN THESE TERMS IS INTENDED TO AFFECT THOSE RIGHTS.\b0\par + +\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\b 13.LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.\par + +\pard\widctlpar\li357\sb120\sa120\kerning0\b0 This limitation applies to\par + +\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-270\li720\sb120\sa120 anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and\par +{\pntext\f4\'B7\tab}claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\par + +\pard\widctlpar\sb120\sa120 It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\par +\lang9 Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\lang1033\par +\lang9 Remarque : Ce logiciel \'e9tant distribu\'e9 au Qu\'e9bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran\'e7ais.\lang1033\par +\kerning36\b EXON\'c9RATION DE GARANTIE. \b0 Le logiciel vis\'e9 par une licence est offert \'ab tel quel \'bb. Toute utilisation de ce logiciel est \'e0 votre seule risque et p\'e9ril. Microsoft n\rquote accorde aucune autre garantie expresse. Vous pouvez b\'e9n\'e9ficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit\'e9 marchande, d\rquote ad\'e9quation \'e0 un usage particulier et d\rquote absence de contrefa\'e7on sont exclues.\b\par +LIMITATION DES DOMMAGES-INT\'c9R\'caTS ET EXCLUSION DE RESPONSABILIT\'c9 POUR LES DOMMAGES. \b0 Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement \'e0 hauteur de 5,00 $ US. Vous ne pouvez pr\'e9tendre \'e0 aucune indemnisation pour les autres dommages, y compris les dommages sp\'e9ciaux, indirects ou accessoires et pertes de b\'e9n\'e9fices.\b\par +\kerning0\b0\lang9 Cette limitation concerne :\lang1033\par + +\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-720\li720\sb120\sa120\lang9 tout ce qui est reli\'e9 au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et\par +{\pntext\f4\'B7\tab}les r\'e9clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit\'e9 stricte, de n\'e9gligence ou d\rquote une autre faute dans la limite autoris\'e9e par la loi en vigueur.\lang1033\par + +\pard\widctlpar\sb120\sa120\lang9 Elle s\rquote applique \'e9galement, m\'eame si Microsoft connaissait ou devrait conna\'eetre l\rquote\'e9ventualit\'e9 d\rquote un tel dommage. Si votre pays n\rquote autorise pas l\rquote exclusion ou la limitation de responsabilit\'e9 pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l\rquote exclusion ci-dessus ne s\rquote appliquera pas \'e0 votre \'e9gard.\lang1033\par +\kerning36\b\fs19 EFFET JURIDIQUE. \b0 Le pr\'e9sent contrat d\'e9crit certains droits juridiques. Vous pourriez avoir d\rquote autres droits pr\'e9vus par les lois de votre pays. Le pr\'e9sent contrat ne modifie pas les droits que vous conf\'e8rent les lois de votre pays si celles-ci ne le permettent pas.\b\par +\kerning0\b0\f2\fs20\par +} + \ No newline at end of file diff --git a/src/Installers/Windows/AspNetCoreModule-Setup/Installers/setupstrings.wxl b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/setupstrings.wxl new file mode 100644 index 0000000000..5ac48523c5 --- /dev/null +++ b/src/Installers/Windows/AspNetCoreModule-Setup/Installers/setupstrings.wxl @@ -0,0 +1,52 @@ + + + + 1033 + + + Microsoft ASP.NET Core Module + Microsoft ASP.NET Core Module V2 + ASP.NET Core IIS Runtime + Adds the support of asp.net core application to IIS. + Microsoft ASP.NET Core Module for IIS Express + Microsoft ASP.NET Core Module V2 for IIS Express + IIS Express 8.0 or higher is not installed. + + + + Microsoft Corporation + An incompatible product, [CONFLICTING_PRODUCT_NAME], is on this computer. Installation of [ProductName] cannot continue. To install this product, use Add/Remove Programs on the Control Panel to remove [CONFLICTING_PRODUCT_NAME]. + Administrator privilege is required to install [ProductName]. + IIS Version 7.0 is required to use [ProductName]. + IIS Version 7.0 or greater is required to install [ProductName]. + IIS Version 7.5 or greater is required to install [ProductName]. + IIS Version 7 or 7.5 is required to install [ProductName]. + IIS Version 8.0 or greater is required to install [ProductName]. + The beta version of [ProductName] was found on this machine. + A newer version of [ProductName] was found on this machine. + Setup cannot continue because another instance of [ProductName] is already installed on this computer. Please uninstall it first and then re-launch this installation. + The IIS 7.0 CoreWebEngine and W3SVC features must be installed to use [ProductName]. + The IIS Management Console must be installed to use [ProductName]. + Please stop both services Windows Process Activation Service (WAS) and Web Management Service (WMSvc) before installing [ProductName]. You will need to start the services after installing [ProductName]. + IIS Metabase is required to install [ProductName]. + The 64-bit version of [ProductName] cannot be installed on a 32-bit edition of Microsoft Windows. + The 32-bit version of [ProductName] cannot be installed on a 64-bit edition of Microsoft Windows. + Microsoft .NET Framework Version 2.0 or greater is required to install [ProductName]. + Microsoft .NET Framework Version 3.5 or greater is required to install [ProductName]. Use 'Add Features' under the Server Manager to install Microsoft .Net Version 3.5. + Microsoft .NET Framework Version 4.0 or greater is required to install [ProductName]. + Please install Microsoft .NET Framework Version 2.0 Service Pack 1 (or a later service pack), before installing [ProductName]. + The Windows Update (wuauserv) service cannot be disabled, it is required to install [ProductName]. + The PowerShell snap-in is part of Windows Operating System. Please install it via 'Programs and Features' or 'Server Manager'. + Microsoft Web Platform Installer Version 3.0 or greater is required to install [ProductName]. + + Setup failed to detect shared configuration. + Shared configuration is enabled for IIS. Installing [ProductName] is not supported when using shared configuration. Please disable shared configuration before installing this feature. + + Please stop World Wide Web Publishing Service (W3SVC) before installing [ProductName]. You will need to start the service after installation. + IIS PowerShell Management Console + IIS PowerShell snap-in + IIS PowerShell snap-in requires PowerShell v1.0 or v2.0 installed + IIS PowerShell snap-in requires WAS and configuration installed + This is a bogus string. + + diff --git a/src/Installers/Windows/WindowsHostingBundle/ANCM.wxs b/src/Installers/Windows/WindowsHostingBundle/ANCM.wxs index 2b1087d3b4..dd47afe26c 100644 --- a/src/Installers/Windows/WindowsHostingBundle/ANCM.wxs +++ b/src/Installers/Windows/WindowsHostingBundle/ANCM.wxs @@ -4,28 +4,28 @@ - - - - + + + + + + + + + + + + + + + + + @@ -15,6 +32,7 @@ + diff --git a/src/Installers/Windows/Wix.props b/src/Installers/Windows/Wix.props index 61c4ca9f6c..049805f94b 100644 --- a/src/Installers/Windows/Wix.props +++ b/src/Installers/Windows/Wix.props @@ -1,7 +1,11 @@ - $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(AspNetCorePatchVersion).0 + + <_TwoDigitYear>$([MSBuild]::Subtract($([System.DateTime]::UtcNow.Year), 2000)) + <_ThreeDigitDayOfYear>$([System.DateTime]::UtcNow.DayOfYear.ToString().PadLeft(3, '0')) + $(_TwoDigitYear)$(_ThreeDigitDayOfYear) + $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(AspNetCorePatchVersion).$(BUILD_MAJOR) Release x64 diff --git a/src/Installers/Windows/clone_and_build_ancm.ps1 b/src/Installers/Windows/clone_and_build_ancm.ps1 deleted file mode 100644 index 8978b22d39..0000000000 --- a/src/Installers/Windows/clone_and_build_ancm.ps1 +++ /dev/null @@ -1,120 +0,0 @@ -# -# This builds installers for AspNetCoreModule. -# This script requires internal-only access to the code which generates ANCM installers. -# -#requires -version 4 -[cmdletbinding()] -param( - [string]$GitCredential, - [string]$Configuration = 'Release', - [string]$DepsZip, - [string]$BuildNumber = 't000', - [string]$AncmSourceBranch = 'release/2.2', - [string]$SignType = '' -) - -$ErrorActionPreference = 'Stop' - -$repoRoot = Resolve-Path "$PSScriptRoot/../../../" - -Import-Module -Scope Local "$repoRoot/scripts/common.psm1" -Force - -$msbuild = Get-MSBuildPath -Prerelease -requires 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' - -# get wix -[version] $wixVer = '3.11.1' -$wixToolSetRoot = "$repoRoot/obj/tools/wix/$wixVer/" -$downloadFile = "$wixToolSetRoot/wix-binaries.zip" -if (-not (Test-Path $downloadFile)) { - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - $downloadUrl = "https://github.com/wixtoolset/wix3/releases/download/wix$($wixVer.Major)$($wixVer.Minor)$($wixVer.Build)rtm/wix$($wixVer.Major)$($wixVer.Minor)-binaries.zip" - Write-Host "Downloading fix $wixVer from $downloadUrl" - New-Item -Type Directory $wixToolSetRoot -ErrorAction Ignore | Out-Null - Invoke-WebRequest -UseBasicParsing -Uri $downloadUrl -OutFile $downloadFile - Expand-Archive $downloadFile -DestinationPath $wixToolSetRoot -} - -# get nuget.exe -$nuget = "$repoRoot/obj/tools/nuget.exe" -if (-not (Test-Path $nuget)) { - Invoke-WebRequest -UseBasicParsing -Uri 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -OutFile $nuget -} - -if (-not $DepsZip) { - $DepsZip = "$repoRoot/modules/IISIntegration/artifacts/build/AspNetCoreModule.zip" -} - -$deps = "$repoRoot/obj/ancm" -Remove-Item -Recurse $deps -Force -ErrorAction Ignore | Out-Null -New-Item -ItemType Directory -ErrorAction Ignore $deps | Out-Null -Expand-Archive $DepsZip -DestinationPath $deps -Force - -Push-Location $PSScriptRoot - -try { - if ($GitCredential) { - # Disable prompts for passwords - $env:GIT_TERMINAL_PROMPT = 0 - } - - if (-not (Test-Path ancm/)) { - $gitSource = "https://${GitCredential}@devdiv.visualstudio.com/DefaultCollection/DevDiv/_git" - Invoke-Block { - & git clone $gitSource/AspNetCoreModule-Setup ` - --branch $AncmSourceBranch ` - ancm/ - } - Invoke-Block { - & git clone $gitSource/IIS-Setup ` - ancm/IIS-Setup - } - Invoke-Block { - & git clone $gitSource/IIS-Common ` - ancm/IIS-Common - } - Invoke-Block { - & git clone $gitSource/IIS-Common ` - ancm/IIS-Setup/IIS-Common - } - } - - Invoke-Block -WorkingDir ancm/ { - & git submodule update --init --recursive - } - - Invoke-Block -WorkingDir ancm/ { - & $nuget restore ANCM-Setup.sln - } - - Invoke-Block -WorkingDir ancm/IIS-Common/lib/ { - & $nuget restore packages.config - } - - Invoke-Block { & $msbuild ` - ancm/Setup.msbuild ` - -m ` - -v:m ` - -nodeReuse:false ` - -clp:Summary ` - "-t:BuildCustomAction;Build" ` - "-p:PrebuiltAspnetCoreRoot=$deps" ` - "-p:WixToolPath=$wixToolSetRoot" ` - "-p:WixTargetsPath=$wixToolSetRoot\Wix.targets" ` - "-p:WixTasksPath=$wixToolSetRoot\wixtasks.dll" ` - "-p:WixNativeCATargetsPath=$wixToolSetRoot\sdk\wix.nativeca.targets" ` - "-p:Configuration=$Configuration" ` - "-p:BuildNumber=$BuildNumber" ` - "-p:SignType=$SignType" ` - "-bl:$repoRoot/artifacts/logs/ancn.msbuild.binlog" - } - - $outputPath = "$repoRoot/artifacts/bin/$Configuration/installers/en-US/" - New-Item $outputPath -ItemType Directory -ErrorAction Ignore | Out-Null - Copy-Item -Recurse "ancm/bin/AspNetCoreModuleV1/$Configuration/x64/en-us/*" $outputPath - Copy-Item -Recurse "ancm/bin/AspNetCoreModuleV1/$Configuration/x86/en-us/*" $outputPath - Copy-Item -Recurse "ancm/bin/AspNetCoreModuleV2/$Configuration/x64/en-us/*" $outputPath - Copy-Item -Recurse "ancm/bin/AspNetCoreModuleV2/$Configuration/x86/en-us/*" $outputPath -} -finally { - Pop-Location -}