source: trunk/samba/source/ndpsmb/ndpsmb.c@ 48

Last change on this file since 48 was 48, checked in by Paul Smedley, 18 years ago

Changes to debug logging

  • Property svn:eol-style set to native
File size: 61.3 KB
Line 
1#define NDPL_LARGEFILES
2#define INCL_LONGLONG
3#include <ndextpl2.h>
4#include <smbwrp.h>
5#include <smbcd.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <stdarg.h>
9#include <time.h>
10
11
12#define NULL ((void *)0)
13
14void log(const char *fmt, ...)
15{
16 char *ndpsmb_debug = getenv("NDPSMB_DEBUG");
17
18 if (ndpsmb_debug != NULL)
19 {
20 FILE * logfile = NULL;
21 va_list args;
22 time_t t = time(NULL);
23 char timebuf[80] = {0};
24 strftime(timebuf,sizeof(timebuf)-1,"%Y/%m/%d %H:%M:%S", localtime(&t));
25 logfile = fopen("smblog","a");
26 if (logfile == NULL)
27 {
28 DosBeep(400,400);
29 }
30 else
31 {
32 fprintf(logfile, "%s: (%02d) ", timebuf, _gettid());
33 va_start(args, fmt);
34 vfprintf(logfile, fmt, args);
35 va_end(args);
36 fclose(logfile);
37 }
38 }
39}
40
41int StrLen(char * s)
42{
43 char * p;
44 if (!s)
45 {
46 return 0;
47 }
48 for (p = s; *p; p++);
49 return (p - s);
50}
51
52char * StrNCat(char *dst, const char *src, int count)
53{
54 int i;
55 if (!dst || !src || count <= 0)
56 {
57 return dst;
58 }
59 for (i = 0; dst[i]; i++);
60 for (;i < count && *src; i++, src++)
61 {
62 dst[i] = *src;
63 }
64 dst[i] = 0;
65 return dst;
66}
67
68char * StrNCpy(char *dst, const char *src, int count)
69{
70 if (!dst || !src || count <= 0)
71 {
72 return dst;
73 }
74 *dst = 0;
75 return StrNCat(dst, src, count);
76}
77
78char * StrCpy(char *dst, const char *src)
79{
80 char * p;
81 if (!dst || !src)
82 {
83 return dst;
84 }
85 p = dst;
86 while (*p++ = *src++);
87 return dst;
88}
89
90char * StrCat(char *dst, const char *src)
91{
92 int i;
93 if (!dst || !src)
94 {
95 return dst;
96 }
97 for (i = 0; dst[i]; i++);
98 for (; *src; i++, src++)
99 {
100 dst[i] = *src;
101 }
102 dst[i] = 0;
103 return dst;
104}
105
106void * MemCpy(void * dst, const void * src, int len)
107{
108 int i;
109 if (!src || !dst || len <= 0)
110 {
111 return dst;
112 }
113 for (i = 0; i < len; i++)
114 {
115 ((char *)dst)[i] = ((char *)src)[i];
116 }
117 return dst;
118}
119
120void *MemSet(void *dst, char c, int len)
121{
122 int i;
123 if (!dst || len <= 0)
124 {
125 return dst;
126 }
127 for (i = 0; i < len; i++)
128 {
129 ((char *)dst)[i] = c;
130 }
131 return dst;
132}
133
134/* uppercased type of resource */
135const char *NdpTypes[] =
136{
137 "SMBFS",
138 NULL
139}
140;
141
142/* Properties of supported resource types */
143
144/* Properties of resource */
145static const NDPROPERTYINFO smbProperties[] =
146{
147 {ND_PROP_STRING, 0, "WORKGROUP", ""},
148 {ND_PROP_STRING, 0, "SERVER", ""},
149 {ND_PROP_STRING, 0, "SHARE", ""},
150 {ND_PROP_STRING, 0, "USER", "guest"},
151 {ND_PROP_STRING, 0, "PASSWORD", ""},
152 {ND_PROP_STRING, 0, "MASTER", "WORKGROUP"},
153 { ND_PROP_ULONG, 0, "MASTERTYPE", "1"},
154 { ND_PROP_ULONG, 0, "MEMLEN", "2"},
155 {ND_PROP_STRING, 0, "LOGFILE", ""},
156 { ND_PROP_ULONG, 0, "LOGLEVEL", "0"},
157 { ND_PROP_ULONG, 0, "EASUPPORT", "1"},
158 {ND_PROP_STRING, 0, NULL, NULL}
159};
160
161
162/* Exported array of properties */
163const NDPROPERTYINFO *NdpPropertiesInfo[] =
164{
165 smbProperties
166};
167
168
169static PLUGINHELPERTABLE2L *ph;
170static int ifL;
171
172int APIENTRY NdpPluginLoad (PLUGINHELPERTABLE2L *pPHT)
173{
174 int rc;
175 HPIPE pipe;
176 unsigned long action;
177 ph = pPHT;
178 ifL = 0;
179/*
180 if (ph->cb < sizeof (PLUGINHELPERTABLE2))
181 {
182 return ERROR_INVALID_FUNCTION;
183 }
184*/
185 if (ph->cb >= sizeof (PLUGINHELPERTABLE2L))
186 {
187 ifL = 1;
188 }
189 log("Working with %s bit fileio NDFS\n", ifL ? "64" : "32");
190 return NO_ERROR;
191}
192
193
194int APIENTRY NdpPluginFree (void)
195{
196 return NO_ERROR;
197}
198
199typedef struct _Resource
200{
201 /* NetDrive information */
202 NDPROPERTYHANDLE properties; /* access handle for the properties */
203 int rootlevel;
204 unsigned long memlen;
205 unsigned long objany;
206 smbwrp_server srv;
207 char logfile[CCHMAXPATH + 1];
208 char loglevel;
209 int easupport;
210} Resource;
211
212typedef struct _Connection
213{
214 Resource *pRes;
215 HPIPE pipe;
216 char * mem;
217 int clientpid;
218 int rc;
219 smbwrp_server srv;
220 smbwrp_file file;
221} Connection;
222
223int openpipe(Resource * pRes, HPIPE * ppipe)
224{
225 HPIPE pipe = 0;
226 unsigned long rc = 0, action;
227
228 if (!pRes)
229 {
230 return ERROR_INVALID_PARAMETER;
231 }
232
233 rc = DosOpen(PIPENAME, &pipe, &action, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, NULL);
234 log("DosOpen1 rc %d\n", rc);
235 if (rc)
236 {
237 unsigned long sid = 0, pid = 0;
238 STARTDATA sd;
239 char params[CCHMAXPATH * 2] = {0};
240
241 MemSet(&sd, 0, sizeof(sd));
242 sd.Length = sizeof(sd);
243 sd.Related = SSF_RELATED_INDEPENDENT;
244 sd.FgBg = SSF_FGBG_BACK;
245 sd.PgmName = EXECNAME;
246 if (pRes->loglevel)
247 {
248 char level[2];
249 level[0] = pRes->loglevel + '0';
250 level[1] = 0;
251 StrNCat(params, " -d ", sizeof(params) - 1);
252 StrNCat(params, level, sizeof(params) - 1);
253 }
254 if (*pRes->logfile)
255 {
256 StrNCat(params, " -l ", sizeof(params) - 1);
257 StrNCat(params, pRes->logfile, sizeof(params) - 1);
258 }
259 log("params <%s>\n", params);
260 sd.PgmInputs = *params ? params : NULL;
261 sd.SessionType = SSF_TYPE_WINDOWABLEVIO;
262 rc = DosStartSession(&sd, &sid, &pid);
263 log("smbcd startsession pid %d sid %d rc %d\n", pid, sid, rc);
264 if (rc == ERROR_SMG_INVALID_CALL)
265 {
266 // ndfs started ndctl detached, so we have to use dosexecpgm
267 char failed[CCHMAXPATH + 1] = {0};
268 RESULTCODES res = {0};
269 char * p = params;
270 StrCpy(p, EXECNAME);
271 p += StrLen(p) + 1;
272 if (*pRes->logfile)
273 {
274 StrCpy(p, "-l ");
275 StrNCat(p, pRes->logfile, sizeof(params) - (p - (char *)params));
276 p += StrLen(p) + 1;
277 if (pRes->loglevel)
278 {
279 char level[2];
280 level[0] = pRes->loglevel + '0';
281 level[1] = 0;
282 StrCpy(p, "-d ");
283 StrNCat(p, level, sizeof(params) - (p - (char *)params));
284 p += StrLen(p) + 1;
285 }
286 }
287 else
288 {
289 StrCpy(p, "-q");
290 p += StrLen(p) + 1;
291 }
292 *p = 0;
293 rc = DosExecPgm(failed, sizeof(failed), EXEC_BACKGROUND, params, NULL, &res, EXECNAME);
294 log("smbcd DosExecPgm codeTerminate %d codeResult %d rc %d\n", res.codeTerminate, res.codeResult, rc);
295 }
296 if (!rc)
297 {
298 DosSleep(500);
299 rc = DosOpen(PIPENAME, &pipe, &action, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, NULL);
300 log("DosOpen2 rc %d\n", rc);
301 }
302 }
303 if (!rc)
304 {
305 if (ppipe)
306 {
307 *ppipe = pipe;
308 }
309 else
310 {
311 DosClose(pipe);
312 }
313 }
314 return rc;
315}
316
317
318void getfindinfo(Connection * pConn, FILEFINDBUF3 * stat, smbwrp_fileinfo * finfo)
319{
320 char * name = ph->fsphStrRChr(finfo->fname, '\\');
321 if (name)
322 {
323 name++;
324 }
325 else
326 {
327 name = finfo->fname;
328 }
329 if (!*name)
330 {
331 name = pConn->srv.share_name;
332 }
333 StrNCpy(stat->achName, name, CCHMAXPATHCOMP - 1);
334 stat->cbFile = finfo->size;
335 stat->cbFileAlloc = stat->cbFile;
336 stat->oNextEntryOffset = 0ul;
337 stat->cchName = StrLen(stat->achName);
338 stat->attrFile = (finfo->attr & 0x37);
339
340 ph->fsphUnixTimeToDosDate(finfo->mtime, &stat->fdateLastWrite, &stat->ftimeLastWrite);
341 ph->fsphUnixTimeToDosDate(finfo->ctime, &stat->fdateCreation, &stat->ftimeCreation);
342 ph->fsphUnixTimeToDosDate(finfo->atime, &stat->fdateLastAccess, &stat->ftimeLastAccess);
343}
344
345int getfindinfoL(Connection * pConn, void * plist, smbwrp_fileinfo * finfo, ULONG ulAttribute, char * mask)
346{
347 FILESTATUS3L stat = {0};
348 char * name = ph->fsphStrRChr(finfo->fname, '\\');
349 if (name)
350 {
351 name++;
352 }
353 else
354 {
355 name = finfo->fname;
356 }
357 if (!*name)
358 {
359 name = pConn->srv.share_name;
360 }
361 if (mask && (!ph->fsphAttrMatch(ulAttribute, finfo->attr & 0x37) || !ph->fsphWildMatch(mask, name, ND_IGNORE_CASE)))
362 {
363 return 0;
364 }
365
366 stat.cbFile = finfo->size;
367 stat.cbFileAlloc = stat.cbFile;
368 stat.attrFile = (finfo->attr & 0x37);
369
370 ph->fsphUnixTimeToDosDate(finfo->mtime, &stat.fdateLastWrite, &stat.ftimeLastWrite);
371 ph->fsphUnixTimeToDosDate(finfo->ctime, &stat.fdateCreation, &stat.ftimeCreation);
372 ph->fsphUnixTimeToDosDate(finfo->atime, &stat.fdateLastAccess, &stat.ftimeLastAccess);
373
374 ph->fsphAddFile32L(plist, &stat, name, StrLen(name), finfo, sizeof(*finfo), 0);
375 return 1;
376}
377
378
379/* accept parameters in form
380 * [filename][;name=filename]
381 */
382int initResource (Resource *pRes)
383{
384 int rc = NO_ERROR;
385 unsigned long t;
386 const unsigned char * q = NULL;
387 HPIPE pipe;
388
389 pRes->memlen = 1 << 18;
390 pRes->rootlevel = 0;
391 *pRes->logfile = 0;
392 pRes->loglevel = 0;
393 pRes->easupport = 1;
394
395 t = 0, q = NULL;
396 rc = ph->fsphQueryStringProperty (pRes->properties, "WORKGROUP", &q, &t);
397 if (!rc && t && *q)
398 {
399 StrNCpy(pRes->srv.workgroup, q, sizeof(pRes->srv.workgroup) - 1);
400 pRes->rootlevel = 1;
401 }
402
403 t = 0, q = NULL;
404 rc = ph->fsphQueryStringProperty (pRes->properties, "SERVER", &q, &t);
405 if (!rc && t && *q)
406 {
407 StrNCpy(pRes->srv.server_name, q, sizeof(pRes->srv.server_name) - 1);
408 pRes->rootlevel = 2;
409 }
410
411 t = 0, q = NULL;
412 rc = ph->fsphQueryStringProperty (pRes->properties, "SHARE", &q, &t);
413 if (!rc && t && *q)
414 {
415 StrNCpy(pRes->srv.share_name, q, sizeof(pRes->srv.share_name) - 1);
416 pRes->rootlevel = 3;
417 }
418
419 t = 0, q = NULL;
420 rc = ph->fsphQueryStringProperty (pRes->properties, "USER", &q, &t);
421 if (!rc && t && *q)
422 {
423 StrNCpy(pRes->srv.username, q, sizeof(pRes->srv.username) - 1);
424 }
425
426 t = 0, q = NULL;
427 rc = ph->fsphQueryStringProperty (pRes->properties, "PASSWORD", &q, &t);
428 if (!rc && t && *q)
429 {
430 StrNCpy(pRes->srv.password, q, sizeof(pRes->srv.password) - 1);
431 }
432
433 t = 0, q = NULL;
434 rc = ph->fsphQueryStringProperty (pRes->properties, "MASTER", &q, &t);
435 if (!rc && t && *q)
436 {
437 StrNCpy(pRes->srv.master, q, sizeof(pRes->srv.master) - 1);
438 }
439
440 t = 0, q = NULL;
441 rc = ph->fsphQueryStringProperty (pRes->properties, "LOGFILE", &q, &t);
442 if (!rc && t && *q)
443 {
444 StrNCpy(pRes->logfile, q, sizeof(pRes->logfile) - 1);
445 }
446
447 t = 0;
448 rc = ph->fsphQueryUlongProperty (pRes->properties, "LOGLEVEL", &t);
449 if (!rc)
450 {
451 if (t > 9)
452 {
453 t = 9;
454 rc = ERROR_INVALID_PARAMETER;
455 }
456 pRes->loglevel = t;
457 }
458
459 t = 0;
460 rc = ph->fsphQueryUlongProperty (pRes->properties, "MASTERTYPE", &t);
461 if (!rc)
462 {
463 if (t > 1)
464 {
465 rc = ERROR_INVALID_PARAMETER;
466 }
467 else
468 {
469 pRes->srv.ifmastergroup = t;
470 }
471 }
472
473 t = 0;
474 rc = ph->fsphQueryUlongProperty (pRes->properties, "EASUPPORT", &t);
475 if (!rc)
476 {
477 if (t > 1)
478 {
479 rc = ERROR_INVALID_PARAMETER;
480 }
481 else
482 {
483 pRes->easupport = t;
484 }
485 }
486
487 t = 0;
488 rc = ph->fsphQueryUlongProperty (pRes->properties, "MEMLEN", &t);
489 if (!rc)
490 {
491 if (t <= (pRes->easupport ? 1 : 0) || t > 10)
492 {
493 rc = ERROR_INVALID_PARAMETER;
494 }
495 else
496 {
497 pRes->memlen = t * 65536;
498 }
499 }
500
501 return rc;
502}
503
504int checkconnection(Connection * pConn)
505{
506 int rc = NO_ERROR;
507 unsigned long action;
508 smb_request req = {0};
509 smb_response resp = {0};
510 if (!pConn)
511 {
512 return ERROR_INVALID_PARAMETER;
513 }
514 log("checkconnection pconnrc %d pipe %d\n", pConn->rc, pConn->pipe);
515 if (!pConn->rc)
516 {
517 unsigned long state = 0;
518 rc = DosQueryNPHState(pConn->pipe, &state);
519 log("DosQueryNPHstate(pConn->pipe) = %d (%08x)\n", pConn->rc, pConn->pipe, rc, state);
520 if (!rc)
521 {
522 return pConn->rc;
523 }
524 }
525 // there were error on pipe, reopen it and restore connection
526 if (pConn->pipe)
527 {
528 DosClose(pConn->pipe);
529 pConn->pipe = 0;
530 }
531 rc = openpipe(pConn->pRes, &pConn->pipe);
532 if (rc)
533 {
534 log("checkconnection openpipe %d\n", rc);
535 pConn->pipe = 0;
536 DosSleep(1000);
537 return ERROR_PIPE_NOT_CONNECTED;
538 }
539 do {
540 req.request = SMBREQ_INIT;
541 req.param = (char *)0xFFFFFFFF;
542 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
543 if (pConn->rc || action < sizeof(resp) || resp.rc)
544 {
545 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
546 break;
547 }
548 pConn->clientpid = resp.value & 0xFFFF;
549 // client daemon pid changed
550 pConn->rc = DosGiveSharedMem(pConn->mem, pConn->clientpid, PAG_READ | PAG_WRITE);
551 if (pConn->rc)
552 {
553 rc = pConn->rc;
554 break;
555 }
556
557 MemCpy(pConn->mem, &pConn->srv, sizeof(pConn->srv));
558 req.request = SMBREQ_CONNECT;
559 req.param = pConn->mem;
560 req.paramlen = sizeof(pConn->srv);
561 req.length = req.paramlen;
562
563 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
564 if (pConn->rc || action < sizeof(resp) || resp.rc)
565 {
566 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
567 break;
568 }
569 MemCpy(&pConn->srv, pConn->mem, sizeof(pConn->srv));
570 rc = NO_ERROR;
571 } while (0);
572
573 if (pConn->rc && pConn->pipe)
574 {
575 DosClose(pConn->pipe);
576 pConn->pipe = 0;
577 }
578 return rc;
579}
580
581int iftestpath(char * path)
582{
583 char * p = path;
584 if (!path)
585 {
586 return 0;
587 }
588 while ((p = ph->fsphStrChr(p, 'A')) != NULL)
589 {
590 if (ph->fsphStrNCmp(p, "A.+,;=[].B", 10) == 0)
591 {
592 return 1;
593 }
594 p++;
595 }
596 return 0;
597}
598
599int pathparser(Resource *pRes, Connection * pConn, char * path, char * result)
600{
601 int rootlevel;
602 int rc = NO_ERROR;
603 if (!pRes || !path || !result)
604 {
605 return ERROR_INVALID_PARAMETER;
606 }
607 // handle special case when someone wants to test support of LFN or smth similar
608 if (iftestpath(path))
609 {
610 StrCpy(result, "\\A.+,;=[].B");
611 return NO_ERROR;
612 }
613 rootlevel = pRes->rootlevel;
614 if (*path == '\\') path++;
615 if (rootlevel < 3)
616 {
617 char * p;
618 int newlevel = 0;
619 smbwrp_server * tmp = (smbwrp_server *)pConn->mem;
620 MemCpy(tmp, &pConn->srv, sizeof(pConn->srv));
621 if (rootlevel == 0)
622 {
623 p = ph->fsphStrChr(path, '\\');
624 if (!p)
625 {
626 p = path + StrLen(path);
627 }
628 if (StrLen(tmp->workgroup) != p - path
629 || (p == path || ph->fsphStrNICmp(path, tmp->workgroup, p - path)))
630 {
631 StrNCpy(tmp->workgroup, path, p - path);
632 tmp->workgroup[p - path] = 0;
633 newlevel = 1;
634 }
635 path = *p == '\\' ? p + 1 : p;
636 rootlevel = 1;
637 }
638 if (rootlevel == 1) // root path starts from server name
639 {
640 p = ph->fsphStrChr(path, '\\');
641 if (!p)
642 {
643 p = path + StrLen(path);
644 }
645 if (StrLen(tmp->server_name) != p - path
646 || (p == path || ph->fsphStrNICmp(path, tmp->server_name, p - path)))
647 {
648 StrNCpy(tmp->server_name, path, p - path);
649 tmp->server_name[p - path] = 0;
650 newlevel = 1;
651 }
652 path = *p == '\\' ? p + 1 : p;
653 rootlevel = 2;
654 }
655 if (rootlevel == 2) // root path starts from share name
656 {
657 p = ph->fsphStrChr(path, '\\');
658 if (!p)
659 {
660 p = path + StrLen(path);
661 }
662 if (StrLen(tmp->share_name) != (p - path)
663 || (p == path || ph->fsphStrNICmp(path, tmp->share_name, p - path)))
664 {
665 StrNCpy(tmp->share_name, path, p - path);
666 tmp->share_name[p - path] = 0;
667 newlevel = 1;
668 }
669 path = *p == '\\' ? p + 1 : p;
670 }
671 if (newlevel)
672 {
673 // reconnect to server here
674 unsigned long action;
675 smb_request req = {0};
676 smb_response resp = {0};
677
678 req.request = SMBREQ_DISCONNECT;
679 req.param = pConn->mem;
680 req.length = 0;
681 req.paramlen = 0;
682
683 DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
684
685 req.request = SMBREQ_CONNECT;
686 req.param = pConn->mem;
687 req.length = pRes->memlen;
688 req.paramlen = sizeof(pConn->srv);
689
690 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
691 if (rc || action < sizeof(resp) || resp.rc)
692 {
693 rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
694 MemCpy(tmp, &pRes->srv, sizeof(pRes->srv));
695 DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
696 // TODO: what to do if the reconnect will fail ?
697 }
698 else
699 {
700 MemCpy(&pConn->srv, tmp, sizeof(pConn->srv));
701 }
702 }
703 }
704 StrCpy(result, "\\");
705 StrNCat(result, path, CCHMAXPATH);
706 return rc;
707}
708
709int APIENTRY NdpFreeResource (HRESOURCE resource)
710{
711 Resource *pRes = (Resource *)resource;
712 MemSet(&pRes->srv, 0, sizeof(pRes->srv));
713 DosFreeMem(pRes);
714 log("NdpFreeResource %d\n", NO_ERROR);
715 return NO_ERROR;
716}
717
718
719int APIENTRY NdpMountResource (HRESOURCE *presource, int type, NDPROPERTYHANDLE properties)
720{
721 int rc = NO_ERROR;
722 unsigned long objany = OBJ_ANY;
723 Resource *pRes = NULL;
724 /* since we support only 1 type of resources we do not need */
725 /* to check what the found type really is */
726 rc = DosAllocMem((void **)&pRes, sizeof(Resource), PAG_COMMIT | PAG_READ | PAG_WRITE | objany);
727 if (rc == ERROR_INVALID_PARAMETER)
728 {
729 objany = 0;
730 rc = DosAllocMem((void **)&pRes, sizeof(Resource), PAG_COMMIT | PAG_READ | PAG_WRITE);
731 }
732 if (!rc && pRes == NULL)
733 {
734 rc = ERROR_NOT_ENOUGH_MEMORY;
735 }
736 if (!rc)
737 {
738 MemSet(pRes, 0, sizeof(Resource));
739 pRes->properties = properties;
740 pRes->objany = objany;
741 rc = initResource (pRes);
742 if (rc == NO_ERROR)
743 {
744 *presource = (HRESOURCE)pRes;
745 }
746 else
747 {
748 NdpFreeResource((HRESOURCE)pRes);
749 }
750 }
751 log("NdpMountResource %d\n", rc);
752 return rc;
753}
754
755int APIENTRY NdpCreateConnection (HRESOURCE resource, HCONNECTION *pconn)
756{
757 int rc;
758 Resource * pRes = (Resource *)resource;
759 unsigned long action;
760 smb_request req = {0};
761 smb_response resp = {0};
762 Connection *pConn = NULL;
763
764 log("NdpCreateConnection in\n");
765
766 rc = DosAllocMem((void **)&pConn, sizeof(Connection), PAG_COMMIT | PAG_READ | PAG_WRITE | pRes->objany);
767 if (!rc && pConn == NULL)
768 {
769 rc = ERROR_NOT_ENOUGH_MEMORY;
770 }
771 if (rc)
772 {
773 log("NdpCreateConnection ERROR_NOT_ENOUGH_MEMORY %d\n", rc);
774 return rc;
775 }
776 MemSet(pConn, 0, sizeof(Connection));
777 pConn->pRes = pRes;
778 pConn->file.fd = -1;
779
780 do {
781 log("NdpCreateConnection open pipe\n");
782 rc = openpipe(pRes, &pConn->pipe);
783 if (rc)
784 {
785 pConn->pipe = 0;
786 break;
787 }
788
789 log("NdpCreateConnection send INIT\n");
790 req.request = SMBREQ_INIT;
791 req.param = (char *)0xFFFFFFFF;
792 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
793 if (rc || action < sizeof(resp) || resp.rc)
794 {
795 return rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
796 }
797 pConn->clientpid = resp.value & 0xFFFF;
798
799 rc = DosAllocSharedMem((PPVOID)&pConn->mem, NULL, pRes->memlen, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE | pRes->objany);
800 if (rc)
801 {
802 break;
803 }
804 rc = DosGiveSharedMem(pConn->mem, pConn->clientpid, PAG_READ | PAG_WRITE);
805 if (rc)
806 {
807 break;
808 }
809
810 log("NdpCreateConnection send CONNECT\n");
811 MemCpy(pConn->mem, &pRes->srv, sizeof(pRes->srv));
812 req.request = SMBREQ_CONNECT;
813 req.param = pConn->mem;
814 req.paramlen = sizeof(pConn->srv);
815 req.length = req.paramlen;
816
817 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
818 if (rc || action < sizeof(resp) || resp.rc)
819 {
820 rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
821 }
822 else
823 {
824 MemCpy(&pConn->srv, pConn->mem, sizeof(pConn->srv));
825 }
826 } while (0);
827 if (rc)
828 {
829 if (pConn->mem)
830 {
831 DosFreeMem(pConn->mem);
832 }
833 if (pConn->pipe)
834 {
835 DosClose(pConn->pipe);
836 }
837 MemSet(pConn, 0, sizeof(*pConn));
838 DosFreeMem(pConn);
839 pConn = NULL;
840 }
841
842 *pconn = (HCONNECTION)pConn;
843 log("NdpCreateConnection %d %d\n", rc, resp.rc);
844 return rc;
845}
846
847
848int APIENTRY NdpFreeConnection (HCONNECTION conn)
849{
850 Connection *pConn = (Connection *)conn;
851 Resource *pRes = pConn->pRes;
852
853 log("NdpFreeConnection in\n");
854 if (pConn->mem)
855 {
856 smb_request req = {0};
857 smb_response resp = {0};
858 unsigned long action;
859 if (pConn->file.fd >= 0)
860 {
861 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
862 req.request = SMBREQ_CLOSE;
863 req.param = pConn->mem;
864 req.length = sizeof(pConn->file);
865 req.paramlen = sizeof(pConn->file);
866
867 DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
868 pConn->file.fd = -1;
869 }
870
871 req.request = SMBREQ_DISCONNECT;
872 req.param = pConn->mem;
873 req.length = 0;
874 req.paramlen = 0;
875
876 DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
877
878 DosFreeMem(pConn->mem);
879 DosClose(pConn->pipe);
880 MemSet(pConn, 0, sizeof(*pConn));
881 }
882
883 DosFreeMem(pConn);
884 log("NdpFreeConnection %d\n", NO_ERROR);
885 return NO_ERROR;
886}
887
888int APIENTRY NdpRsrcCompare (HRESOURCE resource, HRESOURCE resource2)
889{
890 Resource *pRes = (Resource *)resource;
891 Resource *pRes2 = (Resource *)resource2;
892 int rc = ND_RSRC_DIFFERENT;
893
894 log("NdpRsrcCompare in\n");
895
896 if (ph->fsphStrICmp(pRes->srv.server_name, pRes2->srv.server_name) == 0
897 && ph->fsphStrICmp(pRes->srv.share_name, pRes2->srv.share_name) == 0
898 && ph->fsphStrICmp(pRes->srv.username, pRes2->srv.username) == 0
899 && ph->fsphStrICmp(pRes->srv.workgroup, pRes2->srv.workgroup) == 0)
900 {
901 // resources are equal
902 rc = ND_RSRC_EQUAL;
903 }
904
905 log("NdpRsrcCompare %d\n", rc);
906
907 return rc;
908}
909
910int APIENTRY NdpRsrcUpdate (HRESOURCE resource, HRESOURCE resource2)
911{
912 // do nothing
913 log("NdpRsrcUpdate %d\n", NO_ERROR);
914 return NO_ERROR;
915}
916
917int APIENTRY NdpRsrcQueryInfo (HRESOURCE resource, ULONG *pulFlags, void *pdata, ULONG insize, ULONG *poutlen)
918{
919 Resource *pRes = (Resource *)resource;
920 int rc = NO_ERROR;
921 char s[4096];
922
923 log("NdpRsrcQueryInfo in\n");
924
925 switch (pRes->rootlevel)
926 {
927 case 0:
928 {
929 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\@%s", ifL ? "64" : "32", pRes->srv.username);
930 } break;
931 case 1:
932 {
933 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s %s: \\\\@%s", ifL ? "64" : "32", pRes->srv.workgroup, pRes->srv.username);
934 } break;
935 case 2:
936 {
937 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);
938 } break;
939 default:
940 {
941 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);
942 } break;
943 }
944 *poutlen = StrLen(s) + 1;
945 if (*poutlen > insize)
946 {
947 rc = ERROR_BUFFER_OVERFLOW;
948 }
949 else
950 {
951 MemCpy(pdata, s, *poutlen);
952 }
953
954 log("NdpRsrcQueryInfo %d\n", rc);
955
956 return rc;
957}
958
959int APIENTRY NdpRsrcQueryFSAttach (HRESOURCE resource, void *pdata, ULONG insize, ULONG *poutlen)
960{
961 ULONG ulDummy = 0;
962 /* just return the resource info string */
963 return NdpRsrcQueryInfo (resource, &ulDummy, pdata, insize, poutlen);
964}
965
966int APIENTRY NdpRsrcQueryFSAllocate (HRESOURCE resource, NDFSALLOCATE *pfsa)
967{
968 int rc = NO_ERROR, rc1;
969
970 Connection *pConn = 0;
971 smb_request req = {0};
972 smb_response resp = {0};
973 unsigned long action = 0;
974
975 log("NdpRsrcQueryFSAllocate %08x\n", pfsa);
976
977 if (!pfsa)
978 {
979 return NO_ERROR;
980 }
981
982
983 rc = NdpCreateConnection (resource, (HCONNECTION *)&pConn);
984 if (rc)
985 {
986 log("NdpCreateConnection failed rc=%d\n", rc);
987 pfsa->cSectorUnit = 1;
988 pfsa->cUnit = 123456;
989 pfsa->cUnitAvail = 123456;
990 pfsa->cbSector = 2048;
991 return rc;
992 }
993
994 MemSet(pConn->mem, 0, sizeof(FSALLOCATE));
995 req.request = SMBREQ_DSKATTR;
996 req.param = pConn->mem;
997 req.paramlen = sizeof(FSALLOCATE);
998 req.length = req.paramlen;
999
1000 rc = DosTransactNPipe( pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1001 if (rc || action < sizeof(resp) || resp.rc)
1002 {
1003 pfsa->cSectorUnit = 1;
1004 pfsa->cUnit = 123456;
1005 pfsa->cUnitAvail = 123456;
1006 pfsa->cbSector = 2048;
1007 rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1008 }
1009 else
1010 {
1011 FSALLOCATE * fsa = (FSALLOCATE *)pConn->mem;
1012 pfsa->cSectorUnit = fsa->cSectorUnit;
1013 pfsa->cUnit = fsa->cUnit;
1014 pfsa->cUnitAvail = fsa->cUnitAvail;
1015 pfsa->cbSector = fsa->cbSector;
1016 }
1017
1018 rc1 = NdpFreeConnection((HCONNECTION)pConn);
1019
1020 log("NdpRsrcQueryFSAllocate %d/%d/%d (cUnit = %d/cUnitAvail = %d/cbSector = %d)\n", rc, resp.rc, rc1, pfsa->cUnit, pfsa->cUnitAvail, pfsa->cbSector);
1021 return rc;
1022}
1023
1024int APIENTRY NdpFindStart (HCONNECTION conn, void *plist, NDFILEINFOL *pfiparent, char *szPath, ULONG ulAttribute)
1025{
1026 Connection *pConn = (Connection *)conn;
1027 Resource *pRes = pConn->pRes;
1028 int rc = NO_ERROR, count = 0;
1029 unsigned long action;
1030 smb_request req = {0};
1031 smb_response resp = {0};
1032 char *mask = "*";
1033 char dir[CCHMAXPATH+1] = {0};
1034 char path[CCHMAXPATH+1] = {0};
1035 char fullname[CCHMAXPATH+1] = {0};
1036 smbwrp_fileinfo * data;
1037 NDPATHELEMENT *pel = ph->fsphNameElem(0);
1038
1039 log("NdpFindStart in\n");
1040 do
1041 {
1042 rc = checkconnection(pConn);
1043 if (rc)
1044 {
1045 break;
1046 }
1047
1048 StrNCpy(dir, szPath, sizeof(dir) - 1);
1049 if (pel)
1050 {
1051 mask = pel->name;
1052 dir[StrLen(szPath) - pel->length] = 0;
1053 }
1054 action = StrLen(dir) - 1;
1055 if (dir[action] == '\\')
1056 {
1057 dir[action] = 0;
1058 }
1059 rc = pathparser(pRes, pConn, dir, path);
1060 if (rc)
1061 {
1062 break;
1063 }
1064 action = StrLen(path) - 1;
1065 if (path[action] != '\\')
1066 {
1067 StrNCat(path, "\\", sizeof(path) - 1);
1068 }
1069 StrCpy(dir, path);
1070 StrNCat(path, mask, sizeof(path) - 1);
1071
1072 MemCpy(pConn->mem, &pConn->srv, sizeof(pConn->srv));
1073 StrCpy(pConn->mem + sizeof(pConn->srv), path);
1074 req.request = SMBREQ_FILELIST;
1075 req.param = pConn->mem;
1076 req.paramlen = sizeof(pConn->srv) + CCHMAXPATH + 1;
1077 req.length = pRes->memlen;
1078 data = (smbwrp_fileinfo *)(pConn->mem + sizeof(pConn->srv) + CCHMAXPATH + 1);
1079
1080 do {
1081 int i;
1082 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1083 if (pConn->rc || action < sizeof(resp)
1084 || (resp.rc && resp.rc != ERROR_MORE_DATA))
1085 {
1086 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1087 break;
1088 }
1089log("NdpFindStart %d %d %d\n", pConn->rc, resp.rc, resp.length / sizeof(smbwrp_fileinfo));
1090 if (ifL)
1091 {
1092 for (i = 0; i < resp.length / sizeof(smbwrp_fileinfo); i++)
1093 {
1094 smbwrp_fileinfo * finfo = data + i;
1095log("NdpFindStart found <%s> %d\n", finfo->fname, finfo->easize);
1096 StrCpy(fullname, dir);
1097 StrCat(fullname, finfo->fname);
1098 StrCpy(finfo->fname, fullname);
1099 count += getfindinfoL(pConn, plist, finfo, ulAttribute, mask);
1100 }
1101 }
1102 else
1103 {
1104 FILEFINDBUF3 buf = {0};
1105 for (i = 0; i < resp.length / sizeof(smbwrp_fileinfo); i++)
1106 {
1107 smbwrp_fileinfo * finfo = data + i;
1108 getfindinfo(pConn, &buf, finfo);
1109
1110 if (ph->fsphAttrMatch(ulAttribute, buf.attrFile)
1111 && ph->fsphWildMatch(mask, buf.achName, ND_IGNORE_CASE))
1112 {
1113 StrCpy(fullname, dir);
1114 StrCat(fullname, finfo->fname);
1115 StrCpy(finfo->fname, fullname);
1116 ph->fsphAddFileFind32(plist, &buf, finfo, sizeof(*finfo), 0);
1117 count++;
1118 }
1119 }
1120 }
1121 } while (resp.rc == ERROR_MORE_DATA);
1122 } while (0);
1123
1124 log("NdpFindStart <%s> (%s) cnt %d %d %d\n", szPath, path, count, rc, pConn->rc);
1125 return rc;
1126}
1127
1128int APIENTRY NdpQueryPathInfo (HCONNECTION conn, void *plist, char *szPath)
1129{
1130 Connection *pConn = (Connection *)conn;
1131 Resource *pRes = pConn->pRes;
1132 int rc = 0;
1133 unsigned long action;
1134 smb_request req = {0};
1135 smb_response resp = {0};
1136 smbwrp_fileinfo * finfo = (smbwrp_fileinfo *)pConn->mem;
1137 char path[CCHMAXPATH+1] = {0};
1138
1139 log("NdpQueryInfo in <%s>\n", szPath);
1140
1141 do {
1142 if (ph->fsphStrChr(szPath, '*') || ph->fsphStrChr(szPath, '?'))
1143 {
1144 rc = ERROR_FILE_NOT_FOUND;
1145 break;
1146 }
1147
1148 rc = checkconnection(pConn);
1149 if (rc)
1150 {
1151 break;
1152 }
1153
1154 rc = pathparser(pRes, pConn, szPath, path);
1155 switch (rc)
1156 {
1157 case NO_ERROR :
1158 case ERROR_FILE_NOT_FOUND:
1159 case ERROR_PATH_NOT_FOUND:
1160 case ERROR_ACCESS_DENIED:
1161 case ERROR_INVALID_PARAMETER:
1162 {
1163 break;
1164 }
1165 default :
1166 {
1167 rc = ERROR_PATH_NOT_FOUND;
1168 }
1169 }
1170 if (rc)
1171 {
1172 break;
1173 }
1174 StrNCpy(finfo->fname, path, sizeof(finfo->fname) - 1);
1175 req.request = SMBREQ_GETINFO;
1176 req.param = pConn->mem;
1177 req.paramlen = sizeof(*finfo);
1178 req.length = req.paramlen;
1179 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1180 if (pConn->rc || action < sizeof(resp) || resp.rc)
1181 {
1182 switch (resp.rc)
1183 {
1184 case NO_ERROR :
1185 case ERROR_FILE_NOT_FOUND:
1186 case ERROR_PATH_NOT_FOUND:
1187 case ERROR_ACCESS_DENIED:
1188 case ERROR_INVALID_PARAMETER:
1189 break;
1190 default :
1191 {
1192 resp.rc = ERROR_PATH_NOT_FOUND;
1193 }
1194 }
1195 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1196 }
1197 else
1198 {
1199 finfo->easize = -1;
1200 if (ifL)
1201 {
1202 getfindinfoL(pConn, plist, finfo, 0, NULL);
1203 }
1204 else
1205 {
1206 int trc;
1207 FILEFINDBUF3 buf = {0};
1208 getfindinfo(pConn, &buf, finfo);
1209 trc = ph->fsphAddFileFind32(plist, &buf, finfo, sizeof(*finfo), 0);
1210 log("NdpQueryInfo got info <%s> attr %08x size %d namelen %d date %lu %lu. Plist 0x%08x rc = %d\n", buf.achName, buf.attrFile, buf.cbFile, buf.cchName, buf.fdateLastWrite, buf.ftimeLastWrite, plist, trc);
1211 }
1212 }
1213 if (rc == ERROR_FILE_NOT_FOUND)
1214 {
1215 // now try the upper path
1216 char * p = ph->fsphStrChr(finfo->fname, '\\');
1217 if (p && p > finfo->fname)
1218 {
1219 *p = 0;
1220 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1221 if (pConn->rc || action < sizeof(resp) || resp.rc)
1222 {
1223 rc = pConn->rc ? pConn->rc : (resp.rc ? ERROR_PATH_NOT_FOUND : ERROR_INVALID_PARAMETER);
1224 }
1225 }
1226 }
1227 } while (0);
1228
1229 log("NdpQueryInfo <%s> (%s) %d %d\n", szPath, path, rc, pConn->rc);
1230 return rc;
1231}
1232
1233int APIENTRY NdpDeletePathInfo (HRESOURCE resource, NDFILEINFOL *pfi)
1234{
1235// log("NdpDeletePathInfo %d\n", 0);
1236 return NO_ERROR;
1237}
1238
1239int APIENTRY NdpRefresh (HCONNECTION conn, char *path, int tree)
1240{
1241 log("NdpRefresh <%s> %d\n", path, 0);
1242 return NO_ERROR;
1243}
1244
1245int APIENTRY NdpDiscardResourceData (HRESOURCE resource, NDDATABUF *pdatabuf)
1246{
1247 // The plugin do not have to deallocate anything
1248 // because resource data did not contain any pointers
1249 // to plugins data.
1250 // Data stored by fsphSetResourceData will be
1251 // deallocated by NetDrive.
1252
1253 log("NdpDicardresourceData %d\n", 0);
1254 return NO_ERROR;
1255}
1256
1257int APIENTRY NdpSetPathInfo (HCONNECTION conn, NDFILEINFOL *pfi, char *szPathName)
1258{
1259 Connection *pConn = (Connection *)conn;
1260 Resource *pRes = pConn->pRes;
1261 int rc = 0;
1262 unsigned long action;
1263 smb_request req = {0};
1264 smb_response resp = {0};
1265 smbwrp_fileinfo * finfo = (smbwrp_fileinfo *)pConn->mem;
1266 char path[CCHMAXPATH+1] = {0};
1267
1268 log("NdpSetPathInfo in\n");
1269 do {
1270 rc = checkconnection(pConn);
1271 if (rc)
1272 {
1273 break;
1274 }
1275
1276 rc = pathparser(pRes, pConn, szPathName, path);
1277 if (rc)
1278 {
1279 break;
1280 }
1281
1282 MemSet(finfo, 0, sizeof(*finfo));
1283
1284 StrNCpy(finfo->fname, path, sizeof(finfo->fname) - 1);
1285 ph->fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, (unsigned long *)&(finfo->mtime));
1286 if (ifL)
1287 {
1288 finfo->attr = pfi->stat.attrFile & 0x37;
1289 }
1290 else
1291 {
1292 FILESTATUS3 * stat = (FILESTATUS3 *)&(pfi->stat);
1293 finfo->attr = stat->attrFile & 0x37;
1294 }
1295 req.request = SMBREQ_SETINFO;
1296 req.param = pConn->mem;
1297 req.paramlen = sizeof(*finfo);
1298 req.length = req.paramlen;
1299 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1300 if (pConn->rc || action < sizeof(resp) || resp.rc)
1301 {
1302 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1303 }
1304 } while (0);
1305 log("NdpSetPathInfo <%s> (%s) %d %d\n", szPathName, path, rc, pConn->rc);
1306 return rc;
1307}
1308
1309int buildFEALIST(FEALIST *pFEASrc, GEALIST *pGEAList, FEALIST *pFEAList)
1310{
1311 int rc = 0;
1312 FEA * pfea;
1313 FEA * pfeadest;
1314 unsigned long size, done = sizeof(pFEAList->cbList), dsize, ddone = sizeof(pFEAList->cbList);
1315
1316 size = pFEASrc->cbList;
1317 pfea = pFEASrc->list;
1318 pfeadest = pFEAList->list;
1319 dsize = pFEAList->cbList;
1320//log("buildFEALIST in destsize %d srcsize %d pGEAList=%08x pGEAList->cbList=%d\n", dsize, ddone, size, pGEAList, pGEAList ? pGEAList->cbList : 0);
1321 while (done < size)
1322 {
1323 char * name = (char *)(pfea + 1);
1324 int insert = 1;
1325 if (pGEAList && pGEAList->cbList > sizeof(pGEAList->cbList))
1326 {
1327 GEA * pgea = pGEAList->list;
1328 unsigned long size = pGEAList->cbList - sizeof(pGEAList->cbList), done = 0;
1329 insert = 0;
1330 while (done < size)
1331 {
1332//log("comp <%s> <%s>\n", name, pgea->szName);
1333 if (!ph->fsphStrNCmp(name, pgea->szName, pgea->cbName))
1334 {
1335 insert = 1;
1336 break;
1337 }
1338 done += pgea->cbName + 2;
1339 pgea = (GEA *)((char *)pgea + pgea->cbName + 2);
1340 }
1341 }
1342 if (insert)
1343 {
1344 ddone += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1345 if (ddone <= dsize)
1346 {
1347 pfeadest->cbName = pfea->cbName;
1348 pfeadest->cbValue = pfea->cbValue;
1349 pfeadest->fEA = 0;
1350 StrCpy((char *)(pfeadest + 1), name);
1351 MemCpy((char *)(pfeadest + 1) + pfea->cbName + 1, (char *)(pfea + 1) + pfea->cbName + 1, pfea->cbValue);
1352 pfeadest = (FEA *)((char *)pFEAList + ddone);
1353 }
1354 }
1355 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1356//log("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);
1357 pfea = (FEA *)((char *)pFEASrc + done);
1358 }
1359 pFEAList->cbList = ddone;
1360 if (ddone > dsize && dsize > sizeof(pFEAList->cbList))
1361 {
1362 rc = ERROR_BUFFER_OVERFLOW;
1363 }
1364 log("buildFEALIST rc=%d destsize=%d destdone=%d srcsize=%d pGEAList=%08x\n", rc, dsize, ddone, size, pGEAList);
1365 return rc;
1366}
1367
1368int APIENTRY NdpEAQuery (HCONNECTION conn, GEALIST *pGEAList, NDFILEINFOL *pfi, FEALIST *pFEAList)
1369{
1370 Connection *pConn = (Connection *)conn;
1371 Resource *pRes = pConn->pRes;
1372 int rc = 0;
1373 unsigned long action;
1374 smb_request req = {0};
1375 smb_response resp = {0};
1376 char * path = NULL;
1377 FEALIST * pFEASrc;
1378 NDDATABUF fdata = {0};
1379 smbwrp_fileinfo *finfo;
1380
1381 if (!pfi || !pfi->pszName || !pFEAList)
1382 {
1383 return ERROR_EAS_NOT_SUPPORTED;
1384 }
1385 if (!pRes->easupport)
1386 {
1387 return ERROR_EAS_NOT_SUPPORTED;
1388 }
1389
1390 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1391 if (rc || !fdata.ulSize || !fdata.pData)
1392 {
1393 log("NdpEAQuery: ph->fsphGetFileInfoData = %d/%d %08x\n", rc, fdata.ulSize, fdata.pData);
1394 return ERROR_EAS_NOT_SUPPORTED;
1395 }
1396 finfo = (smbwrp_fileinfo *)fdata.pData;
1397 path = finfo->fname;
1398
1399 log("NdpEAQuery in <%s> %08x %d\n", path, pGEAList, pGEAList ? pGEAList->cbList : 0);
1400 do {
1401 rc = checkconnection(pConn);
1402 if (rc)
1403 {
1404 break;
1405 }
1406
1407 StrNCpy(pConn->mem, path, CCHMAXPATH);
1408 req.request = SMBREQ_LISTEA;
1409 req.param = pConn->mem;
1410 req.paramlen = CCHMAXPATH + 1;
1411 req.length = pRes->memlen - req.paramlen;
1412 pFEASrc = (FEALIST *)(pConn->mem + req.paramlen);
1413 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1414 if (pConn->rc || action < sizeof(resp) || resp.rc)
1415 {
1416 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1417 switch (rc)
1418 {
1419 case ERROR_FILE_NOT_FOUND :
1420 case ERROR_PATH_NOT_FOUND :
1421 {
1422 pFEAList->cbList = sizeof(pFEAList->cbList);
1423 rc = NO_ERROR;
1424 } break;
1425 case ERROR_BUFFER_OVERFLOW :
1426 {
1427 pFEAList->cbList = pFEASrc->cbList;
1428 } break;
1429 default :
1430 {
1431 rc = ERROR_EAS_NOT_SUPPORTED;
1432 }
1433 }
1434 }
1435 else
1436 {
1437 rc = buildFEALIST(pFEASrc, pGEAList, pFEAList);
1438 }
1439 } while (0);
1440 log("NdpEAQuery <%s> %d %d %d %d %d\n", pfi->pszName, rc, pFEASrc->cbList, pFEAList->cbList, pConn->rc, resp.rc);
1441 return rc;
1442}
1443
1444int APIENTRY NdpEASet (HCONNECTION conn, FEALIST *pFEAList, NDFILEINFOL *pfi)
1445{
1446 Connection *pConn = (Connection *)conn;
1447 Resource *pRes = pConn->pRes;
1448 int rc = 0;
1449 smb_request req = {0};
1450 smb_response resp = {0};
1451 char * path;
1452 unsigned long action;
1453 NDDATABUF fdata = {0};
1454 smbwrp_fileinfo *finfo;
1455
1456 log("NdpEASet in\n");
1457
1458 if (!pfi || !pfi->pszName || !pFEAList || pFEAList->cbList <= sizeof(long))
1459 {
1460 return ERROR_EAS_NOT_SUPPORTED;
1461 }
1462 if (!pRes->easupport)
1463 {
1464 return ERROR_EAS_NOT_SUPPORTED;
1465 }
1466
1467 if (pFEAList->cbList > pRes->memlen)
1468 {
1469 return ERROR_NOT_ENOUGH_MEMORY;
1470 }
1471
1472 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1473 if (rc || !fdata.ulSize || !fdata.pData)
1474 {
1475 log("NdpEASet: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData);
1476 return ERROR_EAS_NOT_SUPPORTED;
1477 }
1478 finfo = (smbwrp_fileinfo *)fdata.pData;
1479 path = finfo->fname;
1480
1481 do {
1482 rc = checkconnection(pConn);
1483 if (rc)
1484 {
1485 break;
1486 }
1487
1488 StrNCpy(pConn->mem, path, CCHMAXPATH);
1489 MemCpy(pConn->mem + CCHMAXPATH + 1, pFEAList, pFEAList->cbList);
1490 req.request = SMBREQ_SETEA;
1491 req.param = pConn->mem;
1492 req.paramlen = pFEAList->cbList + CCHMAXPATH + 1;
1493 req.length = req.paramlen;
1494 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1495 if (pConn->rc || action < sizeof(resp) || resp.rc)
1496 {
1497 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1498 }
1499 } while (0);
1500 log("NdpEASet %d\n", rc);
1501 return rc;
1502}
1503
1504int APIENTRY NdpEASize (HCONNECTION conn, NDFILEINFOL *pfi, ULONG *pulEASize)
1505{
1506 Connection *pConn = (Connection *)conn;
1507 Resource *pRes = pConn->pRes;
1508 int rc = 0;
1509 unsigned long action;
1510 smb_request req = {0};
1511 smb_response resp = {0};
1512 char * path = NULL;
1513 FEALIST * pfealist;
1514 NDDATABUF fdata = {0};
1515 smbwrp_fileinfo *finfo;
1516 int easize;
1517
1518 if (!pfi || !pulEASize)
1519 {
1520 return ERROR_EAS_NOT_SUPPORTED;
1521 }
1522 if (!pRes->easupport)
1523 {
1524 return ERROR_EAS_NOT_SUPPORTED;
1525 }
1526
1527 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1528 if (rc || !fdata.ulSize || !fdata.pData)
1529 {
1530 log("NdpEASize: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData);
1531 return ERROR_EAS_NOT_SUPPORTED;
1532 }
1533 finfo = (smbwrp_fileinfo *)fdata.pData;
1534 easize = finfo->easize;
1535 finfo->easize = -1;
1536 path = finfo->fname;
1537 if (easize >= 0)
1538 {
1539 *pulEASize = easize;
1540 log("NdpEASize <%s> cached %d\n", path, easize);
1541 return NO_ERROR;
1542 }
1543
1544 log("NdpEASize in <%s> \n", path);
1545 do {
1546 rc = checkconnection(pConn);
1547 if (rc)
1548 {
1549 break;
1550 }
1551
1552 StrNCpy(pConn->mem, path, CCHMAXPATH);
1553 req.request = SMBREQ_LISTEA;
1554 req.param = pConn->mem;
1555 req.paramlen = CCHMAXPATH + 1;
1556 req.length = pRes->memlen - req.paramlen;
1557 pfealist = (FEALIST *)(pConn->mem + req.paramlen);
1558 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1559 if (pConn->rc || action < sizeof(resp) || resp.rc)
1560 {
1561 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1562 switch (rc)
1563 {
1564 case ERROR_FILE_NOT_FOUND :
1565 case ERROR_PATH_NOT_FOUND :
1566 {
1567 pfealist->cbList = sizeof(pfealist->cbList);
1568 } /* Fall through */
1569 case ERROR_BUFFER_OVERFLOW :
1570 {
1571 rc = NO_ERROR;
1572 } break;
1573 default :
1574 {
1575 rc = ERROR_EAS_NOT_SUPPORTED;
1576 }
1577 }
1578 }
1579 *pulEASize = pfealist->cbList;
1580 } while (0);
1581 log("NdpEASize <%s> %d %d %d %d\n", pfi->pszName, *pulEASize, rc, pConn->rc, resp.rc);
1582 return rc;
1583}
1584
1585int APIENTRY NdpSetCurrentDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szPath)
1586{
1587 Connection *pConn = (Connection *)conn;
1588 Resource *pRes = pConn->pRes;
1589 smb_request req = {0};
1590 smb_response resp = {0};
1591 int rc = 0;
1592 unsigned long action;
1593 char path[CCHMAXPATH+1] = {0};
1594
1595 log("NdpSetCurrentDir in\n");
1596 do {
1597 rc = checkconnection(pConn);
1598 if (rc)
1599 {
1600 break;
1601 }
1602
1603 rc = pathparser(pRes, pConn, szPath, path);
1604 if (rc)
1605 {
1606 break;
1607 }
1608
1609 StrNCpy(pConn->mem, path, CCHMAXPATH);
1610 req.request = SMBREQ_CHDIR;
1611 req.param = pConn->mem;
1612 req.paramlen = CCHMAXPATH + 1;
1613 req.length = req.paramlen;
1614 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1615 if (pConn->rc || action < sizeof(resp) || resp.rc)
1616 {
1617 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1618 }
1619 } while (0);
1620 log("NdpSetCurrentDir <%s> (%s) %d %d\n", szPath, path, rc, pConn->rc);
1621 return rc;
1622}
1623
1624int APIENTRY NdpCopy (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
1625{
1626 log("NdpCopy <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
1627 return ERROR_CANNOT_COPY;
1628}
1629
1630int APIENTRY NdpCopy2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
1631{
1632 log("NdpCopy2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
1633 return ERROR_CANNOT_COPY;
1634}
1635
1636int APIENTRY NdpForceDelete (HCONNECTION conn, NDFILEINFOL *pfi, char *szFile)
1637{
1638 Connection *pConn = (Connection *)conn;
1639 Resource *pRes = pConn->pRes;
1640 smb_request req = {0};
1641 smb_response resp = {0};
1642 int rc = 0;
1643 unsigned long action;
1644 char path[CCHMAXPATH+1] = {0};
1645
1646 log("NdpForceDelete in\n");
1647 do {
1648 rc = checkconnection(pConn);
1649 if (rc)
1650 {
1651 break;
1652 }
1653
1654 rc = pathparser(pRes, pConn, szFile, path);
1655 if (rc)
1656 {
1657 break;
1658 }
1659
1660 StrNCpy(pConn->mem, path, CCHMAXPATH);
1661 req.request = SMBREQ_UNLINK;
1662 req.param = pConn->mem;
1663 req.paramlen = CCHMAXPATH + 1;
1664 req.length = req.paramlen;
1665 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1666 if (pConn->rc || action < sizeof(resp) || resp.rc)
1667 {
1668 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1669 }
1670 } while (0);
1671 log("NdpForceDelete <%s> (%s) %d %d\n", szFile, path, rc, pConn->rc);
1672 return rc;
1673}
1674
1675int APIENTRY NdpCreateDir (HCONNECTION conn, NDFILEINFOL *pfiparent, char *szDirName, FEALIST *pFEAList)
1676{
1677 Connection *pConn = (Connection *)conn;
1678 Resource *pRes = pConn->pRes;
1679 smb_request req = {0};
1680 smb_response resp = {0};
1681 int rc = 0;
1682 unsigned long action;
1683 char path[CCHMAXPATH+1] = {0};
1684
1685 log("NdpCreateDir in\n");
1686 do {
1687 rc = checkconnection(pConn);
1688 if (rc)
1689 {
1690 break;
1691 }
1692
1693 rc = pathparser(pRes, pConn, szDirName, path);
1694 if (rc)
1695 {
1696 break;
1697 }
1698
1699 StrNCpy(pConn->mem, path, CCHMAXPATH);
1700 req.request = SMBREQ_MKDIR;
1701 req.param = pConn->mem;
1702 req.paramlen = CCHMAXPATH + 1;
1703 req.length = req.paramlen;
1704 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1705 if (pConn->rc || action < sizeof(resp) || resp.rc)
1706 {
1707 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1708 }
1709 } while (0);
1710 log("NdpCreateDir <%s> (%s) %d %d\n", szDirName, path, rc, pConn->rc);
1711 return rc;
1712}
1713
1714int APIENTRY NdpDeleteDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szDir)
1715{
1716 Connection *pConn = (Connection *)conn;
1717 Resource *pRes = pConn->pRes;
1718 smb_request req = {0};
1719 smb_response resp = {0};
1720 int rc = 0;
1721 unsigned long action;
1722 char path[CCHMAXPATH+1] = {0};
1723
1724 log("NdpDeleteDir in\n");
1725 do {
1726 rc = checkconnection(pConn);
1727 if (rc)
1728 {
1729 break;
1730 }
1731
1732 rc = pathparser(pRes, pConn, szDir, path);
1733 if (rc)
1734 {
1735 break;
1736 }
1737
1738 StrNCpy(pConn->mem, path, CCHMAXPATH);
1739 req.request = SMBREQ_RMDIR;
1740 req.param = pConn->mem;
1741 req.paramlen = CCHMAXPATH + 1;
1742 req.length = req.paramlen;
1743 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1744 if (pConn->rc || action < sizeof(resp) || resp.rc)
1745 {
1746 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1747 }
1748 } while (0);
1749 log("NdpDeleteDir <%s> (%s) %d %d\n", szDir, path, rc, pConn->rc);
1750 return rc;
1751}
1752
1753int APIENTRY NdpMove (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
1754{
1755 Connection *pConn = (Connection *)conn;
1756 Resource *pRes = pConn->pRes;
1757 smb_request req = {0};
1758 smb_response resp = {0};
1759 int rc = 0;
1760 unsigned long action;
1761 char src[CCHMAXPATH+1] = {0};
1762 int l1, l2;
1763 char * p = szDst;
1764
1765 log("NdpMove in\n");
1766 do
1767 {
1768 rc = checkconnection(pConn);
1769 if (rc)
1770 {
1771 break;
1772 }
1773
1774 rc = pathparser(pRes, pConn, szSrc, src);
1775 if (rc)
1776 {
1777 break;
1778 }
1779 l1 = StrLen(szSrc);
1780 l2 = StrLen(src);
1781 if (l1 > l2)
1782 {
1783 if (ph->fsphStrNICmp(szSrc, szDst, l1 - l2))
1784 {
1785 // the file moved accross different shares or servers or workgroups
1786 rc = ERROR_WRITE_PROTECT;
1787 break;
1788 }
1789 p = szDst + l1 - l2 + 1;
1790 }
1791 StrNCpy(pConn->mem, src, CCHMAXPATH);
1792 pConn->mem[CCHMAXPATH + 1] = '\\';
1793 StrNCpy(pConn->mem + CCHMAXPATH + 2, p, CCHMAXPATH - 1);
1794 req.request = SMBREQ_RENAME;
1795 req.param = pConn->mem;
1796 req.paramlen = 2 * (CCHMAXPATH + 1);
1797 req.length = req.paramlen;
1798 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1799 if (pConn->rc || action < sizeof(resp) || resp.rc)
1800 {
1801 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1802 }
1803 } while (0);
1804 log("NdpMove <%s> -> <%s> (%s) %d %d\n", szSrc, szDst, src, rc, pConn->rc);
1805
1806 return rc;
1807}
1808
1809int APIENTRY NdpMove2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
1810{
1811 log("NdpMove2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_WRITE_PROTECT);
1812 return ERROR_WRITE_PROTECT;
1813}
1814
1815
1816int APIENTRY NdpChangeCase (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
1817{
1818 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
1819}
1820
1821int APIENTRY NdpRename (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
1822{
1823 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
1824}
1825
1826int smbopen(Connection *pConn, char *szFileName, int flags, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1827{
1828 Resource *pRes = pConn->pRes;
1829 smb_request req = {0};
1830 smb_response resp = {0};
1831 unsigned long action;
1832 int rc = 0;
1833 char path[CCHMAXPATH+1] = {0};
1834
1835 log("smbopen in %d\n", pConn->file.fd);
1836 do {
1837 if (pConn->file.fd > 0)
1838 {
1839 rc = ERROR_TOO_MANY_OPEN_FILES;
1840 break;
1841 }
1842
1843 rc = checkconnection(pConn);
1844 if (rc)
1845 {
1846 break;
1847 }
1848
1849 rc = pathparser(pRes, pConn, szFileName, path);
1850 if (rc)
1851 {
1852 break;
1853 }
1854
1855 StrNCpy(pConn->file.fullname, szFileName, sizeof(pConn->file.fullname) - 1);
1856 StrNCpy(pConn->file.fname, path, sizeof(pConn->file.fname) - 1);
1857 flags |= O_BINARY;
1858 switch (ulOpenMode & 3)
1859 {
1860 case OPEN_ACCESS_READONLY : flags |= O_RDONLY; break;
1861 case OPEN_ACCESS_WRITEONLY : flags |= O_WRONLY; break;
1862 case OPEN_ACCESS_READWRITE : flags |= O_RDWR; break;
1863 default : flags |= O_RDWR;
1864 }
1865 pConn->file.openmode = flags;
1866 pConn->file.openattr = ulAttribute & 0x37;
1867 pConn->file.denymode = (ulOpenMode & 0x70) >> 4;
1868 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
1869 req.request = SMBREQ_OPEN;
1870 req.param = pConn->mem;
1871 req.paramlen = sizeof(pConn->file);
1872 req.length = req.paramlen;
1873 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1874 if (pConn->rc || action < sizeof(resp) || resp.rc)
1875 {
1876 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1877 }
1878 else
1879 {
1880 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
1881 }
1882 } while (0);
1883 log("smbopen <%s> (%s) %08x %08x %08x %d %d. file = %d\n", szFileName, path, flags, ulOpenMode, ulAttribute, rc, pConn->rc, pConn->file.fd);
1884 if (!rc && pFEAList)
1885 {
1886 int rc1 = NdpFileEASet((HCONNECTION)pConn, (NDFILEHANDLE)0, pFEAList);
1887 log("smbopen NdpFileEASet %d. pFEAList->cbList %d\n", rc1, pFEAList->cbList);
1888 }
1889
1890 return rc;
1891}
1892
1893int APIENTRY NdpOpenReplace (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1894{
1895 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
1896}
1897
1898int APIENTRY NdpOpenReplaceL(HCONNECTION conn, NDFILEINFO *pfi, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1899{
1900 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
1901}
1902
1903int APIENTRY NdpOpenCreate (HCONNECTION conn, NDFILEINFOL *pfiparent, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1904{
1905// return smbopen((Connection *)conn, szFileName, O_CREAT, ulOpenMode, ulAttribute);
1906 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);
1907}
1908
1909int APIENTRY NdpOpenCreateL(HCONNECTION conn, NDFILEINFO *pfiparent, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1910{
1911 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);
1912}
1913
1914int APIENTRY NdpOpenExisting (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulOpenMode, USHORT *pfNeedEA)
1915{
1916 if (pfNeedEA) *pfNeedEA = 0; // wtf is this ?
1917 return smbopen((Connection *)conn, szFileName, 0, ulOpenMode, 0, NULL);
1918}
1919
1920int APIENTRY NdpSetFileAttribute (HCONNECTION conn, NDFILEINFOL *pfi, char *szFileName, USHORT usAttr)
1921{
1922 Connection *pConn = (Connection *)conn;
1923 Resource *pRes = pConn->pRes;
1924 int rc = 0;
1925 unsigned long action;
1926 smb_request req = {0};
1927 smb_response resp = {0};
1928 smbwrp_fileinfo * finfo = (smbwrp_fileinfo *)pConn->mem;
1929 char path[CCHMAXPATH+1] = {0};
1930
1931 log("NdpSetFileAttribute in\n");
1932 do {
1933 rc = checkconnection(pConn);
1934 if (rc)
1935 {
1936 break;
1937 }
1938
1939 rc = pathparser(pRes, pConn, szFileName, path);
1940 if (rc)
1941 {
1942 break;
1943 }
1944
1945 MemSet(finfo, 0, sizeof(*finfo));
1946
1947 StrNCpy(finfo->fname, path, sizeof(finfo->fname) - 1);
1948 finfo->attr = usAttr & 0x37;
1949 req.request = SMBREQ_SETINFO;
1950 req.param = pConn->mem;
1951 req.paramlen = sizeof(*finfo);
1952 req.length = req.paramlen;
1953 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1954 if (pConn->rc || action < sizeof(resp) || resp.rc)
1955 {
1956 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1957 }
1958 } while (0);
1959 log("NdpSetFileAttribute <%s> (%s) %04x %d %d\n", szFileName, path, usAttr, rc, pConn->rc);
1960 return rc;
1961}
1962
1963int APIENTRY NdpFlush (HRESOURCE resource)
1964{
1965 log("NdpFlush %d\n", ERROR_NOT_SUPPORTED);
1966 return ERROR_NOT_SUPPORTED;
1967}
1968
1969int APIENTRY NdpIOCTL (int type, HRESOURCE resource, char *path, int function, void *in, ULONG insize, PULONG poutlen)
1970{
1971 log("NdpIOCTL <%s> %d %d\n", path, function, ERROR_NOT_SUPPORTED);
1972 return ERROR_NOT_SUPPORTED;
1973}
1974
1975int APIENTRY NdpFileQueryInfo (HCONNECTION conn, NDFILEHANDLE handle, void *plist)
1976{
1977 Connection *pConn = (Connection *)conn;
1978 Resource *pRes = pConn->pRes;
1979 int rc = 0;
1980 unsigned long action;
1981 smb_request req = {0};
1982 smb_response resp = {0};
1983 FILEFINDBUF3 buf;
1984 smbwrp_fileinfo * finfo = (smbwrp_fileinfo *)(pConn->mem + sizeof(pConn->file));
1985
1986 log("NdpFileQueryInfo in\n");
1987 do {
1988 if (pConn->file.fd < 0 || !*pConn->file.fname)
1989 {
1990 rc = ERROR_INVALID_HANDLE;
1991 break;
1992 }
1993 if (pConn->rc)
1994 {
1995 rc = ERROR_PIPE_NOT_CONNECTED;
1996 break;
1997 }
1998
1999 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2000 StrNCpy(finfo->fname, pConn->file.fname, sizeof(finfo->fname) - 1);
2001 req.request = SMBREQ_FGETINFO;
2002 req.param = pConn->mem;
2003 req.paramlen = sizeof(pConn->file);
2004 req.length = req.paramlen + sizeof(*finfo);
2005 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2006 if (pConn->rc || action < sizeof(resp) || resp.rc)
2007 {
2008 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2009 }
2010 else
2011 {
2012 finfo->easize = -1;
2013 if (ifL)
2014 {
2015 getfindinfoL(pConn, plist, finfo, 0, NULL);
2016 }
2017 else
2018 {
2019 getfindinfo(pConn, &buf, finfo);
2020 ph->fsphAddFileFind32(plist, &buf, finfo, sizeof(*finfo), 0);
2021 }
2022 }
2023 } while (0);
2024 log("NdpFileQueryInfo <%s> %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, rc, pConn->rc);
2025
2026 return rc;
2027}
2028
2029int APIENTRY NdpFileEAQuery (HCONNECTION conn, NDFILEHANDLE handle, GEALIST *pGEAList, FEALIST *pFEAList)
2030{
2031 Connection *pConn = (Connection *)conn;
2032 Resource *pRes = pConn->pRes;
2033 int rc = 0;
2034 unsigned long action;
2035 smb_request req = {0};
2036 smb_response resp = {0};
2037 FEALIST * pFEASrc;
2038
2039 if (!pFEAList)
2040 {
2041 return ERROR_EAS_NOT_SUPPORTED;
2042 }
2043 if (!pRes->easupport)
2044 {
2045 return ERROR_EAS_NOT_SUPPORTED;
2046 }
2047
2048 log("NdpFileEAQuery in <%s>/%d pGEAList=%08x\n", pConn->file.fname, pConn->file.fd, pGEAList);
2049 do {
2050 if (pConn->file.fd < 0)
2051 {
2052 rc = ERROR_INVALID_HANDLE;
2053 break;
2054 }
2055 if (pConn->rc)
2056 {
2057 rc = ERROR_PIPE_NOT_CONNECTED;
2058 break;
2059 }
2060
2061 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2062 req.request = SMBREQ_FLISTEA;
2063 req.param = pConn->mem;
2064 req.paramlen = sizeof(pConn->file);
2065 req.length = pRes->memlen - req.paramlen;
2066 pFEASrc = (FEALIST *)(pConn->mem + req.paramlen);
2067 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2068 if (pConn->rc || action < sizeof(resp) || resp.rc)
2069 {
2070 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2071 switch (rc)
2072 {
2073 case ERROR_FILE_NOT_FOUND :
2074 case ERROR_PATH_NOT_FOUND :
2075 {
2076 pFEAList->cbList = sizeof(pFEAList->cbList);
2077 rc = NO_ERROR;
2078 } break;
2079 case ERROR_BUFFER_OVERFLOW :
2080 {
2081 pFEAList->cbList = pFEASrc->cbList;
2082 } break;
2083 default :
2084 {
2085 rc = ERROR_EAS_NOT_SUPPORTED;
2086 }
2087 }
2088 }
2089 else
2090 {
2091 rc = buildFEALIST(pFEASrc, pGEAList, pFEAList);
2092 }
2093 } while (0);
2094 log("NdpFileEAQuery out <%s>/%d pFEASrc->cbList=%d pFEAList->cbList=%d rc=%d %d %d\n", pConn->file.fname, pConn->file.fd, pFEASrc->cbList, pFEAList->cbList, rc, pConn->rc, resp.rc);
2095 return rc;
2096}
2097
2098int APIENTRY NdpFileEASet (HCONNECTION conn, NDFILEHANDLE handle, FEALIST *pFEAList)
2099{
2100 Connection *pConn = (Connection *)conn;
2101 Resource *pRes = pConn->pRes;
2102 int rc = 0;
2103 smb_request req = {0};
2104 smb_response resp = {0};
2105 unsigned long action;
2106
2107 log("NdpFileEASet in\n");
2108
2109 if (!pFEAList || pFEAList->cbList <= sizeof(long))
2110 {
2111 return ERROR_EAS_NOT_SUPPORTED;
2112 }
2113 if (!pRes->easupport)
2114 {
2115 return ERROR_EAS_NOT_SUPPORTED;
2116 }
2117 if (pFEAList->cbList > pRes->memlen)
2118 {
2119 return ERROR_NOT_ENOUGH_MEMORY;
2120 }
2121
2122 do {
2123 if (pConn->file.fd < 0)
2124 {
2125 rc = ERROR_INVALID_HANDLE;
2126 break;
2127 }
2128 if (pConn->rc)
2129 {
2130 rc = ERROR_PIPE_NOT_CONNECTED;
2131 break;
2132 }
2133
2134 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2135 MemCpy(pConn->mem + sizeof(pConn->file), pFEAList, pFEAList->cbList);
2136 req.request = SMBREQ_FSETEA;
2137 req.param = pConn->mem;
2138 req.paramlen = pFEAList->cbList + sizeof(pConn->file);
2139 req.length = req.paramlen;
2140
2141 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2142 if (pConn->rc || action < sizeof(resp) || resp.rc)
2143 {
2144 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2145 }
2146 } while (0);
2147 log("NdpFileEASet %d\n", rc);
2148 return rc;
2149}
2150
2151int APIENTRY NdpFileEASize (HCONNECTION conn, NDFILEHANDLE handle, ULONG *pulEASize)
2152{
2153 Connection *pConn = (Connection *)conn;
2154 Resource *pRes = pConn->pRes;
2155 int rc = 0;
2156 unsigned long action;
2157 smb_request req = {0};
2158 smb_response resp = {0};
2159 char path[CCHMAXPATH+1] = {0};
2160 FEALIST * pfealist;
2161
2162 if (!pulEASize)
2163 {
2164 return ERROR_EAS_NOT_SUPPORTED;
2165 }
2166 if (!pRes->easupport)
2167 {
2168 return ERROR_EAS_NOT_SUPPORTED;
2169 }
2170
2171 log("NdpFileEASize in <%s>/%d \n", pConn->file.fname, pConn->file.fd);
2172 do {
2173 if (pConn->file.fd < 0)
2174 {
2175 rc = ERROR_INVALID_HANDLE;
2176 break;
2177 }
2178 if (pConn->rc)
2179 {
2180 rc = ERROR_PIPE_NOT_CONNECTED;
2181 break;
2182 }
2183
2184 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2185 req.request = SMBREQ_FLISTEA;
2186 req.param = pConn->mem;
2187 req.paramlen = sizeof(pConn->file);
2188 req.length = pRes->memlen - req.paramlen;
2189 pfealist = (FEALIST *)(pConn->mem + req.paramlen);
2190 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2191 if (pConn->rc || action < sizeof(resp) || resp.rc)
2192 {
2193 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2194 switch (rc)
2195 {
2196 case ERROR_FILE_NOT_FOUND :
2197 case ERROR_PATH_NOT_FOUND :
2198 {
2199 pfealist->cbList = sizeof(pfealist->cbList);
2200 } /* Fall through */
2201 case ERROR_BUFFER_OVERFLOW :
2202 {
2203 rc = NO_ERROR;
2204 } break;
2205 default :
2206 {
2207 rc = ERROR_EAS_NOT_SUPPORTED;
2208 }
2209 }
2210 }
2211 *pulEASize = pfealist->cbList;
2212 } while (0);
2213 log("NdpFileEASize %d %d %d %d\n", *pulEASize, rc, pConn->rc, resp.rc);
2214 return rc;
2215}
2216
2217int APIENTRY NdpFileSetInfo (HCONNECTION conn, NDFILEHANDLE handle, NDFILEINFOL *pfi)
2218{
2219 Connection *pConn = (Connection *)conn;
2220 Resource *pRes = pConn->pRes;
2221 int rc = 0;
2222 unsigned long action, attrFile;
2223 smb_request req = {0};
2224 smb_response resp = {0};
2225 smbwrp_fileinfo * finfo = (smbwrp_fileinfo *)pConn->mem;
2226
2227 log("NdpFileSetInfo in\n");
2228 do {
2229 if (pConn->file.fd < 0 || !*pConn->file.fname)
2230 {
2231 rc = ERROR_INVALID_HANDLE;
2232 break;
2233 }
2234 if (pConn->rc)
2235 {
2236 rc = ERROR_PIPE_NOT_CONNECTED;
2237 break;
2238 }
2239 if (ifL)
2240 {
2241 attrFile = pfi->stat.attrFile;
2242 }
2243 else
2244 {
2245 FILESTATUS3 * stat = (FILESTATUS3 *)&(pfi->stat);
2246 attrFile = stat->attrFile;
2247 }
2248 // deferred setinfo - on closing the file
2249 pConn->file.openattr = attrFile;
2250 ph->fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, (unsigned long *)&(pConn->file.mtime));
2251 } while (0);
2252 log("NdpFileSetInfo <%s> %08x %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, attrFile, rc, pConn->rc);
2253 return NO_ERROR;
2254}
2255
2256int APIENTRY NdpFileSetFilePtrL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llOffset, ULONG ulMethod, LONGLONG *pllActual)
2257{
2258 Connection *pConn = (Connection *)conn;
2259 Resource *pRes = pConn->pRes;
2260 int rc = 0;
2261 unsigned long action;
2262 smb_request req = {0};
2263 smb_response resp = {0};
2264
2265 log("NdpFileSetFilePtrl in\n");
2266 do {
2267 if (pConn->file.fd < 0)
2268 {
2269 rc = ERROR_INVALID_HANDLE;
2270 break;
2271 }
2272 if (pConn->rc)
2273 {
2274 rc = ERROR_PIPE_NOT_CONNECTED;
2275 break;
2276 }
2277
2278 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2279 *(unsigned long *)(pConn->mem + sizeof(pConn->file)) = ulMethod;
2280 *(long long *)(pConn->mem + sizeof(pConn->file) + sizeof(long)) = llOffset;
2281 req.request = SMBREQ_LSEEK;
2282 req.param = pConn->mem;
2283 req.paramlen = sizeof(pConn->file) + sizeof(long) + sizeof(long long);
2284 req.length = req.paramlen;
2285 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2286 if (pConn->rc || action < sizeof(resp) || resp.rc)
2287 {
2288 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2289 }
2290 else
2291 {
2292 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
2293 *pllActual = pConn->file.offset;
2294 }
2295 } while (0);
2296 log("NdpFileSetFilePtrL <%s> %lld %lu %lld %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llOffset, ulMethod, *pllActual, rc, pConn->rc);
2297
2298 return rc;
2299}
2300
2301int APIENTRY NdpFileSetFilePtr (HCONNECTION conn, NDFILEHANDLE handle, LONG lOffset, ULONG ulMethod, ULONG *pulActual)
2302{
2303 LONGLONG llActual;
2304 int rc = NdpFileSetFilePtrL(conn, handle, lOffset, ulMethod, &llActual);
2305 *pulActual = llActual & 0xFFFFFFFF;
2306 log("NdpFileSetFilePtr %ld %lu %ld %d\n", lOffset, ulMethod, *pulActual, rc);
2307 return rc;
2308}
2309
2310int APIENTRY NdpFileClose (HCONNECTION conn, NDFILEHANDLE handle)
2311{
2312 Connection *pConn = (Connection *)conn;
2313 Resource *pRes = pConn->pRes;
2314 int rc = 0;
2315 unsigned long action;
2316 smb_request req = {0};
2317 smb_response resp = {0};
2318
2319 log("NdpFileClose in %d <%s>\n", pConn->file.fd, pConn->file.fd < 0 ? "!null!" : pConn->file.fname);
2320
2321 do {
2322 if (pConn->file.fd < 0)
2323 {
2324 rc = ERROR_INVALID_HANDLE;
2325 break;
2326 }
2327 if (pConn->rc)
2328 {
2329 rc = ERROR_PIPE_NOT_CONNECTED;
2330 break;
2331 }
2332
2333 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2334 req.request = SMBREQ_CLOSE;
2335 req.param = pConn->mem;
2336 req.length = pRes->memlen;
2337 req.paramlen = sizeof(pConn->file);
2338 req.length = req.paramlen;
2339 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2340 if (pConn->rc || action < sizeof(resp) || resp.rc)
2341 {
2342 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2343 }
2344 else
2345 {
2346 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
2347 }
2348 } while (0);
2349 log("NdpFileClose %d %d %d\n", pConn->file.fd, rc, pConn->rc);
2350 pConn->file.fd = -1;
2351 return rc;
2352}
2353
2354int APIENTRY NdpFileCommit (HCONNECTION conn, NDFILEHANDLE handle)
2355{
2356 log("NdpFileCommit %d\n", NO_ERROR);
2357 return NO_ERROR;
2358}
2359
2360
2361int APIENTRY NdpFileNewSize (HCONNECTION conn, NDFILEHANDLE handle, ULONG ulLen)
2362{
2363 int rc = NdpFileNewSizeL(conn, handle, ulLen);
2364 log("NdpFileNewSize %ld %d\n", ulLen, rc);
2365 return rc;
2366}
2367
2368int APIENTRY NdpFileNewSizeL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llLen)
2369{
2370 Connection *pConn = (Connection *)conn;
2371 Resource *pRes = pConn->pRes;
2372 int rc = 0;
2373 unsigned long action;
2374 smb_request req = {0};
2375 smb_response resp = {0};
2376
2377 log("NdpFileNewSizeL in\n");
2378 do {
2379 if (pConn->file.fd < 0)
2380 {
2381 rc = ERROR_INVALID_HANDLE;
2382 break;
2383 }
2384 if (pConn->rc)
2385 {
2386 rc = ERROR_PIPE_NOT_CONNECTED;
2387 break;
2388 }
2389
2390 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2391 *(long long *)(pConn->mem + sizeof(pConn->file)) = llLen;
2392
2393 req.request = SMBREQ_NEWSIZE;
2394 req.param = pConn->mem;
2395 req.paramlen = sizeof(pConn->file) + sizeof(long long);
2396 req.length = req.paramlen;
2397
2398 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2399 if (pConn->rc || action < sizeof(resp) || resp.rc)
2400 {
2401 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2402 }
2403 else
2404 {
2405 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
2406 }
2407 } while (0);
2408 log("NdpFileNewSizeL <%s> %lld %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llLen, rc, pConn->rc);
2409 return rc;
2410}
2411
2412int APIENTRY NdpFileRead (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulRead, ULONG *pulActual)
2413{
2414 Connection *pConn = (Connection *)conn;
2415 Resource *pRes = pConn->pRes;
2416 int rc = 0;
2417 unsigned long done = 0;
2418 unsigned long onedone;
2419 unsigned long action;
2420 smb_request req = {0};
2421 smb_response resp = {0};
2422
2423 log("NdpFileRead in\n");
2424// log("NdpFileRead <%s> %lu\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulRead);
2425
2426 do {
2427 if (pConn->file.fd < 0)
2428 {
2429 rc = ERROR_INVALID_HANDLE;
2430 break;
2431 }
2432 if (pConn->rc)
2433 {
2434 rc = ERROR_PIPE_NOT_CONNECTED;
2435 break;
2436 }
2437
2438 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2439 req.request = SMBREQ_READ;
2440 req.param = pConn->mem;
2441 req.paramlen = sizeof(pConn->file);
2442
2443 while (done < ulRead)
2444 {
2445 req.length = req.paramlen + (pRes->memlen - req.paramlen < (ulRead - done) ? pRes->memlen - req.paramlen : (ulRead - done));
2446
2447 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2448 if (pConn->rc || action < sizeof(resp) || resp.rc)
2449 {
2450 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2451 break;
2452 }
2453 if (resp.value == 0)
2454 {
2455 break;
2456 }
2457 onedone = resp.value > req.length ? req.length : resp.value;
2458 MemCpy((char *)pBuffer + done, pConn->mem + sizeof(pConn->file), onedone);
2459 done += onedone;
2460 }
2461 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
2462 *pulActual = done;
2463 } while (0);
2464 log("NdpFileRead <%s> %lu %lu %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulRead, *pulActual, rc, pConn->rc);
2465
2466 return rc;
2467}
2468
2469int APIENTRY NdpFileWrite (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulWrite, ULONG *pulActual)
2470{
2471 Connection *pConn = (Connection *)conn;
2472 Resource *pRes = pConn->pRes;
2473 int rc = 0;
2474 unsigned long done = 0;
2475 unsigned long onedone;
2476 unsigned long action;
2477 smb_request req = {0};
2478 smb_response resp = {0};
2479
2480 log("NdpFileWrite in\n");
2481 do {
2482 if (pConn->file.fd < 0)
2483 {
2484 rc = ERROR_INVALID_HANDLE;
2485 break;
2486 }
2487 if (pConn->rc)
2488 {
2489 rc = ERROR_PIPE_NOT_CONNECTED;
2490 break;
2491 }
2492
2493 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2494 req.request = SMBREQ_WRITE;
2495 req.param = pConn->mem;
2496 req.paramlen = sizeof(pConn->file);
2497
2498 while (done < ulWrite)
2499 {
2500 req.length = pRes->memlen - req.paramlen < (ulWrite - done) ? pRes->memlen - req.paramlen : (ulWrite - done);
2501 MemCpy(pConn->mem + sizeof(pConn->file), (char *)pBuffer + done, req.length);
2502 req.length += req.paramlen;
2503
2504 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2505 if (pConn->rc || action < sizeof(resp) || resp.rc)
2506 {
2507 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2508 break;
2509 }
2510 done += resp.value & 0xFFFFFFFF;
2511 if (resp.value < req.length)
2512 {
2513 break;
2514 }
2515 }
2516 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
2517 *pulActual = done;
2518 } while (0);
2519 log("NdpFileWrite <%s> %lu %lu %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulWrite, *pulActual, rc, pConn->rc);
2520
2521 return rc;
2522}
Note: See TracBrowser for help on using the repository browser.