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

Last change on this file since 402 was 401, checked in by Silvan Scherrer, 16 years ago

added all remaining changes from 1.5.0 client

  • 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 smbwrp_file file;
633
634 debug_printf("checkMountResource in tid#%d\n", _gettid());
635 rc = smbwrp_connect( pRes, &cli);
636/* changed to real error codes SCS
637 if (rc)
638 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED); */
639 switch (rc) {
640 case 0:
641 rc = NO_ERROR;
642 break;
643 case 1:
644 case 10:
645 case 11:
646 rc = ERROR_BAD_NET_NAME;
647 break;
648 case 2:
649 rc = ERROR_INIT_ROUTINE_FAILED;
650 break;
651 case 3:
652 rc = ERROR_BAD_NET_RESP;
653 break;
654 case 4:
655 rc = ERROR_NETWORK_BUSY;
656 break;
657 case 6:
658 rc = ERROR_NETWORK_ACCESS_DENIED;
659 break;
660 case 7:
661 rc = ERROR_BAD_NETPATH;
662 break;
663 default:
664 rc = ERROR_UNEXP_NET_ERR;
665 break;
666 } /* endswitch */
667
668 smbwrp_disconnect( pRes, cli);
669
670 return rc;
671}
672
673int APIENTRY NdpMountResource (HRESOURCE *presource, int type, NDPROPERTYHANDLE properties)
674{
675 int rc = NO_ERROR;
676 unsigned long objany = OBJ_ANY;
677 Resource *pRes = NULL;
678
679 debuglocal(9,"NdpMountResource in\n");
680
681 // init code
682 smbwrp_init();
683
684 /* since samba plugin support only 1 type of resources we do not need */
685 /* to check what the found type really is */
686 pRes = malloc( sizeof(Resource));
687 if (pRes == NULL)
688 {
689 rc = ERROR_NOT_ENOUGH_MEMORY;
690 }
691 else
692 {
693 MemSet(pRes, 0, sizeof(Resource));
694 //pRes->objany = objany;
695 // parse init string
696 rc = initResource (pRes, properties);
697 // try to connect to resource (check type) only if thread!=1, so ndctl startup
698 // is not slowed down by network connections.
699 // ndctl does mounting on main thread (#1)
700 // nd/ndpm do not use main thread
701 if (!rc && _gettid()!=1)
702 rc = checkMountResource( pRes);
703 if (!rc)
704 {
705 // store resource data
706 *presource = (HRESOURCE)pRes;
707 }
708 else
709 {
710 free(pRes);
711 }
712 }
713 debuglocal(9,"NdpMountResource rc=%d\n", rc);
714 return rc;
715}
716
717// -------------------------------------------------------------
718
719int APIENTRY NdpFreeResource (HRESOURCE resource)
720{
721 Resource *pRes = (Resource *)resource;
722 MemSet(&pRes->srv, 0, sizeof(pRes->srv));
723 free(pRes);
724 debuglocal(9,"NdpFreeResource %d\n", NO_ERROR);
725 return NO_ERROR;
726}
727
728// -------------------------------------------------------------
729
730int APIENTRY NdpRsrcCompare (HRESOURCE resource, HRESOURCE resource2)
731{
732 Resource *pRes = (Resource *)resource;
733 Resource *pRes2 = (Resource *)resource2;
734 int rc = ND_RSRC_DIFFERENT;
735
736 debuglocal(9,"NdpRsrcCompare in\n");
737 if (ph->fsphStrICmp(pRes->srv.server_name, pRes2->srv.server_name) == 0
738 && ph->fsphStrICmp(pRes->srv.share_name, pRes2->srv.share_name) == 0
739 && ph->fsphStrICmp(pRes->srv.username, pRes2->srv.username) == 0
740 && ph->fsphStrICmp(pRes->srv.workgroup, pRes2->srv.workgroup) == 0)
741 {
742 // resources are equal
743 rc = ND_RSRC_EQUAL;
744 }
745
746 debuglocal(9,"NdpRsrcCompare %d\n", rc);
747
748 return rc;
749}
750
751int APIENTRY NdpRsrcUpdate (HRESOURCE resource, HRESOURCE resource2)
752{
753 // do nothing
754 debuglocal(9,"NdpRsrcUpdate %d\n", NO_ERROR);
755 return NO_ERROR;
756}
757
758int APIENTRY NdpRsrcQueryInfo (HRESOURCE resource, ULONG *pulFlags, void *pdata, ULONG insize, ULONG *poutlen)
759{
760 Resource *pRes = (Resource *)resource;
761 int rc = NO_ERROR;
762 char s[4096];
763
764 debuglocal(9,"NdpRsrcQueryInfo in\n");
765
766 switch (pRes->rootlevel)
767 {
768 case 0:
769 {
770 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\@%s", ifL ? "64" : "32", pRes->srv.username);
771 } break;
772 case 1:
773 {
774 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s %s: \\\\@%s", ifL ? "64" : "32", pRes->srv.workgroup, pRes->srv.username);
775 } break;
776 case 2:
777 {
778 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);
779 } break;
780 default:
781 {
782 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);
783 } break;
784 }
785 *poutlen = StrLen(s) + 1;
786 if (*poutlen > insize)
787 {
788 rc = ERROR_BUFFER_OVERFLOW;
789 }
790 else
791 {
792 MemCpy(pdata, s, *poutlen);
793 }
794
795 debuglocal(9,"NdpRsrcQueryInfo %d\n", rc);
796
797 return rc;
798}
799
800int APIENTRY NdpRsrcQueryFSAttach (HRESOURCE resource, void *pdata, ULONG insize, ULONG *poutlen)
801{
802 ULONG ulDummy = 0;
803 /* just return the resource info string */
804 return NdpRsrcQueryInfo (resource, &ulDummy, pdata, insize, poutlen);
805}
806
807int APIENTRY NdpRsrcQueryFSAllocate (HRESOURCE resource, NDFSALLOCATE *pfsa)
808{
809 Resource *pRes = (Resource *)resource;
810 int rc = NO_ERROR, rc1;
811 unsigned long action = 0;
812 smbwrp_file file;
813 cli_state* cli = NULL;
814 FSALLOCATE fsa;
815
816 debuglocal(9,"NdpRsrcQueryFSAllocate %08x\n", pfsa);
817
818 if (!pfsa)
819 {
820 return NO_ERROR;
821 }
822
823 debug_printf("checkMountResource in tid#%d\n", _gettid());
824 rc = smbwrp_connect( pRes, &cli);
825 if (rc)
826 {
827 debuglocal(9,"NdpCreateConnection failed rc=%d\n", rc);
828 pfsa->cSectorUnit = 1;
829 pfsa->cUnit = 123456;
830 pfsa->cUnitAvail = 123456;
831 pfsa->cbSector = 2048;
832 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED);
833 return rc;
834 }
835
836 rc = smbwrp_dskattr( cli, &fsa);
837 if (rc)
838 {
839 pfsa->cSectorUnit = 1;
840 pfsa->cUnit = 123456;
841 pfsa->cUnitAvail = 123456;
842 pfsa->cbSector = 2048;
843 //rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
844 }
845 else
846 {
847 pfsa->cSectorUnit = fsa.cSectorUnit;
848 pfsa->cUnit = fsa.cUnit;
849 pfsa->cUnitAvail = fsa.cUnitAvail;
850 pfsa->cbSector = fsa.cbSector;
851 }
852
853 smbwrp_disconnect( pRes, cli);
854
855 debuglocal(9,"NdpRsrcQueryFSAllocate %d/%d (cUnit = %d/cUnitAvail = %d/cbSector = %d)\n", rc, rc1, pfsa->cUnit, pfsa->cUnitAvail, pfsa->cbSector);
856 return rc;
857}
858
859// -------------------------------------------------------------
860
861int APIENTRY NdpCreateConnection (HRESOURCE resource, HCONNECTION *pconn)
862{
863 int rc = 0;
864 Resource * pRes = (Resource *)resource;
865 unsigned long action;
866 Connection *pConn = NULL;
867
868 debuglocal(9,"NdpCreateConnection in\n");
869
870 pConn = malloc( sizeof(Connection));
871 if (pConn == NULL)
872 {
873 rc = ERROR_NOT_ENOUGH_MEMORY;
874 }
875 if (rc)
876 {
877 debuglocal(9,"NdpCreateConnection ERROR_NOT_ENOUGH_MEMORY %d\n", rc);
878 return rc;
879 }
880 MemSet(pConn, 0, sizeof(Connection));
881 pConn->pRes = pRes;
882 pConn->file.fd = -1;
883
884 debuglocal(9,"NdpCreateConnection send CONNECT\n");
885 rc = smbwrp_connect( pRes, &pConn->cli);
886 if (rc)
887 {
888 free(pConn);
889 pConn = NULL;
890 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_INVALID_PARAMETER);
891 }
892
893 *pconn = (HCONNECTION)pConn;
894 debuglocal(9,"NdpCreateConnection %d\n", rc);
895 return rc;
896}
897
898// -------------------------------------------------------------
899
900int APIENTRY NdpFreeConnection (HCONNECTION conn)
901{
902 Connection *pConn = (Connection *)conn;
903 Resource *pRes = pConn->pRes;
904 int rc;
905
906 debuglocal(9,"NdpFreeConnection in\n");
907 if (pConn->file.fd >= 0)
908 {
909 rc = smbwrp_close( pConn->cli, &pConn->file);
910 pConn->file.fd = -1;
911 }
912
913 smbwrp_disconnect( pRes, pConn->cli);
914
915 free(pConn);
916 debuglocal(9,"NdpFreeConnection %d\n", NO_ERROR);
917 return NO_ERROR;
918}
919
920// -------------------------------------------------------------
921
922/*
923 * NdpQueryPathInfo is the most important function :) netdrive always calls
924 * the function before every operation to find out the path status: does it exist, is it a file, does a
925 * parent directory exist, etc.
926 * Plugin must return one of the following error codes:
927 * NO_ERROR - path exists and the path information have been successfully retrieved.
928 * ERROR_FILE_NOT_FOUND - all but the last component of the path exist and the
929 * path without the last component is a directory. dir1_ok\dir2_ok\does_not_exist.
930 * the wildcard can not exist, so the plugin returns FILE_NOT_FOUND, if the parent
931 * directory exist.
932 * ERROR_PATH_NOT_FOUND - any of not last path components does not exist, or all
933 * but the last component exist and is a file: \dir_ok\dir2_ok\file_ok\non_existing.
934 * ERROR_REM_NOT_LIST - resource is temporarily unavailable for some reasons.
935 * Any other error codes means an internal plugin error, not related to the status
936 * of the path queried.
937 */
938int APIENTRY NdpQueryPathInfo (HCONNECTION conn, void *plist, char *szPath)
939{
940 Connection *pConn = (Connection *)conn;
941 Resource *pRes = pConn->pRes;
942 smbwrp_fileinfo finfo;
943 int rc = 0;
944 unsigned long action;
945 char path[CCHMAXPATH+1] = {0};
946 int retry = 0;
947
948 debuglocal(9,"NdpQueryPathInfo in <%s>, retry = %d\n", szPath, retry);
949
950 // is wildcard is specified, we suppose parent dir exist, so exit immediately
951 if (ph->fsphStrChr(szPath, '*') || ph->fsphStrChr(szPath, '?'))
952 {
953 return ERROR_FILE_NOT_FOUND;
954 }
955
956
957 do {
958
959 rc = pathparser(pRes, pConn, szPath, path);
960 debuglocal(9,"NdpQueryPathInfo pathparser for <%s> rc=%d\n", path, rc);
961 switch (rc)
962 {
963 case NO_ERROR :
964 case ERROR_FILE_NOT_FOUND:
965 case ERROR_PATH_NOT_FOUND:
966 case ERROR_ACCESS_DENIED:
967 case ERROR_INVALID_PARAMETER:
968 {
969 break;
970 }
971 default :
972 {
973 rc = ERROR_PATH_NOT_FOUND;
974 }
975 }
976 if (rc)
977 {
978 break;
979 }
980 StrNCpy(finfo.fname, path, sizeof(finfo.fname) - 1);
981 debuglocal(9,"NdpQueryPathInfo smbwrp_getattr for <%s>\n", path);
982 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo);
983 if (rc)
984 {
985 // remote server not available for first time?
986 if (rc == ERROR_REM_NOT_LIST && retry == 0)
987 {
988 // free current cli resources
989 smbwrp_disconnect( pRes, pConn->cli);
990 // reconnect
991 smbwrp_connect( pRes, &pConn->cli);
992 // try file list again
993 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo);
994 debuglocal(9,"NdpQueryPathInfo remote connection lost, retry rc = %d\n", rc);
995 }
996 switch (rc)
997 {
998 case NO_ERROR :
999 case ERROR_FILE_NOT_FOUND:
1000 case ERROR_PATH_NOT_FOUND:
1001 case ERROR_ACCESS_DENIED:
1002 case ERROR_INVALID_PARAMETER:
1003 case ERROR_REM_NOT_LIST:
1004 break;
1005 default :
1006 {
1007 rc = ERROR_PATH_NOT_FOUND;
1008 }
1009 }
1010 }
1011 else
1012 {
1013 finfo.easize = -1;
1014 getfindinfoL(pConn, plist, &finfo, 0, NULL);
1015 }
1016 if (rc == ERROR_FILE_NOT_FOUND)
1017 {
1018 // now try the upper path
1019 char * p = ph->fsphStrChr(finfo.fname, '\\');
1020 if (p && p > finfo.fname)
1021 {
1022 *p = 0;
1023 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo);
1024 if (rc)
1025 {
1026 debuglocal(9,"NdpQueryPathInfo upper path in <%s>, retry = %d\n", finfo.fname, retry);
1027 rc = rc ? ERROR_PATH_NOT_FOUND : ERROR_INVALID_PARAMETER;
1028 }
1029 }
1030 }
1031 } while (0);
1032 debuglocal(9,"NdpQueryPathInfo <%s> (%s) %d\n", szPath, path, rc);
1033
1034 return rc;
1035}
1036
1037// -------------------------------------------------------------
1038
1039int APIENTRY NdpFindStart (HCONNECTION conn, void *plist, NDFILEINFOL *pfiparent, char *szPath, ULONG ulAttribute)
1040{
1041 Connection *pConn = (Connection *)conn;
1042 Resource *pRes = pConn->pRes;
1043 int rc = NO_ERROR, count = 0;
1044 unsigned long action;
1045 char *mask = "*";
1046 char dir[CCHMAXPATH+1] = {0};
1047 char path[CCHMAXPATH+1] = {0};
1048 smbwrp_fileinfo * data;
1049 NDPATHELEMENT *pel = ph->fsphNameElem(0);
1050 filelist_state state;
1051 char * p;
1052
1053 debug_printf("NdpFindStart in\n");
1054
1055 StrNCpy(dir, szPath, sizeof(dir) - 1);
1056 if (pel)
1057 {
1058 mask = pel->name;
1059 dir[StrLen(szPath) - pel->length] = 0;
1060 }
1061 action = StrLen(dir) - 1;
1062 if (dir[action] == '\\')
1063 {
1064 dir[action] = 0;
1065 }
1066 rc = pathparser(pRes, pConn, dir, path);
1067 if (rc)
1068 {
1069 return rc;
1070 }
1071 action = StrLen(path) - 1;
1072 if (path[action] != '\\')
1073 {
1074 StrNCat(path, "\\", sizeof(path) - 1);
1075 }
1076 StrCpy(dir, path);
1077 StrNCat(path, mask, sizeof(path) - 1);
1078
1079 // this structure will be used by libsmb callbacks, so we store here all we need
1080 // to fill netdrive structures
1081 state.pConn = pConn;
1082 state.plist = plist;
1083 state.ulAttribute = ulAttribute;
1084 strcpy( state.dir, dir);
1085 strcpy( state.dir_mask, mask);
1086 strcpy( state.mask, path);
1087 p = getlastslash(state.mask);
1088 if (p)
1089 {
1090 *(p + 1) = '*';
1091 *(p + 2) = 0;
1092 }
1093 else
1094 {
1095 strcpy(state.mask, "\\*");
1096 }
1097 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state);
1098 // we need to handle reconnection also here, because NdpQueryPathInfo
1099 // could be called with '*' and exit then immediately (without calling libsmb)
1100 if (rc == ERROR_REM_NOT_LIST)
1101 {
1102 // free current cli resources
1103 smbwrp_disconnect( pRes, pConn->cli);
1104 // reconnect
1105 smbwrp_connect( pRes, &pConn->cli);
1106 // try file list again next loop
1107 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state);
1108 debuglocal(9,"NdpFindStart remote connection lost, retry rc = %d\n", rc);
1109 }
1110
1111 debuglocal(9,"NdpFindStart <%s> (%s) cnt %d %d\n", szPath, path, count, rc);
1112
1113 return rc;
1114}
1115
1116int APIENTRY NdpDeletePathInfo (HRESOURCE resource, NDFILEINFOL *pfi)
1117{
1118// debuglocal(9,"NdpDeletePathInfo %d\n", 0);
1119 return NO_ERROR;
1120}
1121
1122int APIENTRY NdpRefresh (HCONNECTION conn, char *path, int tree)
1123{
1124 debuglocal(9,"NdpRefresh <%s> %d\n", path, 0);
1125 return NO_ERROR;
1126}
1127
1128int APIENTRY NdpDiscardResourceData (HRESOURCE resource, NDDATABUF *pdatabuf)
1129{
1130 // The plugin do not have to deallocate anything
1131 // because resource data did not contain any pointers
1132 // to plugins data.
1133 // Data stored by fsphSetResourceData will be
1134 // deallocated by NetDrive.
1135
1136 debuglocal(9,"NdpDicardresourceData %d\n", 0);
1137 return NO_ERROR;
1138}
1139
1140int APIENTRY NdpSetPathInfo (HCONNECTION conn, NDFILEINFOL *pfi, char *szPathName)
1141{
1142 Connection *pConn = (Connection *)conn;
1143 Resource *pRes = pConn->pRes;
1144 int rc = 0;
1145 unsigned long action;
1146 char path[CCHMAXPATH+1] = {0};
1147 smbwrp_fileinfo finfo;
1148
1149 debug_printf("NdpSetPathInfo in FIXME\n");
1150
1151 do {
1152 rc = pathparser(pRes, pConn, szPathName, path);
1153 if (rc)
1154 {
1155 break;
1156 }
1157
1158 MemSet(&finfo, 0, sizeof(finfo));
1159
1160 StrNCpy(finfo.fname, path, sizeof(finfo.fname) - 1);
1161 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(finfo.mtime));
1162 finfo.attr = pfi->stat.attrFile & 0x37;
1163 rc = smbwrp_setattr(pConn->cli, &finfo);
1164 } while (0);
1165 debuglocal(9,"NdpSetPathInfo <%s> (%s) %d\n", szPathName, path, rc);
1166
1167 return rc;
1168}
1169
1170int buildFEALIST(FEALIST *pFEASrc, GEALIST *pGEAList, FEALIST *pFEAList)
1171{
1172 int rc = 0;
1173 FEA * pfea;
1174 FEA * pfeadest;
1175 unsigned long size, done = sizeof(pFEAList->cbList), dsize, ddone = sizeof(pFEAList->cbList);
1176
1177 size = pFEASrc->cbList;
1178 pfea = pFEASrc->list;
1179 pfeadest = pFEAList->list;
1180 dsize = pFEAList->cbList;
1181//debuglocal(9,"buildFEALIST in destsize %d srcsize %d pGEAList=%08x pGEAList->cbList=%d\n", dsize, ddone, size, pGEAList, pGEAList ? pGEAList->cbList : 0);
1182 while (done < size)
1183 {
1184 char * name = (char *)(pfea + 1);
1185 int insert = 1;
1186 if (pGEAList && pGEAList->cbList > sizeof(pGEAList->cbList))
1187 {
1188 GEA * pgea = pGEAList->list;
1189 unsigned long size = pGEAList->cbList - sizeof(pGEAList->cbList), done = 0;
1190 insert = 0;
1191 while (done < size)
1192 {
1193//debuglocal(9,"comp <%s> <%s>\n", name, pgea->szName);
1194 if (!ph->fsphStrNCmp(name, pgea->szName, pgea->cbName))
1195 {
1196 insert = 1;
1197 break;
1198 }
1199 done += pgea->cbName + 2;
1200 pgea = (GEA *)((char *)pgea + pgea->cbName + 2);
1201 }
1202 }
1203 if (insert)
1204 {
1205 ddone += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1206 if (ddone <= dsize)
1207 {
1208 pfeadest->cbName = pfea->cbName;
1209 pfeadest->cbValue = pfea->cbValue;
1210 pfeadest->fEA = 0;
1211 StrCpy((char *)(pfeadest + 1), name);
1212 MemCpy((char *)(pfeadest + 1) + pfea->cbName + 1, (char *)(pfea + 1) + pfea->cbName + 1, pfea->cbValue);
1213 pfeadest = (FEA *)((char *)pFEAList + ddone);
1214 }
1215 }
1216 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1217//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);
1218 pfea = (FEA *)((char *)pFEASrc + done);
1219 }
1220 pFEAList->cbList = ddone;
1221 if (ddone > dsize && dsize > sizeof(pFEAList->cbList))
1222 {
1223 rc = ERROR_BUFFER_OVERFLOW;
1224 }
1225 debuglocal(9,"buildFEALIST rc=%d destsize=%d destdone=%d srcsize=%d pGEAList=%08x\n", rc, dsize, ddone, size, pGEAList);
1226 return rc;
1227}
1228
1229int APIENTRY NdpEAQuery (HCONNECTION conn, GEALIST *pGEAList, NDFILEINFOL *pfi, FEALIST *pFEAList)
1230{
1231 Connection *pConn = (Connection *)conn;
1232 Resource *pRes = pConn->pRes;
1233 int rc = 0;
1234 unsigned long action;
1235 char * path = NULL;
1236 FEALIST * pFEASrc;
1237 NDDATABUF fdata = {0};
1238 smbwrp_fileinfo *finfo;
1239 char pBuffer[64*1024];
1240
1241 if (!pfi || !pfi->pszName || !pFEAList)
1242 {
1243 return ERROR_EAS_NOT_SUPPORTED;
1244 }
1245 if (!pRes->easupport)
1246 {
1247 return ERROR_EAS_NOT_SUPPORTED;
1248 }
1249
1250 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1251 if (rc || !fdata.ulSize || !fdata.pData)
1252 {
1253 debuglocal(9,"NdpEAQuery: ph->fsphGetFileInfoData = %d/%d %08x\n", rc, fdata.ulSize, fdata.pData);
1254 return ERROR_EAS_NOT_SUPPORTED;
1255 }
1256 finfo = (smbwrp_fileinfo *)fdata.pData;
1257 path = finfo->fname;
1258
1259 debuglocal(9,"NdpEAQuery in <%s> %08x %d\n", path, pGEAList, pGEAList ? pGEAList->cbList : 0);
1260
1261 do {
1262 rc = smbwrp_listea( pConn->cli, path, pBuffer, sizeof( pBuffer));
1263 pFEASrc = (FEALIST*) pBuffer;
1264 if (rc)
1265 {
1266 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1267 switch (rc)
1268 {
1269 case ERROR_FILE_NOT_FOUND :
1270 case ERROR_PATH_NOT_FOUND :
1271 {
1272 pFEAList->cbList = sizeof(pFEAList->cbList);
1273 rc = NO_ERROR;
1274 } break;
1275 case ERROR_BUFFER_OVERFLOW :
1276 {
1277 pFEAList->cbList = pFEASrc->cbList;
1278 } break;
1279 default :
1280 {
1281 rc = ERROR_EAS_NOT_SUPPORTED;
1282 }
1283 }
1284 }
1285 else
1286 {
1287 rc = buildFEALIST((FEALIST *)pFEASrc, pGEAList, pFEAList);
1288 }
1289 } while (0);
1290 debuglocal(9,"NdpEAQuery <%s> %d %d %d\n", pfi->pszName, rc, pFEASrc->cbList, pFEAList->cbList);
1291
1292 return rc;
1293}
1294
1295int APIENTRY NdpEASet (HCONNECTION conn, FEALIST *pFEAList, NDFILEINFOL *pfi)
1296{
1297 Connection *pConn = (Connection *)conn;
1298 Resource *pRes = pConn->pRes;
1299 int rc = 0;
1300 char * path;
1301 unsigned long action;
1302 NDDATABUF fdata = {0};
1303 smbwrp_fileinfo *finfo;
1304
1305 debuglocal(9,"NdpEASet in\n");
1306
1307 if (!pfi || !pfi->pszName || !pFEAList || pFEAList->cbList <= sizeof(long))
1308 {
1309 return ERROR_EAS_NOT_SUPPORTED;
1310 }
1311 if (!pRes->easupport)
1312 {
1313 return ERROR_EAS_NOT_SUPPORTED;
1314 }
1315
1316 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1317 if (rc || !fdata.ulSize || !fdata.pData)
1318 {
1319 debuglocal(9,"NdpEASet: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData);
1320 return ERROR_EAS_NOT_SUPPORTED;
1321 }
1322 finfo = (smbwrp_fileinfo *)fdata.pData;
1323 path = finfo->fname;
1324
1325 do {
1326 // got FEA there
1327 FEA * pfea;
1328 unsigned long done = sizeof(long);
1329 pfea = pFEAList->list;
1330 while (done < pFEAList->cbList)
1331 {
1332 rc = smbwrp_setea(pConn->cli, path, (char*)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue);
1333 if (rc)
1334 {
1335 break;
1336 }
1337 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue);
1338 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1339 }
1340 } while (0);
1341 debuglocal(9,"NdpEASet %d\n", rc);
1342
1343 return rc;
1344}
1345
1346int APIENTRY NdpEASize (HCONNECTION conn, NDFILEINFOL *pfi, ULONG *pulEASize)
1347{
1348 Connection *pConn = (Connection *)conn;
1349 Resource *pRes = pConn->pRes;
1350 int rc = 0;
1351 unsigned long action;
1352 char * path = NULL;
1353 FEALIST * pfealist;
1354 NDDATABUF fdata = {0};
1355 smbwrp_fileinfo *finfo;
1356 char pBuffer[64*1024];
1357 int easize;
1358
1359 if (!pfi || !pulEASize)
1360 {
1361 return ERROR_EAS_NOT_SUPPORTED;
1362 }
1363 if (!pRes->easupport)
1364 {
1365 return ERROR_EAS_NOT_SUPPORTED;
1366 }
1367
1368 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1369 if (rc || !fdata.ulSize || !fdata.pData)
1370 {
1371 debuglocal(9,"NdpEASize: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData);
1372 return ERROR_EAS_NOT_SUPPORTED;
1373 }
1374 finfo = (smbwrp_fileinfo *)fdata.pData;
1375 easize = finfo->easize;
1376 finfo->easize = -1;
1377 path = finfo->fname;
1378 if (easize >= 0)
1379 {
1380 *pulEASize = easize;
1381 debuglocal(9,"NdpEASize <%s> cached %d\n", path, easize);
1382 return NO_ERROR;
1383 }
1384
1385 debuglocal(9,"NdpEASize in <%s> \n", path);
1386
1387 do {
1388 rc = smbwrp_listea(pConn->cli, path, pBuffer, sizeof( pBuffer));
1389 pfealist = (FEALIST*)pBuffer;
1390 if (rc)
1391 {
1392 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1393 switch (rc)
1394 {
1395 case ERROR_FILE_NOT_FOUND :
1396 case ERROR_PATH_NOT_FOUND :
1397 {
1398 pfealist->cbList = sizeof(pfealist->cbList);
1399 } /* Fall through */
1400 case ERROR_BUFFER_OVERFLOW :
1401 {
1402 rc = NO_ERROR;
1403 } break;
1404 default :
1405 {
1406 rc = ERROR_EAS_NOT_SUPPORTED;
1407 }
1408 }
1409 }
1410 *pulEASize = pfealist->cbList;
1411 } while (0);
1412 debuglocal(9,"NdpEASize <%s> %d %d\n", pfi->pszName, *pulEASize, rc);
1413
1414 return rc;
1415}
1416
1417int APIENTRY NdpSetCurrentDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szPath)
1418{
1419 Connection *pConn = (Connection *)conn;
1420 Resource *pRes = pConn->pRes;
1421 int rc = 0;
1422 unsigned long action;
1423 char path[CCHMAXPATH+1] = {0};
1424
1425 debuglocal(9,"NdpSetCurrentDir in\n");
1426
1427 do {
1428 rc = pathparser(pRes, pConn, szPath, path);
1429 if (rc)
1430 {
1431 break;
1432 }
1433
1434 rc = smbwrp_chdir(&pRes->srv, pConn->cli, path);
1435 } while (0);
1436 debuglocal(9,"NdpSetCurrentDir <%s> (%s) %d\n", szPath, path, rc);
1437
1438 return rc;
1439}
1440
1441int APIENTRY NdpCopy (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
1442{
1443 debuglocal(9,"NdpCopy <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
1444 return ERROR_CANNOT_COPY;
1445}
1446
1447int APIENTRY NdpCopy2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
1448{
1449 debuglocal(9,"NdpCopy2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
1450 return ERROR_CANNOT_COPY;
1451}
1452
1453int APIENTRY NdpForceDelete (HCONNECTION conn, NDFILEINFOL *pfi, char *szFile)
1454{
1455 Connection *pConn = (Connection *)conn;
1456 Resource *pRes = pConn->pRes;
1457 int rc = 0;
1458 unsigned long action;
1459 char path[CCHMAXPATH+1] = {0};
1460
1461 debuglocal(9,"NdpForceDelete in\n");
1462
1463 do {
1464 rc = pathparser(pRes, pConn, szFile, path);
1465 if (rc)
1466 {
1467 break;
1468 }
1469
1470 rc = smbwrp_unlink(pConn->cli, path);
1471 } while (0);
1472 debuglocal(9,"NdpForceDelete <%s> (%s) %d\n", szFile, path, rc);
1473
1474 return rc;
1475}
1476
1477int APIENTRY NdpCreateDir (HCONNECTION conn, NDFILEINFOL *pfiparent, char *szDirName, FEALIST *pFEAList)
1478{
1479 Connection *pConn = (Connection *)conn;
1480 Resource *pRes = pConn->pRes;
1481 int rc = 0;
1482 unsigned long action;
1483 char path[CCHMAXPATH+1] = {0};
1484
1485 debuglocal(9,"NdpCreateDir in\n");
1486
1487 do {
1488 rc = pathparser(pRes, pConn, szDirName, path);
1489 if (rc)
1490 {
1491 break;
1492 }
1493
1494 rc = smbwrp_mkdir(pConn->cli, path);
1495 } while (0);
1496 debuglocal(9,"NdpCreateDir <%s> (%s) %d\n", szDirName, path, rc);
1497
1498 return rc;
1499}
1500
1501int APIENTRY NdpDeleteDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szDir)
1502{
1503 Connection *pConn = (Connection *)conn;
1504 Resource *pRes = pConn->pRes;
1505 int rc = 0;
1506 unsigned long action;
1507 char path[CCHMAXPATH+1] = {0};
1508
1509 debuglocal(9,"NdpDeleteDir in\n");
1510
1511 do {
1512 rc = pathparser(pRes, pConn, szDir, path);
1513 if (rc)
1514 {
1515 break;
1516 }
1517
1518 rc = smbwrp_rmdir(pConn->cli, path);
1519 } while (0);
1520 debuglocal(9,"NdpDeleteDir <%s> (%s) %d\n", szDir, path, rc);
1521
1522 return rc;
1523}
1524
1525int APIENTRY NdpMove (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
1526{
1527 Connection *pConn = (Connection *)conn;
1528 Resource *pRes = pConn->pRes;
1529 int rc = 0;
1530 unsigned long action;
1531 char src[CCHMAXPATH+1] = {0};
1532 int l1, l2;
1533 char * p = szDst;
1534
1535 debuglocal(9,"NdpMove in from <%s> to <%s>\n", szSrc, szDst);
1536
1537 do
1538 {
1539 rc = pathparser(pRes, pConn, szSrc, src);
1540 if (rc)
1541 {
1542 break;
1543 }
1544 l1 = StrLen(szSrc);
1545 l2 = StrLen(src);
1546 if (l1 > l2)
1547 {
1548 if (ph->fsphStrNICmp(szSrc, szDst, l1 - l2))
1549 {
1550 // the file moved accross different shares or servers or workgroups
1551 rc = ERROR_WRITE_PROTECT;
1552 break;
1553 }
1554 p = szDst + l1 - l2 + 1;
1555 }
1556 //pConn->mem[CCHMAXPATH + 1] = '\\';
1557 rc = smbwrp_rename(pConn->cli, src, p);
1558 } while (0);
1559 debuglocal(9,"NdpMove <%s> -> <%s> (%s) %d\n", szSrc, szDst, src, rc);
1560
1561 return rc;
1562}
1563
1564int APIENTRY NdpMove2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
1565{
1566 debuglocal(9,"NdpMove2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_WRITE_PROTECT);
1567 return ERROR_WRITE_PROTECT;
1568}
1569
1570
1571int APIENTRY NdpChangeCase (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
1572{
1573 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
1574}
1575
1576int APIENTRY NdpRename (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
1577{
1578 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
1579}
1580
1581int smbopen(Connection *pConn, char *szFileName, int flags, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1582{
1583 Resource *pRes = pConn->pRes;
1584 unsigned long action;
1585 int rc = 0;
1586 char path[CCHMAXPATH+1] = {0};
1587
1588 debuglocal(9,"smbopen in %d\n", pConn->file.fd);
1589
1590 do {
1591 if (pConn->file.fd > 0)
1592 {
1593 rc = ERROR_TOO_MANY_OPEN_FILES;
1594 break;
1595 }
1596
1597 rc = pathparser(pRes, pConn, szFileName, path);
1598 if (rc)
1599 {
1600 break;
1601 }
1602
1603 StrNCpy(pConn->file.fullname, szFileName, sizeof(pConn->file.fullname) - 1);
1604 StrNCpy(pConn->file.fname, path, sizeof(pConn->file.fname) - 1);
1605 flags |= O_BINARY;
1606 switch (ulOpenMode & 3)
1607 {
1608 case OPEN_ACCESS_READONLY : flags |= O_RDONLY; break;
1609 case OPEN_ACCESS_WRITEONLY : flags |= O_WRONLY; break;
1610 case OPEN_ACCESS_READWRITE : flags |= O_RDWR; break;
1611 default : flags |= O_RDWR;
1612 }
1613 pConn->file.openmode = flags;
1614 pConn->file.openattr = ulAttribute & 0x37;
1615 pConn->file.denymode = (ulOpenMode & 0x70) >> 4;
1616 rc = smbwrp_open(pConn->cli, &pConn->file);
1617 } while (0);
1618 debuglocal(9,"smbopen <%s> (%s) %08x %08x %08x %d. file = %d\n", szFileName, path, flags, ulOpenMode, ulAttribute, rc, pConn->file.fd);
1619 if (!rc && pFEAList)
1620 {
1621 int rc1 = NdpFileEASet((HCONNECTION)pConn, (NDFILEHANDLE)0, pFEAList);
1622 debuglocal(9,"smbopen NdpFileEASet %d. pFEAList->cbList %d\n", rc1, pFEAList->cbList);
1623 }
1624
1625 return rc;
1626}
1627
1628int APIENTRY NdpOpenReplace (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1629{
1630 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
1631}
1632
1633int APIENTRY NdpOpenReplaceL(HCONNECTION conn, NDFILEINFO *pfi, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1634{
1635 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
1636}
1637
1638int APIENTRY NdpOpenCreate (HCONNECTION conn, NDFILEINFOL *pfiparent, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1639{
1640// return smbopen((Connection *)conn, szFileName, O_CREAT, ulOpenMode, ulAttribute);
1641 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);
1642}
1643
1644int APIENTRY NdpOpenCreateL(HCONNECTION conn, NDFILEINFO *pfiparent, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1645{
1646 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);
1647}
1648
1649int APIENTRY NdpOpenExisting (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulOpenMode, USHORT *pfNeedEA)
1650{
1651 if (pfNeedEA) *pfNeedEA = 0; // wtf is this ?
1652 return smbopen((Connection *)conn, szFileName, 0, ulOpenMode, 0, NULL);
1653}
1654
1655int APIENTRY NdpSetFileAttribute (HCONNECTION conn, NDFILEINFOL *pfi, char *szFileName, USHORT usAttr)
1656{
1657 Connection *pConn = (Connection *)conn;
1658 Resource *pRes = pConn->pRes;
1659 int rc = 0;
1660 unsigned long action;
1661
1662 smbwrp_fileinfo finfo;
1663 char path[CCHMAXPATH+1] = {0};
1664
1665 debuglocal(9,"NdpSetFileAttribute in\n");
1666 do {
1667 rc = pathparser(pRes, pConn, szFileName, path);
1668 if (rc)
1669 {
1670 break;
1671 }
1672
1673 MemSet(&finfo, 0, sizeof(finfo));
1674 StrNCpy(finfo.fname, path, sizeof(finfo.fname) - 1);
1675 finfo.attr = usAttr & 0x37;
1676 rc = smbwrp_setattr(pConn->cli, &finfo);
1677 } while (0);
1678 debuglocal(9,"NdpSetFileAttribute <%s> (%s) %04x %d\n", szFileName, path, usAttr, rc);
1679
1680 return rc;
1681}
1682
1683int APIENTRY NdpFlush (HRESOURCE resource)
1684{
1685 debuglocal(9,"NdpFlush %d\n", ERROR_NOT_SUPPORTED);
1686 return ERROR_NOT_SUPPORTED;
1687}
1688
1689int APIENTRY NdpIOCTL (int type, HRESOURCE resource, char *path, int function, void *in, ULONG insize, PULONG poutlen)
1690{
1691 debuglocal(9,"NdpIOCTL <%s> %d\n", path, function);
1692
1693 if (in && insize > 4096)
1694 {
1695 char out[4096];
1696 sprintf (out, "SAMBA IOCTL function = %d, parms [%s] insize = %d, *poutlen = %d", function, in, insize, *poutlen);
1697 *poutlen = strlen(out);
1698 strcpy (in, out);
1699 return NO_ERROR;
1700 }
1701
1702 return ERROR_NOT_SUPPORTED;
1703}
1704
1705int APIENTRY NdpFileQueryInfo (HCONNECTION conn, NDFILEHANDLE handle, void *plist)
1706{
1707 Connection *pConn = (Connection *)conn;
1708 Resource *pRes = pConn->pRes;
1709 int rc = 0;
1710 unsigned long action;
1711 smbwrp_fileinfo finfo;
1712
1713 debug_printf("NdpFileQueryInfo in\n");
1714 do {
1715 if (pConn->file.fd < 0 || !*pConn->file.fname)
1716 {
1717 rc = ERROR_INVALID_HANDLE;
1718 break;
1719 }
1720 StrNCpy(finfo.fname, pConn->file.fname, sizeof(finfo.fname) - 1);
1721 rc = smbwrp_fgetattr(pConn->cli, &pConn->file, &finfo);
1722 if (!rc)
1723 {
1724 finfo.easize = -1;
1725 getfindinfoL(pConn, plist, &finfo, 0, NULL);
1726 }
1727 } while (0);
1728 debuglocal(9,"NdpFileQueryInfo <%s> %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, rc);
1729
1730 return rc;
1731}
1732
1733int APIENTRY NdpFileEAQuery (HCONNECTION conn, NDFILEHANDLE handle, GEALIST *pGEAList, FEALIST *pFEAList)
1734{
1735 Connection *pConn = (Connection *)conn;
1736 Resource *pRes = pConn->pRes;
1737 int rc = 0;
1738 unsigned long action;
1739 char pBuffer[64*1024];
1740 FEALIST * pFEASrc;
1741
1742 if (!pFEAList)
1743 {
1744 return ERROR_EAS_NOT_SUPPORTED;
1745 }
1746 if (!pRes->easupport)
1747 {
1748 return ERROR_EAS_NOT_SUPPORTED;
1749 }
1750
1751 debuglocal(9,"NdpFileEAQuery in <%s>/%d pGEAList=%08x\n", pConn->file.fname, pConn->file.fd, pGEAList);
1752 do {
1753 if (pConn->file.fd < 0)
1754 {
1755 rc = ERROR_INVALID_HANDLE;
1756 break;
1757 }
1758 rc = smbwrp_flistea(pConn->cli, &pConn->file, pBuffer, sizeof( pBuffer));
1759 pFEASrc = (FEALIST *) pBuffer;
1760 if (rc)
1761 {
1762 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1763 switch (rc)
1764 {
1765 case ERROR_FILE_NOT_FOUND :
1766 case ERROR_PATH_NOT_FOUND :
1767 {
1768 pFEAList->cbList = sizeof(pFEAList->cbList);
1769 rc = NO_ERROR;
1770 } break;
1771 case ERROR_BUFFER_OVERFLOW :
1772 {
1773 pFEAList->cbList = pFEASrc->cbList;
1774 } break;
1775 default :
1776 {
1777 rc = ERROR_EAS_NOT_SUPPORTED;
1778 }
1779 }
1780 }
1781 else
1782 {
1783 rc = buildFEALIST(pFEASrc, pGEAList, pFEAList);
1784 }
1785 } while (0);
1786 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);
1787
1788 return rc;
1789}
1790
1791int APIENTRY NdpFileEASet (HCONNECTION conn, NDFILEHANDLE handle, FEALIST *pFEAList)
1792{
1793 Connection *pConn = (Connection *)conn;
1794 Resource *pRes = pConn->pRes;
1795 int rc = 0;
1796 unsigned long action;
1797
1798 debuglocal(9,"NdpFileEASet in\n");
1799
1800 if (!pFEAList || pFEAList->cbList <= sizeof(long))
1801 {
1802 return ERROR_EAS_NOT_SUPPORTED;
1803 }
1804 if (!pRes->easupport)
1805 {
1806 return ERROR_EAS_NOT_SUPPORTED;
1807 }
1808
1809 do {
1810 // got FEA there
1811 FEA * pfea;
1812 unsigned long done = sizeof(long);
1813 if (pConn->file.fd < 0)
1814 {
1815 rc = ERROR_INVALID_HANDLE;
1816 break;
1817 }
1818
1819 pfea = pFEAList->list;
1820 while (done < pFEAList->cbList)
1821 {
1822 rc = smbwrp_fsetea(pConn->cli, &pConn->file, (char *)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue);
1823 if (rc)
1824 {
1825 break;
1826 }
1827 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue);
1828 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1829 }
1830
1831 } while (0);
1832 debuglocal(9,"NdpFileEASet %d\n", rc);
1833
1834 return rc;
1835}
1836
1837int APIENTRY NdpFileEASize (HCONNECTION conn, NDFILEHANDLE handle, ULONG *pulEASize)
1838{
1839 Connection *pConn = (Connection *)conn;
1840 Resource *pRes = pConn->pRes;
1841 int rc = 0;
1842 unsigned long action;
1843 char path[CCHMAXPATH+1] = {0};
1844 FEALIST * pFEAList;
1845 char pBuffer[64*1024];
1846
1847 if (!pulEASize)
1848 {
1849 return ERROR_EAS_NOT_SUPPORTED;
1850 }
1851 if (!pRes->easupport)
1852 {
1853 return ERROR_EAS_NOT_SUPPORTED;
1854 }
1855
1856 debuglocal(9,"NdpFileEASize in <%s>/%d \n", pConn->file.fname, pConn->file.fd);
1857 do {
1858 if (pConn->file.fd < 0)
1859 {
1860 rc = ERROR_INVALID_HANDLE;
1861 break;
1862 }
1863 rc = smbwrp_flistea(pConn->cli, &pConn->file, pBuffer, sizeof(pBuffer));
1864 pFEAList = (FEALIST*) pBuffer;
1865 if (rc)
1866 {
1867 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1868 switch (rc)
1869 {
1870 case ERROR_FILE_NOT_FOUND :
1871 case ERROR_PATH_NOT_FOUND :
1872 {
1873 pFEAList->cbList = sizeof(pFEAList->cbList);
1874 } /* Fall through */
1875 case ERROR_BUFFER_OVERFLOW :
1876 {
1877 rc = NO_ERROR;
1878 } break;
1879 default :
1880 {
1881 rc = ERROR_EAS_NOT_SUPPORTED;
1882 }
1883 }
1884 }
1885 *pulEASize = pFEAList->cbList;
1886 } while (0);
1887 debuglocal(9,"NdpFileEASize %d %d\n", *pulEASize, rc);
1888
1889 return rc;
1890}
1891
1892int APIENTRY NdpFileSetInfo (HCONNECTION conn, NDFILEHANDLE handle, NDFILEINFOL *pfi)
1893{
1894 Connection *pConn = (Connection *)conn;
1895 Resource *pRes = pConn->pRes;
1896 int rc = 0;
1897 unsigned long action, attrFile;
1898
1899 debug_printf("NdpFileSetInfo in\n");
1900 do {
1901 if (pConn->file.fd < 0 || !*pConn->file.fname)
1902 {
1903 rc = ERROR_INVALID_HANDLE;
1904 break;
1905 }
1906 attrFile = pfi->stat.attrFile;
1907 // deferred setinfo - on closing the file
1908 pConn->file.openattr = attrFile;
1909 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(pConn->file.mtime));
1910 debug_printf("NdpFileSetInfo mtime %d\n", pConn->file.mtime);
1911 } while (0);
1912 debuglocal(9,"NdpFileSetInfo <%s> %08x %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, attrFile, rc);
1913
1914 return NO_ERROR;
1915}
1916
1917int APIENTRY NdpFileSetFilePtrL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llOffset, ULONG ulMethod, LONGLONG *pllActual)
1918{
1919 Connection *pConn = (Connection *)conn;
1920 Resource *pRes = pConn->pRes;
1921 int rc = 0;
1922 unsigned long action;
1923
1924 debuglocal(9,"NdpFileSetFilePtrl in\n");
1925
1926 do {
1927 if (pConn->file.fd < 0)
1928 {
1929 rc = ERROR_INVALID_HANDLE;
1930 break;
1931 }
1932
1933 rc = smbwrp_lseek(pConn->cli, &pConn->file, ulMethod, llOffset);
1934 if (!rc)
1935 *pllActual = pConn->file.offset;
1936
1937 } while (0);
1938 debuglocal(9,"NdpFileSetFilePtrL <%s> %lld %lu %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llOffset, ulMethod, *pllActual, rc);
1939
1940 return rc;
1941}
1942
1943int APIENTRY NdpFileSetFilePtr (HCONNECTION conn, NDFILEHANDLE handle, LONG lOffset, ULONG ulMethod, ULONG *pulActual)
1944{
1945 LONGLONG llActual;
1946 int rc = NdpFileSetFilePtrL(conn, handle, lOffset, ulMethod, &llActual);
1947 *pulActual = llActual & 0xFFFFFFFF;
1948 debuglocal(9,"NdpFileSetFilePtr %ld %lu %ld %d\n", lOffset, ulMethod, *pulActual, rc);
1949 return rc;
1950}
1951
1952int APIENTRY NdpFileClose (HCONNECTION conn, NDFILEHANDLE handle)
1953{
1954 Connection *pConn = (Connection *)conn;
1955 Resource *pRes = pConn->pRes;
1956 int rc = 0;
1957 unsigned long action;
1958
1959 debuglocal(9,"NdpFileClose in %d <%s>\n", pConn->file.fd, pConn->file.fd < 0 ? "!null!" : pConn->file.fname);
1960
1961 do {
1962 if (pConn->file.fd < 0)
1963 {
1964 rc = ERROR_INVALID_HANDLE;
1965 break;
1966 }
1967
1968 rc = smbwrp_close(pConn->cli, &pConn->file);
1969
1970 } while (0);
1971 debuglocal(9,"NdpFileClose %d %d\n", pConn->file.fd, rc);
1972
1973 pConn->file.fd = -1;
1974 return rc;
1975}
1976
1977int APIENTRY NdpFileCommit (HCONNECTION conn, NDFILEHANDLE handle)
1978{
1979 debuglocal(9,"NdpFileCommit %d\n", NO_ERROR);
1980 return NO_ERROR;
1981}
1982
1983
1984int APIENTRY NdpFileNewSize (HCONNECTION conn, NDFILEHANDLE handle, ULONG ulLen)
1985{
1986 int rc = NdpFileNewSizeL(conn, handle, ulLen);
1987 debuglocal(9,"NdpFileNewSize %ld %d\n", ulLen, rc);
1988 return rc;
1989}
1990
1991int APIENTRY NdpFileNewSizeL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llLen)
1992{
1993 Connection *pConn = (Connection *)conn;
1994 Resource *pRes = pConn->pRes;
1995 int rc = 0;
1996 unsigned long action;
1997
1998 debuglocal(9,"NdpFileNewSizeL in\n");
1999
2000 do {
2001 if (pConn->file.fd < 0)
2002 {
2003 rc = ERROR_INVALID_HANDLE;
2004 break;
2005 }
2006
2007 rc = smbwrp_setfilesize(pConn->cli, &pConn->file, llLen);
2008
2009 } while (0);
2010 debuglocal(9,"NdpFileNewSizeL <%s> %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llLen, rc);
2011
2012 return rc;
2013}
2014
2015int APIENTRY NdpFileRead (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulRead, ULONG *pulActual)
2016{
2017 Connection *pConn = (Connection *)conn;
2018 Resource *pRes = pConn->pRes;
2019 int rc = 0;
2020 unsigned long done = 0;
2021 unsigned long onedone;
2022 unsigned long action;
2023
2024 debuglocal(9,"NdpFileRead in\n");
2025
2026 do {
2027 if (pConn->file.fd < 0)
2028 {
2029 rc = ERROR_INVALID_HANDLE;
2030 break;
2031 }
2032 rc = smbwrp_read(pConn->cli, &pConn->file, pBuffer, ulRead, pulActual);
2033 //*pulActual = ulRead;
2034 //DosSleep(0);
2035
2036 } while (0);
2037 debuglocal(9,"NdpFileRead <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulRead, *pulActual, rc);
2038
2039 return rc;
2040}
2041
2042int APIENTRY NdpFileWrite (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulWrite, ULONG *pulActual)
2043{
2044 Connection *pConn = (Connection *)conn;
2045 Resource *pRes = pConn->pRes;
2046 int rc = 0;
2047 unsigned long done = 0;
2048 unsigned long onedone;
2049 unsigned long action;
2050
2051 debuglocal(9,"NdpFileWrite in\n");
2052
2053 do {
2054 if (pConn->file.fd < 0)
2055 {
2056 rc = ERROR_INVALID_HANDLE;
2057 break;
2058 }
2059 rc = smbwrp_write(pConn->cli, &pConn->file, pBuffer, ulWrite, pulActual);
2060
2061 } while (0);
2062 debuglocal(9,"NdpFileWrite <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulWrite, *pulActual, rc);
2063
2064 return rc;
2065}
2066
Note: See TracBrowser for help on using the repository browser.