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

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

Remove deprecated MEMLEN token

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