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

📄 stafprocess.cpp

📁 Software Testing Automation Framework (STAF)的开发代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF)                              *//* (C) Copyright IBM Corp. 2001                                              *//*                                                                           *//* This software is licensed under the Common Public License (CPL) V1.0.     *//*****************************************************************************/#include "STAF.h"#include "STAFProcess.h"#include "STAF_iostream.h"#include "STAFThread.h"#include "STAFMutexSem.h"#include "STAFEventSem.h"#include "STAFException.h"#include "STAFTrace.h"#include "STAFUtilWin32.h"#include "STAFInternalProcess.h"#include <deque>#include <map>#include <aclapi.h>    // For CreateProcessAsUser()#include <errno.h>     // For EACCES#define _WIN32_WINNT 0x400//F or some reason, winuser.h doesn't define these useful aliases#ifndef WINSTA_ALL_ACCESS#define WINSTA_ALL_ACCESS 0x0000037F#endif#ifndef DESKTOP_ALL_ACCESS#define DESKTOP_ALL_ACCESS 0x00001FF#endiftypedef struct PROFILEINFOIMPL {   DWORD    dwSize;          // Must be set to sizeof(PROFILEINFO)   DWORD    dwFlags;         // See flags above   LPTSTR   lpUserName;      // User name (required)   LPTSTR   lpProfilePath;   // Roaming profile path   LPTSTR   lpDefaultPath;   // Default user profile path   LPTSTR   lpServerName;    // Validating DC name in netbios format   LPTSTR   lpPolicyPath;    // Path to the NT4 style policy file   HANDLE   hProfile;        // Registry key handle - filled by function} PROFILEINFO, FAR * LPPROFILEINFO;// Typedefs for function pointers in USERENV.DLLtypedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (   HANDLE hToken,                // user token   LPPROFILEINFO lpProfileInfo   // user profile information);typedef BOOL (STDMETHODCALLTYPE FAR * LPFNUNLOADUSERPROFILE) (   HANDLE hToken,            // user token   HANDLE hProfile           // user profile handle);typedef BOOL (STDMETHODCALLTYPE FAR * LPFNCREATEENVBLOCK) (   LPVOID *lpEnvironment,    // environment block   HANDLE hToken,            // user token   BOOL   bInherit           // inheritance);typedef BOOL (STDMETHODCALLTYPE FAR * LPFNDESTROYENVBLOCK) (   LPVOID lpEnvironment    // environment block);HMODULE                 sUserEnvLib                  = NULL;LPFNLOADUSERPROFILE     sLoadUserProfileFunc         = NULL;LPFNUNLOADUSERPROFILE   sUnloadUserProfileFunc       = NULL;LPFNCREATEENVBLOCK      sCreateEnvironmentBlockFunc  = NULL;LPFNDESTROYENVBLOCK     sDestroyEnvironmentBlockFunc = NULL;HANDLE sProcessHeap = GetProcessHeap();// End of definitions for CreateUserAsProcess() stuff// Typedefs for function pointers in ADVAPI32.DLLtypedef BOOL (STDMETHODCALLTYPE FAR * LPFNSETSECURITYINFO) (   HANDLE hToken,                // user token   SE_OBJECT_TYPE ObjectType, // type of object    SECURITY_INFORMATION SecurityInfo, // type of security information to set    PSID psidOwner, // pointer to the new owner SID    PSID psidGroup, // pointer to the new primary group SID    PACL pDacl, // pointer to the new DACL    PACL pSacl // pointer to the new SACL);HMODULE                 sAdvApi32Lib                 = NULL;LPFNSETSECURITYINFO     sSetSecurityInfoFunc         = NULL;// End of definitions for SetSecurityInfo() stuffstruct ProcessMonitorInfo{    ProcessMonitorInfo(STAFProcessHandle_t aHandle = 0, STAFProcessID_t aPID = 0,                       STAFProcessEndCallbackLevel1 aCallback =                           STAFProcessEndCallbackLevel1(),                       HANDLE aUsrToken = 0, HANDLE aUsrProfile = 0)        : handle(aHandle), pid(aPID), callback(aCallback),          hUsrToken(aUsrToken), hUsrProfile(aUsrProfile)    { /* Do Nothing */ }    STAFProcessHandle_t handle;    STAFProcessID_t pid;    STAFProcessEndCallbackLevel1 callback;    unsigned int callbackLevel;    HANDLE hUsrToken;    HANDLE hUsrProfile;};typedef std::deque<ProcessMonitorInfo> ProcessMonitorList;typedef std::map<STAFProcessHandle_t, ProcessMonitorList> ProcessMonitorMap;struct ProcessMonitorThreadData{    HANDLE monitorWakeUp;    ProcessMonitorMap monitorMap;};typedef STAFRefPtr<ProcessMonitorThreadData> ProcessMonitorThreadDataPtr;typedef std::deque<ProcessMonitorThreadDataPtr> ProcessMonitorThreadList;// Prototypesstatic BOOL InitUserEnv();static BOOL InitAdvApi32();static void GetPrivilegeError(HANDLE handle, STAFString &errorMsg);static int GrantAccessToWinsta(HANDLE hUsrToken, bool bGrant,                               STAFString &errorMsg);static void DeleteMatchingAces(ACL* pdacl, void* psid);static unsigned int ProcessMonitorThread(void *);static unsigned int UserAuthenticate(STAFUserID_t &hUsrToken,                                     STAFString &username,                                     STAFString &password, bool mustValidate,                                     unsigned int *osRC,                                     STAFString &errorMsg);// Static datastatic STAFMutexSem sMonitorDataSem;static STAFEventSem sThreadSyncSem;static ProcessMonitorThreadDataPtr sTempThreadData;static ProcessMonitorThreadList sThreadList;// Substitution characters valid for a shell command on Windowschar *gSTAFProcessShellSubstitutionChars = "cCpPtTuUwWxX%";/*****************************************************************************//*                               Helper APIs                                 *//*****************************************************************************/// Writes trace warning with GetLastError()static void WriteTraceWarning(const STAFString &msg){    STAFTrace::trace(kSTAFTraceWarning, STAFString(msg) +                      " in STAFProcess::startProcess, OS_RC: " +                     GetLastError());}// Writes trace error with GetLastError()static void WriteTraceError(const STAFString &msg){    STAFTrace::trace(kSTAFTraceError, STAFString(msg) +                      " in STAFProcess::startProcess, OS_RC: " +                     GetLastError());}// Writes trace error with GetLastError()static void WriteTraceError2(const STAFString &msg){    STAFTrace::trace(kSTAFTraceError, STAFString(msg) + ", OS_RC: " +                     GetLastError());}// Writes trace error without GetLastError()static void WriteTraceError3(const STAFString &msg){    STAFTrace::trace(kSTAFTraceError, msg);}void InitProcessManager(){    static STAFMutexSem initSem;    static bool alreadyInited = false;    if (alreadyInited) return;    STAFMutexSemLock initLock(initSem);    if (alreadyInited) return;        if (STAFUtilWin32GetWinType() & kSTAFWinNTPlus)    {        // Set USERENV.DLL function pointers for CreateUserAsProcess()        // if running on Windows NT/2000/XP or above.        int rc = InitUserEnv();        if (rc != TRUE)            WriteTraceError2("InitUserEnv() failed in InitProcessManager()");                    // Set ADVAPI32.DLL function pointers for SetSecurityInfo()        // if running on Windows NT/2000/XP or above.        rc = InitAdvApi32();        if (rc != TRUE)            WriteTraceError2("InitAdvApi32() failed in InitProcessManager()");    }        alreadyInited = true;}unsigned int ProcessMonitorThread(void *){    try    {        ProcessMonitorThreadDataPtr threadData = sTempThreadData;        threadData->monitorWakeUp = CreateEvent(0, TRUE, FALSE, 0);        sThreadSyncSem.post();        HANDLE handles[MAXIMUM_WAIT_OBJECTS] = { 0 };        unsigned int signaledHandleIndex = 0;        ProcessMonitorMap::iterator iter = threadData->monitorMap.begin();        for(unsigned int numHandles = 0;; numHandles = 0)        {            // Use a nested block to ease lock usage            {                STAFMutexSemLock lock(sMonitorDataSem);                for(iter = threadData->monitorMap.begin();                    iter != threadData->monitorMap.end();                     iter++)                {                    if (numHandles == (MAXIMUM_WAIT_OBJECTS - 1)) break;                    handles[numHandles++] = iter->first;                }                handles[numHandles++] = threadData->monitorWakeUp;            }            DWORD rc = WaitForMultipleObjects(numHandles, handles, FALSE,                                              INFINITE);            if ((rc >= WAIT_OBJECT_0) &&                (rc <= (WAIT_OBJECT_0 + numHandles - 1)))            {                signaledHandleIndex = (unsigned int)(rc - WAIT_OBJECT_0);            }            else if ((rc >= WAIT_ABANDONED_0) &&                     (rc <= (WAIT_ABANDONED_0 + numHandles - 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                if (rc == WAIT_FAILED)                {                    WriteTraceError2("Got WAIT_FAILED from "                                     "WaitForMultipleObjects() in "                                     "ProcessMonitorThread()");                }                else if (rc == WAIT_TIMEOUT)                {                    STAFTrace::trace(kSTAFTraceError, "Got WAIT_TIMEOUT "                                     "from WaitForMultipleObjects() "                                     "in ProcessMonitorThread()");                }                else                {                    STAFTrace::trace(kSTAFTraceError, "Unexpected RC, " +                                      STAFString(rc) +                                     ", from WaitForMultipleObjects() "                                     "in processMonitorThread()");                }            }            if (signaledHandleIndex != (numHandles - 1))            {                unsigned int retCode = 0;                // Get the process return code and then free the handle                GetExitCodeProcess(handles[signaledHandleIndex],                                   (LPDWORD)&retCode);                CloseHandle(handles[signaledHandleIndex]);                // Now lock the list while we search for the appropriate                // entry and call the callback                sMonitorDataSem.request();                for(iter = threadData->monitorMap.begin();                    iter != threadData->monitorMap.end() &&                    (iter->first != handles[signaledHandleIndex]);                    iter++)                { /* Do Nothing */ }                if (iter != threadData->monitorMap.end())                {                    ProcessMonitorList monitorList = iter->second;                    threadData->monitorMap.erase(iter->first);                    sMonitorDataSem.release();                    for (ProcessMonitorList::iterator monitorIter =                                                      monitorList.begin();                         monitorIter != monitorList.end(); ++monitorIter)                    {                        ProcessMonitorInfo &processMonitorInfo = *monitorIter;                        if (processMonitorInfo.hUsrToken != 0)                        {   // Perform cleanup for CreateProcessAsUser()                            // Unload the user profile                            if (processMonitorInfo.hUsrProfile != 0)                            {                                if (!sUnloadUserProfileFunc(                                    processMonitorInfo.hUsrToken,                                    processMonitorInfo.hUsrProfile))                                {                                    WriteTraceError2("UnloadUserProfile() "                                                     "failed in ProcessMonitor"                                                     "Thread()");                                }                            }                            // Clean up the interactive winsta/desktop DACLs                            STAFString errorMsg;                            GrantAccessToWinsta(processMonitorInfo.hUsrToken,                                                FALSE, errorMsg);                            CloseHandle(processMonitorInfo.hUsrToken);                        }                        if (processMonitorInfo.callback.callback != 0)                        {                            processMonitorInfo.callback.callback(                                processMonitorInfo.pid,                                processMonitorInfo.handle, retCode,                                processMonitorInfo.callback.data);                        }                    }                }                else                {                    // We shouldn't have been waiting on an object that is                    // no longer in our list.  Spit out an error and continue.                    // Move along ... Nothing to see here.                    STAFTrace::trace(kSTAFTraceError, "Signaled object from "                                     "WaitForMultipleObjects() not in list in "                                     "processMonitorThread()");                    sMonitorDataSem.release();                }            } // end if we were not awoken by our event semaphore            else ResetEvent(threadData->monitorWakeUp);        }  // end of endless for loop    }    catch (STAFException &se)    {

⌨️ 快捷键说明

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