diff --git a/build/windows/HGBase/HGBase.def b/build/windows/HGBase/HGBase.def index 193c2dff..77eb6e1f 100644 --- a/build/windows/HGBase/HGBase.def +++ b/build/windows/HGBase/HGBase.def @@ -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 diff --git a/modules/base/HGNamedPipe.cpp b/modules/base/HGNamedPipe.cpp index e64b7606..e99d63ec 100644 --- a/modules/base/HGNamedPipe.cpp +++ b/modules/base/HGNamedPipe.cpp @@ -1,93 +1,155 @@ #include "HGNamedPipe.h" #include "HGInc.h" +#include "HGThread.h" #include -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,111 @@ 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) // 未连接 + { + 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) + { + // 等待连接出错 + 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; + DWORD clientPid = 0; + if (!ReadFile(pipeServerImpl->m_hPipe, &clientPid, sizeof(DWORD), &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; + } + } + 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) { - 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_hReadEvent; DWORD dwNumerOfReadBytes = 0; - if (!ReadFile(pipeInImpl->m_hPipe, data, size, &dwNumerOfReadBytes, &overlapped)) + if (!ReadFile(pipeServerImpl->m_hPipe, data, size, &dwNumerOfReadBytes, &overlapped)) { if (ERROR_IO_PENDING != GetLastError()) { @@ -313,8 +350,8 @@ 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; @@ -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; } diff --git a/modules/base/HGNamedPipe.h b/modules/base/HGNamedPipe.h index 48352720..24672032 100644 --- a/modules/base/HGNamedPipe.h +++ b/modules/base/HGNamedPipe.h @@ -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__ */ \ No newline at end of file