/******************************************************************* PipeCreateNameAndSecret - *******************************************************************/ extern "C" HRESULT PipeCreateNameAndSecret( __out_z LPWSTR *psczConnectionName, __out_z LPWSTR *psczSecret ) { HRESULT hr = S_OK; RPC_STATUS rs = RPC_S_OK; UUID guid = { }; WCHAR wzGuid[39]; LPWSTR sczConnectionName = NULL; LPWSTR sczSecret = NULL; // Create the unique pipe name. rs = ::UuidCreate(&guid); hr = HRESULT_FROM_RPC(rs); ExitOnFailure(hr, "Failed to create pipe guid."); if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) { hr = E_OUTOFMEMORY; ExitOnRootFailure(hr, "Failed to convert pipe guid into string."); } hr = StrAllocFormatted(&sczConnectionName, L"BurnPipe.%s", wzGuid); ExitOnFailure(hr, "Failed to allocate pipe name."); // Create the unique client secret. rs = ::UuidCreate(&guid); hr = HRESULT_FROM_RPC(rs); ExitOnRootFailure(hr, "Failed to create pipe guid."); if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) { hr = E_OUTOFMEMORY; ExitOnRootFailure(hr, "Failed to convert pipe guid into string."); } hr = StrAllocString(&sczSecret, wzGuid, 0); ExitOnFailure(hr, "Failed to allocate pipe secret."); *psczConnectionName = sczConnectionName; sczConnectionName = NULL; *psczSecret = sczSecret; sczSecret = NULL; LExit: ReleaseStr(sczSecret); ReleaseStr(sczConnectionName); return hr; }
extern "C" HRESULT NetFxRunChainer( __in LPCWSTR wzExecutablePath, __in LPCWSTR wzArguments, __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler, __in LPVOID pvContext, __out DWORD* pdwExitCode ) { HRESULT hr = S_OK; DWORD er = 0; UUID guid = { }; WCHAR wzGuid[39]; RPC_STATUS rs = RPC_S_OK; LPWSTR sczEventName = NULL; LPWSTR sczSectionName = NULL; LPWSTR sczCommand = NULL; NetFxChainer* pNetfxChainer = NULL; STARTUPINFOW si = { }; PROCESS_INFORMATION pi = { }; HRESULT hrInternalError = 0; // Create the unique name suffix. rs = ::UuidCreate(&guid); hr = HRESULT_FROM_RPC(rs); ExitOnFailure(hr, "Failed to create netfx chainer guid."); if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) { hr = E_OUTOFMEMORY; ExitOnRootFailure(hr, "Failed to convert netfx chainer guid into string."); } hr = StrAllocFormatted(&sczSectionName, L"NetFxSection.%ls", wzGuid); ExitOnFailure(hr, "Failed to allocate section name."); hr = StrAllocFormatted(&sczEventName, L"NetFxEvent.%ls", wzGuid); ExitOnFailure(hr, "Failed to allocate event name."); hr = CreateNetFxChainer(sczSectionName, sczEventName, &pNetfxChainer); ExitOnFailure(hr, "Failed to create netfx chainer."); hr = StrAllocFormatted(&sczCommand, L"%ls /pipe %ls", wzArguments, sczSectionName); ExitOnFailure(hr, "Failed to allocate netfx chainer arguments."); si.cb = sizeof(si); if (!::CreateProcessW(wzExecutablePath, sczCommand, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { ExitWithLastError1(hr, "Failed to CreateProcess on path: %ls", wzExecutablePath); } HANDLE handles[2] = { pi.hProcess, pNetfxChainer->hEventChaineeSend }; for (;;) { er = ::WaitForMultipleObjects(2, handles, FALSE, 100); if (WAIT_OBJECT_0 == er) { // Process has exited *pdwExitCode = NetFxGetResult(pNetfxChainer, &hrInternalError); if (E_PENDING == *pdwExitCode) { if (!::GetExitCodeProcess(pi.hProcess, pdwExitCode)) { ExitWithLastError(hr, "Failed to get netfx return code."); } } else if (FAILED(hrInternalError)) { // push internal error message OnNetFxError(pNetfxChainer, hrInternalError, pfnGenericMessageHandler, pvContext); ExitOnFailure(hr, "Failed to send internal error message from netfx chainer."); } break; } else if (WAIT_OBJECT_0 + 1 == er) { // Chainee has notified us of a change. hr = ProcessNetFxMessage(pNetfxChainer, pfnGenericMessageHandler, pvContext); ExitOnFailure(hr, "Failed to process netfx chainer message."); } else if (WAIT_FAILED == er) { ExitWithLastError(hr, "Failed to wait for netfx chainer process to complete"); } } LExit: ReleaseStr(sczSectionName); ReleaseStr(sczEventName); ReleaseStr(sczCommand); DestroyNetFxChainer(pNetfxChainer); ReleaseHandle(pi.hThread); ReleaseHandle(pi.hProcess); return hr; }