Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 42 additions & 41 deletions src/plugins/shared/mhandles.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-FileCopyrightText: 2023 Open Salamander Authors
// SPDX-License-Identifier: GPL-2.0-or-later
// CommentsTranslationProject: TRANSLATED

//****************************************************************************
//
Expand Down Expand Up @@ -37,7 +38,7 @@ C__Handles __Handles;

//*****************************************************************************
//
// vlozeny modul MESSAGES (zobrazovani messageboxu v aktualnim nebo vlastnim threadu)
// included module MESSAGES (displaying messagebox in current or new thread)
//
//*****************************************************************************

Expand All @@ -51,15 +52,15 @@ char __ErrorBuffer[__ERROR_BUFFER_SIZE] = "";
const char* __MessagesTitle = "Message";
HWND __MessagesParent = NULL;

// zajisti aktualnimu threadu pristup k funkcim a datum modulu
// provides access to functions and data of module to current thread
void EnterMessagesModul();
// volat az aktualni thread nebude potrebovat pristup k funkcim a datum modulu
// call once the current thread does not need access to functions and data of module
void LeaveMessagesModul();

/// vraci ukazatel na globalni buffer, ktery naplni retezcem z sprintf
/// returns pointer to global buffer, which is filled with sprintf string
const char* spf(const char* formatString, ...);

/// vraci ukazatel na globalni buffer, ktery naplni popisem chyby
/// returns pointer to global buffer, which is filled with error description
const char* err(DWORD error);

#define MESSAGE(parent, str, buttons) \
Expand All @@ -75,22 +76,22 @@ const char* err(DWORD error);
.MessageBoxT(__MessagesStringBuf.c_str(), \
__MessagesTitle, (buttons))

/** zobrazi messagebox se zadanym textem a ikonou chyby, neni v novem
threadu, distribuje message volajiciho threadu */
/** shows messagebox with given text and icon of the error, is not in new thread,
* distributes message of calling thread */
#define MESSAGE_E(parent, str, buttons) \
MESSAGE(parent, str, MB_ICONEXCLAMATION | (buttons))

/** zobrazi messagebox se zadanym textem a ikonou informaci, v novem threadu,
nerozdistribuje message volajiciho threadu */
/** shows messagebox with given text and icon of the information, in new thread,
does not distribute message of calling thread */
#define MESSAGE_TI(str, buttons) \
MESSAGE_T(str, MB_ICONINFORMATION | (buttons))

/** zobrazi messagebox se zadanym textem a ikonou chyby, v novem threadu,
nerozdistribuje message volajiciho threadu */
/** shows messagebox with given text and icon of the error, in new thread,
does not distribute message of calling thread */
#define MESSAGE_TE(str, buttons) \
MESSAGE_T(str, MB_ICONEXCLAMATION | (buttons))

// kriticka sekce pro cely modul - monitor
// critical section for whole module - monitor
CRITICAL_SECTION __MessagesCriticalSection;

const char* __MessagesLowMemory = "Insufficient memory.";
Expand Down Expand Up @@ -131,62 +132,62 @@ struct C__MessageBoxData
};

int CALLBACK __MessagesMessageBoxThreadF(C__MessageBoxData* data)
{ // nesmi cekat na odezvu volajiciho threadu, protoze ten nebude reagovat
// proto je parent==NULL -> zadne disablovani oken atd.
{ // must not wait for response of calling thread, because it will not react
// therefore parent==NULL -> no disabling of windows etc.
data->Return = MessageBox(NULL, data->Text, data->Caption, data->Type | MB_SETFOREGROUND);
return 0;
}

int C__Messages::MessageBoxT(LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
__Handles.__MessagesStrStream.flush(); // flushnuti do bufferu (v lpText)
__Handles.__MessagesStrStream.flush(); // flush to buffer (in lpText)

C__MessageBoxData data;
data.Caption = lpCaption;
data.Type = uType;
data.Return = 0;

int len = (int)strlen(lpText) + 1;
char* message = (char*)malloc(len); // zaloha textu
char* message = (char*)malloc(len); // text backup
if (message != NULL)
{
memcpy(message, lpText, len);
data.Text = message;
}
else
data.Text = __MessagesLowMemory;
LeaveMessagesModul(); // ted uz muzou zacit blbnout ostatni thready + message loopy
LeaveMessagesModul(); // now other threads + message loops can start to mess

// MessageBox nahodime v novem threadu, aby nerozeslal message tohoto threadu
// MessageBox in new thread, so it does not send message to this thread
DWORD threadID;
HANDLE thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)__MessagesMessageBoxThreadF, &data, 0, &threadID);
if (thread != NULL)
{
WaitForSingleObject(thread, INFINITE); // pockame az ho user odmackne
WaitForSingleObject(thread, INFINITE); // wait until user confirms
CloseHandle(thread);
}
// else TRACE_E("Unable to show MessageBox: " << data.Caption << ": " << data.Text);

if (message != NULL)
free(message);

__MessagesStringBuf.erase(); // priprava pro dalsi message
__MessagesStringBuf.erase(); // prepare for next message

return data.Return;
}

int C__Messages::MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
__Handles.__MessagesStrStream.flush(); // flushnuti do bufferu (v lpText)
__Handles.__MessagesStrStream.flush(); // flush to buffer (in lpText)

int len = (int)strlen(lpText) + 1;
char* message = (char*)malloc(len); // zaloha textu
char* message = (char*)malloc(len); // text backup
char* txt = message;
if (txt != NULL)
memcpy(txt, lpText, len);
else
txt = (char*)__MessagesLowMemory;
LeaveMessagesModul(); // ted uz muzou zacit blbnout ostatni thready + message loopy
LeaveMessagesModul(); // now other threads + message loops can start to mess

if (!IsWindow(hWnd))
hWnd = NULL;
Expand All @@ -195,7 +196,7 @@ int C__Messages::MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT u
if (message != NULL)
free(message);

__MessagesStringBuf.erase(); // priprava pro dalsi message
__MessagesStringBuf.erase(); // prepare for next message

return ret;
}
Expand Down Expand Up @@ -232,7 +233,7 @@ const char* err(DWORD error)

//*****************************************************************************
//
// konec vlozeneho modulu MESSAGES
// the end of included module MESSAGES
//
//*****************************************************************************

Expand Down Expand Up @@ -678,7 +679,7 @@ C__Handles::C__Handles() : __MessagesStrStream(&__MessagesStringBuf), __Messages

C__Handles::~C__Handles()
{
// vyrazeni handlu, ktere se uvolnuji automaticky
// exclude handles, which are released automatically
for (int i = Handles.Count - 1; i >= 0; i--)
{
if (Handles[i].Handle.Origin == __hoLoadAccelerators)
Expand All @@ -688,7 +689,7 @@ C__Handles::~C__Handles()
else if (Handles[i].Handle.Origin == __hoGetStockObject)
Handles.Delete(i);
}
// kontrola + vypis zbylych
// check + print of the remaining
if (Handles.Count != 0)
{
if (MESSAGE_E(NULL, "Some monitored handles remained opened.\n"
Expand All @@ -697,7 +698,7 @@ C__Handles::~C__Handles()
{
if (CanUseTrace)
{
SalamanderDebug->TraceConnectToServer(); // v pripade, ze nebyl nahozeny server
SalamanderDebug->TraceConnectToServer(); // in case that server was not started
TRACE_I("List of opened handles:");
for (int i = 0; i < Handles.Count; i++)
{
Expand All @@ -716,7 +717,7 @@ C__Handles::~C__Handles()
{
if (CanUseTrace)
{
SalamanderDebug->TraceConnectToServer(); // v pripade, ze nebyl nahozeny server
SalamanderDebug->TraceConnectToServer(); // in case that server was not started
TRACE_I(__HandlesMessageNumberOpened << Handles.Count);
}
}
Expand All @@ -735,7 +736,7 @@ C__Handles::SetInfo(const char* file, int line, C__HandlesOutputType outputType)
::EnterCriticalSection(&CriticalSection);
if (CriticalSection.RecursionCount > 1)
{
DebugBreak(); // rekurzivni volani handles !!! zase nejaka maskovana message-loopa - viz call-stack
DebugBreak(); // recursive call of handles !!! a masked message-loop again - see call-stack
}
OutputType = outputType;
TemporaryHandle.File = file;
Expand Down Expand Up @@ -838,7 +839,7 @@ BOOL C__Handles::DeleteHandle(C__HandlesType& type, HANDLE handle,
{
C__HandlesOrigin org = Handles[i].Handle.Origin;
if (org != __hoLoadAccelerators && org != __hoLoadIcon &&
org != __hoGetStockObject) // nejde o handle, ktery nemusi byt uvolneny (prioritne uvolnujeme handly, ktere se musi uvolnit)
org != __hoGetStockObject) // not a handle, which doesn't have to be released (priority is to release handles, which have to be released)
{
if (origin != NULL)
*origin = org;
Expand All @@ -853,15 +854,15 @@ BOOL C__Handles::DeleteHandle(C__HandlesType& type, HANDLE handle,
}
}
}
if (foundTypeOK != -1) // nalezen jen handle, ktery nemusi byt uvolneny
if (foundTypeOK != -1) // found only handle, which doesn't have to be released
{
type = Handles[foundTypeOK].Handle.Type;
if (origin != NULL)
*origin = Handles[foundTypeOK].Handle.Origin;
Handles.Delete(foundTypeOK);
return TRUE;
}
if (found != -1) // nalezen jen handle se shodnym cislem
if (found != -1) // found only handle with matching number
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

matching -> same

{
#if defined(_DEBUG) || defined(__HANDLES_DEBUG)
if (CanUseTrace)
Expand Down Expand Up @@ -1101,7 +1102,7 @@ HDC C__Handles::BeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint)
C__HandlesData tmpTemporaryHandle = TemporaryHandle;
::LeaveCriticalSection(&CriticalSection);

HDC ret = ::BeginPaint(hwnd, lpPaint); // obsahuje message-loopu
HDC ret = ::BeginPaint(hwnd, lpPaint); // contains message-loop

::EnterCriticalSection(&CriticalSection);
OutputType = tmpOutputType;
Expand Down Expand Up @@ -1931,8 +1932,8 @@ BOOL C__Handles::DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHand
MB_OK);
}

// GetCurrentProcess vraci jakysi pseudohandle, takze tahle konstrukce
// neni spravna, meli by se porovnat ID procesu a ne jejich handly ...
// GetCurrentProcess return some pseudohandle, so this is not correct
// way, we should compare process IDs and not their handles ...

if ((dwOptions & DUPLICATE_CLOSE_SOURCE) &&
hSourceProcessHandle == GetCurrentProcess())
Expand Down Expand Up @@ -2135,7 +2136,7 @@ BOOL C__Handles::FreeLibrary(HMODULE hLibModule)
C__HandlesData tmpTemporaryHandle = TemporaryHandle;
::LeaveCriticalSection(&CriticalSection);

BOOL ret = ::FreeLibrary(hLibModule); // obsahuje volani destruktoru globalek DLLka, muze obsahovat message-loopu
BOOL ret = ::FreeLibrary(hLibModule); // contains call to DLL destructor, may contain message-loop
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// contains calls to the destructors of the DLL's globals, may contain a message-loop


::EnterCriticalSection(&CriticalSection);
OutputType = tmpOutputType;
Expand All @@ -2151,7 +2152,7 @@ VOID C__Handles::FreeLibraryAndExitThread(HMODULE hLibModule, DWORD dwExitCode)
C__HandlesData tmpTemporaryHandle = TemporaryHandle;
::LeaveCriticalSection(&CriticalSection);

::FreeLibraryAndExitThread(hLibModule, dwExitCode); // obsahuje volani destruktoru globalek DLLka, muze obsahovat message-loopu
::FreeLibraryAndExitThread(hLibModule, dwExitCode); // contains call to DLL destructor, may contain message-loop
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// contains calls to the destructors of the DLL's globals, may contain a message-loop


::EnterCriticalSection(&CriticalSection);
OutputType = tmpOutputType;
Expand Down Expand Up @@ -2231,7 +2232,7 @@ BOOL C__Handles::FindCloseChangeNotification(HANDLE hChangeHandle)
C__HandlesData tmpTemporaryHandle = TemporaryHandle;
::LeaveCriticalSection(&CriticalSection);

BOOL ret = ::FindCloseChangeNotification(hChangeHandle); // muze se kousnout i na dost dlouho
BOOL ret = ::FindCloseChangeNotification(hChangeHandle); // can stuck for quite long time

::EnterCriticalSection(&CriticalSection);
OutputType = tmpOutputType;
Expand Down Expand Up @@ -2386,7 +2387,7 @@ HDWP C__Handles::DeferWindowPos(HDWP hWinPosInfo, HWND hWnd, HWND hWndInsertAfte
{
HDWP ret = ::DeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);

if (ret != hWinPosInfo) // doslo k realokaci struktury - musime zmenit hodnotu hlidaneho handlu
if (ret != hWinPosInfo) // structure reallocation occured - we must change value of watched handle
{
CheckClose(TRUE, (HANDLE)hWinPosInfo, __htDeferWindowPos, __GetHandlesOrigin(__hoDeferWindowPos), ERROR_SUCCESS, FALSE);
CheckCreate(ret != NULL, __htDeferWindowPos, __hoDeferWindowPos, (HANDLE)ret, GetLastError());
Expand All @@ -2404,7 +2405,7 @@ BOOL C__Handles::EndDeferWindowPos(HDWP hWinPosInfo)
C__HandlesData tmpTemporaryHandle = TemporaryHandle;
::LeaveCriticalSection(&CriticalSection);

BOOL ret = ::EndDeferWindowPos(hWinPosInfo); // obsahuje message-loopu
BOOL ret = ::EndDeferWindowPos(hWinPosInfo); // contains message-loop

::EnterCriticalSection(&CriticalSection);
OutputType = tmpOutputType;
Expand Down
39 changes: 20 additions & 19 deletions src/plugins/shared/mhandles.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-FileCopyrightText: 2023 Open Salamander Authors
// SPDX-License-Identifier: GPL-2.0-or-later
// CommentsTranslationProject: TRANSLATED

//****************************************************************************
//
Expand All @@ -11,19 +12,19 @@

#pragma once

// makro MHANDLES_ENABLE - zapina monitorovani handlu
// POZOR: volat HANDLES_CAN_USE_TRACE() tesne po inicializaci "dbg.h" modulu
// (po inicializaci SalamanderDebug a SalamanderVersion)
// POZOR: MHANDLES se inicializuji/rusi na urovni "lib", pokud tedy plugin
// uroven "lib" (nebo "compiler") pouziva, musi si sam zajistit, ze na
// techto urovnich nebude pouzivat MHANDLES (viz #pragma init_seg (lib))
// POZNAMKA: pro snazsi rozmisteni maker HANDLES() a HANDLES_Q() pouzijte program CheckHnd.exe
// macro MHANDLES_ENABLE - enables monitoring of handles
// CAUTION: call HANDLES_CAN_USE_TRACE() immediately after initialization of
// "dbg.h" module (after initialization of SalamanderDebug and SalamanderVersion)
// CAUTION: MHANDLES are initialized/destroyed on "lib" level, so if plugin
// uses "lib" level (or "compiler" level), it must ensure that it will
// not use MHANDLES on these levels (see #pragma init_seg (lib))
// NOTE: for easier placement of HANDLES() and HANDLES_Q() macros use CheckHnd.exe program

#define NOHANDLES(function) function

#ifndef MHANDLES_ENABLE

// aby nedochazelo k problemum se stredniky v nize nadefinovanych makrech
// so that no problems with semicolons in the below defined macros occur
inline void __HandlesEmptyFunction() {}

#define HANDLES_CAN_USE_TRACE() __HandlesEmptyFunction()
Expand Down Expand Up @@ -54,8 +55,8 @@ enum C__HandlesOutputType

enum C__HandlesType
{
__htHandle_comp_with_CloseHandle, // handle kompatibilni s CloseHandle() a DuplicateHandle()
__htHandle_comp_with_DeleteObject, // handle kompatibilni s DeleteObject() a GetStockObject()
__htHandle_comp_with_CloseHandle, // DeleteObject() and GetStockObject() compatible handle
__htHandle_comp_with_DeleteObject, // DeleteObject() and GetStockObject() compatible handle
__htKey,
__htIcon,
__htGlobal,
Expand Down Expand Up @@ -220,7 +221,7 @@ struct C__HandlesHandle
{
C__HandlesType Type;
C__HandlesOrigin Origin;
HANDLE Handle; // univerzalni, pro vsechny druhy handlu
HANDLE Handle; // universal, for all types of handles

C__HandlesHandle() {}

Expand Down Expand Up @@ -284,16 +285,16 @@ typedef unsigned int uintptr_t;
class C__Handles
{
public:
// objekty pro praci s messageboxy, zde je jen pro zaruceni poradi konstrukce/destrukce
// objects for work with messages boxes, here is only for guarantee of construction/destruction order
std::ostream __MessagesStrStream;
C__Messages __Messages;

protected:
C_HandlesDataArray Handles; // vsechny kontrolovane handly
C__HandlesData TemporaryHandle; // pri vkladani nastaven z SetInfo()
C__HandlesOutputType OutputType; // typ vystupu hlasek
CRITICAL_SECTION CriticalSection; // pro synchronizaci multi-threadu
BOOL CanUseTrace; // TRUE az po inicializaci "dbg.h" modulu, az bude mozne pouzivat TRACE_ makra
C_HandlesDataArray Handles; // all checked handles
C__HandlesData TemporaryHandle; // set from SetInfo() when inserting
C__HandlesOutputType OutputType; // type of messages output
CRITICAL_SECTION CriticalSection; // to synchronize multi-thread access
BOOL CanUseTrace; // TRUE after initialization of "dbg.h" module, after that TRACE_ macros can be used

public:
C__Handles();
Expand Down Expand Up @@ -677,9 +678,9 @@ class C__Handles
BOOL OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);

protected:
void AddHandle(C__HandlesHandle handle); // prida TemporaryHandle
void AddHandle(C__HandlesHandle handle); // adds TemporaryHandle

// vyjme handle, pri uspechu vraci TRUE
// removes handle, returns TRUE on success
BOOL DeleteHandle(C__HandlesType& type, HANDLE handle,
C__HandlesOrigin* origin,
C__HandlesType expType);
Expand Down