/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- ntvfs_request_create
- ntvfs_async_state_push
- ntvfs_async_state_pop
- ntvfs_handle_new
- ntvfs_handle_set_backend_data
- ntvfs_handle_get_backend_data
- ntvfs_handle_remove_backend_data
- ntvfs_handle_search_by_wire_key
- ntvfs_handle_get_wire_key
- ntvfs_set_handle_callbacks
1 /*
2 Unix SMB/CIFS implementation.
3 NTVFS utility code
4 Copyright (C) Stefan Metzmacher 2004
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 this implements common utility functions that many NTVFS backends may wish to use
21 */
22
23 #include "includes.h"
24 #include "../lib/util/dlinklist.h"
25 #include "ntvfs/ntvfs.h"
26
27
28 struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
29 struct auth_session_info *session_info,
30 uint16_t smbpid,
31 struct timeval request_time,
32 void *private_data,
33 void (*send_fn)(struct ntvfs_request *),
34 uint32_t state)
35 {
36 struct ntvfs_request *req;
37 struct ntvfs_async_state *async;
38
39 req = talloc(mem_ctx, struct ntvfs_request);
40 if (!req) return NULL;
41 req->ctx = ctx;
42 req->async_states = NULL;
43 req->session_info = session_info;
44 req->smbpid = smbpid;
45 req->client_caps = ctx->client_caps;
46 req->statistics.request_time = request_time;
47
48 async = talloc(req, struct ntvfs_async_state);
49 if (!async) goto failed;
50
51 async->state = state;
52 async->private_data = private_data;
53 async->send_fn = send_fn;
54 async->status = NT_STATUS_INTERNAL_ERROR;
55 async->ntvfs = NULL;
56
57 DLIST_ADD(req->async_states, async);
58
59 return req;
60 failed:
61 talloc_free(req);
62 return NULL;
63 }
64
65 NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs,
/* [<][>][^][v][top][bottom][index][help] */
66 struct ntvfs_request *req,
67 void *private_data,
68 void (*send_fn)(struct ntvfs_request *))
69 {
70 struct ntvfs_async_state *async;
71
72 async = talloc(req, struct ntvfs_async_state);
73 NT_STATUS_HAVE_NO_MEMORY(async);
74
75 async->state = req->async_states->state;
76 async->private_data = private_data;
77 async->send_fn = send_fn;
78 async->status = NT_STATUS_INTERNAL_ERROR;
79
80 async->ntvfs = ntvfs;
81
82 DLIST_ADD(req->async_states, async);
83
84 return NT_STATUS_OK;
85 }
86
87 void ntvfs_async_state_pop(struct ntvfs_request *req)
/* [<][>][^][v][top][bottom][index][help] */
88 {
89 struct ntvfs_async_state *async;
90
91 async = req->async_states;
92
93 DLIST_REMOVE(req->async_states, async);
94
95 req->async_states->state = async->state;
96 req->async_states->status = async->status;
97
98 talloc_free(async);
99 }
100
101 NTSTATUS ntvfs_handle_new(struct ntvfs_module_context *ntvfs,
/* [<][>][^][v][top][bottom][index][help] */
102 struct ntvfs_request *req,
103 struct ntvfs_handle **h)
104 {
105 if (!ntvfs->ctx->handles.create_new) {
106 return NT_STATUS_NOT_IMPLEMENTED;
107 }
108 return ntvfs->ctx->handles.create_new(ntvfs->ctx->handles.private_data, req, h);
109 }
110
111 NTSTATUS ntvfs_handle_set_backend_data(struct ntvfs_handle *h,
/* [<][>][^][v][top][bottom][index][help] */
112 struct ntvfs_module_context *ntvfs,
113 TALLOC_CTX *private_data)
114 {
115 struct ntvfs_handle_data *d;
116 bool first_time = h->backend_data?false:true;
117
118 for (d=h->backend_data; d; d = d->next) {
119 if (d->owner != ntvfs) continue;
120 d->private_data = talloc_steal(d, private_data);
121 return NT_STATUS_OK;
122 }
123
124 d = talloc(h, struct ntvfs_handle_data);
125 NT_STATUS_HAVE_NO_MEMORY(d);
126 d->owner = ntvfs;
127 d->private_data = talloc_steal(d, private_data);
128
129 DLIST_ADD(h->backend_data, d);
130
131 if (first_time) {
132 NTSTATUS status;
133 status = h->ctx->handles.make_valid(h->ctx->handles.private_data, h);
134 NT_STATUS_NOT_OK_RETURN(status);
135 }
136
137 return NT_STATUS_OK;
138 }
139
140 void *ntvfs_handle_get_backend_data(struct ntvfs_handle *h,
/* [<][>][^][v][top][bottom][index][help] */
141 struct ntvfs_module_context *ntvfs)
142 {
143 struct ntvfs_handle_data *d;
144
145 for (d=h->backend_data; d; d = d->next) {
146 if (d->owner != ntvfs) continue;
147 return d->private_data;
148 }
149
150 return NULL;
151 }
152
153 void ntvfs_handle_remove_backend_data(struct ntvfs_handle *h,
/* [<][>][^][v][top][bottom][index][help] */
154 struct ntvfs_module_context *ntvfs)
155 {
156 struct ntvfs_handle_data *d,*n;
157
158 for (d=h->backend_data; d; d = n) {
159 n = d->next;
160 if (d->owner != ntvfs) continue;
161 DLIST_REMOVE(h->backend_data, d);
162 talloc_free(d);
163 d = NULL;
164 }
165
166 if (h->backend_data) return;
167
168 /* if there's no backend_data anymore, destroy the handle */
169 h->ctx->handles.destroy(h->ctx->handles.private_data, h);
170 }
171
172 struct ntvfs_handle *ntvfs_handle_search_by_wire_key(struct ntvfs_module_context *ntvfs,
/* [<][>][^][v][top][bottom][index][help] */
173 struct ntvfs_request *req,
174 const DATA_BLOB *key)
175 {
176 if (!ntvfs->ctx->handles.search_by_wire_key) {
177 return NULL;
178 }
179 return ntvfs->ctx->handles.search_by_wire_key(ntvfs->ctx->handles.private_data, req, key);
180 }
181
182 DATA_BLOB ntvfs_handle_get_wire_key(struct ntvfs_handle *h, TALLOC_CTX *mem_ctx)
/* [<][>][^][v][top][bottom][index][help] */
183 {
184 return h->ctx->handles.get_wire_key(h->ctx->handles.private_data, h, mem_ctx);
185 }
186
187 NTSTATUS ntvfs_set_handle_callbacks(struct ntvfs_context *ntvfs,
/* [<][>][^][v][top][bottom][index][help] */
188 NTSTATUS (*create_new)(void *private_data, struct ntvfs_request *req, struct ntvfs_handle **h),
189 NTSTATUS (*make_valid)(void *private_data, struct ntvfs_handle *h),
190 void (*destroy)(void *private_data, struct ntvfs_handle *h),
191 struct ntvfs_handle *(*search_by_wire_key)(void *private_data, struct ntvfs_request *req, const DATA_BLOB *key),
192 DATA_BLOB (*get_wire_key)(void *private_data, struct ntvfs_handle *handle, TALLOC_CTX *mem_ctx),
193 void *private_data)
194 {
195 ntvfs->handles.create_new = create_new;
196 ntvfs->handles.make_valid = make_valid;
197 ntvfs->handles.destroy = destroy;
198 ntvfs->handles.search_by_wire_key = search_by_wire_key;
199 ntvfs->handles.get_wire_key = get_wire_key;
200 ntvfs->handles.private_data = private_data;
201 return NT_STATUS_OK;
202 }