source: branches/client-1.6/src/ndpsmb.c@ 494

Last change on this file since 494 was 494, checked in by Silvan Scherrer, 15 years ago

sambaclient 1.6: attemp to fix tz problems closes ticket:56

  • Property svn:eol-style set to native
File size: 50.0 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 0 // as localtime() already does dst we don't need to add something
55 if (gmt->tm_isdst>0) {
56 debug_printf( "daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone);
57 time -= 3600;
58 gmt = localtime( &time);
59 }
60#endif
61 fdate->day = gmt->tm_mday;
62 fdate->month = gmt->tm_mon+1;
63 fdate->year = gmt->tm_year + 1900 - 1980;
64 ftime->twosecs = gmt->tm_sec/2;
65 ftime->minutes = gmt->tm_min;
66 ftime->hours = gmt->tm_hour;
67}
68
69void fsphDosDateToUnixTime( FDATE fdate, FTIME ftime, ULONG* time)
70{
71 struct tm gmtime = { 0 };
72
73 debug_printf( "fsphDosDateToUnixTime time %02d:%02d\n", ftime.hours, ftime.minutes);
74 gmtime.tm_mday = fdate.day;
75 gmtime.tm_mon = fdate.month-1;
76 gmtime.tm_year = fdate.year + 1980 - 1900;
77 gmtime.tm_sec = ftime.twosecs*2;
78 gmtime.tm_min = ftime.minutes;
79 gmtime.tm_hour = ftime.hours;
80 gmtime.tm_isdst = -1; // force libc to check dst saving
81
82 *time = mktime( &gmtime);
83 debug_printf( "fsphDosDateToUnixTime time1 %d %s", *time, ctime( (time_t*)time));
84#if 0 // as mktime() already does dst we don't need to add something
85 struct tm* gmt;
86 gmt = localtime( (time_t*) time);
87 if (gmt->tm_isdst>0) {
88 debug_printf( "fsphDosDateToUnixTime daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone);
89 *time += 3600;
90 }
91#endif
92 debug_printf( "fsphDosDateToUnixTime time2 %d %s", *time, ctime( (time_t*)time));
93}
94
95// -------------------------------------------------------------
96
97int StrLen(char * s)
98{
99 char * p;
100 if (!s)
101 {
102 return 0;
103 }
104 for (p = s; *p; p++);
105 return (p - s);
106}
107
108char * StrNCat(char *dst, const char *src, int count)
109{
110 int i;
111 if (!dst || !src || count <= 0)
112 {
113 return dst;
114 }
115 for (i = 0; dst[i]; i++);
116 for (;i < count && *src; i++, src++)
117 {
118 dst[i] = *src;
119 }
120 dst[i] = 0;
121 return dst;
122}
123
124char * StrNCpy(char *dst, const char *src, int count)
125{
126 if (!dst || !src || count <= 0)
127 {
128 return dst;
129 }
130 *dst = 0;
131 return StrNCat(dst, src, count);
132}
133
134char * StrCpy(char *dst, const char *src)
135{
136 char * p;
137 if (!dst || !src)
138 {
139 return dst;
140 }
141 p = dst;
142 while (*p++ = *src++);
143 return dst;
144}
145
146char * StrCat(char *dst, const char *src)
147{
148 int i;
149 if (!dst || !src)
150 {
151 return dst;
152 }
153 for (i = 0; dst[i]; i++);
154 for (; *src; i++, src++)
155 {
156 dst[i] = *src;
157 }
158 dst[i] = 0;
159 return dst;
160}
161
162void * MemCpy(void * dst, const void * src, int len)
163{
164 int i;
165 if (!src || !dst || len <= 0)
166 {
167 return dst;
168 }
169 for (i = 0; i < len; i++)
170 {
171 ((char *)dst)[i] = ((char *)src)[i];
172 }
173 return dst;
174}
175
176void *MemSet(void *dst, char c, int len)
177{
178 int i;
179 if (!dst || len <= 0)
180 {
181 return dst;
182 }
183 for (i = 0; i < len; i++)
184 {
185 ((char *)dst)[i] = c;
186 }
187 return dst;
188}
189
190// -------------------------------------------------------------
191
192/* uppercased type of resource */
193const char *NdpTypes[] =
194{
195 "SMBFS",
196 NULL
197}
198;
199
200/* Properties of supported resource types */
201
202/* Properties of resource */
203static const NDPROPERTYINFO smbProperties[] =
204{
205 {ND_PROP_STRING, 0, "WORKGROUP", ""},
206 {ND_PROP_STRING, 0, "SERVER", ""},
207 {ND_PROP_STRING, 0, "SHARE", ""},
208 {ND_PROP_STRING, 0, "USER", "guest"},
209 {ND_PROP_STRING, 0, "PASSWORD", ""},
210 {ND_PROP_STRING, 0, "SPASSWORD", ""},
211 {ND_PROP_STRING, 0, "MASTER", "WORKGROUP"},
212 { ND_PROP_ULONG, 0, "MASTERTYPE", "1"},
213 { ND_PROP_ULONG, 0, "EASUPPORT", "1"},
214 {ND_PROP_STRING, 0, NULL, NULL}
215};
216
217
218/* Exported array of properties */
219const NDPROPERTYINFO *NdpPropertiesInfo[] =
220{
221 smbProperties
222};
223
224
225static PLUGINHELPERTABLE2L *ph;
226static int ifL;
227
228int APIENTRY NdpPluginLoad (PLUGINHELPERTABLE2L *pPHT)
229{
230 int rc;
231 HPIPE pipe;
232 unsigned long action;
233 ph = pPHT;
234 ifL = 0;
235/*
236 if (ph->cb < sizeof (PLUGINHELPERTABLE2))
237 {
238 return ERROR_INVALID_FUNCTION;
239 }
240*/
241 if (ph->cb >= sizeof (PLUGINHELPERTABLE2L))
242 {
243 ifL = 1;
244 }
245 debuglocal(9,"Working with %s bit fileio NDFS\n", ifL ? "64" : "32");
246 return NO_ERROR;
247}
248
249
250int APIENTRY NdpPluginFree (void)
251{
252 return NO_ERROR;
253}
254
255
256void getfindinfo(Connection * pConn, FILEFINDBUF3 * stat, smbwrp_fileinfo * finfo)
257{
258 char * name = ph->fsphStrRChr(finfo->fname, '\\');
259 if (name)
260 {
261 name++;
262 }
263 else
264 {
265 name = finfo->fname;
266 }
267 if (!*name)
268 {
269 name = pConn->pRes->srv.share_name;
270 }
271 StrNCpy(stat->achName, name, CCHMAXPATHCOMP - 1);
272 stat->cbFile = finfo->size;
273 stat->cbFileAlloc = stat->cbFile;
274 stat->oNextEntryOffset = 0ul;
275 stat->cchName = StrLen(stat->achName);
276 stat->attrFile = (finfo->attr & 0x37);
277
278 fsphUnixTimeToDosDate(finfo->mtime, &stat->fdateLastWrite, &stat->ftimeLastWrite);
279 fsphUnixTimeToDosDate(finfo->ctime, &stat->fdateCreation, &stat->ftimeCreation);
280 fsphUnixTimeToDosDate(finfo->atime, &stat->fdateLastAccess, &stat->ftimeLastAccess);
281}
282
283int getfindinfoL(Connection * pConn, void * plist, smbwrp_fileinfo * finfo, ULONG ulAttribute, char * mask)
284{
285 FILESTATUS3L stat = {0};
286 char * name = ph->fsphStrRChr(finfo->fname, '\\');
287 if (name)
288 {
289 name++;
290 }
291 else
292 {
293 name = finfo->fname;
294 }
295 if (!*name)
296 {
297 name = pConn->pRes->srv.share_name;
298 }
299 if (mask && (!ph->fsphAttrMatch(ulAttribute, finfo->attr & 0x37) || !ph->fsphWildMatch(mask, name, ND_IGNORE_CASE)))
300 {
301 return 0;
302 }
303
304 stat.cbFile = finfo->size;
305 stat.cbFileAlloc = stat.cbFile;
306 stat.attrFile = (finfo->attr & 0x37);
307
308 fsphUnixTimeToDosDate(finfo->mtime, &stat.fdateLastWrite, &stat.ftimeLastWrite);
309 fsphUnixTimeToDosDate(finfo->ctime, &stat.fdateCreation, &stat.ftimeCreation);
310 fsphUnixTimeToDosDate(finfo->atime, &stat.fdateLastAccess, &stat.ftimeLastAccess);
311 debug_printf( "fname %s\n", finfo->fname);
312 debug_printf( "mtime %d %s", finfo->mtime, ctime( (time_t*)&finfo->mtime));
313 debug_printf( "ftimeLastAccess %02d:%02d:%02d\n", stat.ftimeLastWrite.hours, stat.ftimeLastWrite.minutes, stat.ftimeLastWrite.twosecs*2);
314
315 ph->fsphAddFile32L(plist, &stat, name, StrLen(name), finfo, sizeof(*finfo), 0);
316 return 1;
317}
318
319static unsigned char fromhex (char c)
320{
321 if ('0' <= c && c <= '9')
322 {
323 return c - '0';
324 }
325
326 if ('A' <= c && c <= 'F')
327 {
328 return c - 'A' + 0xA;
329 }
330
331 if ('a' <= c && c <= 'f')
332 {
333 return c - 'a' + 0xA;
334 }
335
336 return 0;
337}
338
339static char tohex (unsigned char b)
340{
341 b &= 0xF;
342
343 if (b <= 9)
344 {
345 return b + '0';
346 }
347
348 return 'A' + (b - 0xA);
349}
350
351static void decryptPassword (const char *pszCrypt, char *pszPlain)
352{
353 /* A simple "decryption", character from the hex value. */
354 const char *s = pszCrypt;
355 char *d = pszPlain;
356
357 while (*s)
358 {
359 *d++ = (char)((fromhex (*s++) << 4) + fromhex (*s++));
360 }
361
362 *d++ = 0;
363}
364
365static void encryptPassword (const char *pszPlain, char *pszCrypt)
366{
367 /* A simple "encryption" encode each character as hex value. */
368 const char *s = pszPlain;
369 char *d = pszCrypt;
370
371 while (*s)
372 {
373 *d++ = tohex ((*s) >> 4);
374 *d++ = tohex (*s);
375 s++;
376 }
377
378 *d++ = 0;
379}
380
381/* accept parameters in form
382 * [filename][;name=filename]
383 */
384int initResource (Resource *pRes, NDPROPERTYHANDLE properties)
385{
386 int rc = NO_ERROR;
387 unsigned long t;
388 const CHAR * q = NULL;
389 int defaultPassword = 1;
390
391 pRes->rootlevel = 0;
392 pRes->easupport = 1;
393#ifdef HAVE_KRB5_H
394 pRes->krb5support = 1;
395#else
396 pRes->krb5support = 0;
397#endif
398
399 t = 0, q = NULL;
400 rc = ph->fsphQueryStringProperty (properties, "WORKGROUP", &q, &t);
401 if (!rc && t && *q)
402 {
403 StrNCpy(pRes->srv.workgroup, q, sizeof(pRes->srv.workgroup) - 1);
404 pRes->rootlevel = 1;
405 }
406
407 t = 0, q = NULL;
408 rc = ph->fsphQueryStringProperty (properties, "SERVER", &q, &t);
409 if (!rc && t && *q)
410 {
411 StrNCpy(pRes->srv.server_name, q, sizeof(pRes->srv.server_name) - 1);
412 pRes->rootlevel = 2;
413 }
414
415 t = 0, q = NULL;
416 rc = ph->fsphQueryStringProperty (properties, "SHARE", &q, &t);
417 if (!rc && t && *q)
418 {
419 StrNCpy(pRes->srv.share_name, q, sizeof(pRes->srv.share_name) - 1);
420 pRes->rootlevel = 3;
421 }
422
423 t = 0, q = NULL;
424 rc = ph->fsphQueryStringProperty (properties, "USER", &q, &t);
425 if (!rc && t && *q)
426 {
427 StrNCpy(pRes->srv.username, q, sizeof(pRes->srv.username) - 1);
428 }
429
430 t = 0, q = NULL;
431 rc = ph->fsphQueryStringProperty (properties, "PASSWORD", &q, &t);
432 if (!rc && t && *q)
433 {
434 StrNCpy(pRes->srv.password, q, sizeof(pRes->srv.password) - 1);
435 defaultPassword = 0;
436 }
437
438 t = 0, q = NULL;
439 rc = ph->fsphQueryStringProperty (properties, "SPASSWORD", &q, &t);
440 if ( rc == NO_ERROR
441 && *q != '\0'
442 && defaultPassword)
443 {
444 char p[1024];
445 p[0] = 0;
446
447 decryptPassword (q, p);
448
449 if (*p)
450 {
451 StrNCpy(pRes->srv.password, p, sizeof(pRes->srv.password) - 1);
452
453 /* clear the plain password */
454 ph->fsphSetProperty (properties, "PASSWORD", "");
455 }
456 }
457 else
458 {
459 char c[1024];
460 encryptPassword (pRes->srv.password, c);
461
462 ph->fsphSetProperty (properties, "SPASSWORD", c);
463
464 // clear the plain password
465 ph->fsphSetProperty (properties, "PASSWORD", "");
466 }
467
468 t = 0, q = NULL;
469 rc = ph->fsphQueryStringProperty (properties, "MASTER", &q, &t);
470 if (!rc && t && *q)
471 {
472 StrNCpy(pRes->srv.master, q, sizeof(pRes->srv.master) - 1);
473 }
474
475 t = 0;
476 rc = ph->fsphQueryUlongProperty (properties, "MASTERTYPE", &t);
477 if (!rc)
478 {
479 if (t > 1)
480 {
481 rc = ERROR_INVALID_PARAMETER;
482 }
483 else
484 {
485 pRes->srv.ifmastergroup = t;
486 }
487 }
488
489 t = 0;
490 rc = ph->fsphQueryUlongProperty (properties, "EASUPPORT", &t);
491 if (!rc)
492 {
493 if (t > 1)
494 {
495 rc = ERROR_INVALID_PARAMETER;
496 }
497 else
498 {
499 pRes->easupport = t;
500 }
501 }
502
503 return rc;
504}
505
506int iftestpath(char * path)
507{
508 char * p = path;
509 if (!path)
510 {
511 return 0;
512 }
513 while ((p = ph->fsphStrChr(p, 'A')) != NULL)
514 {
515 if (ph->fsphStrNCmp(p, "A.+,;=[].B", 10) == 0)
516 {
517 return 1;
518 }
519 p++;
520 }
521 return 0;
522}
523
524int pathparser(Resource *pRes, Connection * pConn, char * path, char * result)
525{
526 int rootlevel;
527 int rc = NO_ERROR;
528 if (!pRes || !path || !result)
529 {
530 return ERROR_INVALID_PARAMETER;
531 }
532 // handle special case when someone wants to test support of LFN or smth similar
533 if (iftestpath(path))
534 {
535 StrCpy(result, "\\A.+,;=[].B");
536 return NO_ERROR;
537 }
538
539 rootlevel = pRes->rootlevel;
540 if (*path == '\\') path++;
541
542 if (rootlevel < 3)
543 {
544 char * p;
545 // flag: 1 parameters changed, reconnection required, 0 do nothing
546 int newlevel = 0;
547 // use a temporary resource to test disconnection/reconnection
548 Resource tmpRes;
549 // copy exising data
550 memcpy( &tmpRes, pRes, sizeof( tmpRes));
551 // pointer to new connection fields
552 smbwrp_server * tmp = &tmpRes.srv;
553 if (rootlevel == 0)
554 {
555 p = ph->fsphStrChr(path, '\\');
556 if (!p)
557 {
558 p = path + StrLen(path);
559 }
560 if (StrLen(tmp->workgroup) != p - path
561 || (p == path || ph->fsphStrNICmp(path, tmp->workgroup, p - path)))
562 {
563 StrNCpy(tmp->workgroup, path, p - path);
564 tmp->workgroup[p - path] = 0;
565 newlevel = 1;
566 }
567 path = *p == '\\' ? p + 1 : p;
568 rootlevel = 1;
569 }
570 if (rootlevel == 1) // root path starts from server name
571 {
572 p = ph->fsphStrChr(path, '\\');
573 if (!p)
574 {
575 p = path + StrLen(path);
576 }
577 if (StrLen(tmp->server_name) != p - path
578 || (p == path || ph->fsphStrNICmp(path, tmp->server_name, p - path)))
579 {
580 StrNCpy(tmp->server_name, path, p - path);
581 tmp->server_name[p - path] = 0;
582 newlevel = 1;
583 }
584 path = *p == '\\' ? p + 1 : p;
585 rootlevel = 2;
586 }
587 if (rootlevel == 2) // root path starts from share name
588 {
589 p = ph->fsphStrChr(path, '\\');
590 if (!p)
591 {
592 p = path + StrLen(path);
593 }
594 if (StrLen(tmp->share_name) != (p - path)
595 || (p == path || ph->fsphStrNICmp(path, tmp->share_name, p - path)))
596 {
597 StrNCpy(tmp->share_name, path, p - path);
598 tmp->share_name[p - path] = 0;
599 newlevel = 1;
600 }
601 path = *p == '\\' ? p + 1 : p;
602 }
603 if (newlevel)
604 {
605 // reconnect to server here, first test new connection
606 cli_state* tmp_cli = NULL;
607 rc = smbwrp_connect( &tmpRes, &tmp_cli);
608 if (!rc)
609 {
610 // new connection is ok, disconnect old one
611 cli_state* cli = pConn->cli;
612 smbwrp_disconnect( pRes, cli);
613 // save tmp data structure
614 memcpy( pRes, &tmpRes, sizeof( tmpRes));
615 // save new connection handle
616 pConn->cli = tmp_cli;
617 }
618 }
619 }
620
621 StrCpy(result, "\\");
622 StrNCat(result, path, CCHMAXPATH);
623
624 return rc;
625}
626
627
628// -------------------------------------------------------------
629
630/* check if the requested resource is available */
631static int checkMountResource( Resource* pRes)
632{
633 int rc;
634 unsigned long action;
635 cli_state* cli = NULL;
636
637 debug_printf("checkMountResource in tid#%d\n", _gettid());
638 rc = smbwrp_connect( pRes, &cli);
639/* changed to real error codes SCS
640 if (rc)
641 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED); */
642 switch (rc) {
643 case 0:
644 rc = NO_ERROR;
645 break;
646 case 1:
647 case 10:
648 case 11:
649 rc = ERROR_BAD_NET_NAME;
650 break;
651 case 2:
652 rc = ERROR_INIT_ROUTINE_FAILED;
653 break;
654 case 3:
655 rc = ERROR_BAD_NET_RESP;
656 break;
657 case 4:
658 rc = ERROR_NETWORK_BUSY;
659 break;
660 case 6:
661 rc = ERROR_NETWORK_ACCESS_DENIED;
662 break;
663 case 7:
664 rc = ERROR_BAD_NETPATH;
665 break;
666 default:
667 rc = ERROR_UNEXP_NET_ERR;
668 break;
669 } /* endswitch */
670
671 smbwrp_disconnect( pRes, cli);
672
673 return rc;
674}
675
676int APIENTRY NdpMountResource (HRESOURCE *presource, int type, NDPROPERTYHANDLE properties)
677{
678 int rc = NO_ERROR;
679 unsigned long objany = OBJ_ANY;
680 Resource *pRes = NULL;
681
682 debuglocal(9,"NdpMountResource in\n");
683
684 // init code
685 smbwrp_init();
686
687 /* since samba plugin support only 1 type of resources we do not need */
688 /* to check what the found type really is */
689 pRes = malloc( sizeof(Resource));
690 if (pRes == NULL)
691 {
692 rc = ERROR_NOT_ENOUGH_MEMORY;
693 }
694 else
695 {
696 MemSet(pRes, 0, sizeof(Resource));
697 //pRes->objany = objany;
698 // parse init string
699 rc = initResource (pRes, properties);
700 // try to connect to resource (check type) only if thread!=1, so ndctl startup
701 // is not slowed down by network connections.
702 // ndctl does mounting on main thread (#1)
703 // nd/ndpm do not use main thread
704 if (!rc && _gettid()!=1)
705 rc = checkMountResource( pRes);
706 if (!rc)
707 {
708 // store resource data
709 *presource = (HRESOURCE)pRes;
710 }
711 else
712 {
713 free(pRes);
714 }
715 }
716 debuglocal(9,"NdpMountResource rc=%d\n", rc);
717 return rc;
718}
719
720// -------------------------------------------------------------
721
722int APIENTRY NdpFreeResource (HRESOURCE resource)
723{
724 Resource *pRes = (Resource *)resource;
725 MemSet(&pRes->srv, 0, sizeof(pRes->srv));
726 free(pRes);
727 debuglocal(9,"NdpFreeResource %d\n", NO_ERROR);
728 return NO_ERROR;
729}
730
731// -------------------------------------------------------------
732
733int APIENTRY NdpRsrcCompare (HRESOURCE resource, HRESOURCE resource2)
734{
735 Resource *pRes = (Resource *)resource;
736 Resource *pRes2 = (Resource *)resource2;
737 int rc = ND_RSRC_DIFFERENT;
738
739 debuglocal(9,"NdpRsrcCompare in\n");
740 if (ph->fsphStrICmp(pRes->srv.server_name, pRes2->srv.server_name) == 0
741 && ph->fsphStrICmp(pRes->srv.share_name, pRes2->srv.share_name) == 0
742 && ph->fsphStrICmp(pRes->srv.username, pRes2->srv.username) == 0
743 && ph->fsphStrICmp(pRes->srv.workgroup, pRes2->srv.workgroup) == 0)
744 {
745 // resources are equal
746 rc = ND_RSRC_EQUAL;
747 }
748
749 debuglocal(9,"NdpRsrcCompare %d\n", rc);
750
751 return rc;
752}
753
754int APIENTRY NdpRsrcUpdate (HRESOURCE resource, HRESOURCE resource2)
755{
756 // do nothing
757 debuglocal(9,"NdpRsrcUpdate %d\n", NO_ERROR);
758 return NO_ERROR;
759}
760
761int APIENTRY NdpRsrcQueryInfo (HRESOURCE resource, ULONG *pulFlags, void *pdata, ULONG insize, ULONG *poutlen)
762{
763 Resource *pRes = (Resource *)resource;
764 int rc = NO_ERROR;
765 char s[4096];
766
767 debuglocal(9,"NdpRsrcQueryInfo in\n");
768
769 switch (pRes->rootlevel)
770 {
771 case 0:
772 {
773 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\@%s", ifL ? "64" : "32", pRes->srv.username);
774 } break;
775 case 1:
776 {
777 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s %s: \\\\@%s", ifL ? "64" : "32", pRes->srv.workgroup, pRes->srv.username);
778 } break;
779 case 2:
780 {
781 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);
782 } break;
783 default:
784 {
785 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);
786 } break;
787 }
788 *poutlen = StrLen(s) + 1;
789 if (*poutlen > insize)
790 {
791 rc = ERROR_BUFFER_OVERFLOW;
792 }
793 else
794 {
795 MemCpy(pdata, s, *poutlen);
796 }
797
798 debuglocal(9,"NdpRsrcQueryInfo %d\n", rc);
799
800 return rc;
801}
802
803int APIENTRY NdpRsrcQueryFSAttach (HRESOURCE resource, void *pdata, ULONG insize, ULONG *poutlen)
804{
805 ULONG ulDummy = 0;
806 /* just return the resource info string */
807 return NdpRsrcQueryInfo (resource, &ulDummy, pdata, insize, poutlen);
808}
809
810int APIENTRY NdpRsrcQueryFSAllocate (HRESOURCE resource, NDFSALLOCATE *pfsa)
811{
812 Resource *pRes = (Resource *)resource;
813 int rc = NO_ERROR, rc1;
814 unsigned long action = 0;
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.