summaryrefslogtreecommitdiff
path: root/src/utilcode
diff options
context:
space:
mode:
authordanmosemsft <danmose@microsoft.com>2017-02-11 07:20:12 -0800
committerdanmosemsft <danmose@microsoft.com>2017-02-11 07:20:12 -0800
commit56d4ba8a9338c3ff7378d18378f38ad847f130f2 (patch)
tree40b9463880286b1bc0b4c3f858680f1ff210c933 /src/utilcode
parent8be2f9bb0039e2c49f59c4fb66cebf5467485ba2 (diff)
downloadcoreclr-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.cpp122
-rw-r--r--src/utilcode/sstring.cpp8
-rw-r--r--src/utilcode/util.cpp53
-rw-r--r--src/utilcode/utilmessagebox.cpp165
-rw-r--r--src/utilcode/winfix.cpp15
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;