Changeset 988 for vendor/current/source3/libsmb/clioplock.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/libsmb/clioplock.c
r746 r988 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 SMB client oplock functions 4 4 Copyright (C) Andrew Tridgell 2001 5 5 6 6 This program is free software; you can redistribute it and/or modify 7 7 it under the terms of the GNU General Public License as published by 8 8 the Free Software Foundation; either version 3 of the License, or 9 9 (at your option) any later version. 10 10 11 11 This program is distributed in the hope that it will be useful, 12 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 GNU General Public License for more details. 15 15 16 16 You should have received a copy of the GNU General Public License 17 17 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 22 22 #include "async_smb.h" 23 23 #include "libsmb/libsmb.h" 24 #include "../libcli/smb/smbXcli_base.h" 25 26 struct cli_smb_oplock_break_waiter_state { 27 uint16_t fnum; 28 uint8_t level; 29 }; 30 31 static void cli_smb_oplock_break_waiter_done(struct tevent_req *subreq); 32 33 struct tevent_req *cli_smb_oplock_break_waiter_send(TALLOC_CTX *mem_ctx, 34 struct tevent_context *ev, 35 struct cli_state *cli) 36 { 37 struct tevent_req *req, *subreq; 38 struct cli_smb_oplock_break_waiter_state *state; 39 40 req = tevent_req_create(mem_ctx, &state, 41 struct cli_smb_oplock_break_waiter_state); 42 if (req == NULL) { 43 return NULL; 44 } 45 46 /* 47 * Create a fake SMB request that we will never send out. This is only 48 * used to be set into the pending queue with the right mid. 49 */ 50 subreq = smb1cli_req_create(mem_ctx, ev, cli->conn, 0, 0, 0, 0, 0, 0, 51 0, NULL, NULL, 0, NULL, 0, NULL); 52 if (tevent_req_nomem(subreq, req)) { 53 return tevent_req_post(req, ev); 54 } 55 smb1cli_req_set_mid(subreq, 0xffff); 56 57 if (!smbXcli_req_set_pending(subreq)) { 58 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 59 return tevent_req_post(req, ev); 60 } 61 tevent_req_set_callback(subreq, cli_smb_oplock_break_waiter_done, req); 62 return req; 63 } 64 65 static void cli_smb_oplock_break_waiter_done(struct tevent_req *subreq) 66 { 67 struct tevent_req *req = tevent_req_callback_data( 68 subreq, struct tevent_req); 69 struct cli_smb_oplock_break_waiter_state *state = tevent_req_data( 70 req, struct cli_smb_oplock_break_waiter_state); 71 struct iovec *iov; 72 uint8_t wct; 73 uint16_t *vwv; 74 NTSTATUS status; 75 76 status = smb1cli_req_recv(subreq, state, 77 &iov, /* piov */ 78 NULL, /* phdr */ 79 &wct, 80 &vwv, 81 NULL, /* pvwv_offset */ 82 NULL, /* pnum_bytes */ 83 NULL, /* pbytes */ 84 NULL, /* pbytes_offset */ 85 NULL, /* pinbuf */ 86 NULL, 0); /* expected */ 87 TALLOC_FREE(subreq); 88 if (!NT_STATUS_IS_OK(status)) { 89 tevent_req_nterror(req, status); 90 return; 91 } 92 if (wct < 8) { 93 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 94 return; 95 } 96 state->fnum = SVAL(vwv+2, 0); 97 state->level = CVAL(vwv+3, 1); 98 tevent_req_done(req); 99 } 100 101 NTSTATUS cli_smb_oplock_break_waiter_recv(struct tevent_req *req, 102 uint16_t *pfnum, 103 uint8_t *plevel) 104 { 105 struct cli_smb_oplock_break_waiter_state *state = tevent_req_data( 106 req, struct cli_smb_oplock_break_waiter_state); 107 NTSTATUS status; 108 109 if (tevent_req_is_nterror(req, &status)) { 110 return status; 111 } 112 *pfnum = state->fnum; 113 *plevel = state->level; 114 return NT_STATUS_OK; 115 } 24 116 25 117 /**************************************************************************** … … 84 176 } 85 177 86 NTSTATUS cli_oplock_ack(struct cli_state *cli, uint16_t fnum, unsigned char level)87 {88 TALLOC_CTX *frame = talloc_stackframe();89 struct event_context *ev;90 struct tevent_req *req;91 NTSTATUS status = NT_STATUS_OK;92 93 if (cli_has_async_calls(cli)) {94 /*95 * Can't use sync call while an async call is in flight96 */97 status = NT_STATUS_INVALID_PARAMETER;98 goto fail;99 }100 101 ev = event_context_init(frame);102 if (ev == NULL) {103 status = NT_STATUS_NO_MEMORY;104 goto fail;105 }106 107 req = cli_oplock_ack_send(frame, ev, cli, fnum, level);108 if (req == NULL) {109 status = NT_STATUS_NO_MEMORY;110 goto fail;111 }112 113 if (!tevent_req_poll(req, ev)) {114 status = map_nt_error_from_unix(errno);115 goto fail;116 }117 118 status = cli_oplock_ack_recv(req);119 fail:120 TALLOC_FREE(frame);121 return status;122 }123 124 /****************************************************************************125 set the oplock handler for a connection126 ****************************************************************************/127 128 void cli_oplock_handler(struct cli_state *cli,129 NTSTATUS (*handler)(struct cli_state *, uint16_t, unsigned char))130 {131 cli->oplock_handler = handler;132 }
Note:
See TracChangeset
for help on using the changeset viewer.