diff --git a/src/powershell-native/CMakeLists.txt b/src/powershell-native/CMakeLists.txt index 4dfbd997cf..7a7d72a536 100644 --- a/src/powershell-native/CMakeLists.txt +++ b/src/powershell-native/CMakeLists.txt @@ -16,13 +16,13 @@ else () endif () # -# Get the path to the Windows SDK build tools. +# Normalize the platform name +# +# TODO: Only x64 and x86 are supported right now. This needs to be expanded to arm as well # if (WindowsSDKPlatform STREQUAL "x64" OR WindowsSDKPlatform STREQUAL "X64" OR WindowsSDKPlatform STREQUAL "amd64" OR WindowsSDKPlatform STREQUAL "AMD64") - # Normalize the platform name SET(WindowsSDKPlatform "x64") elseif (WindowsSDKPlatform STREQUAL "x86" OR WindowsSDKPlatform STREQUAL "X86") - # Normalize the platform name SET(WindowsSDKPlatform "x86") else() message(FATAL_ERROR "Unsupported WindowsSDKPlatform ${WindowsSDKPlatform}") @@ -32,14 +32,15 @@ endif () # set the output path for all binaries # if (BUILD_ONECORE) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/Bin/CoreClr") + set(PWRSH_NATIVE_OUTPUT_DIRECTORY "CoreClr") else () - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/Bin/FullClr") + set(PWRSH_NATIVE_OUTPUT_DIRECTORY "FullClr") endif (BUILD_ONECORE) + foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - message(" Setting output directory for ${OUTPUTCONFIG} to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "${PROJECT_SOURCE_DIR}/Bin/${OUTPUTCONFIG}/${PWRSH_NATIVE_OUTPUT_DIRECTORY}") + message(" Setting output directory for ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG}}") endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES ) # @@ -59,26 +60,6 @@ SET (WIN_VERSION_LONGHORN 0x0600) SET (WIN_VERSION_WS03 0x0502) SET (WIN_VERSION_WINXP 0x0501) -# *** -# *** Original flags: BEGIN -# *** -# -# TODO: Will this interfere with OneCore compilations? -# -# set these flags, so build does static linking for msvcr120.dll -# otherwise this dll need to be present on the system -#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") -#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") - -# Compiler flags that are universal to all powershell native binaries -#SET(common_pwrsh_definitions -# UNICODE -# _UNICODE) - -# *** -# *** Original flags: END -# *** - #include(dsc_defs.cmake) if (BUILD_ONECORE) include(nano_defs.cmake) @@ -87,7 +68,7 @@ else () endif (BUILD_ONECORE) # Default of BUILD_ONECORE should be ON once it is supported -option(BUILD_ONECORE "Compile the OneCore version of the binaries" OFF) +option(BUILD_ONECORE "Compile the OneCore version of the binaries" ON) option(BUILD_DOWNLEVEL "Compile the downlevel version of the binaries" OFF) # Build the common library that powershell.exe and pwrshplugin.dll depend on @@ -97,7 +78,4 @@ add_subdirectory(nativemsh/pwrshcommon) add_subdirectory(nativemsh/pwrshplugin) # Build powershell.exe -#if (NOT BUILD_ONECORE) - # Conditionally build powershell.exe until CssMainEntry.cpp appears. - add_subdirectory(nativemsh/pwrshexe) -#endif () +add_subdirectory(nativemsh/pwrshexe) diff --git a/src/powershell-native/nano_defs.cmake b/src/powershell-native/nano_defs.cmake index f64016f756..983e0886e5 100644 --- a/src/powershell-native/nano_defs.cmake +++ b/src/powershell-native/nano_defs.cmake @@ -26,11 +26,11 @@ SET (LibraryPath) list (APPEND LibraryPath "${OneCoreLibBase}") list (APPEND LibraryPath "${WindowsSDKLibBase}ucrt/${WindowsSDKPlatform}") list (APPEND LibraryPath "${WindowsSDKLibBase}um/${WindowsSDKPlatform}" ) -#list (APPEND LibraryPath "${NETFXSdkDir}lib/um/${WindowsSDKPlatform}") +###list (APPEND LibraryPath "${NETFXSdkDir}lib/um/${WindowsSDKPlatform}") link_directories(${LibraryPath}) # -# Tell CMake to set the platform toolset. +# Tell CMake to set the platform toolset. Nano Server requires the Win10 SDK and updated onecore.lib # set(CMAKE_VS_PLATFORM_TOOLSET "v140") # Use VS 2015 with Win 10 SDK set(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION "10.0.10586.0") # Targets Windows 10. Alt is ${WindowsSDKVersion} @@ -60,22 +60,28 @@ add_compile_options(/Zc:wchar_t) # C++ language conformance: wchar_t is NOT the #add_compile_options(/U_WINDOWS) add_definitions( - -DWIN32 - -DNDEBUG - # -D_DEBUG + -D_WIN64 + -D_AMD64_ + -DAMD64 + -D_APISET_WINDOWS_VERSION=0x601 + -D_APISET_MINWIN_VERSION=0x0101 + -D_APISET_MINCORE_VERSION=0x0100 + -DNTDDI_VERSION=0x0A000002 + # -DWIN32=100 + -D_DEBUG -D_UNICODE -DUNICODE -DWIN32_LEAN_AND_MEAN=1 + #-DNDEBUG ) +set(CMAKE_ENABLE_EXPORTS ON) -#set(MY_COMMON_LINK_FLAGS "/INCREMENTAL /NOLOGO /MANIFEST:NO /NXCOMPAT /DYNAMICBASE /TLBID:1 /MACHINE:x64 /NODEFAULTLIB") -set(MY_COMMON_LINK_FLAGS "/INCREMENTAL:NO /NOLOGO /MANIFEST:NO /NXCOMPAT /DYNAMICBASE /TLBID:1 /MACHINE:x64 /guard:cf /OPT:REF /OPT:ICF") +set(MY_COMMON_LINK_FLAGS "/INCREMENTAL:NO /NOLOGO /MANIFEST:NO /NXCOMPAT /DYNAMICBASE /TLBID:1 /MACHINE:x64 /guard:cf /OPT:REF /OPT:ICF /NODEFAULTLIB") set(MY_COMMON_LINK_FLAGS "${MY_COMMON_LINK_FLAGS} /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:advapi32.lib") # Explicitly exclude kernel32 and advapi32 since CMake is including them and they block execution on Nano Server set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MY_COMMON_LINK_FLAGS}") -#set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /OPT:REF") #windows subsystem -set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") #windows subsystem +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,6.00") #windows subsystem set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MY_COMMON_LINK_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE") #windows subsystem diff --git a/src/powershell-native/nativemsh/pwrshcommon/CMakeLists.txt b/src/powershell-native/nativemsh/pwrshcommon/CMakeLists.txt index 09f80d8ec5..c3971e88d8 100644 --- a/src/powershell-native/nativemsh/pwrshcommon/CMakeLists.txt +++ b/src/powershell-native/nativemsh/pwrshcommon/CMakeLists.txt @@ -14,9 +14,7 @@ if (BUILD_ONECORE) set(PWRSHCOMMON_WINDOWS_LIBS # onecore.lib ) - #set(pwrshcommon_definitions ${common_pwrsh_definitions} CORECLR) - set(pwrshcommon_definitions CORECLR) - set_target_properties(pwrshcommon PROPERTIES COMPILE_DEFINITIONS "${pwrshcommon_definitions}") + set_target_properties(pwrshcommon PROPERTIES COMPILE_DEFINITIONS "CORECLR") else () # NOT BUILD_ONECORE message("Building Full version of pwrshcommon.lib") # Libraries to use when creating this binary for Windows on full SKUs @@ -35,13 +33,8 @@ else () # NOT BUILD_ONECORE # msxml6.lib # mscoree.lib) ) - #set(pwrshcommon_definitions ${common_pwrsh_definitions}) - # target_include_directories(pwrshcommon PUBLIC - # "%ProgramFiles(x86)%/Windows Kits/NETFXSDK/4.6/Include/um") endif (BUILD_ONECORE) -#set_target_properties(pwrshcommon PROPERTIES COMPILE_DEFINITIONS "${pwrshcommon_definitions}") - target_link_libraries(pwrshcommon ${PWRSHCOMMON_WINDOWS_LIBS}) diff --git a/src/powershell-native/nativemsh/pwrshcommon/ClrHostWrapper.h b/src/powershell-native/nativemsh/pwrshcommon/ClrHostWrapper.h index 54df1e2b59..2c86fb9e27 100644 --- a/src/powershell-native/nativemsh/pwrshcommon/ClrHostWrapper.h +++ b/src/powershell-native/nativemsh/pwrshcommon/ClrHostWrapper.h @@ -77,7 +77,7 @@ namespace NativeMsh // // Function Pointer Definitions for the function pointers to load from CoreCLR.dll // - typedef int (*coreclr_initialize_ptr)( + typedef int (STDMETHODCALLTYPE *coreclr_initialize_ptr)( const char* exePath, const char* appDomainFriendlyName, int propertyCount, @@ -86,11 +86,11 @@ namespace NativeMsh void** hostHandle, unsigned int* domainId); - typedef int (*coreclr_shutdown_ptr)( + typedef int (STDMETHODCALLTYPE *coreclr_shutdown_ptr)( void* hostHandle, unsigned int domainId); - typedef int (*coreclr_create_delegate_ptr)( + typedef int (STDMETHODCALLTYPE *coreclr_create_delegate_ptr)( void* hostHandle, unsigned int domainId, const char* entryPointAssemblyName, diff --git a/src/powershell-native/nativemsh/pwrshexe/CMakeLists.txt b/src/powershell-native/nativemsh/pwrshexe/CMakeLists.txt index 9306c687bc..cddff23d3b 100644 --- a/src/powershell-native/nativemsh/pwrshexe/CMakeLists.txt +++ b/src/powershell-native/nativemsh/pwrshexe/CMakeLists.txt @@ -2,18 +2,11 @@ # Builds PowerShell.exe, the native host for PowerShell. # -# Only build powershell.exe for "full" windows. Open PowerShell uses the managed executable. if (BUILD_ONECORE) - #set(BUILD_ONECORE OFF) -endif () - -if (BUILD_ONECORE) - message("*") - message("*********** Building PowerShell.exe for CoreCLR. Add CssMainEntry.cpp") - message("*") # Settings to use when creating PowerShell.exe for Windows on OneCore-based SKUs set(PWRSHEXE_WINDOWS_SOURCES - CssMainEntry.cpp) + CssMainEntry.cpp + ) set(PWRSHEXE_WINDOWS_LIBS ### ${STATIC_MT_CRT_LIB} ### ${STATIC_MT_VCRT_LIB} @@ -22,26 +15,26 @@ if (BUILD_ONECORE) vcruntime.lib ucrtd.lib msvcrt.lib + msvcrt.lib + msvcprtd.lib + user32.lib + atls.lib ) set(powershell_definitions _CONSOLE CORECLR ) - # ${common_pwrsh_definitions}) else () - message("*") - message("*********** Building PowerShell.exe for 'Full' CLR.") - message("*") # Settings to use when creating PowerShell.exe for Windows on full SKUs or downlevel platforms set(PWRSHEXE_WINDOWS_SOURCES - MainEntry.cpp) + MainEntry.cpp + ) # Most libs are automatically added by VS set(PWRSHEXE_WINDOWS_LIBS # CoreCLR libs ${STATIC_MT_CRT_LIB} ${STATIC_MT_VCRT_LIB} ${STATIC_UCRT_LIB} - # # ole32.lib # oleaut32.lib # uuid.lib @@ -53,7 +46,6 @@ else () ) set(powershell_definitions _CONSOLE - # ${common_pwrsh_definitions}) ) endif (BUILD_ONECORE) @@ -61,16 +53,6 @@ add_executable(powershell ${PWRSHEXE_WINDOWS_SOURCES}) set_target_properties(powershell PROPERTIES COMPILE_DEFINITIONS "${powershell_definitions}") -# Set in nano_defs.cmake. Uncomment for other flavors -#set_target_properties(powershell PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE") -#set_target_properties(powershell PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE") -#set_target_properties(powershell PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE") -#set_target_properties(powershell PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:CONSOLE") -message("==== Setting libs = ${PWRSHEXE_WINDOWS_LIBS}") - -target_link_libraries(powershell - ${PWRSHEXE_WINDOWS_LIBS}) - -#target_link_libraries(powershell LINK_PUBLIC pwrshcommon) +target_link_libraries(powershell ${PWRSHEXE_WINDOWS_LIBS}) target_link_libraries(powershell pwrshcommon) diff --git a/src/powershell-native/nativemsh/pwrshplugin/CMakeLists.txt b/src/powershell-native/nativemsh/pwrshplugin/CMakeLists.txt index bec4d1e686..fb5f05f827 100644 --- a/src/powershell-native/nativemsh/pwrshplugin/CMakeLists.txt +++ b/src/powershell-native/nativemsh/pwrshplugin/CMakeLists.txt @@ -6,12 +6,10 @@ add_library(pwrshplugin SHARED pwrshclrhost.cpp pwrshpluginerrorcodes.mc pwrshpluginerrorcodes.rc - pwrshplugin.def) + pwrshplugin.def + ) if (BUILD_ONECORE) - message("*") - message("* Setting up BUILD_ONECORE version of pwrshplugin.dll") - message("*") # Libraries to use when creating this binary for Windows on OneCore-based SKUs set(PWRSHPLUGIN_WINDOWS_LIBS ### ${STATIC_MT_CRT_LIB} @@ -21,24 +19,23 @@ if (BUILD_ONECORE) vcruntime.lib ucrtd.lib msvcrt.lib - wsmsvc.lib) - #set(pwrshplugin_definitions ${common_pwrsh_definitions} CORECLR) - set(pwrshplugin_definitions CORECLR) - set_target_properties(pwrshplugin PROPERTIES COMPILE_DEFINITIONS "${pwrshplugin_definitions}") + msvcprtd.lib + user32.lib + atls.lib + wsmsvc.lib + ) + set_target_properties(pwrshplugin PROPERTIES COMPILE_DEFINITIONS "CORECLR") else () - message("*") - message("* Setting up NOT BUILD_ONECORE version of pwrshplugin.dll") - message("*") # Libraries to use when creating this binary for Windows on full SKUs set(PWRSHPLUGIN_WINDOWS_LIBS # ntdll.lib # kernel32.lib # advapi32.lib # ole32.lib - MUILoad.lib - mscoree.lib # oleaut32.lib # uuid.lib + MUILoad.lib + mscoree.lib wsmsvc.lib # CoreCLR lib ${STATIC_MT_CRT_LIB} @@ -49,11 +46,7 @@ else () set(pwrshplugin_definitions ${common_pwrsh_definitions}) endif (BUILD_ONECORE) -#set_target_properties(pwrshplugin PROPERTIES COMPILE_DEFINITIONS "${pwrshplugin_definitions}") -#set_target_properties(pwrshplugin PROPERTIES COMPILE_DEFINITIONS "_DLL") - target_link_libraries(pwrshplugin ${PWRSHPLUGIN_WINDOWS_LIBS}) -#target_link_libraries(pwrshplugin LINK_PUBLIC pwrshcommon) target_link_libraries(pwrshplugin pwrshcommon) diff --git a/src/powershell-native/nativemsh/pwrshplugin/entrypoints.cpp b/src/powershell-native/nativemsh/pwrshplugin/entrypoints.cpp index a521e0b890..e1ecbc9dec 100644 --- a/src/powershell-native/nativemsh/pwrshplugin/entrypoints.cpp +++ b/src/powershell-native/nativemsh/pwrshplugin/entrypoints.cpp @@ -186,6 +186,7 @@ static PwrshCommon sPwrshCommon; // pwszRuntimeVersion and pRuntimeVersionLength represents the size of pwszRuntimeVersion. // returns: 0 on success, non-zero on failure. _Success_(return == 0) //EXIT_CODE_SUCCESS +__declspec(dllexport) unsigned int GetCLRVersionForPSVersion(int iPSMajorVersion, int iPSMinorVersion, size_t runtimeVersionLength, @@ -323,6 +324,8 @@ DWORD ReportOperationComplete(WSMAN_PLUGIN_REQUEST *requestDetails, DWORD errorC // initialized more than once within the same process, but only once per // applicationIdentification. // ----------------------------------------------------------------------------- +__declspec(dllexport) +extern "C" DWORD WINAPI WSManPluginStartup( __in DWORD flags, __in PCWSTR applicationIdentification, @@ -406,6 +409,8 @@ DWORD WINAPI WSManPluginStartup( // reason: If this is a system shutdown this will be WSMAN_PLUGIN_SHUTDOWN_SYSTEM. // For WSMan service shutdown this will be WSMAN_PLUGIN_SHUTDOWN_SERVICE. For an IIS host //shutdown this will be WSMAN_PLUGIN_SHUTDOWN_IISHOST. +__declspec(dllexport) +extern "C" DWORD WINAPI WSManPluginShutdown( __in PVOID pluginContext, __in DWORD flags, @@ -453,6 +458,8 @@ DWORD WINAPI WSManPluginShutdown( // requestDetails the plug-in needs to call WSManPluginOperationComplete. // The shell is active until this time. // ----------------------------------------------------------------------------- +__declspec(dllexport) +extern "C" VOID WINAPI WSManPluginShell( __in PVOID pluginContext, __in WSMAN_PLUGIN_REQUEST *requestDetails, @@ -528,6 +535,8 @@ VOID WINAPI WSManPluginShell( // corresponding release function has been called. Failure to follow the contract // will result in errors being generated. // ----------------------------------------------------------------------------- +__declspec(dllexport) +extern "C" VOID WINAPI WSManPluginReleaseShellContext(__in PVOID shellContext) { if ((NULL == shellContext)) @@ -560,6 +569,8 @@ VOID WINAPI WSManPluginReleaseShellContext(__in PVOID shellContext) // requestDetails the plug-in needs to call WSManPluginOperationComplete. // The command is active until this time. // ----------------------------------------------------------------------------- +__declspec(dllexport) +extern "C" VOID WINAPI WSManPluginCommand( __in WSMAN_PLUGIN_REQUEST *requestDetails, __in DWORD flags, @@ -593,6 +604,8 @@ VOID WINAPI WSManPluginCommand( // corresponding release function has been called. Failure to follow the contract // will result in errors being generated. // --------------------------------------------------------------------------------- +__declspec(dllexport) +extern "C" VOID WINAPI WSManPluginReleaseCommandContext( __in PVOID shellContext, __in PVOID commandContext @@ -624,6 +637,8 @@ VOID WINAPI WSManPluginReleaseCommandContext( // For each piece of data the plug-in calls WSManPluginResultComplete to // acknowledge receipt and to allow the next piece of data to be delivered. // ----------------------------------------------------------------------------- +__declspec(dllexport) +extern "C" VOID WINAPI WSManPluginSend( __in WSMAN_PLUGIN_REQUEST *requestDetails, __in DWORD flags, @@ -663,6 +678,8 @@ VOID WINAPI WSManPluginSend( // WSManPluginResultComplete. The operation is marked as active until this // time. // ----------------------------------------------------------------------------- +__declspec(dllexport) +extern "C" VOID WINAPI WSManPluginReceive( __in WSMAN_PLUGIN_REQUEST *requestDetails, __in DWORD flags, @@ -698,6 +715,8 @@ VOID WINAPI WSManPluginReceive( // of this callback may be many completion calls for the Signal, Receive, Command // and Shell operations. // ----------------------------------------------------------------------------- +__declspec(dllexport) +extern "C" VOID WINAPI WSManPluginSignal( __in WSMAN_PLUGIN_REQUEST *requestDetails, __in DWORD flags, @@ -723,7 +742,8 @@ VOID WINAPI WSManPluginSignal( } } - +__declspec(dllexport) +extern "C" VOID WINAPI WSManPluginConnect( __in WSMAN_PLUGIN_REQUEST *requestDetails, __in DWORD flags, diff --git a/src/powershell-native/nativemsh/pwrshplugin/pwrshheaders.h b/src/powershell-native/nativemsh/pwrshplugin/pwrshheaders.h index d63dc56cb2..908e9055ff 100644 --- a/src/powershell-native/nativemsh/pwrshplugin/pwrshheaders.h +++ b/src/powershell-native/nativemsh/pwrshplugin/pwrshheaders.h @@ -15,8 +15,10 @@ // pwszRuntimeVersion and pRuntimeVersionLength represents the size of pwszRuntimeVersion. // returns: 0 on success, non-zero on failure. _Success_(return == 0) // EXIT_CODE_SUCCESS -extern unsigned int GetCLRVersionForPSVersion(int iPSMajorVersion, - int iPSMinorVersion, - size_t runtimeVersionLength, - __inout_ecount_part(runtimeVersionLength , *pRuntimeVersionLength) wchar_t* pwszRuntimeVersion, - __out_ecount(1) size_t* pRuntimeVersionLength); \ No newline at end of file +extern "C" +__declspec(dllexport) +unsigned int GetCLRVersionForPSVersion(int iPSMajorVersion, + int iPSMinorVersion, + size_t runtimeVersionLength, + __inout_ecount_part(runtimeVersionLength , *pRuntimeVersionLength) wchar_t* pwszRuntimeVersion, + __out_ecount(1) size_t* pRuntimeVersionLength); diff --git a/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.def b/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.def index f80ff8ac2d..af45f5c785 100644 --- a/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.def +++ b/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.def @@ -15,4 +15,4 @@ WSManPluginSend WSManPluginSignal WSManPluginReceive WSManPluginConnect -PerformWSManPluginReportCompletion \ No newline at end of file +PerformWSManPluginReportCompletion diff --git a/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.h b/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.h index 16efa0f3d2..61734b800b 100644 --- a/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.h +++ b/src/powershell-native/nativemsh/pwrshplugin/pwrshplugin.h @@ -1091,6 +1091,8 @@ public: } }; +__declspec(dllexport) +extern "C" void WINAPI PerformWSManPluginReportCompletion() { // Now report the plugin completion, to indicate that plugin is ready to shutdown.