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

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

Samba Client 1.6: working dll

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