r1983: a completely new implementation of talloc
[jelmer/samba4-debian.git] / source / libcli / raw / rawfile.c
1 /* 
2    Unix SMB/CIFS implementation.
3    client file operations
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Jeremy Allison 2001-2002
6    Copyright (C) James Myers 2003
7    
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.
12    
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.
17    
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.
21 */
22
23 #include "includes.h"
24
25 #define SETUP_REQUEST(cmd, wct, buflen) do { \
26         req = smbcli_request_setup(tree, cmd, wct, buflen); \
27         if (!req) return NULL; \
28 } while (0)
29
30
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)
36 {
37         struct smbcli_request *req = NULL; 
38
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);
45                 break;
46
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);
54                 break;
55         }
56
57         if (!smbcli_request_send(req)) {
58                 smbcli_request_destroy(req);
59                 return NULL;
60         }
61
62         return req;
63 }
64
65 /****************************************************************************
66  Rename a file - sync interface
67 ****************************************************************************/
68 NTSTATUS smb_raw_rename(struct smbcli_tree *tree,
69                         union smb_rename *parms)
70 {
71         struct smbcli_request *req = smb_raw_rename_send(tree, parms);
72         return smbcli_request_simple_recv(req);
73 }
74
75
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)
81 {
82         struct smbcli_request *req; 
83
84         SETUP_REQUEST(SMBunlink, 1, 0);
85
86         SSVAL(req->out.vwv, VWV(0), parms->in.attrib);
87         smbcli_req_append_ascii4(req, parms->in.pattern, STR_TERMINATE);
88
89         if (!smbcli_request_send(req)) {
90                 smbcli_request_destroy(req);
91                 return NULL;
92         }
93         return req;
94 }
95
96 /*
97   delete a file - sync interface
98 */
99 NTSTATUS smb_raw_unlink(struct smbcli_tree *tree,
100                         struct smb_unlink *parms)
101 {
102         struct smbcli_request *req = smb_raw_unlink_send(tree, parms);
103         return smbcli_request_simple_recv(req);
104 }
105
106
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)
112 {
113         struct smb_trans2 t2;
114         uint16_t setup = TRANSACT2_MKDIR;
115         TALLOC_CTX *mem_ctx;
116         struct smbcli_request *req;
117         uint16_t data_total;
118
119         mem_ctx = talloc_init("t2mkdir");
120
121         data_total = ea_list_size(parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);
122
123         t2.in.max_param = 0;
124         t2.in.max_data = 0;
125         t2.in.max_setup = 0;
126         t2.in.flags = 0;
127         t2.in.timeout = 0;
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);
132
133         SIVAL(t2.in.params.data, VWV(0), 0); /* reserved */
134
135         smbcli_blob_append_string(tree->session, mem_ctx, 
136                                &t2.in.params, parms->t2mkdir.in.path, 0);
137
138         ea_put_list(t2.in.data.data, parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);
139
140         req = smb_raw_trans2_send(tree, &t2);
141
142         talloc_destroy(mem_ctx);
143
144         return req;
145 }
146
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)
152 {
153         struct smbcli_request *req; 
154
155         if (parms->generic.level == RAW_MKDIR_T2MKDIR) {
156                 return smb_raw_t2mkdir_send(tree, parms);
157         }
158
159         if (parms->generic.level != RAW_MKDIR_MKDIR) {
160                 return NULL;
161         }
162
163         SETUP_REQUEST(SMBmkdir, 0, 0);
164         
165         smbcli_req_append_ascii4(req, parms->mkdir.in.path, STR_TERMINATE);
166
167         if (!smbcli_request_send(req)) {
168                 return NULL;
169         }
170
171         return req;
172 }
173
174 /****************************************************************************
175  Create a directory - sync interface
176 ****************************************************************************/
177 NTSTATUS smb_raw_mkdir(struct smbcli_tree *tree,
178                        union smb_mkdir *parms)
179 {
180         struct smbcli_request *req = smb_raw_mkdir_send(tree, parms);
181         return smbcli_request_simple_recv(req);
182 }
183
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)
189 {
190         struct smbcli_request *req; 
191
192         SETUP_REQUEST(SMBrmdir, 0, 0);
193         
194         smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE);
195
196         if (!smbcli_request_send(req)) {
197                 smbcli_request_destroy(req);
198                 return NULL;
199         }
200
201         return req;
202 }
203
204 /****************************************************************************
205  Remove a directory - sync interface
206 ****************************************************************************/
207 NTSTATUS smb_raw_rmdir(struct smbcli_tree *tree,
208                        struct smb_rmdir *parms)
209 {
210         struct smbcli_request *req = smb_raw_rmdir_send(tree, parms);
211         return smbcli_request_simple_recv(req);
212 }
213
214
215 /****************************************************************************
216  Open a file using TRANSACT2_OPEN - async send 
217 ****************************************************************************/
218 static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree, 
219                                                union smb_open *parms)
220 {
221         struct smb_trans2 t2;
222         uint16_t setup = TRANSACT2_OPEN;
223         TALLOC_CTX *mem_ctx = talloc_init("smb_raw_t2open");
224         struct smbcli_request *req;
225         uint16_t list_size;
226
227         list_size = ea_list_size(parms->t2open.in.num_eas, parms->t2open.in.eas);
228
229         t2.in.max_param = 30;
230         t2.in.max_data = 0;
231         t2.in.max_setup = 0;
232         t2.in.flags = 0;
233         t2.in.timeout = 0;
234         t2.in.setup_count = 1;
235         t2.in.setup = &setup;
236         t2.in.params = data_blob_talloc(mem_ctx, NULL, 28);
237         t2.in.data = data_blob_talloc(mem_ctx, NULL, list_size);
238
239         SSVAL(t2.in.params.data, VWV(0), parms->t2open.in.flags);
240         SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode);
241         SSVAL(t2.in.params.data, VWV(2), 0); /* reserved */
242         SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs);
243         raw_push_dos_date(tree->session->transport, 
244                          t2.in.params.data, VWV(4), parms->t2open.in.write_time);
245         SSVAL(t2.in.params.data, VWV(6), parms->t2open.in.open_func);
246         SIVAL(t2.in.params.data, VWV(7), parms->t2open.in.size);
247         SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout);
248         SIVAL(t2.in.params.data, VWV(11), 0);
249         SSVAL(t2.in.params.data, VWV(13), 0);
250
251         smbcli_blob_append_string(tree->session, mem_ctx, 
252                                &t2.in.params, parms->t2open.in.fname, 
253                                STR_TERMINATE);
254
255         ea_put_list(t2.in.data.data, parms->t2open.in.num_eas, parms->t2open.in.eas);
256
257         req = smb_raw_trans2_send(tree, &t2);
258
259         talloc_destroy(mem_ctx);
260
261         return req;
262 }
263
264
265 /****************************************************************************
266  Open a file using TRANSACT2_OPEN - async recv
267 ****************************************************************************/
268 static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
269 {
270         struct smbcli_transport *transport = req?req->transport:NULL;
271         struct smb_trans2 t2;
272         NTSTATUS status;
273
274         status = smb_raw_trans2_recv(req, mem_ctx, &t2);
275         if (!NT_STATUS_IS_OK(status)) return status;
276
277         if (t2.out.params.length < 30) {
278                 return NT_STATUS_INFO_LENGTH_MISMATCH;
279         }
280
281         parms->t2open.out.fnum =        SVAL(t2.out.params.data, VWV(0));
282         parms->t2open.out.attrib =      SVAL(t2.out.params.data, VWV(1));
283         parms->t2open.out.write_time =  raw_pull_dos_date3(transport, t2.out.params.data + VWV(2));
284         parms->t2open.out.size =        IVAL(t2.out.params.data, VWV(4));
285         parms->t2open.out.access =      SVAL(t2.out.params.data, VWV(6));
286         parms->t2open.out.ftype =       SVAL(t2.out.params.data, VWV(7));
287         parms->t2open.out.devstate =    SVAL(t2.out.params.data, VWV(8));
288         parms->t2open.out.action =      SVAL(t2.out.params.data, VWV(9));
289         parms->t2open.out.unknown =     SVAL(t2.out.params.data, VWV(10));
290
291         return NT_STATUS_OK;
292 }
293
294 /****************************************************************************
295  Open a file - async send
296 ****************************************************************************/
297 struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms)
298 {
299         int len;
300         struct smbcli_request *req = NULL; 
301
302         switch (parms->open.level) {
303         case RAW_OPEN_T2OPEN:
304                 return smb_raw_t2open_send(tree, parms);
305
306         case RAW_OPEN_OPEN:
307                 SETUP_REQUEST(SMBopen, 2, 0);
308                 SSVAL(req->out.vwv, VWV(0), parms->open.in.flags);
309                 SSVAL(req->out.vwv, VWV(1), parms->open.in.search_attrs);
310                 smbcli_req_append_ascii4(req, parms->open.in.fname, STR_TERMINATE);
311                 break;
312                 
313         case RAW_OPEN_OPENX:
314                 SETUP_REQUEST(SMBopenX, 15, 0);
315                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
316                 SSVAL(req->out.vwv, VWV(1), 0);
317                 SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags);
318                 SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode);
319                 SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs);
320                 SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs);
321                 raw_push_dos_date3(tree->session->transport, 
322                                   req->out.vwv, VWV(6), parms->openx.in.write_time);
323                 SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func);
324                 SIVAL(req->out.vwv, VWV(9), parms->openx.in.size);
325                 SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout);
326                 SIVAL(req->out.vwv, VWV(13),0); /* reserved */
327                 smbcli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE);
328                 break;
329                 
330         case RAW_OPEN_MKNEW:
331                 SETUP_REQUEST(SMBmknew, 3, 0);
332                 SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib);
333                 raw_push_dos_date3(tree->session->transport, 
334                                   req->out.vwv, VWV(1), parms->mknew.in.write_time);
335                 smbcli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE);
336                 break;
337
338         case RAW_OPEN_CREATE:
339                 SETUP_REQUEST(SMBcreate, 3, 0);
340                 SSVAL(req->out.vwv, VWV(0), parms->create.in.attrib);
341                 raw_push_dos_date3(tree->session->transport, 
342                                   req->out.vwv, VWV(1), parms->create.in.write_time);
343                 smbcli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE);
344                 break;
345                 
346         case RAW_OPEN_CTEMP:
347                 SETUP_REQUEST(SMBctemp, 3, 0);
348                 SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib);
349                 raw_push_dos_date3(tree->session->transport, 
350                                   req->out.vwv, VWV(1), parms->ctemp.in.write_time);
351                 smbcli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE);
352                 break;
353                 
354         case RAW_OPEN_SPLOPEN:
355                 SETUP_REQUEST(SMBsplopen, 2, 0);
356                 SSVAL(req->out.vwv, VWV(0), parms->splopen.in.setup_length);
357                 SSVAL(req->out.vwv, VWV(1), parms->splopen.in.mode);
358                 break;
359                 
360         case RAW_OPEN_NTCREATEX:
361                 SETUP_REQUEST(SMBntcreateX, 24, 0);
362                 SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE);
363                 SSVAL(req->out.vwv, VWV(1),0);
364                 SCVAL(req->out.vwv, VWV(2),0); /* padding */
365                 SIVAL(req->out.vwv,  7, parms->ntcreatex.in.flags);
366                 SIVAL(req->out.vwv, 11, parms->ntcreatex.in.root_fid);
367                 SIVAL(req->out.vwv, 15, parms->ntcreatex.in.access_mask);
368                 SBVAL(req->out.vwv, 19, parms->ntcreatex.in.alloc_size);
369                 SIVAL(req->out.vwv, 27, parms->ntcreatex.in.file_attr);
370                 SIVAL(req->out.vwv, 31, parms->ntcreatex.in.share_access);
371                 SIVAL(req->out.vwv, 35, parms->ntcreatex.in.open_disposition);
372                 SIVAL(req->out.vwv, 39, parms->ntcreatex.in.create_options);
373                 SIVAL(req->out.vwv, 43, parms->ntcreatex.in.impersonation);
374                 SCVAL(req->out.vwv, 47, parms->ntcreatex.in.security_flags);
375                 
376                 smbcli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len);
377                 SSVAL(req->out.vwv, 5, len);
378                 break;
379         }
380
381         if (!smbcli_request_send(req)) {
382                 smbcli_request_destroy(req);
383                 return NULL;
384         }
385
386         return req;
387 }
388
389 /****************************************************************************
390  Open a file - async recv
391 ****************************************************************************/
392 NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
393 {
394         if (!smbcli_request_receive(req) ||
395             smbcli_request_is_error(req)) {
396                 goto failed;
397         }
398
399         switch (parms->open.level) {
400         case RAW_OPEN_T2OPEN:
401                 return smb_raw_t2open_recv(req, mem_ctx, parms);
402
403         case RAW_OPEN_OPEN:
404                 SMBCLI_CHECK_WCT(req, 7);
405                 parms->open.out.fnum = SVAL(req->in.vwv, VWV(0));
406                 parms->open.out.attrib = SVAL(req->in.vwv, VWV(1));
407                 parms->open.out.write_time = raw_pull_dos_date3(req->transport,
408                                                                 req->in.vwv + VWV(2));
409                 parms->open.out.size = IVAL(req->in.vwv, VWV(4));
410                 parms->open.out.rmode = SVAL(req->in.vwv, VWV(6));
411                 break;
412
413         case RAW_OPEN_OPENX:
414                 SMBCLI_CHECK_MIN_WCT(req, 15);
415                 parms->openx.out.fnum = SVAL(req->in.vwv, VWV(2));
416                 parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3));
417                 parms->openx.out.write_time = raw_pull_dos_date3(req->transport,
418                                                                  req->in.vwv + VWV(4));
419                 parms->openx.out.size = IVAL(req->in.vwv, VWV(6));
420                 parms->openx.out.access = SVAL(req->in.vwv, VWV(8));
421                 parms->openx.out.ftype = SVAL(req->in.vwv, VWV(9));
422                 parms->openx.out.devstate = SVAL(req->in.vwv, VWV(10));
423                 parms->openx.out.action = SVAL(req->in.vwv, VWV(11));
424                 parms->openx.out.unique_fid = IVAL(req->in.vwv, VWV(12));
425                 if (req->in.wct >= 19) {
426                         parms->openx.out.access_mask = IVAL(req->in.vwv, VWV(15));
427                         parms->openx.out.unknown =     IVAL(req->in.vwv, VWV(17));
428                 } else {
429                         parms->openx.out.access_mask = 0;
430                         parms->openx.out.unknown = 0;
431                 }
432                 break;
433
434         case RAW_OPEN_MKNEW:
435                 SMBCLI_CHECK_WCT(req, 1);
436                 parms->mknew.out.fnum = SVAL(req->in.vwv, VWV(0));
437                 break;
438
439         case RAW_OPEN_CREATE:
440                 SMBCLI_CHECK_WCT(req, 1);
441                 parms->create.out.fnum = SVAL(req->in.vwv, VWV(0));
442                 break;
443
444         case RAW_OPEN_CTEMP:
445                 SMBCLI_CHECK_WCT(req, 1);
446                 parms->ctemp.out.fnum = SVAL(req->in.vwv, VWV(0));
447                 smbcli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII);
448                 break;
449
450         case RAW_OPEN_SPLOPEN:
451                 SMBCLI_CHECK_WCT(req, 1);
452                 parms->splopen.out.fnum = SVAL(req->in.vwv, VWV(0));
453                 break;
454
455         case RAW_OPEN_NTCREATEX:
456                 SMBCLI_CHECK_MIN_WCT(req, 34);
457                 parms->ntcreatex.out.oplock_level =              CVAL(req->in.vwv, 4);
458                 parms->ntcreatex.out.fnum =                      SVAL(req->in.vwv, 5);
459                 parms->ntcreatex.out.create_action =             IVAL(req->in.vwv, 7);
460                 parms->ntcreatex.out.create_time =   smbcli_pull_nttime(req->in.vwv, 11);
461                 parms->ntcreatex.out.access_time =   smbcli_pull_nttime(req->in.vwv, 19);
462                 parms->ntcreatex.out.write_time =    smbcli_pull_nttime(req->in.vwv, 27);
463                 parms->ntcreatex.out.change_time =   smbcli_pull_nttime(req->in.vwv, 35);
464                 parms->ntcreatex.out.attrib =                   IVAL(req->in.vwv, 43);
465                 parms->ntcreatex.out.alloc_size =               BVAL(req->in.vwv, 47);
466                 parms->ntcreatex.out.size =                     BVAL(req->in.vwv, 55);
467                 parms->ntcreatex.out.file_type =                SVAL(req->in.vwv, 63);
468                 parms->ntcreatex.out.ipc_state =                SVAL(req->in.vwv, 65);
469                 parms->ntcreatex.out.is_directory =             CVAL(req->in.vwv, 67);
470                 break;
471         }
472
473 failed:
474         return smbcli_request_destroy(req);
475 }
476
477
478 /****************************************************************************
479  Open a file - sync interface
480 ****************************************************************************/
481 NTSTATUS smb_raw_open(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms)
482 {
483         struct smbcli_request *req = smb_raw_open_send(tree, parms);
484         return smb_raw_open_recv(req, mem_ctx, parms);
485 }
486
487
488 /****************************************************************************
489  Close a file - async send
490 ****************************************************************************/
491 struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms)
492 {
493         struct smbcli_request *req = NULL; 
494
495         switch (parms->generic.level) {
496         case RAW_CLOSE_GENERIC:
497                 return NULL;
498
499         case RAW_CLOSE_CLOSE:
500                 SETUP_REQUEST(SMBclose, 3, 0);
501                 SSVAL(req->out.vwv, VWV(0), parms->close.in.fnum);
502                 raw_push_dos_date3(tree->session->transport, 
503                                   req->out.vwv, VWV(1), parms->close.in.write_time);
504                 break;
505
506         case RAW_CLOSE_SPLCLOSE:
507                 SETUP_REQUEST(SMBsplclose, 3, 0);
508                 SSVAL(req->out.vwv, VWV(0), parms->splclose.in.fnum);
509                 SIVAL(req->out.vwv, VWV(1), 0); /* reserved */
510                 break;
511         }
512
513         if (!req) return NULL;
514
515         if (!smbcli_request_send(req)) {
516                 smbcli_request_destroy(req);
517                 return NULL;
518         }
519
520         return req;
521 }
522
523
524 /****************************************************************************
525  Close a file - sync interface
526 ****************************************************************************/
527 NTSTATUS smb_raw_close(struct smbcli_tree *tree, union smb_close *parms)
528 {
529         struct smbcli_request *req = smb_raw_close_send(tree, parms);
530         return smbcli_request_simple_recv(req);
531 }
532
533
534 /****************************************************************************
535  Locking calls - async interface
536 ****************************************************************************/
537 struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_lock *parms)
538 {
539         struct smbcli_request *req = NULL; 
540
541         switch (parms->generic.level) {
542         case RAW_LOCK_GENERIC:
543                 return NULL;
544
545         case RAW_LOCK_LOCK:
546                 SETUP_REQUEST(SMBlock, 5, 0);
547                 SSVAL(req->out.vwv, VWV(0), parms->lock.in.fnum);
548                 SIVAL(req->out.vwv, VWV(1), parms->lock.in.count);
549                 SIVAL(req->out.vwv, VWV(3), parms->lock.in.offset);
550                 break;
551                 
552         case RAW_LOCK_UNLOCK:
553                 SETUP_REQUEST(SMBunlock, 5, 0);
554                 SSVAL(req->out.vwv, VWV(0), parms->unlock.in.fnum);
555                 SIVAL(req->out.vwv, VWV(1), parms->unlock.in.count);
556                 SIVAL(req->out.vwv, VWV(3), parms->unlock.in.offset);
557                 break;
558                 
559         case RAW_LOCK_LOCKX: {
560                 struct smb_lock_entry *lockp;
561                 uint_t lck_size = (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES)? 20 : 10;
562                 uint_t lock_count = parms->lockx.in.ulock_cnt + parms->lockx.in.lock_cnt;
563                 int i;
564
565                 SETUP_REQUEST(SMBlockingX, 8, lck_size * lock_count);
566                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
567                 SSVAL(req->out.vwv, VWV(1), 0);
568                 SSVAL(req->out.vwv, VWV(2), parms->lockx.in.fnum);
569                 SSVAL(req->out.vwv, VWV(3), parms->lockx.in.mode);
570                 SIVAL(req->out.vwv, VWV(4), parms->lockx.in.timeout);
571                 SSVAL(req->out.vwv, VWV(6), parms->lockx.in.ulock_cnt);
572                 SSVAL(req->out.vwv, VWV(7), parms->lockx.in.lock_cnt);
573                 
574                 /* copy in all the locks */
575                 lockp = &parms->lockx.in.locks[0];
576                 for (i = 0; i < lock_count; i++) {
577                         char *p = req->out.data + lck_size * i;
578                         SSVAL(p, 0, lockp[i].pid);
579                         if (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES) {
580                                 SSVAL(p,  2, 0); /* reserved */
581                                 SIVAL(p,  4, lockp[i].offset>>32);
582                                 SIVAL(p,  8, lockp[i].offset);
583                                 SIVAL(p, 12, lockp[i].count>>32);
584                                 SIVAL(p, 16, lockp[i].count);
585                         } else {
586                                 SIVAL(p, 2, lockp[i].offset);
587                                 SIVAL(p, 6, lockp[i].count);
588                         }
589                 }       
590         }
591         }
592
593         if (!smbcli_request_send(req)) {
594                 smbcli_request_destroy(req);
595                 return NULL;
596         }
597
598         return req;
599 }
600
601 /****************************************************************************
602  Locking calls - sync interface
603 ****************************************************************************/
604 NTSTATUS smb_raw_lock(struct smbcli_tree *tree, union smb_lock *parms)
605 {
606         struct smbcli_request *req = smb_raw_lock_send(tree, parms);
607         return smbcli_request_simple_recv(req);
608 }
609         
610
611 /****************************************************************************
612  Check for existence of a dir - async send
613 ****************************************************************************/
614 struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, struct smb_chkpath *parms)
615 {
616         struct smbcli_request *req; 
617
618         SETUP_REQUEST(SMBchkpth, 0, 0);
619
620         smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE);
621
622         if (!smbcli_request_send(req)) {
623                 smbcli_request_destroy(req);
624                 return NULL;
625         }
626
627         return req;
628 }
629
630 /****************************************************************************
631  Check for existence of a dir - sync interface
632 ****************************************************************************/
633 NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, struct smb_chkpath *parms)
634 {
635         struct smbcli_request *req = smb_raw_chkpath_send(tree, parms);
636         return smbcli_request_simple_recv(req);
637 }
638
639
640
641
642 /****************************************************************************
643  flush a file - async send
644  a flush to fnum 0xFFFF will flush all files
645 ****************************************************************************/
646 struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, struct smb_flush *parms)
647 {
648         struct smbcli_request *req; 
649
650         SETUP_REQUEST(SMBflush, 1, 0);
651         SSVAL(req->out.vwv, VWV(0), parms->in.fnum);
652
653         if (!smbcli_request_send(req)) {
654                 smbcli_request_destroy(req);
655                 return NULL;
656         }
657
658         return req;
659 }
660
661
662 /****************************************************************************
663  flush a file - sync interface
664 ****************************************************************************/
665 NTSTATUS smb_raw_flush(struct smbcli_tree *tree, struct smb_flush *parms)
666 {
667         struct smbcli_request *req = smb_raw_flush_send(tree, parms);
668         return smbcli_request_simple_recv(req);
669 }
670
671
672 /****************************************************************************
673  seek a file - async send
674 ****************************************************************************/
675 struct smbcli_request *smb_raw_seek_send(struct smbcli_tree *tree,
676                                       struct smb_seek *parms)
677 {
678         struct smbcli_request *req; 
679
680         SETUP_REQUEST(SMBlseek, 4, 0);
681
682         SSVAL(req->out.vwv, VWV(0), parms->in.fnum);
683         SSVAL(req->out.vwv, VWV(1), parms->in.mode);
684         SIVALS(req->out.vwv, VWV(2), parms->in.offset);
685
686         if (!smbcli_request_send(req)) {
687                 smbcli_request_destroy(req);
688                 return NULL;
689         }
690         return req;
691 }
692
693 /****************************************************************************
694  seek a file - async receive
695 ****************************************************************************/
696 NTSTATUS smb_raw_seek_recv(struct smbcli_request *req,
697                                       struct smb_seek *parms)
698 {
699         if (!smbcli_request_receive(req) ||
700             smbcli_request_is_error(req)) {
701                 return smbcli_request_destroy(req);
702         }
703
704         SMBCLI_CHECK_WCT(req, 2);       
705         parms->out.offset = IVAL(req->in.vwv, VWV(0));
706
707 failed: 
708         return smbcli_request_destroy(req);
709 }
710
711 /*
712   seek a file - sync interface
713 */
714 NTSTATUS smb_raw_seek(struct smbcli_tree *tree,
715                       struct smb_seek *parms)
716 {
717         struct smbcli_request *req = smb_raw_seek_send(tree, parms);
718         return smb_raw_seek_recv(req, parms);
719 }