aboutsummaryrefslogtreecommitdiff
path: root/src/libs/dutil/test/DUtilUnitTest/PipeUtilTest.cpp
blob: aa6874e44af70b369f8678925bdfb5081f88178d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.

#include "precomp.h"

using namespace System;
using namespace System::Security::Principal;
using namespace Xunit;
using namespace WixInternal::TestSupport;
using namespace WixInternal::TestSupport::XunitExtensions;

static DWORD STDAPICALLTYPE _TestPipeClientThreadProc(
    __in LPVOID lpThreadParameter
);

namespace DutilTests
{
    public ref class PipeUtil
    {
    public:
        [Fact]
            void PipeConnectWriteAndRead()
        {
            HRESULT hr = S_OK;
            HANDLE hServerPipe = INVALID_HANDLE_VALUE;
            HANDLE hClientThread = NULL;
            PIPE_RPC_HANDLE hRpc = { INVALID_HANDLE_VALUE };
            PIPE_MESSAGE msg = { };
            DWORD dwThread = 42;
            DWORD dwTestMessageId = 987654;

            try
            {
                hr = PipeCreate(L"DutilTest", NULL, &hServerPipe);
                NativeAssert::Succeeded(hr, "Failed to create server pipe.");

                PipeRpcInitialize(&hRpc, hServerPipe, FALSE);
                NativeAssert::Equal((DWORD_PTR)hServerPipe, (DWORD_PTR)hRpc.hPipe);

                BOOL fInitialized = PipeRpcInitialized(&hRpc);
                NativeAssert::True(fInitialized);

                hClientThread = ::CreateThread(NULL, 0, _TestPipeClientThreadProc, &dwTestMessageId, 0, NULL);
                if (hClientThread == 0)
                {
                    NativeAssert::Fail("Failed to create client thread.");
                    return;
                }

                hr = PipeServerWaitForClientConnect(hClientThread, hServerPipe);
                NativeAssert::Succeeded(hr, "Failed to wait for client to connect to pipe.");

                hr = PipeRpcReadMessage(&hRpc, &msg);
                NativeAssert::Succeeded(hr, "Failed to read message from client.");

                NativeAssert::Equal(dwTestMessageId, msg.dwMessageType);

                AppWaitForSingleObject(hClientThread, INFINITE);

                ::GetExitCodeThread(hClientThread, &dwThread);
                NativeAssert::Equal((DWORD)12, dwThread);
            }
            finally
            {
                ReleasePipeMessage(&msg);
                ReleaseHandle(hClientThread);
                ReleasePipeHandle(hServerPipe);

                PipeRpcUninitiailize(&hRpc);
            }
        }
    };
}


static DWORD STDAPICALLTYPE _TestPipeClientThreadProc(
    __in LPVOID lpThreadParameter
)
{
    HRESULT hr = S_OK;
    HANDLE hClientPipe = INVALID_HANDLE_VALUE;
    PIPE_RPC_HANDLE hRpc = { INVALID_HANDLE_VALUE };

    hr = PipeClientConnect(L"DutilTest", &hClientPipe);
    if (FAILED(hr))
    {
        return hr;
    }

    PipeRpcInitialize(&hRpc, hClientPipe, TRUE);

    ::Sleep(200);

    hr = PipeRpcWriteMessage(&hRpc, *(LPDWORD)lpThreadParameter, NULL, 0);
    if (FAILED(hr))
    {
        return hr;
    }

    PipeRpcUninitiailize(&hRpc);

    return 12;
}