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

Last change on this file since 24 was 24, checked in by Yuri Dario, 18 years ago

More debugging informations on request.

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