+static void smbd_smb2_ioctl_pipe_write_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct smbd_smb2_ioctl_state *state = tevent_req_data(req,
+ struct smbd_smb2_ioctl_state);
+ NTSTATUS status;
+ ssize_t nwritten = -1;
+
+ status = np_write_recv(subreq, &nwritten);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+
+ if (nwritten != state->in_input.length) {
+ tevent_req_nterror(req, NT_STATUS_PIPE_NOT_AVAILABLE);
+ return;
+ }
+
+ state->out_output = data_blob_talloc(state, NULL, state->in_max_output);
+ if (state->in_max_output > 0 &&
+ tevent_req_nomem(state->out_output.data, req)) {
+ return;
+ }
+
+ subreq = np_read_send(state->smbreq->conn,
+ state->smb2req->conn->smb2.event_ctx,
+ state->fsp->fake_file_handle,
+ state->out_output.data,
+ state->out_output.length);
+ if (tevent_req_nomem(subreq, req)) {
+ return;
+ }
+ tevent_req_set_callback(subreq, smbd_smb2_ioctl_pipe_read_done, req);
+}
+
+static void smbd_smb2_ioctl_pipe_read_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct smbd_smb2_ioctl_state *state = tevent_req_data(req,
+ struct smbd_smb2_ioctl_state);
+ NTSTATUS status;
+ ssize_t nread;
+ bool is_data_outstanding;
+
+ status = np_read_recv(subreq, &nread, &is_data_outstanding);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+
+ state->out_output.length = nread;
+
+ tevent_req_done(req);
+}
+