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

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

Final fix for Ticket #88 (by diver)

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