HGNamedPipe模块调整接口

This commit is contained in:
luoliangyi 2022-08-10 10:22:13 +08:00
parent 0165e8d3ec
commit f6dc65117d
3 changed files with 477 additions and 205 deletions

View File

@ -36,14 +36,16 @@ HGBase_CloseLog
HGBase_GetLogFileSize
HGBase_WriteLog
HGBase_CreateNamedPipe
HGBase_DestroyNamedPipe
HGBase_WriteNamedPipe
HGBase_StopWriteNamedPipe
HGBase_OpenNamedPipe
HGBase_CloseNamedPipe
HGBase_ReadNamedPipe
HGBase_StopReadNamedPipe
HGBase_OpenNamedPipeServer
HGBase_CloseNamedPipeServer
HGBase_NamedPipeServerWrite
HGBase_NamedPipeServerRead
HGBase_NamedPipeServerStop
HGBase_OpenNamedPipeClient
HGBase_CloseNamedPipeClient
HGBase_NamedPipeClientWrite
HGBase_NamedPipeClientRead
HGBase_NamedPipeClientStop
HGBase_OpenConsole
HGBase_CloseConsole

View File

@ -1,93 +1,155 @@
#include "HGNamedPipe.h"
#include "HGInc.h"
#include "HGThread.h"
#include <string>
struct HGNamedPipeOutImpl
struct HGNamedPipeServerImpl
{
HGNamedPipeOutImpl()
HGNamedPipeServerImpl()
{
#if defined(HG_CMP_MSC)
m_hConnectEvent = NULL;
m_hWriteEvent = NULL;
m_hReadEvent = NULL;
m_hProcessEvent = NULL;
m_hPipe = INVALID_HANDLE_VALUE;
m_pOverlapped = NULL;
m_clientPid = 0;
m_thread = NULL;
m_error = HGFALSE;
m_break = HGFALSE;
#else
m_filePath.empty();
m_fdPipe = -1;
// TODO
#endif
}
~HGNamedPipeOutImpl()
~HGNamedPipeServerImpl()
{
#if defined(HG_CMP_MSC)
delete m_pOverlapped;
m_pOverlapped = NULL;
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
if (-1 != m_fdPipe)
{
close(m_fdPipe);
m_fdPipe = -1;
}
unlink(m_filePath.c_str());
// TODO
#endif
}
#if defined(HG_CMP_MSC)
HANDLE m_hConnectEvent;
HANDLE m_hWriteEvent;
HANDLE m_hReadEvent;
HANDLE m_hProcessEvent;
HANDLE m_hPipe;
OVERLAPPED *m_pOverlapped;
DWORD m_clientPid;
HGThread m_thread;
HGBool m_error;
HGBool m_break;
#else
std::string m_filePath;
int m_fdPipe;
// TODO
#endif
};
struct HGNamedPipeInImpl
struct HGNamedPipeClientImpl
{
HGNamedPipeInImpl()
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
m_fdPipe = -1;
// TODO
#endif
}
~HGNamedPipeInImpl()
~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
if (-1 != m_fdPipe)
{
close(m_fdPipe);
m_fdPipe = -1;
}
// 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
int m_fdPipe;
// TODO
#endif
};
HGResult HGAPI HGBase_CreateNamedPipe(const HGChar* pipeName, HGNamedPipeOut* pipeOut)
static void NamedPipeServerFunc(HGThread thread, HGPointer param)
{
if (NULL == pipeName || NULL == pipeOut)
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;
}
@ -97,96 +159,67 @@ HGResult HGAPI HGBase_CreateNamedPipe(const HGChar* pipeName, HGNamedPipeOut* pi
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_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
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;
}
OVERLAPPED* pOverlapped = new OVERLAPPED;
memset(pOverlapped, 0, sizeof(OVERLAPPED));
pOverlapped->hEvent = hConnectEvent;
if (!ConnectNamedPipe(hPipe, pOverlapped))
{
DWORD err = GetLastError();
if (ERROR_IO_PENDING != err && ERROR_PIPE_CONNECTED != err)
{
delete pOverlapped;
CloseHandle(hPipe);
CloseHandle(hWriteEvent);
CloseHandle(hConnectEvent);
return HGBASE_ERR_FAIL;
}
}
HGNamedPipeOutImpl* pipeOutImpl = new HGNamedPipeOutImpl;
pipeOutImpl->m_hConnectEvent = hConnectEvent;
pipeOutImpl->m_hWriteEvent = hWriteEvent;
pipeOutImpl->m_hPipe = hPipe;
pipeOutImpl->m_pOverlapped = pOverlapped;
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
char name[256];
sprintf(name, "/tmp/%s", pipeName);
if (access(name, F_OK) != -1)
return HGBASE_ERR_FAIL;
if (0 != mkfifo(name, 0777))
return HGBASE_ERR_FAIL;
int fdPipe = open(name, O_WRONLY);
if (-1 == fdPipe)
return HGBASE_ERR_FAIL;
HGNamedPipeOutImpl* pipeOutImpl = new HGNamedPipeOutImpl;
pipeOutImpl->m_filePath = name;
pipeOutImpl->m_fdPipe = fdPipe;
// TODO
#endif
*pipeOut = (HGNamedPipeOut)pipeOutImpl;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_DestroyNamedPipe(HGNamedPipeOut pipeOut)
HGResult HGAPI HGBase_CloseNamedPipeServer(HGNamedPipeServer server)
{
if (NULL == pipeOut)
if (NULL == server)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeOutImpl* pipeOutImpl = (HGNamedPipeOutImpl*)pipeOut;
delete pipeOutImpl;
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
delete pipeServerImpl;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_WriteNamedPipe(HGNamedPipeOut pipeOut, const HGByte* data, HGUInt size, HGUInt *writeSize)
HGResult HGAPI HGBase_NamedPipeServerWrite(HGNamedPipeServer server, const HGByte* data, HGUInt size, HGUInt* writeSize)
{
if (NULL == pipeOut || NULL == data || 0 == size)
if (NULL == server || NULL == data || 0 == size)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeOutImpl* pipeOutImpl = (HGNamedPipeOutImpl*)pipeOut;
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
#if defined(HG_CMP_MSC)
// 等待连接
WaitForSingleObject(pipeOutImpl->m_hConnectEvent, INFINITE);
DWORD dwTransferBytes = 0; // 此值无意义
if (!GetOverlappedResult(pipeOutImpl->m_hPipe, pipeOutImpl->m_pOverlapped, &dwTransferBytes, TRUE))
if (NULL == pipeServerImpl->m_thread || pipeServerImpl->m_error || pipeServerImpl->m_break)
{
// 手动停止
return HGBASE_ERR_FAIL;
}
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = pipeOutImpl->m_hWriteEvent;
overlapped.hEvent = pipeServerImpl->m_hWriteEvent;
DWORD dwNumerOfWriteBytes = 0;
if (!WriteFile(pipeOutImpl->m_hPipe, data, size, &dwNumerOfWriteBytes, &overlapped))
if (!WriteFile(pipeServerImpl->m_hPipe, data, size, &dwNumerOfWriteBytes, &overlapped))
{
if (ERROR_IO_PENDING != GetLastError())
{
@ -194,8 +227,8 @@ HGResult HGAPI HGBase_WriteNamedPipe(HGNamedPipeOut pipeOut, const HGByte* data,
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeOutImpl->m_hWriteEvent, INFINITE);
if (!GetOverlappedResult(pipeOutImpl->m_hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
WaitForSingleObject(pipeServerImpl->m_hWriteEvent, INFINITE);
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
{
// ÊÖ¶¯Í£Ö¹
return HGBASE_ERR_FAIL;
@ -205,107 +238,52 @@ HGResult HGAPI HGBase_WriteNamedPipe(HGNamedPipeOut pipeOut, const HGByte* data,
if (NULL != writeSize)
*writeSize = dwNumerOfWriteBytes;
#else
int res = write(pipeOutImpl->m_fdPipe, data, size);
if (-1 == res)
return HGBASE_ERR_FAIL;
if (NULL != writeSize)
*writeSize = res;
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_StopWriteNamedPipe(HGNamedPipeOut pipeOut)
{
if (NULL == pipeOut)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeOutImpl* pipeOutImpl = (HGNamedPipeOutImpl*)pipeOut;
#if defined(HG_CMP_MSC)
SetEvent(pipeOutImpl->m_hConnectEvent);
SetEvent(pipeOutImpl->m_hWriteEvent);
#else
if (-1 != pipeOutImpl->m_fdPipe)
{
close(pipeOutImpl->m_fdPipe);
pipeOutImpl->m_fdPipe = -1;
}
// TODO
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_OpenNamedPipe(const HGChar* pipeName, HGNamedPipeIn* pipeIn)
HGResult HGAPI HGBase_NamedPipeServerRead(HGNamedPipeServer server, HGByte* data, HGUInt size, HGUInt* readSize)
{
if (NULL == pipeName || NULL == pipeIn)
if (NULL == server || NULL == data || 0 == size)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
#if defined(HG_CMP_MSC)
HANDLE hReadEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
assert(NULL != hReadEvent);
char name[256];
sprintf(name, "\\\\.\\pipe\\%s", pipeName);
if (!WaitNamedPipeA(name, NMPWAIT_USE_DEFAULT_WAIT))
if (NULL == pipeServerImpl->m_thread) // 未连接
{
DWORD dw = GetLastError();
return HGBASE_ERR_FAIL;
}
HANDLE hPipe = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (INVALID_HANDLE_VALUE == hPipe)
{
CloseHandle(hReadEvent);
return HGBASE_ERR_FAIL;
}
HGNamedPipeInImpl* pipeInImpl = new HGNamedPipeInImpl;
pipeInImpl->m_hReadEvent = hReadEvent;
pipeInImpl->m_hPipe = hPipe;
#else
char name[256];
sprintf(name, "/tmp/%s", pipeName);
int fdPipe = open(name, O_RDONLY);
if (-1 == fdPipe)
return HGBASE_ERR_FAIL;
HGNamedPipeInImpl* pipeInImpl = new HGNamedPipeInImpl;
pipeInImpl->m_fdPipe = fdPipe;
#endif
*pipeIn = (HGNamedPipeIn)pipeInImpl;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_CloseNamedPipe(HGNamedPipeIn pipeIn)
{
if (NULL == pipeIn)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeInImpl* pipeInImpl = (HGNamedPipeInImpl*)pipeIn;
delete pipeInImpl;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_ReadNamedPipe(HGNamedPipeIn pipeIn, HGByte* data, HGUInt size, HGUInt* readSize)
{
if (NULL == pipeIn || NULL == data || 0 == size)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeInImpl* pipeInImpl = (HGNamedPipeInImpl*)pipeIn;
#if defined(HG_CMP_MSC)
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = pipeInImpl->m_hReadEvent;
overlapped.hEvent = pipeServerImpl->m_hConnectEvent;
if (!ConnectNamedPipe(pipeServerImpl->m_hPipe, &overlapped))
{
DWORD err = GetLastError();
if (ERROR_IO_PENDING != err && ERROR_PIPE_CONNECTED != err)
{
// 等待连接出错
return HGBASE_ERR_FAIL;
}
if (ERROR_IO_PENDING == err)
{
// 等待连接
WaitForSingleObject(pipeServerImpl->m_hConnectEvent, INFINITE);
DWORD dwTransferBytes = 0; // 此值无意义
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwTransferBytes, TRUE))
{
// 手动停止
return HGBASE_ERR_FAIL;
}
}
}
// 读取对方进程ID
memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.hEvent = pipeServerImpl->m_hReadEvent;
DWORD dwNumerOfReadBytes = 0;
if (!ReadFile(pipeInImpl->m_hPipe, data, size, &dwNumerOfReadBytes, &overlapped))
DWORD clientPid = 0;
if (!ReadFile(pipeServerImpl->m_hPipe, &clientPid, sizeof(DWORD), &dwNumerOfReadBytes, &overlapped))
{
if (ERROR_IO_PENDING != GetLastError())
{
@ -313,8 +291,67 @@ HGResult HGAPI HGBase_ReadNamedPipe(HGNamedPipeIn pipeIn, HGByte* data, HGUInt s
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeInImpl->m_hReadEvent, INFINITE);
if (!GetOverlappedResult(pipeInImpl->m_hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
WaitForSingleObject(pipeServerImpl->m_hReadEvent, INFINITE);
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
{
// 手动停止
return HGBASE_ERR_FAIL;
}
}
if (sizeof(DWORD) != dwNumerOfReadBytes || 0 == clientPid)
{
return HGBASE_ERR_FAIL;
}
// 发送己方进程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())
{
// 写入错误
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeServerImpl->m_hWriteEvent, INFINITE);
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
{
// 手动停止
return HGBASE_ERR_FAIL;
}
}
if (sizeof(DWORD) != dwNumerOfWriteBytes)
{
return HGBASE_ERR_FAIL;
}
// 创建线程等待对方进程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())
{
// 读取错误
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeServerImpl->m_hReadEvent, INFINITE);
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
{
// ÊÖ¶¯Í£Ö¹
return HGBASE_ERR_FAIL;
@ -324,32 +361,261 @@ HGResult HGAPI HGBase_ReadNamedPipe(HGNamedPipeIn pipeIn, HGByte* data, HGUInt s
if (NULL != readSize)
*readSize = dwNumerOfReadBytes;
#else
int res = read(pipeInImpl->m_fdPipe, data, size);
if (-1 == res)
return HGBASE_ERR_FAIL;
if (NULL != readSize)
*readSize = res;
// TODO
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_StopReadNamedPipe(HGNamedPipeIn pipeIn)
HGResult HGAPI HGBase_NamedPipeServerStop(HGNamedPipeServer server)
{
if (NULL == pipeIn)
if (NULL == server)
{
return HGBASE_ERR_INVALIDARG;
}
HGNamedPipeInImpl* pipeInImpl = (HGNamedPipeInImpl*)pipeIn;
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
#if defined(HG_CMP_MSC)
SetEvent(pipeInImpl->m_hReadEvent);
pipeServerImpl->m_break = HGTRUE;
SetEvent(pipeServerImpl->m_hConnectEvent);
SetEvent(pipeServerImpl->m_hWriteEvent);
SetEvent(pipeServerImpl->m_hReadEvent);
SetEvent(pipeServerImpl->m_hProcessEvent);
#else
if (-1 != pipeInImpl->m_fdPipe)
{
close(pipeInImpl->m_fdPipe);
pipeInImpl->m_fdPipe = -1;
}
// 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;
}
// 发送己方进程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())
{
// 写入错误
CloseHandle(hPipe);
CloseHandle(hProcessEvent);
CloseHandle(hReadEvent);
CloseHandle(hWriteEvent);
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(hWriteEvent, INFINITE);
if (!GetOverlappedResult(hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
{
// 手动停止
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;
}
// 读取对方进程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())
{
// 读取错误
CloseHandle(hPipe);
CloseHandle(hProcessEvent);
CloseHandle(hReadEvent);
CloseHandle(hWriteEvent);
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(hReadEvent, INFINITE);
if (!GetOverlappedResult(hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
{
// 手动停止
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;
}
// 创建线程等待对方进程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())
{
// 写入错误
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeClientImpl->m_hWriteEvent, INFINITE);
if (!GetOverlappedResult(pipeClientImpl->m_hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
{
// 手动停止
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())
{
// 读取错误
return HGBASE_ERR_FAIL;
}
WaitForSingleObject(pipeClientImpl->m_hReadEvent, INFINITE);
if (!GetOverlappedResult(pipeClientImpl->m_hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
{
// 手动停止
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;
}

View File

@ -4,23 +4,27 @@
#include "HGDef.h"
#include "HGBaseErr.h"
HG_DECLARE_HANDLE(HGNamedPipeOut);
HG_DECLARE_HANDLE(HGNamedPipeIn);
HG_DECLARE_HANDLE(HGNamedPipeServer);
HG_DECLARE_HANDLE(HGNamedPipeClient);
HGEXPORT HGResult HGAPI HGBase_CreateNamedPipe(const HGChar *pipeName, HGNamedPipeOut *pipeOut);
HGEXPORT HGResult HGAPI HGBase_OpenNamedPipeServer(const HGChar* pipeName, HGNamedPipeServer *server);
HGEXPORT HGResult HGAPI HGBase_DestroyNamedPipe(HGNamedPipeOut pipeOut);
HGEXPORT HGResult HGAPI HGBase_CloseNamedPipeServer(HGNamedPipeServer server);
HGEXPORT HGResult HGAPI HGBase_WriteNamedPipe(HGNamedPipeOut pipeOut, const HGByte *data, HGUInt size, HGUInt *writeSize);
HGEXPORT HGResult HGAPI HGBase_NamedPipeServerWrite(HGNamedPipeServer server, const HGByte* data, HGUInt size, HGUInt* writeSize);
HGEXPORT HGResult HGAPI HGBase_StopWriteNamedPipe(HGNamedPipeOut pipeOut);
HGEXPORT HGResult HGAPI HGBase_NamedPipeServerRead(HGNamedPipeServer server, HGByte* data, HGUInt size, HGUInt* readSize);
HGEXPORT HGResult HGAPI HGBase_OpenNamedPipe(const HGChar *pipeName, HGNamedPipeIn *pipeIn);
HGEXPORT HGResult HGAPI HGBase_NamedPipeServerStop(HGNamedPipeServer server);
HGEXPORT HGResult HGAPI HGBase_CloseNamedPipe(HGNamedPipeIn pipeIn);
HGEXPORT HGResult HGAPI HGBase_OpenNamedPipeClient(const HGChar* pipeName, HGNamedPipeClient* client);
HGEXPORT HGResult HGAPI HGBase_ReadNamedPipe(HGNamedPipeIn pipeIn, HGByte *data, HGUInt size, HGUInt *readSize);
HGEXPORT HGResult HGAPI HGBase_CloseNamedPipeClient(HGNamedPipeClient client);
HGEXPORT HGResult HGAPI HGBase_StopReadNamedPipe(HGNamedPipeIn pipeIn);
HGEXPORT HGResult HGAPI HGBase_NamedPipeClientWrite(HGNamedPipeClient client, const HGByte* data, HGUInt size, HGUInt* writeSize);
HGEXPORT HGResult HGAPI HGBase_NamedPipeClientRead(HGNamedPipeClient client, HGByte* data, HGUInt size, HGUInt* readSize);
HGEXPORT HGResult HGAPI HGBase_NamedPipeClientStop(HGNamedPipeClient client);
#endif /* __HGNAMEDPIPE_H__ */