diff options
Diffstat (limited to 'source3/libsmb/cli_smb2_fnum.c')
-rw-r--r-- | source3/libsmb/cli_smb2_fnum.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index c40d6dd3a45..2d87b58d730 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -4337,3 +4337,103 @@ NTSTATUS cli_smb2_set_reparse_point_fnum_recv(struct tevent_req *req) { return tevent_req_simple_recv_ntstatus(req); } + +struct cli_smb2_get_reparse_point_fnum_state { + struct cli_state *cli; + uint16_t fnum; + struct smb2_hnd *ph; + DATA_BLOB output_buffer; +}; + +static void cli_smb2_get_reparse_point_fnum_done(struct tevent_req *subreq); + +struct tevent_req *cli_smb2_get_reparse_point_fnum_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint16_t fnum) +{ + struct tevent_req *req, *subreq; + struct cli_smb2_set_reparse_point_fnum_state *state = NULL; + NTSTATUS status; + + req = tevent_req_create(mem_ctx, &state, + struct cli_smb2_get_reparse_point_fnum_state); + if (req == NULL) { + return NULL; + } + + if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + state->cli = cli; + state->fnum = fnum; + + status = map_fnum_to_smb2_handle(cli, fnum, &state->ph); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + subreq = smb2cli_ioctl_send(state, ev, state->cli->conn, + state->cli->timeout, + state->cli->smb2.session, + state->cli->smb2.tcon, + state->ph->fid_persistent, /* in_fid_persistent */ + state->ph->fid_volatile, /* in_fid_volatile */ + FSCTL_GET_REPARSE_POINT, + 0, /* in_max_input_length */ + NULL, + 64*1024, + NULL, + SMB2_IOCTL_FLAG_IS_FSCTL); + + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + cli_smb2_get_reparse_point_fnum_done, + req); + + return req; +} + +static void cli_smb2_get_reparse_point_fnum_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_smb2_get_reparse_point_fnum_state *state = tevent_req_data( + req, struct cli_smb2_get_reparse_point_fnum_state); + NTSTATUS status; + + status = smb2cli_ioctl_recv(subreq, state, + NULL, + &state->output_buffer); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + state->cli->raw_status = status; + return; + } + tevent_req_done(req); +} + +NTSTATUS cli_smb2_get_reparse_point_fnum_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + DATA_BLOB *output) +{ + struct cli_smb2_get_reparse_point_fnum_state *state = tevent_req_data( + req, struct cli_smb2_get_reparse_point_fnum_state); + + if (tevent_req_is_nterror(req, &state->cli->raw_status)) { + tevent_req_received(req); + return state->cli->raw_status; + } + *output = data_blob_dup_talloc(mem_ctx, state->output_buffer); + if (output->data == NULL) { + tevent_req_received(req); + return NT_STATUS_NO_MEMORY; + } + tevent_req_received(req); + return NT_STATUS_OK; +} |