code_app/modules/base/HGNamedPipe.cpp

622 lines
15 KiB
C++
Raw Blame History

#include "HGNamedPipe.h"
#include "HGInc.h"
#include "HGThread.h"
#include <string>
struct HGNamedPipeServerImpl
{
HGNamedPipeServerImpl()
{
#if defined(HG_CMP_MSC)
m_hConnectEvent = NULL;
m_hWriteEvent = NULL;
m_hReadEvent = NULL;
m_hProcessEvent = NULL;
m_hPipe = INVALID_HANDLE_VALUE;
m_clientPid = 0;
m_thread = NULL;
m_error = HGFALSE;
m_break = HGFALSE;
#else
// TODO
#endif
}
~HGNamedPipeServerImpl()
{
#if defined(HG_CMP_MSC)
HGBase_CloseThread(m_thread);
m_thread = NULL;
CloseHandle(m_hPipe);
m_hPipe = INVALID_HANDLE_VALUE;
CloseHandle(m_hProcessEvent);
m_hProcessEvent = NULL;
CloseHandle(m_hReadEvent);
m_hReadEvent = NULL;
CloseHandle(m_hWriteEvent);
m_hWriteEvent = NULL;
CloseHandle(m_hConnectEvent);
m_hConnectEvent = NULL;
#else
// TODO
#endif
}
#if defined(HG_CMP_MSC)
HANDLE m_hConnectEvent;
HANDLE m_hWriteEvent;
HANDLE m_hReadEvent;
HANDLE m_hProcessEvent;
HANDLE m_hPipe;
DWORD m_clientPid;
HGThread m_thread;
HGBool m_error;
HGBool m_break;
#else
// TODO
#endif
};
struct HGNamedPipeClientImpl
{
HGNamedPipeClientImpl()
{
#if defined(HG_CMP_MSC)
m_hWriteEvent = NULL;
m_hReadEvent = NULL;
m_hProcessEvent = NULL;
m_hPipe = INVALID_HANDLE_VALUE;
m_serverPid = 0;
m_thread = NULL;
m_error = HGFALSE;
m_break = HGFALSE;
#else
// TODO
#endif
}
~HGNamedPipeClientImpl()
{
#if defined(HG_CMP_MSC)
HGBase_CloseThread(m_thread);
m_thread = NULL;
CloseHandle(m_hPipe);
m_hPipe = INVALID_HANDLE_VALUE;
CloseHandle(m_hProcessEvent);
m_hProcessEvent = NULL;
CloseHandle(m_hReadEvent);
m_hReadEvent = NULL;
CloseHandle(m_hWriteEvent);
m_hWriteEvent = NULL;
#else
// TODO
#endif
}
#if defined(HG_CMP_MSC)
HANDLE m_hWriteEvent;
HANDLE m_hReadEvent;
HANDLE m_hProcessEvent;
HANDLE m_hPipe;
DWORD m_serverPid;
HGThread m_thread;
HGBool m_error;
HGBool m_break;
#else
// TODO
#endif
};
static void HGAPI NamedPipeServerFunc(HGThread thread, HGPointer param)
{
HGNamedPipeServerImpl* p = (HGNamedPipeServerImpl*)param;
#if defined(HG_CMP_MSC)
HANDLE handles[2];
handles[0] = OpenProcess(SYNCHRONIZE, FALSE, p->m_clientPid);
handles[1] = p->m_hProcessEvent;
if (WAIT_OBJECT_0 == WaitForMultipleObjects(2, handles, FALSE, INFINITE))
{
p->m_error = HGTRUE;
SetEvent(p->m_hWriteEvent);
SetEvent(p->m_hReadEvent);
}
CloseHandle(handles[0]);
#else
// TODO
#endif
}
static void NamedPipeClientFunc(HGThread thread, HGPointer param)
{
HGNamedPipeClientImpl* p = (HGNamedPipeClientImpl*)param;
#if defined(HG_CMP_MSC)
HANDLE handles[2];
handles[0] = OpenProcess(SYNCHRONIZE, FALSE, p->m_serverPid);
handles[1] = p->m_hProcessEvent;
if (WAIT_OBJECT_0 == WaitForMultipleObjects(2, handles, FALSE, INFINITE))
{
p->m_error = HGTRUE;
SetEvent(p->m_hWriteEvent);
SetEvent(p->m_hReadEvent);
}
CloseHandle(handles[0]);
#else
// TODO
#endif
}
HGResult HGAPI HGBase_OpenNamedPipeServer(const HGChar* pipeName, HGNamedPipeServer* server)
{
if (NULL == pipeName || NULL == server)
{
return HGBASE_ERR_INVALIDARG;
}
#if defined(HG_CMP_MSC)
HANDLE hConnectEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
assert(NULL != hConnectEvent);
HANDLE hWriteEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
assert(NULL != hWriteEvent);
HANDLE hReadEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
assert(NULL != hReadEvent);
HANDLE hProcessEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
assert(NULL != hProcessEvent);
char name[256];
sprintf(name, "\\\\.\\pipe\\%s", pipeName);
HANDLE hPipe = CreateNamedPipeA(name, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
0, 1, 1024, 1024, 0, NULL);
if (INVALID_HANDLE_VALUE == hPipe)
{
CloseHandle(hProcessEvent);
CloseHandle(hReadEvent);
CloseHandle(hWriteEvent);
CloseHandle(hConnectEvent);
return HGBASE_ERR_FAIL;
}
HGNamedPipeServerImpl* pipeServerImpl = new HGNamedPipeServerImpl;
pipeServerImpl->m_hConnectEvent = hConnectEvent;
pipeServerImpl->m_hWriteEvent = hWriteEvent;
pipeServerImpl->m_hReadEvent = hReadEvent;
pipeServerImpl->m_hProcessEvent = hProcessEvent;
pipeServerImpl->m_hPipe = hPipe;
*server = (HGNamedPipeServer)pipeServerImpl;
#else
// TODO
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_CloseNamedPipeServer(HGNamedPipeServer server)
{
if (NULL == server)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
delete pipeServerImpl;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_NamedPipeServerWrite(HGNamedPipeServer server, const HGByte* data, HGUInt size, HGUInt* writeSize)
{
if (NULL == server || NULL == data || 0 == size)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
#if defined(HG_CMP_MSC)
if (NULL == pipeServerImpl->m_thread || pipeServerImpl->m_error || pipeServerImpl->m_break)
{
return HGBASE_ERR_FAIL;
}
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = pipeServerImpl->m_hWriteEvent;
DWORD dwNumerOfWriteBytes = 0;
if (!WriteFile(pipeServerImpl->m_hPipe, data, size, &dwNumerOfWriteBytes, &overlapped))
{
if (ERROR_IO_PENDING != GetLastError())
{
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeServerImpl->m_hWriteEvent, INFINITE);
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
{
// <20>ֶ<EFBFBD>ֹͣ
return HGBASE_ERR_FAIL;
}
}
if (NULL != writeSize)
*writeSize = dwNumerOfWriteBytes;
#else
// TODO
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_NamedPipeServerRead(HGNamedPipeServer server, HGByte* data, HGUInt size, HGUInt* readSize)
{
if (NULL == server || NULL == data || 0 == size)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
#if defined(HG_CMP_MSC)
if (NULL == pipeServerImpl->m_thread) // δ<><CEB4><EFBFBD><EFBFBD>
{
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = pipeServerImpl->m_hConnectEvent;
if (!ConnectNamedPipe(pipeServerImpl->m_hPipe, &overlapped))
{
DWORD err = GetLastError();
if (ERROR_IO_PENDING != err && ERROR_PIPE_CONNECTED != err)
{
// <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD>
return HGBASE_ERR_FAIL;
}
if (ERROR_IO_PENDING == err)
{
// <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>
WaitForSingleObject(pipeServerImpl->m_hConnectEvent, INFINITE);
DWORD dwTransferBytes = 0; // <20><>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwTransferBytes, TRUE))
{
// <20>ֶ<EFBFBD>ֹͣ
return HGBASE_ERR_FAIL;
}
}
}
// <20><>ȡ<EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD>ID
memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.hEvent = pipeServerImpl->m_hReadEvent;
DWORD dwNumerOfReadBytes = 0;
DWORD clientPid = 0;
if (!ReadFile(pipeServerImpl->m_hPipe, &clientPid, sizeof(DWORD), &dwNumerOfReadBytes, &overlapped))
{
if (ERROR_IO_PENDING != GetLastError())
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeServerImpl->m_hReadEvent, INFINITE);
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
{
// <20>ֶ<EFBFBD>ֹͣ
return HGBASE_ERR_FAIL;
}
}
if (sizeof(DWORD) != dwNumerOfReadBytes || 0 == clientPid)
{
return HGBASE_ERR_FAIL;
}
// <20><><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID
memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.hEvent = pipeServerImpl->m_hWriteEvent;
DWORD dwNumerOfWriteBytes = 0;
DWORD serverPid = GetCurrentProcessId();
if (!WriteFile(pipeServerImpl->m_hPipe, &serverPid, sizeof(DWORD), &dwNumerOfWriteBytes, &overlapped))
{
if (ERROR_IO_PENDING != GetLastError())
{
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeServerImpl->m_hWriteEvent, INFINITE);
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
{
// <20>ֶ<EFBFBD>ֹͣ
return HGBASE_ERR_FAIL;
}
}
if (sizeof(DWORD) != dwNumerOfWriteBytes)
{
return HGBASE_ERR_FAIL;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>̵߳ȴ<CCB5><C8B4>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD>ID
pipeServerImpl->m_clientPid = clientPid;
HGBase_OpenThread(NamedPipeServerFunc, pipeServerImpl, &pipeServerImpl->m_thread);
assert(NULL != pipeServerImpl->m_thread);
}
if (pipeServerImpl->m_error || pipeServerImpl->m_break)
{
return HGBASE_ERR_FAIL;
}
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = pipeServerImpl->m_hReadEvent;
DWORD dwNumerOfReadBytes = 0;
if (!ReadFile(pipeServerImpl->m_hPipe, data, size, &dwNumerOfReadBytes, &overlapped))
{
if (ERROR_IO_PENDING != GetLastError())
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeServerImpl->m_hReadEvent, INFINITE);
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
{
// <20>ֶ<EFBFBD>ֹͣ
return HGBASE_ERR_FAIL;
}
}
if (NULL != readSize)
*readSize = dwNumerOfReadBytes;
#else
// TODO
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_NamedPipeServerStop(HGNamedPipeServer server)
{
if (NULL == server)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
#if defined(HG_CMP_MSC)
pipeServerImpl->m_break = HGTRUE;
SetEvent(pipeServerImpl->m_hConnectEvent);
SetEvent(pipeServerImpl->m_hWriteEvent);
SetEvent(pipeServerImpl->m_hReadEvent);
SetEvent(pipeServerImpl->m_hProcessEvent);
#else
// TODO
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_OpenNamedPipeClient(const HGChar* pipeName, HGNamedPipeClient* client)
{
if (NULL == pipeName || NULL == client)
{
return HGBASE_ERR_INVALIDARG;
}
#if defined(HG_CMP_MSC)
HANDLE hWriteEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
assert(NULL != hWriteEvent);
HANDLE hReadEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
assert(NULL != hReadEvent);
HANDLE hProcessEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
assert(NULL != hProcessEvent);
char name[256];
sprintf(name, "\\\\.\\pipe\\%s", pipeName);
HANDLE hPipe = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (INVALID_HANDLE_VALUE == hPipe)
{
CloseHandle(hProcessEvent);
CloseHandle(hReadEvent);
CloseHandle(hWriteEvent);
return HGBASE_ERR_FAIL;
}
// <20><><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = hWriteEvent;
DWORD dwNumerOfWriteBytes = 0;
DWORD clientPid = GetCurrentProcessId();
if (!WriteFile(hPipe, &clientPid, sizeof(DWORD), &dwNumerOfWriteBytes, &overlapped))
{
if (ERROR_IO_PENDING != GetLastError())
{
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CloseHandle(hPipe);
CloseHandle(hProcessEvent);
CloseHandle(hReadEvent);
CloseHandle(hWriteEvent);
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(hWriteEvent, INFINITE);
if (!GetOverlappedResult(hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
{
// <20>ֶ<EFBFBD>ֹͣ
CloseHandle(hPipe);
CloseHandle(hProcessEvent);
CloseHandle(hReadEvent);
CloseHandle(hWriteEvent);
return HGBASE_ERR_FAIL;
}
}
if (sizeof(DWORD) != dwNumerOfWriteBytes)
{
CloseHandle(hPipe);
CloseHandle(hProcessEvent);
CloseHandle(hReadEvent);
CloseHandle(hWriteEvent);
return HGBASE_ERR_FAIL;
}
// <20><>ȡ<EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD>ID
memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.hEvent = hReadEvent;
DWORD dwNumerOfReadBytes = 0;
DWORD serverPid = 0;
if (!ReadFile(hPipe, &serverPid, sizeof(DWORD), &dwNumerOfReadBytes, &overlapped))
{
if (ERROR_IO_PENDING != GetLastError())
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
CloseHandle(hPipe);
CloseHandle(hProcessEvent);
CloseHandle(hReadEvent);
CloseHandle(hWriteEvent);
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(hReadEvent, INFINITE);
if (!GetOverlappedResult(hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
{
// <20>ֶ<EFBFBD>ֹͣ
CloseHandle(hPipe);
CloseHandle(hProcessEvent);
CloseHandle(hReadEvent);
CloseHandle(hWriteEvent);
return HGBASE_ERR_FAIL;
}
}
if (sizeof(DWORD) != dwNumerOfReadBytes || 0 == serverPid)
{
CloseHandle(hPipe);
CloseHandle(hProcessEvent);
CloseHandle(hReadEvent);
CloseHandle(hWriteEvent);
return HGBASE_ERR_FAIL;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>̵߳ȴ<CCB5><C8B4>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD>ID
HGNamedPipeClientImpl* pipeClientImpl = new HGNamedPipeClientImpl;
pipeClientImpl->m_hWriteEvent = hWriteEvent;
pipeClientImpl->m_hReadEvent = hReadEvent;
pipeClientImpl->m_hProcessEvent = hProcessEvent;
pipeClientImpl->m_hPipe = hPipe;
pipeClientImpl->m_serverPid = serverPid;
HGBase_OpenThread(NamedPipeServerFunc, pipeClientImpl, &pipeClientImpl->m_thread);
assert(NULL != pipeClientImpl->m_thread);
*client = (HGNamedPipeClient)pipeClientImpl;
#else
// TODO
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_CloseNamedPipeClient(HGNamedPipeClient client)
{
if (NULL == client)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeClientImpl* pipeClientImpl = (HGNamedPipeClientImpl*)client;
delete pipeClientImpl;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_NamedPipeClientWrite(HGNamedPipeClient client, const HGByte* data, HGUInt size, HGUInt* writeSize)
{
if (NULL == client)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeClientImpl* pipeClientImpl = (HGNamedPipeClientImpl*)client;
#if defined(HG_CMP_MSC)
assert(NULL != pipeClientImpl->m_thread);
if (pipeClientImpl->m_error || pipeClientImpl->m_break)
{
return HGBASE_ERR_FAIL;
}
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = pipeClientImpl->m_hWriteEvent;
DWORD dwNumerOfWriteBytes = 0;
if (!WriteFile(pipeClientImpl->m_hPipe, data, size, &dwNumerOfWriteBytes, &overlapped))
{
if (ERROR_IO_PENDING != GetLastError())
{
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeClientImpl->m_hWriteEvent, INFINITE);
if (!GetOverlappedResult(pipeClientImpl->m_hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
{
// <20>ֶ<EFBFBD>ֹͣ
return HGBASE_ERR_FAIL;
}
}
if (NULL != writeSize)
*writeSize = dwNumerOfWriteBytes;
#else
// TODO
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_NamedPipeClientRead(HGNamedPipeClient client, HGByte* data, HGUInt size, HGUInt* readSize)
{
if (NULL == client)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeClientImpl* pipeClientImpl = (HGNamedPipeClientImpl*)client;
#if defined(HG_CMP_MSC)
assert(NULL != pipeClientImpl->m_thread);
if (pipeClientImpl->m_error || pipeClientImpl->m_break)
{
return HGBASE_ERR_FAIL;
}
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = pipeClientImpl->m_hReadEvent;
DWORD dwNumerOfReadBytes = 0;
if (!ReadFile(pipeClientImpl->m_hPipe, data, size, &dwNumerOfReadBytes, &overlapped))
{
if (ERROR_IO_PENDING != GetLastError())
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeClientImpl->m_hReadEvent, INFINITE);
if (!GetOverlappedResult(pipeClientImpl->m_hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
{
// <20>ֶ<EFBFBD>ֹͣ
return HGBASE_ERR_FAIL;
}
}
if (NULL != readSize)
*readSize = dwNumerOfReadBytes;
#else
// TODO
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_NamedPipeClientStop(HGNamedPipeClient client)
{
if (NULL == client)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeClientImpl* pipeClientImpl = (HGNamedPipeClientImpl*)client;
#if defined(HG_CMP_MSC)
pipeClientImpl->m_break = HGTRUE;
SetEvent(pipeClientImpl->m_hWriteEvent);
SetEvent(pipeClientImpl->m_hReadEvent);
SetEvent(pipeClientImpl->m_hProcessEvent);
#else
// TODO
#endif
return HGBASE_ERR_OK;
}