/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
/* size of the table */ #define ERRTABLESIZE (SAL_N_ELEMENTS(errtable))
/* The following two constants must be the minimum and maximum
values in the (contiguous) range of osl_File_E_xec Failure errors. */ #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
/* These are the low and high value in the range of errors that are
access violations */ #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
/* check the table for the OS error code */ for ( i = 0; i < ERRTABLESIZE; ++i )
{ if ( dwError == errtable[i].oscode ) returnstatic_cast<oslFileError>(errtable[i].errnocode);
}
/* The error code wasn't in the table. We check for a range of */ /* osl_File_E_ACCES errors or exec failure errors (ENOEXEC). Otherwise */ /* osl_File_E_INVAL is returned. */
CSysShExec::CSysShExec( const css::uno::Reference< css::uno::XComponentContext >& xContext ) :
WeakComponentImplHelper< css::system::XSystemShellExecute, css::lang::XServiceInfo >( m_aMutex ),
m_xContext(xContext),
mnNbCallCoInitializeExForReinit(0)
{ /* * As this service is declared thread-affine, it is ensured to be called from a * dedicated thread, so initialize COM here. * * We need COM to be initialized for STA, but osl thread get initialized for MTA. * Once this changed, we can remove the uninitialize call.
*/
o3tl::safeCoInitializeEx(COINIT_APARTMENTTHREADED, mnNbCallCoInitializeExForReinit);
}
CSysShExec::~CSysShExec()
{
o3tl::safeCoUninitializeReinit(COINIT_MULTITHREADED, mnNbCallCoInitializeExForReinit);
}
namespace
{ bool checkExtension(std::u16string_view extension, std::u16string_view denylist) {
assert(!extension.empty()); for (std::size_t i = 0; i != std::u16string_view::npos;) {
std::u16string_view tok = o3tl::getToken(denylist, ';', i);
o3tl::starts_with(tok, u'.', &tok); if (o3tl::equalsIgnoreAsciiCase(extension, tok)) { returnfalse;
}
} returntrue;
}
// This callback checks if the found window is the specified process's top-level window, // and activates the first found such window. BOOL CALLBACK FindAndActivateProcWnd(HWND hwnd, LPARAM lParam)
{ if (!IsWindowVisible(hwnd)) returnTRUE; // continue enumeration if (GetWindow(hwnd, GW_OWNER)) // not a top-level window returnTRUE; // continue enumeration const DWORD nParamProcId = static_cast<DWORD>(lParam);
assert(nParamProcId != 0);
DWORD nWndProcId = 0;
(void)GetWindowThreadProcessId(hwnd, &nWndProcId); if (nWndProcId != nParamProcId) returnTRUE; // continue enumeration
// Found it! Bring it to front if (IsIconic(hwnd))
{
ShowWindow(hwnd, SW_RESTORE);
}
SetForegroundWindow(hwnd);
SetActiveWindow(hwnd); returnFALSE; // stop enumeration
}
sei.cbSize = sizeof(sei);
sei.lpFile = o3tl::toW(preprocessed_command.getStr());
sei.lpParameters = o3tl::toW(aParameter.getStr());
sei.nShow = SW_SHOWNORMAL;
sei.fMask = SEE_MASK_NOCLOSEPROCESS; // we need sei.hProcess
if (NO_SYSTEM_ERROR_MESSAGE & nFlags)
sei.fMask |= SEE_MASK_FLAG_NO_UI;
SetLastError( 0 );
bool bRet = ShellExecuteExW(&sei);
if (!bRet && (nFlags & NO_SYSTEM_ERROR_MESSAGE))
{ // ShellExecuteEx fails to set an error code // we return osl_File_E_INVAL
sal_Int32 psxErr = GetLastError(); if (ERROR_SUCCESS == psxErr)
psxErr = E_UNKNOWN_EXEC_ERROR; else
psxErr = MapError(psxErr);
throw css::system::SystemShellExecuteException( "Error executing command", static_cast< css::system::XSystemShellExecute* >(this),
psxErr);
} else
{ // Get Permission make changes to the Window of the created Process const DWORD procId = GetProcessId(sei.hProcess); if (procId != 0)
{
AllowSetForegroundWindow(procId);
WaitForInputIdle(sei.hProcess, 1000); // so that main window is created; imperfect
EnumWindows(FindAndActivateProcWnd, static_cast<LPARAM>(procId));
}
}
// Close the handle for the created childprocess when we are done
CloseHandle(sei.hProcess);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.