Global Metrics
path: .metrics.cognitive.average
old: null
new: 6.5
path: .metrics.cognitive.sum
old: 0.0
new: 13.0
path: .metrics.halstead.bugs
old: 0.1977836264317013
new: 0.5353574040631274
path: .metrics.halstead.estimated_program_length
old: 941.43714070668
new: 598.6151411030505
path: .metrics.halstead.purity_ratio
old: 2.760812729345102
new: 1.3098799586500012
path: .metrics.halstead.difficulty
old: 5.953846153846154
new: 21.198795180722893
path: .metrics.halstead.length
old: 341.0
new: 457.0
path: .metrics.halstead.level
old: 0.16795865633074936
new: 0.047172492185279906
path: .metrics.halstead.volume
old: 2427.5589057987163
new: 3036.242278727049
path: .metrics.halstead.time
old: 802.9617919180369
new: 3575.8154547658924
path: .metrics.halstead.vocabulary
old: 139.0
new: 100.0
path: .metrics.halstead.N1
old: 169.0
new: 250.0
path: .metrics.halstead.effort
old: 14453.312254524664
new: 64364.67818578606
path: .metrics.halstead.n1
old: 9.0
new: 17.0
path: .metrics.halstead.N2
old: 172.0
new: 207.0
path: .metrics.halstead.n2
old: 130.0
new: 83.0
path: .metrics.nexits.average
old: null
new: 7.0
path: .metrics.nexits.sum
old: 0.0
new: 14.0
path: .metrics.nom.functions
old: 0.0
new: 2.0
path: .metrics.nom.total
old: 0.0
new: 2.0
path: .metrics.loc.ploc
old: 120.0
new: 116.0
path: .metrics.loc.sloc
old: 177.0
new: 178.0
path: .metrics.loc.blank
old: 21.0
new: 23.0
path: .metrics.loc.cloc
old: 36.0
new: 39.0
path: .metrics.loc.lloc
old: 0.0
new: 37.0
path: .metrics.nargs.sum
old: 0.0
new: 6.0
path: .metrics.nargs.average
old: null
new: 3.0
path: .metrics.mi.mi_sei
old: 22.559158504210373
new: 18.99153817329197
path: .metrics.mi.mi_visual_studio
old: 26.587274099178423
new: 24.239503866311473
path: .metrics.mi.mi_original
old: 45.46423870959511
new: 41.44955161139262
path: .metrics.cyclomatic.sum
old: 5.0
new: 17.0
path: .metrics.cyclomatic.average
old: 1.0
new: 4.25
Spaces Data
Minimal test - lines (31, 176)
path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 13.0
path: .spaces[0].metrics.cognitive.average
old: null
new: 6.5
path: .spaces[0].metrics.halstead.effort
old: 569.4926420467566
new: 64689.67135961617
path: .spaces[0].metrics.halstead.N1
old: 20.0
new: 250.0
path: .spaces[0].metrics.halstead.bugs
old: 0.022901863585278907
new: 0.5371579921780201
path: .spaces[0].metrics.halstead.length
old: 46.0
new: 452.0
path: .spaces[0].metrics.halstead.n2
old: 19.0
new: 79.0
path: .spaces[0].metrics.halstead.N2
old: 26.0
new: 202.0
path: .spaces[0].metrics.halstead.time
old: 31.6384801137087
new: 3593.8706310897874
path: .spaces[0].metrics.halstead.vocabulary
old: 23.0
new: 96.0
path: .spaces[0].metrics.halstead.difficulty
old: 2.736842105263158
new: 21.73417721518987
path: .spaces[0].metrics.halstead.n1
old: 4.0
new: 17.0
path: .spaces[0].metrics.halstead.estimated_program_length
old: 88.71062275542812
new: 567.4855474072469
path: .spaces[0].metrics.halstead.level
old: 0.36538461538461536
new: 0.046010483401281305
path: .spaces[0].metrics.halstead.purity_ratio
old: 1.9284917990310464
new: 1.2554989986885994
path: .spaces[0].metrics.halstead.volume
old: 208.0838499786226
new: 2976.4030503259623
path: .spaces[0].metrics.nexits.average
old: null
new: 7.0
path: .spaces[0].metrics.nexits.sum
old: 0.0
new: 14.0
path: .spaces[0].metrics.loc.cloc
old: 1.0
new: 30.0
path: .spaces[0].metrics.loc.lloc
old: 0.0
new: 37.0
path: .spaces[0].metrics.loc.sloc
old: 9.0
new: 146.0
path: .spaces[0].metrics.loc.ploc
old: 9.0
new: 99.0
path: .spaces[0].metrics.loc.blank
old: 0.0
new: 17.0
path: .spaces[0].metrics.nom.functions
old: 0.0
new: 2.0
path: .spaces[0].metrics.nom.total
old: 0.0
new: 2.0
path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 5.333333333333333
path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 16.0
path: .spaces[0].metrics.mi.mi_sei
old: 104.05944704336017
new: 23.13692890628377
path: .spaces[0].metrics.mi.mi_original
old: 107.41766800565247
new: 44.99352446245318
path: .spaces[0].metrics.mi.mi_visual_studio
old: 62.81734971090789
new: 26.312002609621743
path: .spaces[0].metrics.nargs.average
old: null
new: 3.0
path: .spaces[0].metrics.nargs.sum
old: 0.0
new: 6.0
Code
namespace mozilla {
/**
* Ask the current user's Desktop to ShellExecute on our behalf, thus causing
* the resulting launched process to inherit its security priviliges from
* Explorer instead of our process.
*
* This is useful in two scenarios, in particular:
* * We are running as an elevated user and we want to start something as the
* "normal" user;
* * We are starting a process that is incompatible with our process's
* process mitigation policies. By delegating to Explorer, the child process
* will not be affected by our process mitigations.
*
* Since this communication happens over DCOM, Explorer's COM DACL governs
* whether or not we can execute against it, thus avoiding privilege escalation.
*/
inline LauncherVoidResult ShellExecuteByExplorer(const _bstr_t& aPath,
const _variant_t& aArgs,
const _variant_t& aVerb,
const _variant_t& aWorkingDir,
const _variant_t& aShowCmd) {
// NB: Explorer may be a local server, not an inproc server
RefPtr shellWindows;
HRESULT hr = ::CoCreateInstance(
CLSID_ShellWindows, nullptr, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
IID_IShellWindows, getter_AddRefs(shellWindows));
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
// 1. Find the shell view for the desktop.
_variant_t loc(int(CSIDL_DESKTOP));
_variant_t empty;
long hwnd;
RefPtr dispDesktop;
hr = shellWindows->FindWindowSW(&loc, &empty, SWC_DESKTOP, &hwnd,
SWFO_NEEDDISPATCH,
getter_AddRefs(dispDesktop));
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
if (hr == S_FALSE) {
// The call succeeded but the window was not found.
return LAUNCHER_ERROR_FROM_WIN32(ERROR_NOT_FOUND);
}
RefPtr servProv;
hr = dispDesktop->QueryInterface(IID_IServiceProvider,
getter_AddRefs(servProv));
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
RefPtr browser;
hr = servProv->QueryService(SID_STopLevelBrowser, IID_IShellBrowser,
getter_AddRefs(browser));
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
RefPtr activeShellView;
hr = browser->QueryActiveShellView(getter_AddRefs(activeShellView));
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
// 2. Get the automation object for the desktop.
RefPtr dispView;
hr = activeShellView->GetItemObject(SVGIO_BACKGROUND, IID_IDispatch,
getter_AddRefs(dispView));
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
RefPtr folderView;
hr = dispView->QueryInterface(IID_IShellFolderViewDual,
getter_AddRefs(folderView));
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
// 3. Get the interface to IShellDispatch2
RefPtr dispShell;
hr = folderView->get_Application(getter_AddRefs(dispShell));
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
RefPtr shellDisp;
hr =
dispShell->QueryInterface(IID_IShellDispatch2, getter_AddRefs(shellDisp));
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
// Passing the foreground privilege so that the shell can launch an
// application in the foreground. This fails with E_ACCESSDENIED if the
// current window is shown in the background. We keep a soft assert for
// the other failures to investigate how it happened.
hr = ::CoAllowSetForegroundWindow(shellDisp, nullptr);
MOZ_ASSERT(SUCCEEDED(hr) || hr == E_ACCESSDENIED);
// shellapi.h macros interfere with the correct naming of the method being
// called on IShellDispatch2. Temporarily remove that definition.
#if defined(ShellExecute)
# define MOZ_REDEFINE_SHELLEXECUTE
# undef ShellExecute
#endif // defined(ShellExecute)
// 4. Now call IShellDispatch2::ShellExecute to ask Explorer to execute.
hr = shellDisp->ShellExecute(aPath, aArgs, aWorkingDir, aVerb, aShowCmd);
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
// Restore the macro that was removed prior to IShellDispatch2::ShellExecute
#if defined(MOZ_REDEFINE_SHELLEXECUTE)
# if defined(UNICODE)
# define ShellExecute ShellExecuteW
# else
# define ShellExecute ShellExecuteA
# endif
# undef MOZ_REDEFINE_SHELLEXECUTE
#endif // defined(MOZ_REDEFINE_SHELLEXECUTE)
return Ok();
}
using UniqueAbsolutePidl =
UniquePtr, CoTaskMemFreeDeleter>;
inline LauncherResult ShellParseDisplayName(
const wchar_t* aPath) {
PIDLIST_ABSOLUTE rawAbsPidl = nullptr;
SFGAOF sfgao;
HRESULT hr = ::SHParseDisplayName(aPath, nullptr, &rawAbsPidl, 0, &sfgao);
if (FAILED(hr)) {
return LAUNCHER_ERROR_FROM_HRESULT(hr);
}
return UniqueAbsolutePidl(rawAbsPidl);
}
} // namespace mozilla