[IPC]: Use an aux namedpipe to clear main namedpipe left by last process

This commit is contained in:
fanlumaster committed 2025-05-13 10:06:52 +08:00
1 parent 83d0854613
commit b0baf6f205
5 files changed
+120 -11

No files matched your search

+59 -1
View File
@@ -1,6 +1,8 @@
#include "event_listener.h"
#include <Windows.h>
#include <debugapi.h>
#include <ioapiset.h>
#include <namedpipeapi.h>
#include <string>
#include "Ipc.h"
#include "boost/algorithm/string/case_conv.hpp"
@@ -405,12 +407,14 @@ void EnqueueTask(TaskType type)
void EventListenerLoopThread()
{
int numEvents = FANY_IME_EVENT_ARRAY.size();
while (true)
{
spdlog::info("Pipe starts to wait");
OutputDebugString(L"Pipe starts to wait");
BOOL connected = ConnectNamedPipe(hPipe, NULL);
spdlog::info("Pipe connected: {}", connected);
OutputDebugString(fmt::format(L"Pipe connected: {}", connected).c_str());
::mainConnected = connected;
if (connected)
{
while (true)
@@ -427,6 +431,7 @@ void EventListenerLoopThread()
if (!readResult || bytesRead == 0) // Disconnected or error
{
// TODO: Log
OutputDebugString(L"Pipe disconnected or error");
break;
}
@@ -455,6 +460,7 @@ void EventListenerLoopThread()
{
// TODO:
}
OutputDebugString(L"Pipe disconnected");
DisconnectNamedPipe(hPipe);
}
@@ -462,4 +468,56 @@ void EventListenerLoopThread()
pipe_queueCv.notify_one();
::CloseNamedPipe();
}
void AuxPipeEventListenerLoopThread()
{
while (true)
{
spdlog::info("Aux Pipe starts to wait");
OutputDebugString(L"Aux Pipe starts to wait");
BOOL connected = ConnectNamedPipe(hAuxPipe, NULL);
spdlog::info("Aux Pipe connected: {}", connected);
OutputDebugString(fmt::format(L"Aux Pipe connected: {}", connected).c_str());
if (connected)
{
wchar_t buffer[128] = {0};
DWORD bytesRead = 0;
BOOL readResult = ReadFile( //
hAuxPipe, //
buffer, //
sizeof(buffer), //
&bytesRead, //
NULL //
);
if (!readResult || bytesRead == 0) // Disconnected or error
{
// TODO: Log
}
else
{
std::wstring message(buffer, bytesRead / sizeof(wchar_t));
OutputDebugString(message.c_str());
if (message == L"kill")
{
OutputDebugString(L"Aux Pipe to disconnect main pipe");
if (::mainConnected)
{
OutputDebugString(L"Really disconnect main pipe");
// DisconnectNamedPipe(hPipe);
CancelSynchronousIo(::mainPipeThread);
OutputDebugString(L"End disconnect main pipe");
}
}
}
}
else
{
// TODO:
}
OutputDebugString(L"Aux Pipe disconnected");
DisconnectNamedPipe(hAuxPipe);
}
::CloseAuxNamedPipe();
}
} // namespace FanyNamedPipe
+1
View File
@@ -22,4 +22,5 @@ namespace FanyNamedPipe
{
void WorkerThread();
void EventListenerLoopThread();
void AuxPipeEventListenerLoopThread();
} // namespace FanyNamedPipe
+46 -10
View File
@@ -1,4 +1,5 @@
#include "Ipc.h"
#include <debugapi.h>
#include <handleapi.h>
#include <minwindef.h>
#include <winbase.h>
@@ -8,6 +9,7 @@
#include "ipc.h"
#include "spdlog/spdlog.h"
#include "utils/common_utils.h"
#include "fmt/xchar.h"
#define LOW_INTEGRITY_SDDL_SACL \
SDDL_SACL \
@@ -164,16 +166,32 @@ int InitNamedPipe()
//
// Named Pipe
//
hPipe = CreateNamedPipe(FANY_IME_NAMED_PIPE, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE // message type pipe
| PIPE_READMODE_MESSAGE // message-read mode
| PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max instances
BUFFER_SIZE, // output buffer size
BUFFER_SIZE, // input buffer size
0, // client time-out
&sa // security attribute, for UWP/Metro apps
// Nmaedpipe for IME communication
hPipe = CreateNamedPipe( //
FANY_IME_NAMED_PIPE, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE // message type pipe
| PIPE_READMODE_MESSAGE // message-read mode
| PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max instances
BUFFER_SIZE, // output buffer size
BUFFER_SIZE, // input buffer size
0, // client time-out
&sa // security attribute, for UWP/Metro apps
);
// Nmaedpipe for reconnecting main pipe
hAuxPipe = CreateNamedPipe( //
FANY_IME_AUX_NAMED_PIPE, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE // message type pipe
| PIPE_READMODE_MESSAGE // message-read mode
| PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max instances
128, // output buffer size
128, // input buffer size
0, // client time-out
&sa // security attribute, for UWP/Metro apps
);
if (hPipe == INVALID_HANDLE_VALUE)
@@ -185,6 +203,15 @@ int InitNamedPipe()
spdlog::info("Named pipe created successfully");
}
if (hAuxPipe == INVALID_HANDLE_VALUE)
{
OutputDebugString(fmt::format(L"CreateNamedPipe aux pipe failed: {}", GetLastError()).c_str());
}
else
{
OutputDebugString(L"Named pipe aux pipe created successfully");
}
return 0;
}
@@ -238,6 +265,15 @@ int CloseNamedPipe()
return 0;
}
int CloseAuxNamedPipe()
{
if (hAuxPipe != INVALID_HANDLE_VALUE)
{
CloseHandle(hAuxPipe);
}
return 0;
}
int WriteDataToSharedMemory( //
const std::wstring &candidate_string, //
bool write_flag //
+5
View File
@@ -9,7 +9,11 @@ inline const wchar_t *FANY_IME_SHARED_MEMORY = L"Local\\FanyImeSharedMemory";
inline const int BUFFER_SIZE = 4096;
inline const wchar_t *FANY_IME_NAMED_PIPE = L"\\\\.\\pipe\\FanyImeNamedPipe";
inline const wchar_t *FANY_IME_AUX_NAMED_PIPE = L"\\\\.\\pipe\\FanyImeAuxNamedPipe";
inline HANDLE hPipe = INVALID_HANDLE_VALUE;
inline HANDLE hAuxPipe = INVALID_HANDLE_VALUE;
inline bool mainConnected = false;
inline HANDLE mainPipeThread = NULL;
//
// Events from tsf to server
@@ -67,6 +71,7 @@ int InitIpc();
int InitNamedPipe();
int CloseIpc();
int CloseNamedPipe();
int CloseAuxNamedPipe();
int WriteDataToSharedMemory( //
const std::wstring &candidate_string, //
bool write_flag //
+9
View File
@@ -25,9 +25,16 @@ int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In
std::thread worker(WorkerThread);
std::thread listener(EventListenerLoopThread);
//
// Pipe
//
// Named Pipe for IPC between tsf and server
std::thread pipe_worker(FanyNamedPipe::WorkerThread);
std::thread pipe_listener(FanyNamedPipe::EventListenerLoopThread);
::mainPipeThread = pipe_listener.native_handle();
// Aux Named Pipe for reconnecting main pipe
std::thread aux_pipe_listener(FanyNamedPipe::AuxPipeEventListenerLoopThread);
int ret = CreateCandidateWindow(hInstance);
@@ -41,5 +48,7 @@ int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In
pipe_worker.join();
pipe_listener.join();
aux_pipe_listener.join();
return ret;
}