source: branches/client-1.5/src/ndpsmb.c@ 410

Last change on this file since 410 was 398, checked in by Herwig Bauernfeind, 16 years ago

Remove LOGLEVEL token, remove comments

  • Property svn:eol-style set to native
File size: 49.9 KB
Line 
1/*
2 Netdrive Samba client plugin
3 plugin API
4 Copyright (C) netlabs.org 2003-2008
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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <string.h>
25#include <time.h>
26
27#define NDPL_LARGEFILES
28#define INCL_LONGLONG
29#include <ndextpl2.h>
30#include "smbwrp.h"
31#include "util.h"
32
33#if 0
34
35#ifndef DEBUG_PRINTF
36#define debug_printf( ...)
37#endif
38
39#define log debug_printf
40#endif
41
42#define debug_printf(...) debuglocal(9, __VA_ARGS__)
43
44// -------------------------------------------------------------
45
46/* time conversion functions: SMB protocol sends timestamps in GMT time,
47* os2 api uses localtime,
48* emx/klibc uses timezone and daylight saving to convert GMT timestamps,
49* so only the timezone must be counted in conversion.
50*/
51void fsphUnixTimeToDosDate( time_t time, FDATE* fdate, FTIME *ftime)
52{
53 struct tm* gmt = localtime( &time);
54 if (gmt->tm_isdst>0) {
55 debug_printf( "daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone);
56 time -= 3600;
57 gmt = localtime( &time);
58 }
59 fdate->day = gmt->tm_mday;
60 fdate->month = gmt->tm_mon+1;
61 fdate->year = gmt->tm_year + 1900 - 1980;
62 ftime->twosecs = gmt->tm_sec/2;
63 ftime->minutes = gmt->tm_min;
64 ftime->hours = gmt->tm_hour;
65}
66
67void fsphDosDateToUnixTime( FDATE fdate, FTIME ftime, ULONG* time)
68{
69 struct tm gmtime = { 0 };
70 struct tm* gmt;
71
72 debug_printf( "fsphDosDateToUnixTime time %02d:%02d\n", ftime.hours, ftime.minutes);
73 gmtime.tm_mday = fdate.day;
74 gmtime.tm_mon = fdate.month-1;
75 gmtime.tm_year = fdate.year + 1980 - 1900;
76 gmtime.tm_sec = ftime.twosecs*2;
77 gmtime.tm_min = ftime.minutes;
78 gmtime.tm_hour = ftime.hours;
79 gmtime.tm_isdst = -1; // force libc to check dst saving
80
81 *time = mktime( &gmtime);
82 debug_printf( "fsphDosDateToUnixTime time1 %d %s", *time, ctime( (time_t*)time));
83 gmt = localtime( (time_t*) time);
84 if (gmt->tm_isdst>0) {
85 debug_printf( "fsphDosDateToUnixTime daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone);
86 *time += 3600;
87 }
88 debug_printf( "fsphDosDateToUnixTime time2 %d %s", *time, ctime( (time_t*)time));
89}
90
91// -------------------------------------------------------------
92
93int StrLen(char * s)
94{
95 char * p;
96 if (!s)
97 {
98 return 0;
99 }
100 for (p = s; *p; p++);
101 return (p - s);
102}
103
104char * StrNCat(char *dst, const char *src, int count)
105{
106 int i;
107 if (!dst || !src || count <= 0)
108 {
109 return dst;
110 }
111 for (i = 0; dst[i]; i++);
112 for (;i < count && *src; i++, src++)
113 {
114 dst[i] = *src;
115 }
116 dst[i] = 0;
117 return dst;
118}
119
120char * StrNCpy(char *dst, const char *src, int count)
121{
122 if (!dst || !src || count <= 0)
123 {
124 return dst;
125 }
126 *dst = 0;
127 return StrNCat(dst, src, count);
128}
129
130char * StrCpy(char *dst, const char *src)
131{
132 char * p;
133 if (!dst || !src)
134 {
135 return dst;
136 }
137 p = dst;
138 while (*p++ = *src++);
139 return dst;
140}
141
142char * StrCat(char *dst, const char *src)
143{
144 int i;
145 if (!dst || !src)
146 {
147 return dst;
148 }
149 for (i = 0; dst[i]; i++);
150 for (; *src; i++, src++)
151 {
152 dst[i] = *src;
153 }
154 dst[i] = 0;
155 return dst;
156}
157
158void * MemCpy(void * dst, const void * src, int len)
159{
160 int i;
161 if (!src || !dst || len <= 0)
162 {
163 return dst;
164 }
165 for (i = 0; i < len; i++)
166 {
167 ((char *)dst)[i] = ((char *)src)[i];
168 }
169 return dst;
170}
171
172void *MemSet(void *dst, char c, int len)
173{
174 int i;
175 if (!dst || len <= 0)
176 {
177 return dst;
178 }
179 for (i = 0; i < len; i++)
180 {
181 ((char *)dst)[i] = c;
182 }
183 return dst;
184}
185
186// -------------------------------------------------------------
187
188/* uppercased type of resource */
189const char *NdpTypes[] =
190{
191 "SMBFS",
192 NULL
193}
194;
195
196/* Properties of supported resource types */
197
198/* Properties of resource */
199static const NDPROPERTYINFO smbProperties[] =
200{
201 {ND_PROP_STRING, 0, "WORKGROUP", ""},
202 {ND_PROP_STRING, 0, "SERVER", ""},
203 {ND_PROP_STRING, 0, "SHARE", ""},
204 {ND_PROP_STRING, 0, "USER", "guest"},
205 {ND_PROP_STRING, 0, "PASSWORD", ""},
206 {ND_PROP_STRING, 0, "SPASSWORD", ""},
207 {ND_PROP_STRING, 0, "MASTER", "WORKGROUP"},
208 { ND_PROP_ULONG, 0, "MASTERTYPE", "1"},
209 { ND_PROP_ULONG, 0, "EASUPPORT", "1"},
210 {ND_PROP_STRING, 0, NULL, NULL}
211};
212
213
214/* Exported array of properties */
215const NDPROPERTYINFO *NdpPropertiesInfo[] =
216{
217 smbProperties
218};
219
220
221static PLUGINHELPERTABLE2L *ph;
222static int ifL;
223
224int APIENTRY NdpPluginLoad (PLUGINHELPERTABLE2L *pPHT)
225{
226 int rc;
227 HPIPE pipe;
228 unsigned long action;
229 ph = pPHT;
230 ifL = 0;
231/*
232 if (ph->cb < sizeof (PLUGINHELPERTABLE2))
233 {
234 return ERROR_INVALID_FUNCTION;
235 }
236*/
237 if (ph->cb >= sizeof (PLUGINHELPERTABLE2L))
238 {
239 ifL = 1;
240 }
241 debuglocal(9,"Working with %s bit fileio NDFS\n", ifL ? "64" : "32");
242 return NO_ERROR;
243}
244
245
246int APIENTRY NdpPluginFree (void)
247{
248 return NO_ERROR;
249}
250
251
252void getfindinfo(Connection * pConn, FILEFINDBUF3 * stat, smbwrp_fileinfo * finfo)
253{
254 char * name = ph->fsphStrRChr(finfo->fname, '\\');
255 if (name)
256 {
257 name++;
258 }
259 else
260 {
261 name = finfo->fname;
262 }
263 if (!*name)
264 {
265 name = pConn->pRes->srv.share_name;
266 }
267 StrNCpy(stat->achName, name, CCHMAXPATHCOMP - 1);
268 stat->cbFile = finfo->size;
269 stat->cbFileAlloc = stat->cbFile;
270 stat->oNextEntryOffset = 0ul;
271 stat->cchName = StrLen(stat->achName);
272 stat->attrFile = (finfo->attr & 0x37);
273
274 fsphUnixTimeToDosDate(finfo->mtime, &stat->fdateLastWrite, &stat->ftimeLastWrite);
275 fsphUnixTimeToDosDate(finfo->ctime, &stat->fdateCreation, &stat->ftimeCreation);
276 fsphUnixTimeToDosDate(finfo->atime, &stat->fdateLastAccess, &stat->ftimeLastAccess);
277}
278
279int getfindinfoL(Connection * pConn, void * plist, smbwrp_fileinfo * finfo, ULONG ulAttribute, char * mask)
280{
281 FILESTATUS3L stat = {0};
282 char * name = ph->fsphStrRChr(finfo->fname, '\\');
283 if (name)
284 {
285 name++;
286 }
287 else
288 {
289 name = finfo->fname;
290 }
291 if (!*name)
292 {
293 name = pConn->pRes->srv.share_name;
294 }
295 if (mask && (!ph->fsphAttrMatch(ulAttribute, finfo->attr & 0x37) || !ph->fsphWildMatch(mask, name, ND_IGNORE_CASE)))
296 {
297 return 0;
298 }
299
300 stat.cbFile = finfo->size;
301 stat.cbFileAlloc = stat.cbFile;
302 stat.attrFile = (finfo->attr & 0x37);
303
304 fsphUnixTimeToDosDate(finfo->mtime, &stat.fdateLastWrite, &stat.ftimeLastWrite);
305 fsphUnixTimeToDosDate(finfo->ctime, &stat.fdateCreation, &stat.ftimeCreation);
306 fsphUnixTimeToDosDate(finfo->atime, &stat.fdateLastAccess, &stat.ftimeLastAccess);
307 debug_printf( "fname %s\n", finfo->fname);
308 debug_printf( "mtime %d %s", finfo->mtime, ctime( (time_t*)&finfo->mtime));
309 debug_printf( "ftimeLastAccess %02d:%02d:%02d\n", stat.ftimeLastWrite.hours, stat.ftimeLastWrite.minutes, stat.ftimeLastWrite.twosecs*2);
310
311 ph->fsphAddFile32L(plist, &stat, name, StrLen(name), finfo, sizeof(*finfo), 0);
312 return 1;
313}
314
315static unsigned char fromhex (char c)
316{
317 if ('0' <= c && c <= '9')
318 {
319 return c - '0';
320 }
321
322 if ('A' <= c && c <= 'F')
323 {
324 return c - 'A' + 0xA;
325 }
326
327 if ('a' <= c && c <= 'f')
328 {
329 return c - 'a' + 0xA;
330 }
331
332 return 0;
333}
334
335static char tohex (unsigned char b)
336{
337 b &= 0xF;
338
339 if (b <= 9)
340 {
341 return b + '0';
342 }
343
344 return 'A' + (b - 0xA);
345}
346
347static void decryptPassword (const char *pszCrypt, char *pszPlain)
348{
349 /* A simple "decryption", character from the hex value. */
350 const char *s = pszCrypt;
351 char *d = pszPlain;
352
353 while (*s)
354 {
355 *d++ = (char)((fromhex (*s++) << 4) + fromhex (*s++));
356 }
357
358 *d++ = 0;
359}
360
361static void encryptPassword (const char *pszPlain, char *pszCrypt)
362{
363 /* A simple "encryption" encode each character as hex value. */
364 const char *s = pszPlain;
365 char *d = pszCrypt;
366
367 while (*s)
368 {
369 *d++ = tohex ((*s) >> 4);
370 *d++ = tohex (*s);
371 s++;
372 }
373
374 *d++ = 0;
375}
376
377/* accept parameters in form
378 * [filename][;name=filename]
379 */
380int initResource (Resource *pRes, NDPROPERTYHANDLE properties)
381{
382 int rc = NO_ERROR;
383 unsigned long t;
384 const CHAR * q = NULL;
385 int defaultPassword = 1;
386
387 pRes->rootlevel = 0;
388 pRes->easupport = 1;
389#ifdef HAVE_KRB5_H
390 pRes->krb5support = 1;
391#else
392 pRes->krb5support = 0;
393#endif
394
395 t = 0, q = NULL;
396 rc = ph->fsphQueryStringProperty (properties, "WORKGROUP", &q, &t);
397 if (!rc && t && *q)
398 {
399 StrNCpy(pRes->srv.workgroup, q, sizeof(pRes->srv.workgroup) - 1);
400 pRes->rootlevel = 1;
401 }
402
403 t = 0, q = NULL;
404 rc = ph->fsphQueryStringProperty (properties, "SERVER", &q, &t);
405 if (!rc && t && *q)
406 {
407 StrNCpy(pRes->srv.server_name, q, sizeof(pRes->srv.server_name) - 1);
408 pRes->rootlevel = 2;
409 }
410
411 t = 0, q = NULL;
412 rc = ph->fsphQueryStringProperty (properties, "SHARE", &q, &t);
413 if (!rc && t && *q)
414 {
415 StrNCpy(pRes->srv.share_name, q, sizeof(pRes->srv.share_name) - 1);
416 pRes->rootlevel = 3;
417 }
418
419 t = 0, q = NULL;
420 rc = ph->fsphQueryStringProperty (properties, "USER", &q, &t);
421 if (!rc && t && *q)
422 {
423 StrNCpy(pRes->srv.username, q, sizeof(pRes->srv.username) - 1);
424 }
425
426 t = 0, q = NULL;
427 rc = ph->fsphQueryStringProperty (properties, "PASSWORD", &q, &t);
428 if (!rc && t && *q)
429 {
430 StrNCpy(pRes->srv.password, q, sizeof(pRes->srv.password) - 1);
431 defaultPassword = 0;
432 }
433
434 t = 0, q = NULL;
435 rc = ph->fsphQueryStringProperty (properties, "SPASSWORD", &q, &t);
436 if ( rc == NO_ERROR
437 && *q != '\0'
438 && defaultPassword)
439 {
440 char p[1024];
441 p[0] = 0;
442
443 decryptPassword (q, p);
444
445 if (*p)
446 {
447 StrNCpy(pRes->srv.password, p, sizeof(pRes->srv.password) - 1);
448
449 /* clear the plain password */
450 ph->fsphSetProperty (properties, "PASSWORD", "");
451 }
452 }
453 else
454 {
455 char c[1024];
456 encryptPassword (pRes->srv.password, c);
457
458 ph->fsphSetProperty (properties, "SPASSWORD", c);
459
460 // clear the plain password
461 ph->fsphSetProperty (properties, "PASSWORD", "");
462 }
463
464 t = 0, q = NULL;
465 rc = ph->fsphQueryStringProperty (properties, "MASTER", &q, &t);
466 if (!rc && t && *q)
467 {
468 StrNCpy(pRes->srv.master, q, sizeof(pRes->srv.master) - 1);
469 }
470
471 t = 0, q = NULL;
472
473 t = 0;
474 rc = ph->fsphQueryUlongProperty (properties, "MASTERTYPE", &t);
475 if (!rc)
476 {
477 if (t > 1)
478 {
479 rc = ERROR_INVALID_PARAMETER;
480 }
481 else
482 {
483 pRes->srv.ifmastergroup = t;
484 }
485 }
486
487 t = 0;
488 rc = ph->fsphQueryUlongProperty (properties, "EASUPPORT", &t);
489 if (!rc)
490 {
491 if (t > 1)
492 {
493 rc = ERROR_INVALID_PARAMETER;
494 }
495 else
496 {
497 pRes->easupport = t;
498 }
499 }
500
501 return rc;
502}
503
504int iftestpath(char * path)
505{
506 char * p = path;
507 if (!path)
508 {
509 return 0;
510 }
511 while ((p = ph->fsphStrChr(p, 'A')) != NULL)
512 {
513 if (ph->fsphStrNCmp(p, "A.+,;=[].B", 10) == 0)
514 {
515 return 1;
516 }
517 p++;
518 }
519 return 0;
520}
521
522int pathparser(Resource *pRes, Connection * pConn, char * path, char * result)
523{
524 int rootlevel;
525 int rc = NO_ERROR;
526 if (!pRes || !path || !result)
527 {
528 return ERROR_INVALID_PARAMETER;
529 }
530 // handle special case when someone wants to test support of LFN or smth similar
531 if (iftestpath(path))
532 {
533 StrCpy(result, "\\A.+,;=[].B");
534 return NO_ERROR;
535 }
536
537 rootlevel = pRes->rootlevel;
538 if (*path == '\\') path++;
539
540 if (rootlevel < 3)
541 {
542 char * p;
543 // flag: 1 parameters changed, reconnection required, 0 do nothing
544 int newlevel = 0;
545 // use a temporary resource to test disconnection/reconnection
546 Resource tmpRes;
547 // copy exising data
548 memcpy( &tmpRes, pRes, sizeof( tmpRes));
549 // pointer to new connection fields
550 smbwrp_server * tmp = &tmpRes.srv;
551 if (rootlevel == 0)
552 {
553 p = ph->fsphStrChr(path, '\\');
554 if (!p)
555 {
556 p = path + StrLen(path);
557 }
558 if (StrLen(tmp->workgroup) != p - path
559 || (p == path || ph->fsphStrNICmp(path, tmp->workgroup, p - path)))
560 {
561 StrNCpy(tmp->workgroup, path, p - path);
562 tmp->workgroup[p - path] = 0;
563 newlevel = 1;
564 }
565 path = *p == '\\' ? p + 1 : p;
566 rootlevel = 1;
567 }
568 if (rootlevel == 1) // root path starts from server name
569 {
570 p = ph->fsphStrChr(path, '\\');
571 if (!p)
572 {
573 p = path + StrLen(path);
574 }
575 if (StrLen(tmp->server_name) != p - path
576 || (p == path || ph->fsphStrNICmp(path, tmp->server_name, p - path)))
577 {
578 StrNCpy(tmp->server_name, path, p - path);
579 tmp->server_name[p - path] = 0;
580 newlevel = 1;
581 }
582 path = *p == '\\' ? p + 1 : p;
583 rootlevel = 2;
584 }
585 if (rootlevel == 2) // root path starts from share name
586 {
587 p = ph->fsphStrChr(path, '\\');
588 if (!p)
589 {
590 p = path + StrLen(path);
591 }
592 if (StrLen(tmp->share_name) != (p - path)
593 || (p == path || ph->fsphStrNICmp(path, tmp->share_name, p - path)))
594 {
595 StrNCpy(tmp->share_name, path, p - path);
596 tmp->share_name[p - path] = 0;
597 newlevel = 1;
598 }
599 path = *p == '\\' ? p + 1 : p;
600 }
601 if (newlevel)
602 {
603 // reconnect to server here, first test new connection
604 cli_state* tmp_cli = NULL;
605 rc = smbwrp_connect( &tmpRes, &tmp_cli);
606 if (!rc)
607 {
608 // new connection is ok, disconnect old one
609 cli_state* cli = pConn->cli;
610 smbwrp_disconnect( pRes, cli);
611 // save tmp data structure
612 memcpy( pRes, &tmpRes, sizeof( tmpRes));
613 // save new connection handle
614 pConn->cli = tmp_cli;
615 }
616 }
617 }
618
619 StrCpy(result, "\\");
620 StrNCat(result, path, CCHMAXPATH);
621
622 return rc;
623}
624
625
626// -------------------------------------------------------------
627
628/* check if the requested resource is available */
629static int checkMountResource( Resource* pRes)
630{
631 int rc;
632 unsigned long action;
633 cli_state* cli = NULL;
634 smbwrp_file file;
635
636 debug_printf("checkMountResource in tid#%d\n", _gettid());
637 rc = smbwrp_connect( pRes, &cli);
638/* changed to real error codes SCS
639 if (rc)
640 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED); */
641 switch (rc) {
642 case 0:
643 rc = NO_ERROR;
644 break;
645 case 1:
646 case 10:
647 case 11:
648 rc = ERROR_BAD_NET_NAME;
649 break;
650 case 2:
651 rc = ERROR_INIT_ROUTINE_FAILED;
652 break;
653 case 3:
654 rc = ERROR_BAD_NET_RESP;
655 break;
656 case 4:
657 rc = ERROR_NETWORK_BUSY;
658 break;
659 case 6:
660 rc = ERROR_NETWORK_ACCESS_DENIED;
661 break;
662 case 7:
663 rc = ERROR_BAD_NETPATH;
664 break;
665 default:
666 rc = ERROR_UNEXP_NET_ERR;
667 break;
668 } /* endswitch */
669
670 smbwrp_disconnect( pRes, cli);
671
672 return rc;
673}
674
675int APIENTRY NdpMountResource (HRESOURCE *presource, int type, NDPROPERTYHANDLE properties)
676{
677 int rc = NO_ERROR;
678 unsigned long objany = OBJ_ANY;
679 Resource *pRes = NULL;
680
681 debuglocal(9,"NdpMountResource in\n");
682
683 // init code
684 smbwrp_init();
685
686 /* since samba plugin support only 1 type of resources we do not need */
687 /* to check what the found type really is */
688 pRes = malloc( sizeof(Resource));
689 if (pRes == NULL)
690 {
691 rc = ERROR_NOT_ENOUGH_MEMORY;
692 }
693 else
694 {
695 MemSet(pRes, 0, sizeof(Resource));
696 //pRes->objany = objany;
697 // parse init string
698 rc = initResource (pRes, properties);
699 // try to connect to resource (check type) only if thread!=1, so ndctl startup
700 // is not slowed down by network connections.
701 // ndctl does mounting on main thread (#1)
702 // nd/ndpm do not use main thread
703 if (!rc && _gettid()!=1)
704 rc = checkMountResource( pRes);
705 if (!rc)
706 {
707 // store resource data
708 *presource = (HRESOURCE)pRes;
709 }
710 else
711 {
712 free(pRes);
713 }
714 }
715 debuglocal(9,"NdpMountResource rc=%d\n", rc);
716 return rc;
717}
718
719// -------------------------------------------------------------
720
721int APIENTRY NdpFreeResource (HRESOURCE resource)
722{
723 Resource *pRes = (Resource *)resource;
724 MemSet(&pRes->srv, 0, sizeof(pRes->srv));
725 free(pRes);
726 debuglocal(9,"NdpFreeResource %d\n", NO_ERROR);
727 return NO_ERROR;
728}
729
730// -------------------------------------------------------------
731
732int APIENTRY NdpRsrcCompare (HRESOURCE resource, HRESOURCE resource2)
733{
734 Resource *pRes = (Resource *)resource;
735 Resource *pRes2 = (Resource *)resource2;
736 int rc = ND_RSRC_DIFFERENT;
737
738 debuglocal(9,"NdpRsrcCompare in\n");
739 if (ph->fsphStrICmp(pRes->srv.server_name, pRes2->srv.server_name) == 0
740 && ph->fsphStrICmp(pRes->srv.share_name, pRes2->srv.share_name) == 0
741 && ph->fsphStrICmp(pRes->srv.username, pRes2->srv.username) == 0
742 && ph->fsphStrICmp(pRes->srv.workgroup, pRes2->srv.workgroup) == 0)
743 {
744 // resources are equal
745 rc = ND_RSRC_EQUAL;
746 }
747
748 debuglocal(9,"NdpRsrcCompare %d\n", rc);
749
750 return rc;
751}
752
753int APIENTRY NdpRsrcUpdate (HRESOURCE resource, HRESOURCE resource2)
754{
755 // do nothing
756 debuglocal(9,"NdpRsrcUpdate %d\n", NO_ERROR);
757 return NO_ERROR;
758}
759
760int APIENTRY NdpRsrcQueryInfo (HRESOURCE resource, ULONG *pulFlags, void *pdata, ULONG insize, ULONG *poutlen)
761{
762 Resource *pRes = (Resource *)resource;
763 int rc = NO_ERROR;
764 char s[4096];
765
766 debuglocal(9,"NdpRsrcQueryInfo in\n");
767
768 switch (pRes->rootlevel)
769 {
770 case 0:
771 {
772 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\@%s", ifL ? "64" : "32", pRes->srv.username);
773 } break;
774 case 1:
775 {
776 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s %s: \\\\@%s", ifL ? "64" : "32", pRes->srv.workgroup, pRes->srv.username);
777 } break;
778 case 2:
779 {
780 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\%s%s%s@%s", ifL ? "64" : "32", *pRes->srv.workgroup ? pRes->srv.workgroup : "", *pRes->srv.workgroup ? ":" : "", pRes->srv.server_name, pRes->srv.username);
781 } break;
782 default:
783 {
784 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\%s%s%s\\%s@%s", ifL ? "64" : "32", *pRes->srv.workgroup ? pRes->srv.workgroup : "", *pRes->srv.workgroup ? ":" : "", pRes->srv.server_name, pRes->srv.share_name, pRes->srv.username);
785 } break;
786 }
787 *poutlen = StrLen(s) + 1;
788 if (*poutlen > insize)
789 {
790 rc = ERROR_BUFFER_OVERFLOW;
791 }
792 else
793 {
794 MemCpy(pdata, s, *poutlen);
795 }
796
797 debuglocal(9,"NdpRsrcQueryInfo %d\n", rc);
798
799 return rc;
800}
801
802int APIENTRY NdpRsrcQueryFSAttach (HRESOURCE resource, void *pdata, ULONG insize, ULONG *poutlen)
803{
804 ULONG ulDummy = 0;
805 /* just return the resource info string */
806 return NdpRsrcQueryInfo (resource, &ulDummy, pdata, insize, poutlen);
807}
808
809int APIENTRY NdpRsrcQueryFSAllocate (HRESOURCE resource, NDFSALLOCATE *pfsa)
810{
811 Resource *pRes = (Resource *)resource;
812 int rc = NO_ERROR, rc1;
813 unsigned long action = 0;
814 smbwrp_file file;
815 cli_state* cli = NULL;
816 FSALLOCATE fsa;
817
818 debuglocal(9,"NdpRsrcQueryFSAllocate %08x\n", pfsa);
819
820 if (!pfsa)
821 {
822 return NO_ERROR;
823 }
824
825 debug_printf("checkMountResource in tid#%d\n", _gettid());
826 rc = smbwrp_connect( pRes, &cli);
827 if (rc)
828 {
829 debuglocal(9,"NdpCreateConnection failed rc=%d\n", rc);
830 pfsa->cSectorUnit = 1;
831 pfsa->cUnit = 123456;
832 pfsa->cUnitAvail = 123456;
833 pfsa->cbSector = 2048;
834 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED);
835 return rc;
836 }
837
838 rc = smbwrp_dskattr( cli, &fsa);
839 if (rc)
840 {
841 pfsa->cSectorUnit = 1;
842 pfsa->cUnit = 123456;
843 pfsa->cUnitAvail = 123456;
844 pfsa->cbSector = 2048;
845 //rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
846 }
847 else
848 {
849 pfsa->cSectorUnit = fsa.cSectorUnit;
850 pfsa->cUnit = fsa.cUnit;
851 pfsa->cUnitAvail = fsa.cUnitAvail;
852 pfsa->cbSector = fsa.cbSector;
853 }
854
855 smbwrp_disconnect( pRes, cli);
856
857 debuglocal(9,"NdpRsrcQueryFSAllocate %d/%d (cUnit = %d/cUnitAvail = %d/cbSector = %d)\n", rc, rc1, pfsa->cUnit, pfsa->cUnitAvail, pfsa->cbSector);
858 return rc;
859}
860
861// -------------------------------------------------------------
862
863int APIENTRY NdpCreateConnection (HRESOURCE resource, HCONNECTION *pconn)
864{
865 int rc = 0;
866 Resource * pRes = (Resource *)resource;
867 unsigned long action;
868 Connection *pConn = NULL;
869
870 debuglocal(9,"NdpCreateConnection in\n");
871
872 pConn = malloc( sizeof(Connection));
873 if (pConn == NULL)
874 {
875 rc = ERROR_NOT_ENOUGH_MEMORY;
876 }
877 if (rc)
878 {
879 debuglocal(9,"NdpCreateConnection ERROR_NOT_ENOUGH_MEMORY %d\n", rc);
880 return rc;
881 }
882 MemSet(pConn, 0, sizeof(Connection));
883 pConn->pRes = pRes;
884 pConn->file.fd = -1;
885
886 debuglocal(9,"NdpCreateConnection send CONNECT\n");
887 rc = smbwrp_connect( pRes, &pConn->cli);
888 if (rc)
889 {
890 free(pConn);
891 pConn = NULL;
892 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_INVALID_PARAMETER);
893 }
894
895 *pconn = (HCONNECTION)pConn;
896 debuglocal(9,"NdpCreateConnection %d\n", rc);
897 return rc;
898}
899
900// -------------------------------------------------------------
901
902int APIENTRY NdpFreeConnection (HCONNECTION conn)
903{
904 Connection *pConn = (Connection *)conn;
905 Resource *pRes = pConn->pRes;
906 int rc;
907
908 debuglocal(9,"NdpFreeConnection in\n");
909 if (pConn->file.fd >= 0)
910 {
911 rc = smbwrp_close( pConn->cli, &pConn->file);
912 pConn->file.fd = -1;
913 }
914
915 smbwrp_disconnect( pRes, pConn->cli);
916
917 free(pConn);
918 debuglocal(9,"NdpFreeConnection %d\n", NO_ERROR);
919 return NO_ERROR;
920}
921
922// -------------------------------------------------------------
923
924/*
925 * NdpQueryPathInfo is the most important function :) netdrive always calls
926 * the function before every operation to find out the path status: does it exist, is it a file, does a
927 * parent directory exist, etc.
928 * Plugin must return one of the following error codes:
929 * NO_ERROR - path exists and the path information have been successfully retrieved.
930 * ERROR_FILE_NOT_FOUND - all but the last component of the path exist and the
931 * path without the last component is a directory. dir1_ok\dir2_ok\does_not_exist.
932 * the wildcard can not exist, so the plugin returns FILE_NOT_FOUND, if the parent
933 * directory exist.
934 * ERROR_PATH_NOT_FOUND - any of not last path components does not exist, or all
935 * but the last component exist and is a file: \dir_ok\dir2_ok\file_ok\non_existing.
936 * ERROR_REM_NOT_LIST - resource is temporarily unavailable for some reasons.
937 * Any other error codes means an internal plugin error, not related to the status
938 * of the path queried.
939 */
940int APIENTRY NdpQueryPathInfo (HCONNECTION conn, void *plist, char *szPath)
941{
942 Connection *pConn = (Connection *)conn;
943 Resource *pRes = pConn->pRes;
944 smbwrp_fileinfo finfo;
945 int rc = 0;
946 unsigned long action;
947 char path[CCHMAXPATH+1] = {0};
948 int retry = 0;
949
950 debuglocal(9,"NdpQueryPathInfo in <%s>, retry = %d\n", szPath, retry);
951
952 // is wildcard is specified, we suppose parent dir exist, so exit immediately
953 if (ph->fsphStrChr(szPath, '*') || ph->fsphStrChr(szPath, '?'))
954 {
955 return ERROR_FILE_NOT_FOUND;
956 }
957
958
959 do {
960
961 rc = pathparser(pRes, pConn, szPath, path);
962 debuglocal(9,"NdpQueryPathInfo pathparser for <%s> rc=%d\n", path, rc);
963 switch (rc)
964 {
965 case NO_ERROR :
966 case ERROR_FILE_NOT_FOUND:
967 case ERROR_PATH_NOT_FOUND:
968 case ERROR_ACCESS_DENIED:
969 case ERROR_INVALID_PARAMETER:
970 {
971 break;
972 }
973 default :
974 {
975 rc = ERROR_PATH_NOT_FOUND;
976 }
977 }
978 if (rc)
979 {
980 break;
981 }
982 StrNCpy(finfo.fname, path, sizeof(finfo.fname) - 1);
983 debuglocal(9,"NdpQueryPathInfo smbwrp_getattr for <%s>\n", path);
984 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo);
985 if (rc)
986 {
987 // remote server not available for first time?
988 if (rc == ERROR_REM_NOT_LIST && retry == 0)
989 {
990 // free current cli resources
991 smbwrp_disconnect( pRes, pConn->cli);
992 // reconnect
993 smbwrp_connect( pRes, &pConn->cli);
994 // try file list again
995 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo);
996 debuglocal(9,"NdpQueryPathInfo remote connection lost, retry rc = %d\n", rc);
997 }
998 switch (rc)
999 {
1000 case NO_ERROR :
1001 case ERROR_FILE_NOT_FOUND:
1002 case ERROR_PATH_NOT_FOUND:
1003 case ERROR_ACCESS_DENIED:
1004 case ERROR_INVALID_PARAMETER:
1005 case ERROR_REM_NOT_LIST:
1006 break;
1007 default :
1008 {
1009 rc = ERROR_PATH_NOT_FOUND;
1010 }
1011 }
1012 }
1013 else
1014 {
1015 finfo.easize = -1;
1016 getfindinfoL(pConn, plist, &finfo, 0, NULL);
1017 }
1018 if (rc == ERROR_FILE_NOT_FOUND)
1019 {
1020 // now try the upper path
1021 char * p = ph->fsphStrChr(finfo.fname, '\\');
1022 if (p && p > finfo.fname)
1023 {
1024 *p = 0;
1025 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo);
1026 if (rc)
1027 {
1028 debuglocal(9,"NdpQueryPathInfo upper path in <%s>, retry = %d\n", finfo.fname, retry);
1029 rc = rc ? ERROR_PATH_NOT_FOUND : ERROR_INVALID_PARAMETER;
1030 }
1031 }
1032 }
1033 } while (0);
1034 debuglocal(9,"NdpQueryPathInfo <%s> (%s) %d\n", szPath, path, rc);
1035
1036 return rc;
1037}
1038
1039// -------------------------------------------------------------
1040
1041int APIENTRY NdpFindStart (HCONNECTION conn, void *plist, NDFILEINFOL *pfiparent, char *szPath, ULONG ulAttribute)
1042{
1043 Connection *pConn = (Connection *)conn;
1044 Resource *pRes = pConn->pRes;
1045 int rc = NO_ERROR, count = 0;
1046 unsigned long action;
1047 char *mask = "*";
1048 char dir[CCHMAXPATH+1] = {0};
1049 char path[CCHMAXPATH+1] = {0};
1050 smbwrp_fileinfo * data;
1051 NDPATHELEMENT *pel = ph->fsphNameElem(0);
1052 filelist_state state;
1053 char * p;
1054
1055 debug_printf("NdpFindStart in\n");
1056
1057 StrNCpy(dir, szPath, sizeof(dir) - 1);
1058 if (pel)
1059 {
1060 mask = pel->name;
1061 dir[StrLen(szPath) - pel->length] = 0;
1062 }
1063 action = StrLen(dir) - 1;
1064 if (dir[action] == '\\')
1065 {
1066 dir[action] = 0;
1067 }
1068 rc = pathparser(pRes, pConn, dir, path);
1069 if (rc)
1070 {
1071 return rc;
1072 }
1073 action = StrLen(path) - 1;
1074 if (path[action] != '\\')
1075 {
1076 StrNCat(path, "\\", sizeof(path) - 1);
1077 }
1078 StrCpy(dir, path);
1079 StrNCat(path, mask, sizeof(path) - 1);
1080
1081 // this structure will be used by libsmb callbacks, so we store here all we need
1082 // to fill netdrive structures
1083 state.pConn = pConn;
1084 state.plist = plist;
1085 state.ulAttribute = ulAttribute;
1086 strcpy( state.dir, dir);
1087 strcpy( state.dir_mask, mask);
1088 strcpy( state.mask, path);
1089 p = getlastslash(state.mask);
1090 if (p)
1091 {
1092 *(p + 1) = '*';
1093 *(p + 2) = 0;
1094 }
1095 else
1096 {
1097 strcpy(state.mask, "\\*");
1098 }
1099 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state);
1100 // we need to handle reconnection also here, because NdpQueryPathInfo
1101 // could be called with '*' and exit then immediately (without calling libsmb)
1102 if (rc == ERROR_REM_NOT_LIST)
1103 {
1104 // free current cli resources
1105 smbwrp_disconnect( pRes, pConn->cli);
1106 // reconnect
1107 smbwrp_connect( pRes, &pConn->cli);
1108 // try file list again next loop
1109 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state);
1110 debuglocal(9,"NdpFindStart remote connection lost, retry rc = %d\n", rc);
1111 }
1112
1113 debuglocal(9,"NdpFindStart <%s> (%s) cnt %d %d\n", szPath, path, count, rc);
1114
1115 return rc;
1116}
1117
1118int APIENTRY NdpDeletePathInfo (HRESOURCE resource, NDFILEINFOL *pfi)
1119{
1120// debuglocal(9,"NdpDeletePathInfo %d\n", 0);
1121 return NO_ERROR;
1122}
1123
1124int APIENTRY NdpRefresh (HCONNECTION conn, char *path, int tree)
1125{
1126 debuglocal(9,"NdpRefresh <%s> %d\n", path, 0);
1127 return NO_ERROR;
1128}
1129
1130int APIENTRY NdpDiscardResourceData (HRESOURCE resource, NDDATABUF *pdatabuf)
1131{
1132 // The plugin do not have to deallocate anything
1133 // because resource data did not contain any pointers
1134 // to plugins data.
1135 // Data stored by fsphSetResourceData will be
1136 // deallocated by NetDrive.
1137
1138 debuglocal(9,"NdpDicardresourceData %d\n", 0);
1139 return NO_ERROR;
1140}
1141
1142int APIENTRY NdpSetPathInfo (HCONNECTION conn, NDFILEINFOL *pfi, char *szPathName)
1143{
1144 Connection *pConn = (Connection *)conn;
1145 Resource *pRes = pConn->pRes;
1146 int rc = 0;
1147 unsigned long action;
1148 char path[CCHMAXPATH+1] = {0};
1149 smbwrp_fileinfo finfo;
1150
1151 debug_printf("NdpSetPathInfo in FIXME\n");
1152
1153 do {
1154 rc = pathparser(pRes, pConn, szPathName, path);
1155 if (rc)
1156 {
1157 break;
1158 }
1159
1160 MemSet(&finfo, 0, sizeof(finfo));
1161
1162 StrNCpy(finfo.fname, path, sizeof(finfo.fname) - 1);
1163 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(finfo.mtime));
1164 finfo.attr = pfi->stat.attrFile & 0x37;
1165 rc = smbwrp_setattr(pConn->cli, &finfo);
1166 } while (0);
1167 debuglocal(9,"NdpSetPathInfo <%s> (%s) %d\n", szPathName, path, rc);
1168
1169 return rc;
1170}
1171
1172int buildFEALIST(FEALIST *pFEASrc, GEALIST *pGEAList, FEALIST *pFEAList)
1173{
1174 int rc = 0;
1175 FEA * pfea;
1176 FEA * pfeadest;
1177 unsigned long size, done = sizeof(pFEAList->cbList), dsize, ddone = sizeof(pFEAList->cbList);
1178
1179 size = pFEASrc->cbList;
1180 pfea = pFEASrc->list;
1181 pfeadest = pFEAList->list;
1182 dsize = pFEAList->cbList;
1183//debuglocal(9,"buildFEALIST in destsize %d srcsize %d pGEAList=%08x pGEAList->cbList=%d\n", dsize, ddone, size, pGEAList, pGEAList ? pGEAList->cbList : 0);
1184 while (done < size)
1185 {
1186 char * name = (char *)(pfea + 1);
1187 int insert = 1;
1188 if (pGEAList && pGEAList->cbList > sizeof(pGEAList->cbList))
1189 {
1190 GEA * pgea = pGEAList->list;
1191 unsigned long size = pGEAList->cbList - sizeof(pGEAList->cbList), done = 0;
1192 insert = 0;
1193 while (done < size)
1194 {
1195//debuglocal(9,"comp <%s> <%s>\n", name, pgea->szName);
1196 if (!ph->fsphStrNCmp(name, pgea->szName, pgea->cbName))
1197 {
1198 insert = 1;
1199 break;
1200 }
1201 done += pgea->cbName + 2;
1202 pgea = (GEA *)((char *)pgea + pgea->cbName + 2);
1203 }
1204 }
1205 if (insert)
1206 {
1207 ddone += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1208 if (ddone <= dsize)
1209 {
1210 pfeadest->cbName = pfea->cbName;
1211 pfeadest->cbValue = pfea->cbValue;
1212 pfeadest->fEA = 0;
1213 StrCpy((char *)(pfeadest + 1), name);
1214 MemCpy((char *)(pfeadest + 1) + pfea->cbName + 1, (char *)(pfea + 1) + pfea->cbName + 1, pfea->cbValue);
1215 pfeadest = (FEA *)((char *)pFEAList + ddone);
1216 }
1217 }
1218 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1219//debuglocal(9,"buuildfea <%s> insert=%d pfea->cbName=%d pfea->cbValue=%d srcdone=%d destdone=%d pfeadest=%08x pfea=%08x\n", name, insert, pfea->cbName, pfea->cbValue, done, ddone, pfeadest, pfea);
1220 pfea = (FEA *)((char *)pFEASrc + done);
1221 }
1222 pFEAList->cbList = ddone;
1223 if (ddone > dsize && dsize > sizeof(pFEAList->cbList))
1224 {
1225 rc = ERROR_BUFFER_OVERFLOW;
1226 }
1227 debuglocal(9,"buildFEALIST rc=%d destsize=%d destdone=%d srcsize=%d pGEAList=%08x\n", rc, dsize, ddone, size, pGEAList);
1228 return rc;
1229}
1230
1231int APIENTRY NdpEAQuery (HCONNECTION conn, GEALIST *pGEAList, NDFILEINFOL *pfi, FEALIST *pFEAList)
1232{
1233 Connection *pConn = (Connection *)conn;
1234 Resource *pRes = pConn->pRes;
1235 int rc = 0;
1236 unsigned long action;
1237 char * path = NULL;
1238 FEALIST * pFEASrc;
1239 NDDATABUF fdata = {0};
1240 smbwrp_fileinfo *finfo;
1241 char pBuffer[64*1024];
1242
1243 if (!pfi || !pfi->pszName || !pFEAList)
1244 {
1245 return ERROR_EAS_NOT_SUPPORTED;
1246 }
1247 if (!pRes->easupport)
1248 {
1249 return ERROR_EAS_NOT_SUPPORTED;
1250 }
1251
1252 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1253 if (rc || !fdata.ulSize || !fdata.pData)
1254 {
1255 debuglocal(9,"NdpEAQuery: ph->fsphGetFileInfoData = %d/%d %08x\n", rc, fdata.ulSize, fdata.pData);
1256 return ERROR_EAS_NOT_SUPPORTED;
1257 }
1258 finfo = (smbwrp_fileinfo *)fdata.pData;
1259 path = finfo->fname;
1260
1261 debuglocal(9,"NdpEAQuery in <%s> %08x %d\n", path, pGEAList, pGEAList ? pGEAList->cbList : 0);
1262
1263 do {
1264 rc = smbwrp_listea( pConn->cli, path, pBuffer, sizeof( pBuffer));
1265 pFEASrc = (FEALIST*) pBuffer;
1266 if (rc)
1267 {
1268 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1269 switch (rc)
1270 {
1271 case ERROR_FILE_NOT_FOUND :
1272 case ERROR_PATH_NOT_FOUND :
1273 {
1274 pFEAList->cbList = sizeof(pFEAList->cbList);
1275 rc = NO_ERROR;
1276 } break;
1277 case ERROR_BUFFER_OVERFLOW :
1278 {
1279 pFEAList->cbList = pFEASrc->cbList;
1280 } break;
1281 default :
1282 {
1283 rc = ERROR_EAS_NOT_SUPPORTED;
1284 }
1285 }
1286 }
1287 else
1288 {
1289 rc = buildFEALIST((FEALIST *)pFEASrc, pGEAList, pFEAList);
1290 }
1291 } while (0);
1292 debuglocal(9,"NdpEAQuery <%s> %d %d %d\n", pfi->pszName, rc, pFEASrc->cbList, pFEAList->cbList);
1293
1294 return rc;
1295}
1296
1297int APIENTRY NdpEASet (HCONNECTION conn, FEALIST *pFEAList, NDFILEINFOL *pfi)
1298{
1299 Connection *pConn = (Connection *)conn;
1300 Resource *pRes = pConn->pRes;
1301 int rc = 0;
1302 char * path;
1303 unsigned long action;
1304 NDDATABUF fdata = {0};
1305 smbwrp_fileinfo *finfo;
1306
1307 debuglocal(9,"NdpEASet in\n");
1308
1309 if (!pfi || !pfi->pszName || !pFEAList || pFEAList->cbList <= sizeof(long))
1310 {
1311 return ERROR_EAS_NOT_SUPPORTED;
1312 }
1313 if (!pRes->easupport)
1314 {
1315 return ERROR_EAS_NOT_SUPPORTED;
1316 }
1317
1318 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1319 if (rc || !fdata.ulSize || !fdata.pData)
1320 {
1321 debuglocal(9,"NdpEASet: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData);
1322 return ERROR_EAS_NOT_SUPPORTED;
1323 }
1324 finfo = (smbwrp_fileinfo *)fdata.pData;
1325 path = finfo->fname;
1326
1327 do {
1328 // got FEA there
1329 FEA * pfea;
1330 unsigned long done = sizeof(long);
1331 pfea = pFEAList->list;
1332 while (done < pFEAList->cbList)
1333 {
1334 rc = smbwrp_setea(pConn->cli, path, (char*)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue);
1335 if (rc)
1336 {
1337 break;
1338 }
1339 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue);
1340 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1341 }
1342 } while (0);
1343 debuglocal(9,"NdpEASet %d\n", rc);
1344
1345 return rc;
1346}
1347
1348int APIENTRY NdpEASize (HCONNECTION conn, NDFILEINFOL *pfi, ULONG *pulEASize)
1349{
1350 Connection *pConn = (Connection *)conn;
1351 Resource *pRes = pConn->pRes;
1352 int rc = 0;
1353 unsigned long action;
1354 char * path = NULL;
1355 FEALIST * pfealist;
1356 NDDATABUF fdata = {0};
1357 smbwrp_fileinfo *finfo;
1358 char pBuffer[64*1024];
1359 int easize;
1360
1361 if (!pfi || !pulEASize)
1362 {
1363 return ERROR_EAS_NOT_SUPPORTED;
1364 }
1365 if (!pRes->easupport)
1366 {
1367 return ERROR_EAS_NOT_SUPPORTED;
1368 }
1369
1370 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1371 if (rc || !fdata.ulSize || !fdata.pData)
1372 {
1373 debuglocal(9,"NdpEASize: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData);
1374 return ERROR_EAS_NOT_SUPPORTED;
1375 }
1376 finfo = (smbwrp_fileinfo *)fdata.pData;
1377 easize = finfo->easize;
1378 finfo->easize = -1;
1379 path = finfo->fname;
1380 if (easize >= 0)
1381 {
1382 *pulEASize = easize;
1383 debuglocal(9,"NdpEASize <%s> cached %d\n", path, easize);
1384 return NO_ERROR;
1385 }
1386
1387 debuglocal(9,"NdpEASize in <%s> \n", path);
1388
1389 do {
1390 rc = smbwrp_listea(pConn->cli, path, pBuffer, sizeof( pBuffer));
1391 pfealist = (FEALIST*)pBuffer;
1392 if (rc)
1393 {
1394 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1395 switch (rc)
1396 {
1397 case ERROR_FILE_NOT_FOUND :
1398 case ERROR_PATH_NOT_FOUND :
1399 {
1400 pfealist->cbList = sizeof(pfealist->cbList);
1401 } /* Fall through */
1402 case ERROR_BUFFER_OVERFLOW :
1403 {
1404 rc = NO_ERROR;
1405 } break;
1406 default :
1407 {
1408 rc = ERROR_EAS_NOT_SUPPORTED;
1409 }
1410 }
1411 }
1412 *pulEASize = pfealist->cbList;
1413 } while (0);
1414 debuglocal(9,"NdpEASize <%s> %d %d\n", pfi->pszName, *pulEASize, rc);
1415
1416 return rc;
1417}
1418
1419int APIENTRY NdpSetCurrentDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szPath)
1420{
1421 Connection *pConn = (Connection *)conn;
1422 Resource *pRes = pConn->pRes;
1423 int rc = 0;
1424 unsigned long action;
1425 char path[CCHMAXPATH+1] = {0};
1426
1427 debuglocal(9,"NdpSetCurrentDir in\n");
1428
1429 do {
1430 rc = pathparser(pRes, pConn, szPath, path);
1431 if (rc)
1432 {
1433 break;
1434 }
1435
1436 rc = smbwrp_chdir(&pRes->srv, pConn->cli, path);
1437 } while (0);
1438 debuglocal(9,"NdpSetCurrentDir <%s> (%s) %d\n", szPath, path, rc);
1439
1440 return rc;
1441}
1442
1443int APIENTRY NdpCopy (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
1444{
1445 debuglocal(9,"NdpCopy <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
1446 return ERROR_CANNOT_COPY;
1447}
1448
1449int APIENTRY NdpCopy2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
1450{
1451 debuglocal(9,"NdpCopy2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
1452 return ERROR_CANNOT_COPY;
1453}
1454
1455int APIENTRY NdpForceDelete (HCONNECTION conn, NDFILEINFOL *pfi, char *szFile)
1456{
1457 Connection *pConn = (Connection *)conn;
1458 Resource *pRes = pConn->pRes;
1459 int rc = 0;
1460 unsigned long action;
1461 char path[CCHMAXPATH+1] = {0};
1462
1463 debuglocal(9,"NdpForceDelete in\n");
1464
1465 do {
1466 rc = pathparser(pRes, pConn, szFile, path);
1467 if (rc)
1468 {
1469 break;
1470 }
1471
1472 rc = smbwrp_unlink(pConn->cli, path);
1473 } while (0);
1474 debuglocal(9,"NdpForceDelete <%s> (%s) %d\n", szFile, path, rc);
1475
1476 return rc;
1477}
1478
1479int APIENTRY NdpCreateDir (HCONNECTION conn, NDFILEINFOL *pfiparent, char *szDirName, FEALIST *pFEAList)
1480{
1481 Connection *pConn = (Connection *)conn;
1482 Resource *pRes = pConn->pRes;
1483 int rc = 0;
1484 unsigned long action;
1485 char path[CCHMAXPATH+1] = {0};
1486
1487 debuglocal(9,"NdpCreateDir in\n");
1488
1489 do {
1490 rc = pathparser(pRes, pConn, szDirName, path);
1491 if (rc)
1492 {
1493 break;
1494 }
1495
1496 rc = smbwrp_mkdir(pConn->cli, path);
1497 } while (0);
1498 debuglocal(9,"NdpCreateDir <%s> (%s) %d\n", szDirName, path, rc);
1499
1500 return rc;
1501}
1502
1503int APIENTRY NdpDeleteDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szDir)
1504{
1505 Connection *pConn = (Connection *)conn;
1506 Resource *pRes = pConn->pRes;
1507 int rc = 0;
1508 unsigned long action;
1509 char path[CCHMAXPATH+1] = {0};
1510
1511 debuglocal(9,"NdpDeleteDir in\n");
1512
1513 do {
1514 rc = pathparser(pRes, pConn, szDir, path);
1515 if (rc)
1516 {
1517 break;
1518 }
1519
1520 rc = smbwrp_rmdir(pConn->cli, path);
1521 } while (0);
1522 debuglocal(9,"NdpDeleteDir <%s> (%s) %d\n", szDir, path, rc);
1523
1524 return rc;
1525}
1526
1527int APIENTRY NdpMove (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
1528{
1529 Connection *pConn = (Connection *)conn;
1530 Resource *pRes = pConn->pRes;
1531 int rc = 0;
1532 unsigned long action;
1533 char src[CCHMAXPATH+1] = {0};
1534 int l1, l2;
1535 char * p = szDst;
1536
1537 debuglocal(9,"NdpMove in from <%s> to <%s>\n", szSrc, szDst);
1538
1539 do
1540 {
1541 rc = pathparser(pRes, pConn, szSrc, src);
1542 if (rc)
1543 {
1544 break;
1545 }
1546 l1 = StrLen(szSrc);
1547 l2 = StrLen(src);
1548 if (l1 > l2)
1549 {
1550 if (ph->fsphStrNICmp(szSrc, szDst, l1 - l2))
1551 {
1552 // the file moved accross different shares or servers or workgroups
1553 rc = ERROR_WRITE_PROTECT;
1554 break;
1555 }
1556 p = szDst + l1 - l2 + 1;
1557 }
1558 //pConn->mem[CCHMAXPATH + 1] = '\\';
1559 rc = smbwrp_rename(pConn->cli, src, p);
1560 } while (0);
1561 debuglocal(9,"NdpMove <%s> -> <%s> (%s) %d\n", szSrc, szDst, src, rc);
1562
1563 return rc;
1564}
1565
1566int APIENTRY NdpMove2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
1567{
1568 debuglocal(9,"NdpMove2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_WRITE_PROTECT);
1569 return ERROR_WRITE_PROTECT;
1570}
1571
1572
1573int APIENTRY NdpChangeCase (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
1574{
1575 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
1576}
1577
1578int APIENTRY NdpRename (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
1579{
1580 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
1581}
1582
1583int smbopen(Connection *pConn, char *szFileName, int flags, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1584{
1585 Resource *pRes = pConn->pRes;
1586 unsigned long action;
1587 int rc = 0;
1588 char path[CCHMAXPATH+1] = {0};
1589
1590 debuglocal(9,"smbopen in %d\n", pConn->file.fd);
1591
1592 do {
1593 if (pConn->file.fd > 0)
1594 {
1595 rc = ERROR_TOO_MANY_OPEN_FILES;
1596 break;
1597 }
1598
1599 rc = pathparser(pRes, pConn, szFileName, path);
1600 if (rc)
1601 {
1602 break;
1603 }
1604
1605 StrNCpy(pConn->file.fullname, szFileName, sizeof(pConn->file.fullname) - 1);
1606 StrNCpy(pConn->file.fname, path, sizeof(pConn->file.fname) - 1);
1607 flags |= O_BINARY;
1608 switch (ulOpenMode & 3)
1609 {
1610 case OPEN_ACCESS_READONLY : flags |= O_RDONLY; break;
1611 case OPEN_ACCESS_WRITEONLY : flags |= O_WRONLY; break;
1612 case OPEN_ACCESS_READWRITE : flags |= O_RDWR; break;
1613 default : flags |= O_RDWR;
1614 }
1615 pConn->file.openmode = flags;
1616 pConn->file.openattr = ulAttribute & 0x37;
1617 pConn->file.denymode = (ulOpenMode & 0x70) >> 4;
1618 rc = smbwrp_open(pConn->cli, &pConn->file);
1619 } while (0);
1620 debuglocal(9,"smbopen <%s> (%s) %08x %08x %08x %d. file = %d\n", szFileName, path, flags, ulOpenMode, ulAttribute, rc, pConn->file.fd);
1621 if (!rc && pFEAList)
1622 {
1623 int rc1 = NdpFileEASet((HCONNECTION)pConn, (NDFILEHANDLE)0, pFEAList);
1624 debuglocal(9,"smbopen NdpFileEASet %d. pFEAList->cbList %d\n", rc1, pFEAList->cbList);
1625 }
1626
1627 return rc;
1628}
1629
1630int APIENTRY NdpOpenReplace (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1631{
1632 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
1633}
1634
1635int APIENTRY NdpOpenReplaceL(HCONNECTION conn, NDFILEINFO *pfi, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1636{
1637 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
1638}
1639
1640int APIENTRY NdpOpenCreate (HCONNECTION conn, NDFILEINFOL *pfiparent, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1641{
1642// return smbopen((Connection *)conn, szFileName, O_CREAT, ulOpenMode, ulAttribute);
1643 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);
1644}
1645
1646int APIENTRY NdpOpenCreateL(HCONNECTION conn, NDFILEINFO *pfiparent, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1647{
1648 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);
1649}
1650
1651int APIENTRY NdpOpenExisting (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulOpenMode, USHORT *pfNeedEA)
1652{
1653 if (pfNeedEA) *pfNeedEA = 0; // wtf is this ?
1654 return smbopen((Connection *)conn, szFileName, 0, ulOpenMode, 0, NULL);
1655}
1656
1657int APIENTRY NdpSetFileAttribute (HCONNECTION conn, NDFILEINFOL *pfi, char *szFileName, USHORT usAttr)
1658{
1659 Connection *pConn = (Connection *)conn;
1660 Resource *pRes = pConn->pRes;
1661 int rc = 0;
1662 unsigned long action;
1663
1664 smbwrp_fileinfo finfo;
1665 char path[CCHMAXPATH+1] = {0};
1666
1667 debuglocal(9,"NdpSetFileAttribute in\n");
1668 do {
1669 rc = pathparser(pRes, pConn, szFileName, path);
1670 if (rc)
1671 {
1672 break;
1673 }
1674
1675 MemSet(&finfo, 0, sizeof(finfo));
1676 StrNCpy(finfo.fname, path, sizeof(finfo.fname) - 1);
1677 finfo.attr = usAttr & 0x37;
1678 rc = smbwrp_setattr(pConn->cli, &finfo);
1679 } while (0);
1680 debuglocal(9,"NdpSetFileAttribute <%s> (%s) %04x %d\n", szFileName, path, usAttr, rc);
1681
1682 return rc;
1683}
1684
1685int APIENTRY NdpFlush (HRESOURCE resource)
1686{
1687 debuglocal(9,"NdpFlush %d\n", ERROR_NOT_SUPPORTED);
1688 return ERROR_NOT_SUPPORTED;
1689}
1690
1691int APIENTRY NdpIOCTL (int type, HRESOURCE resource, char *path, int function, void *in, ULONG insize, PULONG poutlen)
1692{
1693 debuglocal(9,"NdpIOCTL <%s> %d\n", path, function);
1694
1695 if (in && insize > 4096)
1696 {
1697 char out[4096];
1698 sprintf (out, "SAMBA IOCTL function = %d, parms [%s] insize = %d, *poutlen = %d", function, in, insize, *poutlen);
1699 *poutlen = strlen(out);
1700 strcpy (in, out);
1701 return NO_ERROR;
1702 }
1703
1704 return ERROR_NOT_SUPPORTED;
1705}
1706
1707int APIENTRY NdpFileQueryInfo (HCONNECTION conn, NDFILEHANDLE handle, void *plist)
1708{
1709 Connection *pConn = (Connection *)conn;
1710 Resource *pRes = pConn->pRes;
1711 int rc = 0;
1712 unsigned long action;
1713 smbwrp_fileinfo finfo;
1714
1715 debug_printf("NdpFileQueryInfo in\n");
1716 do {
1717 if (pConn->file.fd < 0 || !*pConn->file.fname)
1718 {
1719 rc = ERROR_INVALID_HANDLE;
1720 break;
1721 }
1722 StrNCpy(finfo.fname, pConn->file.fname, sizeof(finfo.fname) - 1);
1723 rc = smbwrp_fgetattr(pConn->cli, &pConn->file, &finfo);
1724 if (!rc)
1725 {
1726 finfo.easize = -1;
1727 getfindinfoL(pConn, plist, &finfo, 0, NULL);
1728 }
1729 } while (0);
1730 debuglocal(9,"NdpFileQueryInfo <%s> %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, rc);
1731
1732 return rc;
1733}
1734
1735int APIENTRY NdpFileEAQuery (HCONNECTION conn, NDFILEHANDLE handle, GEALIST *pGEAList, FEALIST *pFEAList)
1736{
1737 Connection *pConn = (Connection *)conn;
1738 Resource *pRes = pConn->pRes;
1739 int rc = 0;
1740 unsigned long action;
1741 char pBuffer[64*1024];
1742 FEALIST * pFEASrc;
1743
1744 if (!pFEAList)
1745 {
1746 return ERROR_EAS_NOT_SUPPORTED;
1747 }
1748 if (!pRes->easupport)
1749 {
1750 return ERROR_EAS_NOT_SUPPORTED;
1751 }
1752
1753 debuglocal(9,"NdpFileEAQuery in <%s>/%d pGEAList=%08x\n", pConn->file.fname, pConn->file.fd, pGEAList);
1754 do {
1755 if (pConn->file.fd < 0)
1756 {
1757 rc = ERROR_INVALID_HANDLE;
1758 break;
1759 }
1760 rc = smbwrp_flistea(pConn->cli, &pConn->file, pBuffer, sizeof( pBuffer));
1761 pFEASrc = (FEALIST *) pBuffer;
1762 if (rc)
1763 {
1764 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1765 switch (rc)
1766 {
1767 case ERROR_FILE_NOT_FOUND :
1768 case ERROR_PATH_NOT_FOUND :
1769 {
1770 pFEAList->cbList = sizeof(pFEAList->cbList);
1771 rc = NO_ERROR;
1772 } break;
1773 case ERROR_BUFFER_OVERFLOW :
1774 {
1775 pFEAList->cbList = pFEASrc->cbList;
1776 } break;
1777 default :
1778 {
1779 rc = ERROR_EAS_NOT_SUPPORTED;
1780 }
1781 }
1782 }
1783 else
1784 {
1785 rc = buildFEALIST(pFEASrc, pGEAList, pFEAList);
1786 }
1787 } while (0);
1788 debuglocal(9,"NdpFileEAQuery out <%s>/%d pFEASrc->cbList=%d pFEAList->cbList=%d rc=%d\n", pConn->file.fname, pConn->file.fd, pFEASrc->cbList, pFEAList->cbList, rc);
1789
1790 return rc;
1791}
1792
1793int APIENTRY NdpFileEASet (HCONNECTION conn, NDFILEHANDLE handle, FEALIST *pFEAList)
1794{
1795 Connection *pConn = (Connection *)conn;
1796 Resource *pRes = pConn->pRes;
1797 int rc = 0;
1798 unsigned long action;
1799
1800 debuglocal(9,"NdpFileEASet in\n");
1801
1802 if (!pFEAList || pFEAList->cbList <= sizeof(long))
1803 {
1804 return ERROR_EAS_NOT_SUPPORTED;
1805 }
1806 if (!pRes->easupport)
1807 {
1808 return ERROR_EAS_NOT_SUPPORTED;
1809 }
1810
1811 do {
1812 // got FEA there
1813 FEA * pfea;
1814 unsigned long done = sizeof(long);
1815 if (pConn->file.fd < 0)
1816 {
1817 rc = ERROR_INVALID_HANDLE;
1818 break;
1819 }
1820
1821 pfea = pFEAList->list;
1822 while (done < pFEAList->cbList)
1823 {
1824 rc = smbwrp_fsetea(pConn->cli, &pConn->file, (char *)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue);
1825 if (rc)
1826 {
1827 break;
1828 }
1829 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue);
1830 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1831 }
1832
1833 } while (0);
1834 debuglocal(9,"NdpFileEASet %d\n", rc);
1835
1836 return rc;
1837}
1838
1839int APIENTRY NdpFileEASize (HCONNECTION conn, NDFILEHANDLE handle, ULONG *pulEASize)
1840{
1841 Connection *pConn = (Connection *)conn;
1842 Resource *pRes = pConn->pRes;
1843 int rc = 0;
1844 unsigned long action;
1845 char path[CCHMAXPATH+1] = {0};
1846 FEALIST * pFEAList;
1847 char pBuffer[64*1024];
1848
1849 if (!pulEASize)
1850 {
1851 return ERROR_EAS_NOT_SUPPORTED;
1852 }
1853 if (!pRes->easupport)
1854 {
1855 return ERROR_EAS_NOT_SUPPORTED;
1856 }
1857
1858 debuglocal(9,"NdpFileEASize in <%s>/%d \n", pConn->file.fname, pConn->file.fd);
1859 do {
1860 if (pConn->file.fd < 0)
1861 {
1862 rc = ERROR_INVALID_HANDLE;
1863 break;
1864 }
1865 rc = smbwrp_flistea(pConn->cli, &pConn->file, pBuffer, sizeof(pBuffer));
1866 pFEAList = (FEALIST*) pBuffer;
1867 if (rc)
1868 {
1869 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1870 switch (rc)
1871 {
1872 case ERROR_FILE_NOT_FOUND :
1873 case ERROR_PATH_NOT_FOUND :
1874 {
1875 pFEAList->cbList = sizeof(pFEAList->cbList);
1876 } /* Fall through */
1877 case ERROR_BUFFER_OVERFLOW :
1878 {
1879 rc = NO_ERROR;
1880 } break;
1881 default :
1882 {
1883 rc = ERROR_EAS_NOT_SUPPORTED;
1884 }
1885 }
1886 }
1887 *pulEASize = pFEAList->cbList;
1888 } while (0);
1889 debuglocal(9,"NdpFileEASize %d %d\n", *pulEASize, rc);
1890
1891 return rc;
1892}
1893
1894int APIENTRY NdpFileSetInfo (HCONNECTION conn, NDFILEHANDLE handle, NDFILEINFOL *pfi)
1895{
1896 Connection *pConn = (Connection *)conn;
1897 Resource *pRes = pConn->pRes;
1898 int rc = 0;
1899 unsigned long action, attrFile;
1900
1901 debug_printf("NdpFileSetInfo in\n");
1902 do {
1903 if (pConn->file.fd < 0 || !*pConn->file.fname)
1904 {
1905 rc = ERROR_INVALID_HANDLE;
1906 break;
1907 }
1908 attrFile = pfi->stat.attrFile;
1909 // deferred setinfo - on closing the file
1910 pConn->file.openattr = attrFile;
1911 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(pConn->file.mtime));
1912 debug_printf("NdpFileSetInfo mtime %d\n", pConn->file.mtime);
1913 } while (0);
1914 debuglocal(9,"NdpFileSetInfo <%s> %08x %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, attrFile, rc);
1915
1916 return NO_ERROR;
1917}
1918
1919int APIENTRY NdpFileSetFilePtrL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llOffset, ULONG ulMethod, LONGLONG *pllActual)
1920{
1921 Connection *pConn = (Connection *)conn;
1922 Resource *pRes = pConn->pRes;
1923 int rc = 0;
1924 unsigned long action;
1925
1926 debuglocal(9,"NdpFileSetFilePtrl in\n");
1927
1928 do {
1929 if (pConn->file.fd < 0)
1930 {
1931 rc = ERROR_INVALID_HANDLE;
1932 break;
1933 }
1934
1935 rc = smbwrp_lseek(pConn->cli, &pConn->file, ulMethod, llOffset);
1936 if (!rc)
1937 *pllActual = pConn->file.offset;
1938
1939 } while (0);
1940 debuglocal(9,"NdpFileSetFilePtrL <%s> %lld %lu %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llOffset, ulMethod, *pllActual, rc);
1941
1942 return rc;
1943}
1944
1945int APIENTRY NdpFileSetFilePtr (HCONNECTION conn, NDFILEHANDLE handle, LONG lOffset, ULONG ulMethod, ULONG *pulActual)
1946{
1947 LONGLONG llActual;
1948 int rc = NdpFileSetFilePtrL(conn, handle, lOffset, ulMethod, &llActual);
1949 *pulActual = llActual & 0xFFFFFFFF;
1950 debuglocal(9,"NdpFileSetFilePtr %ld %lu %ld %d\n", lOffset, ulMethod, *pulActual, rc);
1951 return rc;
1952}
1953
1954int APIENTRY NdpFileClose (HCONNECTION conn, NDFILEHANDLE handle)
1955{
1956 Connection *pConn = (Connection *)conn;
1957 Resource *pRes = pConn->pRes;
1958 int rc = 0;
1959 unsigned long action;
1960
1961 debuglocal(9,"NdpFileClose in %d <%s>\n", pConn->file.fd, pConn->file.fd < 0 ? "!null!" : pConn->file.fname);
1962
1963 do {
1964 if (pConn->file.fd < 0)
1965 {
1966 rc = ERROR_INVALID_HANDLE;
1967 break;
1968 }
1969
1970 rc = smbwrp_close(pConn->cli, &pConn->file);
1971
1972 } while (0);
1973 debuglocal(9,"NdpFileClose %d %d\n", pConn->file.fd, rc);
1974
1975 pConn->file.fd = -1;
1976 return rc;
1977}
1978
1979int APIENTRY NdpFileCommit (HCONNECTION conn, NDFILEHANDLE handle)
1980{
1981 debuglocal(9,"NdpFileCommit %d\n", NO_ERROR);
1982 return NO_ERROR;
1983}
1984
1985
1986int APIENTRY NdpFileNewSize (HCONNECTION conn, NDFILEHANDLE handle, ULONG ulLen)
1987{
1988 int rc = NdpFileNewSizeL(conn, handle, ulLen);
1989 debuglocal(9,"NdpFileNewSize %ld %d\n", ulLen, rc);
1990 return rc;
1991}
1992
1993int APIENTRY NdpFileNewSizeL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llLen)
1994{
1995 Connection *pConn = (Connection *)conn;
1996 Resource *pRes = pConn->pRes;
1997 int rc = 0;
1998 unsigned long action;
1999
2000 debuglocal(9,"NdpFileNewSizeL in\n");
2001
2002 do {
2003 if (pConn->file.fd < 0)
2004 {
2005 rc = ERROR_INVALID_HANDLE;
2006 break;
2007 }
2008
2009 rc = smbwrp_setfilesize(pConn->cli, &pConn->file, llLen);
2010
2011 } while (0);
2012 debuglocal(9,"NdpFileNewSizeL <%s> %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llLen, rc);
2013
2014 return rc;
2015}
2016
2017int APIENTRY NdpFileRead (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulRead, ULONG *pulActual)
2018{
2019 Connection *pConn = (Connection *)conn;
2020 Resource *pRes = pConn->pRes;
2021 int rc = 0;
2022 unsigned long done = 0;
2023 unsigned long onedone;
2024 unsigned long action;
2025
2026 debuglocal(9,"NdpFileRead in\n");
2027
2028 do {
2029 if (pConn->file.fd < 0)
2030 {
2031 rc = ERROR_INVALID_HANDLE;
2032 break;
2033 }
2034 rc = smbwrp_read(pConn->cli, &pConn->file, pBuffer, ulRead, pulActual);
2035 //*pulActual = ulRead;
2036 //DosSleep(0);
2037
2038 } while (0);
2039 debuglocal(9,"NdpFileRead <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulRead, *pulActual, rc);
2040
2041 return rc;
2042}
2043
2044int APIENTRY NdpFileWrite (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulWrite, ULONG *pulActual)
2045{
2046 Connection *pConn = (Connection *)conn;
2047 Resource *pRes = pConn->pRes;
2048 int rc = 0;
2049 unsigned long done = 0;
2050 unsigned long onedone;
2051 unsigned long action;
2052
2053 debuglocal(9,"NdpFileWrite in\n");
2054
2055 do {
2056 if (pConn->file.fd < 0)
2057 {
2058 rc = ERROR_INVALID_HANDLE;
2059 break;
2060 }
2061 rc = smbwrp_write(pConn->cli, &pConn->file, pBuffer, ulWrite, pulActual);
2062
2063 } while (0);
2064 debuglocal(9,"NdpFileWrite <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulWrite, *pulActual, rc);
2065
2066 return rc;
2067}
2068
Note: See TracBrowser for help on using the repository browser.