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

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

sambaclient 1.6: attemp to fix tz problems closes ticket:56

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