/* -*- 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 .
*/
// we need to make sure we can create a thread in the remote process, if the handle was created // in something that doesn't give us appropriate levels of access then we will need to give it the // desired level of access - if the process handle was grabbed from OpenProcess it's quite possible // that the handle doesn't have the appropriate level of access...
bool bHaveDuplHdl = DuplicateHandle(GetCurrentProcess(), // handle to process that has handle
hProcess, // handle to be duplicated
GetCurrentProcess(), // process that will get the dup handle
&hDupProcess, // store duplicate process handle here
dwAccessFlags, // desired access FALSE, // handle can't be inherited
0); // zero means no additional action needed
if (bHaveDuplHdl)
hProcess = hDupProcess; // so we were able to duplicate the handle, all good... else
SAL_WARN("sal.osl", "Could not duplicate process handle, let's hope for the best...");
if (GetExitCodeProcess(hProcess, &dwProcessStatus) && (dwProcessStatus == STILL_ACTIVE))
{ // We need to get the address of the Win32 procedure ExitProcess, can't call it // directly because we'll be calling the thunk and that will probably lead to an // access violation. Once we have the address, then we need to create a new // thread in the process (which we might need to run in the address space of // another process) and then call on ExitProcess to try to cleanly terminate that // process
DWORD dwTID = 0; // dummy variable as we don't need to track the thread ID
// Note: we want to call on ExitProcess() and not TerminateProcess() - this is // because with ExitProcess() Windows notifies all attached dlls that the process // is detaching from the dll, but TerminateProcess() terminates all threads // immediately, doesn't call any termination handlers and doesn't notify any dlls // that it is detaching from them
HINSTANCE hKernel = GetModuleHandleW(L"kernel32.dll");
FARPROC pfnExitProc = GetProcAddress(hKernel, "ExitProcess");
hRemoteThread = CreateRemoteThread(
hProcess, /* process handle */
nullptr, /* default security descriptor */
0, /* initial size of stack in bytes is default
size for executable */ reinterpret_cast<LPTHREAD_START_ROUTINE>(pfnExitProc), /* Win32 ExitProcess() */ reinterpret_cast<PVOID>(UINT(0)), /* ExitProcess(UINT uExitCode) argument */
0, /* value of 0 tells thread to run immediately
after creation */
&dwTID); /* new remote thread's identifier */
}
bool bHasExited = false;
if (hRemoteThread)
{
WaitForSingleObject(hProcess, INFINITE); // wait for process to terminate, never stop waiting...
CloseHandle(hRemoteThread); // close the thread handle to allow the process to exit
bHasExited = true;
}
// need to close this duplicated process handle... if (bHaveDuplHdl)
CloseHandle(hProcess);
if (bHasExited) return osl_Process_E_None;
// fallback - given that we wait for an infinite time on WaitForSingleObject, this should // never occur... unless CreateRemoteThread failed
SAL_WARN("sal.osl", "TerminateProcess(hProcess, 0) called - we should never get here!"); return (TerminateProcess(hProcess, 0) == FALSE) ? osl_Process_E_Unknown : osl_Process_E_None;
}
oslProcessError SAL_CALL osl_setEnvironment(rtl_uString *ustrVar, rtl_uString *ustrValue)
{ // set Windows environment variable if (SetEnvironmentVariableW(o3tl::toW(ustrVar->buffer), o3tl::toW(ustrValue->buffer)))
{
_wputenv_s(o3tl::toW(ustrVar->buffer), o3tl::toW(ustrValue->buffer)); return osl_Process_E_None;
} return osl_Process_E_Unknown;
}
oslProcessError SAL_CALL osl_clearEnvironment(rtl_uString *ustrVar)
{ // delete the variable from the current process environment // by setting SetEnvironmentVariable's second parameter to NULL if (SetEnvironmentVariableW(o3tl::toW(ustrVar->buffer), nullptr))
{
_wputenv_s(o3tl::toW(ustrVar->buffer), L""); return osl_Process_E_None;
} return osl_Process_E_Unknown;
}
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 und die Messung sind noch experimentell.