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 3 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, see <http://www.gnu.org/licenses/>.
20 this implements common utility functions that many NTVFS backends may wish to use
24 #include "lib/util/dlinklist.h"
25 #include "ntvfs/ntvfs.h"
28 struct ntvfs_request
*ntvfs_request_create(struct ntvfs_context
*ctx
, TALLOC_CTX
*mem_ctx
,
29 struct auth_session_info
*session_info
,
31 struct timeval request_time
,
33 void (*send_fn
)(struct ntvfs_request
*),
36 struct ntvfs_request
*req
;
37 struct ntvfs_async_state
*async
;
39 req
= talloc(mem_ctx
, struct ntvfs_request
);
40 if (!req
) return NULL
;
42 req
->async_states
= NULL
;
43 req
->session_info
= session_info
;
45 req
->client_caps
= ctx
->client_caps
;
46 req
->statistics
.request_time
= request_time
;
48 async
= talloc(req
, struct ntvfs_async_state
);
49 if (!async
) goto failed
;
52 async
->private_data
= private_data
;
53 async
->send_fn
= send_fn
;
54 async
->status
= NT_STATUS_INTERNAL_ERROR
;
57 DLIST_ADD(req
->async_states
, async
);
65 NTSTATUS
ntvfs_async_state_push(struct ntvfs_module_context
*ntvfs
,
66 struct ntvfs_request
*req
,
68 void (*send_fn
)(struct ntvfs_request
*))
70 struct ntvfs_async_state
*async
;
72 async
= talloc(req
, struct ntvfs_async_state
);
73 NT_STATUS_HAVE_NO_MEMORY(async
);
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
;
82 DLIST_ADD(req
->async_states
, async
);
87 void ntvfs_async_state_pop(struct ntvfs_request
*req
)
89 struct ntvfs_async_state
*async
;
91 async
= req
->async_states
;
93 DLIST_REMOVE(req
->async_states
, async
);
95 req
->async_states
->state
= async
->state
;
96 req
->async_states
->status
= async
->status
;
101 NTSTATUS
ntvfs_handle_new(struct ntvfs_module_context
*ntvfs
,
102 struct ntvfs_request
*req
,
103 struct ntvfs_handle
**h
)
105 if (!ntvfs
->ctx
->handles
.create_new
) {
106 return NT_STATUS_NOT_IMPLEMENTED
;
108 return ntvfs
->ctx
->handles
.create_new(ntvfs
->ctx
->handles
.private_data
, req
, h
);
111 NTSTATUS
ntvfs_handle_set_backend_data(struct ntvfs_handle
*h
,
112 struct ntvfs_module_context
*ntvfs
,
113 TALLOC_CTX
*private_data
)
115 struct ntvfs_handle_data
*d
;
116 bool first_time
= h
->backend_data
?false:true;
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
);
124 d
= talloc(h
, struct ntvfs_handle_data
);
125 NT_STATUS_HAVE_NO_MEMORY(d
);
127 d
->private_data
= talloc_steal(d
, private_data
);
129 DLIST_ADD(h
->backend_data
, d
);
133 status
= h
->ctx
->handles
.make_valid(h
->ctx
->handles
.private_data
, h
);
134 NT_STATUS_NOT_OK_RETURN(status
);
140 void *ntvfs_handle_get_backend_data(struct ntvfs_handle
*h
,
141 struct ntvfs_module_context
*ntvfs
)
143 struct ntvfs_handle_data
*d
;
145 for (d
=h
->backend_data
; d
; d
= d
->next
) {
146 if (d
->owner
!= ntvfs
) continue;
147 return d
->private_data
;
153 void ntvfs_handle_remove_backend_data(struct ntvfs_handle
*h
,
154 struct ntvfs_module_context
*ntvfs
)
156 struct ntvfs_handle_data
*d
,*n
;
158 for (d
=h
->backend_data
; d
; d
= n
) {
160 if (d
->owner
!= ntvfs
) continue;
161 DLIST_REMOVE(h
->backend_data
, d
);
166 if (h
->backend_data
) return;
168 /* if there's no backend_data anymore, destroy the handle */
169 h
->ctx
->handles
.destroy(h
->ctx
->handles
.private_data
, h
);
172 struct ntvfs_handle
*ntvfs_handle_search_by_wire_key(struct ntvfs_module_context
*ntvfs
,
173 struct ntvfs_request
*req
,
174 const DATA_BLOB
*key
)
176 if (!ntvfs
->ctx
->handles
.search_by_wire_key
) {
179 return ntvfs
->ctx
->handles
.search_by_wire_key(ntvfs
->ctx
->handles
.private_data
, req
, key
);
182 DATA_BLOB
ntvfs_handle_get_wire_key(struct ntvfs_handle
*h
, TALLOC_CTX
*mem_ctx
)
184 return h
->ctx
->handles
.get_wire_key(h
->ctx
->handles
.private_data
, h
, mem_ctx
);
187 NTSTATUS
ntvfs_set_handle_callbacks(struct ntvfs_context
*ntvfs
,
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
),
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
;