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

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

sambaclient 1.5: attemp to fix tz problems fixes ticket:56

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