2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite NPFS Connect test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
11 #define MAX_INSTANCES 5
13 #define OUT_QUOTA 4096
15 #define CheckServer(ServerHandle, State) \
16 NpCheckServerPipe(ServerHandle, \
17 BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \
20 OUT_QUOTA, OUT_QUOTA, \
23 #define CheckClient(ClientHandle, State) \
24 NpCheckClientPipe(ClientHandle, \
25 BYTE_STREAM, QUEUE, BYTE_STREAM, DUPLEX, \
28 OUT_QUOTA, OUT_QUOTA, \
34 IN OUT PTHREAD_CONTEXT Context
)
39 Context
->Connect
.Status
= NpOpenPipe(&ClientHandle
,
40 Context
->Connect
.PipePath
,
41 FILE_PIPE_FULL_DUPLEX
);
42 Context
->Connect
.ClientHandle
= ClientHandle
;
48 IN OUT PTHREAD_CONTEXT Context
)
50 Context
->Listen
.Status
= NpListenPipe(Context
->Listen
.ServerHandle
);
56 IN PTHREAD_CONTEXT Context
,
58 IN ULONG MilliSeconds
)
60 Context
->Work
= ConnectPipe
;
61 Context
->Connect
.PipePath
= PipePath
;
62 return TriggerWork(Context
, MilliSeconds
);
68 IN PTHREAD_CONTEXT Context
,
69 IN HANDLE ServerHandle
,
70 IN ULONG MilliSeconds
)
72 Context
->Work
= ListenPipe
;
73 Context
->Listen
.ServerHandle
= ServerHandle
;
74 return TriggerWork(Context
, MilliSeconds
);
80 IN HANDLE ServerHandle
,
84 THREAD_CONTEXT ConnectContext
;
85 THREAD_CONTEXT ListenContext
;
89 StartWorkerThread(&ConnectContext
);
90 StartWorkerThread(&ListenContext
);
92 /* Server should start out listening */
93 CheckServer(ServerHandle
, FILE_PIPE_LISTENING_STATE
);
95 /* Connect a client */
97 Okay
= CheckConnectPipe(&ConnectContext
, PipePath
, 100);
98 ok_bool_true(Okay
, "CheckConnectPipe returned");
99 ok_eq_hex(ConnectContext
.Connect
.Status
, STATUS_SUCCESS
);
100 if (NT_SUCCESS(ConnectContext
.Connect
.Status
))
102 ClientHandle
= ConnectContext
.Connect
.ClientHandle
;
103 CheckClient(ClientHandle
, FILE_PIPE_CONNECTED_STATE
);
105 CheckServer(ServerHandle
, FILE_PIPE_CONNECTED_STATE
);
107 /* Connect another client */
108 Okay
= CheckConnectPipe(&ConnectContext
, PipePath
, 100);
109 ok_bool_true(Okay
, "CheckConnectPipe returned");
110 ok_eq_hex(ConnectContext
.Connect
.Status
, STATUS_PIPE_NOT_AVAILABLE
);
111 if (NT_SUCCESS(ConnectContext
.Connect
.Status
))
112 ObCloseHandle(ConnectContext
.Connect
.ClientHandle
, KernelMode
);
113 CheckClient(ClientHandle
, FILE_PIPE_CONNECTED_STATE
);
114 CheckServer(ServerHandle
, FILE_PIPE_CONNECTED_STATE
);
116 /* Disconnecting the client should fail */
117 Status
= NpDisconnectPipe(ClientHandle
);
118 ok_eq_hex(Status
, STATUS_ILLEGAL_FUNCTION
);
119 CheckClient(ClientHandle
, FILE_PIPE_CONNECTED_STATE
);
120 CheckServer(ServerHandle
, FILE_PIPE_CONNECTED_STATE
);
122 /* Listening on the client should fail */
123 Status
= NpListenPipe(ClientHandle
);
124 ok_eq_hex(Status
, STATUS_ILLEGAL_FUNCTION
);
125 CheckClient(ClientHandle
, FILE_PIPE_CONNECTED_STATE
);
126 CheckServer(ServerHandle
, FILE_PIPE_CONNECTED_STATE
);
130 ObCloseHandle(ClientHandle
, KernelMode
);
131 CheckServer(ServerHandle
, FILE_PIPE_CLOSING_STATE
);
133 /* Connecting a client now should fail */
134 Okay
= CheckConnectPipe(&ConnectContext
, PipePath
, 100);
135 ok_bool_true(Okay
, "CheckConnectPipe returned");
136 ok_eq_hex(ConnectContext
.Connect
.Status
, STATUS_PIPE_NOT_AVAILABLE
);
137 if (NT_SUCCESS(ConnectContext
.Connect
.Status
))
138 ObCloseHandle(ConnectContext
.Connect
.ClientHandle
, KernelMode
);
139 CheckServer(ServerHandle
, FILE_PIPE_CLOSING_STATE
);
141 /* Listening should fail */
142 Okay
= CheckListenPipe(&ListenContext
, ServerHandle
, 100);
143 ok_bool_true(Okay
, "CheckListenPipe returned");
144 if (!skip(Okay
, "Listen succeeded unexpectedly\n"))
145 CheckServer(ServerHandle
, FILE_PIPE_CLOSING_STATE
);
147 /* Disconnect server */
148 Status
= NpDisconnectPipe(ServerHandle
);
149 ok_eq_hex(Status
, STATUS_SUCCESS
);
150 CheckServer(ServerHandle
, FILE_PIPE_DISCONNECTED_STATE
);
152 /* Disconnecting again should fail */
153 Status
= NpDisconnectPipe(ServerHandle
);
154 ok_eq_hex(Status
, STATUS_PIPE_DISCONNECTED
);
155 CheckServer(ServerHandle
, FILE_PIPE_DISCONNECTED_STATE
);
157 /* Connecting a client now should fail */
158 Okay
= CheckConnectPipe(&ConnectContext
, PipePath
, 100);
159 ok_bool_true(Okay
, "CheckConnectPipe returned");
160 ok_eq_hex(ConnectContext
.Connect
.Status
, STATUS_PIPE_NOT_AVAILABLE
);
161 if (NT_SUCCESS(ConnectContext
.Connect
.Status
))
162 ObCloseHandle(ConnectContext
.Connect
.ClientHandle
, KernelMode
);
163 CheckServer(ServerHandle
, FILE_PIPE_DISCONNECTED_STATE
);
165 /**************************************************************************/
166 /* Now listen again */
167 Okay
= CheckListenPipe(&ListenContext
, ServerHandle
, 100);
168 ok_bool_false(Okay
, "CheckListenPipe returned");
169 //blocks: CheckServer(ServerHandle, FILE_PIPE_LISTENING_STATE);
173 Okay
= CheckConnectPipe(&ConnectContext
, PipePath
, 100);
174 ok_bool_true(Okay
, "CheckConnectPipe returned");
175 ok_eq_hex(ConnectContext
.Connect
.Status
, STATUS_SUCCESS
);
176 if (NT_SUCCESS(ConnectContext
.Connect
.Status
))
178 ClientHandle
= ConnectContext
.Connect
.ClientHandle
;
179 CheckClient(ClientHandle
, FILE_PIPE_CONNECTED_STATE
);
181 Okay
= WaitForWork(&ListenContext
, 100);
182 ok_bool_true(Okay
, "WaitForWork returned");
183 ok_eq_hex(ListenContext
.Listen
.Status
, STATUS_SUCCESS
);
184 CheckServer(ServerHandle
, FILE_PIPE_CONNECTED_STATE
);
186 /* Listening again should fail */
187 Okay
= CheckListenPipe(&ListenContext
, ServerHandle
, 100);
188 ok_bool_true(Okay
, "CheckListenPipe returned");
189 ok_eq_hex(ListenContext
.Listen
.Status
, STATUS_PIPE_CONNECTED
);
190 CheckClient(ClientHandle
, FILE_PIPE_CONNECTED_STATE
);
191 CheckServer(ServerHandle
, FILE_PIPE_CONNECTED_STATE
);
193 /* Disconnect server */
194 Status
= NpDisconnectPipe(ServerHandle
);
195 ok_eq_hex(Status
, STATUS_SUCCESS
);
196 NpQueryPipe(ClientHandle
, STATUS_PIPE_DISCONNECTED
);
197 CheckServer(ServerHandle
, FILE_PIPE_DISCONNECTED_STATE
);
201 ObCloseHandle(ClientHandle
, KernelMode
);
202 CheckServer(ServerHandle
, FILE_PIPE_DISCONNECTED_STATE
);
204 /**************************************************************************/
205 /* Listen once more */
206 Okay
= CheckListenPipe(&ListenContext
, ServerHandle
, 100);
207 ok_bool_false(Okay
, "CheckListenPipe returned");
208 //blocks: CheckServer(ServerHandle, FILE_PIPE_LISTENING_STATE);
212 Okay
= CheckConnectPipe(&ConnectContext
, PipePath
, 100);
213 ok_bool_true(Okay
, "CheckConnectPipe returned");
214 ok_eq_hex(ConnectContext
.Connect
.Status
, STATUS_SUCCESS
);
215 if (NT_SUCCESS(ConnectContext
.Connect
.Status
))
217 ClientHandle
= ConnectContext
.Connect
.ClientHandle
;
218 CheckClient(ClientHandle
, FILE_PIPE_CONNECTED_STATE
);
220 Okay
= WaitForWork(&ListenContext
, 100);
221 ok_bool_true(Okay
, "WaitForWork returned");
222 ok_eq_hex(ListenContext
.Listen
.Status
, STATUS_SUCCESS
);
223 CheckServer(ServerHandle
, FILE_PIPE_CONNECTED_STATE
);
226 Status
= ObCloseHandle(ServerHandle
, KernelMode
);
227 ok_eq_hex(Status
, STATUS_SUCCESS
);
228 CheckClient(ClientHandle
, FILE_PIPE_CLOSING_STATE
);
232 ObCloseHandle(ClientHandle
, KernelMode
);
234 FinishWorkerThread(&ListenContext
);
235 FinishWorkerThread(&ConnectContext
);
238 static KSTART_ROUTINE RunTest
;
248 UNREFERENCED_PARAMETER(Context
);
250 ServerHandle
= INVALID_HANDLE_VALUE
;
251 Status
= NpCreatePipe(&ServerHandle
,
252 DEVICE_NAMED_PIPE L
"\\KmtestNpfsConnectTestPipe",
253 BYTE_STREAM
, QUEUE
, BYTE_STREAM
, DUPLEX
,
257 ok_eq_hex(Status
, STATUS_SUCCESS
);
258 ok(ServerHandle
!= NULL
&& ServerHandle
!= INVALID_HANDLE_VALUE
, "ServerHandle = %p\n", ServerHandle
);
259 if (!skip(NT_SUCCESS(Status
) && ServerHandle
!= NULL
&& ServerHandle
!= INVALID_HANDLE_VALUE
, "No pipe\n"))
261 CheckServer(ServerHandle
, FILE_PIPE_LISTENING_STATE
);
262 TestConnect(ServerHandle
, DEVICE_NAMED_PIPE L
"\\KmtestNpfsConnectTestPipe");
266 START_TEST(NpfsConnect
)
270 Thread
= KmtStartThread(RunTest
, NULL
);
271 KmtFinishThread(Thread
, NULL
);