13 if (p_bytes == 0)
return;
18 SetLastError(NO_ERROR);
19 if (WriteFile(
m_handle, p_buffer, pfc::downcast_guarded<DWORD>(p_bytes), &bytesWritten, &ol)) {
21 if (bytesWritten != p_bytes)
throw exception_io();
26 const DWORD code = GetLastError();
30 SetLastError(NO_ERROR);
31 DWORD state =
myWait(_countof(handles), handles);
32 if (state == WAIT_OBJECT_0) {
34 WIN32_IO_OP( GetOverlappedResult(
m_handle,&ol,&bytesWritten,TRUE) );
39 if (bytesWritten != p_bytes)
throw exception_io();
47 uint8_t * ptr = (uint8_t*) p_buffer;
49 while(done < p_bytes) {
51 size_t delta =
readPass(ptr + done, p_bytes - done, abort);
52 if (delta == 0)
break;
58 if (p_bytes == 0)
return 0;
63 SetLastError(NO_ERROR);
64 if (ReadFile(
m_handle, p_buffer, pfc::downcast_guarded<DWORD>(p_bytes), &bytesDone, &ol)) {
70 const DWORD code = GetLastError();
72 case ERROR_HANDLE_EOF:
74 case ERROR_IO_PENDING:
82 SetLastError(NO_ERROR);
83 DWORD state =
myWait(_countof(handles), handles);
84 if (state == WAIT_OBJECT_0) {
85 SetLastError(NO_ERROR);
86 if (!GetOverlappedResult(
m_handle,&ol,&bytesDone,TRUE)) {
87 const DWORD code = GetLastError();
88 if (code == ERROR_HANDLE_EOF) bytesDone = 0;
104 DWORD state = MsgWaitForMultipleObjects(count, handles, FALSE,
m_timeOut, QS_ALLINPUT);
105 if (state == WAIT_OBJECT_0 + count) {
116 #if _WIN32_WINNT >= 0x600 124 while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
137 SubProcess(
const char * exePath, DWORD timeOutMS = 60*1000) : ExePath(exePath), hStdIn(), hStdOut(), hProcess(), ProcessMessages(false), TimeOutMS(timeOutMS) {
139 WIN32_OP( (ev =
CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL );
141 WIN32_OP( (ev =
CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL );
150 si.dwFlags = STARTF_USESTDHANDLES | STARTF_FORCEOFFFEEDBACK;
153 myCreatePipeOut(si.hStdInput, hStdIn);
154 myCreatePipeIn(hStdOut, si.hStdOutput);
155 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
157 PROCESS_INFORMATION pi = {};
163 hProcess = pi.hProcess; _Close(pi.hThread);
165 _Close(si.hStdInput);
166 _Close(si.hStdOutput);
169 _Close(si.hStdInput);
170 _Close(si.hStdOutput);
174 CloseHandle(hEventRead);
175 CloseHandle(hEventWrite);
179 return hProcess != NULL;
189 PipeIO writer(hStdIn, hEventWrite, ProcessMessages, TimeOutMS);
190 writer.
write(p_buffer, p_bytes, abort);
193 PipeIO reader(hStdOut, hEventRead, ProcessMessages, TimeOutMS);
194 return reader.
read(p_buffer, p_bytes, abort);
197 SetPriorityClass(hProcess, val);
204 _Close(hStdIn); _Close(hStdOut);
205 if (hProcess != NULL) {
210 TerminateProcess(hProcess, -1);
218 if (h != NULL) {CloseHandle(h); h = NULL;}
222 SECURITY_ATTRIBUTES Attributes = {
sizeof(SECURITY_ATTRIBUTES), 0,
true };
223 WIN32_OP( CreatePipe( &in, &out, &Attributes, 0 ) );
233 SECURITY_ATTRIBUTES Attributes = {
sizeof(SECURITY_ATTRIBUTES), 0,
true };
235 SetLastError(NO_ERROR);
236 HANDLE pipe = CreateNamedPipe(
238 FILE_FLAG_FIRST_PIPE_INSTANCE | PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
239 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
243 NMPWAIT_USE_DEFAULT_WAIT,&Attributes);
244 if (pipe == INVALID_HANDLE_VALUE)
throw exception_win32(GetLastError());
246 in = CreateFile(pipeName,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,&Attributes,OPEN_EXISTING,0,NULL);
247 DuplicateHandle ( GetCurrentProcess(), pipe, GetCurrentProcess(), &out, 0, FALSE, DUPLICATE_SAME_ACCESS );
252 SECURITY_ATTRIBUTES Attributes = {
sizeof(SECURITY_ATTRIBUTES), 0,
true };
254 SetLastError(NO_ERROR);
255 HANDLE pipe = CreateNamedPipe(
257 FILE_FLAG_FIRST_PIPE_INSTANCE | PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
258 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
262 NMPWAIT_USE_DEFAULT_WAIT,&Attributes);
263 if (pipe == INVALID_HANDLE_VALUE)
throw exception_win32(GetLastError());
265 out = CreateFile(pipeName,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,&Attributes,OPEN_EXISTING,0,NULL);
266 DuplicateHandle ( GetCurrentProcess(), pipe, GetCurrentProcess(), &in, 0, FALSE, DUPLICATE_SAME_ACCESS );
DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds)
void CleanUp(bool bDetach=false)
PFC_NORETURN void exception_io_from_win32(DWORD p_code)
size_t read(void *p_buffer, size_t p_bytes, abort_callback &abort)
void write(const void *p_buffer, size_t p_bytes, abort_callback &abort)
SubProcess(const char *exePath, DWORD timeOutMS=60 *1000)
void SetPriority(DWORD val)
PipeIO(HANDLE handle, HANDLE hEvent, bool processMessages, DWORD timeOut=INFINITE)
PFC_DECLARE_EXCEPTION(timeout, exception_io,"Timeout")
static void myCreatePipeIn(HANDLE &in, HANDLE &out)
typedef HANDLE(WINAPI *pPowerCreateRequest_t)(__in void *Context)
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
string8_fastalloc string_formatter
const bool m_processMessages
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName)
const pfc::string8 ExePath
static void _Close(HANDLE &h)
static void myCreatePipeOut(HANDLE &in, HANDLE &out)
static void ProcessPendingMessages()
size_t read(void *p_buffer, size_t p_bytes, abort_callback &abort)
void _cancel(OVERLAPPED &ol)
void write(const void *p_buffer, size_t p_bytes, abort_callback &abort)
size_t readPass(void *p_buffer, size_t p_bytes, abort_callback &abort)
DWORD myWait(DWORD count, const HANDLE *handles)
static pfc::string_formatter makePipeName()
static void myCreatePipe(HANDLE &in, HANDLE &out)