Esempio n. 1
0
// Redirects stdout/stderr back to the original stdout/stderr.
// Note, this will not restore the original handle values returned by GetStdHandle,
// rather a duplicated number. This is because the original handle value is invalid
// due to dup2 closing the file originally in stdout/stderr
HRESULT
StdWrapper::StopRedirection() const
{
    // After setting the std handle, we need to set stdout/stderr to the current
    // output/error handle.
    FILE * file = _fdopen(m_previousFileDescriptor, "w");
    if (file == nullptr)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    RETURN_LAST_ERROR_IF(!SetStdHandle(m_stdHandleNumber, reinterpret_cast<HANDLE>(_get_osfhandle(m_previousFileDescriptor))));

    if (!m_enableNativeRedirection)
    {
        return S_OK;
    }

    // Set stdout/stderr to the newly created file output.
    const auto dup2Result = _dup2(_fileno(file), _fileno(m_stdStream));
    if (dup2Result != 0)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    if (setvbuf(m_stdStream, nullptr, _IONBF, 0) != 0)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    if (fclose(m_redirectedFile) != 0)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    return S_OK;
}
Esempio n. 2
0
HRESULT ClientReader::Initialize(bool IsLoopback, FLOAT SampleRate, HANDLE WaitEvent, CComPtr<IMMDevice> InputDevice, CComPtr<IDXAudioCallback> Callback) {
	HRESULT hr = S_OK;
	BYTE* Buffer = nullptr;
	int error = 0;

	m_Callback = Callback;

	//Create the SRC_STATE object
	m_ResampleState = src_new (
		SRC_SINC_FASTEST, //More than adequate for a real time stream
		2,				  //Two channels (stereo)
		&error
	); if (error != 0) {
		m_Callback->OnObjectFailure (
			FILENAME,
			__LINE__,
			E_FAIL
		); return E_FAIL;
	}

	//"Activate" the device (create the IAudioClient interface)
	hr = InputDevice->Activate (
		__uuidof(IAudioClient),
		CLSCTX_ALL,
		nullptr,
		(void**)(&m_Client)
	); RETURN_HR(__LINE__);

	//Retrieves the device period - this is how often new information is provided
	//to the stream, in 100-nanosecond units.
	hr = m_Client->GetDevicePeriod (
		&m_Period,
		nullptr
	); RETURN_HR(__LINE__);

	//Retrieves the mix format - this is the format in which the audio endpoint gives
	//us the data.  This data will need to be resampled, so we need to know what form
	//it's in.
	hr = m_Client->GetMixFormat (
		(WAVEFORMATEX**)(&m_WaveFormat)
	); RETURN_HR(__LINE__);

	//Initialize the client, marking how we're going to be using it
	hr = m_Client->Initialize (
		AUDCLNT_SHAREMODE_SHARED, //Always use shared - exclusive is meant for drivers and is unpredictable otherwise
		WaitEvent ? AUDCLNT_STREAMFLAGS_EVENTCALLBACK : NULL | //Use an event callback if specified
		IsLoopback ? AUDCLNT_STREAMFLAGS_LOOPBACK : NULL, //Make this a loopback stream if specified
		m_Period, //Creates a buffer large enough to store one packet
		m_Period, //Use the endpoint's periodicity (this can't ve any other value)
		(WAVEFORMATEX*)(m_WaveFormat), //Pass in the wave format we just retrieved
		NULL //No audio session stuff
	); RETURN_HR(__LINE__);

	//Create the IAudioCaptureClient interface
	hr = m_Client->GetService (
		IID_PPV_ARGS(&m_CaptureClient)
	); RETURN_HR(__LINE__);

	//If using an event callback mechanism, provide the event handle (this is from CDXAudioStream)
	if (WaitEvent != NULL) {
		hr = m_Client->SetEventHandle (
			WaitEvent
		); RETURN_HR(__LINE__);
	}

	//Calculate the number of frames the endpoint is going to give us each period.
	m_PeriodFrames = (UINT32)(ceil(DOUBLE(m_Period * m_WaveFormat->Format.nSamplesPerSec) / 10000000));

	//Calculate the resample ratio - this is the ratio of the output sample rate to the input sample rate, IE
	//the sample rate specified by the application developer divided by the sample rate used by the endpoint.
	//This value is used by libsamplerate.
	m_ResampleRatio = DOUBLE(SampleRate) / DOUBLE(m_WaveFormat->Format.nSamplesPerSec); //Output sample rate / input sample rate

	return S_OK;
}
Esempio n. 3
0
// Redirects stdout/stderr to the provided handle.
// Example:
// If the handleToRedirecTo = 0x24
// Before:
// _fileno(stdout) = 1
// GetStdHandle(STD_OUTPUT_HANDLE) = 0x20
// After:
// _fileno(stdout) = 3
// GetStdHandle(STD_OUTPUT_HANDLE) = 0x28 <- Duplicated from 0x24
HRESULT
StdWrapper::StartRedirection()
{
    HANDLE stdHandle;

    // In IIS, stdout and stderr are set to null as w3wp is created with DETACHED_PROCESS,
    // so fileno(m_stdStream) returns -2.
    // Open a null file such that undoing the redirection succeeds and _dup2 works.
    // m_previousFileDescriptor will be used for restoring stdout/stderr
    if (_fileno(m_stdStream) == -2)
    {
        freopen_s((FILE**)&m_stdStream, "nul", "w", m_stdStream);
        m_previousFileDescriptor = _dup(_fileno(m_stdStream));
    }
    else
    {
        m_previousFileDescriptor = _dup(_fileno(m_stdStream));
    }

    if (!m_enableNativeRedirection)
    {
        RETURN_LAST_ERROR_IF(!SetStdHandle(m_stdHandleNumber, m_handleToRedirectTo));

        return S_OK;
    }
    // After setting the std handle, we need to set stdout/stderr to the current
    // output/error handle.

    // Duplicate the handle before opening the handle and associating a file pointer.
    // If we don't by calling close on the file, the same handle value will be closed
    // multiple times.
    // Note, by calling duplicate handle, the new handle returned will have a different value
    // than the original, but point to the same underlying file object.
    RETURN_LAST_ERROR_IF(!DuplicateHandle(
        /* hSourceProcessHandle*/ GetCurrentProcess(),
        /* hSourceHandle */ m_handleToRedirectTo,
        /* hTargetProcessHandle */ GetCurrentProcess(),
        /* lpTargetHandle */&stdHandle,
        /* dwDesiredAccess */ 0, // dwDesired is ignored if DUPLICATE_SAME_ACCESS is specified
        /* bInheritHandle */ TRUE,
        /* dwOptions  */ DUPLICATE_SAME_ACCESS));

    RETURN_LAST_ERROR_IF(!SetStdHandle(m_stdHandleNumber, stdHandle));

    // _open_osfhandle will associate a filedescriptor with the handle.
    const auto fileDescriptor = _open_osfhandle(reinterpret_cast<intptr_t>(stdHandle), _O_WTEXT | _O_TEXT);

    if (fileDescriptor == -1)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    m_redirectedFile = _fdopen(fileDescriptor, "w");

    if (m_redirectedFile == nullptr)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    // Set stdout/stderr to the newly created file.
    const auto dup2Result = _dup2(_fileno(m_redirectedFile), _fileno(m_stdStream));

    if (dup2Result != 0)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    // Removes buffering from the output
    if (setvbuf(m_stdStream, nullptr, _IONBF, 0) != 0)
    {
        RETURN_HR(HRESULT_FROM_WIN32(ERROR_FILE_INVALID));
    }

    return S_OK;
}
HRESULT SwapChainController12::CreateSwapChain(CComPtr<IUnknown> DeviceUnk, UINT NumBuffers) {
	HRESULT hr = S_OK;
	BOOL bresult = TRUE;

	if (NumBuffers < 2) {
		hr = E_INVALIDARG;
		RETURN_HR(__LINE__);
	}

	DXGI_SWAP_CHAIN_DESC desc; Zero(desc);
	CComPtr<IDXGIFactory4> factory;
	CComPtr<IDXGISwapChain> BaseSwapChain;

	RECT WindowRect;

	//Retrieves the client area of the window, which tells us its renderable width and height
	bresult = GetClientRect (
		m_Handle,
		&WindowRect
	); RETURN_BRESULT(__LINE__);

	//Fill the swap chain description
	desc.BufferCount = NumBuffers; //For D3D12, this is the total number of buffers, not the number of back buffers.
	desc.BufferDesc.Format = GLOBAL_DXGI_FORMAT;
	desc.BufferDesc.Width = WindowRect.right - WindowRect.left;
	desc.BufferDesc.Height = WindowRect.bottom - WindowRect.top;
	desc.BufferDesc.RefreshRate.Numerator = 0;
	desc.BufferDesc.RefreshRate.Denominator = 0;
	desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
	desc.OutputWindow = m_Handle;
	desc.SampleDesc.Count = 1;
	desc.SampleDesc.Quality = 0;
	desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
	desc.Windowed = TRUE;

	//This is the factory that made the application's device
	hr = m_OutputEnum.GetAdapter()->GetParent (
		IID_PPV_ARGS(&factory)
	); RETURN_HR(__LINE__);

	//Use that factory to create the swap chain
	hr = factory->CreateSwapChain (
		DeviceUnk,
		&desc,
		&BaseSwapChain
	); RETURN_HR(__LINE__);

	hr = BaseSwapChain->QueryInterface (
		IID_PPV_ARGS(&m_SwapChain)
	); RETURN_HR(__LINE__);

	//Turn off alt-enter, since we're using F11 instead
	hr = factory->MakeWindowAssociation (
		m_Handle,
		DXGI_MWA_NO_WINDOW_CHANGES
	); RETURN_HR(__LINE__);

	return S_OK;
}