예제 #1
0
int pthread_np_notice_thread()
{
  if (!pthread_self()) {
    pthread_t pth = (pthread_t)calloc(sizeof(pthread_thread),1);
    pth->teb = NtCurrentTeb();
    pthread_mutex_init(&pth->fiber_lock,NULL);
    pthread_mutex_init(&pth->lock,NULL);
    pth->state = pthread_state_running;
    pth->fiber_group = pth;

    sigemptyset(&pth->blocked_signal_set);

    DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
                    GetCurrentProcess(), &pth->handle, 0, TRUE,
                    DUPLICATE_SAME_ACCESS);
    tls_impersonate(pth);

    if (pthread_initialized) {
      RegisterWaitForSingleObject(&pth->wait_handle,
                                  pth->handle,
                                  pthreads_win32_unnotice,
                                  pth,
                                  INFINITE,
                                  WT_EXECUTEONLYONCE);
    }
    return 1;
  } else {
    return 0;
  }
}
예제 #2
0
void ExplorerAliveChecker::init()
{
	DWORD dwExplorerProcessId = NULL;

	GetWindowThreadProcessId(_explorerHwnd, &dwExplorerProcessId);

	if (dwExplorerProcessId == NULL)
		ExplorerQuitCallback(this, FALSE);

	HANDLE explorerProcessHandle = OpenProcess(SYNCHRONIZE,
									FALSE,
									dwExplorerProcessId);
	
	if (explorerProcessHandle != NULL)
	{
		HANDLE waitObjectHandle;
		// request function to t
		RegisterWaitForSingleObject(&waitObjectHandle,
									explorerProcessHandle,
									ExplorerQuitCallback,
									this, // argument to pass to callback function
									INFINITE,
									WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE);
	}

			
}
예제 #3
0
		bool ObjectWatcher::StartWatching(HANDLE object, Delegate* delegate) {
			CHECK(delegate);
			if (wait_object_) {
				NOTREACHED() << "Already watching an object";
				return false;
			}

			// Since our job is to just notice when an object is signaled and report the
			// result back to this thread, we can just run on a Windows wait thread.
			DWORD wait_flags = WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE;

			// DoneWaiting can be synchronously called from RegisterWaitForSingleObject,
			// so set up all state now.
			callback_ = base::Bind(&ObjectWatcher::Signal, weak_factory_.GetWeakPtr(),
				delegate);
			object_ = object;
			origin_loop_ = MessageLoop::current();

			if (!RegisterWaitForSingleObject(&wait_object_, object, DoneWaiting,
				this, INFINITE, wait_flags)) {
				DPLOG(FATAL) << "RegisterWaitForSingleObject failed";
				object_ = NULL;
				wait_object_ = NULL;
				return false;
			}

			// We need to know if the current message loop is going away so we can
			// prevent the wait thread from trying to access a dead message loop.
			MessageLoop::current()->AddDestructionObserver(this);
			return true;
		}
예제 #4
0
static PyObject *
overlapped_RegisterWaitWithQueue(PyObject *self, PyObject *args)
{
    HANDLE NewWaitObject;
    HANDLE Object;
    ULONG Milliseconds;
    struct PostCallbackData data, *pdata;

    if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE F_POINTER F_DWORD,
                          &Object,
                          &data.CompletionPort,
                          &data.Overlapped,
                          &Milliseconds))
        return NULL;

    /* Use PyMem_RawMalloc() rather than PyMem_Malloc(), since
       PostToQueueCallback() will call PyMem_Free() from a new C thread
       which doesn't hold the GIL. */
    pdata = PyMem_RawMalloc(sizeof(struct PostCallbackData));
    if (pdata == NULL)
        return SetFromWindowsErr(0);

    *pdata = data;

    if (!RegisterWaitForSingleObject(
            &NewWaitObject, Object, (WAITORTIMERCALLBACK)PostToQueueCallback,
            pdata, Milliseconds,
            WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE))
    {
        PyMem_RawFree(pdata);
        return SetFromWindowsErr(0);
    }

    return Py_BuildValue(F_HANDLE, NewWaitObject);
}
예제 #5
0
bool DirectoryWinAPI::setWatch(const std::string& path, ICallbackBase<void>* cb)
{
	if(callbacks.size() > MAXIMUM_WAIT_OBJECTS)
	{
		LOGERROR("Too many objects being watched", "setWatch");
	}

	HANDLE watchHandle = FindFirstChangeNotification(path.c_str(), TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE);
	if (watchHandle == INVALID_HANDLE_VALUE) 
	{
		DWORD err = GetLastError();
		LOGERROR(err, "FindFirstChangeNotification");
		return false;
	}

	HANDLE poolHandle;
	if(!RegisterWaitForSingleObject(&poolHandle, watchHandle, onEventTriggered, watchHandle, INFINITE, WT_EXECUTEINWAITTHREAD))
	{
		DWORD err = GetLastError();
		LOGERROR(err, "RegisterWaitForSingleObject");
		return false;
	}

	DirWinAPIWait waitStruct = { cb, poolHandle };
	callbacks[watchHandle] = waitStruct;

	return true;
}
예제 #6
0
OP_STATUS WindowsOpAutoUpdatePI::PackageExtractor::Extract(uni_char *package)
{
    if (m_is_extracting)
        return OpStatus::ERR;

    m_is_extracting = TRUE;

    SHELLEXECUTEINFO info;
    memset(&info, 0, sizeof(info));

    info.cbSize = sizeof(info);
    info.fMask = SEE_MASK_NOCLOSEPROCESS;
    info.lpVerb = NULL;
    info.lpFile = package;
    info.nShow = SW_HIDE;

    if (!ShellExecuteEx(&info))
    {
        return OpStatus::ERR;
    }

    m_process_handle = info.hProcess;

    if (!RegisterWaitForSingleObject(&m_wait_object, m_process_handle, WaitOrTimerCallback, this, INFINITE, WT_EXECUTEONLYONCE))
    {
        CloseHandle(m_process_handle);
        return OpStatus::ERR;
    }

    return OpStatus::OK;
}
예제 #7
0
bool MonitorIPs::Initialize()
{
    Log(LOG_DEBUG,__LINE__,">> MonIPs.Init");

    m_hSync = CreateMutex(NULL,FALSE,NULL);
    if(!m_hSync)
    {
        Log(LOG_DEBUG,__LINE__,"<< MonIPs.Init, Sync Obj %u",GetLastError());
        return false;
    }

    m_o.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (!m_o.hEvent)
    {
        Log(LOG_DEBUG,__LINE__,"<< MonIPs.Init, CreateEv %u",GetLastError());
        return false;
    }

    if(!RegisterWaitForSingleObject(&m_hWait,m_o.hEvent,s_OnChange,this,INFINITE,0))
    {
        Log(LOG_DEBUG,__LINE__,"<< MonIPs.Init, RegWaitForSnglObj %u",GetLastError());
        return false;
    }

    CheckIPAddress();

    Log(LOG_DEBUG,__LINE__,"<< MonIPs.Init, Ev 0x%p, ret True",m_o.hEvent);
    return true;
}
예제 #8
0
파일: tty.c 프로젝트: hghazal/node
static void uv_tty_queue_read_raw(uv_loop_t* loop, uv_tty_t* handle) {
  uv_req_t* req;
  BOOL r;

  assert(handle->flags & UV_HANDLE_READING);
  assert(!(handle->flags & UV_HANDLE_READ_PENDING));

  assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE);

  handle->read_line_buffer = uv_null_buf_;

  req = &handle->read_req;
  memset(&req->overlapped, 0, sizeof(req->overlapped));

  r = RegisterWaitForSingleObject(&handle->read_raw_wait,
                                  handle->handle,
                                  uv_tty_post_raw_read,
                                  (void*) req,
                                  INFINITE,
                                  WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
  if (!r) {
    handle->read_raw_wait = NULL;
    SET_REQ_ERROR(req, GetLastError());
    uv_insert_pending_req(loop, req);
  }

  handle->flags |= UV_HANDLE_READ_PENDING;
  handle->reqs_pending++;
}
void NetworkConnection::continueReceive()
{
	if (closed || sendError)	// Close if anything is wrong
	{
		close();
	}
	else
	{
		bufferInfo.buf = (char*)receiveBuffer;	// Set buffer data
		bufferInfo.len = BUFFER_SIZE;
	
										// 0 means send completed instantly
		if (WSARecv(connection, &bufferInfo, 1, &bytesReceived, 
			&flags, &receiveOverlapped, NULL) == 0) 
		{
			dataReceived();	// Wait for more data
		}
		else
		{
			if (WSAGetLastError() == WSA_IO_PENDING) // Data is pending
			{		// Send a wait handle to the WinAPI thread pool
				RegisterWaitForSingleObject(&newWaitHandle, 
					receiveOverlapped.hEvent, 
					DataReceivedCallback, 
					this, INFINITE, WT_EXECUTEONLYONCE);
			}
			else
			{
				close();
			}
		}
	}
}
예제 #10
0
파일: timer.c 프로젝트: mheily/libkqueue
int
evfilt_timer_knote_create(struct filter *filt, struct knote *kn)
{
    HANDLE th;
    LARGE_INTEGER liDueTime;

    kn->kev.flags |= EV_CLEAR;

    th = CreateWaitableTimer(NULL, FALSE, NULL);
    if (th == NULL) {
        dbg_lasterror("CreateWaitableTimer()");
        return (-1);
    }
    dbg_printf("created timer handle %p", th);

    convert_msec_to_filetime(&liDueTime, kn->kev.data);

    // XXX-FIXME add completion routine to this call
    if (!SetWaitableTimer(th, &liDueTime, (LONG)( (kn->kev.flags & EV_ONESHOT) ? 0 : kn->kev.data ), NULL, NULL, FALSE)) {
        dbg_lasterror("SetWaitableTimer()");
        CloseHandle(th);
        return (-1);
    }

    kn->data.handle = th;
    RegisterWaitForSingleObject(&kn->kn_event_whandle, th, evfilt_timer_callback, kn, INFINITE, 0);
    knote_retain(kn);

    return (0);
}
예제 #11
0
파일: tcp.c 프로젝트: mindspeaker/libuv
int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
    uv_buf_t bufs[], int bufcnt, uv_write_cb cb) {
  int result;
  DWORD bytes;

  uv_req_init(loop, (uv_req_t*) req);
  req->type = UV_WRITE;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;
  memset(&req->overlapped, 0, sizeof(req->overlapped));

  /* Prepare the overlapped structure. */
  memset(&(req->overlapped), 0, sizeof(req->overlapped));
  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
    req->event_handle = CreateEvent(NULL, 0, 0, NULL);
    if (!req->event_handle) {
      uv_fatal_error(GetLastError(), "CreateEvent");
    }
    req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
    req->wait_handle = INVALID_HANDLE_VALUE;
  }

  result = WSASend(handle->socket,
                   (WSABUF*)bufs,
                   bufcnt,
                   &bytes,
                   0,
                   &req->overlapped,
                   NULL);

  if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
    /* Request completed immediately. */
    req->queued_bytes = 0;
    handle->reqs_pending++;
    handle->write_reqs_pending++;
    REGISTER_HANDLE_REQ(loop, handle, req);
    uv_insert_pending_req(loop, (uv_req_t*) req);
  } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
    /* Request queued by the kernel. */
    req->queued_bytes = uv_count_bufs(bufs, bufcnt);
    handle->reqs_pending++;
    handle->write_reqs_pending++;
    REGISTER_HANDLE_REQ(loop, handle, req);
    handle->write_queue_size += req->queued_bytes;
    if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
        !RegisterWaitForSingleObject(&req->wait_handle,
          req->event_handle, post_write_completion, (void*) req,
          INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) {
      SET_REQ_ERROR(req, GetLastError());
      uv_insert_pending_req(loop, (uv_req_t*)req);
    }
  } else {
    /* Send failed due to an error. */
    uv__set_sys_error(loop, WSAGetLastError());
    return -1;
  }

  return 0;
}
예제 #12
0
/* function registers `exit` callback */
BOOL Process::RegisterExitCallback(ProcessCallback callback)
{
	if (!callback) 
		return FALSE;

	exitCallback = callback;

	/* directs a wait thread in the thread pool to wait on the object */
	return RegisterWaitForSingleObject(&hWait, hProcess, OnExited, this, INFINITE, WT_EXECUTEONLYONCE);
}
예제 #13
0
static void register_wait( int job_id )
{
    if ( globs.jobs > MAXIMUM_WAIT_OBJECTS )
    {
        HANDLE ignore;
        RegisterWaitForSingleObject( &cmdtab[ job_id ].wait_handle,
            cmdtab[ job_id ].pi.hProcess,
            &try_wait_callback, &cmdtab[ job_id ], INFINITE,
            WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE );
    }
}
예제 #14
0
파일: IPC.cpp 프로젝트: N1MX/UOInterface
	extern "C" __declspec(dllexport) DWORD WINAPI OnAttach(LPDWORD args)
	{
		try
		{
			const DWORD access = PROCESS_DUP_HANDLE | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | SYNCHRONIZE;
			HANDLE hProcess = OpenProcess(access, FALSE, args[0]);
			if (!hProcess)
				throw L"OpenProcess";

			//init shared memory
			HANDLE mmf = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, sizeof(SharedMemory), nullptr);
			if (!mmf)
				throw L"CreateFileMapping";
			shared = (SharedMemory*)MapViewOfFile(mmf, FILE_MAP_ALL_ACCESS, 0, 0, 0);
			if (!shared)
				throw L"MapViewOfFile";
			HANDLE mmfRemote = Duplicate(hProcess, mmf);
			CloseHandle(mmf);

			if (!RegisterWaitForSingleObject(&mmf, hProcess, OnExit, nullptr, INFINITE, WT_EXECUTEONLYONCE))
				throw L"RegisterWaitForSingleObject";
			CloseHandle(mmf);

			//init events
			sentOut = CreateEvent(nullptr, FALSE, FALSE, nullptr);
			handledOut = CreateEvent(nullptr, FALSE, FALSE, nullptr);
			sentIn = CreateEvent(nullptr, FALSE, FALSE, nullptr);
			handledIn = CreateEvent(nullptr, FALSE, FALSE, nullptr);
			if (!sentOut || !handledOut || !sentIn || !handledIn)
				throw L"CreateEvent";
			shared->msgOut[0] = (UINT)Duplicate(hProcess, sentOut);
			shared->msgOut[1] = (UINT)Duplicate(hProcess, handledOut);
			shared->msgOut[2] = (UINT)Duplicate(hProcess, sentIn);
			shared->msgOut[3] = (UINT)Duplicate(hProcess, handledIn);
			CloseHandle(hProcess);

			//init UOHooks
			Client client;
			Hooks::Imports(client);
			Hooks::Packets(client);
			Hooks::Other(client);
			if (args[1])
				Patches::Encryption(client);
			Patches::Multi(client);
			Patches::Intro(client);
			memcpy(shared->dataOut, Hooks::GetPacketTable(), 0x100 * sizeof(UINT));

			std::thread(MessagePump).detach();//start ipc server
			return (DWORD)mmfRemote;
		}
		catch (LPCWSTR str) { MessageBox(nullptr, str, L"OnAttach", MB_ICONERROR | MB_OK); }
		return 0;
	}
예제 #15
0
파일: process.c 프로젝트: HenryRawas/libuv
void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
  if (handle->wait_handle != INVALID_HANDLE_VALUE) {
    handle->close_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
    UnregisterWaitEx(handle->wait_handle, handle->close_handle);
    handle->wait_handle = NULL;

    RegisterWaitForSingleObject(&handle->wait_handle, handle->close_handle,
        close_wait_callback, (void*)handle, INFINITE,
        WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
  } else {
    uv_want_endgame(loop, (uv_handle_t*)handle);
  }
}
//-----------------------------------------------------------------------------
// Function:    MonitorPeopleNearMe
//
// Purpose:     Watches for change events in PeopleNearMe data
//
// Returns:     HRESULT
//
HRESULT MonitorPeopleNearMe()
{
    HRESULT hr = S_OK;
    PEER_COLLAB_EVENT_REGISTRATION  eventReg = {0};
   
    // Create the event handle for the model
    //
    g_hModelEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    if (NULL == g_hModelEvent)
    {
        return E_OUTOFMEMORY;
    }

    // Setup the event registration specifying the type of event to be notified about
    //
    eventReg.eventType = PEER_EVENT_PEOPLE_NEAR_ME_CHANGED;
    eventReg.pInstance = NULL;

    // Register to be notified when the People Near Me change
    //
    hr = PeerCollabRegisterEvent(g_hModelEvent, 1, &eventReg, &g_hModelPeerEvent);

    if (SUCCEEDED(hr))
    {
        // Registers a wait object that will call ProcessUpdateCallBack
        // whenever a PEER_EVENT_PEOPLE_NEAR_ME_CHANGED is received.
        //
        if (!RegisterWaitForSingleObject(&g_hModelWaitObject,
                                    g_hModelEvent, 
                                    ProcessUpdateCallBack,
                                    NULL,
                                    INFINITE,
                                    0))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
        }
    }

    if (FAILED(hr))
    {
        MessageBox(g_hModelDlgOwner, L"Error", L"Could not initialize People Near Me monitoring.", MB_OK);
    }

    return hr;
}
예제 #17
0
int monitor_service() {
  /* Set service status to started */
  int ret = start_service();
  if (ret) {
    char code[16];
    _snprintf(code, sizeof(code), "%d", ret);
    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_START_SERVICE_FAILED, exe, service_name, ret, 0);
    return ret;
  }
  log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_STARTED_SERVICE, exe, flags, service_name, dir, 0);

  /* Monitor service service */
  if (! RegisterWaitForSingleObject(&wait_handle, process_handle, end_service, (void *) pid, INFINITE, WT_EXECUTEONLYONCE | WT_EXECUTELONGFUNCTION)) {
    log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_REGISTERWAITFORSINGLEOBJECT_FAILED, service_name, exe, error_string(GetLastError()), 0);
  }

  return 0;
}
예제 #18
0
bool CEXIETHERNET::RecvInit()
{
	// Set up recv event

	if ((mHRecvEvent = CreateEvent(nullptr, false, false, nullptr)) == nullptr)
	{
		ERROR_LOG(SP1, "Failed to create recv event:%x", GetLastError());
		return false;
	}

	ZeroMemory(&mReadOverlapped, sizeof(mReadOverlapped));

	RegisterWaitForSingleObject(&mHReadWait, mHRecvEvent, ReadWaitCallback,
		this, INFINITE, WT_EXECUTEDEFAULT);

	mReadOverlapped.hEvent = mHRecvEvent;

	return true;
}
예제 #19
0
    //-------------------------------------------------------------------------
    Bool Instance::Load( DWORD process_id )
    {
        xassert(_process_id == 0);

        // open process with all access privileges required by the tools that will use it (dont use PROCESS_ALL_ACCESS)
        _process = OpenProcess(
            PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_CREATE_THREAD|PROCESS_VM_READ|PROCESS_VM_WRITE|SYNCHRONIZE,
            FALSE, process_id);
        if( _process )
        {
            // choose inject dll
            const Char* inject_dll = _ChooseInjectDll();
            if( inject_dll != NULL )
            {
                // set notify name
                _injector.SetNotifyName(INJECT_NOTIFY_FUNCTION);

                // load
                if( _injector.Load(_process, inject_dll) )
                {
                    // notify init
                    if( Notify(NOTIFY_INIT) )
                    {
                        // register process exit handler
                        if( RegisterWaitForSingleObject(&_wait_handle, _process, _ProcessExitHandler, this, INFINITE, WT_EXECUTEONLYONCE) )
                        {
                            _process_id = process_id;
                            return true;
                        }
                    }
                }
            }

            // unload
            Unload();
        }

        return false;
    }
예제 #20
0
파일: win32.c 프로젝트: prasincs/pcp
int
__pmSetSignalHandler(int sig, __pmSignalHandler func)
{
    int sts, index;
    char *signame, evname[64];
    HANDLE eventhdl, waithdl;

    if ((signame = MapSignals(sig, &index)) < 0)
	return index;

    if (signals[index].callback) {	/* remove old handler */
	UnregisterWait(signals[index].waithandle);
	CloseHandle(signals[index].eventhandle);
	signals[index].callback = NULL;
	signals[index].signal = -1;
    }

    if (func == SIG_IGN)
	return 0;

    sts = 0;
    snprintf(evname, sizeof(evname), "PCP/%" FMT_PID "/%s", getpid(), signame);
    if (!(eventhdl = CreateEvent(NULL, FALSE, FALSE, TEXT(evname)))) {
	sts = GetLastError();
	fprintf(stderr, "CreateEvent::%s failed (%d)\n", signame, sts);
    }
    else if (!RegisterWaitForSingleObject(&waithdl, eventhdl,
		SignalCallback, (PVOID)index, INFINITE, 0)) {
	sts = GetLastError();
	fprintf(stderr, "RegisterWait::%s failed (%d)\n", signame, sts);
    }
    else {
	signals[index].eventhandle = eventhdl;
	signals[index].waithandle = waithdl;
	signals[index].callback = func;
	signals[index].signal = sig;
    }
    return sts;
}
예제 #21
0
파일: orte_wait.c 프로젝트: bringhurst/ompi
int
orte_wait_cb(pid_t wpid, orte_wait_fn_t callback, void *data)
{
    opal_process_handle_t* handle;

    if (wpid <= 0) return ORTE_ERR_NOT_IMPLEMENTED;
    if (NULL == callback) return ORTE_ERR_BAD_PARAM;

    OPAL_THREAD_LOCK(&mutex);
    handle = find_pending_pid(wpid, false);
    if( handle != NULL ) {
        opal_list_remove_item( &pending_pids, (opal_list_item_t*)handle );
        OBJ_RELEASE(handle);
        return ORTE_SUCCESS;
    }
    handle = find_pending_cb( wpid, true );
    handle->pid = wpid;
    handle->callback = callback;
    handle->data = data;

    if( false == RegisterWaitForSingleObject( &handle->registered_handle, (HANDLE)handle->pid, 
                                              trigger_process_detection, (void*)handle, INFINITE,
                                              WT_EXECUTEONLYONCE | WT_EXECUTELONGFUNCTION) ) {
        DWORD errcode = GetLastError();
        char* localbuf = NULL;

        FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                       NULL, errcode, 0, (LPTSTR)&localbuf, 1024, NULL );
        opal_output( 0, "Failed to initialize the process callback for pid %lu error %s\n",
                        (unsigned long)(handle->pid), localbuf );
        LocalFree( localbuf );
    }

    OPAL_THREAD_UNLOCK(&mutex);

    return OPAL_SUCCESS;
}
예제 #22
0
INT_PTR
PluginHangUIChild::HangUIDlgProc(HWND aDlgHandle, UINT aMsgCode, WPARAM aWParam,
                                 LPARAM aLParam)
{
  mDlgHandle = aDlgHandle;
  switch (aMsgCode) {
    case WM_INITDIALOG: {
      // Register a wait on the Firefox process so that we will be informed
      // if it dies while the dialog is showing
      RegisterWaitForSingleObject(&mRegWaitProcess,
                                  mParentProcess,
                                  &SOnParentProcessExit,
                                  this,
                                  INFINITE,
                                  WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE);
      SetWindowText(aDlgHandle, mWindowTitle);
      SetDlgItemText(aDlgHandle, IDC_MSG, mMessageText);
      SetDlgItemText(aDlgHandle, IDC_NOFUTURE, mNoFutureText);
      SetDlgItemText(aDlgHandle, IDC_CONTINUE, mWaitBtnText);
      SetDlgItemText(aDlgHandle, IDC_STOP, mKillBtnText);
      ResizeButtons();
      HANDLE icon = LoadImage(NULL, IDI_QUESTION, IMAGE_ICON, 0, 0,
                              LR_DEFAULTSIZE | LR_SHARED);
      if (icon) {
        SendDlgItemMessage(aDlgHandle, IDC_DLGICON, STM_SETICON, (WPARAM)icon, 0);
      }
      EnableWindow(mParentWindow, FALSE);
      return TRUE;
    }
    case WM_CLOSE: {
      mResponseBits |= HANGUI_USER_RESPONSE_CANCEL;
      EndDialog(aDlgHandle, 0);
      SetWindowLongPtr(aDlgHandle, DWLP_MSGRESULT, 0);
      return TRUE;
    }
    case WM_COMMAND: {
      switch (LOWORD(aWParam)) {
        case IDC_CONTINUE:
          if (HIWORD(aWParam) == BN_CLICKED) {
            mResponseBits |= HANGUI_USER_RESPONSE_CONTINUE;
            EndDialog(aDlgHandle, 1);
            SetWindowLongPtr(aDlgHandle, DWLP_MSGRESULT, 0);
            return TRUE;
          }
          break;
        case IDC_STOP:
          if (HIWORD(aWParam) == BN_CLICKED) {
            mResponseBits |= HANGUI_USER_RESPONSE_STOP;
            EndDialog(aDlgHandle, 1);
            SetWindowLongPtr(aDlgHandle, DWLP_MSGRESULT, 0);
            return TRUE;
          }
          break;
        case IDC_NOFUTURE:
          if (HIWORD(aWParam) == BN_CLICKED) {
            if (Button_GetCheck(GetDlgItem(aDlgHandle,
                                           IDC_NOFUTURE)) == BST_CHECKED) {
              mResponseBits |= HANGUI_USER_RESPONSE_DONT_SHOW_AGAIN;
            } else {
              mResponseBits &=
                ~static_cast<DWORD>(HANGUI_USER_RESPONSE_DONT_SHOW_AGAIN);
            }
            SetWindowLongPtr(aDlgHandle, DWLP_MSGRESULT, 0);
            return TRUE;
          }
          break;
        default:
          break;
      }
      break;
    }
    case WM_DESTROY: {
      EnableWindow(mParentWindow, TRUE);
      break;
    }
    default:
      break;
  }
  return FALSE;
}
예제 #23
0
파일: process.c 프로젝트: JarshChen/jxcore
int uv_spawn_jx(uv_loop_t* loop, uv_process_t* process,
                uv_process_options_t* options) {
#ifdef WINONECORE
  error_console("Error: WindowsOneCore does not support spawning a process.\n");
  return -1; // not supported
#else
  int i;
  uv_err_t err = uv_ok_;
  WCHAR* path = NULL;
  BOOL result;
  WCHAR* application_path = NULL, *application = NULL, *arguments = NULL,
         *env = NULL, *cwd = NULL;
  STARTUPINFOW startup;
  PROCESS_INFORMATION info;
  DWORD process_flags;

  if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) {
    uv__set_artificial_error(loop, UV_ENOTSUP);
    return -1;
  }

  if (options->file == NULL || options->args == NULL) {
    uv__set_artificial_error(loop, UV_EINVAL);
    return -1;
  }

  assert(options->file != NULL);
  assert(!(options->flags &
           ~(UV_PROCESS_DETACHED | UV_PROCESS_SETGID | UV_PROCESS_SETUID |
             UV_PROCESS_WINDOWS_HIDE | UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));

  uv_process_init(loop, process);
  process->exit_cb = options->exit_cb;

  err = uv_utf8_to_utf16_alloc(options->file, &application);
  if (err.code != UV_OK) goto done;

  err = make_program_args(
      options->args, options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
      &arguments);
  if (err.code != UV_OK) goto done;

  if (options->env) {
    err = make_program_env(options->env, &env);
    if (err.code != UV_OK) goto done;
  }

  if (options->cwd) {
    /* Explicit cwd */
    err = uv_utf8_to_utf16_alloc(options->cwd, &cwd);
    if (err.code != UV_OK) goto done;

  } else {
    /* Inherit cwd */
    DWORD cwd_len, r;

    cwd_len = GetCurrentDirectoryW(0, NULL);
    if (!cwd_len) {
      err = uv__new_sys_error(GetLastError());
      goto done;
    }

    cwd = (WCHAR*)malloc(cwd_len * sizeof(WCHAR));
    if (cwd == NULL) {
      err = uv__new_artificial_error(UV_ENOMEM);
      goto done;
    }

    r = GetCurrentDirectoryW(cwd_len, cwd);
    if (r == 0 || r >= cwd_len) {
      err = uv__new_sys_error(GetLastError());
      goto done;
    }
  }

  /* Get PATH environment variable. */
  {
    DWORD path_len, r;

    path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
    if (path_len == 0) {
      err = uv__new_sys_error(GetLastError());
      goto done;
    }

    path = (WCHAR*)malloc(path_len * sizeof(WCHAR));
    if (path == NULL) {
      err = uv__new_artificial_error(UV_ENOMEM);
      goto done;
    }

    r = GetEnvironmentVariableW(L"PATH", path, path_len);
    if (r == 0 || r >= path_len) {
      err = uv__new_sys_error(GetLastError());
      goto done;
    }
  }

  application_path = search_path(application, cwd, path);
  if (application_path == NULL) {
    /* Not found. */
    err = uv__new_artificial_error(UV_ENOENT);
    goto done;
  }

  err = uv__stdio_create(loop, options, &process->child_stdio_buffer);
  if (err.code != UV_OK) goto done;

  startup.cb = sizeof(startup);
  startup.lpReserved = NULL;
  startup.lpDesktop = NULL;
  startup.lpTitle = NULL;
  startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;

  startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer);
  startup.lpReserved2 = (BYTE*)process->child_stdio_buffer;

  startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0);
  startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1);
  startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2);

  if (options->flags & UV_PROCESS_WINDOWS_HIDE) {
    /* Use SW_HIDE to avoid any potential process window. */
    startup.wShowWindow = SW_HIDE;
  } else {
    startup.wShowWindow = SW_SHOWDEFAULT;
  }

  process_flags = CREATE_UNICODE_ENVIRONMENT;

  if (options->flags & UV_PROCESS_DETACHED) {
    /* Note that we're not setting the CREATE_BREAKAWAY_FROM_JOB flag. That
     * means that libuv might not let you create a fully deamonized process
     * when run under job control. However the type of job control that libuv
     * itself creates doesn't trickle down to subprocesses so they can still
     * daemonize.
     *
     * A reason to not do this is that CREATE_BREAKAWAY_FROM_JOB makes the
     * CreateProcess call fail if we're under job control that doesn't allow
     * breakaway.
     */
    process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
  }

  if (CreateProcessW(application_path, arguments, NULL, NULL, 1, process_flags,
                     env, cwd, &startup, &info)) {
    /* Spawn succeeded */
    process->process_handle = info.hProcess;
    process->pid = info.dwProcessId;

    /* If the process isn't spawned as detached, assign to the global job */
    /* object so windows will kill it when the parent process dies. */
    if (!(options->flags & UV_PROCESS_DETACHED)) {
      uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);

      if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) {
        /* AssignProcessToJobObject might fail if this process is under job
         * control and the job doesn't have the
         * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version
         * that doesn't support nested jobs.
         *
         * When that happens we just swallow the error and continue without
         * establishing a kill-child-on-parent-exit relationship, otherwise
         * there would be no way for libuv applications run under job control
         * to spawn processes at all.
         */
        DWORD err = GetLastError();
        if (err != ERROR_ACCESS_DENIED)
          uv_fatal_error(err, "AssignProcessToJobObject");
      }
    }

    /* Set IPC pid to all IPC pipes. */
    for (i = 0; i < options->stdio_count; i++) {
      const uv_stdio_container_t* fdopt = &options->stdio[i];
      if (fdopt->flags & UV_CREATE_PIPE &&
          fdopt->data.stream->type == UV_NAMED_PIPE &&
          ((uv_pipe_t*)fdopt->data.stream)->ipc) {
        ((uv_pipe_t*)fdopt->data.stream)->ipc_pid = info.dwProcessId;
      }
    }

    /* Setup notifications for when the child process exits. */
    result = RegisterWaitForSingleObject(
        &process->wait_handle, process->process_handle, exit_wait_callback,
        (void*)process, INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
    if (!result) {
      uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
    }

    CloseHandle(info.hThread);

  } else {
    /* CreateProcessW failed. */
    err = uv__new_sys_error(GetLastError());
  }

done:
  JX_FREE(process, application);
  JX_FREE(process, application_path);
  JX_FREE(process, arguments);
  JX_FREE(process, cwd);
  JX_FREE(process, env);
  JX_FREE(process, path);

  process->spawn_error = err;

  if (process->child_stdio_buffer != NULL) {
    /* Clean up child stdio handles. */
    uv__stdio_destroy(process->child_stdio_buffer);
    process->child_stdio_buffer = NULL;
  }

  /* Make the handle active. It will remain active until the exit callback */
  /* is made or the handle is closed, whichever happens first. */
  uv__handle_start(process);

  /* If an error happened, queue the exit req. */
  if (err.code != UV_OK) {
    process->exit_cb_pending = 1;
    uv_insert_pending_req(loop, (uv_req_t*)&process->exit_req);
  }

  return 0;
#endif
}
예제 #24
0
static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
    uv_pipe_t* handle, uv_buf_t bufs[], int bufcnt,
    uv_stream_t* send_handle, uv_write_cb cb) {
  int result;
  uv_tcp_t* tcp_send_handle;
  uv_write_t* ipc_header_req;
  uv_ipc_frame_uv_stream ipc_frame;

  if (bufcnt != 1 && (bufcnt != 0 || !send_handle)) {
    uv__set_artificial_error(loop, UV_ENOTSUP);
    return -1;
  }

  /* Only TCP handles are supported for sharing. */
  if (send_handle && ((send_handle->type != UV_TCP) ||
      (!(send_handle->flags & UV_HANDLE_BOUND) &&
       !(send_handle->flags & UV_HANDLE_CONNECTION)))) {
    uv__set_artificial_error(loop, UV_ENOTSUP);
    return -1;
  }

  assert(handle->handle != INVALID_HANDLE_VALUE);

  uv_req_init(loop, (uv_req_t*) req);
  req->type = UV_WRITE;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;
  req->ipc_header = 0;
  req->event_handle = NULL;
  req->wait_handle = INVALID_HANDLE_VALUE;
  memset(&req->overlapped, 0, sizeof(req->overlapped));

  if (handle->ipc) {
    assert(!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
    ipc_frame.header.flags = 0;

    /* Use the IPC framing protocol. */
    if (send_handle) {
      tcp_send_handle = (uv_tcp_t*)send_handle;

      if (uv_tcp_duplicate_socket(tcp_send_handle, handle->ipc_pid,
          &ipc_frame.socket_info)) {
        return -1;
      }
      ipc_frame.header.flags |= UV_IPC_TCP_SERVER;

      if (tcp_send_handle->flags & UV_HANDLE_CONNECTION) {
        ipc_frame.header.flags |= UV_IPC_TCP_CONNECTION;
      }
    }

    if (bufcnt == 1) {
      ipc_frame.header.flags |= UV_IPC_RAW_DATA;
      ipc_frame.header.raw_data_length = bufs[0].len;
    }

    /*
     * Use the provided req if we're only doing a single write.
     * If we're doing multiple writes, use ipc_header_write_req to do
     * the first write, and then use the provided req for the second write.
     */
    if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
      ipc_header_req = req;
    } else {
      /*
       * Try to use the preallocated write req if it's available.
       * Otherwise allocate a new one.
       */
      if (handle->ipc_header_write_req.type != UV_WRITE) {
        ipc_header_req = (uv_write_t*)&handle->ipc_header_write_req;
      } else {
        ipc_header_req = (uv_write_t*)malloc(sizeof(uv_write_t));
        if (!ipc_header_req) {
          uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
        }
      }

      uv_req_init(loop, (uv_req_t*) ipc_header_req);
      ipc_header_req->type = UV_WRITE;
      ipc_header_req->handle = (uv_stream_t*) handle;
      ipc_header_req->cb = NULL;
      ipc_header_req->ipc_header = 1;
    }

    /* Write the header or the whole frame. */
    memset(&ipc_header_req->overlapped, 0, sizeof(ipc_header_req->overlapped));

    result = WriteFile(handle->handle,
                        &ipc_frame,
                        ipc_frame.header.flags & UV_IPC_TCP_SERVER ?
                          sizeof(ipc_frame) : sizeof(ipc_frame.header),
                        NULL,
                        &ipc_header_req->overlapped);
    if (!result && GetLastError() != ERROR_IO_PENDING) {
      uv__set_sys_error(loop, GetLastError());
      return -1;
    }

    if (result) {
      /* Request completed immediately. */
      ipc_header_req->queued_bytes = 0;
    } else {
      /* Request queued by the kernel. */
      ipc_header_req->queued_bytes = ipc_frame.header.flags & UV_IPC_TCP_SERVER ?
        sizeof(ipc_frame) : sizeof(ipc_frame.header);
      handle->write_queue_size += ipc_header_req->queued_bytes;
    }

    REGISTER_HANDLE_REQ(loop, handle, ipc_header_req);
    handle->reqs_pending++;
    handle->write_reqs_pending++;

    /* If we don't have any raw data to write - we're done. */
    if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
      return 0;
    }
  }

  if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
    req->write_buffer = bufs[0];
    uv_insert_non_overlapped_write_req(handle, req);
    if (handle->write_reqs_pending == 0) {
      uv_queue_non_overlapped_write(handle);
    }

    /* Request queued by the kernel. */
    req->queued_bytes = uv_count_bufs(bufs, bufcnt);
    handle->write_queue_size += req->queued_bytes;
  } else {
    result = WriteFile(handle->handle,
                       bufs[0].base,
                       bufs[0].len,
                       NULL,
                       &req->overlapped);

    if (!result && GetLastError() != ERROR_IO_PENDING) {
      uv__set_sys_error(loop, GetLastError());
      return -1;
    }

    if (result) {
      /* Request completed immediately. */
      req->queued_bytes = 0;
    } else {
      /* Request queued by the kernel. */
      req->queued_bytes = uv_count_bufs(bufs, bufcnt);
      handle->write_queue_size += req->queued_bytes;
    }

    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
      req->event_handle = CreateEvent(NULL, 0, 0, NULL);
      if (!req->event_handle) {
        uv_fatal_error(GetLastError(), "CreateEvent");
      }
      if (!RegisterWaitForSingleObject(&req->wait_handle,
          req->overlapped.hEvent, post_completion_write_wait, (void*) req,
          INFINITE, WT_EXECUTEINWAITTHREAD)) {
        uv__set_sys_error(loop, GetLastError());
        return -1;
      }
    }
  }

  REGISTER_HANDLE_REQ(loop, handle, req);
  handle->reqs_pending++;
  handle->write_reqs_pending++;

  return 0;
}
예제 #25
0
TProcess startSubProcess(void* self, int argc, char* argv[])
{
    IProcessManager _    = (IProcessManager)self;
    IErrorLogger    elog = _->errorLogger;

    STARTUPINFO          si;
    PROCESS_INFORMATION  pi;
    SECURITY_ATTRIBUTES  sa;
    BackendParams		 paramSm;
    char		         paramSmStr[32];
    char                 commandLine[MAX_PATH * 2];
    int                  cmdCharCount;
    HANDLE               paramMap;
    DeadChildInfo        childInfo;
    HANDLE               tokenHandle = NULL;

    int                  i, j;

    ASSERT(elog, argv != NULL, -1);
    ASSERT(elog, argv[0] != NULL, -1);
    ASSERT(elog, argv[1] != NULL, -1);
    ASSERT(elog, argv[2] == NULL, -1);

    /* Set up shared memory for parameter passing */
    ZeroMemory(&sa, sizeof(sa));
    sa.nLength        = sizeof(sa);
    sa.bInheritHandle = TRUE;

    if (!OpenProcessToken(
                GetCurrentProcess(),
                TOKEN_ALL_ACCESS,
                &tokenHandle))
    {
        elog->log(LOG_ERROR,
                  ERROR_CODE_OPEN_PROCESS_TOKEN,
                  "could not open process token: error code %lu",
                  GetLastError());

        return -1;
    }

    if (!SetPrivilege(
                _,
                tokenHandle,
                SE_CREATE_GLOBAL_NAME,
                True))
    {
        elog->log(LOG_ERROR,
                  ERROR_CODE_SET_PRIVILEDGE_FAILED,
                  "could not open process token: error code %lu",
                  GetLastError());

        return -1;
    }

    /* If the first parameter is INVALID_HANDLE_VALUE,
     * the calling process must also specify a size
     * for the file mapping object. In this scenario,
     * CreateFileMapping creates a file mapping object
     * of a specified size that is backed by the system paging file
     * instead of by a file in the file system.
     */
    paramMap = CreateFileMapping(INVALID_HANDLE_VALUE,
                                 &sa,
                                 PAGE_READWRITE,
                                 0,
                                 sizeof(SBackendParams),
                                 sharedMemParamsName);

    if (paramMap == NULL || paramMap == INVALID_HANDLE_VALUE)
    {
        int error = GetLastError();

        elog->log(LOG_ERROR,
                  ERROR_CODE_CREATE_FILE_MAP_FAILED,
                  "could not create file mapping: error code %lu",
                  error);

        return -1;
    }

    sharedMemID       = paramMap;
    sharedMemSegmSize = sizeof(SBackendParams);

    /* Maps a view of a file mapping into the address space of a calling process. */
    paramSm = MapViewOfFile(paramMap, FILE_MAP_WRITE, 0, 0, sizeof(SBackendParams));
    if (!paramSm)
    {
        elog->log(LOG_ERROR,
                  ERROR_CODE_MAP_MEMORY_TO_FILE,
                  "could not map backend parameter memory: error code %lu",
                  GetLastError());

        CloseHandle(paramSm);
        return -1;
    }

    sprintf(paramSmStr, "%lu", (DWORD)paramSm);
    argv[2] = paramSmStr;

    cmdCharCount = sizeof(commandLine);
    commandLine[cmdCharCount - 1] = '\0';
    commandLine[cmdCharCount - 2] = '\0';

    snprintf(commandLine, cmdCharCount - 1, "\"%s\"", ExecPath);

    i = 0;
    while (argv[++i] != NULL)
    {
        j = strlen(commandLine);
        snprintf(commandLine + j, sizeof(commandLine) - 1 - j, " \"%s\"", argv[i]);
    }

    if (commandLine[sizeof(commandLine) - 2] != '\0')
    {
        elog->log(LOG_ERROR,
                  ERROR_CODE_PROC_CMD_LINE_TO_LONG,
                  "subprocess command line too long");
        return -1;
    }

    memset(&pi, 0, sizeof(pi));
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);

    /* Create the subprocess in a suspended state.
     * This will be resumed later,
     * once we have written out the parameter file.
     * If this parameter TRUE, each inheritable handle
     * in the calling process is inherited by the new process.
     * If the parameter is FALSE, the handles are not inherited.
     * Note that inherited handles have the same value
     * and access rights as the original handles.
     */
    if (!CreateProcess(NULL, commandLine, NULL,
                       NULL, TRUE, CREATE_SUSPENDED,
                       NULL, NULL, &si, &pi))
    {
        elog->log(LOG_ERROR,
                  ERROR_CODE_CREATE_PROCESS_FAILED,
                  "CreateProcess call failed: (error code %lu)",
                  GetLastError());

        return -1;
    }

    if (!fillBackandParams(
                _,
                paramSm,
                pi.hProcess,
                pi.dwProcessId))
    {
        /* Delete the process */
        if (!TerminateProcess(pi.hProcess, 255))
            elog->log(LOG_ERROR,
                      ERROR_CODE_TERMINATE_PROCESS_FAILED,
                      "Terminate process failed: (error code %lu)",
                      GetLastError());

        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return -1;
    }

    /* Drop the handler to the shared memory.
     * Now the shared memory has already been passed
     * along to the child process.
     */
    if (!UnmapViewOfFile(paramSm))
        elog->log(LOG_ERROR,
                  ERROR_CODE_UNMAP_VIEW_OF_FILE,
                  "could not unmap view of backend parameter file: error code %lu",
                  GetLastError());

    if (!CloseHandle(paramMap))
        elog->log(LOG_ERROR,
                  ERROR_CODE_CLOSE_HANDLER_FAILED,
                  "could not close handle to backend parameter file: error code %lu",
                  GetLastError());

    /* All variables are written out, so we can resume the thread */
    if (ResumeThread(pi.hThread) == -1)
    {
        /* Delete the process */
        if (!TerminateProcess(pi.hProcess, 255))
        {
            elog->log(LOG_ERROR,
                      ERROR_CODE_TERMINATE_PROCESS_FAILED,
                      "Terminate process failed: (error code %lu)",
                      GetLastError());

            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            return -1;
        }

        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);

        elog->log(LOG_ERROR,
                  ERROR_CODE_RESUME_THREAD_FAILED,
                  "Terminate process failed: (error code %lu)",
                  GetLastError());
        return -1;
    }

    childInfo = malloc(sizeof(SDeadChildInfo));
    if (childInfo == NULL)
        elog->log(LOG_FATAL,
                  ERROR_CODE_OUT_OF_MEMORY,
                  "out of memory");

    childInfo->procHandle = pi.hProcess;
    childInfo->procId     = pi.dwProcessId;

    /* Directs a wait thread in the thread pool to wait on the object.
     * The wait thread queues the specified callback function to the thread pool
     * when one of the following occurs:
     *  - The specified object is in the signaled state.
     *  - The time-out interval elapses.
     * When a process terminates, the state of the process object
     * becomes signaled, releasing any threads
     * that had been waiting for the process to terminate.
     */
    if (!RegisterWaitForSingleObject(
                &childInfo->waitHandle,
                pi.hProcess,
                deadChildProcCallBack,
                childInfo,
                INFINITE,
                WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD))
        elog->log(LOG_ERROR,
                  ERROR_CODE_REGISTER_WAIT_HANDLER_FAILED,
                  "Could not register process for wait: error code %lu",
                  GetLastError());

    /* Don't close pi.hProcess here -
     * the wait thread needs access to it.
     */
    CloseHandle(pi.hThread);

    return pi.hProcess;
}
예제 #26
0
파일: tcp.c 프로젝트: AlexandreXavier/node
static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
  uv_loop_t* loop = handle->loop;
  BOOL success;
  DWORD bytes;
  SOCKET accept_socket;
  short family;

  assert(handle->flags & UV_HANDLE_LISTENING);
  assert(req->accept_socket == INVALID_SOCKET);

  /* choose family and extension function */
  if (handle->flags & UV_HANDLE_IPV6) {
    family = AF_INET6;
  } else {
    family = AF_INET;
  }

  /* Open a socket for the accepted connection. */
  accept_socket = socket(family, SOCK_STREAM, 0);
  if (accept_socket == INVALID_SOCKET) {
    SET_REQ_ERROR(req, WSAGetLastError());
    uv_insert_pending_req(loop, (uv_req_t*)req);
    handle->reqs_pending++;
    return;
  }

  /* Prepare the overlapped structure. */
  memset(&(req->overlapped), 0, sizeof(req->overlapped));
  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
    req->overlapped.hEvent = (HANDLE) ((DWORD) req->event_handle | 1);
  }

  success = handle->func_acceptex(handle->socket,
                                  accept_socket,
                                  (void*)req->accept_buffer,
                                  0,
                                  sizeof(struct sockaddr_storage),
                                  sizeof(struct sockaddr_storage),
                                  &bytes,
                                  &req->overlapped);

  if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
    /* Process the req without IOCP. */
    req->accept_socket = accept_socket;
    handle->reqs_pending++;
    uv_insert_pending_req(loop, (uv_req_t*)req);
  } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
    /* The req will be processed with IOCP. */
    req->accept_socket = accept_socket;
    handle->reqs_pending++;
    if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
        req->wait_handle == INVALID_HANDLE_VALUE &&
        !RegisterWaitForSingleObject(&req->wait_handle,
          req->overlapped.hEvent, post_completion, (void*) req,
          INFINITE, WT_EXECUTEINWAITTHREAD)) {
      SET_REQ_ERROR(req, GetLastError());
      uv_insert_pending_req(loop, (uv_req_t*)req);
      handle->reqs_pending++;
      return;
    }
  } else {
    /* Make this req pending reporting an error. */
    SET_REQ_ERROR(req, WSAGetLastError());
    uv_insert_pending_req(loop, (uv_req_t*)req);
    handle->reqs_pending++;
    /* Destroy the preallocated client socket. */
    closesocket(accept_socket);
    /* Destroy the event handle */
    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
      CloseHandle(req->overlapped.hEvent);
      req->event_handle = NULL;
    }
  }
}
예제 #27
0
static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
  uv_read_t* req;
  uv_buf_t buf;
  int result;
  DWORD bytes, flags;

  assert(handle->flags & UV_HANDLE_READING);
  assert(!(handle->flags & UV_HANDLE_READ_PENDING));

  req = &handle->read_req;
  memset(&req->overlapped, 0, sizeof(req->overlapped));

  /*
   * Preallocate a read buffer if the number of active streams is below
   * the threshold.
  */
  if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) {
    handle->flags &= ~UV_HANDLE_ZERO_READ;
    handle->read_buffer = handle->alloc_cb((uv_handle_t*) handle, 65536);
    assert(handle->read_buffer.len > 0);
    buf = handle->read_buffer;
  } else {
    handle->flags |= UV_HANDLE_ZERO_READ;
    buf.base = (char*) &uv_zero_;
    buf.len = 0;
  }

  /* Prepare the overlapped structure. */
  memset(&(req->overlapped), 0, sizeof(req->overlapped));
  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
    assert(req->event_handle);
    req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
  }

  flags = 0;
  result = WSARecv(handle->socket,
                   (WSABUF*)&buf,
                   1,
                   &bytes,
                   &flags,
                   &req->overlapped,
                   NULL);

  if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
    /* Process the req without IOCP. */
    handle->flags |= UV_HANDLE_READ_PENDING;
    req->overlapped.InternalHigh = bytes;
    handle->reqs_pending++;
    uv_insert_pending_req(loop, (uv_req_t*)req);
  } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
    /* The req will be processed with IOCP. */
    handle->flags |= UV_HANDLE_READ_PENDING;
    handle->reqs_pending++;
    if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
        req->wait_handle == INVALID_HANDLE_VALUE &&
        !RegisterWaitForSingleObject(&req->wait_handle,
          req->event_handle, post_completion, (void*) req,
          INFINITE, WT_EXECUTEINWAITTHREAD)) {
      SET_REQ_ERROR(req, GetLastError());
      uv_insert_pending_req(loop, (uv_req_t*)req);
    }
  } else {
    /* Make this req pending reporting an error. */
    SET_REQ_ERROR(req, WSAGetLastError());
    uv_insert_pending_req(loop, (uv_req_t*)req);
    handle->reqs_pending++;
  }
}
예제 #28
0
파일: svchost.c 프로젝트: hoangduit/reactos
DWORD
WINAPI
SvcRegisterStopCallback (
    _In_ PHANDLE phNewWaitObject,
    _In_ LPCWSTR ServiceName,
    _In_ HANDLE hObject,
    _In_ PSVCHOST_STOP_CALLBACK pfnStopCallback,
    _In_ PVOID pContext,
    _In_ ULONG dwFlags
    )
{
    ULONG i;
    PSVCHOST_CALLBACK_CONTEXT pSvcsStopCbContext = NULL;
    PSVCHOST_SERVICE pService = NULL;
    DWORD dwError = ERROR_SUCCESS;

    /* All parameters must be present */
    if ((phNewWaitObject == NULL) ||
        (ServiceName == NULL) ||
        (hObject == NULL) ||
        (pfnStopCallback == NULL))
    {
        /* Fail otherwise */
        return ERROR_INVALID_PARAMETER;
    }

    /* Don't allow new DLLs while we send notifications */
    EnterCriticalSection(&ListLock);

    /* Scan all registered services */
    for (i = 0; i < ServiceCount; i++)
    {
        /* Search for the service entry matching this service name */
        if (lstrcmpiW(ServiceName, ServiceArray[i].pszServiceName) == 0)
        {
            /* Found it */
            pService = &ServiceArray[i];
            break;
        }
    }

    /* Do we have a service? Does it already have a callback? */
    if ((pService == NULL) || (pService->pfnStopCallback != NULL))
    {
        /* Affirmative, nothing for us to do */
        dwError = ERROR_INVALID_DATA;
        DBG_ERR("Service %ws missing or already registered for callback, "
                "status %d\n",
                ServiceName,
                dwError);
        goto Quickie;
    }

    /* Allocate our internal context */
    pSvcsStopCbContext = MemAlloc(HEAP_ZERO_MEMORY, sizeof(*pSvcsStopCbContext));
    if (pSvcsStopCbContext == NULL)
    {
        /* We failed, bail out */
        dwError = ERROR_NOT_ENOUGH_MEMORY;
        DBG_ERR("MemAlloc for context block for service %ws failed, status "
                "%d\n",
                ServiceName,
                dwError);
        goto Quickie;
    }

    /* Setup the context and register for the wait */
    pSvcsStopCbContext->pContext = pContext;
    pSvcsStopCbContext->pService = pService;
    if (RegisterWaitForSingleObject(phNewWaitObject,
                                    hObject,
                                    SvchostStopCallback,
                                    pSvcsStopCbContext,
                                    INFINITE,
                                    dwFlags))
    {
        /* We now have an active thread associated with this wait */
        pService->cServiceActiveThreadCount++;
        pService->pfnStopCallback = pfnStopCallback;
        DBG_TRACE("Registered stop callback for service %ws, active threads %d\n",
                  ServiceName,
                  pService->cServiceActiveThreadCount);
    }
    else
    {
        /* Registration failed, bail out */
        dwError = GetLastError();
        DBG_ERR("Registration for stop callback for service %ws failed, "
                "status %d\n",
                ServiceName,
                dwError);
    }

Quickie:
    /* Drop the lock, and free the context if we failed */
    LeaveCriticalSection(&ListLock);
    if (dwError != ERROR_SUCCESS) MemFree(pSvcsStopCbContext);
    return dwError;
}
예제 #29
0
파일: process.c 프로젝트: Ankso/node
int uv_spawn(uv_loop_t* loop, uv_process_t* process,
    uv_process_options_t options) {
  int i;
  uv_err_t err = uv_ok_;
  WCHAR* path = NULL;
  BOOL result;
  WCHAR* application_path = NULL, *application = NULL, *arguments = NULL,
           *env = NULL, *cwd = NULL;
  STARTUPINFOW startup;
  PROCESS_INFORMATION info;
  DWORD process_flags;

  if (options.flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) {
    uv__set_artificial_error(loop, UV_ENOTSUP);
    return -1;
  }

  if (options.file == NULL ||
      options.args == NULL) {
    uv__set_artificial_error(loop, UV_EINVAL);
    return -1;
  }

  assert(options.file != NULL);
  assert(!(options.flags & ~(UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
                             UV_PROCESS_DETACHED |
                             UV_PROCESS_SETGID |
                             UV_PROCESS_SETUID)));

  uv_process_init(loop, process);
  process->exit_cb = options.exit_cb;

  err = uv_utf8_to_utf16_alloc(options.file, &application);
  if (err.code != UV_OK)
    goto done;

  err = make_program_args(options.args,
                          options.flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
                          &arguments);
  if (err.code != UV_OK)
    goto done;

  if (options.cwd) {
    /* Explicit cwd */
    err = uv_utf8_to_utf16_alloc(options.cwd, &cwd);
    if (err.code != UV_OK)
      goto done;

  } else {
    /* Inherit cwd */
    DWORD cwd_len, r;

    cwd_len = GetCurrentDirectoryW(0, NULL);
    if (!cwd_len) {
      err = uv__new_sys_error(GetLastError());
      goto done;
    }

    cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR));
    if (cwd == NULL) {
      err = uv__new_artificial_error(UV_ENOMEM);
      goto done;
    }

    r = GetCurrentDirectoryW(cwd_len, cwd);
    if (r == 0 || r >= cwd_len) {
      err = uv__new_sys_error(GetLastError());
      goto done;
    }
  }

   /* Get PATH environment variable. */
  {
    DWORD path_len, r;

    path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
    if (path_len == 0) {
      err = uv__new_sys_error(GetLastError());
      goto done;
    }


    path = (WCHAR*) malloc(path_len * sizeof(WCHAR));
    if (path == NULL) {
      err = uv__new_artificial_error(UV_ENOMEM);
      goto done;
    }

    r = GetEnvironmentVariableW(L"PATH", path, path_len);
    if (r == 0 || r >= path_len) {
      err = uv__new_sys_error(GetLastError());
      goto done;
    }
  }

  application_path = search_path(application,
                                 cwd,
                                 path);
  if (application_path == NULL) {
    /* Not found. */
    err = uv__new_artificial_error(UV_ENOENT);
    goto done;
  }


  err = uv__stdio_create(loop, &options, &process->child_stdio_buffer);
  if (err.code != UV_OK)
    goto done;

  startup.cb = sizeof(startup);
  startup.lpReserved = NULL;
  startup.lpDesktop = NULL;
  startup.lpTitle = NULL;
  startup.dwFlags = STARTF_USESTDHANDLES;
  startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer);
  startup.lpReserved2 = (BYTE*) process->child_stdio_buffer;
  startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0);
  startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1);
  startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2);

  process_flags = CREATE_UNICODE_ENVIRONMENT;
  if (options.flags & UV_PROCESS_DETACHED) {
    process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
  }

  if (CreateProcessW(application_path,
                     arguments,
                     NULL,
                     NULL,
                     1,
                     process_flags,
                     env,
                     cwd,
                     &startup,
                     &info)) {
    /* Spawn succeeded */
    process->process_handle = info.hProcess;
    process->pid = info.dwProcessId;

    /* Set IPC pid to all IPC pipes. */
    for (i = 0; i < options.stdio_count; i++) {
      const uv_stdio_container_t* fdopt = &options.stdio[i];
      if (fdopt->flags & UV_CREATE_PIPE &&
          fdopt->data.stream->type == UV_NAMED_PIPE &&
          ((uv_pipe_t*) fdopt->data.stream)->ipc) {
        ((uv_pipe_t*) fdopt->data.stream)->ipc_pid = info.dwProcessId;
      }
    }

    /* Setup notifications for when the child process exits. */
    result = RegisterWaitForSingleObject(&process->wait_handle,
        process->process_handle, exit_wait_callback, (void*)process, INFINITE,
        WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
    if (!result) {
      uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
    }

    CloseHandle(info.hThread);

  } else {
    /* CreateProcessW failed. */
    err = uv__new_sys_error(GetLastError());
  }

done:
  free(application);
  free(application_path);
  free(arguments);
  free(cwd);
  free(env);
  free(path);

  process->spawn_error = err;

  if (process->child_stdio_buffer != NULL) {
    /* Clean up child stdio handles. */
    uv__stdio_destroy(process->child_stdio_buffer);
    process->child_stdio_buffer = NULL;
  }

  /* Make the handle active. It will remain active until the exit callback */
  /* is made or the handle is closed, whichever happens first. */
  uv__handle_start(process);

  /* If an error happened, queue the exit req. */
  if (err.code != UV_OK) {
    process->exit_cb_pending = 1;
    uv_insert_pending_req(loop, (uv_req_t*) &process->exit_req);
  }

  return 0;
}
예제 #30
0
static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
  uv_read_t* req;
  int result;

  assert(handle->flags & UV_HANDLE_READING);
  assert(!(handle->flags & UV_HANDLE_READ_PENDING));

  assert(handle->handle != INVALID_HANDLE_VALUE);

  req = &handle->read_req;

  if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
    if (!QueueUserWorkItem(&uv_pipe_zero_readfile_thread_proc,
                           req,
                           WT_EXECUTELONGFUNCTION)) {
      /* Make this req pending reporting an error. */
      SET_REQ_ERROR(req, GetLastError());
      goto error;
    }
  } else {
    memset(&req->overlapped, 0, sizeof(req->overlapped));
    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
      req->overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
    }

    /* Do 0-read */
    result = ReadFile(handle->handle,
                      &uv_zero_,
                      0,
                      NULL,
                      &req->overlapped);

    if (!result && GetLastError() != ERROR_IO_PENDING) {
      /* Make this req pending reporting an error. */
      SET_REQ_ERROR(req, GetLastError());
      goto error;
    }

    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
      if (!req->event_handle) {
        req->event_handle = CreateEvent(NULL, 0, 0, NULL);
        if (!req->event_handle) {
          uv_fatal_error(GetLastError(), "CreateEvent");
        }
      }
      if (req->wait_handle == INVALID_HANDLE_VALUE) {
        if (!RegisterWaitForSingleObject(&req->wait_handle,
            req->overlapped.hEvent, post_completion_read_wait, (void*) req,
            INFINITE, WT_EXECUTEINWAITTHREAD)) {
          SET_REQ_ERROR(req, GetLastError());
          goto error;
        }
      }
    }
  }

  /* Start the eof timer if there is one */
  eof_timer_start(handle);
  handle->flags |= UV_HANDLE_READ_PENDING;
  handle->reqs_pending++;
  return;

error:
  uv_insert_pending_req(loop, (uv_req_t*)req);
  handle->flags |= UV_HANDLE_READ_PENDING;
  handle->reqs_pending++;
}