2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2001-2002
6 Copyright (C) James Myers 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "libcli/raw/libcliraw.h"
26 #define SETUP_REQUEST(cmd, wct, buflen) do { \
27 req = smbcli_request_setup(tree, cmd, wct, buflen); \
28 if (!req) return NULL; \
31 /****************************************************************************
32 Rename a file - async interface
33 ****************************************************************************/
34 struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree,
35 union smb_rename *parms)
37 struct smbcli_request *req = NULL;
39 switch (parms->generic.level) {
40 case RAW_RENAME_RENAME:
41 SETUP_REQUEST(SMBmv, 1, 0);
42 SSVAL(req->out.vwv, VWV(0), parms->rename.in.attrib);
43 smbcli_req_append_ascii4(req, parms->rename.in.pattern1, STR_TERMINATE);
44 smbcli_req_append_ascii4(req, parms->rename.in.pattern2, STR_TERMINATE);
47 case RAW_RENAME_NTRENAME:
48 SETUP_REQUEST(SMBntrename, 4, 0);
49 SSVAL(req->out.vwv, VWV(0), parms->ntrename.in.attrib);
50 SSVAL(req->out.vwv, VWV(1), parms->ntrename.in.flags);
51 SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.cluster_size);
52 smbcli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE);
53 smbcli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE);
57 if (!smbcli_request_send(req)) {
58 smbcli_request_destroy(req);
65 /****************************************************************************
66 Rename a file - sync interface
67 ****************************************************************************/
68 NTSTATUS smb_raw_rename(struct smbcli_tree *tree,
69 union smb_rename *parms)
71 struct smbcli_request *req = smb_raw_rename_send(tree, parms);
72 return smbcli_request_simple_recv(req);
76 /****************************************************************************
77 Delete a file - async interface
78 ****************************************************************************/
79 struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree,
80 struct smb_unlink *parms)
82 struct smbcli_request *req;
84 SETUP_REQUEST(SMBunlink, 1, 0);
86 SSVAL(req->out.vwv, VWV(0), parms->in.attrib);
87 smbcli_req_append_ascii4(req, parms->in.pattern, STR_TERMINATE);
89 if (!smbcli_request_send(req)) {
90 smbcli_request_destroy(req);
97 delete a file - sync interface
99 NTSTATUS smb_raw_unlink(struct smbcli_tree *tree,
100 struct smb_unlink *parms)
102 struct smbcli_request *req = smb_raw_unlink_send(tree, parms);
103 return smbcli_request_simple_recv(req);
107 /****************************************************************************
108 create a directory using TRANSACT2_MKDIR - async interface
109 ****************************************************************************/
110 static struct smbcli_request *smb_raw_t2mkdir_send(struct smbcli_tree *tree,
111 union smb_mkdir *parms)
113 struct smb_trans2 t2;
114 uint16_t setup = TRANSACT2_MKDIR;
116 struct smbcli_request *req;
119 mem_ctx = talloc_init("t2mkdir");
121 data_total = ea_list_size(parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);
128 t2.in.setup_count = 1;
129 t2.in.setup = &setup;
130 t2.in.params = data_blob_talloc(mem_ctx, NULL, 4);
131 t2.in.data = data_blob_talloc(mem_ctx, NULL, data_total);
133 SIVAL(t2.in.params.data, VWV(0), 0); /* reserved */
135 smbcli_blob_append_string(tree->session, mem_ctx,
136 &t2.in.params, parms->t2mkdir.in.path, STR_TERMINATE);
138 ea_put_list(t2.in.data.data, parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);
140 req = smb_raw_trans2_send(tree, &t2);
142 talloc_free(mem_ctx);
147 /****************************************************************************
148 Create a directory - async interface
149 ****************************************************************************/
150 struct smbcli_request *smb_raw_mkdir_send(struct smbcli_tree *tree,
151 union smb_mkdir *parms)
153 struct smbcli_request *req;
155 if (parms->generic.level == RAW_MKDIR_T2MKDIR) {
156 return smb_raw_t2mkdir_send(tree, parms);
159 if (parms->generic.level != RAW_MKDIR_MKDIR) {
163 SETUP_REQUEST(SMBmkdir, 0, 0);
165 smbcli_req_append_ascii4(req, parms->mkdir.in.path, STR_TERMINATE);
167 if (!smbcli_request_send(req)) {
174 /****************************************************************************
175 Create a directory - sync interface
176 ****************************************************************************/
177 NTSTATUS smb_raw_mkdir(struct smbcli_tree *tree,
178 union smb_mkdir *parms)
180 struct smbcli_request *req = smb_raw_mkdir_send(tree, parms);
181 return smbcli_request_simple_recv(req);
184 /****************************************************************************
185 Remove a directory - async interface
186 ****************************************************************************/
187 struct smbcli_request *smb_raw_rmdir_send(struct smbcli_tree *tree,
188 struct smb_rmdir *parms)
190 struct smbcli_request *req;
192 SETUP_REQUEST(SMBrmdir, 0, 0);
194 smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE);
196 if (!smbcli_request_send(req)) {
197 smbcli_request_destroy(req);
204 /****************************************************************************
205 Remove a directory - sync interface
206 ****************************************************************************/
207 NTSTATUS smb_raw_rmdir(struct smbcli_tree *tree,
208 struct smb_rmdir *parms)
210 struct smbcli_request *req = smb_raw_rmdir_send(tree, parms);
211 return smbcli_request_simple_recv(req);
216 Open a file using TRANSACT2_OPEN - async recv
218 static NTSTATUS smb_raw_nttrans_create_recv(struct smbcli_request *req,
220 union smb_open *parms)
223 struct smb_nttrans nt;
226 status = smb_raw_nttrans_recv(req, mem_ctx, &nt);
227 if (!NT_STATUS_IS_OK(status)) return status;
229 if (nt.out.params.length < 69) {
230 return NT_STATUS_INVALID_PARAMETER;
233 params = nt.out.params.data;
235 parms->ntcreatex.out.oplock_level = CVAL(params, 0);
236 parms->ntcreatex.out.fnum = SVAL(params, 2);
237 parms->ntcreatex.out.create_action = IVAL(params, 4);
238 parms->ntcreatex.out.create_time = smbcli_pull_nttime(params, 12);
239 parms->ntcreatex.out.access_time = smbcli_pull_nttime(params, 20);
240 parms->ntcreatex.out.write_time = smbcli_pull_nttime(params, 28);
241 parms->ntcreatex.out.change_time = smbcli_pull_nttime(params, 36);
242 parms->ntcreatex.out.attrib = IVAL(params, 44);
243 parms->ntcreatex.out.alloc_size = BVAL(params, 48);
244 parms->ntcreatex.out.size = BVAL(params, 56);
245 parms->ntcreatex.out.file_type = SVAL(params, 64);
246 parms->ntcreatex.out.ipc_state = SVAL(params, 66);
247 parms->ntcreatex.out.is_directory = CVAL(params, 68);
254 Open a file using NTTRANS CREATE - async send
256 static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tree,
257 union smb_open *parms)
259 struct smb_nttrans nt;
261 TALLOC_CTX *mem_ctx = talloc_new(tree);
263 DATA_BLOB sd_blob, ea_blob;
264 struct smbcli_request *req;
268 nt.in.max_param = 101;
270 nt.in.setup_count = 0;
271 nt.in.function = NT_TRANSACT_CREATE;
274 sd_blob = data_blob(NULL, 0);
275 ea_blob = data_blob(NULL, 0);
277 if (parms->ntcreatex.in.sec_desc) {
278 status = ndr_push_struct_blob(&sd_blob, mem_ctx,
279 parms->ntcreatex.in.sec_desc,
280 (ndr_push_flags_fn_t)ndr_push_security_descriptor);
281 if (!NT_STATUS_IS_OK(status)) {
282 talloc_free(mem_ctx);
287 if (parms->ntcreatex.in.ea_list) {
288 uint32_t ea_size = ea_list_size_chained(parms->ntcreatex.in.ea_list->num_eas,
289 parms->ntcreatex.in.ea_list->eas);
290 ea_blob = data_blob_talloc(mem_ctx, NULL, ea_size);
291 if (ea_blob.data == NULL) {
294 ea_put_list_chained(ea_blob.data,
295 parms->ntcreatex.in.ea_list->num_eas,
296 parms->ntcreatex.in.ea_list->eas);
299 nt.in.params = data_blob_talloc(mem_ctx, NULL, 54);
300 if (nt.in.params.data == NULL) {
301 talloc_free(mem_ctx);
305 /* build the parameter section */
306 params = nt.in.params.data;
308 SIVAL(params, 0, parms->ntcreatex.in.flags);
309 SIVAL(params, 4, parms->ntcreatex.in.root_fid);
310 SIVAL(params, 8, parms->ntcreatex.in.access_mask);
311 SBVAL(params, 12, parms->ntcreatex.in.alloc_size);
312 SIVAL(params, 20, parms->ntcreatex.in.file_attr);
313 SIVAL(params, 24, parms->ntcreatex.in.share_access);
314 SIVAL(params, 28, parms->ntcreatex.in.open_disposition);
315 SIVAL(params, 32, parms->ntcreatex.in.create_options);
316 SIVAL(params, 36, sd_blob.length);
317 SIVAL(params, 40, ea_blob.length);
318 SIVAL(params, 48, parms->ntcreatex.in.impersonation);
319 SCVAL(params, 52, parms->ntcreatex.in.security_flags);
320 SCVAL(params, 53, 0);
322 fname_len = smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,
323 parms->ntcreatex.in.fname, STR_TERMINATE);
325 SIVAL(nt.in.params.data, 44, fname_len);
327 /* build the data section */
328 nt.in.data = data_blob_talloc(mem_ctx, NULL, sd_blob.length + ea_blob.length);
329 memcpy(nt.in.data.data, sd_blob.data, sd_blob.length);
330 memcpy(nt.in.data.data+sd_blob.length, ea_blob.data, ea_blob.length);
332 /* send the request on its way */
333 req = smb_raw_nttrans_send(tree, &nt);
335 talloc_free(mem_ctx);
341 /****************************************************************************
342 Open a file using TRANSACT2_OPEN - async send
343 ****************************************************************************/
344 static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree,
345 union smb_open *parms)
347 struct smb_trans2 t2;
348 uint16_t setup = TRANSACT2_OPEN;
349 TALLOC_CTX *mem_ctx = talloc_init("smb_raw_t2open");
350 struct smbcli_request *req;
353 list_size = ea_list_size(parms->t2open.in.num_eas, parms->t2open.in.eas);
355 t2.in.max_param = 30;
360 t2.in.setup_count = 1;
361 t2.in.setup = &setup;
362 t2.in.params = data_blob_talloc(mem_ctx, NULL, 28);
363 t2.in.data = data_blob_talloc(mem_ctx, NULL, list_size);
365 SSVAL(t2.in.params.data, VWV(0), parms->t2open.in.flags);
366 SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode);
367 SSVAL(t2.in.params.data, VWV(2), parms->t2open.in.search_attrs);
368 SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs);
369 raw_push_dos_date(tree->session->transport,
370 t2.in.params.data, VWV(4), parms->t2open.in.write_time);
371 SSVAL(t2.in.params.data, VWV(6), parms->t2open.in.open_func);
372 SIVAL(t2.in.params.data, VWV(7), parms->t2open.in.size);
373 SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout);
374 SIVAL(t2.in.params.data, VWV(11), 0);
375 SSVAL(t2.in.params.data, VWV(13), 0);
377 smbcli_blob_append_string(tree->session, mem_ctx,
378 &t2.in.params, parms->t2open.in.fname,
381 ea_put_list(t2.in.data.data, parms->t2open.in.num_eas, parms->t2open.in.eas);
383 req = smb_raw_trans2_send(tree, &t2);
385 talloc_free(mem_ctx);
391 /****************************************************************************
392 Open a file using TRANSACT2_OPEN - async recv
393 ****************************************************************************/
394 static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
396 struct smbcli_transport *transport = req?req->transport:NULL;
397 struct smb_trans2 t2;
400 status = smb_raw_trans2_recv(req, mem_ctx, &t2);
401 if (!NT_STATUS_IS_OK(status)) return status;
403 if (t2.out.params.length < 30) {
404 return NT_STATUS_INFO_LENGTH_MISMATCH;
407 parms->t2open.out.fnum = SVAL(t2.out.params.data, VWV(0));
408 parms->t2open.out.attrib = SVAL(t2.out.params.data, VWV(1));
409 parms->t2open.out.write_time = raw_pull_dos_date3(transport, t2.out.params.data + VWV(2));
410 parms->t2open.out.size = IVAL(t2.out.params.data, VWV(4));
411 parms->t2open.out.access = SVAL(t2.out.params.data, VWV(6));
412 parms->t2open.out.ftype = SVAL(t2.out.params.data, VWV(7));
413 parms->t2open.out.devstate = SVAL(t2.out.params.data, VWV(8));
414 parms->t2open.out.action = SVAL(t2.out.params.data, VWV(9));
415 parms->t2open.out.file_id = SVAL(t2.out.params.data, VWV(10));
420 /****************************************************************************
421 Open a file - async send
422 ****************************************************************************/
423 struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms)
426 struct smbcli_request *req = NULL;
427 BOOL bigoffset = False;
429 switch (parms->generic.level) {
430 case RAW_OPEN_T2OPEN:
431 return smb_raw_t2open_send(tree, parms);
434 SETUP_REQUEST(SMBopen, 2, 0);
435 SSVAL(req->out.vwv, VWV(0), parms->openold.in.open_mode);
436 SSVAL(req->out.vwv, VWV(1), parms->openold.in.search_attrs);
437 smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE);
441 SETUP_REQUEST(SMBopenX, 15, 0);
442 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
443 SSVAL(req->out.vwv, VWV(1), 0);
444 SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags);
445 SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode);
446 SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs);
447 SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs);
448 raw_push_dos_date3(tree->session->transport,
449 req->out.vwv, VWV(6), parms->openx.in.write_time);
450 SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func);
451 SIVAL(req->out.vwv, VWV(9), parms->openx.in.size);
452 SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout);
453 SIVAL(req->out.vwv, VWV(13),0); /* reserved */
454 smbcli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE);
458 SETUP_REQUEST(SMBmknew, 3, 0);
459 SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib);
460 raw_push_dos_date3(tree->session->transport,
461 req->out.vwv, VWV(1), parms->mknew.in.write_time);
462 smbcli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE);
465 case RAW_OPEN_CREATE:
466 SETUP_REQUEST(SMBcreate, 3, 0);
467 SSVAL(req->out.vwv, VWV(0), parms->create.in.attrib);
468 raw_push_dos_date3(tree->session->transport,
469 req->out.vwv, VWV(1), parms->create.in.write_time);
470 smbcli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE);
474 SETUP_REQUEST(SMBctemp, 3, 0);
475 SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib);
476 raw_push_dos_date3(tree->session->transport,
477 req->out.vwv, VWV(1), parms->ctemp.in.write_time);
478 smbcli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE);
481 case RAW_OPEN_SPLOPEN:
482 SETUP_REQUEST(SMBsplopen, 2, 0);
483 SSVAL(req->out.vwv, VWV(0), parms->splopen.in.setup_length);
484 SSVAL(req->out.vwv, VWV(1), parms->splopen.in.mode);
487 case RAW_OPEN_NTCREATEX:
488 SETUP_REQUEST(SMBntcreateX, 24, 0);
489 SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE);
490 SSVAL(req->out.vwv, VWV(1),0);
491 SCVAL(req->out.vwv, VWV(2),0); /* padding */
492 SIVAL(req->out.vwv, 7, parms->ntcreatex.in.flags);
493 SIVAL(req->out.vwv, 11, parms->ntcreatex.in.root_fid);
494 SIVAL(req->out.vwv, 15, parms->ntcreatex.in.access_mask);
495 SBVAL(req->out.vwv, 19, parms->ntcreatex.in.alloc_size);
496 SIVAL(req->out.vwv, 27, parms->ntcreatex.in.file_attr);
497 SIVAL(req->out.vwv, 31, parms->ntcreatex.in.share_access);
498 SIVAL(req->out.vwv, 35, parms->ntcreatex.in.open_disposition);
499 SIVAL(req->out.vwv, 39, parms->ntcreatex.in.create_options);
500 SIVAL(req->out.vwv, 43, parms->ntcreatex.in.impersonation);
501 SCVAL(req->out.vwv, 47, parms->ntcreatex.in.security_flags);
503 smbcli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len);
504 SSVAL(req->out.vwv, 5, len);
507 case RAW_OPEN_NTTRANS_CREATE:
508 return smb_raw_nttrans_create_send(tree, parms);
511 case RAW_OPEN_OPENX_READX:
512 SETUP_REQUEST(SMBopenX, 15, 0);
513 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
514 SSVAL(req->out.vwv, VWV(1), 0);
515 SSVAL(req->out.vwv, VWV(2), parms->openxreadx.in.flags);
516 SSVAL(req->out.vwv, VWV(3), parms->openxreadx.in.open_mode);
517 SSVAL(req->out.vwv, VWV(4), parms->openxreadx.in.search_attrs);
518 SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.file_attrs);
519 raw_push_dos_date3(tree->session->transport,
520 req->out.vwv, VWV(6), parms->openxreadx.in.write_time);
521 SSVAL(req->out.vwv, VWV(8), parms->openxreadx.in.open_func);
522 SIVAL(req->out.vwv, VWV(9), parms->openxreadx.in.size);
523 SIVAL(req->out.vwv, VWV(11),parms->openxreadx.in.timeout);
524 SIVAL(req->out.vwv, VWV(13),0);
525 smbcli_req_append_string(req, parms->openxreadx.in.fname, STR_TERMINATE);
527 if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) {
531 smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0);
533 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
534 SSVAL(req->out.vwv, VWV(1), 0);
535 SSVAL(req->out.vwv, VWV(2), 0);
536 SIVAL(req->out.vwv, VWV(3), parms->openxreadx.in.offset);
537 SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.maxcnt & 0xFFFF);
538 SSVAL(req->out.vwv, VWV(6), parms->openxreadx.in.mincnt);
539 SIVAL(req->out.vwv, VWV(7), parms->openxreadx.in.maxcnt >> 16);
540 SSVAL(req->out.vwv, VWV(9), parms->openxreadx.in.remaining);
542 SIVAL(req->out.vwv, VWV(10),parms->openxreadx.in.offset>>32);
547 if (!smbcli_request_send(req)) {
548 smbcli_request_destroy(req);
555 /****************************************************************************
556 Open a file - async recv
557 ****************************************************************************/
558 NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
562 if (!smbcli_request_receive(req) ||
563 smbcli_request_is_error(req)) {
567 switch (parms->openold.level) {
568 case RAW_OPEN_T2OPEN:
569 return smb_raw_t2open_recv(req, mem_ctx, parms);
572 SMBCLI_CHECK_WCT(req, 7);
573 parms->openold.out.fnum = SVAL(req->in.vwv, VWV(0));
574 parms->openold.out.attrib = SVAL(req->in.vwv, VWV(1));
575 parms->openold.out.write_time = raw_pull_dos_date3(req->transport,
576 req->in.vwv + VWV(2));
577 parms->openold.out.size = IVAL(req->in.vwv, VWV(4));
578 parms->openold.out.rmode = SVAL(req->in.vwv, VWV(6));
582 SMBCLI_CHECK_MIN_WCT(req, 15);
583 parms->openx.out.fnum = SVAL(req->in.vwv, VWV(2));
584 parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3));
585 parms->openx.out.write_time = raw_pull_dos_date3(req->transport,
586 req->in.vwv + VWV(4));
587 parms->openx.out.size = IVAL(req->in.vwv, VWV(6));
588 parms->openx.out.access = SVAL(req->in.vwv, VWV(8));
589 parms->openx.out.ftype = SVAL(req->in.vwv, VWV(9));
590 parms->openx.out.devstate = SVAL(req->in.vwv, VWV(10));
591 parms->openx.out.action = SVAL(req->in.vwv, VWV(11));
592 parms->openx.out.unique_fid = IVAL(req->in.vwv, VWV(12));
593 if (req->in.wct >= 19) {
594 parms->openx.out.access_mask = IVAL(req->in.vwv, VWV(15));
595 parms->openx.out.unknown = IVAL(req->in.vwv, VWV(17));
597 parms->openx.out.access_mask = 0;
598 parms->openx.out.unknown = 0;
603 SMBCLI_CHECK_WCT(req, 1);
604 parms->mknew.out.fnum = SVAL(req->in.vwv, VWV(0));
607 case RAW_OPEN_CREATE:
608 SMBCLI_CHECK_WCT(req, 1);
609 parms->create.out.fnum = SVAL(req->in.vwv, VWV(0));
613 SMBCLI_CHECK_WCT(req, 1);
614 parms->ctemp.out.fnum = SVAL(req->in.vwv, VWV(0));
615 smbcli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII);
618 case RAW_OPEN_SPLOPEN:
619 SMBCLI_CHECK_WCT(req, 1);
620 parms->splopen.out.fnum = SVAL(req->in.vwv, VWV(0));
623 case RAW_OPEN_NTCREATEX:
624 SMBCLI_CHECK_MIN_WCT(req, 34);
625 parms->ntcreatex.out.oplock_level = CVAL(req->in.vwv, 4);
626 parms->ntcreatex.out.fnum = SVAL(req->in.vwv, 5);
627 parms->ntcreatex.out.create_action = IVAL(req->in.vwv, 7);
628 parms->ntcreatex.out.create_time = smbcli_pull_nttime(req->in.vwv, 11);
629 parms->ntcreatex.out.access_time = smbcli_pull_nttime(req->in.vwv, 19);
630 parms->ntcreatex.out.write_time = smbcli_pull_nttime(req->in.vwv, 27);
631 parms->ntcreatex.out.change_time = smbcli_pull_nttime(req->in.vwv, 35);
632 parms->ntcreatex.out.attrib = IVAL(req->in.vwv, 43);
633 parms->ntcreatex.out.alloc_size = BVAL(req->in.vwv, 47);
634 parms->ntcreatex.out.size = BVAL(req->in.vwv, 55);
635 parms->ntcreatex.out.file_type = SVAL(req->in.vwv, 63);
636 parms->ntcreatex.out.ipc_state = SVAL(req->in.vwv, 65);
637 parms->ntcreatex.out.is_directory = CVAL(req->in.vwv, 67);
640 case RAW_OPEN_NTTRANS_CREATE:
641 return smb_raw_nttrans_create_recv(req, mem_ctx, parms);
643 case RAW_OPEN_OPENX_READX:
644 SMBCLI_CHECK_MIN_WCT(req, 15);
645 parms->openxreadx.out.fnum = SVAL(req->in.vwv, VWV(2));
646 parms->openxreadx.out.attrib = SVAL(req->in.vwv, VWV(3));
647 parms->openxreadx.out.write_time = raw_pull_dos_date3(req->transport,
648 req->in.vwv + VWV(4));
649 parms->openxreadx.out.size = IVAL(req->in.vwv, VWV(6));
650 parms->openxreadx.out.access = SVAL(req->in.vwv, VWV(8));
651 parms->openxreadx.out.ftype = SVAL(req->in.vwv, VWV(9));
652 parms->openxreadx.out.devstate = SVAL(req->in.vwv, VWV(10));
653 parms->openxreadx.out.action = SVAL(req->in.vwv, VWV(11));
654 parms->openxreadx.out.unique_fid = IVAL(req->in.vwv, VWV(12));
655 if (req->in.wct >= 19) {
656 parms->openxreadx.out.access_mask = IVAL(req->in.vwv, VWV(15));
657 parms->openxreadx.out.unknown = IVAL(req->in.vwv, VWV(17));
659 parms->openxreadx.out.access_mask = 0;
660 parms->openxreadx.out.unknown = 0;
663 status = smbcli_chained_advance(req);
664 if (!NT_STATUS_IS_OK(status)) {
668 SMBCLI_CHECK_WCT(req, 12);
669 parms->openxreadx.out.remaining = SVAL(req->in.vwv, VWV(2));
670 parms->openxreadx.out.compaction_mode = SVAL(req->in.vwv, VWV(3));
671 parms->openxreadx.out.nread = SVAL(req->in.vwv, VWV(5));
672 if (parms->openxreadx.out.nread >
673 MAX(parms->openxreadx.in.mincnt, parms->openxreadx.in.maxcnt) ||
674 !smbcli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)),
675 parms->openxreadx.out.nread,
676 parms->openxreadx.out.data)) {
677 req->status = NT_STATUS_BUFFER_TOO_SMALL;
683 return smbcli_request_destroy(req);
687 /****************************************************************************
688 Open a file - sync interface
689 ****************************************************************************/
690 NTSTATUS smb_raw_open(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms)
692 struct smbcli_request *req = smb_raw_open_send(tree, parms);
693 return smb_raw_open_recv(req, mem_ctx, parms);
697 /****************************************************************************
698 Close a file - async send
699 ****************************************************************************/
700 struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms)
702 struct smbcli_request *req = NULL;
704 switch (parms->generic.level) {
705 case RAW_CLOSE_CLOSE:
706 SETUP_REQUEST(SMBclose, 3, 0);
707 SSVAL(req->out.vwv, VWV(0), parms->close.in.fnum);
708 raw_push_dos_date3(tree->session->transport,
709 req->out.vwv, VWV(1), parms->close.in.write_time);
712 case RAW_CLOSE_SPLCLOSE:
713 SETUP_REQUEST(SMBsplclose, 3, 0);
714 SSVAL(req->out.vwv, VWV(0), parms->splclose.in.fnum);
715 SIVAL(req->out.vwv, VWV(1), 0); /* reserved */
719 if (!req) return NULL;
721 if (!smbcli_request_send(req)) {
722 smbcli_request_destroy(req);
730 /****************************************************************************
731 Close a file - sync interface
732 ****************************************************************************/
733 NTSTATUS smb_raw_close(struct smbcli_tree *tree, union smb_close *parms)
735 struct smbcli_request *req = smb_raw_close_send(tree, parms);
736 return smbcli_request_simple_recv(req);
740 /****************************************************************************
741 Locking calls - async interface
742 ****************************************************************************/
743 struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_lock *parms)
745 struct smbcli_request *req = NULL;
747 switch (parms->generic.level) {
749 SETUP_REQUEST(SMBlock, 5, 0);
750 SSVAL(req->out.vwv, VWV(0), parms->lock.in.fnum);
751 SIVAL(req->out.vwv, VWV(1), parms->lock.in.count);
752 SIVAL(req->out.vwv, VWV(3), parms->lock.in.offset);
755 case RAW_LOCK_UNLOCK:
756 SETUP_REQUEST(SMBunlock, 5, 0);
757 SSVAL(req->out.vwv, VWV(0), parms->unlock.in.fnum);
758 SIVAL(req->out.vwv, VWV(1), parms->unlock.in.count);
759 SIVAL(req->out.vwv, VWV(3), parms->unlock.in.offset);
762 case RAW_LOCK_LOCKX: {
763 struct smb_lock_entry *lockp;
764 uint_t lck_size = (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES)? 20 : 10;
765 uint_t lock_count = parms->lockx.in.ulock_cnt + parms->lockx.in.lock_cnt;
768 SETUP_REQUEST(SMBlockingX, 8, lck_size * lock_count);
769 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
770 SSVAL(req->out.vwv, VWV(1), 0);
771 SSVAL(req->out.vwv, VWV(2), parms->lockx.in.fnum);
772 SSVAL(req->out.vwv, VWV(3), parms->lockx.in.mode);
773 SIVAL(req->out.vwv, VWV(4), parms->lockx.in.timeout);
774 SSVAL(req->out.vwv, VWV(6), parms->lockx.in.ulock_cnt);
775 SSVAL(req->out.vwv, VWV(7), parms->lockx.in.lock_cnt);
777 /* copy in all the locks */
778 lockp = &parms->lockx.in.locks[0];
779 for (i = 0; i < lock_count; i++) {
780 uint8_t *p = req->out.data + lck_size * i;
781 SSVAL(p, 0, lockp[i].pid);
782 if (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES) {
783 SSVAL(p, 2, 0); /* reserved */
784 SIVAL(p, 4, lockp[i].offset>>32);
785 SIVAL(p, 8, lockp[i].offset);
786 SIVAL(p, 12, lockp[i].count>>32);
787 SIVAL(p, 16, lockp[i].count);
789 SIVAL(p, 2, lockp[i].offset);
790 SIVAL(p, 6, lockp[i].count);
796 if (!smbcli_request_send(req)) {
797 smbcli_request_destroy(req);
804 /****************************************************************************
805 Locking calls - sync interface
806 ****************************************************************************/
807 NTSTATUS smb_raw_lock(struct smbcli_tree *tree, union smb_lock *parms)
809 struct smbcli_request *req = smb_raw_lock_send(tree, parms);
810 return smbcli_request_simple_recv(req);
814 /****************************************************************************
815 Check for existence of a dir - async send
816 ****************************************************************************/
817 struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, struct smb_chkpath *parms)
819 struct smbcli_request *req;
821 SETUP_REQUEST(SMBchkpth, 0, 0);
823 smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE);
825 if (!smbcli_request_send(req)) {
826 smbcli_request_destroy(req);
833 /****************************************************************************
834 Check for existence of a dir - sync interface
835 ****************************************************************************/
836 NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, struct smb_chkpath *parms)
838 struct smbcli_request *req = smb_raw_chkpath_send(tree, parms);
839 return smbcli_request_simple_recv(req);
845 /****************************************************************************
846 flush a file - async send
847 a flush to fnum 0xFFFF will flush all files
848 ****************************************************************************/
849 struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, struct smb_flush *parms)
851 struct smbcli_request *req;
853 SETUP_REQUEST(SMBflush, 1, 0);
854 SSVAL(req->out.vwv, VWV(0), parms->in.fnum);
856 if (!smbcli_request_send(req)) {
857 smbcli_request_destroy(req);
865 /****************************************************************************
866 flush a file - sync interface
867 ****************************************************************************/
868 NTSTATUS smb_raw_flush(struct smbcli_tree *tree, struct smb_flush *parms)
870 struct smbcli_request *req = smb_raw_flush_send(tree, parms);
871 return smbcli_request_simple_recv(req);
875 /****************************************************************************
876 seek a file - async send
877 ****************************************************************************/
878 struct smbcli_request *smb_raw_seek_send(struct smbcli_tree *tree,
879 struct smb_seek *parms)
881 struct smbcli_request *req;
883 SETUP_REQUEST(SMBlseek, 4, 0);
885 SSVAL(req->out.vwv, VWV(0), parms->in.fnum);
886 SSVAL(req->out.vwv, VWV(1), parms->in.mode);
887 SIVALS(req->out.vwv, VWV(2), parms->in.offset);
889 if (!smbcli_request_send(req)) {
890 smbcli_request_destroy(req);
896 /****************************************************************************
897 seek a file - async receive
898 ****************************************************************************/
899 NTSTATUS smb_raw_seek_recv(struct smbcli_request *req,
900 struct smb_seek *parms)
902 if (!smbcli_request_receive(req) ||
903 smbcli_request_is_error(req)) {
904 return smbcli_request_destroy(req);
907 SMBCLI_CHECK_WCT(req, 2);
908 parms->out.offset = IVAL(req->in.vwv, VWV(0));
911 return smbcli_request_destroy(req);
915 seek a file - sync interface
917 NTSTATUS smb_raw_seek(struct smbcli_tree *tree,
918 struct smb_seek *parms)
920 struct smbcli_request *req = smb_raw_seek_send(tree, parms);
921 return smb_raw_seek_recv(req, parms);