Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : Wrap unix errno around tevent_req 4 : Copyright (C) Volker Lendecke 2009 5 : 6 : This program is free software; you can redistribute it and/or modify 7 : it under the terms of the GNU General Public License as published by 8 : the Free Software Foundation; either version 3 of the License, or 9 : (at your option) any later version. 10 : 11 : This program is distributed in the hope that it will be useful, 12 : but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : GNU General Public License for more details. 15 : 16 : You should have received a copy of the GNU General Public License 17 : along with this program. If not, see <http://www.gnu.org/licenses/>. 18 : */ 19 : 20 : #include "../replace/replace.h" 21 : #include "tevent_ntstatus.h" 22 : #include "libcli/util/error.h" 23 : 24 : #define TEVENT_NTERROR_MAGIC (0x917b5acd) 25 : 26 20773100 : bool _tevent_req_nterror(struct tevent_req *req, 27 : NTSTATUS status, 28 : const char *location) 29 : { 30 177146 : uint64_t err; 31 : 32 20773100 : if (NT_STATUS_IS_OK(status)) { 33 20055998 : return false; 34 : } 35 : 36 : /* 37 : * I've put this variable here, because I'm not 100% certain 38 : * how to correctly assign a 64-bit constant and left-shift it 39 : * by 32 bits in a single expression. If anyone knows, feel 40 : * free :-) 41 : */ 42 546164 : err = TEVENT_NTERROR_MAGIC; 43 546164 : err <<= 32; 44 546164 : err |= NT_STATUS_V(status); 45 : 46 546164 : return _tevent_req_error(req, err, location); 47 : } 48 : 49 22624245 : bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *status) 50 : { 51 198059 : enum tevent_req_state state; 52 198059 : uint64_t err; 53 : 54 22624245 : if (!tevent_req_is_error(req, &state, &err)) { 55 21885169 : return false; 56 : } 57 547234 : switch (state) { 58 737 : case TEVENT_REQ_TIMED_OUT: 59 737 : *status = NT_STATUS_IO_TIMEOUT; 60 737 : break; 61 0 : case TEVENT_REQ_NO_MEMORY: 62 0 : *status = NT_STATUS_NO_MEMORY; 63 0 : break; 64 546473 : case TEVENT_REQ_USER_ERROR: 65 546473 : if ((err >> 32) != TEVENT_NTERROR_MAGIC) { 66 0 : abort(); 67 : } 68 546473 : *status = NT_STATUS(err & 0xffffffff); 69 546473 : break; 70 24 : default: 71 24 : *status = NT_STATUS_INTERNAL_ERROR; 72 24 : break; 73 : } 74 541017 : return true; 75 : } 76 : 77 3446615 : NTSTATUS tevent_req_simple_recv_ntstatus(struct tevent_req *req) 78 : { 79 3446615 : NTSTATUS status = NT_STATUS_OK; 80 : 81 : /* 82 : * Ignore result of tevent_req_is_nterror, we're only interested in 83 : * the status 84 : */ 85 3446615 : tevent_req_is_nterror(req, &status); 86 3446615 : tevent_req_received(req); 87 3446615 : return status; 88 : } 89 : 90 685352 : void tevent_req_simple_finish_ntstatus(struct tevent_req *subreq, 91 : NTSTATUS subreq_status) 92 : { 93 685352 : struct tevent_req *req = tevent_req_callback_data( 94 : subreq, struct tevent_req); 95 : 96 685352 : TALLOC_FREE(subreq); 97 : 98 685352 : if (!NT_STATUS_IS_OK(subreq_status)) { 99 6452 : tevent_req_nterror(req, subreq_status); 100 6452 : return; 101 : } 102 678900 : tevent_req_done(req); 103 : } 104 : 105 1584556 : bool tevent_req_poll_ntstatus(struct tevent_req *req, 106 : struct tevent_context *ev, 107 : NTSTATUS *status) 108 : { 109 1584556 : bool ret = tevent_req_poll(req, ev); 110 1584556 : if (!ret) { 111 0 : *status = map_nt_error_from_unix_common(errno); 112 : } 113 1584556 : return ret; 114 : }