diff options
author | danmosemsft <danmose@microsoft.com> | 2017-02-11 07:20:12 -0800 |
---|---|---|
committer | danmosemsft <danmose@microsoft.com> | 2017-02-11 07:20:12 -0800 |
commit | 56d4ba8a9338c3ff7378d18378f38ad847f130f2 (patch) | |
tree | 40b9463880286b1bc0b4c3f858680f1ff210c933 /src/utilcode | |
parent | 8be2f9bb0039e2c49f59c4fb66cebf5467485ba2 (diff) | |
download | coreclr-56d4ba8a9338c3ff7378d18378f38ad847f130f2.tar.gz coreclr-56d4ba8a9338c3ff7378d18378f38ad847f130f2.tar.bz2 coreclr-56d4ba8a9338c3ff7378d18378f38ad847f130f2.zip |
Revert "Remove always defined FEATURE_CORESYSTEM"
This reverts commit 751771a8976f909af772e35c167bd7e3ffbe44c8.
Diffstat (limited to 'src/utilcode')
-rw-r--r-- | src/utilcode/securitywrapper.cpp | 122 | ||||
-rw-r--r-- | src/utilcode/sstring.cpp | 8 | ||||
-rw-r--r-- | src/utilcode/util.cpp | 53 | ||||
-rw-r--r-- | src/utilcode/utilmessagebox.cpp | 165 | ||||
-rw-r--r-- | src/utilcode/winfix.cpp | 15 |
5 files changed, 363 insertions, 0 deletions
diff --git a/src/utilcode/securitywrapper.cpp b/src/utilcode/securitywrapper.cpp index c357ab6146..0f146ab55e 100644 --- a/src/utilcode/securitywrapper.cpp +++ b/src/utilcode/securitywrapper.cpp @@ -207,6 +207,116 @@ exit: return hr; } +#ifndef FEATURE_CORESYSTEM +//----------------------------------------------------------------------------- +// get the sid of a given process id using WTSEnumerateProcesses +// @todo: Make this function fail when WTSEnumerateProcesses is not available +// Or is it always available on all of our platform? +// +// Caller remember to call delete on *ppSid +//----------------------------------------------------------------------------- +HRESULT GetSidFromProcessEXWorker(DWORD dwProcessId, PSID *ppSid) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + PRECONDITION(CheckPointer(ppSid)); + } + CONTRACTL_END; + + HRESULT hr = S_OK; + PWTS_PROCESS_INFOW rgProcessInfo = NULL; + DWORD dwNumProcesses; + DWORD iProc; + DWORD cbSid; + PSID pSid = NULL; + + LOG((LF_CORDB, LL_INFO10000, + "SecurityUtil::GetSidFromProcessEx: 0x%08x\n", + dwProcessId)); + + + *ppSid = NULL; + if (!WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, // use local server + 0, // Reserved must be zero + 1, // version must be 1 + &rgProcessInfo, // Receives pointer to process list + &dwNumProcesses)) + { + hr = HRESULT_FROM_GetLastError(); + goto exit; + } + + for (iProc = 0; iProc < dwNumProcesses; iProc++) + { + + if (rgProcessInfo[iProc].ProcessId == dwProcessId) + { + if (rgProcessInfo[iProc].pUserSid == NULL) + { + LOG((LF_CORDB, LL_INFO10000, + "SecurityUtil::GetSidFromProcessEx is not able to retreive SID\n")); + + // if there is no Sid for the user, don't call GetLengthSid. + // It will crash! It is ok to return E_FAIL as caller will ignore it. + hr = E_FAIL; + goto exit; + } + cbSid = GetLengthSid(rgProcessInfo[iProc].pUserSid); + pSid = new (nothrow) BYTE[cbSid]; + if (pSid == NULL) + { + hr = E_OUTOFMEMORY; + } + else + { + if (!CopySid(cbSid, pSid, rgProcessInfo[iProc].pUserSid)) + { + hr = HRESULT_FROM_GetLastError(); + } + else + { + // We are done. Go to exit + hr = S_OK; + } + } + + // we already find a match. Even if we fail from memory allocation of CopySid, still + // goto exit. + goto exit; + } + } + + // Walk the whole list and cannot find the matching PID + // Find a better error code. + hr = E_FAIL; + +exit: + + if (rgProcessInfo) + { + WTSFreeMemory(rgProcessInfo); + } + + if (FAILED(hr) && pSid) + { + delete [] (reinterpret_cast<BYTE*>(pSid)); + } + + if (SUCCEEDED(hr)) + { + _ASSERTE(pSid); + *ppSid = pSid; + } + LOG((LF_CORDB, LL_INFO10000, + "SecurityUtil::GetSidFromProcessEx return hr : 0x%08x\n", + hr)); + + + return hr; +} +#endif // !FEATURE_CORESYSTEM //----------------------------------------------------------------------------- // The functions below initialize this SidBuffer instance with a Sid from @@ -252,6 +362,12 @@ HRESULT SidBuffer::InitFromProcessNoThrow(DWORD pid) _ASSERTE(m_pBuffer == NULL); HRESULT hr = GetSidFromProcessWorker(pid, kOwnerSid, (PSID *) &m_pBuffer); +#ifndef FEATURE_CORESYSTEM + if (FAILED(hr)) + { + hr = GetSidFromProcessEXWorker(pid, (PSID *) &m_pBuffer); + } +#endif // !FEATURE_CORESYSTEM if (FAILED(hr)) { return hr; @@ -411,6 +527,12 @@ HRESULT SidBuffer::InitFromProcessUserNoThrow(DWORD pid) _ASSERTE(m_pBuffer == NULL); HRESULT hr = GetSidFromProcessWorker(pid, kUserSid, (PSID *) &m_pBuffer); +#ifndef FEATURE_CORESYSTEM + if (FAILED(hr)) + { + hr = GetSidFromProcessEXWorker(pid, (PSID *) &m_pBuffer); + } +#endif // !FEATURE_CORESYSTEM if (FAILED(hr)) { return hr; diff --git a/src/utilcode/sstring.cpp b/src/utilcode/sstring.cpp index cf495ccb15..7c332e08c3 100644 --- a/src/utilcode/sstring.cpp +++ b/src/utilcode/sstring.cpp @@ -2237,7 +2237,11 @@ void SString::PVPrintf(const WCHAR *format, va_list args) { // First, try to use the existing buffer va_copy(ap, args); +#if defined(FEATURE_CORESYSTEM) int result = _vsnwprintf_s(GetRawUnicode(), GetRawCount()+1, _TRUNCATE, format, ap); +#else + int result = _vswprintf_p(GetRawUnicode(), GetRawCount()+1, format, ap); +#endif va_end(ap); if (result >= 0) { @@ -2267,7 +2271,11 @@ void SString::PVPrintf(const WCHAR *format, va_list args) errno = 0; va_copy(ap, args); +#if defined(FEATURE_CORESYSTEM) int result = _vsnwprintf_s(GetRawUnicode(), GetRawCount()+1, _TRUNCATE, format, ap); +#else + int result = _vswprintf_p(GetRawUnicode(), GetRawCount()+1, format, ap); +#endif va_end(ap); if (result >= 0) diff --git a/src/utilcode/util.cpp b/src/utilcode/util.cpp index 67e353b359..b9ca380212 100644 --- a/src/utilcode/util.cpp +++ b/src/utilcode/util.cpp @@ -28,7 +28,60 @@ UINT32 g_nClrInstanceId = 0; //********** Code. ************************************************************ +#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORESYSTEM) +extern WinRTStatusEnum gWinRTStatus = WINRT_STATUS_UNINITED; +#endif // FEATURE_COMINTEROP && !FEATURE_CORESYSTEM +#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORESYSTEM) +//------------------------------------------------------------------------------ +// +// Attempt to detect the presense of Windows Runtime support on the current OS. +// Our algorithm to do this is to ensure that: +// 1. combase.dll exists +// 2. combase.dll contains a RoInitialize export +// + +void InitWinRTStatus() +{ + STATIC_CONTRACT_NOTHROW; + STATIC_CONTRACT_GC_NOTRIGGER; + STATIC_CONTRACT_CANNOT_TAKE_LOCK; + STATIC_CONTRACT_SO_TOLERANT; + + WinRTStatusEnum winRTStatus = WINRT_STATUS_UNSUPPORTED; + + const WCHAR wszComBaseDll[] = W("\\combase.dll"); + const SIZE_T cchComBaseDll = _countof(wszComBaseDll); + + WCHAR wszComBasePath[MAX_LONGPATH + 1]; + const SIZE_T cchComBasePath = _countof(wszComBasePath); + + ZeroMemory(wszComBasePath, cchComBasePath * sizeof(wszComBasePath[0])); + + UINT cchSystemDirectory = WszGetSystemDirectory(wszComBasePath, MAX_LONGPATH); + + // Make sure that we're only probing in the system directory. If we can't find the system directory, or + // we find it but combase.dll doesn't fit into it, we'll fall back to a safe default of saying that WinRT + // is simply not present. + if (cchSystemDirectory > 0 && cchComBasePath - cchSystemDirectory >= cchComBaseDll) + { + if (wcscat_s(wszComBasePath, wszComBaseDll) == 0) + { + HModuleHolder hComBase(WszLoadLibrary(wszComBasePath)); + if (hComBase != NULL) + { + FARPROC activateInstace = GetProcAddress(hComBase, "RoInitialize"); + if (activateInstace != NULL) + { + winRTStatus = WINRT_STATUS_SUPPORTED; + } + } + } + } + + gWinRTStatus = winRTStatus; +} +#endif // FEATURE_COMINTEROP && !FEATURE_CORESYSTEM //***************************************************************************** // Convert a string of hex digits into a hex value of the specified # of bytes. //***************************************************************************** diff --git a/src/utilcode/utilmessagebox.cpp b/src/utilcode/utilmessagebox.cpp index 899b12088a..5ceb3909f6 100644 --- a/src/utilcode/utilmessagebox.cpp +++ b/src/utilcode/utilmessagebox.cpp @@ -18,6 +18,11 @@ #include "ndpversion.h" #include "../dlls/mscorrc/resource.h" #include "ex.h" +#if !defined(FEATURE_CORESYSTEM) +#undef NTDDI_VERSION +#define NTDDI_VERSION NTDDI_WIN7 +#include "commctrl.h" +#endif BOOL ShouldDisplayMsgBoxOnCriticalFailure() @@ -44,6 +49,16 @@ BOOL ShouldDisplayMsgBoxOnCriticalFailure() } +#if !defined(FEATURE_CORESYSTEM) && !defined(FEATURE_CORECLR) +enum ProbedTaskDialogIndirectState +{ + ProbedTaskDialogIndirectState_NotProbed = 0, + ProbedTaskDialogIndirectState_NotAvailable = 1, + ProbedTaskDialogIndirectState_Available = 2 +}; + +static ProbedTaskDialogIndirectState siProbedTaskDialogIndirect = ProbedTaskDialogIndirectState_NotProbed; +#endif // !FEATURE_CORESYSTEM && !FEATURE_CORECLR // We'd like to use TaskDialogIndirect for asserts coming from managed code in particular @@ -71,7 +86,157 @@ int MessageBoxImpl( } CONTRACTL_END; +#if defined(FEATURE_CORESYSTEM) || defined (FEATURE_CORECLR) return WszMessageBox(hWnd, message, title, uType); +#else + bool mustUseMessageBox = false; // Mac, Silverlight, pre-Vista? Do we support this type of message box? + decltype(TaskDialogIndirect)* pfnTaskDialogIndirect = NULL; + ULONG_PTR cookie = NULL; // For activation context. + bool activatedActivationContext = false; + HModuleHolder hmodComctl32; + HANDLE hActCtx = INVALID_HANDLE_VALUE; + + // Note: TaskDialogIndirect is only in the v6 and above versions of comctl32. Windows + // stores that library in the WinSxS directory in a directory with + // "Microsoft.Windows.Common-Controls" in the name. Your application can only see + // this library if the linker has added a manifest dependency on the V6 common controls + // to your application. Or, you can create an activation context to make this work, + // if your library also has the appropriate manifest dependency. + // Also, I'm not going to leave comctl32.dll mapped, to ensure it can't somehow + // interfere with older versions. Therefore, re-load comctl32.dll every time through + // this method. We will record whether TaskDialogIndirect is available though, so + // we can fall back to MessageBox faster. + + // We don't yet have a perfect mapping from all MessageBox behavior to TaskDialogIndirect behavior. + // Use MessageBox to avoid most of this complexity. + if (((uType & MB_ICONMASK) != MB_ICONWARNING) && (uType & MB_ICONMASK) != MB_ICONERROR || + (uType & MB_TYPEMASK) != MB_ABORTRETRYIGNORE || + (uType & MB_DEFMASK) != 0 || + (uType & MB_MODEMASK) != 0 || + (uType & MB_MISCMASK) != 0) + mustUseMessageBox = true; + else if (mustUseMessageBox || siProbedTaskDialogIndirect == ProbedTaskDialogIndirectState_NotAvailable) + mustUseMessageBox = true; + else { + // Replace our application's ActivationContext temporarily, load comctl32 + // & look for TaskDialogIndirect. Don't cache pointer. + // The following code was suggested by some Windows experts. We do not want + // to add a manifest to our library saying we use comctl32 v6, because that + // will mean loading a lot of extra libraries on startup (a significant perf hit). + // We could either store the manifest as a resource, or more creatively since + // we are effectively a Windows component, rely on %windir%\WindowsShell.manifest. + ACTCTX ctx = { sizeof(ACTCTX) }; + ctx.dwFlags = 0; + StackSString manifestPath; // Point this at %windir%\WindowsShell.manifest, for comctl32 version 6. + UINT numChars = WszGetWindowsDirectory(manifestPath.OpenUnicodeBuffer(MAX_PATH_FNAME), MAX_PATH_FNAME); + if (numChars == 0 || numChars >= MAX_PATH_FNAME) + { + _ASSERTE(0); // How did this fail? + } + else { + manifestPath.CloseBuffer(numChars); + if (manifestPath[manifestPath.GetCount() - 1] != W('\\')) + manifestPath.Append(W('\\')); + manifestPath.Append(W("WindowsShell.manifest")); // Other Windows components have already loaded this. + ctx.lpSource = manifestPath.GetUnicode(); + hActCtx = CreateActCtx(&ctx); + if (hActCtx != INVALID_HANDLE_VALUE) + { + if (!ActivateActCtx(hActCtx, &cookie)) + { + cookie = NULL; + _ASSERTE(0); // Why did ActivateActCtx fail? (We'll continue executing & cope with the failure.) + } + else { + activatedActivationContext = true; + // Activation context was replaced - now we can load comctl32 version 6. + hmodComctl32 = WszLoadLibrary(W("comctl32.dll")); + + if (hmodComctl32 != INVALID_HANDLE_VALUE) { + pfnTaskDialogIndirect = (decltype(TaskDialogIndirect)*)GetProcAddress(hmodComctl32, "TaskDialogIndirect"); + if (pfnTaskDialogIndirect == NULL) { + hmodComctl32.Release(); + } + } + } + } + } + + siProbedTaskDialogIndirect = (pfnTaskDialogIndirect == NULL) ? ProbedTaskDialogIndirectState_NotAvailable : ProbedTaskDialogIndirectState_Available; + mustUseMessageBox = (pfnTaskDialogIndirect == NULL); + } + + int result = MB_OK; + if (mustUseMessageBox) { + result = WszMessageBox(hWnd, message, title, uType); + } + else { + _ASSERTE(pfnTaskDialogIndirect != NULL); + int nButtonPressed = 0; + TASKDIALOGCONFIG config = {0}; + config.cbSize = sizeof(config); + config.hwndParent = hWnd; + config.dwCommonButtons = 0; + config.pszWindowTitle = title; + config.dwFlags = (uType & MB_RTLREADING) ? TDF_RTL_LAYOUT : 0; + + // Set the user-visible icon in the window. + _ASSERTE(((uType & MB_ICONMASK) == MB_ICONWARNING) || ((uType & MB_ICONMASK) == MB_ICONERROR)); + config.pszMainIcon = ((uType & MB_ICONMASK) == MB_ICONWARNING) ? TD_WARNING_ICON : TD_ERROR_ICON; + + config.pszMainInstruction = title; + config.pszContent = message; + config.pszExpandedInformation = detailedText; + + // Set up the buttons + // Note about button hot keys: Windows keeps track of of where the last input came from + // (ie, mouse or keyboard). If you use the mouse to interact w/ one dialog box and then use + // the keyboard, the next dialog will not include hot keys. This is a Windows feature to + // minimize clutter on the screen for mouse users. + _ASSERTE((uType & MB_TYPEMASK) == MB_ABORTRETRYIGNORE); + StackSString abortLabel, debugLabel, ignoreLabel; + const WCHAR *pAbortLabel, *pDebugLabel, *pIgnoreLabel; + + if (abortLabel.LoadResource(CCompRC::Optional, IDS_DIALOG_BOX_ABORT_BUTTON)) + pAbortLabel = abortLabel.GetUnicode(); + else + pAbortLabel = W("&Abort"); + if (debugLabel.LoadResource(CCompRC::Optional, IDS_DIALOG_BOX_DEBUG_BUTTON)) + pDebugLabel = debugLabel.GetUnicode(); + else + pDebugLabel = W("&Debug"); + if (ignoreLabel.LoadResource(CCompRC::Optional, IDS_DIALOG_BOX_IGNORE_BUTTON)) + pIgnoreLabel = ignoreLabel.GetUnicode(); + else + pIgnoreLabel = W("&Ignore"); + + const TASKDIALOG_BUTTON abortDebugIgnoreButtons[] = { + { IDOK, pAbortLabel }, + { IDRETRY, pDebugLabel }, + { IDIGNORE, pIgnoreLabel } + }; + config.pButtons = abortDebugIgnoreButtons; + config.cButtons = 3; + + HRESULT hr = pfnTaskDialogIndirect(&config, &nButtonPressed, NULL, NULL); + _ASSERTE(hr == S_OK); + if (hr == S_OK) { + result = nButtonPressed; + } + else { + result = IDOK; + } + + _ASSERTE(result == IDOK || result == IDRETRY || result == IDIGNORE); + } + + if (activatedActivationContext) { + DeactivateActCtx(0, cookie); + ReleaseActCtx(hActCtx); // perf isn't important so we won't bother caching the actctx + } + + return result; +#endif } int UtilMessageBoxVA( diff --git a/src/utilcode/winfix.cpp b/src/utilcode/winfix.cpp index d6bd59cac8..3a044865ec 100644 --- a/src/utilcode/winfix.cpp +++ b/src/utilcode/winfix.cpp @@ -231,6 +231,21 @@ BOOL RunningInteractive() if (fInteractive != -1) return fInteractive != 0; +#if !defined(FEATURE_CORESYSTEM) + HWINSTA hwinsta = NULL; + + if ((hwinsta = GetProcessWindowStation() ) != NULL) + { + DWORD lengthNeeded; + USEROBJECTFLAGS flags; + + if (GetUserObjectInformationW (hwinsta, UOI_FLAGS, &flags, sizeof(flags), &lengthNeeded)) + { + if ((flags.dwFlags & WSF_VISIBLE) == 0) + fInteractive = 0; + } + } +#endif // !FEATURE_CORESYSTEM if (fInteractive != 0) fInteractive = 1; |