2 Unix SMB/CIFS implementation.
4 Copyright (C) Stefan Metzmacher 2004
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 2 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 this implements common utility functions that many NTVFS backends may wish to use
25 #include "dlinklist.h"
26 #include "ntvfs/ntvfs.h"
29 _PUBLIC_ struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, TALLOC_CTX *mem_ctx,
30 struct auth_session_info *session_info,
31 uint16_t smbpid, uint16_t smbmid,
32 struct timeval request_time,
34 void (*send_fn)(struct ntvfs_request *),
37 struct ntvfs_request *req;
38 struct ntvfs_async_state *async;
40 req = talloc(mem_ctx, struct ntvfs_request);
41 if (!req) return NULL;
43 req->async_states = NULL;
44 req->session_info = session_info;
47 req->statistics.request_time = request_time;
49 async = talloc(req, struct ntvfs_async_state);
50 if (!async) goto failed;
53 async->private_data = private_data;
54 async->send_fn = send_fn;
55 async->status = NT_STATUS_INTERNAL_ERROR;
58 DLIST_ADD(req->async_states, async);
66 _PUBLIC_ NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs,
67 struct ntvfs_request *req,
69 void (*send_fn)(struct ntvfs_request *))
71 struct ntvfs_async_state *async;
73 async = talloc(req, struct ntvfs_async_state);
74 NT_STATUS_HAVE_NO_MEMORY(async);
76 async->state = req->async_states->state;
77 async->private_data = private_data;
78 async->send_fn = send_fn;
79 async->status = NT_STATUS_INTERNAL_ERROR;
83 DLIST_ADD(req->async_states, async);
88 _PUBLIC_ void ntvfs_async_state_pop(struct ntvfs_request *req)
90 struct ntvfs_async_state *async;
92 async = req->async_states;
94 DLIST_REMOVE(req->async_states, async);
96 req->async_states->state = async->state;
97 req->async_states->status = async->status;
102 _PUBLIC_ NTSTATUS ntvfs_handle_new(struct ntvfs_module_context *ntvfs,
103 struct ntvfs_request *req,
104 struct ntvfs_handle **h)
106 if (!ntvfs->ctx->handles.create_new) {
107 return NT_STATUS_NOT_IMPLEMENTED;
109 return ntvfs->ctx->handles.create_new(ntvfs->ctx->handles.private_data, req, h);
112 _PUBLIC_ NTSTATUS ntvfs_handle_set_backend_data(struct ntvfs_handle *h,
113 struct ntvfs_module_context *ntvfs,
114 TALLOC_CTX *private_data)
116 struct ntvfs_handle_data *d;
117 BOOL first_time = h->backend_data?False:True;
119 for (d=h->backend_data; d; d = d->next) {
120 if (d->owner != ntvfs) continue;
121 d->private_data = talloc_steal(d, private_data);
125 d = talloc(h, struct ntvfs_handle_data);
126 NT_STATUS_HAVE_NO_MEMORY(d);
128 d->private_data = talloc_steal(d, private_data);
130 DLIST_ADD(h->backend_data, d);
134 status = h->ctx->handles.make_valid(h->ctx->handles.private_data, h);
135 NT_STATUS_NOT_OK_RETURN(status);
141 _PUBLIC_ void *ntvfs_handle_get_backend_data(struct ntvfs_handle *h,
142 struct ntvfs_module_context *ntvfs)
144 struct ntvfs_handle_data *d;
146 for (d=h->backend_data; d; d = d->next) {
147 if (d->owner != ntvfs) continue;
148 return d->private_data;
154 _PUBLIC_ void ntvfs_handle_remove_backend_data(struct ntvfs_handle *h,
155 struct ntvfs_module_context *ntvfs)
157 struct ntvfs_handle_data *d,*n;
159 for (d=h->backend_data; d; d = n) {
161 if (d->owner != ntvfs) continue;
162 DLIST_REMOVE(h->backend_data, d);
167 if (h->backend_data) return;
169 /* if there's no backend_data anymore, destroy the handle */
170 h->ctx->handles.destroy(h->ctx->handles.private_data, h);
173 _PUBLIC_ struct ntvfs_handle *ntvfs_handle_search_by_wire_key(struct ntvfs_module_context *ntvfs,
174 struct ntvfs_request *req,
175 const DATA_BLOB *key)
177 if (!ntvfs->ctx->handles.search_by_wire_key) {
180 return ntvfs->ctx->handles.search_by_wire_key(ntvfs->ctx->handles.private_data, req, key);
183 _PUBLIC_ DATA_BLOB ntvfs_handle_get_wire_key(struct ntvfs_handle *h, TALLOC_CTX *mem_ctx)
185 return h->ctx->handles.get_wire_key(h->ctx->handles.private_data, h, mem_ctx);
188 _PUBLIC_ NTSTATUS ntvfs_set_handle_callbacks(struct ntvfs_context *ntvfs,
189 NTSTATUS (*create_new)(void *private_data, struct ntvfs_request *req, struct ntvfs_handle **h),
190 NTSTATUS (*make_valid)(void *private_data, struct ntvfs_handle *h),
191 void (*destroy)(void *private_data, struct ntvfs_handle *h),
192 struct ntvfs_handle *(*search_by_wire_key)(void *private_data, struct ntvfs_request *req, const DATA_BLOB *key),
193 DATA_BLOB (*get_wire_key)(void *private_data, struct ntvfs_handle *handle, TALLOC_CTX *mem_ctx),
196 ntvfs->handles.create_new = create_new;
197 ntvfs->handles.make_valid = make_valid;
198 ntvfs->handles.destroy = destroy;
199 ntvfs->handles.search_by_wire_key = search_by_wire_key;
200 ntvfs->handles.get_wire_key = get_wire_key;
201 ntvfs->handles.private_data = private_data;