[+] NT: IProcess::AsLoopSource()
[*] NT: Bug fix: our side of the process streams were not marked as FILE_FLAG_OVERLAPPED [+] CreatePipeEx.NT.cpp
This commit is contained in:
parent
dfc21453ef
commit
0a38ffacfa
@ -84,13 +84,13 @@ namespace Aurora::Processes
|
||||
virtual bool Write(const Memory::MemoryViewStreamRead &source) = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns a asynchronous file stream transaction of pipe pair: stdout, stdin
|
||||
* @brief Returns an asynchronous file stream transaction of pipe pair: stdout, stdin
|
||||
* @return
|
||||
*/
|
||||
virtual AuSPtr<IO::FS::IAsyncTransaction> NewAsyncTransaction() = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns a asynchronous file stream transaction of pipe pair: stderr, INVALID
|
||||
* @brief Returns an asynchronous file stream transaction of pipe pair: stderr, INVALID
|
||||
* @return
|
||||
*/
|
||||
virtual AuSPtr<IO::FS::IAsyncTransaction> NewErrorStreamAsyncTransaction() = 0;
|
||||
|
122
Source/Processes/CreatePipeEx.NT.cpp
Normal file
122
Source/Processes/CreatePipeEx.NT.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/******************************************************************************\
|
||||
* This is a part of the Microsoft Source Code Samples.
|
||||
* Copyright 1995 - 1997 Microsoft Corporation.
|
||||
* All rights reserved.
|
||||
* This source code is only intended as a supplement to
|
||||
* Microsoft Development Tools and/or WinHelp documentation.
|
||||
* See these sources for detailed information regarding the
|
||||
* Microsoft samples programs.
|
||||
\******************************************************************************/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
|
||||
/*++
|
||||
Copyright (c) 1997 Microsoft Corporation
|
||||
Module Name:
|
||||
CreatePipeEx.NT.cpp
|
||||
Abstract:
|
||||
CreatePipe-like function that lets one or both handles be overlapped
|
||||
Author:
|
||||
Dave Hart Summer 1997
|
||||
Revision History:
|
||||
J Reece Wilson 2022: Updated default size to match Linux's 16 page assumption
|
||||
Renamed MyCreatePipeEx to CreatePipeEx
|
||||
Now using Au atomics
|
||||
Added second parameter check
|
||||
--*/
|
||||
|
||||
|
||||
static AuUInt32 gPipeSerialNumber;
|
||||
|
||||
BOOL
|
||||
APIENTRY
|
||||
CreatePipeEx(
|
||||
OUT LPHANDLE lpReadPipe,
|
||||
OUT LPHANDLE lpWritePipe,
|
||||
IN LPSECURITY_ATTRIBUTES lpPipeAttributes,
|
||||
IN DWORD nSize,
|
||||
DWORD dwReadMode,
|
||||
DWORD dwWriteMode
|
||||
)
|
||||
{
|
||||
HANDLE ReadPipeHandle, WritePipeHandle;
|
||||
DWORD dwError;
|
||||
char PipeNameBuffer[MAX_PATH];
|
||||
|
||||
//
|
||||
// Only one valid OpenMode flag - FILE_FLAG_OVERLAPPED
|
||||
//
|
||||
|
||||
if ((dwReadMode | dwWriteMode) & (~FILE_FLAG_OVERLAPPED))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Check output arguments are non-null
|
||||
//
|
||||
|
||||
if (!lpReadPipe || !lpWritePipe)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the default timeout to 120 seconds
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Set the default pipe size
|
||||
//
|
||||
|
||||
if (nSize == 0)
|
||||
{
|
||||
nSize = 16 * AuHwInfo::GetPageSize();
|
||||
}
|
||||
|
||||
sprintf(PipeNameBuffer,
|
||||
"\\\\.\\Pipe\\AuroraProcessCStandardStream.%08x.%08x",
|
||||
GetCurrentProcessId(),
|
||||
AuAtomicAdd(&gPipeSerialNumber, 1u)
|
||||
);
|
||||
|
||||
ReadPipeHandle = CreateNamedPipeA(
|
||||
PipeNameBuffer,
|
||||
PIPE_ACCESS_INBOUND | dwReadMode,
|
||||
PIPE_TYPE_BYTE | PIPE_WAIT,
|
||||
1, // Number of pipes
|
||||
nSize, // Out buffer size
|
||||
nSize, // In buffer size
|
||||
120 * 1000, // Timeout in ms
|
||||
lpPipeAttributes
|
||||
);
|
||||
|
||||
if (!ReadPipeHandle)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WritePipeHandle = CreateFileA(
|
||||
PipeNameBuffer,
|
||||
GENERIC_WRITE,
|
||||
0, // No sharing
|
||||
lpPipeAttributes,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | dwWriteMode,
|
||||
NULL // Template file
|
||||
);
|
||||
|
||||
if (INVALID_HANDLE_VALUE == WritePipeHandle)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
CloseHandle(ReadPipeHandle);
|
||||
SetLastError(dwError);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*lpReadPipe = ReadPipeHandle;
|
||||
*lpWritePipe = WritePipeHandle;
|
||||
return TRUE;
|
||||
}
|
45
Source/Processes/CreatePipeEx.NT.hpp
Normal file
45
Source/Processes/CreatePipeEx.NT.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
/*++
|
||||
Routine Description:
|
||||
The CreatePipeEx API is used to create an anonymous pipe I/O device.
|
||||
Unlike CreatePipe FILE_FLAG_OVERLAPPED may be specified for one or
|
||||
both handles.
|
||||
Two handles to the device are created. One handle is opened for
|
||||
reading and the other is opened for writing. These handles may be
|
||||
used in subsequent calls to ReadFile and WriteFile to transmit data
|
||||
through the pipe.
|
||||
Arguments:
|
||||
lpReadPipe - Returns a handle to the read side of the pipe. Data
|
||||
may be read from the pipe by specifying this handle value in a
|
||||
subsequent call to ReadFile.
|
||||
lpWritePipe - Returns a handle to the write side of the pipe. Data
|
||||
may be written to the pipe by specifying this handle value in a
|
||||
subsequent call to WriteFile.
|
||||
lpPipeAttributes - An optional parameter that may be used to specify
|
||||
the attributes of the new pipe. If the parameter is not
|
||||
specified, then the pipe is created without a security
|
||||
descriptor, and the resulting handles are not inherited on
|
||||
process creation. Otherwise, the optional security attributes
|
||||
are used on the pipe, and the inherit handles flag effects both
|
||||
pipe handles.
|
||||
nSize - Supplies the requested buffer size for the pipe. This is
|
||||
only a suggestion and is used by the operating system to
|
||||
calculate an appropriate buffering mechanism. A value of zero
|
||||
indicates that the system is to choose the default buffering
|
||||
scheme.
|
||||
Return Value:
|
||||
TRUE - The operation was successful.
|
||||
FALSE/NULL - The operation failed. Extended error status is available
|
||||
using GetLastError.
|
||||
--*/
|
||||
BOOL
|
||||
APIENTRY
|
||||
CreatePipeEx(
|
||||
OUT LPHANDLE lpReadPipe,
|
||||
OUT LPHANDLE lpWritePipe,
|
||||
IN LPSECURITY_ATTRIBUTES lpPipeAttributes,
|
||||
IN DWORD nSize,
|
||||
DWORD dwReadMode,
|
||||
DWORD dwWriteMode
|
||||
);
|
@ -18,9 +18,27 @@
|
||||
|
||||
#include <Source/IO/FS/FS.hpp>
|
||||
#include <Source/IO/FS/Async.NT.hpp>
|
||||
#include <Source/Loop/LSHandle.hpp>
|
||||
|
||||
#include "CreatePipeEx.NT.hpp"
|
||||
|
||||
namespace Aurora::Processes
|
||||
{
|
||||
struct ProcessAliveLoopSource : Loop::LSHandle
|
||||
{
|
||||
ProcessAliveLoopSource(HANDLE h);
|
||||
virtual AuLoop::ELoopSource GetType() override;
|
||||
};
|
||||
|
||||
ProcessAliveLoopSource::ProcessAliveLoopSource(HANDLE h) : LSHandle(AuReinterpretCast<AuUInt>(h))
|
||||
{
|
||||
}
|
||||
|
||||
AuLoop::ELoopSource ProcessAliveLoopSource::GetType()
|
||||
{
|
||||
return AuLoop::ELoopSource::eProcessDead;
|
||||
}
|
||||
|
||||
ProcessImpl::ProcessImpl(const StartupParmaters ¶ms) : startup_(params)
|
||||
{
|
||||
AuIOFS::NormalizePath(this->startup_.process, this->startup_.process);
|
||||
@ -116,6 +134,11 @@ namespace Aurora::Processes
|
||||
return this->thread_->AsWaitable();
|
||||
}
|
||||
|
||||
AuSPtr<Loop::ILoopSource> ProcessImpl::AsLoopSource()
|
||||
{
|
||||
return this->loopSource_;
|
||||
}
|
||||
|
||||
AuSInt ProcessImpl::GetExitCode()
|
||||
{
|
||||
return this->exitCode_;
|
||||
@ -217,7 +240,7 @@ namespace Aurora::Processes
|
||||
this->exitCode_ = 0x10110100;
|
||||
if (this->startup_.fwdOut)
|
||||
{
|
||||
if (!CreatePipe(&pipeStdOutRead_, &pipeStdOutWrite_, &saAttr, 0))
|
||||
if (!CreatePipeEx(&pipeStdOutRead_, &pipeStdOutWrite_, &saAttr, 0, FILE_FLAG_OVERLAPPED, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -230,7 +253,7 @@ namespace Aurora::Processes
|
||||
|
||||
if (this->startup_.fwdErr)
|
||||
{
|
||||
if (!CreatePipe(&pipeStdErrRead_, &pipeStdErrWrite_, &saAttr, 0))
|
||||
if (!CreatePipeEx(&pipeStdErrRead_, &pipeStdErrWrite_, &saAttr, 0, FILE_FLAG_OVERLAPPED, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -243,7 +266,7 @@ namespace Aurora::Processes
|
||||
|
||||
if (this->startup_.fwdIn)
|
||||
{
|
||||
if (!CreatePipe(&pipeStdInRead_, &pipeStdInWrite_, &saAttr, 0))
|
||||
if (!CreatePipeEx(&pipeStdInRead_, &pipeStdInWrite_, &saAttr, 0, 0, FILE_FLAG_OVERLAPPED))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -406,6 +429,12 @@ namespace Aurora::Processes
|
||||
return false;
|
||||
}
|
||||
|
||||
this->loopSource_ = AuMakeShared<ProcessAliveLoopSource>(this->process_);
|
||||
if (!this->loopSource_)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
this->thread_->Run();
|
||||
return true;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace Aurora::Processes
|
||||
|
||||
bool Terminate() override;
|
||||
AuSPtr<Threading::IWaitable> AsWaitable() override;
|
||||
AuSPtr<Loop::ILoopSource> AsLoopSource() override;
|
||||
AuSInt GetExitCode() override;
|
||||
|
||||
void ShutdownPipes();
|
||||
@ -49,6 +50,8 @@ namespace Aurora::Processes
|
||||
HANDLE pipeStdInRead_ {INVALID_HANDLE_VALUE};
|
||||
HANDLE pipeStdInWrite_ {INVALID_HANDLE_VALUE};
|
||||
|
||||
AuSPtr<Loop::ILoopSource> loopSource_;
|
||||
|
||||
AuSPtr<IO::FS::FileHandle> fsHandle_;
|
||||
AuSPtr<IO::FS::NtAsyncFileStream> fsStream_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user