summaryrefslogtreecommitdiff
path: root/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.cpp
blob: a588928f004c965a078223611dd8ec40bff32f18 (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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

/*=====================================================================
**
** Source:  test5.c (DuplicateHandle)
**
** Purpose: Tests the PAL implementation of the DuplicateHandle function,
**          with CreatePipe. This test will create a pipe and write to it,
**          the duplicate the read handle and read what was written.
**
** Depends: WriteFile
**          ReadFile
**          memcmp
**          CloseHandle
**
**
**===================================================================*/

#include <palsuite.h>

const char* cTestString = "one fish, two fish, red fish, blue fish.";

int __cdecl main(int argc, char **argv)
{
    HANDLE  hReadPipe   = NULL;
    HANDLE  hWritePipe  = NULL;
    HANDLE  hDupPipe    = NULL;
    BOOL    bRetVal     = FALSE;
    DWORD   dwBytesWritten;
    DWORD   dwBytesRead;
    char    buffer[256];

    SECURITY_ATTRIBUTES lpPipeAttributes;

    /*Initialize the PAL*/
    if ((PAL_Initialize(argc, argv)) != 0)
    {
        return (FAIL);
    }

    /*Setup SECURITY_ATTRIBUTES structure for CreatePipe*/
    lpPipeAttributes.nLength              = sizeof(lpPipeAttributes); 
    lpPipeAttributes.lpSecurityDescriptor = NULL; 
    lpPipeAttributes.bInheritHandle       = TRUE; 

    /*Create a Pipe*/
    bRetVal = CreatePipe(&hReadPipe,       /* read handle*/
                         &hWritePipe,      /* write handle */
                         &lpPipeAttributes,/* security attributes*/
                         0);               /* pipe size*/
    if (bRetVal == FALSE)
    {
        Fail("ERROR:%u:Unable to create pipe\n", GetLastError());
    }

    /*Write to the write pipe handle*/
    bRetVal = WriteFile(hWritePipe,         /* handle to write pipe*/
                        cTestString,        /* buffer to write*/
                        strlen(cTestString),/* number of bytes to write*/
                        &dwBytesWritten,    /* number of bytes written*/
                        NULL);              /* overlapped buffer*/
    if (bRetVal == FALSE)
    {
        Trace("ERROR:%u:unable to write to write pipe handle "
            "hWritePipe=0x%lx\n", GetLastError(), hWritePipe);
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        Fail("");
    }

    /*Duplicate the pipe handle*/
    if (!(DuplicateHandle(GetCurrentProcess(),       /* source handle process*/
                          hReadPipe,                 /* handle to duplicate*/
                          GetCurrentProcess(),       /* target process handle*/
                          &hDupPipe,                 /* duplicate handle*/
                          GENERIC_READ|GENERIC_WRITE,/* requested access*/
                          FALSE,                     /* handle inheritance*/
                          DUPLICATE_SAME_ACCESS)))   /* optional actions*/
    {
        Trace("ERROR:%u:Fail to create the duplicate handle"
             " to hReadPipe=0x%lx",
             GetLastError(),
             hReadPipe);
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        Fail("");
    }
    
    /*Read from the duplicated handle, 256 bytes, more bytes
     than actually written. This will allow us to use the 
     value that ReadFile returns for comparision.*/
    bRetVal = ReadFile(hDupPipe,           /* handle to read pipe*/
                       buffer,             /* buffer to write to*/
                       256,                /* number of bytes to read*/
                       &dwBytesRead,       /* number of bytes read*/
                       NULL);              /* overlapped buffer*/
    if (bRetVal == FALSE)
    {
        Trace("ERROR:%u:unable read from the duplicated pipe " 
             "hDupPipe=0x%lx\n",
             GetLastError(), 
             hDupPipe);
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        CloseHandle(hDupPipe);
        Fail("");
    }

    /*Compare what was read with what was written.*/
    if ((memcmp(cTestString, buffer, dwBytesRead)) != 0)
    {
        Trace("ERROR:%u: read \"%s\" expected \"%s\" \n", 
               GetLastError(),
               buffer,
               cTestString);
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        CloseHandle(hDupPipe);
        Fail("");
    }

    /*Compare values returned from WriteFile and ReadFile.*/
    if (dwBytesWritten != dwBytesRead)
    {
        Trace("ERROR:%u: WriteFile wrote \"%s\", but ReadFile read \"%s\","
             " these should be the same\n", 
             GetLastError(),
             buffer, 
             cTestString);
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        CloseHandle(hDupPipe);
        Fail("");
    }

    /*Cleanup.*/
    CloseHandle(hWritePipe);
    CloseHandle(hReadPipe);
    CloseHandle(hDupPipe);
    
    PAL_Terminate();
    return (PASS);
}