summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c117
2 files changed, 106 insertions, 15 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 9199d6c0d3..b308e86af7 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6314,6 +6314,10 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
const char *client_address,
struct auth_serversupplied_info *server_info,
struct fake_file_handle **phandle);
+struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct fake_file_handle *handle,
+ const uint8_t *data, size_t len);
+NTSTATUS np_write_recv(struct async_req *req, ssize_t *nwritten);
NTSTATUS np_write(struct fake_file_handle *handle, const uint8_t *data,
size_t len, ssize_t *nwritten);
NTSTATUS np_read(struct fake_file_handle *handle, uint8_t *data, size_t len,
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 0753476230..b5b6bbd6eb 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -1109,32 +1109,119 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
return NT_STATUS_OK;
}
-NTSTATUS np_write(struct fake_file_handle *handle, const uint8_t *data,
- size_t len, ssize_t *nwritten)
+struct np_write_state {
+ ssize_t nwritten;
+};
+
+static void np_write_done(struct async_req *subreq);
+
+struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct fake_file_handle *handle,
+ const uint8_t *data, size_t len)
{
- DEBUG(6, ("np_write: len: %d\n", (int)len));
+ struct async_req *result, *subreq;
+ struct np_write_state *state;
+ NTSTATUS status;
+
+ DEBUG(6, ("np_write_send: len: %d\n", (int)len));
dump_data(50, data, len);
- switch (handle->type) {
- case FAKE_FILE_TYPE_NAMED_PIPE: {
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct np_write_state)) {
+ return NULL;
+ }
+
+ if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
struct pipes_struct *p = talloc_get_type_abort(
handle->private_data, struct pipes_struct);
- *nwritten = write_to_internal_pipe(p, (char *)data, len);
- break;
+
+ state->nwritten = write_to_internal_pipe(p, (char *)data, len);
+
+ status = (state->nwritten >= 0)
+ ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
+ goto post_status;
}
- case FAKE_FILE_TYPE_NAMED_PIPE_PROXY: {
+
+ if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
struct np_proxy_state *p = talloc_get_type_abort(
handle->private_data, struct np_proxy_state);
- *nwritten = write_data(p->fd, (char *)data, len);
- break;
+
+ state->nwritten = len;
+
+ subreq = sendall_send(state, ev, p->fd, data, len, 0);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = np_write_done;
+ subreq->async.priv = result;
+ return result;
}
- default:
- return NT_STATUS_INVALID_HANDLE;
- break;
+
+ status = NT_STATUS_INVALID_HANDLE;
+ post_status:
+ if (async_post_status(result, ev, status)) {
+ return result;
}
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
- return ((*nwritten) >= 0)
- ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
+static void np_write_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ NTSTATUS status;
+
+ status = sendall_recv(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+ return async_req_done(req);
+}
+
+NTSTATUS np_write_recv(struct async_req *req, ssize_t *pnwritten)
+{
+ struct np_write_state *state = talloc_get_type_abort(
+ req->private_data, struct np_write_state);
+ NTSTATUS status;
+
+ if (async_req_is_error(req, &status)) {
+ return status;
+ }
+ *pnwritten = state->nwritten;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS np_write(struct fake_file_handle *handle, const uint8_t *data,
+ size_t len, ssize_t *nwritten)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status;
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = np_write_send(frame, ev, handle, data, len);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
+
+ status = np_write_recv(req, nwritten);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
}
NTSTATUS np_read(struct fake_file_handle *handle, uint8_t *data, size_t len,