📄 staflocalipcconnprovider.cpp
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF) *//* (C) Copyright IBM Corp. 2001, 2004 *//* *//* This software is licensed under the Common Public License (CPL) V1.0. *//*****************************************************************************/#include "STAF.h"#include "STAFConnectionProvider.h"#include "STAFString.h"#include "STAFInternalUtil.h"#include "STAFThreadManager.h"#include "STAFTrace.h"#include "STAFEventSem.h"#include "STAFMutexSem.h"#include "STAFUtilWin32.h"#include <aclapi.h>#include <map>#include <set>#include <stdlib.h>#define CATCH_STANDARD(functionString) \catch (STAFException &e)\{\ if (errorBuffer)\ {\ *errorBuffer = getExceptionString(e, "STAFLocalIPCConnProvider.cpp: "\ functionString)\ .adoptImpl();\ }\}\catch (...)\{\ if (errorBuffer)\ {\ STAFString error("STAFLocalIPCConnProvider.cpp: Caught unknown "\ "exception in " functionString "()");\ *errorBuffer = error.adoptImpl();\ }\}#define CATCH_STANDARD_TRACE(functionString) \catch (STAFException &e)\{\ STAFTrace::trace(kSTAFTraceError,\ getExceptionString(e, "STAFLocalIPCConnProvider.cpp: "\ functionString));\}\catch (...)\{\ STAFTrace::trace(kSTAFTraceError,\ "STAFLocalIPCConnProvider.cpp: Caught unknown exception "\ "in " functionString "()");\}// PrototypesSTAFRC_t STAFConnectionProviderConstruct(STAFConnectionProvider_t *provider, void *constructInfo, unsigned int constructInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderStart(STAFConnectionProvider_t provider, void *startInfo, unsigned int startInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderStop(STAFConnectionProvider_t provider, void *stopInfo, unsigned int stopInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderDestruct(STAFConnectionProvider_t *provider, void *destructInfo, unsigned int destructInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderConnect(STAFConnectionProvider_t provider, STAFConnection_t *connection, void *connectInfo, unsigned int connectInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderGetMyNetworkIDs(STAFConnectionProvider_t provider, STAFStringConst_t *logicalID, STAFStringConst_t *physicalD, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderGetOptions( STAFConnectionProvider_t provider, STAFObject_t *options, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderGetProperty( STAFConnectionProvider_t provider, STAFConnectionProviderProperty_t property, STAFStringConst_t *value, STAFString_t *errorBuffer);STAFRC_t STAFConnectionRead(STAFConnection_t connection, void *buffer, unsigned int readLength, STAFString_t *errorBuffer);STAFRC_t STAFConnectionReadUInt(STAFConnection_t connection, unsigned int *uint, STAFString_t *errorBuffer);STAFRC_t STAFConnectionReadSTAFString(STAFConnection_t connection, STAFString_t *stafString, STAFString_t *errorBuffer);STAFRC_t STAFConnectionWrite(STAFConnection_t connection, void *buffer, unsigned int writeLength, STAFString_t *errorBuffer);STAFRC_t STAFConnectionWriteUInt(STAFConnection_t connection, unsigned int uint, STAFString_t *errorBuffer);STAFRC_t STAFConnectionWriteSTAFString(STAFConnection_t connection, STAFStringConst_t stafString, STAFString_t *errorBuffer);STAFRC_t STAFConnectionGetPeerNetworkIDs(STAFConnection_t connection, STAFStringConst_t *logicalID, STAFStringConst_t *physicalD, STAFString_t *errorBuffer);STAFRC_t STAFConnectionDestruct(STAFConnection_t *connection, STAFString_t *errorBuffer);static STAFConnectionProviderFunctionTable gFuncTable ={ STAFConnectionProviderConstruct, STAFConnectionProviderStart, STAFConnectionProviderStop, STAFConnectionProviderDestruct, STAFConnectionProviderConnect, STAFConnectionProviderGetMyNetworkIDs, STAFConnectionProviderGetOptions, STAFConnectionProviderGetProperty, STAFConnectionRead, STAFConnectionReadUInt, STAFConnectionReadSTAFString, STAFConnectionWrite, STAFConnectionWriteUInt, STAFConnectionWriteSTAFString, STAFConnectionGetPeerNetworkIDs, STAFConnectionDestruct};typedef enum{ kSharedMemory = 0, kNamedPipes = 1} STAFLocalIPCMethod_t;struct STAFLocalConnectionProviderImpl : STAFConnectionProviderImpl{ STAFConnectionProviderMode_t mode; void *data; STAFString ipcName; STAFLocalIPCMethod_t ipcMethod; // Indicates IPC method (named pipes or // shared memory) HANDLE serverSynch; // Used only by shared memory IPC method HANDLE clientSynch; // Used only by shared memory IPC method void *sharedMem; // Used only by shared memory IPC method HANDLE fileMap; // Used only by shared memory IPC method STAFString logicalNetworkID; STAFString physicalNetworkID; STAFObjectPtr options; STAFString portProperty; STAFString isSecureProperty; STAFConnectionProviderNewConnectionFunc_t connFunc; STAFEventSemPtr syncSem; STAFConnectionProviderState_t state; STAFThreadManagerPtr threadManager;};struct STAFLocalConnectionImpl : STAFConnectionImpl{ STAFLocalIPCMethod_t ipcMethod; // Indicates IPC method (named pipes or // shared memory) union { HANDLE pipeHandle; // Used only by named pipes IPC method HANDLE readHandle; // Used only by shared memory IPC method }; HANDLE writeHandle; // Used only by shared memory IPC method};struct LocalConnectionData{ STAFConnectionProviderNewConnectionFunc_t connFunc; STAFLocalConnectionProviderImpl *provider; STAFLocalConnectionImpl *connection;};//===================================================================// These static variables are only used by named pipes IPC methodstatic unsigned int BUFFER_SIZE = 1024;static STAFString PIPENAME_PREFIX = "\\\\.\\pipe\\STAF_";//===================================================================//===================================================================// These variables are only used by shared memory IPC methodstruct PipeData{ HANDLE clientMutex; HANDLE serverSynchSem; HANDLE clientSynchSem; DWORD *pidSwap; HANDLE *readHandlePtr; HANDLE *writeHandlePtr; HANDLE serverProcessHandle;};typedef std::map<STAFString, PipeData> PipeMap;static STAFMutexSem sPipeMapSem;static PipeMap sPipeMap;//===================================================================typedef std::set<STAFConnectionProvider_t> ProviderSet;static STAFMutexSem sActiveProvidersSem;static ProviderSet sActiveProviders;void atExit(){ ProviderSet activeProvidersCopy; { STAFMutexSemLock lock(sActiveProvidersSem); activeProvidersCopy = sActiveProviders; } for (ProviderSet::iterator iter = activeProvidersCopy.begin(); iter != activeProvidersCopy.end(); ++iter) { STAFConnectionProvider_t thisProvider = *iter; // XXX: Shut it down. I.e., kill any threads }}unsigned int STAFLocalIPCConnectionThread(void *data){ try { LocalConnectionData *connData = reinterpret_cast<LocalConnectionData *>(data); connData->connFunc(connData->provider, connData->connection, &gFuncTable, connData->provider->data); delete connData; } CATCH_STANDARD_TRACE("STAFLocalIPCConnectionThread"); return 0;}// Used only by named pipes IPC method#define HANDLE_NAMEDPIPES_RUN_ERROR(string) \{\ STAFTrace::trace(kSTAFTraceError, STAFString(string) + ", RC=" +\ STAFString(GetLastError()));\\ if (connImpl.pipeHandle != 0)\ {\ DisconnectNamedPipe(connImpl.pipeHandle);\ CloseHandle(connImpl.pipeHandle);\ }\\ continue;\}// Used only by shared memory IPC method#define HANDLE_SHAREDMEM_RUN_ERROR(string) \{\ STAFTrace::trace(kSTAFTraceError, STAFString(string) + ", RC=" +\ STAFString(GetLastError()));\\ if (clientWriteHandle != 0) CloseHandle(clientWriteHandle);\ if (connImpl.writeHandle != 0) CloseHandle(connImpl.writeHandle);\ if (clientReadHandle != 0) CloseHandle(clientReadHandle);\ if (connImpl.readHandle != 0) CloseHandle(connImpl.readHandle);\ if (clientProcess != 0) CloseHandle(clientProcess);\\ *pidSwap = 0;\ SetEvent(provider->clientSynch);\\ continue;\}unsigned int STAFLocalIPCRunThread(void *providerImpl){ STAFLocalConnectionProviderImpl *provider = reinterpret_cast<STAFLocalConnectionProviderImpl *>(providerImpl); STAFLocalConnectionImpl connImpl; connImpl.ipcMethod = provider->ipcMethod; BOOL connected; PSECURITY_DESCRIPTOR sd = 0; try { provider->syncSem->post(); if (provider->ipcMethod == kNamedPipes) { STAFString pipeName = PIPENAME_PREFIX + provider->ipcName; // Set up security attributes SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = sd; // Create a Null Security Descriptor to allow access to everyone if (STAFUtilWin32CreateNullSD(&sd)) { STAFTrace::trace( kSTAFTraceError, STAFString("STAFUtilWin32CreateNullSD(), RC=") + STAFString(GetLastError())); } while (provider->state == kSTAFConnectionProviderActive) { connImpl.pipeHandle = 0; connImpl.pipeHandle = CreateNamedPipe( pipeName.toCurrentCodePage()->buffer(), PIPE_ACCESS_DUPLEX, // read/write access PIPE_TYPE_BYTE | // byte type pipe PIPE_READMODE_BYTE | // byte-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances BUFFER_SIZE, // output buffer size BUFFER_SIZE, // input buffer size NMPWAIT_USE_DEFAULT_WAIT, // client time-out &sa); if (connImpl.pipeHandle == INVALID_HANDLE_VALUE) HANDLE_NAMEDPIPES_RUN_ERROR("CreateNamedPipe()"); // Wait for the client to connect; if it succeeds, the function // returns a nonzero value. If the function returns zero, // GetLastError returns ERROR_PIPE_CONNECTED. connected = ConnectNamedPipe(connImpl.pipeHandle, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if (!connected) { HANDLE_NAMEDPIPES_RUN_ERROR("ConnectNamedPipe()"); } if (provider->state != kSTAFConnectionProviderActive) break; // Ok, let's perform the callback now LocalConnectionData connData;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -