⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 staflocalipcconnprovider.cpp

📁 Software Testing Automation Framework (STAF)的开发代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                connData.connFunc   = provider->connFunc;                connData.provider   = provider;                connData.connection = new STAFLocalConnectionImpl(connImpl);                provider->threadManager->dispatch(                    STAFLocalIPCConnectionThread,                    new LocalConnectionData(connData));            }        }        else        {            // Set up variables into shared memory            DWORD *pidSwap = (DWORD *)provider->sharedMem;            HANDLE *readHandlePtr = (HANDLE *)((char *)provider->sharedMem +                                               (2 * sizeof(DWORD)));            HANDLE *writeHandlePtr =                (HANDLE *)((char *)provider->sharedMem +                           (2 * sizeof(DWORD)) + sizeof(HANDLE));                        while (provider->state == kSTAFConnectionProviderActive)            {                // XXX: See if there is any positive gain by moving the                // definitions of these 3 variables outside the while loop                HANDLE clientReadHandle = 0;                HANDLE clientWriteHandle = 0;                HANDLE clientProcess = 0;                WaitForMultipleObjects(1, &provider->serverSynch,                                       TRUE, INFINITE);                            if (provider->state != kSTAFConnectionProviderActive)                    break;                // XXX: Temp until auto-reset event sem done                ResetEvent(provider->serverSynch);                clientProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE,                                            *pidSwap);                if (clientProcess == 0)                    HANDLE_SHAREDMEM_RUN_ERROR("OpenProcess2()");                // Create ServerRead/ClientWrite pipe                if (!CreatePipe(&connImpl.readHandle, &clientWriteHandle, 0,                                0x00000400))                {                    HANDLE_SHAREDMEM_RUN_ERROR("CreatePipe()");                }                // Create ServerWrite/ClientRead pipe                if (!CreatePipe(&clientReadHandle, &connImpl.writeHandle, 0,                                0x00000400))                {                    HANDLE_SHAREDMEM_RUN_ERROR("CreatePipe()");                }                if (!DuplicateHandle(GetCurrentProcess(), clientReadHandle,                                     clientProcess, readHandlePtr, 0, FALSE,                                     DUPLICATE_SAME_ACCESS |                                     DUPLICATE_CLOSE_SOURCE))                {                    HANDLE_SHAREDMEM_RUN_ERROR("DuplicateHandle(readHandle)");                }                if (!DuplicateHandle(GetCurrentProcess(), clientWriteHandle,                                     clientProcess, writeHandlePtr, 0, FALSE,                                     DUPLICATE_SAME_ACCESS |                                     DUPLICATE_CLOSE_SOURCE))                {                    HANDLE_SHAREDMEM_RUN_ERROR("DuplicateHandle(writeHandle)");                }                CloseHandle(clientProcess);                SetEvent(provider->clientSynch);                            // Ok, let's perform the callback now                LocalConnectionData connData;                connData.connFunc   = provider->connFunc;                connData.provider   = provider;                connData.connection = new STAFLocalConnectionImpl(connImpl);                provider->threadManager->dispatch(                    STAFLocalIPCConnectionThread,                    new LocalConnectionData(connData));            }        }    }    CATCH_STANDARD_TRACE("STAFLocalIPCRunThread");    if (sd != 0) STAFUtilWin32DeleteNullSD(&sd);    try    {        provider->syncSem->post();    }    CATCH_STANDARD_TRACE("STAFLocalIPCRunThread");    return 0;}//============ Shared Memory Only Functions ==================================// These functions are only used if using shared memory (not when using// named pipes as the ipcMethod) #define HANDLE_PIPEDATA_ERROR(string) \HANDLE_PIPEDATA_ERROR2(string, GetLastError())#define HANDLE_PIPEDATA_ERROR2(string, error) \{\    STAFString theError = STAFString(string) + ", RC=" + STAFString(error);\\    if (errorBuffer)                  *errorBuffer = theError.adoptImpl();\    if (sd != 0)                      STAFUtilWin32DeleteNullSD(&sd);\    if (sharedMem != 0)               UnmapViewOfFile(sharedMem);\    if (fileMap != 0)                 CloseHandle(fileMap);\    if (pipeData.clientMutex != 0)    CloseHandle(pipeData.clientMutex);\    if (pipeData.serverSynchSem != 0) CloseHandle(pipeData.serverSynchSem);\    if (pipeData.clientSynchSem != 0) CloseHandle(pipeData.clientSynchSem);\\    return;\}// Note: You should already own sPipeMapSem before calling this functionstatic void GetPipeData(const STAFString &pipeName, PipeData &pipeData,                        STAFString_t *errorBuffer){    PipeMap::iterator iter;    if ((iter = sPipeMap.find(pipeName)) == sPipeMap.end())    {        HANDLE fileMap = 0;        void *sharedMem = 0;        DWORD *serverPID = 0;        SECURITY_ATTRIBUTES sa;        PSECURITY_DESCRIPTOR sd = 0;        STAFString globalStr = "";        if (STAFUtilWin32GetWinType() & kSTAFWin2KPlus)        {            // Open Process to get process handle and SetSecurityInfo            HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE,                                         GetCurrentProcessId());            if (pHandle == 0) HANDLE_PIPEDATA_ERROR("First OpenProcess()");                    int rc = SetSecurityInfo(pHandle, SE_KERNEL_OBJECT,                                     DACL_SECURITY_INFORMATION, 0, 0, 0, 0);            if (rc != 0) HANDLE_PIPEDATA_ERROR2("SetSecurityInfo()", rc);              // To support Fast User Switching and Terminal Server need            // to prepend Global\\ for Win2K and above.            globalStr = "Global\\";        }        STAFString sharedMemName = globalStr + pipeName + "/SharedMemory";        // Obtain Shared Memory        fileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,                                  sharedMemName.toCurrentCodePage()->buffer());        if (fileMap == 0) HANDLE_PIPEDATA_ERROR("OpenFileMapping()");        sharedMem = MapViewOfFile(fileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);        if (sharedMem == 0) HANDLE_PIPEDATA_ERROR("MapViewOfFile()");        // Set up security attributes        sa.nLength = sizeof(SECURITY_ATTRIBUTES);        sa.bInheritHandle = TRUE;        sa.lpSecurityDescriptor = sd;        // Create Null Security Descriptor to allow access to everyone        if (STAFUtilWin32CreateNullSD(&sd))            HANDLE_PIPEDATA_ERROR("STAFUtilWin32CreateNullSD()");        sa.lpSecurityDescriptor = sd;        // Get initialization semaphores        STAFString clientMutexName = globalStr + pipeName + "/ClientMutex";        STAFString serverSynchName = globalStr + pipeName + "/ServerSynch";        STAFString clientSynchName = globalStr + pipeName + "/ClientSynch";        pipeData.clientMutex = CreateMutex(&sa, FALSE,                               clientMutexName.toCurrentCodePage()->buffer());        if (pipeData.clientMutex == 0) HANDLE_PIPEDATA_ERROR("CreateMutex()");        pipeData.serverSynchSem = CreateEvent(&sa, TRUE, FALSE,                                   serverSynchName.toCurrentCodePage()->buffer());        if (pipeData.serverSynchSem == 0) HANDLE_PIPEDATA_ERROR("CreateEvent()");                        pipeData.clientSynchSem = CreateEvent(&sa, TRUE, FALSE,                                   clientSynchName.toCurrentCodePage()->buffer());        if (pipeData.clientSynchSem == 0) HANDLE_PIPEDATA_ERROR("CreateEvent()");        // Set up some pointers into the shared memory area        pipeData.pidSwap = (DWORD *)sharedMem;        serverPID = (DWORD *)((char *)sharedMem + sizeof(DWORD));        pipeData.readHandlePtr = (HANDLE *)((char *)sharedMem +                                            (2 *sizeof(DWORD)));        pipeData.writeHandlePtr = (HANDLE *)((char *)sharedMem +                                             (2 * sizeof(DWORD)) +                                             sizeof(HANDLE));        // Obtain handle to Factory process        pipeData.serverProcessHandle = OpenProcess(PROCESS_ALL_ACCESS,                                                   FALSE, *serverPID);        if (pipeData.serverProcessHandle == 0)            HANDLE_PIPEDATA_ERROR("Second OpenProcess()");        sPipeMap[pipeName] = pipeData;        if (sd != 0) STAFUtilWin32DeleteNullSD(&sd);    }    else pipeData = iter->second;}#define HANDLE_PIPECONNECT_ERROR(string) \HANDLE_PIPECONNECT_ERROR2(string, GetLastError())#define HANDLE_PIPECONNECT_ERROR2(string, error) \{\    STAFString theError = STAFString(string) + STAFString(error);\\    if (errorBuffer)                  *errorBuffer = theError.adoptImpl();\\    return false;\}// True = successfully connected, False = server process disappeared// Note: This function can still throw exceptionsstatic bool ConnectToPipe(PipeData &pipeData, HANDLE &readHandle,                          HANDLE &writeHandle, STAFString_t *errorBuffer){    // Obtain the client mutex on this "named pipe", while we swap    // process information with the STAFLocalConnectionFactory    WaitForSingleObject(pipeData.clientMutex, INFINITE);    *pipeData.pidSwap = GetCurrentProcessId();    ResetEvent(pipeData.clientSynchSem);    SetEvent(pipeData.serverSynchSem);    HANDLE waitArray[2] = { pipeData.clientSynchSem,                            pipeData.serverProcessHandle };    DWORD rc = WaitForMultipleObjects(2, waitArray, FALSE, INFINITE);    unsigned int signaledHandleIndex = 0;    if ((rc >= WAIT_OBJECT_0) && (rc <= (WAIT_OBJECT_0 + 2 - 1)))    {        signaledHandleIndex = (unsigned int)(rc - WAIT_OBJECT_0);    }    else if ((rc >= WAIT_ABANDONED_0) &&             (rc <= (WAIT_ABANDONED_0 + 2 - 1)))    {        signaledHandleIndex = (unsigned int)(rc - WAIT_ABANDONED_0);    }    else    {        // We either got WAIT_FAILED, WAIT_TIMEOUT or some other return        // code which we weren't expecting, so spit out an error message        // and continue        ReleaseMutex(pipeData.clientMutex);        HANDLE_PIPECONNECT_ERROR2("Other side closed connection", rc);    }    if (signaledHandleIndex != 0)    {        ReleaseMutex(pipeData.clientMutex);        return false;    }    if (pipeData.pidSwap == 0)    {        ReleaseMutex(pipeData.clientMutex);        HANDLE_PIPECONNECT_ERROR("Other side closed connection");    }    readHandle = *pipeData.readHandlePtr;    writeHandle = *pipeData.writeHandlePtr;    ReleaseMutex(pipeData.clientMutex);    return true;}//========= End Shared Memory Only Functions =================================STAFRC_t STAFConnectionProviderConstruct(STAFConnectionProvider_t *provider,                                         void *constructInfo,                                         unsigned int constructInfoLevel,                                         STAFString_t *errorBuffer){    if (provider == 0) return kSTAFInvalidParm;    if (constructInfoLevel != 1) return kSTAFInvalidAPILevel;    STAFConnectionProviderConstructInfoLevel1 *cpInfo =        reinterpret_cast<STAFConnectionProviderConstructInfoLevel1 *>(            constructInfo);    try    {        static bool initedAtExit =  false;        if (!initedAtExit)        {            STAFMutexSemLock lock(sActiveProvidersSem);            if (!initedAtExit) atexit(atExit);        }        STAFLocalConnectionProviderImpl lipcData;        lipcData.mode     = cpInfo->mode;        lipcData.syncSem  = STAFEventSemPtr(            new STAFEventSem, STAFEventSemPtr::INIT);        lipcData.state    = kSTAFConnectionProviderStopped;        lipcData.ipcName  = "STAF";        lipcData.threadManager = STAFThreadManagerPtr(            new STAFThreadManager, STAFThreadManagerPtr::INIT);                // The Windows local connection provider supports two methods for        // handling interprocess communication (IPC):        // 1) Shared memory        // 2) Named pipes        //        // Notes:        // - Windows Me/98/95 cannot create named pipes so the shared memory        //   IPC method must be used.        // - Windows Vista with UAC enabled cannot use global shared memory        //   so the named pipes method must be used.        // - The performance using either of these methods is equivalent.        //   So, we chose to continue to use shared memory for pre-Vista        //   machines (though we could have selected to use named pipes for        //   Windows NT and later) and we are using named pipes for Vista        //   and future Windows versions.        if (STAFUtilWin32GetWinType() & kSTAFWinVistaPlus)            lipcData.ipcMethod = kNamedPipes;        else            lipcData.ipcMethod = kSharedMemory;        // Get instance name        if (getenv("STAF_INSTANCE_NAME") != NULL)        {            lipcData.ipcName  =  getenv("STAF_INSTANCE_NAME");        }        for (unsigned int i = 0; i < cpInfo->numOptions; ++i)        {            STAFString thisOption =                       STAFString(cpInfo->optionNames[i]).upperCase();            if (thisOption == "IPCNAME")            {                lipcData.ipcName += cpInfo->optionValues[i];            }            else            {                if (errorBuffer)                {                    *errorBuffer =                        STAFString(cpInfo->optionNames[i]).adoptImpl();                }                return kSTAFInvalidValue;            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -